/** 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;
  }
    /** Enter a set of generated class files. */
    private List<ClassSymbol> enterClassFiles(Map<String, JavaFileObject> classFiles) {
      ClassReader reader = ClassReader.instance(context);
      Names names = Names.instance(context);
      List<ClassSymbol> list = List.nil();

      for (Map.Entry<String, JavaFileObject> entry : classFiles.entrySet()) {
        Name name = names.fromString(entry.getKey());
        JavaFileObject file = entry.getValue();
        if (file.getKind() != JavaFileObject.Kind.CLASS) throw new AssertionError(file);
        ClassSymbol cs;
        if (isPkgInfo(file, JavaFileObject.Kind.CLASS)) {
          Name packageName = Convert.packagePart(name);
          PackageSymbol p = reader.enterPackage(packageName);
          if (p.package_info == null)
            p.package_info = reader.enterClass(Convert.shortName(name), p);
          cs = p.package_info;
          if (cs.classfile == null) cs.classfile = file;
        } else cs = reader.enterClass(name, file);
        list = list.prepend(cs);
      }
      return list.reverse();
    }
예제 #3
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;
  }
예제 #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);
  }
예제 #5
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;
  }
예제 #6
0
  void createSymbols() throws IOException {
    Set<String> legacy = getLegacyPackages();
    Set<String> legacyProprietary = getLegacyPackages();
    Set<String> documented = new HashSet<String>();
    Set<PackageSymbol> packages =
        ((JavacProcessingEnvironment) processingEnv).getSpecifiedPackages();
    String jarName = processingEnv.getOptions().get("com.sun.tools.javac.sym.Jar");
    if (jarName == null)
      throw new RuntimeException("Must use -Acom.sun.tools.javac.sym.Jar=LOCATION_OF_JAR");
    String destName = processingEnv.getOptions().get("com.sun.tools.javac.sym.Dest");
    if (destName == null)
      throw new RuntimeException("Must use -Acom.sun.tools.javac.sym.Dest=LOCATION_OF_JAR");

    for (PackageSymbol psym : packages) {
      String name = psym.getQualifiedName().toString();
      legacyProprietary.remove(name);
      documented.add(name);
    }

    JavaCompiler tool = ToolProvider.getSystemJavaCompiler();
    StandardJavaFileManager fm = tool.getStandardFileManager(null, null, null);
    Location jarLocation = StandardLocation.locationFor(jarName);
    File jarFile = new File(jarName);
    fm.setLocation(jarLocation, List.of(jarFile));
    fm.setLocation(StandardLocation.CLASS_PATH, List.<File>nil());
    fm.setLocation(StandardLocation.SOURCE_PATH, List.<File>nil());
    {
      ArrayList<File> bootClassPath = new ArrayList<File>();
      bootClassPath.add(jarFile);
      for (File path : fm.getLocation(StandardLocation.PLATFORM_CLASS_PATH)) {
        if (!new File(path.getName()).equals(new File("rt.jar"))) bootClassPath.add(path);
      }
      System.err.println("Using boot class path = " + bootClassPath);
      fm.setLocation(StandardLocation.PLATFORM_CLASS_PATH, bootClassPath);
    }
    // System.out.println(fm.getLocation(StandardLocation.PLATFORM_CLASS_PATH));
    File destDir = new File(destName);
    if (!destDir.exists())
      if (!destDir.mkdirs()) throw new RuntimeException("Could not create " + destDir);
    fm.setLocation(StandardLocation.CLASS_OUTPUT, List.of(destDir));
    Set<String> hiddenPackages = new HashSet<String>();
    Set<String> crisp = new HashSet<String>();
    List<String> options = List.of("-XDdev");
    // options = options.prepend("-doe");
    // options = options.prepend("-verbose");
    JavacTaskImpl task = (JavacTaskImpl) tool.getTask(null, fm, null, options, null, null);
    com.sun.tools.javac.main.JavaCompiler compiler =
        com.sun.tools.javac.main.JavaCompiler.instance(task.getContext());
    ClassReader reader = ClassReader.instance(task.getContext());
    ClassWriter writer = ClassWriter.instance(task.getContext());
    Symtab syms = Symtab.instance(task.getContext());
    Attribute.Compound proprietary =
        new Attribute.Compound(
            syms.proprietaryType, List.<Pair<Symbol.MethodSymbol, Attribute>>nil());

    Type.moreInfo = true;
    Pool pool = new Pool();
    for (JavaFileObject file : fm.list(jarLocation, "", EnumSet.of(CLASS), true)) {
      String className = fm.inferBinaryName(jarLocation, file);
      int index = className.lastIndexOf('.');
      String pckName = index == -1 ? "" : className.substring(0, index);
      boolean addLegacyAnnotation = false;
      if (documented.contains(pckName)) {
        if (!legacy.contains(pckName)) crisp.add(pckName);
        // System.out.println("Documented: " + className);
      } else if (legacyProprietary.contains(pckName)) {
        addLegacyAnnotation = true;
        // System.out.println("Legacy proprietary: " + className);
      } else {
        // System.out.println("Hidden " + className);
        hiddenPackages.add(pckName);
        continue;
      }
      TypeSymbol sym = (TypeSymbol) compiler.resolveIdent(className);
      if (sym.kind != Kinds.TYP) {
        if (className.indexOf('$') < 0) {
          System.err.println("Ignoring (other) " + className + " : " + sym);
          System.err.println("   " + sym.getClass().getSimpleName() + " " + sym.type);
        }
        continue;
      }
      sym.complete();
      if (sym.getEnclosingElement().getKind() != ElementKind.PACKAGE) {
        System.err.println("Ignoring (bad) " + sym.getQualifiedName());
        continue;
      }
      ClassSymbol cs = (ClassSymbol) sym;
      if (addLegacyAnnotation) {
        cs.attributes_field =
            (cs.attributes_field == null)
                ? List.of(proprietary)
                : cs.attributes_field.prepend(proprietary);
      }
      writeClass(pool, cs, writer);
    }

    if (false) {
      for (String pckName : crisp) System.out.println("Crisp: " + pckName);
      for (String pckName : hiddenPackages) System.out.println("Hidden: " + pckName);
      for (String pckName : legacyProprietary) System.out.println("Legacy proprietary: " + pckName);
      for (String pckName : documented) System.out.println("Documented: " + pckName);
    }
  }