Search in sources :

Example 1 with AbstractTypedTree

use of org.sonar.java.model.AbstractTypedTree in project sonar-java by SonarSource.

the class TypeAndReferenceSolver method resolveAs.

public JavaSymbol resolveAs(Tree tree, int kind, Resolve.Env resolveEnv, boolean associateReference) {
    if (tree.is(Tree.Kind.IDENTIFIER, Tree.Kind.MEMBER_SELECT)) {
        JavaSymbol resolvedSymbol;
        IdentifierTree identifierTree;
        if (tree.is(Tree.Kind.MEMBER_SELECT)) {
            MemberSelectExpressionTree mse = (MemberSelectExpressionTree) tree;
            if (JavaKeyword.CLASS.getValue().equals(mse.identifier().name())) {
                // resolve type of expression xxx.class
                return resolveClassType(tree, resolveEnv, mse);
            }
            identifierTree = mse.identifier();
            List<AnnotationTree> identifierAnnotations = identifierTree.annotations();
            scan(identifierAnnotations);
            completeMetadata((JavaSymbol) identifierTree.symbol(), identifierAnnotations);
            Resolve.Resolution res = getSymbolOfMemberSelectExpression(mse, kind, resolveEnv);
            resolvedSymbol = res.symbol();
            JavaType resolvedType = resolve.resolveTypeSubstitution(res.type(), getType(mse.expression()));
            registerType(identifierTree, resolvedType);
            registerType(tree, resolvedType);
        } else {
            identifierTree = (IdentifierTree) tree;
            Resolve.Resolution resolution = resolve.findIdent(resolveEnv, identifierTree.name(), kind);
            resolvedSymbol = resolution.symbol();
            registerType(tree, resolution.type());
        }
        if (associateReference) {
            associateReference(identifierTree, resolvedSymbol);
        }
        return resolvedSymbol;
    }
    tree.accept(this);
    JavaType type = getType(tree);
    if (tree.is(Tree.Kind.INFERED_TYPE)) {
        type = symbols.deferedType((AbstractTypedTree) tree);
        registerType(tree, type);
    }
    if (type == null) {
        throw new IllegalStateException("Type not resolved " + tree);
    }
    return type.symbol;
}
Also used : MemberSelectExpressionTree(org.sonar.plugins.java.api.tree.MemberSelectExpressionTree) IdentifierTree(org.sonar.plugins.java.api.tree.IdentifierTree) AnnotationTree(org.sonar.plugins.java.api.tree.AnnotationTree) Resolution(org.sonar.java.resolve.Resolve.Resolution) AbstractTypedTree(org.sonar.java.model.AbstractTypedTree)

Example 2 with AbstractTypedTree

use of org.sonar.java.model.AbstractTypedTree in project sonar-java by SonarSource.

the class TypeAndReferenceSolver method visitAnnotation.

@Override
public void visitAnnotation(AnnotationTree tree) {
    if (((AbstractTypedTree) tree.annotationType()).isTypeSet()) {
        // This handle the case where type and its annotation is shared between two variables.
        return;
    }
    resolveAs(tree.annotationType(), JavaSymbol.TYP);
    Arguments arguments = tree.arguments();
    if (arguments.size() > 1 || (!arguments.isEmpty() && arguments.get(0).is(Tree.Kind.ASSIGNMENT))) {
        // resolve by identifying correct identifier in assignment.
        for (ExpressionTree expressionTree : arguments) {
            AssignmentExpressionTree aet = (AssignmentExpressionTree) expressionTree;
            IdentifierTree variable = (IdentifierTree) aet.variable();
            JavaSymbol identInType = resolve.findMethod(semanticModel.getEnv(tree), getType(tree.annotationType()), variable.name(), ImmutableList.<JavaType>of()).symbol();
            associateReference(variable, identInType);
            JavaType type = identInType.type;
            if (type == null) {
                type = Symbols.unknownType;
            }
            registerType(variable, type);
            resolveAs(aet.expression(), JavaSymbol.VAR);
        }
    } else {
        for (ExpressionTree expressionTree : arguments) {
            resolveAs(expressionTree, JavaSymbol.VAR);
        }
    }
    registerType(tree, getType(tree.annotationType()));
}
Also used : Arguments(org.sonar.plugins.java.api.tree.Arguments) TypeArguments(org.sonar.plugins.java.api.tree.TypeArguments) MemberSelectExpressionTree(org.sonar.plugins.java.api.tree.MemberSelectExpressionTree) AssignmentExpressionTree(org.sonar.plugins.java.api.tree.AssignmentExpressionTree) UnaryExpressionTree(org.sonar.plugins.java.api.tree.UnaryExpressionTree) ExpressionTree(org.sonar.plugins.java.api.tree.ExpressionTree) BinaryExpressionTree(org.sonar.plugins.java.api.tree.BinaryExpressionTree) ConditionalExpressionTree(org.sonar.plugins.java.api.tree.ConditionalExpressionTree) ArrayAccessExpressionTree(org.sonar.plugins.java.api.tree.ArrayAccessExpressionTree) LambdaExpressionTree(org.sonar.plugins.java.api.tree.LambdaExpressionTree) AssignmentExpressionTree(org.sonar.plugins.java.api.tree.AssignmentExpressionTree) IdentifierTree(org.sonar.plugins.java.api.tree.IdentifierTree) AbstractTypedTree(org.sonar.java.model.AbstractTypedTree)

