Search in sources :

Example 1 with ClassSymbol

use of com.sun.tools.javac.code.Symbol.ClassSymbol in project lombok by rzwitserloot.

the class HandleWither method createWitherForField.

public void createWitherForField(AccessLevel level, JavacNode fieldNode, JavacNode source, boolean strictMode, List<JCAnnotation> onMethod, List<JCAnnotation> onParam) {
    JavacNode typeNode = fieldNode.up();
    boolean makeAbstract = typeNode != null && typeNode.getKind() == Kind.TYPE && (((JCClassDecl) typeNode.get()).mods.flags & Flags.ABSTRACT) != 0;
    if (fieldNode.getKind() != Kind.FIELD) {
        fieldNode.addError("@Wither is only supported on a class or a field.");
        return;
    }
    JCVariableDecl fieldDecl = (JCVariableDecl) fieldNode.get();
    String methodName = toWitherName(fieldNode);
    if (methodName == null) {
        fieldNode.addWarning("Not generating wither for this field: It does not fit your @Accessors prefix list.");
        return;
    }
    if ((fieldDecl.mods.flags & Flags.STATIC) != 0) {
        if (strictMode) {
            fieldNode.addWarning("Not generating wither for this field: Withers cannot be generated for static fields.");
        }
        return;
    }
    if ((fieldDecl.mods.flags & Flags.FINAL) != 0 && fieldDecl.init != null) {
        if (strictMode) {
            fieldNode.addWarning("Not generating wither for this field: Withers cannot be generated for final, initialized fields.");
        }
        return;
    }
    if (fieldDecl.name.toString().startsWith("$")) {
        if (strictMode) {
            fieldNode.addWarning("Not generating wither for this field: Withers cannot be generated for fields starting with $.");
        }
        return;
    }
    for (String altName : toAllWitherNames(fieldNode)) {
        switch(methodExists(altName, fieldNode, false, 1)) {
            case EXISTS_BY_LOMBOK:
                return;
            case EXISTS_BY_USER:
                if (strictMode) {
                    String altNameExpl = "";
                    if (!altName.equals(methodName))
                        altNameExpl = String.format(" (%s)", altName);
                    fieldNode.addWarning(String.format("Not generating %s(): A method with that name already exists%s", methodName, altNameExpl));
                }
                return;
            default:
            case NOT_EXISTS:
        }
    }
    long access = toJavacModifier(level);
    JCMethodDecl createdWither = createWither(access, fieldNode, fieldNode.getTreeMaker(), source, onMethod, onParam, makeAbstract);
    ClassSymbol sym = ((JCClassDecl) fieldNode.up().get()).sym;
    Type returnType = sym == null ? null : sym.type;
    injectMethod(typeNode, createdWither, List.<Type>of(getMirrorForFieldType(fieldNode)), returnType);
}
Also used : JCClassDecl(com.sun.tools.javac.tree.JCTree.JCClassDecl) Type(com.sun.tools.javac.code.Type) JCMethodDecl(com.sun.tools.javac.tree.JCTree.JCMethodDecl) JavacNode(lombok.javac.JavacNode) ClassSymbol(com.sun.tools.javac.code.Symbol.ClassSymbol) JCVariableDecl(com.sun.tools.javac.tree.JCTree.JCVariableDecl)

Example 2 with ClassSymbol

use of com.sun.tools.javac.code.Symbol.ClassSymbol in project bazel by bazelbuild.

the class ImplicitDependencyExtractor method accumulate.

/**
   * Collects the implicit dependencies of the given set of ClassSymbol roots. As we're interested
   * in differentiating between symbols that were just resolved vs. symbols that were fully
   * completed by the compiler, we start the analysis by finding all the implicit dependencies
   * reachable from the given set of roots. For completeness, we then walk the symbol table
   * associated with the given context and collect the jar files of the remaining class symbols
   * found there.
   *
   * @param context compilation context
   * @param roots root classes in the implicit dependency collection
   */
