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;
}
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()));
}
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());
}
}
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));
}
}
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);
}
Aggregations