Search in sources :

Example 1 with PackageSymbol

use of com.sun.tools.javac.code.Symbol.PackageSymbol in project checker-framework by typetools.

the class FlowExpressionParseUtil method matchPackageNameWithinExpression.

/**
 * Greedily matches the longest substring of {@code expression} to a package (starting from the
 * beginning of the string).
 *
 * @param expression the expression string that may start with a package name
 * @param resolver the {@code Resolver} for the current processing environment
 * @param path the tree path to the local scope
 * @return {@code null} if the expression string did not start with a package name; otherwise a
 *     {@code Pair} containing the {@code PackageSymbol} for the matched package, and the
 *     remaining substring of the expression (always non-null) after the package name
 * @throws FlowExpressionParseException if the entire expression string matches a package name
 */
private static Pair<PackageSymbol, String> matchPackageNameWithinExpression(String expression, Resolver resolver, TreePath path) throws FlowExpressionParseException {
    Pair<String, String> select = parseMemberSelect(expression);
    // groups will not be filled in.
    if (select == null) {
        return null;
    }
    String packageName = select.first;
    String remainingString = select.second, remainingStringIfPackageMatched = remainingString;
    // the result of this method call
    PackageSymbol result = null;
    while (true) {
        // At this point, packageName is one component longer than result, and that extra
        // component appears in remainingString but not in remainingStringIfPackageMatched.  In
        // other words, result and remainingStringIfPackageMatched are consistent, and
        // packageName and remainingString are consistent.  Try to set result to account for the
        // extra component in packageName.
        PackageSymbol longerResult;
        try {
            longerResult = resolver.findPackage(packageName, path);
        } catch (Throwable t) {
            throw constructParserException(expression, "findPackage threw an exception when looking up package " + packageName, t);
        }
        if (longerResult == null) {
            break;
        }
        result = longerResult;
        remainingString = remainingStringIfPackageMatched;
        select = parseMemberSelect(remainingString);
        if (select != null) {
            packageName += "." + select.first;
            remainingStringIfPackageMatched = select.second;
        } else {
            // There are no dots in remainingString, so we are done.
            // Fail if the whole string represents a package, otherwise return.
            PackageSymbol wholeExpressionAsPackage;
            try {
                wholeExpressionAsPackage = resolver.findPackage(expression, path);
            } catch (Throwable t) {
                throw constructParserException(expression, "findPackage threw an exception when looking up package " + expression, t);
            }
            if (wholeExpressionAsPackage != null) {
                // The entire expression matches a package name.
                throw constructParserException(expression, "a flow expression string cannot be just a package name");
            }
            break;
        }
    }
    if (result == null) {
        return null;
    }
    // an exception would have been thrown above if the entire expression is a package name
    assert remainingString != null;
    return Pair.of(result, remainingString);
}
Also used : PackageSymbol(com.sun.tools.javac.code.Symbol.PackageSymbol)

Example 2 with PackageSymbol

use of com.sun.tools.javac.code.Symbol.PackageSymbol 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) Collections(java.util.Collections) 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)

Example 3 with PackageSymbol

use of com.sun.tools.javac.code.Symbol.PackageSymbol in project j2objc by google.

the class TreeConverter method convertPackage.

private PackageDeclaration convertPackage(PackageElement pkg, Trees trees) {
    JCTree node = (JCTree) trees.getTree(pkg);
    PackageDeclaration newNode = new PackageDeclaration().setPackageElement(pkg);
    for (JCTree.JCAnnotation pkgAnnotation : unit.getPackageAnnotations()) {
        newNode.addAnnotation((Annotation) convert(pkgAnnotation));
    }
    if (unit.sourcefile.toUri().getPath().endsWith("package-info.java")) {
        newNode.setJavadoc((Javadoc) getAssociatedJavaDoc(node, pkg));
    }
    return (PackageDeclaration) newNode.setName(convertName((PackageSymbol) pkg, getPosition(node))).setPosition(SourcePosition.NO_POSITION);
}
Also used : PackageSymbol(com.sun.tools.javac.code.Symbol.PackageSymbol) JCTree(com.sun.tools.javac.tree.JCTree) PackageDeclaration(com.google.devtools.j2objc.ast.PackageDeclaration)

Example 4 with PackageSymbol

use of com.sun.tools.javac.code.Symbol.PackageSymbol in project checker-framework by typetools.

the class FlowExpressionParseUtil method matchPackageAndClassNameWithinExpression.

/**
 * Matches a substring of {@code expression} to a package and class name (starting from the
 * beginning of the string).
 *
 * @param expression the expression string that may start with a package and class name
 * @param resolver the {@code Resolver} for the current processing environment
 * @param path the tree path to the local scope
 * @return {@code null} if the expression string did not start with a package name; otherwise a
 *     {@code Pair} containing the {@code ClassName} for the matched class, and the remaining
 *     substring of the expression (possibly null) after the package and class name.
 * @throws FlowExpressionParseException if the entire expression string matches a package name
 *     (but no class name), or if a package name was matched but the class could not be found
 *     within the package (e.g., {@code "myExistingPackage.myNonExistentClass"}).
 */