public void accumulate(Context context, Set<ClassSymbol> roots) {
    Symtab symtab = Symtab.instance(context);
    if (symtab.classes == null) {
        return;
    }
    // Collect transitive references for root types
    for (ClassSymbol root : roots) {
        root.type.accept(typeVisitor, null);
    }
    Set<String> platformJars = getPlatformJars(fileManager);
    // Collect all other partially resolved types
    for (ClassSymbol cs : symtab.classes.values()) {
        // When recording we want to differentiate between jar references through completed symbols
        // and incomplete symbols
        boolean completed = cs.isCompleted();
        if (cs.classfile != null) {
            collectJarOf(cs.classfile, platformJars, completed);
        } else if (cs.sourcefile != null) {
            collectJarOf(cs.sourcefile, platformJars, completed);
        }
    }
}
Also used : Symtab(com.sun.tools.javac.code.Symtab) ClassSymbol(com.sun.tools.javac.code.Symbol.ClassSymbol)

Example 3 with ClassSymbol

use of com.sun.tools.javac.code.Symbol.ClassSymbol in project error-prone by google.

the class EqualsIncompatibleType method matchMethodInvocation.

@Override
public Description matchMethodInvocation(MethodInvocationTree invocationTree, final VisitorState state) {
    if (!STATIC_EQUALS_INVOCATION_MATCHER.matches(invocationTree, state) && !INSTANCE_EQUALS_INVOCATION_MATCHER.matches(invocationTree, state)) {
        return Description.NO_MATCH;
    }
    // This is the type of the object on which the java.lang.Object.equals() method
    // is called, either directly or indirectly via a static utility method. In the latter,
    // it is the type of the first argument to the static method.
    Type receiverType;
    // This is the type of the argument to the java.lang.Object.equals() method.
    // In case a static utility method is used, it is the type of the second argument
    // to this method.
    Type argumentType;
    if (STATIC_EQUALS_INVOCATION_MATCHER.matches(invocationTree, state)) {
        receiverType = ASTHelpers.getType(invocationTree.getArguments().get(0));
        argumentType = ASTHelpers.getType(invocationTree.getArguments().get(1));
    } else {
        receiverType = ASTHelpers.getReceiverType(invocationTree);
        argumentType = ASTHelpers.getType(invocationTree.getArguments().get(0));
    }
    if (receiverType == null || argumentType == null) {
        return Description.NO_MATCH;
    }
    // 1.7: java.lang.Object can be cast to primitives (implicitly through the boxed primitive type)
    if (ASTHelpers.isCastable(argumentType, receiverType, state)) {
        return Description.NO_MATCH;
    }
    // Otherwise, we explore the superclasses of the receiver type as well as the interfaces it
    // implements and we collect all overrides of java.lang.Object.equals(). If one of those
    // overrides is inherited by the argument, then we don't flag the equality test.
    final Types types = state.getTypes();
    Predicate<MethodSymbol> equalsPredicate = new Predicate<MethodSymbol>() {

        @Override
        public boolean apply(MethodSymbol methodSymbol) {
            return !methodSymbol.isStatic() && ((methodSymbol.flags() & Flags.SYNTHETIC) == 0) && types.isSameType(methodSymbol.getReturnType(), state.getSymtab().booleanType) && methodSymbol.getParameters().size() == 1 && types.isSameType(methodSymbol.getParameters().get(0).type, state.getSymtab().objectType);
        }
    };
    Name equalsName = state.getName("equals");
    Set<MethodSymbol> overridesOfEquals = ASTHelpers.findMatchingMethods(equalsName, equalsPredicate, receiverType, types);
    ClassSymbol argumentClass = (ClassSymbol) argumentType.tsym;
    for (MethodSymbol method : overridesOfEquals) {
        ClassSymbol methodClass = method.enclClass();
        if (argumentClass.isSubClass(methodClass, types) && !methodClass.equals(state.getSymtab().objectType.tsym) && !methodClass.equals(state.getSymtab().enumSym)) {
            // with the receiver that implements an override of java.lang.Object.equals().
            return Description.NO_MATCH;
        }
    }
    // assertFalse(objOfReceiverType.equals(objOfArgumentType))
    if (ASSERT_FALSE_MATCHER.matches(state.getPath().getParentPath().getLeaf(), state)) {
        return Description.NO_MATCH;
    }
    // When we reach this point, we know that the two following facts hold:
    // (1) The types of the receiver and the argument to the eventual invocation of
    //     java.lang.Object.equals() are incompatible.
    // (2) No common superclass (other than java.lang.Object) or interface of the receiver and the
    //     argument defines an override of java.lang.Object.equals().
    // This equality test almost certainly evaluates to false, which is very unlikely to be the
    // programmer's intent. Hence, this is reported as an error. There is no sensible fix to suggest
    // in this situation.
    Description.Builder description = buildDescription(invocationTree);
    description.setMessage("Calling " + ASTHelpers.getSymbol(invocationTree).getSimpleName() + " on incompatible types " + receiverType + " and " + argumentType);
    return description.build();
}
Also used : Types(com.sun.tools.javac.code.Types) Matchers.toType(com.google.errorprone.matchers.Matchers.toType) Matchers.isSameType(com.google.errorprone.matchers.Matchers.isSameType) Type(com.sun.tools.javac.code.Type) Description(com.google.errorprone.matchers.Description) MethodSymbol(com.sun.tools.javac.code.Symbol.MethodSymbol) ClassSymbol(com.sun.tools.javac.code.Symbol.ClassSymbol) Predicate(com.google.common.base.Predicate) Name(com.sun.tools.javac.util.Name)

