aboutsummaryrefslogtreecommitdiffstats
path: root/javaparser-symbol-solver-core/src/main/java/com/github/javaparser/symbolsolver/reflectionmodel/ReflectionClassAdapter.java
diff options
context:
space:
mode:
Diffstat (limited to 'javaparser-symbol-solver-core/src/main/java/com/github/javaparser/symbolsolver/reflectionmodel/ReflectionClassAdapter.java')
-rw-r--r--javaparser-symbol-solver-core/src/main/java/com/github/javaparser/symbolsolver/reflectionmodel/ReflectionClassAdapter.java190
1 files changed, 190 insertions, 0 deletions
diff --git a/javaparser-symbol-solver-core/src/main/java/com/github/javaparser/symbolsolver/reflectionmodel/ReflectionClassAdapter.java b/javaparser-symbol-solver-core/src/main/java/com/github/javaparser/symbolsolver/reflectionmodel/ReflectionClassAdapter.java
new file mode 100644
index 000000000..5be7bece9
--- /dev/null
+++ b/javaparser-symbol-solver-core/src/main/java/com/github/javaparser/symbolsolver/reflectionmodel/ReflectionClassAdapter.java
@@ -0,0 +1,190 @@
+package com.github.javaparser.symbolsolver.reflectionmodel;
+
+import com.github.javaparser.resolution.UnsolvedSymbolException;
+import com.github.javaparser.resolution.declarations.*;
+import com.github.javaparser.resolution.types.ResolvedReferenceType;
+import com.github.javaparser.resolution.types.ResolvedType;
+import com.github.javaparser.symbolsolver.javaparsermodel.LambdaArgumentTypePlaceholder;
+import com.github.javaparser.symbolsolver.logic.FunctionalInterfaceLogic;
+import com.github.javaparser.symbolsolver.model.resolution.TypeSolver;
+import com.github.javaparser.symbolsolver.model.typesystem.NullType;
+import com.github.javaparser.symbolsolver.model.typesystem.ReferenceTypeImpl;
+
+import java.lang.annotation.Annotation;
+import java.lang.reflect.Field;
+import java.lang.reflect.ParameterizedType;
+import java.lang.reflect.TypeVariable;
+import java.util.*;
+import java.util.stream.Collectors;
+
+/**
+ * @author Federico Tomassetti
+ */
+class ReflectionClassAdapter {
+
+ private Class<?> clazz;
+ private TypeSolver typeSolver;
+ private ResolvedReferenceTypeDeclaration typeDeclaration;
+
+ public ReflectionClassAdapter(Class<?> clazz, TypeSolver typeSolver, ResolvedReferenceTypeDeclaration typeDeclaration) {
+ this.clazz = clazz;
+ this.typeSolver = typeSolver;
+ this.typeDeclaration = typeDeclaration;
+ }
+
+ public ReferenceTypeImpl getSuperClass() {
+ if (clazz.getGenericSuperclass() == null) {
+ return null;
+ }
+ java.lang.reflect.Type superType = clazz.getGenericSuperclass();
+ if (superType instanceof ParameterizedType) {
+ ParameterizedType parameterizedType = (ParameterizedType) superType;
+ List<ResolvedType> typeParameters = Arrays.stream(parameterizedType.getActualTypeArguments())
+ .map((t) -> ReflectionFactory.typeUsageFor(t, typeSolver))
+ .collect(Collectors.toList());
+ return new ReferenceTypeImpl(new ReflectionClassDeclaration(clazz.getSuperclass(), typeSolver), typeParameters, typeSolver);
+ }
+ return new ReferenceTypeImpl(new ReflectionClassDeclaration(clazz.getSuperclass(), typeSolver), typeSolver);
+ }
+
+ public List<ResolvedReferenceType> getInterfaces() {
+ List<ResolvedReferenceType> interfaces = new ArrayList<>();
+ for (java.lang.reflect.Type superInterface : clazz.getGenericInterfaces()) {
+ if (superInterface instanceof ParameterizedType) {
+ ParameterizedType parameterizedType = (ParameterizedType) superInterface;
+ List<ResolvedType> typeParameters = Arrays.stream(parameterizedType.getActualTypeArguments())
+ .map((t) -> ReflectionFactory.typeUsageFor(t, typeSolver))
+ .collect(Collectors.toList());
+ interfaces.add(new ReferenceTypeImpl(new ReflectionInterfaceDeclaration((Class<?>) ((ParameterizedType) superInterface).getRawType(), typeSolver), typeParameters, typeSolver));
+ } else {
+ interfaces.add(new ReferenceTypeImpl(new ReflectionInterfaceDeclaration((Class<?>) superInterface, typeSolver), typeSolver));
+ }
+ }
+ return interfaces;
+ }
+
+ public List<ResolvedReferenceType> getAncestors() {
+ List<ResolvedReferenceType> ancestors = new LinkedList<>();
+ if (getSuperClass() != null) {
+ ReferenceTypeImpl superClass = getSuperClass();
+ ancestors.add(superClass);
+ } else {
+ ReferenceTypeImpl object = new ReferenceTypeImpl(new ReflectionClassDeclaration(Object.class, typeSolver), typeSolver);
+ ancestors.add(object);
+ }
+ ancestors.addAll(getInterfaces());
+ for (int i = 0; i < ancestors.size(); i++) {
+ ResolvedReferenceType ancestor = ancestors.get(i);
+ if (ancestor.hasName() && ancestor.getQualifiedName().equals(Object.class.getCanonicalName())) {
+ ancestors.remove(i);
+ i--;
+ }
+ }
+ return ancestors;
+ }
+
+ public ResolvedFieldDeclaration getField(String name) {
+ for (Field field : clazz.getDeclaredFields()) {
+ if (field.getName().equals(name)) {
+ return new ReflectionFieldDeclaration(field, typeSolver);
+ }
+ }
+ for (ResolvedReferenceType ancestor : typeDeclaration.getAllAncestors()) {
+ if (ancestor.getTypeDeclaration().hasField(name)) {
+ ReflectionFieldDeclaration reflectionFieldDeclaration = (ReflectionFieldDeclaration) ancestor.getTypeDeclaration().getField(name);
+ return reflectionFieldDeclaration.replaceType(ancestor.getFieldType(name).get());
+ }
+ }
+ throw new UnsolvedSymbolException(name, "Field in " + this);
+ }
+
+ public boolean hasField(String name) {
+ for (Field field : clazz.getDeclaredFields()) {
+ if (field.getName().equals(name)) {
+ return true;
+ }
+ }
+ ReferenceTypeImpl superclass = getSuperClass();
+ if (superclass == null) {
+ return false;
+ } else {
+ return superclass.getTypeDeclaration().hasField(name);
+ }
+ }
+
+ public List<ResolvedFieldDeclaration> getAllFields() {
+ ArrayList<ResolvedFieldDeclaration> fields = new ArrayList<>();
+ for (Field field : clazz.getDeclaredFields()) {
+ fields.add(new ReflectionFieldDeclaration(field, typeSolver));
+ }
+ for (ResolvedReferenceType ancestor : typeDeclaration.getAllAncestors()) {
+ fields.addAll(ancestor.getTypeDeclaration().getAllFields());
+ }
+ return fields;
+ }
+
+ public Set<ResolvedMethodDeclaration> getDeclaredMethods() {
+ return Arrays.stream(clazz.getDeclaredMethods())
+ .filter(m -> !m.isSynthetic() && !m.isBridge())
+ .map(m -> new ReflectionMethodDeclaration(m, typeSolver))
+ .collect(Collectors.toSet());
+ }
+
+ public List<ResolvedTypeParameterDeclaration> getTypeParameters() {
+ List<ResolvedTypeParameterDeclaration> params = new ArrayList<>();
+ for (TypeVariable<?> tv : this.clazz.getTypeParameters()) {
+ params.add(new ReflectionTypeParameter(tv, true, typeSolver));
+ }
+ return params;
+ }
+
+ public boolean isAssignableBy(ResolvedType type) {
+ if (type instanceof NullType) {
+ return true;
+ }
+ if (type instanceof LambdaArgumentTypePlaceholder) {
+ return isFunctionalInterface();
+ }
+ if (type.isArray()) {
+ return false;
+ }
+ if (type.isPrimitive()) {
+ return false;
+ }
+ if (type.describe().equals(typeDeclaration.getQualifiedName())) {
+ return true;
+ }
+ if (type instanceof ReferenceTypeImpl) {
+ ReferenceTypeImpl otherTypeDeclaration = (ReferenceTypeImpl) type;
+ return otherTypeDeclaration.getTypeDeclaration().canBeAssignedTo(typeDeclaration);
+ }
+
+ return false;
+ }
+
+ public boolean hasDirectlyAnnotation(String canonicalName) {
+ for (Annotation a : clazz.getDeclaredAnnotations()) {
+ if (a.annotationType().getCanonicalName().equals(canonicalName)) {
+ return true;
+ }
+ }
+ return false;
+ }
+
+ private final boolean isFunctionalInterface() {
+ return FunctionalInterfaceLogic.getFunctionalMethod(typeDeclaration).isPresent();
+ }
+
+ public List<ResolvedConstructorDeclaration> getConstructors() {
+ return Arrays.stream(clazz.getConstructors())
+ .map(m -> new ReflectionConstructorDeclaration(m, typeSolver))
+ .collect(Collectors.toList());
+ }
+
+ public Optional<ResolvedReferenceTypeDeclaration> containerType() {
+ Class<?> declaringClass = clazz.getDeclaringClass();
+ return declaringClass == null ?
+ Optional.empty() :
+ Optional.of(ReflectionFactory.typeDeclarationFor(declaringClass, typeSolver));
+ }
+}