예제 #1
0
  /** Perform the appropriate flow operations for assignment to a local variable */
  protected Map flowLocalAssign(
      DataFlowItem inItem, FlowGraph graph, LocalAssign a, Set succEdgeKeys) {
    Local l = (Local) a.left();
    Map m = new HashMap(inItem.initStatus);
    MinMaxInitCount initCount = (MinMaxInitCount) m.get(l.localInstance());

    // initcount could be null if the local is defined in the outer
    // class, or if we have not yet seen its declaration (i.e. the
    // local is used in its own initialization)
    if (initCount == null) {
      initCount = new MinMaxInitCount(InitCount.ZERO, InitCount.ZERO);
    }

    initCount = new MinMaxInitCount(initCount.getMin().increment(), initCount.getMax().increment());

    m.put(l.localInstance(), initCount);
    return itemToMap(new DataFlowItem(m), succEdgeKeys);
  }
예제 #2
0
 /** Check that the local variable <code>l</code> is used correctly. */
 protected void checkLocal(FlowGraph graph, Local l, DataFlowItem dfIn, DataFlowItem dfOut)
     throws SemanticException {
   if (!currCBI.localDeclarations.contains(l.localInstance())) {
     // it's a local variable that has not been declared within
     // this scope. The only way this can arise is from an
     // inner class that is not a member of a class (typically
     // a local class, or an anonymous class declared in a method,
     // constructor or initializer).
     // We need to check that it is a final local, and also
     // keep track of it, to ensure that it has been definitely
     // assigned at this point.
     currCBI.outerLocalsUsed.add(l.localInstance());
   } else {
     MinMaxInitCount initCount = (MinMaxInitCount) dfIn.initStatus.get(l.localInstance());
     if (initCount != null && InitCount.ZERO.equals(initCount.getMin())) {
       // the local variable may not have been initialized.
       // However, we only want to complain if the local is reachable
       if (l.reachable()) {
         throw new SemanticException(
             "Local variable \"" + l.name() + "\" may not have been initialized", l.position());
       }
     }
   }
 }
예제 #3
0
  /** Flatten complex expressions within the AST */
  public Node leave(Node old, Node n, NodeVisitor v) {
    if (n == noFlatten) {
      noFlatten = null;
      return n;
    }

    if (n instanceof Block) {
      List l = (List) stack.removeFirst();
      return ((Block) n).statements(l);
    } else if (n instanceof Stmt && !(n instanceof LocalDecl)) {
      List l = (List) stack.getFirst();
      l.add(n);
      return n;
    } else if (n instanceof Expr
        && !(n instanceof Lit)
        && !(n instanceof Special)
        && !(n instanceof Local)) {

      Expr e = (Expr) n;

      if (e instanceof Assign) {
        return n;
      }

      // create a local temp, initialized to the value of the complex
      // expression

      String name = newID();
      LocalDecl def =
          nf.LocalDecl(
              e.position(), Flags.FINAL, nf.CanonicalTypeNode(e.position(), e.type()), name, e);
      def = def.localInstance(ts.localInstance(e.position(), Flags.FINAL, e.type(), name));

      List l = (List) stack.getFirst();
      l.add(def);

      // return the local temp instead of the complex expression
      Local use = nf.Local(e.position(), name);
      use = (Local) use.type(e.type());
      use = use.localInstance(ts.localInstance(e.position(), Flags.FINAL, e.type(), name));
      return use;
    }

    return n;
  }