Example 3 with AbstractTypedTree

use of org.sonar.java.model.AbstractTypedTree in project sonar-java by SonarSource.

the class TypeAndReferenceSolver method visitMethodInvocation.

@Override
public void visitMethodInvocation(MethodInvocationTree tree) {
    MethodInvocationTreeImpl mit = (MethodInvocationTreeImpl) tree;
    Resolve.Env methodEnv = semanticModel.getEnv(tree);
    if (mit.isTypeSet() && mit.symbol().isMethodSymbol()) {
        TypeSubstitution typeSubstitution = inferedSubstitution(mit);
        List<JavaType> argTypes = getParameterTypes(tree.arguments());
        JavaSymbol.MethodJavaSymbol methodSymbol = (JavaSymbol.MethodJavaSymbol) mit.symbol();
        List<JavaType> formals = methodSymbol.parameterTypes().stream().map(t -> (JavaType) t).collect(Collectors.toList());
        List<JavaType> inferedArgTypes = resolve.resolveTypeSubstitution(formals, typeSubstitution);
        int size = inferedArgTypes.size();
        IntStream.range(0, argTypes.size()).forEach(i -> {
            JavaType arg = argTypes.get(i);
            Type formal = inferedArgTypes.get(Math.min(i, size - 1));
            if (formal != arg) {
                AbstractTypedTree argTree = (AbstractTypedTree) mit.arguments().get(i);
                argTree.setInferedType(formal);
                argTree.accept(this);
            }
        });
        List<JavaType> typeParamTypes = getParameterTypes(tree.typeArguments());
        JavaType resultType = ((MethodJavaType) mit.symbol().type()).resultType;
        // if result type is a type var defined by the method we are solving, use the target type.
        if (resultType.symbol.owner == mit.symbol()) {
            resultType = (JavaType) mit.symbolType();
        }
        inferReturnTypeFromInferedArgs(tree, methodEnv, argTypes, typeParamTypes, resultType, typeSubstitution);
        return;
    }
    scan(tree.arguments());
    scan(tree.typeArguments());
    List<JavaType> argTypes = getParameterTypes(tree.arguments());
    List<JavaType> typeParamTypes = getParameterTypes(tree.typeArguments());
    Resolve.Resolution resolution = resolveMethodSymbol(tree.methodSelect(), methodEnv, argTypes, typeParamTypes);
    JavaSymbol symbol;
    JavaType returnType;
    if (resolution == null) {
        returnType = symbols.deferedType(mit);
        symbol = Symbols.unknownSymbol;
    } else {
        symbol = resolution.symbol();
        returnType = resolution.type();
        if (symbol.isMethodSymbol()) {
            MethodJavaType methodType = (MethodJavaType) resolution.type();
            returnType = methodType.resultType;
        }
    }
    mit.setSymbol(symbol);
    if (returnType != null && returnType.isTagged(JavaType.DEFERRED)) {
        ((DeferredType) returnType).setTree(mit);
    }
    registerType(tree, returnType);
    if (resolution != null) {
        inferArgumentTypes(argTypes, resolution);
        inferReturnTypeFromInferedArgs(tree, methodEnv, argTypes, typeParamTypes, returnType, new TypeSubstitution());
    }
}
Also used : AbstractTypedTree(org.sonar.java.model.AbstractTypedTree) BaseTreeVisitor(org.sonar.plugins.java.api.tree.BaseTreeVisitor) Resolution(org.sonar.java.resolve.Resolve.Resolution) UnionTypeTree(org.sonar.plugins.java.api.tree.UnionTypeTree) MemberSelectExpressionTree(org.sonar.plugins.java.api.tree.MemberSelectExpressionTree) Map(java.util.Map) ArrayTypeTree(org.sonar.plugins.java.api.tree.ArrayTypeTree) Arguments(org.sonar.plugins.java.api.tree.Arguments) TypeTree(org.sonar.plugins.java.api.tree.TypeTree) ImmutableSet(com.google.common.collect.ImmutableSet) NewArrayTree(org.sonar.plugins.java.api.tree.NewArrayTree) ContinueStatementTree(org.sonar.plugins.java.api.tree.ContinueStatementTree) Collection(java.util.Collection) ExpressionStatementTree(org.sonar.plugins.java.api.tree.ExpressionStatementTree) JavaKeyword(org.sonar.java.ast.api.JavaKeyword) ParameterizedTypeTree(org.sonar.plugins.java.api.tree.ParameterizedTypeTree) TypeCastTree(org.sonar.plugins.java.api.tree.TypeCastTree) Collectors(java.util.stream.Collectors) NewClassTree(org.sonar.plugins.java.api.tree.NewClassTree) List(java.util.List) AssignmentExpressionTree(org.sonar.plugins.java.api.tree.AssignmentExpressionTree) ClassTree(org.sonar.plugins.java.api.tree.ClassTree) VariableTreeImpl(org.sonar.java.model.declaration.VariableTreeImpl) Optional(java.util.Optional) UnaryExpressionTree(org.sonar.plugins.java.api.tree.UnaryExpressionTree) NewClassTreeImpl(org.sonar.java.model.expression.NewClassTreeImpl) IdentifierTree(org.sonar.plugins.java.api.tree.IdentifierTree) Symbol(org.sonar.plugins.java.api.semantic.Symbol) IntStream(java.util.stream.IntStream) ParenthesizedTreeImpl(org.sonar.java.model.expression.ParenthesizedTreeImpl) WildcardTree(org.sonar.plugins.java.api.tree.WildcardTree) TypeArguments(org.sonar.plugins.java.api.tree.TypeArguments) LabeledStatementTree(org.sonar.plugins.java.api.tree.LabeledStatementTree) BreakStatementTree(org.sonar.plugins.java.api.tree.BreakStatementTree) ThrowStatementTree(org.sonar.plugins.java.api.tree.ThrowStatementTree) ExpressionTree(org.sonar.plugins.java.api.tree.ExpressionTree) ArrayList(java.util.ArrayList) ParenthesizedTree(org.sonar.plugins.java.api.tree.ParenthesizedTree) VariableTree(org.sonar.plugins.java.api.tree.VariableTree) ImmutableList(com.google.common.collect.ImmutableList) IdentifierTreeImpl(org.sonar.java.model.expression.IdentifierTreeImpl) ConditionalExpressionTreeImpl(org.sonar.java.model.expression.ConditionalExpressionTreeImpl) ArrayDimensionTree(org.sonar.plugins.java.api.tree.ArrayDimensionTree) LambdaExpressionTreeImpl(org.sonar.java.model.expression.LambdaExpressionTreeImpl) EnumConstantTree(org.sonar.plugins.java.api.tree.EnumConstantTree) MethodReferenceTree(org.sonar.plugins.java.api.tree.MethodReferenceTree) Nullable(javax.annotation.Nullable) AnnotationTree(org.sonar.plugins.java.api.tree.AnnotationTree) BinaryExpressionTree(org.sonar.plugins.java.api.tree.BinaryExpressionTree) ReturnStatementTree(org.sonar.plugins.java.api.tree.ReturnStatementTree) LiteralTree(org.sonar.plugins.java.api.tree.LiteralTree) ConditionalExpressionTree(org.sonar.plugins.java.api.tree.ConditionalExpressionTree) ImportTree(org.sonar.plugins.java.api.tree.ImportTree) PrimitiveTypeTree(org.sonar.plugins.java.api.tree.PrimitiveTypeTree) MethodReferenceTreeImpl(org.sonar.java.model.expression.MethodReferenceTreeImpl) MethodInvocationTreeImpl(org.sonar.java.model.expression.MethodInvocationTreeImpl) TypeParameterTree(org.sonar.plugins.java.api.tree.TypeParameterTree) Tree(org.sonar.plugins.java.api.tree.Tree) Type(org.sonar.plugins.java.api.semantic.Type) ArrayAccessExpressionTree(org.sonar.plugins.java.api.tree.ArrayAccessExpressionTree) Maps(com.google.common.collect.Maps) MethodInvocationTree(org.sonar.plugins.java.api.tree.MethodInvocationTree) LambdaExpressionTree(org.sonar.plugins.java.api.tree.LambdaExpressionTree) InstanceOfTree(org.sonar.plugins.java.api.tree.InstanceOfTree) VisibleForTesting(com.google.common.annotations.VisibleForTesting) TypeArgumentListTreeImpl(org.sonar.java.model.expression.TypeArgumentListTreeImpl) CheckForNull(javax.annotation.CheckForNull) MethodTree(org.sonar.plugins.java.api.tree.MethodTree) MethodInvocationTreeImpl(org.sonar.java.model.expression.MethodInvocationTreeImpl) AbstractTypedTree(org.sonar.java.model.AbstractTypedTree) Resolution(org.sonar.java.resolve.Resolve.Resolution) Type(org.sonar.plugins.java.api.semantic.Type)

