/** Construct a new compiler from a shared context. */
  public AptJavaCompiler(Context context) {
    super(preRegister(context));

    context.put(compilerKey, this);
    apt = Apt.instance(context);

    ClassReader classReader = ClassReader.instance(context);
    classReader.preferSource = true;

    // TEMPORARY NOTE: bark==log, but while refactoring, we maintain their
    // original identities, to remember the original intent.
    log = Log.instance(context);
    bark = Bark.instance(context);

    Options options = Options.instance(context);
    classOutput = options.get("-retrofit") == null;
    nocompile = options.get("-nocompile") != null;
    print = options.get("-print") != null;
    classesAsDecls = options.get("-XclassesAsDecls") != null;

    genSourceFileNames = new java.util.LinkedHashSet<String>();
    genClassFileNames = new java.util.LinkedHashSet<String>();

    // this forces a copy of the line map to be kept in the tree,
    // for use by com.sun.mirror.util.SourcePosition.
    lineDebugInfo = true;
  }
Beispiel #2
0
  public void visitTopLevel(JCCompilationUnit tree) {
    JavaFileObject prev = log.useSource(tree.sourcefile);
    boolean addEnv = false;
    boolean isPkgInfo =
        tree.sourcefile.isNameCompatible("package-info", JavaFileObject.Kind.SOURCE);
    if (tree.pid != null) {
      tree.packge = reader.enterPackage(TreeInfo.fullName(tree.pid));
      if (tree.packageAnnotations.nonEmpty()) {
        if (isPkgInfo) {
          addEnv = true;
        } else {
          log.error(tree.packageAnnotations.head.pos(), "pkg.annotations.sb.in.package-info.java");
        }
      }
    } else {
      tree.packge = syms.unnamedPackage;
    }
    tree.packge.complete(); // Find all classes in package.
    Env<AttrContext> env = topLevelEnv(tree);

    // Save environment of package-info.java file.
    if (isPkgInfo) {
      Env<AttrContext> env0 = typeEnvs.get(tree.packge);
      if (env0 == null) {
        typeEnvs.put(tree.packge, env);
      } else {
        JCCompilationUnit tree0 = env0.toplevel;
        if (!fileManager.isSameFile(tree.sourcefile, tree0.sourcefile)) {
          log.warning(
              tree.pid != null ? tree.pid.pos() : null, "pkg-info.already.seen", tree.packge);
          if (addEnv
              || (tree0.packageAnnotations.isEmpty()
                  && tree.docComments != null
                  && tree.docComments.get(tree) != null)) {
            typeEnvs.put(tree.packge, env);
          }
        }
      }
    }
    classEnter(tree.defs, env);
    if (addEnv) {
      todo.append(env);
    }
    log.useSource(prev);
    result = null;
  }
Beispiel #3
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> env = typeEnvs.get(tree);
            if (env == null) env = topLevelEnv(tree);
            memberEnter.memberEnter(tree, env);
            log.useSource(prev);
          }
        }
      }
    } finally {
      uncompleted = prevUncompleted;
      annotate.enterDone();
    }
  }
Beispiel #4
0
  protected Enter(Context context) {
    context.put(enterKey, this);

    log = Log.instance(context);
    reader = ClassReader.instance(context);
    make = TreeMaker.instance(context);
    syms = Symtab.instance(context);
    chk = Check.instance(context);
    memberEnter = MemberEnter.instance(context);
    types = Types.instance(context);
    annotate = Annotate.instance(context);
    lint = Lint.instance(context);

    predefClassDef =
        make.ClassDef(make.Modifiers(PUBLIC), syms.predefClass.name, null, null, null, null);
    predefClassDef.sym = syms.predefClass;
    todo = Todo.instance(context);
    fileManager = context.get(JavaFileManager.class);
  }
  /**
   * Main method: compile a list of files, return all compiled classes
   *
   * @param filenames The names of all files to be compiled.
   */
  public List<ClassSymbol> compile(
      List<String> filenames,
      Map<String, String> origOptions,
      ClassLoader aptCL,
      AnnotationProcessorFactory providedFactory,
      java.util.Set<Class<? extends AnnotationProcessorFactory>> productiveFactories,
      java.util.Set<java.io.File> aggregateGenFiles)
      throws Throwable {
    // as a JavaCompiler can only be used once, throw an exception if
    // it has been used before.
    assert !hasBeenUsed : "attempt to reuse JavaCompiler";
    hasBeenUsed = true;

    this.aggregateGenFiles = aggregateGenFiles;

    long msec = System.currentTimeMillis();

    ListBuffer<ClassSymbol> classes = new ListBuffer<ClassSymbol>();
    try {
      JavacFileManager fm = (JavacFileManager) fileManager;
      // parse all files
      ListBuffer<JCCompilationUnit> trees = new ListBuffer<JCCompilationUnit>();
      for (List<String> l = filenames; l.nonEmpty(); l = l.tail) {
        if (classesAsDecls) {
          if (!l.head.endsWith(".java")) { // process as class file
            ClassSymbol cs = reader.enterClass(names.fromString(l.head));
            try {
              cs.complete();
            } catch (Symbol.CompletionFailure cf) {
              bark.aptError("CantFindClass", l);
              continue;
            }

            classes.append(cs); // add to list of classes
            continue;
          }
        }
        JavaFileObject fo = fm.getJavaFileObjectsFromStrings(List.of(l.head)).iterator().next();
        trees.append(parse(fo));
      }

      // enter symbols for all files
      List<JCCompilationUnit> roots = trees.toList();

      if (errorCount() == 0) {
        boolean prev = bark.setDiagnosticsIgnored(true);
        try {
          enter.main(roots);
        } finally {
          bark.setDiagnosticsIgnored(prev);
        }
      }

      if (errorCount() == 0) {
        apt.main(roots, classes, origOptions, aptCL, providedFactory, productiveFactories);
        genSourceFileNames.addAll(apt.getSourceFileNames());
        genClassFileNames.addAll(apt.getClassFileNames());
      }

    } catch (Abort ex) {
    }

    if (verbose) log.printVerbose("total", Long.toString(System.currentTimeMillis() - msec));

    chk.reportDeferredDiagnostics();

    printCount("error", errorCount());
    printCount("warn", warningCount());

    return classes.toList();
  }
Beispiel #6
0
 /** Complain about a duplicate class. */
 protected void duplicateClass(DiagnosticPosition pos, ClassSymbol c) {
   log.error(pos, "duplicate.class", c.fullname);
 }
Beispiel #7
0
  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;
  }