Example 4 with ClassSymbol

use of com.sun.tools.javac.code.Symbol.ClassSymbol in project error-prone by google.

the class AmbiguousMethodReference method matchClass.

@Override
public Description matchClass(ClassTree tree, VisitorState state) {
    ClassSymbol origin = getSymbol(tree);
    Types types = state.getTypes();
    Iterable<Symbol> members = types.membersClosure(getType(tree), /*skipInterface=*/
    false).getSymbols();
    // collect declared and inherited methods, grouped by reference descriptor
    Map<String, List<MethodSymbol>> methods = stream(members.spliterator(), false).filter(MethodSymbol.class::isInstance).map(MethodSymbol.class::cast).filter(m -> m.isConstructor() || m.owner.equals(origin)).collect(groupingBy(m -> methodReferenceDescriptor(types, m), toCollection(ArrayList::new)));
    // look for groups of ambiguous method references
    for (Tree member : tree.getMembers()) {
        if (!(member instanceof MethodTree)) {
            continue;
        }
        MethodSymbol msym = getSymbol((MethodTree) member);
        if (isSuppressed(msym)) {
            continue;
        }
        List<MethodSymbol> clash = methods.remove(methodReferenceDescriptor(types, msym));
        if (clash == null) {
            continue;
        }
        clash.remove(msym);
        // ignore overridden inherited methods and hidden interface methods
        clash.removeIf(m -> types.isSubSignature(msym.type, m.type));
        if (clash.isEmpty()) {
            continue;
        }
        String message = String.format("This method's reference is ambiguous, its name and functional interface type" + " are the same as: %s", clash.stream().map(m -> Signatures.prettyMethodSignature(origin, m)).collect(joining(", ")));
        state.reportMatch(buildDescription(member).setMessage(message).build());
    }
    return NO_MATCH;
}
Also used : MethodSymbol(com.sun.tools.javac.code.Symbol.MethodSymbol) ClassTreeMatcher(com.google.errorprone.bugpatterns.BugChecker.ClassTreeMatcher) MethodTree(com.sun.source.tree.MethodTree) Collectors.groupingBy(java.util.stream.Collectors.groupingBy) ASTHelpers.getSymbol(com.google.errorprone.util.ASTHelpers.getSymbol) Symbol(com.sun.tools.javac.code.Symbol) NO_MATCH(com.google.errorprone.matchers.Description.NO_MATCH) ASTHelpers.getType(com.google.errorprone.util.ASTHelpers.getType) ClassSymbol(com.sun.tools.javac.code.Symbol.ClassSymbol) Collectors.joining(java.util.stream.Collectors.joining) ArrayList(java.util.ArrayList) Collectors.toCollection(java.util.stream.Collectors.toCollection) VisitorState(com.google.errorprone.VisitorState) List(java.util.List) Types(com.sun.tools.javac.code.Types) StreamSupport.stream(java.util.stream.StreamSupport.stream) Signatures(com.google.errorprone.util.Signatures) Description(com.google.errorprone.matchers.Description) Map(java.util.Map) BugPattern(com.google.errorprone.BugPattern) WARNING(com.google.errorprone.BugPattern.SeverityLevel.WARNING) JDK(com.google.errorprone.BugPattern.Category.JDK) Tree(com.sun.source.tree.Tree) ClassTree(com.sun.source.tree.ClassTree) Types(com.sun.tools.javac.code.Types) MethodTree(com.sun.source.tree.MethodTree) ClassSymbol(com.sun.tools.javac.code.Symbol.ClassSymbol) MethodSymbol(com.sun.tools.javac.code.Symbol.MethodSymbol) ASTHelpers.getSymbol(com.google.errorprone.util.ASTHelpers.getSymbol) Symbol(com.sun.tools.javac.code.Symbol) ClassSymbol(com.sun.tools.javac.code.Symbol.ClassSymbol) ArrayList(java.util.ArrayList) MethodSymbol(com.sun.tools.javac.code.Symbol.MethodSymbol) MethodTree(com.sun.source.tree.MethodTree) Tree(com.sun.source.tree.Tree) ClassTree(com.sun.source.tree.ClassTree) ArrayList(java.util.ArrayList) List(java.util.List)

