@Override protected ResolvedReferenceType create(ResolvedReferenceTypeDeclaration typeDeclaration, List<ResolvedType> typeParametersCorrected) { return new ReferenceTypeImpl(typeDeclaration, typeParametersCorrected, typeSolver); }
public List<ResolvedReferenceType> getDirectAncestors() { // We need to go through the inheritance line and propagate the type parametes List<ResolvedReferenceType> ancestors = typeDeclaration.getAncestors(); ancestors = ancestors.stream() .map(a -> typeParametersMap().replaceAll(a).asReferenceType()) .collect(Collectors.toList()); // Avoid repetitions of Object ancestors.removeIf(a -> a.getQualifiedName().equals(Object.class.getCanonicalName())); boolean isClassWithSuperClassOrObject = this.getTypeDeclaration().isClass() && (this.getTypeDeclaration().asClass().getSuperClass() == null || !this.getTypeDeclaration().asClass().getSuperClass().getQualifiedName().equals(Object.class.getCanonicalName())); if (!isClassWithSuperClassOrObject) { ResolvedReferenceTypeDeclaration objectType = typeSolver.solveType(Object.class.getCanonicalName()); ResolvedReferenceType objectRef = create(objectType); ancestors.add(objectRef); } return ancestors; }
/** * Execute a transformation on all the type parameters of this element. */ @Override public ResolvedType transformTypeParameters(ResolvedTypeTransformer transformer) { ResolvedType result = this; int i = 0; for (ResolvedType tp : this.typeParametersValues()) { ResolvedType transformedTp = transformer.transform(tp); // Identity comparison on purpose if (transformedTp != tp) { List<ResolvedType> typeParametersCorrected = result.asReferenceType().typeParametersValues(); typeParametersCorrected.set(i, transformedTp); result = create(typeDeclaration, typeParametersCorrected); } i++; } return result; }
@Override public ResolvedType toRawType() { if (this.isRawType()) { return this; } else { return new ReferenceTypeImpl(typeDeclaration, typeSolver); } }
public List<ResolvedReferenceType> getAllAncestors() { // We need to go through the inheritance line and propagate the type parametes List<ResolvedReferenceType> ancestors = typeDeclaration.getAllAncestors(); ancestors = ancestors.stream() .map(a -> typeParametersMap().replaceAll(a).asReferenceType()) .collect(Collectors.toList()); // Avoid repetitions of Object ancestors.removeIf(a -> a.getQualifiedName().equals(Object.class.getCanonicalName())); ResolvedReferenceTypeDeclaration objectType = typeSolver.solveType(Object.class.getCanonicalName()); ResolvedReferenceType objectRef = create(objectType); ancestors.add(objectRef); return ancestors; }
public boolean isAssignableBy(ResolvedType other) { if (other instanceof NullType) { return !this.isPrimitive(); if (!other.isVoid() && this.getQualifiedName().equals(Object.class.getCanonicalName())) { return true; if (this.getQualifiedName().equals(Object.class.getCanonicalName())) { return true; } else { if (isCorrespondingBoxingType(other.describe())) return true; return this.getTypeDeclaration().hasAnnotation(FunctionalInterface.class.getCanonicalName()); } else if (other instanceof ReferenceTypeImpl) { ReferenceTypeImpl otherRef = (ReferenceTypeImpl) other; if (compareConsideringTypeParameters(otherRef)) { return true; for (ResolvedReferenceType otherAncestor : otherRef.getAllAncestors()) { if (compareConsideringTypeParameters(otherAncestor)) { return true; for (ResolvedTypeParameterDeclaration.Bound bound : other.asTypeVariable().asTypeParameter().getBounds()) { if (bound.isExtends()) { if (this.isAssignableBy(bound.getType())) { return true; return isAssignableBy(other.asConstraintType().getBound());
static SymbolReference<ResolvedMethodDeclaration> solveMethod(String name, List<ResolvedType> parameterTypes, boolean staticOnly, TypeSolver typeSolver, ResolvedReferenceTypeDeclaration scopeType, Class clazz){ List<ResolvedMethodDeclaration> methods = new ArrayList<>(); Predicate<Method> staticOnlyCheck = m -> !staticOnly || (staticOnly && Modifier.isStatic(m.getModifiers())); for (Method method : clazz.getMethods()) { if (method.isBridge() || method.isSynthetic() || !method.getName().equals(name)|| !staticOnlyCheck.test(method)) continue; ResolvedMethodDeclaration methodDeclaration = new ReflectionMethodDeclaration(method, typeSolver); methods.add(methodDeclaration); } for (ResolvedReferenceType ancestor : scopeType.getAncestors()) { SymbolReference<ResolvedMethodDeclaration> ref = MethodResolutionLogic.solveMethodInType(ancestor.getTypeDeclaration(), name, parameterTypes, staticOnly, typeSolver); if (ref.isSolved()) { methods.add(ref.getCorrespondingDeclaration()); } } if (scopeType.getAncestors().isEmpty()){ ReferenceTypeImpl objectClass = new ReferenceTypeImpl(new ReflectionClassDeclaration(Object.class, typeSolver), typeSolver); SymbolReference<ResolvedMethodDeclaration> ref = MethodResolutionLogic.solveMethodInType(objectClass.getTypeDeclaration(), name, parameterTypes, staticOnly, typeSolver); if (ref.isSolved()) { methods.add(ref.getCorrespondingDeclaration()); } } return MethodResolutionLogic.findMostApplicable(methods, name, parameterTypes, typeSolver); }
@Override public Set<ResolvedFieldDeclaration> getDeclaredFields() { return new HashSet<>(getTypeDeclaration().getDeclaredFields()); } }
@Test public void testGetAllAncestorsConsideringGenericsCases() { ReferenceTypeImpl foo = new ReferenceTypeImpl(new ReflectionClassDeclaration(Foo.class, typeSolver), typeSolver); ReferenceTypeImpl bar = new ReferenceTypeImpl(new ReflectionClassDeclaration(Bar.class, typeSolver), typeSolver); ReferenceTypeImpl left, right; new ReferenceTypeImpl( new ReflectionClassDeclaration(MoreBazzing.class, typeSolver), ImmutableList.of(foo, bar), typeSolver) .isAssignableBy(new ReferenceTypeImpl( new ReflectionClassDeclaration(MoreBazzing.class, typeSolver), ImmutableList.of(foo, bar), typeSolver)) new ReferenceTypeImpl( new ReflectionClassDeclaration(MoreBazzing.class, typeSolver), ImmutableList.of(ResolvedWildcard.extendsBound(foo), bar), typeSolver) .isAssignableBy(new ReferenceTypeImpl( new ReflectionClassDeclaration(MoreBazzing.class, typeSolver), ImmutableList.of(foo, bar), typeSolver)) new ReferenceTypeImpl( new ReflectionClassDeclaration(MoreBazzing.class, typeSolver), ImmutableList.of(foo, ResolvedWildcard.extendsBound(bar)), typeSolver) .isAssignableBy(new ReferenceTypeImpl( new ReflectionClassDeclaration(MoreBazzing.class, typeSolver), ImmutableList.of(foo, bar), typeSolver)) new ReferenceTypeImpl( new ReflectionClassDeclaration(MoreBazzing.class, typeSolver), ImmutableList.of(ResolvedWildcard.extendsBound(foo), ResolvedWildcard.extendsBound(foo)), typeSolver)
@Test public void testDerivationOfTypeParameters() { ReflectionTypeSolver typeSolver = new ReflectionTypeSolver(); ReferenceTypeImpl ref1 = new ReferenceTypeImpl(typeSolver.solveType(LinkedList.class.getCanonicalName()), typeSolver); assertEquals(1, ref1.typeParametersValues().size()); assertEquals(true, ref1.typeParametersValues().get(0).isTypeVariable()); assertEquals("E", ref1.typeParametersValues().get(0).asTypeParameter().getName()); }
@Test public void charSequenceIsAssignableToObject() { TypeSolver typeSolver = new ReflectionTypeSolver(); ReferenceTypeImpl charSequence = new ReferenceTypeImpl(new ReflectionInterfaceDeclaration(CharSequence.class, typeSolver), typeSolver); ReferenceTypeImpl object = new ReferenceTypeImpl(new ReflectionClassDeclaration(Object.class, typeSolver), typeSolver); assertEquals(false, charSequence.isAssignableBy(object)); assertEquals(true, object.isAssignableBy(charSequence)); }
@Test public void testGetSuperclassWithTypeParameters() { ReflectionClassDeclaration compilationUnit = (ReflectionClassDeclaration) typeResolver.solveType("com.github.javaparser.ast.body.ConstructorDeclaration"); assertEquals("com.github.javaparser.ast.body.CallableDeclaration", compilationUnit.getSuperClass().getQualifiedName()); assertEquals("com.github.javaparser.ast.body.ConstructorDeclaration", compilationUnit.getSuperClass().typeParametersMap().getValueBySignature("com.github.javaparser.ast.body.CallableDeclaration.T").get().asReferenceType().getQualifiedName()); }
@Test public void testIsAssignableByGenerics() { assertEquals(false, listOfStrings.isAssignableBy(listOfWildcardExtendsString)); assertEquals(false, listOfStrings.isAssignableBy(listOfWildcardExtendsString)); assertEquals(true, listOfWildcardExtendsString.isAssignableBy(listOfStrings)); assertEquals(false, listOfWildcardExtendsString.isAssignableBy(listOfWildcardSuperString)); assertEquals(true, listOfWildcardSuperString.isAssignableBy(listOfStrings)); assertEquals(false, listOfWildcardSuperString.isAssignableBy(listOfWildcardExtendsString)); }
@Override public boolean mention(List<ResolvedTypeParameterDeclaration> typeParameters) { return typeParametersValues().stream().anyMatch(tp -> tp.mention(typeParameters)); }
public ResolvedReferenceType deriveTypeParameters(ResolvedTypeParametersMap typeParametersMap) { return create(typeDeclaration, typeParametersMap); }
@Test public void testGetAllAncestorsConsideringTypeParameters() { assertTrue(linkedListOfString.getAllAncestors().contains(object)); assertTrue(linkedListOfString.getAllAncestors().contains(listOfStrings)); assertTrue(linkedListOfString.getAllAncestors().contains(collectionOfString)); assertFalse(linkedListOfString.getAllAncestors().contains(listOfA)); }
@Test public void testIsPrimitive() { assertEquals(false, object.isPrimitive()); assertEquals(false, string.isPrimitive()); assertEquals(false, listOfA.isPrimitive()); assertEquals(false, listOfStrings.isPrimitive()); }
@Test public void testGetSuperclassWithoutTypeParameters() { ReflectionClassDeclaration compilationUnit = (ReflectionClassDeclaration) typeResolver.solveType("com.github.javaparser.ast.CompilationUnit"); assertEquals("com.github.javaparser.ast.Node", compilationUnit.getSuperClass().getQualifiedName()); }
public boolean isAssignableBy(ResolvedType other) { if (other instanceof NullType) { return !this.isPrimitive(); if (!other.isVoid() && this.getQualifiedName().equals(Object.class.getCanonicalName())) { return true; if (this.getQualifiedName().equals(Object.class.getCanonicalName())) { return true; } else { if (isCorrespondingBoxingType(other.describe())) return true; return this.getTypeDeclaration().hasAnnotation(FunctionalInterface.class.getCanonicalName()); } else if (other instanceof ReferenceTypeImpl) { ReferenceTypeImpl otherRef = (ReferenceTypeImpl) other; if (compareConsideringTypeParameters(otherRef)) { return true; for (ResolvedReferenceType otherAncestor : otherRef.getAllAncestors()) { if (compareConsideringTypeParameters(otherAncestor)) { return true; for (ResolvedTypeParameterDeclaration.Bound bound : other.asTypeVariable().asTypeParameter().getBounds()) { if (bound.isExtends()) { if (this.isAssignableBy(bound.getType())) { return true; return isAssignableBy(other.asConstraintType().getBound());
static SymbolReference<ResolvedMethodDeclaration> solveMethod(String name, List<ResolvedType> parameterTypes, boolean staticOnly, TypeSolver typeSolver, ResolvedReferenceTypeDeclaration scopeType, Class clazz){ List<ResolvedMethodDeclaration> methods = new ArrayList<>(); Predicate<Method> staticOnlyCheck = m -> !staticOnly || (staticOnly && Modifier.isStatic(m.getModifiers())); for (Method method : clazz.getMethods()) { if (method.isBridge() || method.isSynthetic() || !method.getName().equals(name)|| !staticOnlyCheck.test(method)) continue; ResolvedMethodDeclaration methodDeclaration = new ReflectionMethodDeclaration(method, typeSolver); methods.add(methodDeclaration); } for (ResolvedReferenceType ancestor : scopeType.getAncestors()) { SymbolReference<ResolvedMethodDeclaration> ref = MethodResolutionLogic.solveMethodInType(ancestor.getTypeDeclaration(), name, parameterTypes, staticOnly); if (ref.isSolved()) { methods.add(ref.getCorrespondingDeclaration()); } } if (scopeType.getAncestors().isEmpty()){ ReferenceTypeImpl objectClass = new ReferenceTypeImpl(new ReflectionClassDeclaration(Object.class, typeSolver), typeSolver); SymbolReference<ResolvedMethodDeclaration> ref = MethodResolutionLogic.solveMethodInType(objectClass.getTypeDeclaration(), name, parameterTypes, staticOnly); if (ref.isSolved()) { methods.add(ref.getCorrespondingDeclaration()); } } return MethodResolutionLogic.findMostApplicable(methods, name, parameterTypes, typeSolver); }