Exemple #1
0
  /** Perform the appropriate flow operations for declaration of a local variable */
  protected Map flowLocalDecl(
      DataFlowItem inItem, FlowGraph graph, LocalDecl ld, Set succEdgeKeys) {
    Map m = new HashMap(inItem.initStatus);
    MinMaxInitCount initCount = (MinMaxInitCount) m.get(ld.localInstance());
    // if (initCount == null) {
    if (ld.init() != null) {
      // declaration of local var with initialization.
      initCount = new MinMaxInitCount(InitCount.ONE, InitCount.ONE);
    } else {
      // declaration of local var with no initialization.
      initCount = new MinMaxInitCount(InitCount.ZERO, InitCount.ZERO);
    }

    m.put(ld.localInstance(), initCount);
    //        }
    //        else {
    // the initCount is not null. We now have a problem. Why is the
    // initCount not null? Has this variable been assigned in its own
    // initialization, or is this a declaration inside a loop body?
    // XXX@@@ THIS IS A BUG THAT NEEDS TO BE FIXED.
    // Currently, the declaration "final int i = (i=5);" will
    // not be rejected, as we cannot distinguish between that and
    // "while (true) {final int i = 4;}"
    //        }

    // record the fact that we have seen a local declaration
    currCBI.localDeclarations.add(ld.localInstance());

    return itemToMap(new DataFlowItem(m), succEdgeKeys);
  }
  /** 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;
  }