use of com.github.javaparser.symbolsolver.core.resolution.Context in project javaparser by javaparser.
the class LambdaExprContextResolutionTest method solveParameterOfLambdaInVarDecl.
@Test
public void solveParameterOfLambdaInVarDecl() {
CompilationUnit cu = parseSample("Lambda");
com.github.javaparser.ast.body.ClassOrInterfaceDeclaration clazz = Navigator.demandClass(cu, "Agenda");
MethodDeclaration method = Navigator.demandMethod(clazz, "testFunctionalVar");
VariableDeclarator varDecl = Navigator.demandVariableDeclaration(method, "a").get();
LambdaExpr lambdaExpr = (LambdaExpr) varDecl.getInitializer().get();
File src = adaptPath(new File("src/test/resources"));
CombinedTypeSolver combinedTypeSolver = new CombinedTypeSolver();
combinedTypeSolver.add(new ReflectionTypeSolver());
combinedTypeSolver.add(new JavaParserTypeSolver(src));
Context context = new LambdaExprContext(lambdaExpr, combinedTypeSolver);
Optional<Value> ref = context.solveSymbolAsValue("p", typeSolver);
assertTrue(ref.isPresent());
assertEquals("java.lang.String", ref.get().getType().describe());
}
use of com.github.javaparser.symbolsolver.core.resolution.Context in project javaparser by javaparser.
the class TypeExtractor method visit.
@Override
public ResolvedType visit(MethodReferenceExpr node, Boolean solveLambdas) {
if (requireParentNode(node) instanceof MethodCallExpr) {
MethodCallExpr callExpr = (MethodCallExpr) requireParentNode(node);
int pos = JavaParserSymbolDeclaration.getParamPos(node);
SymbolReference<ResolvedMethodDeclaration> refMethod = facade.solve(callExpr, false);
if (!refMethod.isSolved()) {
throw new com.github.javaparser.resolution.UnsolvedSymbolException(requireParentNode(node).toString(), callExpr.getName().getId());
}
logger.finest("getType on method reference expr " + refMethod.getCorrespondingDeclaration().getName());
// logger.finest("Method param " + refMethod.getCorrespondingDeclaration().getParam(pos));
if (solveLambdas) {
MethodUsage usage = facade.solveMethodAsUsage(callExpr);
ResolvedType result = usage.getParamType(pos);
// We need to replace the type variables
Context ctx = JavaParserFactory.getContext(node, typeSolver);
result = solveGenericTypes(result, ctx, typeSolver);
// lambdas
if (FunctionalInterfaceLogic.getFunctionalMethod(result).isPresent()) {
MethodReferenceExpr methodReferenceExpr = node;
ResolvedType actualType = facade.toMethodUsage(methodReferenceExpr).returnType();
ResolvedType formalType = FunctionalInterfaceLogic.getFunctionalMethod(result).get().returnType();
InferenceContext inferenceContext = new InferenceContext(MyObjectProvider.INSTANCE);
inferenceContext.addPair(formalType, actualType);
result = inferenceContext.resolve(inferenceContext.addSingle(result));
}
return result;
}
return refMethod.getCorrespondingDeclaration().getParam(pos).getType();
}
throw new UnsupportedOperationException("The type of a method reference expr depends on the position and its return value");
}
use of com.github.javaparser.symbolsolver.core.resolution.Context in project javaparser by javaparser.
the class TypeExtractor method visit.
@Override
public ResolvedType visit(LambdaExpr node, Boolean solveLambdas) {
if (requireParentNode(node) instanceof MethodCallExpr) {
MethodCallExpr callExpr = (MethodCallExpr) requireParentNode(node);
int pos = JavaParserSymbolDeclaration.getParamPos(node);
SymbolReference<ResolvedMethodDeclaration> refMethod = facade.solve(callExpr);
if (!refMethod.isSolved()) {
throw new com.github.javaparser.resolution.UnsolvedSymbolException(requireParentNode(node).toString(), callExpr.getName().getId());
}
logger.finest("getType on lambda expr " + refMethod.getCorrespondingDeclaration().getName());
if (solveLambdas) {
// The type parameter referred here should be the java.util.stream.Stream.T
ResolvedType result = refMethod.getCorrespondingDeclaration().getParam(pos).getType();
if (callExpr.getScope().isPresent()) {
Expression scope = callExpr.getScope().get();
// If it is a static call we should not try to get the type of the scope
boolean staticCall = false;
if (scope instanceof NameExpr) {
NameExpr nameExpr = (NameExpr) scope;
try {
SymbolReference<ResolvedTypeDeclaration> type = JavaParserFactory.getContext(nameExpr, typeSolver).solveType(nameExpr.getName().getId(), typeSolver);
if (type.isSolved()) {
staticCall = true;
}
} catch (Exception e) {
}
}
if (!staticCall) {
ResolvedType scopeType = facade.getType(scope);
if (scopeType.isReferenceType()) {
result = scopeType.asReferenceType().useThisTypeParametersOnTheGivenType(result);
}
}
}
// We need to replace the type variables
Context ctx = JavaParserFactory.getContext(node, typeSolver);
result = solveGenericTypes(result, ctx, typeSolver);
// We should find out which is the functional method (e.g., apply) and replace the params of the
// solveLambdas with it, to derive so the values. We should also consider the value returned by the
// lambdas
Optional<MethodUsage> functionalMethod = FunctionalInterfaceLogic.getFunctionalMethod(result);
if (functionalMethod.isPresent()) {
LambdaExpr lambdaExpr = node;
InferenceContext lambdaCtx = new InferenceContext(MyObjectProvider.INSTANCE);
InferenceContext funcInterfaceCtx = new InferenceContext(MyObjectProvider.INSTANCE);
// At this point parameterType
// if Function<T=? super Stream.T, ? extends map.R>
// we should replace Stream.T
ResolvedType functionalInterfaceType = ReferenceTypeImpl.undeterminedParameters(functionalMethod.get().getDeclaration().declaringType(), typeSolver);
lambdaCtx.addPair(result, functionalInterfaceType);
ResolvedType actualType;
if (lambdaExpr.getBody() instanceof ExpressionStmt) {
actualType = facade.getType(((ExpressionStmt) lambdaExpr.getBody()).getExpression());
} else if (lambdaExpr.getBody() instanceof BlockStmt) {
BlockStmt blockStmt = (BlockStmt) lambdaExpr.getBody();
// Get all the return statements in the lambda block
List<ReturnStmt> returnStmts = blockStmt.findAll(ReturnStmt.class);
if (returnStmts.size() > 0) {
actualType = returnStmts.stream().map(returnStmt -> returnStmt.getExpression().map(e -> facade.getType(e)).orElse(ResolvedVoidType.INSTANCE)).filter(x -> x != null && !x.isVoid() && !x.isNull()).findFirst().orElse(ResolvedVoidType.INSTANCE);
} else {
return ResolvedVoidType.INSTANCE;
}
} else {
throw new UnsupportedOperationException();
}
ResolvedType formalType = functionalMethod.get().returnType();
// Infer the functional interfaces' return vs actual type
funcInterfaceCtx.addPair(formalType, actualType);
// Substitute to obtain a new type
ResolvedType functionalTypeWithReturn = funcInterfaceCtx.resolve(funcInterfaceCtx.addSingle(functionalInterfaceType));
// we don't need to bother inferring types
if (!(formalType instanceof ResolvedVoidType)) {
lambdaCtx.addPair(result, functionalTypeWithReturn);
result = lambdaCtx.resolve(lambdaCtx.addSingle(result));
}
}
return result;
} else {
return refMethod.getCorrespondingDeclaration().getParam(pos).getType();
}
} else {
throw new UnsupportedOperationException("The type of a lambda expr depends on the position and its return value");
}
}
use of com.github.javaparser.symbolsolver.core.resolution.Context in project javaparser by javaparser.
the class JavaParserFacade method solve.
public SymbolReference<ResolvedAnnotationDeclaration> solve(AnnotationExpr annotationExpr) {
Context context = JavaParserFactory.getContext(annotationExpr, typeSolver);
SymbolReference<ResolvedTypeDeclaration> typeDeclarationSymbolReference = context.solveType(annotationExpr.getNameAsString(), typeSolver);
ResolvedAnnotationDeclaration annotationDeclaration = (ResolvedAnnotationDeclaration) typeDeclarationSymbolReference.getCorrespondingDeclaration();
if (typeDeclarationSymbolReference.isSolved()) {
return SymbolReference.solved(annotationDeclaration);
} else {
return SymbolReference.unsolved(ResolvedAnnotationDeclaration.class);
}
}
use of com.github.javaparser.symbolsolver.core.resolution.Context in project javaparser by javaparser.
the class JavaParserFacade method convertToUsage.
protected ResolvedType convertToUsage(com.github.javaparser.ast.type.Type type, Context context) {
if (context == null) {
throw new NullPointerException("Context should not be null");
}
if (type instanceof ClassOrInterfaceType) {
ClassOrInterfaceType classOrInterfaceType = (ClassOrInterfaceType) type;
String name = qName(classOrInterfaceType);
SymbolReference<ResolvedTypeDeclaration> ref = context.solveType(name, typeSolver);
if (!ref.isSolved()) {
throw new UnsolvedSymbolException(name);
}
ResolvedTypeDeclaration typeDeclaration = ref.getCorrespondingDeclaration();
List<ResolvedType> typeParameters = Collections.emptyList();
if (classOrInterfaceType.getTypeArguments().isPresent()) {
typeParameters = classOrInterfaceType.getTypeArguments().get().stream().map((pt) -> convertToUsage(pt, context)).collect(Collectors.toList());
}
if (typeDeclaration.isTypeParameter()) {
if (typeDeclaration instanceof ResolvedTypeParameterDeclaration) {
return new ResolvedTypeVariable((ResolvedTypeParameterDeclaration) typeDeclaration);
} else {
JavaParserTypeVariableDeclaration javaParserTypeVariableDeclaration = (JavaParserTypeVariableDeclaration) typeDeclaration;
return new ResolvedTypeVariable(javaParserTypeVariableDeclaration.asTypeParameter());
}
} else {
return new ReferenceTypeImpl((ResolvedReferenceTypeDeclaration) typeDeclaration, typeParameters, typeSolver);
}
} else if (type instanceof com.github.javaparser.ast.type.PrimitiveType) {
return ResolvedPrimitiveType.byName(((com.github.javaparser.ast.type.PrimitiveType) type).getType().name());
} else if (type instanceof WildcardType) {
WildcardType wildcardType = (WildcardType) type;
if (wildcardType.getExtendedType().isPresent() && !wildcardType.getSuperType().isPresent()) {
// removed (ReferenceTypeImpl)
return ResolvedWildcard.extendsBound(convertToUsage(wildcardType.getExtendedType().get(), context));
} else if (!wildcardType.getExtendedType().isPresent() && wildcardType.getSuperType().isPresent()) {
// removed (ReferenceTypeImpl)
return ResolvedWildcard.superBound(convertToUsage(wildcardType.getSuperType().get(), context));
} else if (!wildcardType.getExtendedType().isPresent() && !wildcardType.getSuperType().isPresent()) {
return ResolvedWildcard.UNBOUNDED;
} else {
throw new UnsupportedOperationException(wildcardType.toString());
}
} else if (type instanceof com.github.javaparser.ast.type.VoidType) {
return ResolvedVoidType.INSTANCE;
} else if (type instanceof com.github.javaparser.ast.type.ArrayType) {
com.github.javaparser.ast.type.ArrayType jpArrayType = (com.github.javaparser.ast.type.ArrayType) type;
return new ResolvedArrayType(convertToUsage(jpArrayType.getComponentType(), context));
} else if (type instanceof UnionType) {
UnionType unionType = (UnionType) type;
return new ResolvedUnionType(unionType.getElements().stream().map(el -> convertToUsage(el, context)).collect(Collectors.toList()));
} else if (type instanceof VarType) {
Node parent = type.getParentNode().get();
if (!(parent instanceof VariableDeclarator)) {
throw new IllegalStateException("Trying to resolve a `var` which is not in a variable declaration.");
}
final VariableDeclarator variableDeclarator = (VariableDeclarator) parent;
return variableDeclarator.getInitializer().map(Expression::calculateResolvedType).orElseThrow(() -> new IllegalStateException("Cannot resolve `var` which has no initializer."));
} else {
throw new UnsupportedOperationException(type.getClass().getCanonicalName());
}
}
Aggregations