private static Pair<ClassName, String> matchPackageAndClassNameWithinExpression(String expression, Resolver resolver, TreePath path) throws FlowExpressionParseException {
    Pair<PackageSymbol, String> packageSymbolAndRemainingString = matchPackageNameWithinExpression(expression, resolver, path);
    if (packageSymbolAndRemainingString == null) {
        return null;
    }
    PackageSymbol packageSymbol = packageSymbolAndRemainingString.first;
    String packageRemainingString = packageSymbolAndRemainingString.second;
    Pair<String, String> select = parseMemberSelect(packageRemainingString);
    String classNameString;
    String remainingString;
    if (select != null) {
        classNameString = select.first;
        remainingString = select.second;
    } else {
        classNameString = packageRemainingString;
        remainingString = null;
    }
    ClassSymbol classSymbol;
    try {
        classSymbol = resolver.findClassInPackage(classNameString, packageSymbol, path);
    } catch (Throwable t) {
        throw constructParserException(expression, " findClassInPackage threw an exception when looking up class " + classNameString + " in package " + packageSymbol.toString(), t);
    }
    if (classSymbol == null) {
        throw constructParserException(expression, "classSymbol==null when looking up class " + classNameString + " in package " + packageSymbol.toString());
    }
    TypeMirror classType = ElementUtils.getType(classSymbol);
    if (classType == null) {
        throw constructParserException(expression, "classType==null when looking for class symbol " + classSymbol);
    }
    return Pair.of(new ClassName(classType), remainingString);
}
Also used : PackageSymbol(com.sun.tools.javac.code.Symbol.PackageSymbol) TypeMirror(javax.lang.model.type.TypeMirror) ClassSymbol(com.sun.tools.javac.code.Symbol.ClassSymbol) ClassName(org.checkerframework.dataflow.analysis.FlowExpressions.ClassName)

Example 5 with PackageSymbol

use of com.sun.tools.javac.code.Symbol.PackageSymbol in project checker-framework by typetools.

the class Resolver method findPackage.

/**
 * Finds the package with name {@code name}.
 *
 * @param name the name of the package
 * @param path the tree path to the local scope
 * @return the {@code PackageSymbol} for the package if it is found, {@code null} otherwise
 */
@Nullable
public PackageSymbol findPackage(String name, TreePath path) {
    Log.DiagnosticHandler discardDiagnosticHandler = new Log.DiscardDiagnosticHandler(log);
    try {
        Env<AttrContext> env = getEnvForPath(path);
        Element res = wrapInvocationOnResolveInstance(FIND_IDENT, env, names.fromString(name), Kinds.KindSelector.PCK);
        // a.b.c.MyClass.myStaticField. "exists()" must be called on it to ensure that it exists.
        if (res.getKind() == ElementKind.PACKAGE) {
            PackageSymbol ps = (PackageSymbol) res;
            return ps.exists() ? ps : null;
        } else {
            return null;
        }
    } finally {
        log.popDiagnosticHandler(discardDiagnosticHandler);
    }
}
Also used : PackageSymbol(com.sun.tools.javac.code.Symbol.PackageSymbol) Log(com.sun.tools.javac.util.Log) VariableElement(javax.lang.model.element.VariableElement) ExecutableElement(javax.lang.model.element.ExecutableElement) Element(javax.lang.model.element.Element) AttrContext(com.sun.tools.javac.comp.AttrContext) Nullable(org.checkerframework.checker.nullness.qual.Nullable)

Aggregations

PackageSymbol (com.sun.tools.javac.code.Symbol.PackageSymbol)9 ClassSymbol (com.sun.tools.javac.code.Symbol.ClassSymbol)5 Symbol (com.sun.tools.javac.code.Symbol)3 VisitorState (com.google.errorprone.VisitorState)2 ClassTree (com.sun.source.tree.ClassTree)2 Tree (com.sun.source.tree.Tree)2 MethodSymbol (com.sun.tools.javac.code.Symbol.MethodSymbol)2 TypeSymbol (com.sun.tools.javac.code.Symbol.TypeSymbol)2 AttrContext (com.sun.tools.javac.comp.AttrContext)2 ImmutableList (com.google.common.collect.ImmutableList)1 ImmutableSet (com.google.common.collect.ImmutableSet)1 Iterables.getFirst (com.google.common.collect.Iterables.getFirst)1 Sets (com.google.common.collect.Sets)1 PackageDeclaration (com.google.devtools.j2objc.ast.PackageDeclaration)1 BugPattern (com.google.errorprone.BugPattern)1 JDK (com.google.errorprone.BugPattern.Category.JDK)1 WARNING (com.google.errorprone.BugPattern.SeverityLevel.WARNING)1 StandardTags (com.google.errorprone.BugPattern.StandardTags)1 ClassTreeMatcher (com.google.errorprone.bugpatterns.BugChecker.ClassTreeMatcher)1 TypeParameterTreeMatcher (com.google.errorprone.bugpatterns.BugChecker.TypeParameterTreeMatcher)1