use of com.github.javaparser.resolution.types.ResolvedType in project javaparser by javaparser.
the class MethodUsage method replaceTypeParameter.
public MethodUsage replaceTypeParameter(ResolvedTypeParameterDeclaration typeParameter, ResolvedType type) {
if (type == null) {
throw new IllegalArgumentException();
}
// TODO if the method declaration has a type param with that name ignore this call
MethodUsage res = new MethodUsage(declaration, paramTypes, returnType, exceptionTypes, typeParametersMap.toBuilder().setValue(typeParameter, type).build());
Map<ResolvedTypeParameterDeclaration, ResolvedType> inferredTypes = new HashMap<>();
for (int i = 0; i < paramTypes.size(); i++) {
ResolvedType originalParamType = paramTypes.get(i);
ResolvedType newParamType = originalParamType.replaceTypeVariables(typeParameter, type, inferredTypes);
res = res.replaceParamType(i, newParamType);
}
for (int i = 0; i < exceptionTypes.size(); i++) {
ResolvedType originalType = exceptionTypes.get(i);
ResolvedType newType = originalType.replaceTypeVariables(typeParameter, type, inferredTypes);
res = res.replaceExceptionType(i, newType);
}
ResolvedType oldReturnType = res.returnType;
ResolvedType newReturnType = oldReturnType.replaceTypeVariables(typeParameter, type, inferredTypes);
res = res.replaceReturnType(newReturnType);
return res;
}
use of com.github.javaparser.resolution.types.ResolvedType 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.resolution.types.ResolvedType 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.resolution.types.ResolvedType in project javaparser by javaparser.
the class AbstractJavaParserContext method findTypeDeclarations.
protected Collection<ResolvedReferenceTypeDeclaration> findTypeDeclarations(Optional<Expression> optScope, TypeSolver typeSolver) {
if (optScope.isPresent()) {
Expression scope = optScope.get();
// consider static methods
if (scope instanceof NameExpr) {
NameExpr scopeAsName = (NameExpr) scope;
SymbolReference<ResolvedTypeDeclaration> symbolReference = this.solveType(scopeAsName.getName().getId(), typeSolver);
if (symbolReference.isSolved() && symbolReference.getCorrespondingDeclaration().isType()) {
return singletonList(symbolReference.getCorrespondingDeclaration().asReferenceType());
}
}
ResolvedType typeOfScope;
try {
typeOfScope = JavaParserFacade.get(typeSolver).getType(scope);
} catch (Exception e) {
throw new RuntimeException("Issue calculating the type of the scope of " + this, e);
}
if (typeOfScope.isWildcard()) {
if (typeOfScope.asWildcard().isExtends() || typeOfScope.asWildcard().isSuper()) {
return singletonList(typeOfScope.asWildcard().getBoundedType().asReferenceType().getTypeDeclaration());
} else {
return singletonList(new ReflectionClassDeclaration(Object.class, typeSolver).asReferenceType());
}
} else if (typeOfScope.isArray()) {
// method call on array are Object methods
return singletonList(new ReflectionClassDeclaration(Object.class, typeSolver).asReferenceType());
} else if (typeOfScope.isTypeVariable()) {
Collection<ResolvedReferenceTypeDeclaration> result = new ArrayList<>();
for (ResolvedTypeParameterDeclaration.Bound bound : typeOfScope.asTypeParameter().getBounds()) {
result.add(bound.getType().asReferenceType().getTypeDeclaration());
}
return result;
} else if (typeOfScope.isConstraint()) {
return singletonList(typeOfScope.asConstraintType().getBound().asReferenceType().getTypeDeclaration());
}
return singletonList(typeOfScope.asReferenceType().getTypeDeclaration());
}
ResolvedType typeOfScope = JavaParserFacade.get(typeSolver).getTypeOfThisIn(wrappedNode);
return singletonList(typeOfScope.asReferenceType().getTypeDeclaration());
}
use of com.github.javaparser.resolution.types.ResolvedType in project javaparser by javaparser.
the class MethodDeclarationCommonLogic method resolveTypeVariables.
public MethodUsage resolveTypeVariables(Context context, List<ResolvedType> parameterTypes) {
ResolvedType returnType = replaceTypeParams(methodDeclaration.getReturnType(), typeSolver, context);
List<ResolvedType> params = new ArrayList<>();
for (int i = 0; i < methodDeclaration.getNumberOfParams(); i++) {
ResolvedType replaced = replaceTypeParams(methodDeclaration.getParam(i).getType(), typeSolver, context);
params.add(replaced);
}
// We now look at the type parameter for the method which we can derive from the parameter types
// and then we replace them in the return type
// Map<TypeParameterDeclaration, Type> determinedTypeParameters = new HashMap<>();
InferenceContext inferenceContext = new InferenceContext(MyObjectProvider.INSTANCE);
for (int i = 0; i < methodDeclaration.getNumberOfParams() - (methodDeclaration.hasVariadicParameter() ? 1 : 0); i++) {
ResolvedType formalParamType = methodDeclaration.getParam(i).getType();
ResolvedType actualParamType = parameterTypes.get(i);
inferenceContext.addPair(formalParamType, actualParamType);
}
returnType = inferenceContext.resolve(inferenceContext.addSingle(returnType));
return new MethodUsage(methodDeclaration, params, returnType);
}
Aggregations