use of com.github.javaparser.resolution.types.ResolvedType in project javaparser by javaparser.
the class ExpressionCompatibleWithType method reduce.
@Override
public ReductionResult reduce(BoundSet currentBoundSet) {
if (isProperType(T)) {
if (isCompatibleInALooseInvocationContext(typeSolver, expression, T)) {
return ReductionResult.trueResult();
} else {
return ReductionResult.falseResult();
}
}
if (isStandaloneExpression(expression)) {
ResolvedType s = JavaParserFacade.get(typeSolver).getType(expression, false);
return ReductionResult.empty().withConstraint(new TypeCompatibleWithType(typeSolver, s, T));
}
if (isPolyExpression(expression)) {
if (expression instanceof EnclosedExpr) {
EnclosedExpr enclosedExpr = (EnclosedExpr) expression;
return ReductionResult.oneConstraint(new ExpressionCompatibleWithType(typeSolver, enclosedExpr.getInner(), T));
}
if (expression instanceof ObjectCreationExpr) {
BoundSet B3 = new TypeInference(typeSolver).invocationTypeInferenceBoundsSetB3();
return ReductionResult.bounds(B3);
}
if (expression instanceof MethodCallExpr) {
throw new UnsupportedOperationException();
}
if (expression instanceof ConditionalExpr) {
ConditionalExpr conditionalExpr = (ConditionalExpr) expression;
return ReductionResult.withConstraints(new ExpressionCompatibleWithType(typeSolver, conditionalExpr.getThenExpr(), T), new ExpressionCompatibleWithType(typeSolver, conditionalExpr.getElseExpr(), T));
}
if (expression instanceof LambdaExpr) {
LambdaExpr lambdaExpr = (LambdaExpr) expression;
if (!FunctionalInterfaceLogic.isFunctionalInterfaceType(T)) {
return ReductionResult.falseResult();
}
// - Otherwise, let T' be the ground target type derived from T, as specified in §15.27.3. If §18.5.3
// is used to derive a functional interface type which is parameterized, then the test that
// F<A'1, ..., A'm> is a subtype of F<A1, ..., Am> is not performed (instead, it is asserted with a
// constraint formula below). Let the target function type for the lambda expression be the
// function type of T'. Then:
Pair<ResolvedType, Boolean> result = TypeHelper.groundTargetTypeOfLambda(lambdaExpr, T, typeSolver);
ResolvedType TFirst = result.a;
MethodType targetFunctionType = TypeHelper.getFunctionType(TFirst);
targetFunctionType = replaceTypeVariablesWithInferenceVariables(targetFunctionType);
if (result.b) {
throw new UnsupportedOperationException();
}
if (targetFunctionType.getFormalArgumentTypes().size() != lambdaExpr.getParameters().size()) {
return ReductionResult.falseResult();
}
if (targetFunctionType.getReturnType().isVoid()) {
throw new UnsupportedOperationException();
}
if (!targetFunctionType.getReturnType().isVoid() && lambdaExpr.getBody() instanceof BlockStmt && !isValueCompatibleBlock(lambdaExpr.getBody())) {
return ReductionResult.falseResult();
}
// - Otherwise, the constraint reduces to all of the following constraint formulas:
List<ConstraintFormula> constraints = new LinkedList<>();
// - If the lambda parameters have explicitly declared types F1, ..., Fn and the function type
// has parameter types G1, ..., Gn, then i) for all i (1 ≤ i ≤ n), ‹Fi = Gi›, and ii) ‹T' <: T›.
boolean hasExplicitlyDeclaredTypes = lambdaExpr.getParameters().stream().anyMatch(p -> !(p.getType() instanceof UnknownType));
if (hasExplicitlyDeclaredTypes) {
throw new UnsupportedOperationException();
}
if (!targetFunctionType.getReturnType().isVoid()) {
ResolvedType R = targetFunctionType.getReturnType();
if (TypeHelper.isProperType(R)) {
if (lambdaExpr.getBody() instanceof BlockStmt) {
List<Expression> resultExpressions = ExpressionHelper.getResultExpressions((BlockStmt) lambdaExpr.getBody());
for (Expression e : resultExpressions) {
if (!ExpressionHelper.isCompatibleInAssignmentContext(e, R, typeSolver)) {
return ReductionResult.falseResult();
}
}
} else {
Expression e = ((ExpressionStmt) lambdaExpr.getBody()).getExpression();
if (!ExpressionHelper.isCompatibleInAssignmentContext(e, R, typeSolver)) {
return ReductionResult.falseResult();
}
}
} else {
if (lambdaExpr.getBody() instanceof BlockStmt) {
getAllReturnExpressions((BlockStmt) lambdaExpr.getBody()).forEach(e -> constraints.add(new ExpressionCompatibleWithType(typeSolver, e, R)));
} else {
// FEDERICO: Added - Start
for (int i = 0; i < lambdaExpr.getParameters().size(); i++) {
ResolvedType paramType = targetFunctionType.getFormalArgumentTypes().get(i);
TypeInferenceCache.record(typeSolver, lambdaExpr, lambdaExpr.getParameter(i).getNameAsString(), paramType);
}
// FEDERICO: Added - End
Expression e = ((ExpressionStmt) lambdaExpr.getBody()).getExpression();
constraints.add(new ExpressionCompatibleWithType(typeSolver, e, R));
}
}
}
return ReductionResult.withConstraints(constraints);
}
if (expression instanceof MethodReferenceExpr) {
throw new UnsupportedOperationException();
}
throw new RuntimeException("This should not happen");
}
throw new RuntimeException("This should not happen");
}
use of com.github.javaparser.resolution.types.ResolvedType in project javaparser by javaparser.
the class TypeSameAsType method reduce.
@Override
public ReductionResult reduce(BoundSet currentBoundSet) {
if (!S.isWildcard() && !T.isWildcard()) {
if (isProperType(S) && isProperType(T)) {
if (S.equals(T)) {
return ReductionResult.trueResult();
} else {
return ReductionResult.falseResult();
}
}
if (S.isNull() || T.isNull()) {
return ReductionResult.falseResult();
}
if (isInferenceVariable(S) && !T.isPrimitive()) {
return ReductionResult.oneBound(new SameAsBound(S, T));
}
if (isInferenceVariable(T) && !S.isPrimitive()) {
return ReductionResult.oneBound(new SameAsBound(S, T));
}
if (S.isReferenceType() && T.isReferenceType() && S.asReferenceType().toRawType().equals(T.asReferenceType().toRawType())) {
ReductionResult res = ReductionResult.empty();
List<ResolvedType> Bs = S.asReferenceType().typeParametersValues();
List<ResolvedType> As = T.asReferenceType().typeParametersValues();
for (int i = 0; i < Bs.size(); i++) {
res = res.withConstraint(new TypeSameAsType(Bs.get(i), As.get(i)));
}
return res;
}
if (S.isArray() && T.isArray()) {
return ReductionResult.oneConstraint(new TypeSameAsType(S.asArrayType().getComponentType(), T.asArrayType().getComponentType()));
}
return ReductionResult.falseResult();
}
throw new UnsupportedOperationException();
}
use of com.github.javaparser.resolution.types.ResolvedType in project javaparser by javaparser.
the class ReflectionMethodResolutionLogic method solveMethodAsUsage.
static Optional<MethodUsage> solveMethodAsUsage(String name, List<ResolvedType> argumentsTypes, TypeSolver typeSolver, Context invokationContext, List<ResolvedType> typeParameterValues, ResolvedReferenceTypeDeclaration scopeType, Class clazz) {
if (typeParameterValues.size() != scopeType.getTypeParameters().size()) {
// if it is zero we are going to ignore them
if (!scopeType.getTypeParameters().isEmpty()) {
// Parameters not specified, so default to Object
typeParameterValues = new ArrayList<>();
for (int i = 0; i < scopeType.getTypeParameters().size(); i++) {
typeParameterValues.add(new ReferenceTypeImpl(new ReflectionClassDeclaration(Object.class, typeSolver), typeSolver));
}
}
}
List<MethodUsage> methods = new ArrayList<>();
for (Method method : clazz.getMethods()) {
if (method.getName().equals(name) && !method.isBridge() && !method.isSynthetic()) {
ResolvedMethodDeclaration methodDeclaration = new ReflectionMethodDeclaration(method, typeSolver);
MethodUsage methodUsage = replaceParams(typeParameterValues, scopeType, methodDeclaration);
methods.add(methodUsage);
}
}
for (ResolvedReferenceType ancestor : scopeType.getAncestors()) {
SymbolReference<ResolvedMethodDeclaration> ref = MethodResolutionLogic.solveMethodInType(ancestor.getTypeDeclaration(), name, argumentsTypes, typeSolver);
if (ref.isSolved()) {
ResolvedMethodDeclaration correspondingDeclaration = ref.getCorrespondingDeclaration();
MethodUsage methodUsage = replaceParams(typeParameterValues, ancestor.getTypeDeclaration(), correspondingDeclaration);
methods.add(methodUsage);
}
}
if (scopeType.getAncestors().isEmpty()) {
ReferenceTypeImpl objectClass = new ReferenceTypeImpl(new ReflectionClassDeclaration(Object.class, typeSolver), typeSolver);
SymbolReference<ResolvedMethodDeclaration> ref = MethodResolutionLogic.solveMethodInType(objectClass.getTypeDeclaration(), name, argumentsTypes, typeSolver);
if (ref.isSolved()) {
MethodUsage usage = replaceParams(typeParameterValues, objectClass.getTypeDeclaration(), ref.getCorrespondingDeclaration());
methods.add(usage);
}
}
final List<ResolvedType> finalTypeParameterValues = typeParameterValues;
argumentsTypes = argumentsTypes.stream().map((pt) -> {
int i = 0;
for (ResolvedTypeParameterDeclaration tp : scopeType.getTypeParameters()) {
pt = pt.replaceTypeVariables(tp, finalTypeParameterValues.get(i));
i++;
}
return pt;
}).collect(Collectors.toList());
return MethodResolutionLogic.findMostApplicableUsage(methods, name, argumentsTypes, typeSolver);
}
use of com.github.javaparser.resolution.types.ResolvedType in project javaparser by javaparser.
the class ConstructorResolutionLogic method isApplicable.
private static boolean isApplicable(ResolvedConstructorDeclaration constructor, List<ResolvedType> argumentsTypes, TypeSolver typeSolver, boolean withWildcardTolerance) {
if (constructor.hasVariadicParameter()) {
int pos = constructor.getNumberOfParams() - 1;
if (constructor.getNumberOfParams() == argumentsTypes.size()) {
// check if the last value is directly assignable as an array
ResolvedType expectedType = constructor.getLastParam().getType();
ResolvedType actualType = argumentsTypes.get(pos);
if (!expectedType.isAssignableBy(actualType)) {
for (ResolvedTypeParameterDeclaration tp : constructor.getTypeParameters()) {
expectedType = MethodResolutionLogic.replaceTypeParam(expectedType, tp, typeSolver);
}
if (!expectedType.isAssignableBy(actualType)) {
if (actualType.isArray() && expectedType.isAssignableBy(actualType.asArrayType().getComponentType())) {
argumentsTypes.set(pos, actualType.asArrayType().getComponentType());
} else {
argumentsTypes = groupVariadicParamValues(argumentsTypes, pos, constructor.getLastParam().getType());
}
}
}
// else it is already assignable, nothing to do
} else {
if (pos > argumentsTypes.size()) {
return false;
}
argumentsTypes = groupVariadicParamValues(argumentsTypes, pos, constructor.getLastParam().getType());
}
}
if (constructor.getNumberOfParams() != argumentsTypes.size()) {
return false;
}
Map<String, ResolvedType> matchedParameters = new HashMap<>();
boolean needForWildCardTolerance = false;
for (int i = 0; i < constructor.getNumberOfParams(); i++) {
ResolvedType expectedType = constructor.getParam(i).getType();
ResolvedType actualType = argumentsTypes.get(i);
if ((expectedType.isTypeVariable() && !(expectedType.isWildcard())) && expectedType.asTypeParameter().declaredOnMethod()) {
matchedParameters.put(expectedType.asTypeParameter().getName(), actualType);
continue;
}
boolean isAssignableWithoutSubstitution = expectedType.isAssignableBy(actualType) || (constructor.getParam(i).isVariadic() && new ResolvedArrayType(expectedType).isAssignableBy(actualType));
if (!isAssignableWithoutSubstitution && expectedType.isReferenceType() && actualType.isReferenceType()) {
isAssignableWithoutSubstitution = MethodResolutionLogic.isAssignableMatchTypeParameters(expectedType.asReferenceType(), actualType.asReferenceType(), matchedParameters);
}
if (!isAssignableWithoutSubstitution) {
List<ResolvedTypeParameterDeclaration> typeParameters = constructor.getTypeParameters();
typeParameters.addAll(constructor.declaringType().getTypeParameters());
for (ResolvedTypeParameterDeclaration tp : typeParameters) {
expectedType = MethodResolutionLogic.replaceTypeParam(expectedType, tp, typeSolver);
}
if (!expectedType.isAssignableBy(actualType)) {
if (actualType.isWildcard() && withWildcardTolerance && !expectedType.isPrimitive()) {
needForWildCardTolerance = true;
continue;
}
if (constructor.hasVariadicParameter() && i == constructor.getNumberOfParams() - 1) {
if (new ResolvedArrayType(expectedType).isAssignableBy(actualType)) {
continue;
}
}
return false;
}
}
}
return !withWildcardTolerance || needForWildCardTolerance;
}
use of com.github.javaparser.resolution.types.ResolvedType in project javaparser by javaparser.
the class ConstructorResolutionLogic method isMoreSpecific.
private static boolean isMoreSpecific(ResolvedConstructorDeclaration constructorA, ResolvedConstructorDeclaration constructorB, TypeSolver typeSolver) {
boolean oneMoreSpecificFound = false;
if (constructorA.getNumberOfParams() < constructorB.getNumberOfParams()) {
return true;
}
if (constructorA.getNumberOfParams() > constructorB.getNumberOfParams()) {
return false;
}
for (int i = 0; i < constructorA.getNumberOfParams(); i++) {
ResolvedType tdA = constructorA.getParam(i).getType();
ResolvedType tdB = constructorB.getParam(i).getType();
// B is more specific
if (tdB.isAssignableBy(tdA) && !tdA.isAssignableBy(tdB)) {
oneMoreSpecificFound = true;
}
// A is more specific
if (tdA.isAssignableBy(tdB) && !tdB.isAssignableBy(tdA)) {
return false;
}
// FIXME
if (i == (constructorA.getNumberOfParams() - 1) && tdA.arrayLevel() > tdB.arrayLevel()) {
return true;
}
}
return oneMoreSpecificFound;
}
Aggregations