Example 4 with AbstractTypedTree

use of org.sonar.java.model.AbstractTypedTree in project sonar-java by SonarSource.

the class TypeAndReferenceSolver method visitLambdaExpression.

@Override
public void visitLambdaExpression(LambdaExpressionTree tree) {
    LambdaExpressionTreeImpl lambdaExpressionTree = (LambdaExpressionTreeImpl) tree;
    if (lambdaExpressionTree.isTypeSet()) {
        // type should be tied to a SAM interface
        JavaType lambdaType = (JavaType) lambdaExpressionTree.symbolType();
        List<JavaType> samMethodArgs = resolve.findSamMethodArgs(lambdaType);
        for (int i = 0; i < samMethodArgs.size(); i++) {
            VariableTree param = lambdaExpressionTree.parameters().get(i);
            if (param.type().is(Tree.Kind.INFERED_TYPE)) {
                JavaType inferedType = samMethodArgs.get(i);
                if (inferedType.isTagged(JavaType.WILDCARD)) {
                    // JLS8 18.5.3
                    inferedType = ((WildCardType) inferedType).bound;
                }
                ((AbstractTypedTree) param.type()).setInferedType(inferedType);
                ((JavaSymbol.VariableJavaSymbol) param.symbol()).type = inferedType;
            }
        }
        super.visitLambdaExpression(tree);
        if (lambdaType.isUnknown() || lambdaType.isTagged(JavaType.DEFERRED)) {
            return;
        }
        refineLambdaType(lambdaExpressionTree, lambdaType);
    } else {
        registerType(tree, symbols.deferedType(lambdaExpressionTree));
    }
}
Also used : LambdaExpressionTreeImpl(org.sonar.java.model.expression.LambdaExpressionTreeImpl) VariableTree(org.sonar.plugins.java.api.tree.VariableTree) AbstractTypedTree(org.sonar.java.model.AbstractTypedTree)

