예제 #1
0
  @Override
  public Description matchClass(ClassTree classTree, VisitorState state) {

    TypeSymbol symbol = ASTHelpers.getSymbol(classTree);
    if (symbol.getKind() != ElementKind.CLASS) {
      return Description.NO_MATCH;
    }

    MethodTree equals = null;
    for (Tree member : classTree.getMembers()) {
      if (!(member instanceof MethodTree)) {
        continue;
      }
      MethodTree methodTree = (MethodTree) member;
      if (EQUALS_MATCHER.matches(methodTree, state)) {
        equals = methodTree;
      }
    }
    if (equals == null) {
      return Description.NO_MATCH;
    }

    MethodSymbol hashCodeSym =
        ASTHelpers.resolveExistingMethod(
            state,
            symbol,
            state.getName("hashCode"),
            ImmutableList.<Type>of(),
            ImmutableList.<Type>of());

    if (hashCodeSym.owner.equals(state.getSymtab().objectType.tsym)) {
      return describeMatch(equals);
    }
    return Description.NO_MATCH;
  }
예제 #2
0
 /**
  * Find a method in the enclosing class's superclass that this method overrides.
  *
  * @return A superclass method that is overridden by {@code method}
  */
 public static MethodSymbol findSuperMethod(MethodSymbol method, Types types) {
   TypeSymbol superClass = method.enclClass().getSuperclass().tsym;
   if (superClass == null) {
     return null;
   }
   for (Symbol sym : superClass.members().getSymbols()) {
     if (sym.name.contentEquals(method.name) && method.overrides(sym, superClass, types, true)) {
       return (MethodSymbol) sym;
     }
   }
   return null;
 }
예제 #3
0
 public Env<AttrContext> getClassEnv(TypeSymbol sym) {
   Env<AttrContext> localEnv = getEnv(sym);
   Env<AttrContext> lintEnv = localEnv;
   while (lintEnv.info.lint == null) lintEnv = lintEnv.next;
   localEnv.info.lint = lintEnv.info.lint.augment(sym.attributes_field, sym.flags());
   return localEnv;
 }
 private void addAllFireListenerMethods(
     final JavacType type, final TypeSymbol interfaze, final TypeSymbol superInterfaze) {
   for (Symbol member : superInterfaze.getEnclosedElements()) {
     if (member.getKind() != ElementKind.METHOD) continue;
     handler.addFireListenerMethod(type, interfaze, (MethodSymbol) member);
   }
   ClassType superInterfazeType = (ClassType) superInterfaze.type;
   if (superInterfazeType.interfaces_field != null)
     for (Type iface : superInterfazeType.interfaces_field) {
       addAllFireListenerMethods(type, interfaze, iface.asElement());
     }
 }
예제 #5
0
 /** @return all values of the given enum type, in declaration order. */
 public static LinkedHashSet<String> enumValues(TypeSymbol enumType) {
   if (enumType.getKind() != ElementKind.ENUM) {
     throw new IllegalStateException();
   }
   Scope scope = enumType.members();
   Deque<String> values = new ArrayDeque<>();
   for (Symbol sym : scope.getSymbols()) {
     if (sym instanceof VarSymbol) {
       VarSymbol var = (VarSymbol) sym;
       if ((var.flags() & Flags.ENUM) != 0) {
         /**
          * Javac gives us the members backwards, apparently. It's worth making an effort to
          * preserve declaration order because it's useful for diagnostics (e.g. in {@link
          * MissingCasesInEnumSwitch}).
          */
         values.push(sym.name.toString());
       }
     }
   }
   return new LinkedHashSet<>(values);
 }
예제 #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);
    }
  }