/** * Determine if we are interested in this field on the basis of the target of the field. To wit, * if the field is static, then the target of the field must be the current class; if the field is * not static then the target must be "this". */ protected boolean isFieldsTargetAppropriate(Field f) { if (f.fieldInstance().flags().isStatic()) { ClassType containingClass = (ClassType) currCBI.currCodeDecl.codeInstance().container(); return containingClass.equals(f.fieldInstance().container()); } else { return (f.target() instanceof Special && Special.THIS.equals(((Special) f.target()).kind())); } }
protected NodeVisitor enterCall(Node n) throws SemanticException { if (n instanceof FieldDecl) { FieldDecl fd = (FieldDecl) n; FwdReferenceChecker frc = (FwdReferenceChecker) this.copy(); frc.inInitialization = true; frc.inStaticInit = fd.flags().flags().isStatic(); frc.declaredFields = new HashSet<FieldDef>(declaredFields); declaredFields.add(fd.fieldDef()); return frc; } else if (n instanceof Initializer) { FwdReferenceChecker frc = (FwdReferenceChecker) this.copy(); frc.inInitialization = true; frc.inStaticInit = ((Initializer) n).flags().flags().isStatic(); return frc; } else if (n instanceof FieldAssign) { FwdReferenceChecker frc = (FwdReferenceChecker) this.copy(); return frc; } else if (n instanceof Field) { if (inInitialization) { // we need to check if this is an illegal fwd reference. Field f = (Field) n; // an illegal fwd reference if a usage of an instance // (resp. static) field occurs in an instance (resp. static) // initialization, and the innermost enclosing class or // interface of the usage is the same as the container of // the field, and we have not yet seen the field declaration. // // In addition, if a field is not accessed as a simple name, // then all is ok ClassType currentClass = context().currentClass(); StructType fContainer = f.fieldInstance().container(); if (inStaticInit == f.fieldInstance().flags().isStatic() && currentClass.typeEquals(fContainer, context) && !declaredFields.contains(f.fieldInstance().def()) && f.isTargetImplicit()) { throw new SemanticException("Illegal forward reference", f.position()); } } } return this; }
/** create a constructor that can be traced back to the aspect that introduced it. */ public InterTypeConstructorInstance_c( TypeSystem ts, Position pos, String identifier, ClassType origin, ClassType container, Flags flags, List formalTypes, List excTypes) { super(ts, pos, container, flags, formalTypes, excTypes); this.origin = origin; this.identifier = identifier; if (container.toClass().flags().isInterface()) interfaceTarget = container.toClass(); else interfaceTarget = null; if (flags().isPrivate() || flags().isPackage()) { mangleType = origin; // not quite right, same as ajc. // ought to generate a fresh type for each aspect List fts = new LinkedList(formalTypes); fts.add(mangleType); mangled = new ConstructorInstance_c(ts, pos, container, flags, fts, excTypes); } }