예제 #1
0
  /**
   * Main method: enter one class from a list of toplevel trees and place the rest on uncompleted
   * for later processing.
   *
   * @param trees The list of trees to be processed.
   * @param c The class symbol to be processed.
   */
  public void complete(List<JCCompilationUnit> trees, ClassSymbol c) {
    annotate.enterStart();
    ListBuffer<ClassSymbol> prevUncompleted = uncompleted;
    if (memberEnter.completionEnabled) uncompleted = new ListBuffer<ClassSymbol>();

    try {
      // enter all classes, and construct uncompleted list
      classEnter(trees, null);

      // complete all uncompleted classes in memberEnter
      if (memberEnter.completionEnabled) {
        while (uncompleted.nonEmpty()) {
          ClassSymbol clazz = uncompleted.next();
          if (c == null || c == clazz || prevUncompleted == null) clazz.complete();
          else
            // defer
            prevUncompleted.append(clazz);
        }

        // if there remain any unimported toplevels (these must have
        // no classes at all), process their import statements as well.
        for (JCCompilationUnit tree : trees) {
          if (tree.starImportScope.elems == null) {
            JavaFileObject prev = log.useSource(tree.sourcefile);
            Env<AttrContext> topEnv = topLevelEnv(tree);
            memberEnter.memberEnter(tree, topEnv);
            log.useSource(prev);
          }
        }
      }
    } finally {
      uncompleted = prevUncompleted;
      annotate.enterDone();
    }
  }
예제 #2
0
 /** Visitor method: enter classes of a list of trees, returning a list of types. */
 <T extends JCTree> List<Type> classEnter(List<T> trees, Env<AttrContext> env) {
   ListBuffer<Type> ts = new ListBuffer<Type>();
   for (List<T> l = trees; l.nonEmpty(); l = l.tail) {
     Type t = classEnter(l.head, env);
     if (t != null) ts.append(t);
   }
   return ts.toList();
 }
예제 #3
0
 // where
 private void handleFlowResults(Queue<Env<AttrContext>> queue, ListBuffer<Element> elems) {
   for (Env<AttrContext> env : queue) {
     switch (env.tree.getTag()) {
       case JCTree.CLASSDEF:
         JCClassDecl cdef = (JCClassDecl) env.tree;
         if (cdef.sym != null) elems.append(cdef.sym);
         break;
       case JCTree.TOPLEVEL:
         JCCompilationUnit unit = (JCCompilationUnit) env.tree;
         if (unit.packge != null) elems.append(unit.packge);
         break;
     }
   }
   genList.addAll(queue);
 }
예제 #4
0
  /**
   * Translate the given abstract syntax trees to elements.
   *
   * @param trees a list of abstract syntax trees.
   * @throws java.io.IOException TODO
   * @return a list of elements corresponding to the top level classes in the abstract syntax trees
   */
  public Iterable<? extends TypeElement> enter(Iterable<? extends CompilationUnitTree> trees)
      throws IOException {
    prepareCompiler();

    ListBuffer<JCCompilationUnit> roots = null;

    if (trees == null) {
      // If there are still files which were specified to be compiled
      // (i.e. in fileObjects) but which have not yet been entered,
      // then we make sure they have been parsed and add them to the
      // list to be entered.
      if (notYetEntered.size() > 0) {
        if (!parsed) parse(); // TODO would be nice to specify files needed to be parsed
        for (JavaFileObject file : fileObjects) {
          JCCompilationUnit unit = notYetEntered.remove(file);
          if (unit != null) {
            if (roots == null) roots = new ListBuffer<JCCompilationUnit>();
            roots.append(unit);
          }
        }
        notYetEntered.clear();
      }
    } else {
      for (CompilationUnitTree cu : trees) {
        if (cu instanceof JCCompilationUnit) {
          if (roots == null) roots = new ListBuffer<JCCompilationUnit>();
          roots.append((JCCompilationUnit) cu);
          notYetEntered.remove(cu.getSourceFile());
        } else throw new IllegalArgumentException(cu.toString());
      }
    }

    if (roots == null) return List.nil();

    try {
      List<JCCompilationUnit> units = compiler.enterTrees(roots.toList());

      if (notYetEntered.isEmpty()) compiler = compiler.processAnnotations(units);

      ListBuffer<TypeElement> elements = new ListBuffer<TypeElement>();
      for (JCCompilationUnit unit : units) {
        for (JCTree node : unit.defs) {
          if (node.getTag() == JCTree.CLASSDEF) {
            JCClassDecl cdef = (JCClassDecl) node;
            if (cdef.sym != null) // maybe null if errors in anno processing
            elements.append(cdef.sym);
          }
        }
      }
      return elements.toList();
    } finally {
      compiler.log.flush();
    }
  }