Example 5 with ClassSymbol

use of com.sun.tools.javac.code.Symbol.ClassSymbol in project error-prone by google.

the class FindIdentifiers method isVisible.

private static boolean isVisible(VarSymbol var, final TreePath path) {
    switch(var.getKind()) {
        case ENUM_CONSTANT:
        case FIELD:
            // TODO(eaftan): Switch collector to ImmutableList.toImmutableList() when released
            List<ClassSymbol> enclosingClasses = StreamSupport.stream(path.spliterator(), false).filter(tree -> tree instanceof ClassTree).map(ClassTree.class::cast).map(ASTHelpers::getSymbol).collect(Collectors.toCollection(ArrayList::new));
            if (!var.isStatic()) {
                // Instance fields are not visible if we are in a static context...
                if (inStaticContext(path)) {
                    return false;
                }
                // the enclosing static nested class (JLS 8.5.1).
                if (lowerThan(path, (curr, unused) -> curr instanceof ClassTree && ASTHelpers.getSymbol((ClassTree) curr).isStatic(), (curr, unused) -> curr instanceof ClassTree && ASTHelpers.getSymbol((ClassTree) curr).equals(var.owner))) {
                    return false;
                }
            }
            // fields (JLS 6.6.1).
            if (enclosingClasses.contains(ASTHelpers.enclosingClass(var))) {
                return true;
            }
            PackageSymbol enclosingPackage = ((JCCompilationUnit) path.getCompilationUnit()).packge;
            Set<Modifier> modifiers = var.getModifiers();
            // (JLS 6.6.1).
            if (Objects.equals(enclosingPackage, ASTHelpers.enclosingPackage(var))) {
                return !modifiers.contains(Modifier.PRIVATE);
            }
            // in the enclosing class or a superclass).
            return modifiers.contains(Modifier.PUBLIC) || modifiers.contains(Modifier.PROTECTED);
        case PARAMETER:
        case LOCAL_VARIABLE:
            // final or effectively final (JLS 8.1.3).
            if (lowerThan(path, (curr, parent) -> curr.getKind() == Kind.LAMBDA_EXPRESSION || (curr.getKind() == Kind.NEW_CLASS && ((NewClassTree) curr).getClassBody() != null) || (curr.getKind() == Kind.CLASS && parent.getKind() == Kind.BLOCK), (curr, unused) -> Objects.equals(var.owner, ASTHelpers.getSymbol(curr)))) {
                if ((var.flags() & (Flags.FINAL | Flags.EFFECTIVELY_FINAL)) == 0) {
                    return false;
                }
            }
            return true;
        case EXCEPTION_PARAMETER:
        case RESOURCE_VARIABLE:
            return true;
        default:
            throw new IllegalArgumentException("Unexpected variable type: " + var.getKind());
    }
}
Also used : MethodSymbol(com.sun.tools.javac.code.Symbol.MethodSymbol) ClassType(com.sun.tools.javac.code.Type.ClassType) Modifier(javax.lang.model.element.Modifier) ClassSymbol(com.sun.tools.javac.code.Symbol.ClassSymbol) MethodInvocationTree(com.sun.source.tree.MethodInvocationTree) IdentifierTree(com.sun.source.tree.IdentifierTree) CatchTree(com.sun.source.tree.CatchTree) ForLoopTree(com.sun.source.tree.ForLoopTree) Method(java.lang.reflect.Method) TypeSymbol(com.sun.tools.javac.code.Symbol.TypeSymbol) TreePath(com.sun.source.util.TreePath) ImmutableSet(com.google.common.collect.ImmutableSet) Symbol(com.sun.tools.javac.code.Symbol) Set(java.util.Set) MemberSelectTree(com.sun.source.tree.MemberSelectTree) Env(com.sun.tools.javac.comp.Env) CompilationUnitTree(com.sun.source.tree.CompilationUnitTree) Collectors(java.util.stream.Collectors) Sets(com.google.common.collect.Sets) JCCompilationUnit(com.sun.tools.javac.tree.JCTree.JCCompilationUnit) TreeScanner(com.sun.source.util.TreeScanner) Objects(java.util.Objects) List(java.util.List) WriteableScope(com.sun.tools.javac.code.Scope.WriteableScope) JCMethodDecl(com.sun.tools.javac.tree.JCTree.JCMethodDecl) PackageSymbol(com.sun.tools.javac.code.Symbol.PackageSymbol) BlockTree(com.sun.source.tree.BlockTree) StatementTree(com.sun.source.tree.StatementTree) EnhancedForLoopTree(com.sun.source.tree.EnhancedForLoopTree) Flags(com.sun.tools.javac.code.Flags) Name(com.sun.tools.javac.util.Name) Scope(com.sun.tools.javac.code.Scope) Type(com.sun.tools.javac.code.Type) MethodTree(com.sun.source.tree.MethodTree) MemberEnter(com.sun.tools.javac.comp.MemberEnter) VariableTree(com.sun.source.tree.VariableTree) AttrContext(com.sun.tools.javac.comp.AttrContext) ArrayList(java.util.ArrayList) VisitorState(com.google.errorprone.VisitorState) BiPredicate(java.util.function.BiPredicate) Kind(com.sun.source.tree.Tree.Kind) ImmutableList(com.google.common.collect.ImmutableList) NewClassTree(com.sun.source.tree.NewClassTree) StreamSupport(java.util.stream.StreamSupport) ImportTree(com.sun.source.tree.ImportTree) Tree(com.sun.source.tree.Tree) ClassTree(com.sun.source.tree.ClassTree) LinkedHashSet(java.util.LinkedHashSet) Nullable(javax.annotation.Nullable) VarSymbol(com.sun.tools.javac.code.Symbol.VarSymbol) Enter(com.sun.tools.javac.comp.Enter) ElementKind(javax.lang.model.element.ElementKind) KindSelector(com.sun.tools.javac.code.Kinds.KindSelector) TryTree(com.sun.source.tree.TryTree) Resolve(com.sun.tools.javac.comp.Resolve) JCCompilationUnit(com.sun.tools.javac.tree.JCTree.JCCompilationUnit) PackageSymbol(com.sun.tools.javac.code.Symbol.PackageSymbol) ClassSymbol(com.sun.tools.javac.code.Symbol.ClassSymbol) NewClassTree(com.sun.source.tree.NewClassTree) ClassTree(com.sun.source.tree.ClassTree) NewClassTree(com.sun.source.tree.NewClassTree) Modifier(javax.lang.model.element.Modifier)

