예제 #1
0
  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;
  }