Example 5 with AbstractTypedTree

use of org.sonar.java.model.AbstractTypedTree in project sonar-java by SonarSource.

the class TypeAndReferenceSolver method setInferedType.

private void setInferedType(Type infered, DeferredType deferredType) {
    AbstractTypedTree inferedExpression = deferredType.tree();
    Type newType = infered;
    if (inferedExpression.is(Tree.Kind.NEW_CLASS)) {
        Type newClassType = ((NewClassTree) inferedExpression).identifier().symbolType();
        if (((JavaType) newClassType).isParameterized()) {
            newType = resolve.resolveTypeSubstitutionWithDiamondOperator((ParametrizedTypeJavaType) newClassType, (JavaType) infered);
        }
    }
    inferedExpression.setInferedType(newType);
    inferedExpression.accept(this);
}
Also used : Type(org.sonar.plugins.java.api.semantic.Type) AbstractTypedTree(org.sonar.java.model.AbstractTypedTree)

Aggregations

AbstractTypedTree (org.sonar.java.model.AbstractTypedTree)6 IdentifierTree (org.sonar.plugins.java.api.tree.IdentifierTree)4 MemberSelectExpressionTree (org.sonar.plugins.java.api.tree.MemberSelectExpressionTree)4 ConditionalExpressionTree (org.sonar.plugins.java.api.tree.ConditionalExpressionTree)3 LambdaExpressionTree (org.sonar.plugins.java.api.tree.LambdaExpressionTree)3 LambdaExpressionTreeImpl (org.sonar.java.model.expression.LambdaExpressionTreeImpl)2 Resolution (org.sonar.java.resolve.Resolve.Resolution)2 Type (org.sonar.plugins.java.api.semantic.Type)2 AnnotationTree (org.sonar.plugins.java.api.tree.AnnotationTree)2 Arguments (org.sonar.plugins.java.api.tree.Arguments)2 ArrayAccessExpressionTree (org.sonar.plugins.java.api.tree.ArrayAccessExpressionTree)2 AssignmentExpressionTree (org.sonar.plugins.java.api.tree.AssignmentExpressionTree)2 MethodReferenceTree (org.sonar.plugins.java.api.tree.MethodReferenceTree)2 Tree (org.sonar.plugins.java.api.tree.Tree)2 VariableTree (org.sonar.plugins.java.api.tree.VariableTree)2 VisibleForTesting (com.google.common.annotations.VisibleForTesting)1 ImmutableList (com.google.common.collect.ImmutableList)1 ImmutableSet (com.google.common.collect.ImmutableSet)1 Maps (com.google.common.collect.Maps)1 ArrayList (java.util.ArrayList)1