protected void setupClassBody(ClassBody n) throws SemanticException { ClassBodyInfo newCDI = new ClassBodyInfo(); newCDI.outer = currCBI; currCBI = newCDI; // set up currClassFinalFieldInitCounts to contain mappings // for all the final fields of the class. Iterator classMembers = n.members().iterator(); while (classMembers.hasNext()) { ClassMember cm = (ClassMember) classMembers.next(); if (cm instanceof FieldDecl) { FieldDecl fd = (FieldDecl) cm; if (fd.flags().isFinal()) { MinMaxInitCount initCount; if (fd.init() != null) { // the field has an initializer initCount = new MinMaxInitCount(InitCount.ONE, InitCount.ONE); // do dataflow over the initialization expression // to pick up any uses of outer local variables. if (currCBI.outer != null) dataflow(fd.init()); } else { // the field does not have an initializer initCount = new MinMaxInitCount(InitCount.ZERO, InitCount.ZERO); } newCDI.currClassFinalFieldInitCounts.put(fd.fieldInstance(), initCount); } } } }
private Node buildFieldDecl(FieldDecl fd) throws SemanticException { Type t = fd.declType(); if (t.isSubtype(SJ_PROTOCOL_TYPE)) { if (!(fd instanceof SJFieldProtocolDecl)) { throw new SemanticException( "[SJProtocolDeclTypeBuilder] Protocols may only be declared using the protocol keyword: " + fd); } SJTypeNode tn = disambiguateSJTypeNode(this, ((SJProtocolDecl) fd).sessionType()); SJSessionType st = tn.type(); String sjname = fd.name(); // Should match that given by SJVariable.sjname. SJFieldInstance fi = (SJFieldInstance) fd.fieldInstance(); SJFieldProtocolInstance fpi = sjts.SJFieldProtocolInstance((SJFieldInstance) fd.fieldInstance(), st, sjname); fpi.setConstantValue( fi .constantValue()); // Currently, constant checker not run on custom nodes/type // objects. (Previously done by SJNoAliasTypeBuilder.) fd = fd.fieldInstance(fpi); fd = (FieldDecl) setSJProtocolDeclExt((SJProtocolDecl) fd, tn, sjname); updateSJFieldInstance(fi, fpi); } return fd; }
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; }