예제 #5
0
    void run(Queue<Env<AttrContext>> list, Iterable<? extends TypeElement> classes) {
      Set<TypeElement> set = new HashSet<TypeElement>();
      for (TypeElement item : classes) set.add(item);

      ListBuffer<Env<AttrContext>> defer = ListBuffer.<Env<AttrContext>>lb();
      while (list.peek() != null) {
        Env<AttrContext> env = list.remove();
        ClassSymbol csym = env.enclClass.sym;
        if (csym != null && set.contains(csym.outermostClass())) process(env);
        else defer = defer.append(env);
      }

      list.addAll(defer);
    }
예제 #6
0
 private static List<JavaFileObject> toList(Iterable<? extends JavaFileObject> fileObjects) {
   if (fileObjects == null) return List.nil();
   ListBuffer<JavaFileObject> result = new ListBuffer<JavaFileObject>();
   for (JavaFileObject fo : fileObjects) result.append(fo);
   return result.toList();
 }
예제 #7
0
 private static String[] toArray(Iterable<String> iter) {
   ListBuffer<String> result = new ListBuffer<String>();
   if (iter != null) for (String s : iter) result.append(s);
   return result.toArray(new String[result.length()]);
 }
예제 #8
0
  @Override
  public void visitClassDef(JCClassDecl tree) {
    Symbol owner = env.info.scope.owner;
    Scope enclScope = enterScope(env);
    ClassSymbol c;
    if (owner.kind == PCK) {
      // We are seeing a toplevel class.
      PackageSymbol packge = (PackageSymbol) owner;
      for (Symbol q = packge; q != null && q.kind == PCK; q = q.owner) q.flags_field |= EXISTS;
      c = reader.enterClass(tree.name, packge);
      packge.members().enterIfAbsent(c);
      if ((tree.mods.flags & PUBLIC) != 0 && !classNameMatchesFileName(c, env)) {
        log.error(tree.pos(), "class.public.should.be.in.file", tree.name);
      }
    } else {
      if (!tree.name.isEmpty() && !chk.checkUniqueClassName(tree.pos(), tree.name, enclScope)) {
        result = null;
        return;
      }
      if (owner.kind == TYP) {
        // We are seeing a member class.
        c = reader.enterClass(tree.name, (TypeSymbol) owner);
        if ((owner.flags_field & INTERFACE) != 0) {
          tree.mods.flags |= PUBLIC | STATIC;
        }
      } else {
        // We are seeing a local class.
        c = reader.defineClass(tree.name, owner);
        c.flatname = chk.localClassName(c);
        if (!c.name.isEmpty()) chk.checkTransparentClass(tree.pos(), c, env.info.scope);
      }
    }
    tree.sym = c;

    // Enter class into `compiled' table and enclosing scope.
    if (chk.compiled.get(c.flatname) != null) {
      duplicateClass(tree.pos(), c);
      result = types.createErrorType(tree.name, (TypeSymbol) owner, Type.noType);
      tree.sym = (ClassSymbol) result.tsym;
      return;
    }
    chk.compiled.put(c.flatname, c);
    enclScope.enter(c);

    // Set up an environment for class block and store in `typeEnvs'
    // table, to be retrieved later in memberEnter and attribution.
    Env<AttrContext> localEnv = classEnv(tree, env);
    typeEnvs.put(c, localEnv);

    // Fill out class fields.
    c.completer = memberEnter;
    c.flags_field = chk.checkFlags(tree.pos(), tree.mods.flags, c, tree);
    c.sourcefile = env.toplevel.sourcefile;
    c.members_field = new Scope(c);

    ClassType ct = (ClassType) c.type;
    if (owner.kind != PCK && (c.flags_field & STATIC) == 0) {
      // We are seeing a local or inner class.
      // Set outer_field of this class to closest enclosing class
      // which contains this class in a non-static context
      // (its "enclosing instance class"), provided such a class exists.
      Symbol owner1 = owner;
      while ((owner1.kind & (VAR | MTH)) != 0 && (owner1.flags_field & STATIC) == 0) {
        owner1 = owner1.owner;
      }
      if (owner1.kind == TYP) {
        ct.setEnclosingType(owner1.type);
      }
    }

    // Enter type parameters.
    ct.typarams_field = classEnter(tree.typarams, localEnv);

    // Add non-local class to uncompleted, to make sure it will be
    // completed later.
    if (!c.isLocal() && uncompleted != null) uncompleted.append(c);
    //      System.err.println("entering " + c.fullname + " in " + c.owner);//DEBUG

    // Recursively enter all member classes.
    classEnter(tree.defs, localEnv);

    result = c.type;
  }