Aggregations

ClassSymbol (com.sun.tools.javac.code.Symbol.ClassSymbol)49 Symbol (com.sun.tools.javac.code.Symbol)20 MethodSymbol (com.sun.tools.javac.code.Symbol.MethodSymbol)20 Type (com.sun.tools.javac.code.Type)17 VarSymbol (com.sun.tools.javac.code.Symbol.VarSymbol)10 PackageSymbol (com.sun.tools.javac.code.Symbol.PackageSymbol)9 ClassType (com.sun.tools.javac.code.Type.ClassType)9 ClassTree (com.sun.source.tree.ClassTree)8 TypeSymbol (com.sun.tools.javac.code.Symbol.TypeSymbol)8 MethodTree (com.sun.source.tree.MethodTree)6 Tree (com.sun.source.tree.Tree)6 ArrayType (com.sun.tools.javac.code.Type.ArrayType)5 CompilationUnitTree (com.sun.source.tree.CompilationUnitTree)4 VariableTree (com.sun.source.tree.VariableTree)4 Name (com.sun.tools.javac.util.Name)4 ArrayList (java.util.ArrayList)4 Violation (com.google.errorprone.bugpatterns.threadsafety.ImmutableAnalysis.Violation)3 BlockTree (com.sun.source.tree.BlockTree)3 EnhancedForLoopTree (com.sun.source.tree.EnhancedForLoopTree)3 ForLoopTree (com.sun.source.tree.ForLoopTree)3