aboutsummaryrefslogtreecommitdiff
path: root/javaparser-core/src/main
diff options
context:
space:
mode:
authorRyan Beckett <beckett.ryan@gmail.com>2017-10-07 00:22:00 -0400
committerRyan Beckett <beckett.ryan@gmail.com>2017-10-07 00:22:00 -0400
commit18fc54740d8373ac384ba2811dc308296dcca429 (patch)
tree0a3d3f44a29cbf02a57a94417f3c5f337030fa03 /javaparser-core/src/main
parent5807302b24c943577962b65e75fd647c23fe1cc9 (diff)
parentd4e119c24f16decfba0d67898530418139a0db11 (diff)
downloadjavaparser-18fc54740d8373ac384ba2811dc308296dcca429.tar.gz
Merge branch '#1072_visitor_set' of https://github.com/ryan-beckett/javaparser into #1072_visitor_set
Diffstat (limited to 'javaparser-core/src/main')
-rw-r--r--javaparser-core/src/main/java/com/github/javaparser/ast/Node.java14
-rw-r--r--javaparser-core/src/main/java/com/github/javaparser/ast/body/MethodDeclaration.java10
-rw-r--r--javaparser-core/src/main/java/com/github/javaparser/ast/nodeTypes/NodeWithMembers.java45
-rw-r--r--javaparser-core/src/main/java/com/github/javaparser/ast/type/ArrayType.java6
-rw-r--r--javaparser-core/src/main/java/com/github/javaparser/ast/type/ClassOrInterfaceType.java8
-rw-r--r--javaparser-core/src/main/java/com/github/javaparser/ast/type/IntersectionType.java8
-rw-r--r--javaparser-core/src/main/java/com/github/javaparser/ast/type/PrimitiveType.java8
-rw-r--r--javaparser-core/src/main/java/com/github/javaparser/ast/type/ReferenceType.java2
-rw-r--r--javaparser-core/src/main/java/com/github/javaparser/ast/type/Type.java12
-rw-r--r--javaparser-core/src/main/java/com/github/javaparser/ast/type/TypeParameter.java13
-rw-r--r--javaparser-core/src/main/java/com/github/javaparser/ast/type/UnionType.java8
-rw-r--r--javaparser-core/src/main/java/com/github/javaparser/ast/type/UnknownType.java9
-rw-r--r--javaparser-core/src/main/java/com/github/javaparser/ast/type/VoidType.java8
-rw-r--r--javaparser-core/src/main/java/com/github/javaparser/ast/type/WildcardType.java8
-rw-r--r--javaparser-core/src/main/java/com/github/javaparser/resolution/MethodAmbiguityException.java38
-rw-r--r--javaparser-core/src/main/java/com/github/javaparser/resolution/MethodUsage.java192
-rw-r--r--javaparser-core/src/main/java/com/github/javaparser/resolution/Resolvable.java26
-rw-r--r--javaparser-core/src/main/java/com/github/javaparser/resolution/SymbolResolver.java28
-rw-r--r--javaparser-core/src/main/java/com/github/javaparser/resolution/UnsolvedSymbolException.java53
-rw-r--r--javaparser-core/src/main/java/com/github/javaparser/resolution/declarations/HasAccessSpecifier.java38
-rw-r--r--javaparser-core/src/main/java/com/github/javaparser/resolution/declarations/ResolvedAnnotationDeclaration.java28
-rw-r--r--javaparser-core/src/main/java/com/github/javaparser/resolution/declarations/ResolvedClassDeclaration.java85
-rw-r--r--javaparser-core/src/main/java/com/github/javaparser/resolution/declarations/ResolvedConstructorDeclaration.java33
-rw-r--r--javaparser-core/src/main/java/com/github/javaparser/resolution/declarations/ResolvedDeclaration.java98
-rw-r--r--javaparser-core/src/main/java/com/github/javaparser/resolution/declarations/ResolvedEnumDeclaration.java41
-rw-r--r--javaparser-core/src/main/java/com/github/javaparser/resolution/declarations/ResolvedFieldDeclaration.java51
-rw-r--r--javaparser-core/src/main/java/com/github/javaparser/resolution/declarations/ResolvedInterfaceDeclaration.java58
-rw-r--r--javaparser-core/src/main/java/com/github/javaparser/resolution/declarations/ResolvedMethodDeclaration.java54
-rw-r--r--javaparser-core/src/main/java/com/github/javaparser/resolution/declarations/ResolvedMethodLikeDeclaration.java159
-rw-r--r--javaparser-core/src/main/java/com/github/javaparser/resolution/declarations/ResolvedParameterDeclaration.java57
-rw-r--r--javaparser-core/src/main/java/com/github/javaparser/resolution/declarations/ResolvedReferenceTypeDeclaration.java246
-rw-r--r--javaparser-core/src/main/java/com/github/javaparser/resolution/declarations/ResolvedTypeDeclaration.java177
-rw-r--r--javaparser-core/src/main/java/com/github/javaparser/resolution/declarations/ResolvedTypeParameterDeclaration.java305
-rw-r--r--javaparser-core/src/main/java/com/github/javaparser/resolution/declarations/ResolvedTypeParametrizable.java49
-rw-r--r--javaparser-core/src/main/java/com/github/javaparser/resolution/declarations/ResolvedValueDeclaration.java39
-rw-r--r--javaparser-core/src/main/java/com/github/javaparser/resolution/types/ResolvedArrayType.java113
-rw-r--r--javaparser-core/src/main/java/com/github/javaparser/resolution/types/ResolvedIntersectionType.java81
-rw-r--r--javaparser-core/src/main/java/com/github/javaparser/resolution/types/ResolvedLambdaConstraintType.java65
-rw-r--r--javaparser-core/src/main/java/com/github/javaparser/resolution/types/ResolvedPrimitiveType.java141
-rw-r--r--javaparser-core/src/main/java/com/github/javaparser/resolution/types/ResolvedReferenceType.java451
-rw-r--r--javaparser-core/src/main/java/com/github/javaparser/resolution/types/ResolvedType.java181
-rw-r--r--javaparser-core/src/main/java/com/github/javaparser/resolution/types/ResolvedTypeTransformer.java30
-rw-r--r--javaparser-core/src/main/java/com/github/javaparser/resolution/types/ResolvedTypeVariable.java129
-rw-r--r--javaparser-core/src/main/java/com/github/javaparser/resolution/types/ResolvedUnionType.java69
-rw-r--r--javaparser-core/src/main/java/com/github/javaparser/resolution/types/ResolvedVoidType.java49
-rw-r--r--javaparser-core/src/main/java/com/github/javaparser/resolution/types/ResolvedWildcard.java183
-rw-r--r--javaparser-core/src/main/java/com/github/javaparser/resolution/types/parametrization/ResolvedTypeParameterValueProvider.java72
-rw-r--r--javaparser-core/src/main/java/com/github/javaparser/resolution/types/parametrization/ResolvedTypeParametersMap.java146
-rw-r--r--javaparser-core/src/main/java/com/github/javaparser/resolution/types/parametrization/ResolvedTypeParametrized.java31
49 files changed, 3740 insertions, 15 deletions
diff --git a/javaparser-core/src/main/java/com/github/javaparser/ast/Node.java b/javaparser-core/src/main/java/com/github/javaparser/ast/Node.java
index 5f45e75b0..0694d5cd7 100644
--- a/javaparser-core/src/main/java/com/github/javaparser/ast/Node.java
+++ b/javaparser-core/src/main/java/com/github/javaparser/ast/Node.java
@@ -41,6 +41,7 @@ import com.github.javaparser.metamodel.NodeMetaModel;
import com.github.javaparser.metamodel.PropertyMetaModel;
import com.github.javaparser.printer.PrettyPrinter;
import com.github.javaparser.printer.PrettyPrinterConfiguration;
+import com.github.javaparser.resolution.SymbolResolver;
import javax.annotation.Generated;
import java.util.*;
@@ -663,4 +664,17 @@ public abstract class Node implements Cloneable, HasParentNode<Node>, Visitable,
}
return Optional.empty();
}
+
+ protected SymbolResolver getSymbolResolver() {
+ return findCompilationUnit().map(cu -> {
+ SymbolResolver symbolResolver = cu.getData(SYMBOL_RESOLVER_KEY);
+ if (symbolResolver == null) {
+ throw new IllegalStateException("Symbol resolution not configured");
+ }
+ return symbolResolver;
+ }).orElseThrow(() -> new IllegalStateException("The node is not inserted in a CompilationUnit"));
+ }
+
+ // We need to expose it because we will need to use it to inject the SymbolSolver
+ public static final DataKey<SymbolResolver> SYMBOL_RESOLVER_KEY = new DataKey<SymbolResolver>() { };
}
diff --git a/javaparser-core/src/main/java/com/github/javaparser/ast/body/MethodDeclaration.java b/javaparser-core/src/main/java/com/github/javaparser/ast/body/MethodDeclaration.java
index f0bbaaa8d..ccda1673d 100644
--- a/javaparser-core/src/main/java/com/github/javaparser/ast/body/MethodDeclaration.java
+++ b/javaparser-core/src/main/java/com/github/javaparser/ast/body/MethodDeclaration.java
@@ -48,6 +48,9 @@ import com.github.javaparser.metamodel.MethodDeclarationMetaModel;
import com.github.javaparser.metamodel.JavaParserMetaModel;
import javax.annotation.Generated;
import com.github.javaparser.TokenRange;
+import com.github.javaparser.resolution.Resolvable;
+import com.github.javaparser.resolution.declarations.ResolvedMethodDeclaration;
+
import java.util.function.Consumer;
/**
@@ -59,7 +62,7 @@ import java.util.function.Consumer;
*
* @author Julio Vilmar Gesser
*/
-public final class MethodDeclaration extends CallableDeclaration<MethodDeclaration> implements NodeWithType<MethodDeclaration, Type>, NodeWithOptionalBlockStmt<MethodDeclaration>, NodeWithJavadoc<MethodDeclaration>, NodeWithDeclaration, NodeWithSimpleName<MethodDeclaration>, NodeWithParameters<MethodDeclaration>, NodeWithThrownExceptions<MethodDeclaration>, NodeWithTypeParameters<MethodDeclaration>, NodeWithAccessModifiers<MethodDeclaration>, NodeWithAbstractModifier<MethodDeclaration>, NodeWithStaticModifier<MethodDeclaration>, NodeWithFinalModifier<MethodDeclaration>, NodeWithStrictfpModifier<MethodDeclaration> {
+public final class MethodDeclaration extends CallableDeclaration<MethodDeclaration> implements NodeWithType<MethodDeclaration, Type>, NodeWithOptionalBlockStmt<MethodDeclaration>, NodeWithJavadoc<MethodDeclaration>, NodeWithDeclaration, NodeWithSimpleName<MethodDeclaration>, NodeWithParameters<MethodDeclaration>, NodeWithThrownExceptions<MethodDeclaration>, NodeWithTypeParameters<MethodDeclaration>, NodeWithAccessModifiers<MethodDeclaration>, NodeWithAbstractModifier<MethodDeclaration>, NodeWithStaticModifier<MethodDeclaration>, NodeWithFinalModifier<MethodDeclaration>, NodeWithStrictfpModifier<MethodDeclaration>, Resolvable<ResolvedMethodDeclaration> {
private Type type;
@@ -323,4 +326,9 @@ public final class MethodDeclaration extends CallableDeclaration<MethodDeclarati
public void ifMethodDeclaration(Consumer<MethodDeclaration> action) {
action.accept(this);
}
+
+ @Override
+ public ResolvedMethodDeclaration resolve() {
+ return getSymbolResolver().resolve(this, ResolvedMethodDeclaration.class);
+ }
}
diff --git a/javaparser-core/src/main/java/com/github/javaparser/ast/nodeTypes/NodeWithMembers.java b/javaparser-core/src/main/java/com/github/javaparser/ast/nodeTypes/NodeWithMembers.java
index e51c8adbf..6d5f0c3ff 100644
--- a/javaparser-core/src/main/java/com/github/javaparser/ast/nodeTypes/NodeWithMembers.java
+++ b/javaparser-core/src/main/java/com/github/javaparser/ast/nodeTypes/NodeWithMembers.java
@@ -18,13 +18,13 @@
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*/
-
package com.github.javaparser.ast.nodeTypes;
import com.github.javaparser.ast.Modifier;
import com.github.javaparser.ast.Node;
import com.github.javaparser.ast.NodeList;
import com.github.javaparser.ast.body.*;
+import com.github.javaparser.ast.expr.Expression;
import com.github.javaparser.ast.stmt.BlockStmt;
import com.github.javaparser.ast.type.Type;
import com.github.javaparser.ast.type.VoidType;
@@ -46,6 +46,10 @@ import static java.util.stream.Collectors.toList;
* method.
*/
public interface NodeWithMembers<N extends Node> {
+ /**
+ * @return all members inside the braces of this node,
+ * like fields, methods, nested types, etc.
+ */
NodeList<BodyDeclaration<?>> getMembers();
void tryAddImportToParentCompilationUnit(Class<?> clazz);
@@ -82,7 +86,7 @@ public interface NodeWithMembers<N extends Node> {
}
/**
- * Add a field to this
+ * Add a field to this.
*
* @param type the type of the field
* @param name the name of the field
@@ -94,7 +98,7 @@ public interface NodeWithMembers<N extends Node> {
}
/**
- * Add a field to this
+ * Add a field to this.
*
* @param type the type of the field
* @param name the name of the field
@@ -112,7 +116,22 @@ public interface NodeWithMembers<N extends Node> {
}
/**
- * Add a private field to this
+ * Add a field to this.
+ *
+ * @param type the type of the field
+ * @param name the name of the field
+ * @param initializer the initializer of the field
+ * @param modifiers the modifiers like {@link Modifier#PUBLIC}
+ * @return the {@link FieldDeclaration} created
+ */
+ default FieldDeclaration addFieldWithInitializer(Type type, String name, Expression initializer, Modifier... modifiers) {
+ FieldDeclaration declaration = addField(type, name, modifiers);
+ declaration.getVariables().iterator().next().setInitializer(initializer);
+ return declaration;
+ }
+
+ /**
+ * Add a private field to this.
*
* @param typeClass the type of the field
* @param name the name of the field
@@ -124,7 +143,7 @@ public interface NodeWithMembers<N extends Node> {
/**
* Add a private field to this and automatically add the import of the type if
- * needed
+ * needed.
*
* @param type the type of the field
* @param name the name of the field
@@ -135,7 +154,7 @@ public interface NodeWithMembers<N extends Node> {
}
/**
- * Add a public field to this
+ * Add a public field to this.
*
* @param typeClass the type of the field
* @param name the name of the field
@@ -147,7 +166,7 @@ public interface NodeWithMembers<N extends Node> {
/**
* Add a public field to this and automatically add the import of the type if
- * needed
+ * needed.
*
* @param type the type of the field
* @param name the name of the field
@@ -158,7 +177,7 @@ public interface NodeWithMembers<N extends Node> {
}
/**
- * Add a protected field to this
+ * Add a protected field to this.
*
* @param typeClass the type of the field
* @param name the name of the field
@@ -170,7 +189,7 @@ public interface NodeWithMembers<N extends Node> {
/**
* Add a protected field to this and automatically add the import of the type
- * if needed
+ * if needed.
*
* @param type the type of the field
* @param name the name of the field
@@ -181,7 +200,7 @@ public interface NodeWithMembers<N extends Node> {
}
/**
- * Adds a methods with void return by default to this
+ * Adds a methods with void return by default to this.
*
* @param methodName the method name
* @param modifiers the modifiers like {@link Modifier#PUBLIC}
@@ -197,6 +216,9 @@ public interface NodeWithMembers<N extends Node> {
return methodDeclaration;
}
+ /**
+ * Add an initializer block ({@link InitializerDeclaration}) to this.
+ */
default BlockStmt addInitializer() {
BlockStmt block = new BlockStmt();
InitializerDeclaration initializerDeclaration = new InitializerDeclaration(false, block);
@@ -204,6 +226,9 @@ public interface NodeWithMembers<N extends Node> {
return block;
}
+ /**
+ * Add a static initializer block ({@link InitializerDeclaration}) to this.
+ */
default BlockStmt addStaticInitializer() {
BlockStmt block = new BlockStmt();
InitializerDeclaration initializerDeclaration = new InitializerDeclaration(true, block);
diff --git a/javaparser-core/src/main/java/com/github/javaparser/ast/type/ArrayType.java b/javaparser-core/src/main/java/com/github/javaparser/ast/type/ArrayType.java
index d9ba8bf4a..91cf98369 100644
--- a/javaparser-core/src/main/java/com/github/javaparser/ast/type/ArrayType.java
+++ b/javaparser-core/src/main/java/com/github/javaparser/ast/type/ArrayType.java
@@ -32,6 +32,7 @@ import com.github.javaparser.ast.visitor.GenericVisitor;
import com.github.javaparser.ast.visitor.VoidVisitor;
import com.github.javaparser.metamodel.ArrayTypeMetaModel;
import com.github.javaparser.metamodel.JavaParserMetaModel;
+import com.github.javaparser.resolution.types.ResolvedArrayType;
import com.github.javaparser.utils.Pair;
import javax.annotation.Generated;
import java.util.ArrayList;
@@ -47,6 +48,11 @@ import java.util.function.Consumer;
*/
public final class ArrayType extends ReferenceType implements NodeWithAnnotations<ArrayType> {
+ @Override
+ public ResolvedArrayType resolve() {
+ return getSymbolResolver().resolve(this, ResolvedArrayType.class);
+ }
+
/**
* The origin of a pair of array brackets [].
*/
diff --git a/javaparser-core/src/main/java/com/github/javaparser/ast/type/ClassOrInterfaceType.java b/javaparser-core/src/main/java/com/github/javaparser/ast/type/ClassOrInterfaceType.java
index 6758234d5..5a7328de4 100644
--- a/javaparser-core/src/main/java/com/github/javaparser/ast/type/ClassOrInterfaceType.java
+++ b/javaparser-core/src/main/java/com/github/javaparser/ast/type/ClassOrInterfaceType.java
@@ -41,6 +41,8 @@ import static com.github.javaparser.utils.Utils.assertNotNull;
import static java.util.stream.Collectors.joining;
import javax.annotation.Generated;
import com.github.javaparser.TokenRange;
+import com.github.javaparser.resolution.types.ResolvedReferenceType;
+
import java.util.function.Consumer;
/**
@@ -280,4 +282,10 @@ public final class ClassOrInterfaceType extends ReferenceType implements NodeWit
public void ifClassOrInterfaceType(Consumer<ClassOrInterfaceType> action) {
action.accept(this);
}
+
+ @Override
+ public ResolvedReferenceType resolve() {
+ return getSymbolResolver().resolve(this, ResolvedReferenceType.class);
+ }
+
}
diff --git a/javaparser-core/src/main/java/com/github/javaparser/ast/type/IntersectionType.java b/javaparser-core/src/main/java/com/github/javaparser/ast/type/IntersectionType.java
index 8a719be4c..8799e7470 100644
--- a/javaparser-core/src/main/java/com/github/javaparser/ast/type/IntersectionType.java
+++ b/javaparser-core/src/main/java/com/github/javaparser/ast/type/IntersectionType.java
@@ -38,6 +38,9 @@ import static com.github.javaparser.utils.Utils.assertNotNull;
import static java.util.stream.Collectors.joining;
import javax.annotation.Generated;
import com.github.javaparser.TokenRange;
+import com.github.javaparser.resolution.types.ResolvedIntersectionType;
+import com.github.javaparser.resolution.types.ResolvedReferenceType;
+
import java.util.function.Consumer;
/**
@@ -165,4 +168,9 @@ public final class IntersectionType extends Type implements NodeWithAnnotations<
public void ifIntersectionType(Consumer<IntersectionType> action) {
action.accept(this);
}
+
+ @Override
+ public ResolvedIntersectionType resolve() {
+ return getSymbolResolver().resolve(this, ResolvedIntersectionType.class);
+ }
}
diff --git a/javaparser-core/src/main/java/com/github/javaparser/ast/type/PrimitiveType.java b/javaparser-core/src/main/java/com/github/javaparser/ast/type/PrimitiveType.java
index c98817533..c88ad7b1d 100644
--- a/javaparser-core/src/main/java/com/github/javaparser/ast/type/PrimitiveType.java
+++ b/javaparser-core/src/main/java/com/github/javaparser/ast/type/PrimitiveType.java
@@ -38,6 +38,9 @@ import com.github.javaparser.metamodel.PrimitiveTypeMetaModel;
import com.github.javaparser.metamodel.JavaParserMetaModel;
import javax.annotation.Generated;
import com.github.javaparser.TokenRange;
+import com.github.javaparser.resolution.types.ResolvedPrimitiveType;
+import com.github.javaparser.resolution.types.ResolvedReferenceType;
+
import java.util.function.Consumer;
/**
@@ -219,4 +222,9 @@ public final class PrimitiveType extends Type implements NodeWithAnnotations<Pri
public void ifPrimitiveType(Consumer<PrimitiveType> action) {
action.accept(this);
}
+
+ @Override
+ public ResolvedPrimitiveType resolve() {
+ return getSymbolResolver().resolve(this, ResolvedPrimitiveType.class);
+ }
}
diff --git a/javaparser-core/src/main/java/com/github/javaparser/ast/type/ReferenceType.java b/javaparser-core/src/main/java/com/github/javaparser/ast/type/ReferenceType.java
index f27b32c69..5b0d13b36 100644
--- a/javaparser-core/src/main/java/com/github/javaparser/ast/type/ReferenceType.java
+++ b/javaparser-core/src/main/java/com/github/javaparser/ast/type/ReferenceType.java
@@ -29,6 +29,8 @@ import com.github.javaparser.metamodel.ReferenceTypeMetaModel;
import com.github.javaparser.metamodel.JavaParserMetaModel;
import javax.annotation.Generated;
import com.github.javaparser.TokenRange;
+import com.github.javaparser.resolution.types.ResolvedReferenceType;
+
import java.util.function.Consumer;
/**
diff --git a/javaparser-core/src/main/java/com/github/javaparser/ast/type/Type.java b/javaparser-core/src/main/java/com/github/javaparser/ast/type/Type.java
index 2efe4887e..585bf029b 100644
--- a/javaparser-core/src/main/java/com/github/javaparser/ast/type/Type.java
+++ b/javaparser-core/src/main/java/com/github/javaparser/ast/type/Type.java
@@ -21,6 +21,7 @@
package com.github.javaparser.ast.type;
import com.github.javaparser.ast.AllFieldsConstructor;
+import com.github.javaparser.ast.DataKey;
import com.github.javaparser.ast.Node;
import com.github.javaparser.ast.NodeList;
import com.github.javaparser.ast.expr.AnnotationExpr;
@@ -31,7 +32,13 @@ import com.github.javaparser.metamodel.TypeMetaModel;
import static com.github.javaparser.utils.Utils.assertNotNull;
import javax.annotation.Generated;
import com.github.javaparser.TokenRange;
+import com.github.javaparser.resolution.Resolvable;
+import com.github.javaparser.resolution.SymbolResolver;
+import com.github.javaparser.resolution.types.ResolvedType;
+
import java.util.function.Consumer;
+import java.util.function.Supplier;
+
import static com.github.javaparser.utils.CodeGenerationUtils.f;
/**
@@ -39,7 +46,7 @@ import static com.github.javaparser.utils.CodeGenerationUtils.f;
*
* @author Julio Vilmar Gesser
*/
-public abstract class Type extends Node {
+public abstract class Type extends Node implements Resolvable<Object> {
private NodeList<AnnotationExpr> annotations;
@@ -288,4 +295,7 @@ public abstract class Type extends Node {
@Generated("com.github.javaparser.generator.core.node.TypeCastingGenerator")
public void ifWildcardType(Consumer<WildcardType> action) {
}
+
+ @Override
+ public abstract ResolvedType resolve();
}
diff --git a/javaparser-core/src/main/java/com/github/javaparser/ast/type/TypeParameter.java b/javaparser-core/src/main/java/com/github/javaparser/ast/type/TypeParameter.java
index 11d01c50f..3d4f470b7 100644
--- a/javaparser-core/src/main/java/com/github/javaparser/ast/type/TypeParameter.java
+++ b/javaparser-core/src/main/java/com/github/javaparser/ast/type/TypeParameter.java
@@ -30,8 +30,6 @@ import com.github.javaparser.ast.nodeTypes.NodeWithSimpleName;
import com.github.javaparser.ast.observer.ObservableProperty;
import com.github.javaparser.ast.visitor.GenericVisitor;
import com.github.javaparser.ast.visitor.VoidVisitor;
-import java.util.Arrays;
-import java.util.List;
import static com.github.javaparser.utils.Utils.assertNotNull;
import static java.util.stream.Collectors.joining;
import com.github.javaparser.ast.Node;
@@ -40,6 +38,9 @@ import com.github.javaparser.metamodel.TypeParameterMetaModel;
import com.github.javaparser.metamodel.JavaParserMetaModel;
import javax.annotation.Generated;
import com.github.javaparser.TokenRange;
+import com.github.javaparser.resolution.declarations.ResolvedTypeParameterDeclaration;
+import com.github.javaparser.resolution.types.ResolvedTypeVariable;
+
import java.util.function.Consumer;
/**
@@ -54,7 +55,8 @@ import java.util.function.Consumer;
* @author Julio Vilmar Gesser
* @see com.github.javaparser.ast.nodeTypes.NodeWithTypeParameters
*/
-public final class TypeParameter extends ReferenceType implements NodeWithSimpleName<TypeParameter>, NodeWithAnnotations<TypeParameter> {
+public final class TypeParameter extends ReferenceType
+ implements NodeWithSimpleName<TypeParameter>, NodeWithAnnotations<TypeParameter> {
private SimpleName name;
@@ -227,4 +229,9 @@ public final class TypeParameter extends ReferenceType implements NodeWithSimple
public void ifTypeParameter(Consumer<TypeParameter> action) {
action.accept(this);
}
+
+ @Override
+ public ResolvedTypeVariable resolve() {
+ return getSymbolResolver().resolve(this, ResolvedTypeVariable.class);
+ }
}
diff --git a/javaparser-core/src/main/java/com/github/javaparser/ast/type/UnionType.java b/javaparser-core/src/main/java/com/github/javaparser/ast/type/UnionType.java
index e6b48dd36..c60d2c443 100644
--- a/javaparser-core/src/main/java/com/github/javaparser/ast/type/UnionType.java
+++ b/javaparser-core/src/main/java/com/github/javaparser/ast/type/UnionType.java
@@ -38,6 +38,9 @@ import com.github.javaparser.metamodel.UnionTypeMetaModel;
import com.github.javaparser.metamodel.JavaParserMetaModel;
import javax.annotation.Generated;
import com.github.javaparser.TokenRange;
+import com.github.javaparser.resolution.types.ResolvedReferenceType;
+import com.github.javaparser.resolution.types.ResolvedUnionType;
+
import java.util.function.Consumer;
/**
@@ -174,4 +177,9 @@ public final class UnionType extends Type implements NodeWithAnnotations<UnionTy
public void ifUnionType(Consumer<UnionType> action) {
action.accept(this);
}
+
+ @Override
+ public ResolvedUnionType resolve() {
+ return getSymbolResolver().resolve(this, ResolvedUnionType.class);
+ }
}
diff --git a/javaparser-core/src/main/java/com/github/javaparser/ast/type/UnknownType.java b/javaparser-core/src/main/java/com/github/javaparser/ast/type/UnknownType.java
index 2bd7849e7..733fff848 100644
--- a/javaparser-core/src/main/java/com/github/javaparser/ast/type/UnknownType.java
+++ b/javaparser-core/src/main/java/com/github/javaparser/ast/type/UnknownType.java
@@ -33,6 +33,10 @@ import com.github.javaparser.metamodel.UnknownTypeMetaModel;
import com.github.javaparser.metamodel.JavaParserMetaModel;
import javax.annotation.Generated;
import com.github.javaparser.TokenRange;
+import com.github.javaparser.resolution.types.ResolvedReferenceType;
+import com.github.javaparser.resolution.types.ResolvedType;
+import com.github.javaparser.resolution.types.ResolvedUnionType;
+
import java.util.function.Consumer;
/**
@@ -125,4 +129,9 @@ public final class UnknownType extends Type {
public void ifUnknownType(Consumer<UnknownType> action) {
action.accept(this);
}
+
+ @Override
+ public ResolvedType resolve() {
+ return getSymbolResolver().resolve(this, ResolvedReferenceType.class);
+ }
}
diff --git a/javaparser-core/src/main/java/com/github/javaparser/ast/type/VoidType.java b/javaparser-core/src/main/java/com/github/javaparser/ast/type/VoidType.java
index 91f21054b..74420da36 100644
--- a/javaparser-core/src/main/java/com/github/javaparser/ast/type/VoidType.java
+++ b/javaparser-core/src/main/java/com/github/javaparser/ast/type/VoidType.java
@@ -34,6 +34,9 @@ import com.github.javaparser.metamodel.VoidTypeMetaModel;
import com.github.javaparser.metamodel.JavaParserMetaModel;
import javax.annotation.Generated;
import com.github.javaparser.TokenRange;
+import com.github.javaparser.resolution.types.ResolvedUnionType;
+import com.github.javaparser.resolution.types.ResolvedVoidType;
+
import java.util.function.Consumer;
/**
@@ -121,4 +124,9 @@ public final class VoidType extends Type implements NodeWithAnnotations<VoidType
public void ifVoidType(Consumer<VoidType> action) {
action.accept(this);
}
+
+ @Override
+ public ResolvedVoidType resolve() {
+ return getSymbolResolver().resolve(this, ResolvedVoidType.class);
+ }
}
diff --git a/javaparser-core/src/main/java/com/github/javaparser/ast/type/WildcardType.java b/javaparser-core/src/main/java/com/github/javaparser/ast/type/WildcardType.java
index f685ff8bf..fb23f7a36 100644
--- a/javaparser-core/src/main/java/com/github/javaparser/ast/type/WildcardType.java
+++ b/javaparser-core/src/main/java/com/github/javaparser/ast/type/WildcardType.java
@@ -36,6 +36,9 @@ import java.util.List;
import java.util.Optional;
import javax.annotation.Generated;
import com.github.javaparser.TokenRange;
+import com.github.javaparser.resolution.types.ResolvedUnionType;
+import com.github.javaparser.resolution.types.ResolvedWildcard;
+
import java.util.function.Consumer;
/**
@@ -276,4 +279,9 @@ public final class WildcardType extends Type implements NodeWithAnnotations<Wild
public void ifWildcardType(Consumer<WildcardType> action) {
action.accept(this);
}
+
+ @Override
+ public ResolvedWildcard resolve() {
+ return getSymbolResolver().resolve(this, ResolvedWildcard.class);
+ }
}
diff --git a/javaparser-core/src/main/java/com/github/javaparser/resolution/MethodAmbiguityException.java b/javaparser-core/src/main/java/com/github/javaparser/resolution/MethodAmbiguityException.java
new file mode 100644
index 000000000..76632c5ab
--- /dev/null
+++ b/javaparser-core/src/main/java/com/github/javaparser/resolution/MethodAmbiguityException.java
@@ -0,0 +1,38 @@
+/*
+ * Copyright (C) 2007-2010 Júlio Vilmar Gesser.
+ * Copyright (C) 2011, 2013-2016 The JavaParser Team.
+ *
+ * This file is part of JavaParser.
+ *
+ * JavaParser can be used either under the terms of
+ * a) the GNU Lesser General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ * b) the terms of the Apache License
+ *
+ * You should have received a copy of both licenses in LICENCE.LGPL and
+ * LICENCE.APACHE. Please refer to those files for details.
+ *
+ * JavaParser is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License for more details.
+ */
+
+package com.github.javaparser.resolution;
+
+/**
+ * It is not possible to decide how to resolve a method invocation.
+ *
+ * @author Federico Tomassetti
+ */
+public class MethodAmbiguityException extends RuntimeException {
+
+ /**
+ * Create an instance from a description of the reason why there is ambiguity in this particular case.
+ */
+ public MethodAmbiguityException(String description) {
+ super(description);
+ }
+
+}
diff --git a/javaparser-core/src/main/java/com/github/javaparser/resolution/MethodUsage.java b/javaparser-core/src/main/java/com/github/javaparser/resolution/MethodUsage.java
new file mode 100644
index 000000000..ec3a06bbe
--- /dev/null
+++ b/javaparser-core/src/main/java/com/github/javaparser/resolution/MethodUsage.java
@@ -0,0 +1,192 @@
+/*
+ * Copyright (C) 2007-2010 Júlio Vilmar Gesser.
+ * Copyright (C) 2011, 2013-2016 The JavaParser Team.
+ *
+ * This file is part of JavaParser.
+ *
+ * JavaParser can be used either under the terms of
+ * a) the GNU Lesser General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ * b) the terms of the Apache License
+ *
+ * You should have received a copy of both licenses in LICENCE.LGPL and
+ * LICENCE.APACHE. Please refer to those files for details.
+ *
+ * JavaParser is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License for more details.
+ */
+
+package com.github.javaparser.resolution;
+
+import com.github.javaparser.resolution.declarations.ResolvedMethodDeclaration;
+import com.github.javaparser.resolution.declarations.ResolvedReferenceTypeDeclaration;
+import com.github.javaparser.resolution.declarations.ResolvedTypeParameterDeclaration;
+import com.github.javaparser.resolution.types.ResolvedType;
+import com.github.javaparser.resolution.types.parametrization.ResolvedTypeParametersMap;
+import com.github.javaparser.resolution.types.parametrization.ResolvedTypeParametrized;
+
+
+import java.util.*;
+
+/**
+ * This is basically a MethodDeclaration with some TypeParameters defined.
+ * The defined TypeParameters can comes from the Method itself or from the surrounding types.
+ *
+ * @author Federico Tomassetti
+ */
+public class MethodUsage implements ResolvedTypeParametrized {
+ private ResolvedMethodDeclaration declaration;
+ private List<ResolvedType> paramTypes = new ArrayList<>();
+ private List<ResolvedType> exceptionTypes = new ArrayList<>();
+ private ResolvedType returnType;
+ private ResolvedTypeParametersMap typeParametersMap;
+
+ public MethodUsage(ResolvedMethodDeclaration declaration) {
+ this.typeParametersMap = ResolvedTypeParametersMap.empty();
+ this.declaration = declaration;
+ for (int i = 0; i < declaration.getNumberOfParams(); i++) {
+ paramTypes.add(declaration.getParam(i).getType());
+ }
+ for (int i = 0; i < declaration.getNumberOfSpecifiedExceptions(); i++) {
+ exceptionTypes.add(declaration.getSpecifiedException(i));
+ }
+ returnType = declaration.getReturnType();
+ }
+
+ public MethodUsage(ResolvedMethodDeclaration declaration,
+ List<ResolvedType> paramTypes, ResolvedType returnType) {
+ this(declaration, paramTypes, returnType, declaration.getSpecifiedExceptions(),
+ ResolvedTypeParametersMap.empty());
+ }
+
+ public MethodUsage(ResolvedMethodDeclaration declaration, List<ResolvedType> paramTypes, ResolvedType returnType,
+ List<ResolvedType> exceptionTypes) {
+ this(declaration, paramTypes, returnType, exceptionTypes, ResolvedTypeParametersMap.empty());
+ }
+
+ private MethodUsage(ResolvedMethodDeclaration declaration, List<ResolvedType> paramTypes, ResolvedType returnType,
+ List<ResolvedType> exceptionTypes, ResolvedTypeParametersMap typeParametersMap) {
+ this.declaration = declaration;
+ this.paramTypes = paramTypes;
+ this.returnType = returnType;
+ this.exceptionTypes = exceptionTypes;
+ this.typeParametersMap = typeParametersMap;
+ }
+
+ @Override
+ public String toString() {
+ return "MethodUsage{" +
+ "declaration=" + declaration +
+ ", paramTypes=" + paramTypes +
+ '}';
+ }
+
+ public ResolvedMethodDeclaration getDeclaration() {
+ return declaration;
+ }
+
+ public String getName() {
+ return declaration.getName();
+ }
+
+ public ResolvedReferenceTypeDeclaration declaringType() {
+ return declaration.declaringType();
+ }
+
+ public ResolvedType returnType() {
+ return returnType;
+ }
+
+ public List<ResolvedType> getParamTypes() {
+ return paramTypes;
+ }
+
+ public MethodUsage replaceParamType(int i, ResolvedType replaced) {
+ if (i < 0 || i >= getNoParams()) {
+ throw new IllegalArgumentException();
+ }
+ if (paramTypes.get(i) == replaced) {
+ return this;
+ }
+ List<ResolvedType> newParams = new LinkedList<>(paramTypes);
+ newParams.set(i, replaced);
+ return new MethodUsage(declaration, newParams, returnType, exceptionTypes, typeParametersMap);
+ }
+
+ public MethodUsage replaceExceptionType(int i, ResolvedType replaced) {
+ if (i < 0 || i >= exceptionTypes.size()) {
+ throw new IllegalArgumentException();
+ }
+ if (exceptionTypes.get(i) == replaced) {
+ return this;
+ }
+ List<ResolvedType> newTypes = new LinkedList<>(exceptionTypes);
+ newTypes.set(i, replaced);
+ return new MethodUsage(declaration, paramTypes, returnType, newTypes, typeParametersMap);
+ }
+
+ public MethodUsage replaceReturnType(ResolvedType returnType) {
+ if (returnType == this.returnType) {
+ return this;
+ } else {
+ return new MethodUsage(declaration, paramTypes, returnType, exceptionTypes, typeParametersMap);
+ }
+ }
+
+ /**
+ * Return the number of formal arguments accepted by this method.
+ */
+ public int getNoParams() {
+ return paramTypes.size();
+ }
+
+ /**
+ * Return the type of the formal argument at the given position.
+ */
+ public ResolvedType getParamType(int i) {
+ return paramTypes.get(i);
+ }
+
+ 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;
+ }
+
+ @Override
+ public ResolvedTypeParametersMap typeParametersMap() {
+ return typeParametersMap;
+ }
+
+ public String getQualifiedSignature() {
+ // TODO use the type parameters
+ return this.getDeclaration().getQualifiedSignature();
+ }
+
+ public List<ResolvedType> exceptionTypes() {
+ return exceptionTypes;
+ }
+}
diff --git a/javaparser-core/src/main/java/com/github/javaparser/resolution/Resolvable.java b/javaparser-core/src/main/java/com/github/javaparser/resolution/Resolvable.java
new file mode 100644
index 000000000..2b12a1bb8
--- /dev/null
+++ b/javaparser-core/src/main/java/com/github/javaparser/resolution/Resolvable.java
@@ -0,0 +1,26 @@
+/*
+ * Copyright (C) 2007-2010 Júlio Vilmar Gesser.
+ * Copyright (C) 2011, 2013-2016 The JavaParser Team.
+ *
+ * This file is part of JavaParser.
+ *
+ * JavaParser can be used either under the terms of
+ * a) the GNU Lesser General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ * b) the terms of the Apache License
+ *
+ * You should have received a copy of both licenses in LICENCE.LGPL and
+ * LICENCE.APACHE. Please refer to those files for details.
+ *
+ * JavaParser is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License for more details.
+ */
+
+package com.github.javaparser.resolution;
+
+public interface Resolvable<T> {
+ T resolve();
+}
diff --git a/javaparser-core/src/main/java/com/github/javaparser/resolution/SymbolResolver.java b/javaparser-core/src/main/java/com/github/javaparser/resolution/SymbolResolver.java
new file mode 100644
index 000000000..977fb0904
--- /dev/null
+++ b/javaparser-core/src/main/java/com/github/javaparser/resolution/SymbolResolver.java
@@ -0,0 +1,28 @@
+/*
+ * Copyright (C) 2007-2010 Júlio Vilmar Gesser.
+ * Copyright (C) 2011, 2013-2016 The JavaParser Team.
+ *
+ * This file is part of JavaParser.
+ *
+ * JavaParser can be used either under the terms of
+ * a) the GNU Lesser General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ * b) the terms of the Apache License
+ *
+ * You should have received a copy of both licenses in LICENCE.LGPL and
+ * LICENCE.APACHE. Please refer to those files for details.
+ *
+ * JavaParser is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License for more details.
+ */
+
+package com.github.javaparser.resolution;
+
+import com.github.javaparser.ast.Node;
+
+public interface SymbolResolver {
+ <T> T resolve(Node node, Class<T> resultClass);
+}
diff --git a/javaparser-core/src/main/java/com/github/javaparser/resolution/UnsolvedSymbolException.java b/javaparser-core/src/main/java/com/github/javaparser/resolution/UnsolvedSymbolException.java
new file mode 100644
index 000000000..b915096d0
--- /dev/null
+++ b/javaparser-core/src/main/java/com/github/javaparser/resolution/UnsolvedSymbolException.java
@@ -0,0 +1,53 @@
+/*
+ * Copyright (C) 2007-2010 Júlio Vilmar Gesser.
+ * Copyright (C) 2011, 2013-2016 The JavaParser Team.
+ *
+ * This file is part of JavaParser.
+ *
+ * JavaParser can be used either under the terms of
+ * a) the GNU Lesser General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ * b) the terms of the Apache License
+ *
+ * You should have received a copy of both licenses in LICENCE.LGPL and
+ * LICENCE.APACHE. Please refer to those files for details.
+ *
+ * JavaParser is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License for more details.
+ */
+
+package com.github.javaparser.resolution;
+
+/**
+ * This exception is thrown when a symbol cannot be resolved.
+ *
+ * @author Federico Tomassetti
+ */
+public class UnsolvedSymbolException extends RuntimeException {
+
+ private String context;
+ private String name;
+
+ public UnsolvedSymbolException(String name, String context) {
+ super("Unsolved symbol in " + context + " : " + name);
+ this.context = context;
+ this.name = name;
+ }
+
+ public UnsolvedSymbolException(String name) {
+ super("Unsolved symbol : " + name);
+ this.context = "unknown";
+ this.name = name;
+ }
+
+ @Override
+ public String toString() {
+ return "UnsolvedSymbolException{" +
+ "context='" + context + '\'' +
+ ", name='" + name + '\''+
+ '}';
+ }
+}
diff --git a/javaparser-core/src/main/java/com/github/javaparser/resolution/declarations/HasAccessSpecifier.java b/javaparser-core/src/main/java/com/github/javaparser/resolution/declarations/HasAccessSpecifier.java
new file mode 100644
index 000000000..5d7e5bb55
--- /dev/null
+++ b/javaparser-core/src/main/java/com/github/javaparser/resolution/declarations/HasAccessSpecifier.java
@@ -0,0 +1,38 @@
+/*
+ * Copyright (C) 2007-2010 Júlio Vilmar Gesser.
+ * Copyright (C) 2011, 2013-2016 The JavaParser Team.
+ *
+ * This file is part of JavaParser.
+ *
+ * JavaParser can be used either under the terms of
+ * a) the GNU Lesser General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ * b) the terms of the Apache License
+ *
+ * You should have received a copy of both licenses in LICENCE.LGPL and
+ * LICENCE.APACHE. Please refer to those files for details.
+ *
+ * JavaParser is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License for more details.
+ */
+
+package com.github.javaparser.resolution.declarations;
+
+import com.github.javaparser.ast.AccessSpecifier;
+
+/**
+ * Anything which can have an AccessSpecifier.
+ *
+ * @author Federico Tomassetti
+ */
+public interface HasAccessSpecifier {
+
+ /**
+ * The access specifier of this element.
+ */
+ AccessSpecifier accessSpecifier();
+
+}
diff --git a/javaparser-core/src/main/java/com/github/javaparser/resolution/declarations/ResolvedAnnotationDeclaration.java b/javaparser-core/src/main/java/com/github/javaparser/resolution/declarations/ResolvedAnnotationDeclaration.java
new file mode 100644
index 000000000..f52937c06
--- /dev/null
+++ b/javaparser-core/src/main/java/com/github/javaparser/resolution/declarations/ResolvedAnnotationDeclaration.java
@@ -0,0 +1,28 @@
+/*
+ * Copyright (C) 2007-2010 Júlio Vilmar Gesser.
+ * Copyright (C) 2011, 2013-2016 The JavaParser Team.
+ *
+ * This file is part of JavaParser.
+ *
+ * JavaParser can be used either under the terms of
+ * a) the GNU Lesser General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ * b) the terms of the Apache License
+ *
+ * You should have received a copy of both licenses in LICENCE.LGPL and
+ * LICENCE.APACHE. Please refer to those files for details.
+ *
+ * JavaParser is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License for more details.
+ */
+
+package com.github.javaparser.resolution.declarations;
+
+/**
+ * @author Federico Tomassetti
+ */
+public interface ResolvedAnnotationDeclaration extends ResolvedReferenceTypeDeclaration {
+}
diff --git a/javaparser-core/src/main/java/com/github/javaparser/resolution/declarations/ResolvedClassDeclaration.java b/javaparser-core/src/main/java/com/github/javaparser/resolution/declarations/ResolvedClassDeclaration.java
new file mode 100644
index 000000000..08a8d75a2
--- /dev/null
+++ b/javaparser-core/src/main/java/com/github/javaparser/resolution/declarations/ResolvedClassDeclaration.java
@@ -0,0 +1,85 @@
+/*
+ * Copyright (C) 2007-2010 Júlio Vilmar Gesser.
+ * Copyright (C) 2011, 2013-2016 The JavaParser Team.
+ *
+ * This file is part of JavaParser.
+ *
+ * JavaParser can be used either under the terms of
+ * a) the GNU Lesser General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ * b) the terms of the Apache License
+ *
+ * You should have received a copy of both licenses in LICENCE.LGPL and
+ * LICENCE.APACHE. Please refer to those files for details.
+ *
+ * JavaParser is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License for more details.
+ */
+
+package com.github.javaparser.resolution.declarations;
+
+import com.github.javaparser.resolution.types.ResolvedReferenceType;
+
+import java.util.List;
+
+/**
+ * Declaration of a Class (not an interface or an enum).
+ *
+ * @author Federico Tomassetti
+ */
+public interface ResolvedClassDeclaration extends ResolvedReferenceTypeDeclaration,
+ ResolvedTypeParametrizable, HasAccessSpecifier {
+
+ /**
+ * This method should always return true.
+ */
+ @Override
+ default boolean isClass() {
+ return true;
+ }
+
+ /**
+ * This is a ReferenceTypeUsage because it could contain type typeParametersValues.
+ * For example: class A extends B<Integer, String>.
+ * <p>
+ * Note that only the Object class should not have a superclass and therefore
+ * return null.
+ */
+ ResolvedReferenceType getSuperClass();
+
+ /**
+ * Return all the interfaces implemented directly by this class.
+ * It does not include the interfaces implemented by superclasses or extended
+ * by the interfaces implemented.
+ */
+ List<ResolvedReferenceType> getInterfaces();
+
+ /**
+ * Get all superclasses, with all the type typeParametersValues expressed as functions of the type
+ * typeParametersValues of this declaration.
+ */
+ List<ResolvedReferenceType> getAllSuperClasses();
+
+ /**
+ * Return all the interfaces implemented by this class, either directly or indirectly, including the interfaces
+ * extended by interfaces it implements.
+ * <p>
+ * Get all interfaces, with all the type typeParametersValues expressed as functions of the type
+ * typeParametersValues of this declaration.
+ */
+ List<ResolvedReferenceType> getAllInterfaces();
+
+ ///
+ /// Constructors
+ ///
+
+ /**
+ * List of constructors available for the class.
+ * This list should also include the default constructor.
+ */
+ List<ResolvedConstructorDeclaration> getConstructors();
+
+}
diff --git a/javaparser-core/src/main/java/com/github/javaparser/resolution/declarations/ResolvedConstructorDeclaration.java b/javaparser-core/src/main/java/com/github/javaparser/resolution/declarations/ResolvedConstructorDeclaration.java
new file mode 100644
index 000000000..4bc6cb4e4
--- /dev/null
+++ b/javaparser-core/src/main/java/com/github/javaparser/resolution/declarations/ResolvedConstructorDeclaration.java
@@ -0,0 +1,33 @@
+/*
+ * Copyright (C) 2007-2010 Júlio Vilmar Gesser.
+ * Copyright (C) 2011, 2013-2016 The JavaParser Team.
+ *
+ * This file is part of JavaParser.
+ *
+ * JavaParser can be used either under the terms of
+ * a) the GNU Lesser General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ * b) the terms of the Apache License
+ *
+ * You should have received a copy of both licenses in LICENCE.LGPL and
+ * LICENCE.APACHE. Please refer to those files for details.
+ *
+ * JavaParser is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License for more details.
+ */
+
+package com.github.javaparser.resolution.declarations;
+
+/**
+ * A declaration of a constructor.
+ *
+ * @author Federico Tomassetti
+ */
+public interface ResolvedConstructorDeclaration extends ResolvedMethodLikeDeclaration {
+
+ @Override
+ ResolvedClassDeclaration declaringType();
+}
diff --git a/javaparser-core/src/main/java/com/github/javaparser/resolution/declarations/ResolvedDeclaration.java b/javaparser-core/src/main/java/com/github/javaparser/resolution/declarations/ResolvedDeclaration.java
new file mode 100644
index 000000000..86bee80aa
--- /dev/null
+++ b/javaparser-core/src/main/java/com/github/javaparser/resolution/declarations/ResolvedDeclaration.java
@@ -0,0 +1,98 @@
+/*
+ * Copyright (C) 2007-2010 Júlio Vilmar Gesser.
+ * Copyright (C) 2011, 2013-2016 The JavaParser Team.
+ *
+ * This file is part of JavaParser.
+ *
+ * JavaParser can be used either under the terms of
+ * a) the GNU Lesser General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ * b) the terms of the Apache License
+ *
+ * You should have received a copy of both licenses in LICENCE.LGPL and
+ * LICENCE.APACHE. Please refer to those files for details.
+ *
+ * JavaParser is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License for more details.
+ */
+
+package com.github.javaparser.resolution.declarations;
+
+/**
+ * A generic declaration.
+ *
+ * @author Federico Tomassetti
+ */
+public interface ResolvedDeclaration {
+
+ /**
+ * Anonymous classes do not have a name, for example.
+ */
+ default boolean hasName() {
+ return true;
+ }
+
+ /**
+ * Should return the name or throw a RuntimeException if the name is not available.
+ */
+ String getName();
+
+ /**
+ * Does this declaration represents a class field?
+ */
+ default boolean isField() {
+ return false;
+ }
+
+ /**
+ * Does this declaration represents a method parameter?
+ */
+ default boolean isParameter() {
+ return false;
+ }
+
+ /**
+ * Does this declaration represents a type?
+ */
+ default boolean isType() {
+ return false;
+ }
+
+ /**
+ * Does this declaration represents a method?
+ */
+ default boolean isMethod() {
+ return false;
+ }
+
+ /**
+ * Return this as a FieldDeclaration or throw an UnsupportedOperationException
+ */
+ default ResolvedFieldDeclaration asField() {
+ throw new UnsupportedOperationException(String.format("%s is not a FieldDeclaration", this));
+ }
+
+ /**
+ * Return this as a ParameterDeclaration or throw an UnsupportedOperationException
+ */
+ default ResolvedParameterDeclaration asParameter() {
+ throw new UnsupportedOperationException(String.format("%s is not a ParameterDeclaration", this));
+ }
+
+ /**
+ * Return this as a TypeDeclaration or throw an UnsupportedOperationException
+ */
+ default ResolvedTypeDeclaration asType() {
+ throw new UnsupportedOperationException(String.format("%s is not a TypeDeclaration", this));
+ }
+
+ /**
+ * Return this as a MethodDeclaration or throw an UnsupportedOperationException
+ */
+ default ResolvedMethodDeclaration asMethod() {
+ throw new UnsupportedOperationException(String.format("%s is not a MethodDeclaration", this));
+ }
+}
diff --git a/javaparser-core/src/main/java/com/github/javaparser/resolution/declarations/ResolvedEnumDeclaration.java b/javaparser-core/src/main/java/com/github/javaparser/resolution/declarations/ResolvedEnumDeclaration.java
new file mode 100644
index 000000000..20fd38932
--- /dev/null
+++ b/javaparser-core/src/main/java/com/github/javaparser/resolution/declarations/ResolvedEnumDeclaration.java
@@ -0,0 +1,41 @@
+/*
+ * Copyright (C) 2007-2010 Júlio Vilmar Gesser.
+ * Copyright (C) 2011, 2013-2016 The JavaParser Team.
+ *
+ * This file is part of JavaParser.
+ *
+ * JavaParser can be used either under the terms of
+ * a) the GNU Lesser General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ * b) the terms of the Apache License
+ *
+ * You should have received a copy of both licenses in LICENCE.LGPL and
+ * LICENCE.APACHE. Please refer to those files for details.
+ *
+ * JavaParser is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License for more details.
+ */
+
+package com.github.javaparser.resolution.declarations;
+
+/**
+ * Declaration of an Enum.
+ *
+ * @author Federico Tomassetti
+ */
+public interface ResolvedEnumDeclaration extends ResolvedReferenceTypeDeclaration,
+ HasAccessSpecifier {
+
+ @Override
+ default boolean isEnum() {
+ return true;
+ }
+
+ @Override
+ default ResolvedEnumDeclaration asEnum() {
+ return this;
+ }
+}
diff --git a/javaparser-core/src/main/java/com/github/javaparser/resolution/declarations/ResolvedFieldDeclaration.java b/javaparser-core/src/main/java/com/github/javaparser/resolution/declarations/ResolvedFieldDeclaration.java
new file mode 100644
index 000000000..194c892c5
--- /dev/null
+++ b/javaparser-core/src/main/java/com/github/javaparser/resolution/declarations/ResolvedFieldDeclaration.java
@@ -0,0 +1,51 @@
+/*
+ * Copyright (C) 2007-2010 Júlio Vilmar Gesser.
+ * Copyright (C) 2011, 2013-2016 The JavaParser Team.
+ *
+ * This file is part of JavaParser.
+ *
+ * JavaParser can be used either under the terms of
+ * a) the GNU Lesser General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ * b) the terms of the Apache License
+ *
+ * You should have received a copy of both licenses in LICENCE.LGPL and
+ * LICENCE.APACHE. Please refer to those files for details.
+ *
+ * JavaParser is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License for more details.
+ */
+
+package com.github.javaparser.resolution.declarations;
+
+/**
+ * Declaration of a field.
+ *
+ * @author Federico Tomassetti
+ */
+public interface ResolvedFieldDeclaration extends ResolvedValueDeclaration, HasAccessSpecifier {
+
+ /**
+ * Is the field static?
+ */
+ boolean isStatic();
+
+ @Override
+ default boolean isField() {
+ return true;
+ }
+
+ @Override
+ default ResolvedFieldDeclaration asField() {
+ return this;
+ }
+
+ /**
+ * The type on which this field has been declared
+ */
+ ResolvedTypeDeclaration declaringType();
+
+}
diff --git a/javaparser-core/src/main/java/com/github/javaparser/resolution/declarations/ResolvedInterfaceDeclaration.java b/javaparser-core/src/main/java/com/github/javaparser/resolution/declarations/ResolvedInterfaceDeclaration.java
new file mode 100644
index 000000000..5ef53b2ce
--- /dev/null
+++ b/javaparser-core/src/main/java/com/github/javaparser/resolution/declarations/ResolvedInterfaceDeclaration.java
@@ -0,0 +1,58 @@
+/*
+ * Copyright (C) 2007-2010 Júlio Vilmar Gesser.
+ * Copyright (C) 2011, 2013-2016 The JavaParser Team.
+ *
+ * This file is part of JavaParser.
+ *
+ * JavaParser can be used either under the terms of
+ * a) the GNU Lesser General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ * b) the terms of the Apache License
+ *
+ * You should have received a copy of both licenses in LICENCE.LGPL and
+ * LICENCE.APACHE. Please refer to those files for details.
+ *
+ * JavaParser is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License for more details.
+ */
+
+package com.github.javaparser.resolution.declarations;
+
+import com.github.javaparser.resolution.types.ResolvedReferenceType;
+
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * An interface declaration.
+ *
+ * @author Federico Tomassetti
+ */
+public interface ResolvedInterfaceDeclaration extends ResolvedReferenceTypeDeclaration,
+ ResolvedTypeParametrizable, HasAccessSpecifier {
+
+ @Override
+ default boolean isInterface() {
+ return true;
+ }
+
+ /**
+ * Return the list of interfaces extended directly by this one.
+ */
+ List<ResolvedReferenceType> getInterfacesExtended();
+
+ /**
+ * Return the list of interfaces extended directly or indirectly by this one.
+ */
+ default List<ResolvedReferenceType> getAllInterfacesExtended() {
+ List<ResolvedReferenceType> interfaces = new ArrayList<>();
+ for (ResolvedReferenceType interfaceDeclaration : getInterfacesExtended()) {
+ interfaces.add(interfaceDeclaration);
+ interfaces.addAll(interfaceDeclaration.getAllInterfacesAncestors());
+ }
+ return interfaces;
+ }
+}
diff --git a/javaparser-core/src/main/java/com/github/javaparser/resolution/declarations/ResolvedMethodDeclaration.java b/javaparser-core/src/main/java/com/github/javaparser/resolution/declarations/ResolvedMethodDeclaration.java
new file mode 100644
index 000000000..9f2f64ce3
--- /dev/null
+++ b/javaparser-core/src/main/java/com/github/javaparser/resolution/declarations/ResolvedMethodDeclaration.java
@@ -0,0 +1,54 @@
+/*
+ * Copyright (C) 2007-2010 Júlio Vilmar Gesser.
+ * Copyright (C) 2011, 2013-2016 The JavaParser Team.
+ *
+ * This file is part of JavaParser.
+ *
+ * JavaParser can be used either under the terms of
+ * a) the GNU Lesser General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ * b) the terms of the Apache License
+ *
+ * You should have received a copy of both licenses in LICENCE.LGPL and
+ * LICENCE.APACHE. Please refer to those files for details.
+ *
+ * JavaParser is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License for more details.
+ */
+
+package com.github.javaparser.resolution.declarations;
+
+import com.github.javaparser.resolution.types.ResolvedType;
+
+/**
+ * A declaration of a method (either in an interface, a class, an enum or an annotation).
+ *
+ * @author Federico Tomassetti
+ */
+public interface ResolvedMethodDeclaration extends ResolvedMethodLikeDeclaration {
+
+ /**
+ * The type of the value returned by the current method. This method can also be invoked
+ * for methods returning void.
+ */
+ ResolvedType getReturnType();
+
+ /**
+ * Is the method abstract? All interface methods not marked as default are abstract.
+ */
+ boolean isAbstract();
+
+ /**
+ * Is this a default method?
+ */
+ boolean isDefaultMethod();
+
+ /*
+ * Is this method static?
+ */
+ boolean isStatic();
+
+}
diff --git a/javaparser-core/src/main/java/com/github/javaparser/resolution/declarations/ResolvedMethodLikeDeclaration.java b/javaparser-core/src/main/java/com/github/javaparser/resolution/declarations/ResolvedMethodLikeDeclaration.java
new file mode 100644
index 000000000..90aa2e72d
--- /dev/null
+++ b/javaparser-core/src/main/java/com/github/javaparser/resolution/declarations/ResolvedMethodLikeDeclaration.java
@@ -0,0 +1,159 @@
+/*
+ * Copyright (C) 2007-2010 Júlio Vilmar Gesser.
+ * Copyright (C) 2011, 2013-2016 The JavaParser Team.
+ *
+ * This file is part of JavaParser.
+ *
+ * JavaParser can be used either under the terms of
+ * a) the GNU Lesser General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ * b) the terms of the Apache License
+ *
+ * You should have received a copy of both licenses in LICENCE.LGPL and
+ * LICENCE.APACHE. Please refer to those files for details.
+ *
+ * JavaParser is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License for more details.
+ */
+
+package com.github.javaparser.resolution.declarations;
+
+import com.github.javaparser.resolution.types.ResolvedType;
+
+import java.util.Collections;
+import java.util.LinkedList;
+import java.util.List;
+import java.util.Optional;
+
+/**
+ * This is a common interface for MethodDeclaration and ConstructorDeclaration.
+ *
+ * @author Federico Tomassetti
+ */
+public interface ResolvedMethodLikeDeclaration extends ResolvedDeclaration,
+ ResolvedTypeParametrizable, HasAccessSpecifier {
+ /**
+ * The package name of the declaring type.
+ */
+ default String getPackageName() {
+ return declaringType().getPackageName();
+ }
+
+ /**
+ * The class(es) wrapping the declaring type.
+ */
+ default String getClassName() {
+ return declaringType().getClassName();
+ }
+
+ /**
+ * The qualified name of the method composed by the qualfied name of the declaring type
+ * followed by a dot and the name of the method.
+ */
+ default String getQualifiedName() {
+ return declaringType().getQualifiedName() + "." + this.getName();
+ }
+
+ /**
+ * The signature of the method.
+ */
+ default String getSignature() {
+ StringBuffer sb = new StringBuffer();
+ sb.append(getName());
+ sb.append("(");
+ for (int i = 0; i < getNumberOfParams(); i++) {
+ if (i != 0) {
+ sb.append(", ");
+ }
+ sb.append(getParam(i).describeType());
+ }
+ sb.append(")");
+ return sb.toString();
+ }
+
+ /**
+ * The qualified signature of the method. It is composed by the qualified name of the declaring type
+ * followed by the signature of the method.
+ */
+ default String getQualifiedSignature() {
+ return declaringType().getId() + "." + this.getSignature();
+ }
+
+ /**
+ * The type in which the method is declared.
+ */
+ ResolvedReferenceTypeDeclaration declaringType();
+
+ /**
+ * Number of params.
+ */
+ int getNumberOfParams();
+
+ /**
+ * Get the ParameterDeclaration at the corresponding position or throw IllegalArgumentException.
+ */
+ ResolvedParameterDeclaration getParam(int i);
+
+ /**
+ * Utility method to get the last ParameterDeclaration. It throws UnsupportedOperationException if the method
+ * has no parameters.
+ * The last parameter can be variadic and sometimes it needs to be handled in a special way.
+ */
+ default ResolvedParameterDeclaration getLastParam() {
+ if (getNumberOfParams() == 0) {
+ throw new UnsupportedOperationException("This method has no typeParametersValues, therefore it has no a last parameter");
+ }
+ return getParam(getNumberOfParams() - 1);
+ }
+
+ /**
+ * Has the method or construcor a variadic parameter?
+ * Note that when a method has a variadic parameter it should have an array type.
+ */
+ default boolean hasVariadicParameter() {
+ if (getNumberOfParams() == 0) {
+ return false;
+ } else {
+ return getParam(getNumberOfParams() - 1).isVariadic();
+ }
+ }
+
+ @Override
+ default Optional<ResolvedTypeParameterDeclaration> findTypeParameter(String name) {
+ for (ResolvedTypeParameterDeclaration tp : this.getTypeParameters()) {
+ if (tp.getName().equals(name)) {
+ return Optional.of(tp);
+ }
+ }
+ return declaringType().findTypeParameter(name);
+ }
+
+ /**
+ * Number of exceptions listed in the throws clause.
+ */
+ int getNumberOfSpecifiedExceptions();
+
+ /**
+ * Type of the corresponding entry in the throws clause.
+ *
+ * @throws IllegalArgumentException if the index is negative or it is equal or greater than the value returned by
+ * getNumberOfSpecifiedExceptions
+ * @throws UnsupportedOperationException for those types of methods of constructor that do not declare exceptions
+ */
+ ResolvedType getSpecifiedException(int index);
+
+ default List<ResolvedType> getSpecifiedExceptions() {
+ if (getNumberOfSpecifiedExceptions() == 0) {
+ return Collections.emptyList();
+ } else {
+ List<ResolvedType> exceptions = new LinkedList<>();
+ for (int i=0;i<getNumberOfSpecifiedExceptions();i++) {
+ exceptions.add(getSpecifiedException(i));
+ }
+ return exceptions;
+ }
+ }
+}
diff --git a/javaparser-core/src/main/java/com/github/javaparser/resolution/declarations/ResolvedParameterDeclaration.java b/javaparser-core/src/main/java/com/github/javaparser/resolution/declarations/ResolvedParameterDeclaration.java
new file mode 100644
index 000000000..668652271
--- /dev/null
+++ b/javaparser-core/src/main/java/com/github/javaparser/resolution/declarations/ResolvedParameterDeclaration.java
@@ -0,0 +1,57 @@
+/*
+ * Copyright (C) 2007-2010 Júlio Vilmar Gesser.
+ * Copyright (C) 2011, 2013-2016 The JavaParser Team.
+ *
+ * This file is part of JavaParser.
+ *
+ * JavaParser can be used either under the terms of
+ * a) the GNU Lesser General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ * b) the terms of the Apache License
+ *
+ * You should have received a copy of both licenses in LICENCE.LGPL and
+ * LICENCE.APACHE. Please refer to those files for details.
+ *
+ * JavaParser is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License for more details.
+ */
+
+package com.github.javaparser.resolution.declarations;
+
+/**
+ * Declaration of a parameter.
+ *
+ * @author Federico Tomassetti
+ */
+public interface ResolvedParameterDeclaration extends ResolvedValueDeclaration {
+
+ @Override
+ default boolean isParameter() {
+ return true;
+ }
+
+ @Override
+ default ResolvedParameterDeclaration asParameter() {
+ return this;
+ }
+
+ /**
+ * Is this parameter declared as variadic?
+ */
+ boolean isVariadic();
+
+ /**
+ * Describe the type of the parameter. In practice add three dots to the type name
+ * is the parameter is variadic.
+ */
+ default String describeType() {
+ if (isVariadic()) {
+ return getType().asArrayType().getComponentType().describe() + "...";
+ } else {
+ return getType().describe();
+ }
+ }
+}
diff --git a/javaparser-core/src/main/java/com/github/javaparser/resolution/declarations/ResolvedReferenceTypeDeclaration.java b/javaparser-core/src/main/java/com/github/javaparser/resolution/declarations/ResolvedReferenceTypeDeclaration.java
new file mode 100644
index 000000000..b39521067
--- /dev/null
+++ b/javaparser-core/src/main/java/com/github/javaparser/resolution/declarations/ResolvedReferenceTypeDeclaration.java
@@ -0,0 +1,246 @@
+/*
+ * Copyright (C) 2007-2010 Júlio Vilmar Gesser.
+ * Copyright (C) 2011, 2013-2016 The JavaParser Team.
+ *
+ * This file is part of JavaParser.
+ *
+ * JavaParser can be used either under the terms of
+ * a) the GNU Lesser General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ * b) the terms of the Apache License
+ *
+ * You should have received a copy of both licenses in LICENCE.LGPL and
+ * LICENCE.APACHE. Please refer to those files for details.
+ *
+ * JavaParser is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License for more details.
+ */
+
+package com.github.javaparser.resolution.declarations;
+
+import com.github.javaparser.ast.AccessSpecifier;
+import com.github.javaparser.resolution.MethodUsage;
+import com.github.javaparser.resolution.UnsolvedSymbolException;
+import com.github.javaparser.resolution.types.ResolvedReferenceType;
+import com.github.javaparser.resolution.types.ResolvedType;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Optional;
+import java.util.Set;
+import java.util.stream.Collectors;
+
+/**
+ * @author Federico Tomassetti
+ */
+public interface ResolvedReferenceTypeDeclaration extends ResolvedTypeDeclaration,
+ ResolvedTypeParametrizable {
+
+ @Override
+ default ResolvedReferenceTypeDeclaration asReferenceType() {
+ return this;
+ }
+
+ ///
+ /// Ancestors
+ ///
+
+ /**
+ * The list of all the direct ancestors of the current declaration.
+ * Note that the ancestor can be parametrized types with values specified. For example:
+ * <p>
+ * class A implements Comparable&lt;String&gt; {}
+ * <p>
+ * In this case the ancestor is Comparable&lt;String&gt;
+ */
+ List<ResolvedReferenceType> getAncestors();
+
+ /**
+ * The list of all the ancestors of the current declaration, direct and indirect.
+ * This list does not contains duplicates with the exacting same type parameters.
+ */
+ default List<ResolvedReferenceType> getAllAncestors() {
+ List<ResolvedReferenceType> ancestors = new ArrayList<>();
+ // We want to avoid infinite recursion in case of Object having Object as ancestor
+ if (!(Object.class.getCanonicalName().equals(getQualifiedName()))) {
+ for (ResolvedReferenceType ancestor : getAncestors()) {
+ ancestors.add(ancestor);
+ for (ResolvedReferenceType inheritedAncestor : ancestor.getAllAncestors()) {
+ if (!ancestors.contains(inheritedAncestor)) {
+ ancestors.add(inheritedAncestor);
+ }
+ }
+ }
+ }
+ return ancestors;
+ }
+
+ ///
+ /// Fields
+ ///
+
+ /**
+ * Note that the type of the field should be expressed using the type variables of this particular type.
+ * Consider for example:
+ * <p>
+ * class Foo<E> { E field; }
+ * <p>
+ * class Bar extends Foo<String> { }
+ * <p>
+ * When calling getField("field") on Foo I should get a FieldDeclaration with type E, while calling it on
+ * Bar I should get a FieldDeclaration with type String.
+ */
+ default ResolvedFieldDeclaration getField(String name) {
+ Optional<ResolvedFieldDeclaration> field = this.getAllFields().stream().filter(f -> f.getName().equals(name)).findFirst();
+ if (field.isPresent()) {
+ return field.get();
+ } else {
+ throw new UnsolvedSymbolException("Field not found: " + name);
+ }
+ }
+
+ /**
+ * Consider only field or inherited field which is not private.
+ */
+ default ResolvedFieldDeclaration getVisibleField(String name) {
+ Optional<ResolvedFieldDeclaration> field = getVisibleFields().stream().filter(f -> f.getName().equals(name)).findFirst();
+ if (field.isPresent()) {
+ return field.get();
+ } else {
+ throw new IllegalArgumentException();
+ }
+ }
+
+ /**
+ * Has this type a field with the given name?
+ */
+ default boolean hasField(String name) {
+ return this.getAllFields().stream().filter(f -> f.getName().equals(name)).findFirst().isPresent();
+ }
+
+ /**
+ * Either a declared field or inherited field which is not private.
+ */
+ default boolean hasVisibleField(String name) {
+ return getVisibleFields().stream().filter(f -> f.getName().equals(name)).findFirst().isPresent();
+ }
+
+ /**
+ * Return a list of all fields, either declared in this declaration or inherited.
+ */
+ List<ResolvedFieldDeclaration> getAllFields();
+
+ /**
+ * Return a list of all fields declared and the inherited ones which are not private.
+ */
+ default List<ResolvedFieldDeclaration> getVisibleFields() {
+ return getAllFields().stream()
+ .filter(f -> f.declaringType().equals(this) || f.accessSpecifier() != AccessSpecifier.PRIVATE)
+ .collect(Collectors.toList());
+ }
+
+ /**
+ * Return a list of all the non static fields, either declared or inherited.
+ */
+ default List<ResolvedFieldDeclaration> getAllNonStaticFields() {
+ return getAllFields().stream().filter(it -> !it.isStatic()).collect(Collectors.toList());
+ }
+
+ /**
+ * Return a list of all the static fields, either declared or inherited.
+ */
+ default List<ResolvedFieldDeclaration> getAllStaticFields() {
+ return getAllFields().stream().filter(it -> it.isStatic()).collect(Collectors.toList());
+ }
+
+ /**
+ * Return a list of all the fields declared in this type.
+ */
+ default List<ResolvedFieldDeclaration> getDeclaredFields() {
+ return getAllFields().stream().filter(it -> it.declaringType().getQualifiedName().equals(getQualifiedName())).collect(Collectors.toList());
+ }
+
+ ///
+ /// Methods
+ ///
+
+ /**
+ * Return a list of all the methods declared in this type declaration.
+ */
+ Set<ResolvedMethodDeclaration> getDeclaredMethods();
+
+ /**
+ * Return a list of all the methods declared of this type declaration, either declared or inherited.
+ * Note that it should not include overridden methods.
+ */
+ Set<MethodUsage> getAllMethods();
+
+ ///
+ /// Assignability
+ ///
+
+ /**
+ * Can we assign instances of the given type to variables having the type defined
+ * by this declaration?
+ */
+ boolean isAssignableBy(ResolvedType type);
+
+ /**
+ * Can we assign instances of the type defined by this declaration to variables having the type defined
+ * by the given type?
+ */
+ default boolean canBeAssignedTo(ResolvedReferenceTypeDeclaration other) {
+ return other.isAssignableBy(this);
+ }
+
+ /**
+ * Can we assign instances of the given type to variables having the type defined
+ * by this declaration?
+ */
+ boolean isAssignableBy(ResolvedReferenceTypeDeclaration other);
+
+ ///
+ /// Annotations
+ ///
+
+ /**
+ * Has the type at least one annotation declared having the specified qualified name?
+ */
+ boolean hasDirectlyAnnotation(String qualifiedName);
+
+ /**
+ * Has the type at least one annotation declared or inherited having the specified qualified name?
+ */
+ default boolean hasAnnotation(String qualifiedName) {
+ if (hasDirectlyAnnotation(qualifiedName)) {
+ return true;
+ }
+ return getAllAncestors().stream().anyMatch(it -> it.asReferenceType().getTypeDeclaration().hasDirectlyAnnotation(qualifiedName));
+ }
+
+ /**
+ * This means that the type has a functional method. Conceptually, a functional interface has exactly one abstract method.
+ * Typically these classes has the FunctionInterface annotation but this is not mandatory.
+ */
+ boolean isFunctionalInterface();
+
+ ///
+ /// Type parameters
+ ///
+
+ @Override
+ default Optional<ResolvedTypeParameterDeclaration> findTypeParameter(String name) {
+ for (ResolvedTypeParameterDeclaration tp : this.getTypeParameters()) {
+ if (tp.getName().equals(name)) {
+ return Optional.of(tp);
+ }
+ }
+ if (this.containerType().isPresent()) {
+ return this.containerType().get().findTypeParameter(name);
+ }
+ return Optional.empty();
+ }
+}
diff --git a/javaparser-core/src/main/java/com/github/javaparser/resolution/declarations/ResolvedTypeDeclaration.java b/javaparser-core/src/main/java/com/github/javaparser/resolution/declarations/ResolvedTypeDeclaration.java
new file mode 100644
index 000000000..bb96f00e3
--- /dev/null
+++ b/javaparser-core/src/main/java/com/github/javaparser/resolution/declarations/ResolvedTypeDeclaration.java
@@ -0,0 +1,177 @@
+/*
+ * Copyright (C) 2007-2010 Júlio Vilmar Gesser.
+ * Copyright (C) 2011, 2013-2016 The JavaParser Team.
+ *
+ * This file is part of JavaParser.
+ *
+ * JavaParser can be used either under the terms of
+ * a) the GNU Lesser General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ * b) the terms of the Apache License
+ *
+ * You should have received a copy of both licenses in LICENCE.LGPL and
+ * LICENCE.APACHE. Please refer to those files for details.
+ *
+ * JavaParser is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License for more details.
+ */
+
+package com.github.javaparser.resolution.declarations;
+
+import com.github.javaparser.resolution.UnsolvedSymbolException;
+
+import java.util.Optional;
+import java.util.Set;
+
+/**
+ * A declaration of a type. It could be a primitive type, an enum, a class, an interface
+ * or a type variable.
+ * It cannot be an annotation or an array.
+ *
+ * @author Federico Tomassetti
+ */
+public interface ResolvedTypeDeclaration extends ResolvedDeclaration {
+
+ ///
+ /// Containment
+ ///
+
+ /**
+ * Get the list of types defined inside the current type.
+ */
+ default Set<ResolvedReferenceTypeDeclaration> internalTypes() {
+ throw new UnsupportedOperationException("InternalTypes not available for " + this.getClass().getCanonicalName());
+ }
+
+ /**
+ * Returns a type declaration for the internal type based on name.
+ * (Does not include internal types inside internal types).
+ */
+ default ResolvedReferenceTypeDeclaration getInternalType(String name) {
+ Optional<ResolvedReferenceTypeDeclaration> type =
+ this.internalTypes().stream().filter(f -> f.getName().equals(name)).findFirst();
+ return type.orElseThrow(() ->
+ new UnsolvedSymbolException("Internal type not found: " + name));
+ }
+
+ /**
+ * Does this type contain an internal type with the given name?
+ * (Does not include internal types inside internal types).
+ */
+ default boolean hasInternalType(String name) {
+ return this.internalTypes().stream().anyMatch(f -> f.getName().equals(name));
+ }
+
+ /**
+ * Get the ReferenceTypeDeclaration enclosing this declaration.
+ *
+ * @return
+ */
+ Optional<ResolvedReferenceTypeDeclaration> containerType();
+
+ ///
+ /// Misc
+ ///
+
+ /**
+ * Is this the declaration of a class?
+ * Note that an Enum is not considered a Class in this case.
+ */
+ default boolean isClass() {
+ return false;
+ }
+
+ /**
+ * Is this the declaration of an interface?
+ */
+ default boolean isInterface() {
+ return false;
+ }
+
+ /**
+ * Is this the declaration of an enum?
+ */
+ default boolean isEnum() {
+ return false;
+ }
+
+ /**
+ * Is this the declaration of a type parameter?
+ */
+ default boolean isTypeParameter() {
+ return false;
+ }
+
+ @Override
+ default boolean isType() {
+ return true;
+ }
+
+ @Override
+ default ResolvedTypeDeclaration asType() {
+ return this;
+ }
+
+ /**
+ * Return this as a ClassDeclaration or throw UnsupportedOperationException.
+ */
+ default ResolvedClassDeclaration asClass() {
+ throw new UnsupportedOperationException(String.format("%s is not a class", this));
+ }
+
+ /**
+ * Return this as a InterfaceDeclaration or throw UnsupportedOperationException.
+ */
+ default ResolvedInterfaceDeclaration asInterface() {
+ throw new UnsupportedOperationException(String.format("%s is not an interface", this));
+ }
+
+ /**
+ * Return this as a EnumDeclaration or throw UnsupportedOperationException.
+ */
+ default ResolvedEnumDeclaration asEnum() {
+ throw new UnsupportedOperationException(String.format("%s is not an enum", this));
+ }
+
+ /**
+ * Return this as a TypeParameterDeclaration or throw UnsupportedOperationException.
+ */
+ default ResolvedTypeParameterDeclaration asTypeParameter() {
+ throw new UnsupportedOperationException(String.format("%s is not a type parameter", this));
+ }
+
+ default ResolvedReferenceTypeDeclaration asReferenceType() {
+ throw new UnsupportedOperationException(String.format("%s is not a reference type", this));
+ }
+
+ /**
+ * The package name of the type.
+ */
+ String getPackageName();
+
+ /**
+ * The class(es) wrapping this type.
+ */
+ String getClassName();
+
+ /**
+ * The fully qualified name of the type declared.
+ */
+ String getQualifiedName();
+
+ /**
+ * The ID corresponds most of the type to the qualified name. It differs only for local
+ * classes which do not have a qualified name but have an ID.
+ */
+ default String getId() {
+ String qname = getQualifiedName();
+ if (qname == null) {
+ return String.format("<localClass>:%s", getName());
+ }
+ return qname;
+ }
+
+}
diff --git a/javaparser-core/src/main/java/com/github/javaparser/resolution/declarations/ResolvedTypeParameterDeclaration.java b/javaparser-core/src/main/java/com/github/javaparser/resolution/declarations/ResolvedTypeParameterDeclaration.java
new file mode 100644
index 000000000..14326db1f
--- /dev/null
+++ b/javaparser-core/src/main/java/com/github/javaparser/resolution/declarations/ResolvedTypeParameterDeclaration.java
@@ -0,0 +1,305 @@
+/*
+ * Copyright (C) 2007-2010 Júlio Vilmar Gesser.
+ * Copyright (C) 2011, 2013-2016 The JavaParser Team.
+ *
+ * This file is part of JavaParser.
+ *
+ * JavaParser can be used either under the terms of
+ * a) the GNU Lesser General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ * b) the terms of the Apache License
+ *
+ * You should have received a copy of both licenses in LICENCE.LGPL and
+ * LICENCE.APACHE. Please refer to those files for details.
+ *
+ * JavaParser is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License for more details.
+ */
+
+package com.github.javaparser.resolution.declarations;
+
+
+import com.github.javaparser.resolution.types.ResolvedType;
+
+import java.util.List;
+import java.util.Optional;
+
+/**
+ * Declaration of a type parameter.
+ * For example:
+ * <p>
+ * class A&lt;E extends String&gt;{}
+ * </p>
+ * <p>
+ * In this case <b>E</b> would be a type parameter.
+ *
+ * @author Federico Tomassetti
+ */
+public interface ResolvedTypeParameterDeclaration extends ResolvedTypeDeclaration {
+
+ /**
+ * Instantiate a TypeParameter defined on a Type with the given data.
+ */
+ static ResolvedTypeParameterDeclaration onType(final String name, String classQName, List<Bound> bounds) {
+ return new ResolvedTypeParameterDeclaration() {
+ @Override
+ public String getName() {
+ return name;
+ }
+
+ @Override
+ public boolean declaredOnType() {
+ return true;
+ }
+
+ @Override
+ public boolean declaredOnMethod() {
+ return false;
+ }
+
+ @Override
+ public boolean declaredOnConstructor() {
+ return false;
+ }
+
+ @Override
+ public String getContainerQualifiedName() {
+ return classQName;
+ }
+
+ @Override
+ public String getContainerId() {
+ return classQName;
+ }
+
+ @Override
+ public ResolvedTypeParametrizable getContainer() {
+ return null;
+ }
+
+ @Override
+ public List<Bound> getBounds() {
+ return bounds;
+ }
+
+ @Override
+ public String toString() {
+ return "TypeParameter onType " + name;
+ }
+
+ @Override
+ public Optional<ResolvedReferenceTypeDeclaration> containerType() {
+ throw new UnsupportedOperationException();
+ }
+ };
+ }
+
+ /**
+ * Name of the type parameter.
+ */
+ String getName();
+
+ /**
+ * Is the type parameter been defined on a type?
+ */
+ default boolean declaredOnType() {
+ return (getContainer() instanceof ResolvedReferenceTypeDeclaration);
+ }
+
+ /**
+ * Is the type parameter been defined on a method?
+ */
+ default boolean declaredOnMethod() {
+ return (getContainer() instanceof ResolvedMethodDeclaration);
+ }
+
+ /**
+ * Is the type parameter been defined on a constructor?
+ */
+ default boolean declaredOnConstructor() {
+ return (getContainer() instanceof ResolvedConstructorDeclaration);
+ }
+
+ /**
+ * The package name of the type bound(s).
+ * This is unsupported because there is no package for a Type Parameter, only for its container.
+ */
+ default String getPackageName() {
+ throw new UnsupportedOperationException();
+ }
+
+ /**
+ * The class(es) wrapping the type bound(s).
+ * This is unsupported because there is no class for a Type Parameter, only for its container.
+ */
+ default String getClassName() {
+ throw new UnsupportedOperationException();
+ }
+
+ /**
+ * The qualified name of the Type Parameter.
+ * It is composed by the qualified name of the container followed by a dot and the name of the Type Parameter.
+ * The qualified name of a method is its qualified signature.
+ */
+ default String getQualifiedName() {
+ return String.format("%s.%s", getContainerId(), getName());
+ }
+
+ /**
+ * The qualified name of the container.
+ */
+ String getContainerQualifiedName();
+
+ /**
+ * The ID of the container. See TypeContainer.getId
+ */
+ String getContainerId();
+
+ /**
+ * The TypeParametrizable of the container. Can be either a ReferenceTypeDeclaration or a MethodLikeDeclaration
+ */
+ ResolvedTypeParametrizable getContainer();
+
+ /**
+ * The bounds specified for the type parameter.
+ * For example:
+ * "extends A" or "super B"
+ */
+ List<Bound> getBounds();
+
+ /**
+ * Has the type parameter a lower bound?
+ */
+ default boolean hasLowerBound() {
+ for (Bound b : getBounds()) {
+ if (b.isExtends()) {
+ return true;
+ }
+ }
+ return false;
+ }
+
+ /**
+ * Has the type parameter an upper bound?
+ */
+ default boolean hasUpperBound() {
+ for (Bound b : getBounds()) {
+ if (b.isSuper()) {
+ return true;
+ }
+ }
+ return false;
+ }
+
+ /**
+ * Get the type used as lower bound.
+ *
+ * @throws IllegalStateException if there is no lower bound
+ */
+ default ResolvedType getLowerBound() {
+ for (Bound b : getBounds()) {
+ if (b.isExtends()) {
+ return b.getType();
+ }
+ }
+ throw new IllegalStateException();
+ }
+
+ /**
+ * Get the type used as upper bound.
+ *
+ * @throws IllegalStateException if there is no upper bound
+ */
+ default ResolvedType getUpperBound() {
+ for (Bound b : getBounds()) {
+ if (b.isSuper()) {
+ return b.getType();
+ }
+ }
+ throw new IllegalStateException();
+ }
+
+ /**
+ * A Bound on a Type Parameter.
+ */
+ class Bound {
+ private boolean extendsBound;
+ private ResolvedType type;
+
+ private Bound(boolean extendsBound, ResolvedType type) {
+ this.extendsBound = extendsBound;
+ this.type = type;
+ }
+
+ /**
+ * Create an extends bound with the given type:
+ * <p>
+ * extends "given type"
+ * </p>
+ */
+ public static Bound extendsBound(ResolvedType type) {
+ return new Bound(true, type);
+ }
+
+ /**
+ * Create a super bound with the given type:
+ * <p>
+ * super "given type"
+ * </p>
+ */
+ public static Bound superBound(ResolvedType type) {
+ return new Bound(false, type);
+ }
+
+ /**
+ * Get the type used in the Bound.
+ */
+ public ResolvedType getType() {
+ return type;
+ }
+
+ /**
+ * Is this an extends bound?
+ */
+ public boolean isExtends() {
+ return extendsBound;
+ }
+
+ /**
+ * Is this a super bound?
+ */
+ public boolean isSuper() {
+ return !isExtends();
+ }
+
+ @Override
+ public String toString() {
+ return "Bound{" +
+ "extendsBound=" + extendsBound +
+ ", type=" + type +
+ '}';
+ }
+
+ @Override
+ public boolean equals(Object o) {
+ if (this == o) return true;
+ if (o == null || getClass() != o.getClass()) return false;
+
+ Bound bound = (Bound) o;
+
+ if (extendsBound != bound.extendsBound) return false;
+ return type != null ? type.equals(bound.type) : bound.type == null;
+ }
+
+ @Override
+ public int hashCode() {
+ int result = (extendsBound ? 1 : 0);
+ result = 31 * result + (type != null ? type.hashCode() : 0);
+ return result;
+ }
+ }
+
+}
diff --git a/javaparser-core/src/main/java/com/github/javaparser/resolution/declarations/ResolvedTypeParametrizable.java b/javaparser-core/src/main/java/com/github/javaparser/resolution/declarations/ResolvedTypeParametrizable.java
new file mode 100644
index 000000000..3d6b92e7a
--- /dev/null
+++ b/javaparser-core/src/main/java/com/github/javaparser/resolution/declarations/ResolvedTypeParametrizable.java
@@ -0,0 +1,49 @@
+/*
+ * Copyright (C) 2007-2010 Júlio Vilmar Gesser.
+ * Copyright (C) 2011, 2013-2016 The JavaParser Team.
+ *
+ * This file is part of JavaParser.
+ *
+ * JavaParser can be used either under the terms of
+ * a) the GNU Lesser General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ * b) the terms of the Apache License
+ *
+ * You should have received a copy of both licenses in LICENCE.LGPL and
+ * LICENCE.APACHE. Please refer to those files for details.
+ *
+ * JavaParser is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License for more details.
+ */
+
+package com.github.javaparser.resolution.declarations;
+
+import java.util.List;
+import java.util.Optional;
+
+/**
+ * An entity which has type parameter.
+ *
+ * @author Federico Tomassetti
+ */
+public interface ResolvedTypeParametrizable {
+
+ /**
+ * The list of type parameters defined on this element.
+ */
+ List<ResolvedTypeParameterDeclaration> getTypeParameters();
+
+ /**
+ * Find the closest TypeParameterDeclaration with the given name.
+ * It first look on this element itself and then on the containers.
+ */
+ Optional<ResolvedTypeParameterDeclaration> findTypeParameter(String name);
+
+ default boolean isGeneric() {
+ return !getTypeParameters().isEmpty();
+ }
+
+}
diff --git a/javaparser-core/src/main/java/com/github/javaparser/resolution/declarations/ResolvedValueDeclaration.java b/javaparser-core/src/main/java/com/github/javaparser/resolution/declarations/ResolvedValueDeclaration.java
new file mode 100644
index 000000000..ee6230ad8
--- /dev/null
+++ b/javaparser-core/src/main/java/com/github/javaparser/resolution/declarations/ResolvedValueDeclaration.java
@@ -0,0 +1,39 @@
+/*
+ * Copyright (C) 2007-2010 Júlio Vilmar Gesser.
+ * Copyright (C) 2011, 2013-2016 The JavaParser Team.
+ *
+ * This file is part of JavaParser.
+ *
+ * JavaParser can be used either under the terms of
+ * a) the GNU Lesser General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ * b) the terms of the Apache License
+ *
+ * You should have received a copy of both licenses in LICENCE.LGPL and
+ * LICENCE.APACHE. Please refer to those files for details.
+ *
+ * JavaParser is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License for more details.
+ */
+
+package com.github.javaparser.resolution.declarations;
+
+
+import com.github.javaparser.resolution.types.ResolvedType;
+
+/**
+ * Declaration of a value.
+ *
+ * @author Federico Tomassetti
+ */
+public interface ResolvedValueDeclaration extends ResolvedDeclaration {
+
+ /**
+ * Type of the declaration.
+ */
+ ResolvedType getType();
+
+}
diff --git a/javaparser-core/src/main/java/com/github/javaparser/resolution/types/ResolvedArrayType.java b/javaparser-core/src/main/java/com/github/javaparser/resolution/types/ResolvedArrayType.java
new file mode 100644
index 000000000..bc422f75f
--- /dev/null
+++ b/javaparser-core/src/main/java/com/github/javaparser/resolution/types/ResolvedArrayType.java
@@ -0,0 +1,113 @@
+/*
+ * Copyright (C) 2007-2010 Júlio Vilmar Gesser.
+ * Copyright (C) 2011, 2013-2016 The JavaParser Team.
+ *
+ * This file is part of JavaParser.
+ *
+ * JavaParser can be used either under the terms of
+ * a) the GNU Lesser General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ * b) the terms of the Apache License
+ *
+ * You should have received a copy of both licenses in LICENCE.LGPL and
+ * LICENCE.APACHE. Please refer to those files for details.
+ *
+ * JavaParser is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License for more details.
+ */
+
+package com.github.javaparser.resolution.types;
+
+import com.github.javaparser.resolution.declarations.ResolvedTypeParameterDeclaration;
+
+import java.util.Map;
+
+/**
+ * Array Type.
+ *
+ * @author Federico Tomassetti
+ */
+public class ResolvedArrayType implements ResolvedType {
+
+ private ResolvedType baseType;
+
+ public ResolvedArrayType(ResolvedType baseType) {
+ this.baseType = baseType;
+ }
+
+ ///
+ /// Object methods
+ ///
+
+ @Override
+ public boolean equals(Object o) {
+ if (this == o) return true;
+ if (o == null || getClass() != o.getClass()) return false;
+
+ ResolvedArrayType that = (ResolvedArrayType) o;
+
+ if (!baseType.equals(that.baseType)) return false;
+
+ return true;
+ }
+
+ @Override
+ public int hashCode() {
+ return baseType.hashCode();
+ }
+
+ @Override
+ public String toString() {
+ return "ResolvedArrayType{" + baseType + "}";
+ }
+
+ ///
+ /// Type methods
+ ///
+
+ @Override
+ public ResolvedArrayType asArrayType() {
+ return this;
+ }
+
+ @Override
+ public boolean isArray() {
+ return true;
+ }
+
+ @Override
+ public String describe() {
+ return baseType.describe() + "[]";
+ }
+
+ public ResolvedType getComponentType() {
+ return baseType;
+ }
+
+ @Override
+ public boolean isAssignableBy(ResolvedType other) {
+ if (other.isArray()) {
+ if (baseType.isPrimitive() && other.asArrayType().getComponentType().isPrimitive()) {
+ return baseType.equals(other.asArrayType().getComponentType());
+ }
+ return baseType.isAssignableBy(other.asArrayType().getComponentType());
+ } else if (other.isNull()) {
+ return true;
+ }
+ return false;
+ }
+
+ @Override
+ public ResolvedType replaceTypeVariables(ResolvedTypeParameterDeclaration tpToReplace, ResolvedType replaced, Map<ResolvedTypeParameterDeclaration, ResolvedType> inferredTypes) {
+ ResolvedType baseTypeReplaced = baseType.replaceTypeVariables(tpToReplace, replaced, inferredTypes);
+ if (baseTypeReplaced == baseType) {
+ return this;
+ } else {
+ return new ResolvedArrayType(baseTypeReplaced);
+ }
+ }
+
+}
diff --git a/javaparser-core/src/main/java/com/github/javaparser/resolution/types/ResolvedIntersectionType.java b/javaparser-core/src/main/java/com/github/javaparser/resolution/types/ResolvedIntersectionType.java
new file mode 100644
index 000000000..e308feace
--- /dev/null
+++ b/javaparser-core/src/main/java/com/github/javaparser/resolution/types/ResolvedIntersectionType.java
@@ -0,0 +1,81 @@
+/*
+ * Copyright (C) 2007-2010 Júlio Vilmar Gesser.
+ * Copyright (C) 2011, 2013-2016 The JavaParser Team.
+ *
+ * This file is part of JavaParser.
+ *
+ * JavaParser can be used either under the terms of
+ * a) the GNU Lesser General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ * b) the terms of the Apache License
+ *
+ * You should have received a copy of both licenses in LICENCE.LGPL and
+ * LICENCE.APACHE. Please refer to those files for details.
+ *
+ * JavaParser is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License for more details.
+ */
+
+package com.github.javaparser.resolution.types;
+
+import com.github.javaparser.resolution.declarations.ResolvedTypeParameterDeclaration;
+
+import java.util.*;
+import java.util.stream.Collectors;
+
+/**
+ * An intersection type is defined in java as list of types separates by ampersands.
+ *
+ * @author Federico Tomassetti
+ */
+public class ResolvedIntersectionType implements ResolvedType {
+ private List<ResolvedType> elements;
+
+ public ResolvedIntersectionType(Collection<ResolvedType> elements) {
+ if (elements.size() < 2) {
+ throw new IllegalArgumentException("An intersection type should have at least two elements. This has " + elements.size());
+ }
+ this.elements = new LinkedList<>(elements);
+ }
+
+ @Override
+ public boolean equals(Object o) {
+ if (this == o) return true;
+ if (o == null || getClass() != o.getClass()) return false;
+
+ ResolvedIntersectionType that = (ResolvedIntersectionType) o;
+
+ return new HashSet<>(elements).equals(new HashSet<>(that.elements));
+ }
+
+ @Override
+ public int hashCode() {
+ return new HashSet<>(elements).hashCode();
+ }
+
+ @Override
+ public String describe() {
+ return String.join(" & ", elements.stream().map(ResolvedType::describe).collect(Collectors.toList()));
+ }
+
+ @Override
+ public boolean isAssignableBy(ResolvedType other) {
+ return elements.stream().allMatch(e -> e.isAssignableBy(other));
+ }
+
+ @Override
+ public ResolvedType replaceTypeVariables(ResolvedTypeParameterDeclaration tp, ResolvedType replaced, Map<ResolvedTypeParameterDeclaration, ResolvedType> inferredTypes) {
+ List<ResolvedType> elementsReplaced = elements.stream()
+ .map(e -> e.replaceTypeVariables(tp, replaced, inferredTypes))
+ .collect(Collectors.toList());
+ if (elementsReplaced.equals(elements)) {
+ return this;
+ } else {
+ return new ResolvedIntersectionType(elementsReplaced);
+ }
+ }
+
+}
diff --git a/javaparser-core/src/main/java/com/github/javaparser/resolution/types/ResolvedLambdaConstraintType.java b/javaparser-core/src/main/java/com/github/javaparser/resolution/types/ResolvedLambdaConstraintType.java
new file mode 100644
index 000000000..e43d434d8
--- /dev/null
+++ b/javaparser-core/src/main/java/com/github/javaparser/resolution/types/ResolvedLambdaConstraintType.java
@@ -0,0 +1,65 @@
+/*
+ * Copyright (C) 2007-2010 Júlio Vilmar Gesser.
+ * Copyright (C) 2011, 2013-2016 The JavaParser Team.
+ *
+ * This file is part of JavaParser.
+ *
+ * JavaParser can be used either under the terms of
+ * a) the GNU Lesser General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ * b) the terms of the Apache License
+ *
+ * You should have received a copy of both licenses in LICENCE.LGPL and
+ * LICENCE.APACHE. Please refer to those files for details.
+ *
+ * JavaParser is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License for more details.
+ */
+
+package com.github.javaparser.resolution.types;
+
+public class ResolvedLambdaConstraintType implements ResolvedType {
+ private ResolvedType bound;
+
+ private ResolvedLambdaConstraintType(ResolvedType bound) {
+ this.bound = bound;
+ }
+
+ @Override
+ public String describe() {
+ return "? super " + bound.describe();
+ }
+
+ public ResolvedType getBound() {
+ return bound;
+ }
+
+ @Override
+ public boolean isConstraint() {
+ return true;
+ }
+
+ @Override
+ public ResolvedLambdaConstraintType asConstraintType() {
+ return this;
+ }
+
+ public static ResolvedLambdaConstraintType bound(ResolvedType bound){
+ return new ResolvedLambdaConstraintType(bound);
+ }
+
+ @Override
+ public boolean isAssignableBy(ResolvedType other) {
+ return bound.isAssignableBy(other);
+ }
+
+ @Override
+ public String toString() {
+ return "LambdaConstraintType{" +
+ "bound=" + bound +
+ '}';
+ }
+} \ No newline at end of file
diff --git a/javaparser-core/src/main/java/com/github/javaparser/resolution/types/ResolvedPrimitiveType.java b/javaparser-core/src/main/java/com/github/javaparser/resolution/types/ResolvedPrimitiveType.java
new file mode 100644
index 000000000..05b6102e9
--- /dev/null
+++ b/javaparser-core/src/main/java/com/github/javaparser/resolution/types/ResolvedPrimitiveType.java
@@ -0,0 +1,141 @@
+/*
+ * Copyright (C) 2007-2010 Júlio Vilmar Gesser.
+ * Copyright (C) 2011, 2013-2016 The JavaParser Team.
+ *
+ * This file is part of JavaParser.
+ *
+ * JavaParser can be used either under the terms of
+ * a) the GNU Lesser General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ * b) the terms of the Apache License
+ *
+ * You should have received a copy of both licenses in LICENCE.LGPL and
+ * LICENCE.APACHE. Please refer to those files for details.
+ *
+ * JavaParser is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License for more details.
+ */
+
+package com.github.javaparser.resolution.types;
+
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.List;
+
+/**
+ * @author Federico Tomassetti
+ */
+public class ResolvedPrimitiveType implements ResolvedType {
+
+ ///
+ /// Constants
+ ///
+
+ public static final ResolvedPrimitiveType BYTE = new ResolvedPrimitiveType("byte",
+ Byte.class.getCanonicalName(), Collections.emptyList());
+ public static final ResolvedPrimitiveType SHORT = new ResolvedPrimitiveType("short",
+ Short.class.getCanonicalName(), Collections.singletonList(BYTE));
+ public static final ResolvedPrimitiveType CHAR = new ResolvedPrimitiveType("char",
+ Character.class.getCanonicalName(), Collections.emptyList());
+ public static final ResolvedPrimitiveType INT = new ResolvedPrimitiveType("int",
+ Integer.class.getCanonicalName(), Arrays.asList(BYTE, SHORT, CHAR));
+ public static final ResolvedPrimitiveType LONG = new ResolvedPrimitiveType("long",
+ Long.class.getCanonicalName(), Arrays.asList(BYTE, SHORT, INT, CHAR));
+ public static final ResolvedPrimitiveType BOOLEAN = new ResolvedPrimitiveType("boolean",
+ Boolean.class.getCanonicalName(), Collections.emptyList());
+ public static final ResolvedPrimitiveType FLOAT = new ResolvedPrimitiveType("float",
+ Float.class.getCanonicalName(), Arrays.asList(LONG, INT, SHORT, BYTE, CHAR));
+ public static final ResolvedPrimitiveType DOUBLE = new ResolvedPrimitiveType("double",
+ Double.class.getCanonicalName(), Arrays.asList(FLOAT, LONG, INT, SHORT, BYTE, CHAR));
+ public static final List<ResolvedPrimitiveType> ALL = Arrays.asList(
+ INT, BOOLEAN, LONG, CHAR, FLOAT, DOUBLE, SHORT, BYTE);
+
+ ///
+ /// Fields
+ ///
+
+ private String name;
+ private String boxTypeQName;
+ private List<ResolvedPrimitiveType> promotionTypes;
+
+ private ResolvedPrimitiveType(String name, String boxTypeQName, List<ResolvedPrimitiveType> promotionTypes) {
+ this.name = name;
+ this.boxTypeQName = boxTypeQName;
+ this.promotionTypes = promotionTypes;
+ }
+
+ public static ResolvedType byName(String name) {
+ name = name.toLowerCase();
+ for (ResolvedPrimitiveType ptu : ALL) {
+ if (ptu.describe().equals(name)) {
+ return ptu;
+ }
+ }
+ throw new IllegalArgumentException("Name " + name);
+ }
+
+ @Override
+ public String toString() {
+ return "PrimitiveTypeUsage{" +
+ "name='" + name + '\'' +
+ '}';
+ }
+
+ public ResolvedPrimitiveType asPrimitive() {
+ return this;
+ }
+
+ @Override
+ public boolean isArray() {
+ return false;
+ }
+
+ @Override
+ public boolean isPrimitive() {
+ return true;
+ }
+
+ @Override
+ public boolean isReferenceType() {
+ return false;
+ }
+
+ @Override
+ public String describe() {
+ return name;
+ }
+
+ @Override
+ public boolean isTypeVariable() {
+ return false;
+ }
+
+ @Override
+ public boolean isAssignableBy(ResolvedType other) {
+ if (other.isPrimitive()) {
+ return this == other || promotionTypes.contains(other);
+ } else if (other.isReferenceType()) {
+ if (other.asReferenceType().getQualifiedName().equals(boxTypeQName)) {
+ return true;
+ }
+ for (ResolvedPrimitiveType promotion : promotionTypes) {
+ if (other.asReferenceType().getQualifiedName().equals(promotion.boxTypeQName)) {
+ return true;
+ }
+ }
+ return false;
+ } else if (other.isConstraint()){
+ return this.isAssignableBy(other.asConstraintType().getBound());
+ } else {
+ return false;
+ }
+ }
+
+ public String getBoxTypeQName() {
+ return boxTypeQName;
+ }
+
+}
diff --git a/javaparser-core/src/main/java/com/github/javaparser/resolution/types/ResolvedReferenceType.java b/javaparser-core/src/main/java/com/github/javaparser/resolution/types/ResolvedReferenceType.java
new file mode 100644
index 000000000..4fecaf6ec
--- /dev/null
+++ b/javaparser-core/src/main/java/com/github/javaparser/resolution/types/ResolvedReferenceType.java
@@ -0,0 +1,451 @@
+/*
+ * Copyright (C) 2007-2010 Júlio Vilmar Gesser.
+ * Copyright (C) 2011, 2013-2016 The JavaParser Team.
+ *
+ * This file is part of JavaParser.
+ *
+ * JavaParser can be used either under the terms of
+ * a) the GNU Lesser General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ * b) the terms of the Apache License
+ *
+ * You should have received a copy of both licenses in LICENCE.LGPL and
+ * LICENCE.APACHE. Please refer to those files for details.
+ *
+ * JavaParser is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License for more details.
+ */
+
+package com.github.javaparser.resolution.types;
+
+import com.github.javaparser.resolution.MethodUsage;
+import com.github.javaparser.resolution.declarations.ResolvedReferenceTypeDeclaration;
+import com.github.javaparser.resolution.declarations.ResolvedTypeParameterDeclaration;
+import com.github.javaparser.resolution.types.parametrization.ResolvedTypeParameterValueProvider;
+import com.github.javaparser.resolution.types.parametrization.ResolvedTypeParametersMap;
+import com.github.javaparser.resolution.types.parametrization.ResolvedTypeParametrized;
+import com.github.javaparser.utils.Pair;
+
+import java.util.*;
+import java.util.stream.Collectors;
+
+/**
+ * A ReferenceType like a class, an interface or an enum. Note that this type can contain also the values
+ * specified for the type parameters.
+ *
+ * @author Federico Tomassetti
+ */
+public abstract class ResolvedReferenceType implements ResolvedType,
+ ResolvedTypeParametrized, ResolvedTypeParameterValueProvider {
+
+ //
+ // Fields
+ //
+
+ protected ResolvedReferenceTypeDeclaration typeDeclaration;
+ protected ResolvedTypeParametersMap typeParametersMap;
+
+ //
+ // Constructors
+ //
+
+ public ResolvedReferenceType(ResolvedReferenceTypeDeclaration typeDeclaration) {
+ this(typeDeclaration, deriveParams(typeDeclaration));
+ }
+
+ public ResolvedReferenceType(ResolvedReferenceTypeDeclaration typeDeclaration, List<ResolvedType> typeArguments) {
+ if (typeDeclaration.isTypeParameter()) {
+ throw new IllegalArgumentException("You should use only Classes, Interfaces and enums");
+ }
+ if (typeArguments.size() > 0 && typeArguments.size() != typeDeclaration.getTypeParameters().size()) {
+ throw new IllegalArgumentException(String.format(
+ "expected either zero type arguments or has many as defined in the declaration (%d). Found %d",
+ typeDeclaration.getTypeParameters().size(), typeArguments.size()));
+ }
+ ResolvedTypeParametersMap.Builder typeParametersMapBuilder = new ResolvedTypeParametersMap.Builder();
+ for (int i = 0; i < typeArguments.size(); i++) {
+ typeParametersMapBuilder.setValue(typeDeclaration.getTypeParameters().get(i), typeArguments.get(i));
+ }
+ this.typeParametersMap = typeParametersMapBuilder.build();
+ this.typeDeclaration = typeDeclaration;
+ }
+
+ //
+ // Public Object methods
+ //
+
+ @Override
+ public boolean equals(Object o) {
+ if (this == o) return true;
+ if (o == null || getClass() != o.getClass()) return false;
+
+ ResolvedReferenceType that = (ResolvedReferenceType) o;
+
+ if (!typeDeclaration.equals(that.typeDeclaration)) return false;
+ if (!typeParametersMap.equals(that.typeParametersMap)) return false;
+
+ return true;
+ }
+
+ @Override
+ public int hashCode() {
+ int result = typeDeclaration.hashCode();
+ result = 31 * result + typeParametersMap.hashCode();
+ return result;
+ }
+
+ @Override
+ public String toString() {
+ return "ReferenceType{" + getQualifiedName() +
+ ", typeParametersMap=" + typeParametersMap +
+ '}';
+ }
+
+ ///
+ /// Relation with other types
+ ///
+
+ @Override
+ public final boolean isReferenceType() {
+ return true;
+ }
+
+ ///
+ /// Downcasting
+ ///
+
+ @Override
+ public ResolvedReferenceType asReferenceType() {
+ return this;
+ }
+
+ ///
+ /// Naming
+ ///
+
+ @Override
+ public String describe() {
+ StringBuilder sb = new StringBuilder();
+ if (hasName()) {
+ sb.append(typeDeclaration.getQualifiedName());
+ } else {
+ sb.append("<anonymous class>");
+ }
+ if (!typeParametersMap().isEmpty()) {
+ sb.append("<");
+ sb.append(String.join(", ", typeDeclaration.getTypeParameters().stream()
+ .map(tp -> typeParametersMap().getValue(tp).describe())
+ .collect(Collectors.toList())));
+ sb.append(">");
+ }
+ return sb.toString();
+ }
+
+ ///
+ /// TypeParameters
+ ///
+
+ /**
+ * Execute a transformation on all the type parameters of this element.
+ */
+ public abstract ResolvedType transformTypeParameters(ResolvedTypeTransformer transformer);
+
+ @Override
+ public ResolvedType replaceTypeVariables(ResolvedTypeParameterDeclaration tpToReplace, ResolvedType replaced,
+ Map<ResolvedTypeParameterDeclaration, ResolvedType> inferredTypes) {
+ if (replaced == null) {
+ throw new IllegalArgumentException();
+ }
+
+ ResolvedReferenceType result = this;
+ int i = 0;
+ for (ResolvedType tp : this.typeParametersValues()) {
+ ResolvedType transformedTp = tp.replaceTypeVariables(tpToReplace, replaced, inferredTypes);
+ // Identity comparison on purpose
+ if (tp.isTypeVariable() && tp.asTypeVariable().describe().equals(tpToReplace.getName())) {
+ inferredTypes.put(tp.asTypeParameter(), replaced);
+ }
+ // FIXME
+ if (true) {
+ List<ResolvedType> typeParametersCorrected = result.asReferenceType().typeParametersValues();
+ typeParametersCorrected.set(i, transformedTp);
+ result = create(typeDeclaration, typeParametersCorrected);
+ }
+ i++;
+ }
+
+ List<ResolvedType> values = result.typeParametersValues();
+ // FIXME
+ if(values.contains(tpToReplace)){
+ int index = values.indexOf(tpToReplace);
+ values.set(index, replaced);
+ return create(result.getTypeDeclaration(), values);
+ }
+
+ return result;
+ }
+
+ ///
+ /// Assignability
+ ///
+
+ /**
+ * This method checks if ThisType t = new OtherType() would compile.
+ */
+ @Override
+ public abstract boolean isAssignableBy(ResolvedType other);
+
+ ///
+ /// Ancestors
+ ///
+
+ /**
+ * Return all ancestors, that means all superclasses and interfaces.
+ * This list should always include Object (unless this is a reference to Object).
+ * The type typeParametersValues should be expressed in terms of this type typeParametersValues.
+ * <p>
+ * For example, given:
+ * <p>
+ * class Foo&lt;A, B&gt; {}
+ * class Bar&lt;C&gt; extends Foo&lt;C, String&gt; {}
+ * <p>
+ * a call to getAllAncestors on a reference to Bar having type parameter Boolean should include
+ * Foo&lt;Boolean, String&gt;.
+ */
+ public abstract List<ResolvedReferenceType> getAllAncestors();
+
+ public final List<ResolvedReferenceType> getAllInterfacesAncestors() {
+ return getAllAncestors().stream()
+ .filter(it -> it.getTypeDeclaration().isInterface())
+ .collect(Collectors.toList());
+ }
+
+ public final List<ResolvedReferenceType> getAllClassesAncestors() {
+ return getAllAncestors().stream()
+ .filter(it -> it.getTypeDeclaration().isClass())
+ .collect(Collectors.toList());
+ }
+
+ ///
+ /// Type parameters
+ ///
+
+ /**
+ * Get the type associated with the type parameter with the given name.
+ * It returns Optional.empty unless the type declaration declares a type parameter with the given name.
+ */
+ public Optional<ResolvedType> getGenericParameterByName(String name) {
+ for (ResolvedTypeParameterDeclaration tp : typeDeclaration.getTypeParameters()) {
+ if (tp.getName().equals(name)) {
+ return Optional.of(this.typeParametersMap().getValue(tp));
+ }
+ }
+ return Optional.empty();
+ }
+
+ /**
+ * Get the values for all type parameters declared on this type.
+ * The list can be empty for raw types.
+ */
+ public List<ResolvedType> typeParametersValues() {
+ return this.typeParametersMap.isEmpty() ? Collections.emptyList() : typeDeclaration.getTypeParameters().stream().map(tp -> typeParametersMap.getValue(tp)).collect(Collectors.toList());
+ }
+
+ /**
+ * Get the values for all type parameters declared on this type.
+ * In case of raw types the values correspond to TypeVariables.
+ */
+ public List<Pair<ResolvedTypeParameterDeclaration, ResolvedType>> getTypeParametersMap() {
+ List<Pair<ResolvedTypeParameterDeclaration, ResolvedType>> typeParametersMap = new ArrayList<>();
+ if (!isRawType()) {
+ for (int i = 0; i < typeDeclaration.getTypeParameters().size(); i++) {
+ typeParametersMap.add(new Pair<>(typeDeclaration.getTypeParameters().get(0), typeParametersValues().get(i)));
+ }
+ }
+ return typeParametersMap;
+ }
+
+ @Override
+ public ResolvedTypeParametersMap typeParametersMap() {
+ return typeParametersMap;
+ }
+
+ ///
+ /// Other methods introduced by ReferenceType
+ ///
+
+ /**
+ * Corresponding TypeDeclaration
+ */
+ public final ResolvedReferenceTypeDeclaration getTypeDeclaration() {
+ return typeDeclaration;
+ }
+
+ /**
+ * The type of the field could be different from the one in the corresponding FieldDeclaration because
+ * type variables would be solved.
+ */
+ public Optional<ResolvedType> getFieldType(String name) {
+ if (!typeDeclaration.hasField(name)) {
+ return Optional.empty();
+ }
+ ResolvedType type = typeDeclaration.getField(name).getType();
+ type = useThisTypeParametersOnTheGivenType(type);
+ return Optional.of(type);
+ }
+
+ /**
+ * Has the TypeDeclaration a name? Anonymous classes do not have one.
+ */
+ public boolean hasName() {
+ return typeDeclaration.hasName();
+ }
+
+ /**
+ * Qualified name of the declaration.
+ */
+ public String getQualifiedName() {
+ return typeDeclaration.getQualifiedName();
+ }
+
+ /**
+ * Id of the declaration. It corresponds to the qualified name, unless for local classes.
+ */
+ public String getId() {
+ return typeDeclaration.getId();
+ }
+
+ /**
+ * Methods declared on this type.
+ */
+ public abstract Set<MethodUsage> getDeclaredMethods();
+
+ public boolean isRawType() {
+ if (!typeDeclaration.getTypeParameters().isEmpty()) {
+ if (typeParametersMap().isEmpty()) {
+ return true;
+ }
+ for (String name : typeParametersMap().getNames()) {
+ Optional<ResolvedType> value = typeParametersMap().getValueBySignature(name);
+ if (value.isPresent() && value.get().isTypeVariable() && value.get().asTypeVariable().qualifiedName().equals(name)) {
+ // nothing to do
+ } else {
+ return false;
+ }
+ }
+ return true;
+ }
+ return false;
+ }
+
+ public Optional<ResolvedType> typeParamValue(ResolvedTypeParameterDeclaration typeParameterDeclaration) {
+ if (typeParameterDeclaration.declaredOnMethod()) {
+ throw new IllegalArgumentException();
+ }
+ String typeId = this.getTypeDeclaration().getId();
+ if (typeId.equals(typeParameterDeclaration.getContainerId())) {
+ return Optional.of(this.typeParametersMap().getValue(typeParameterDeclaration));
+ }
+ for (ResolvedReferenceType ancestor : this.getAllAncestors()) {
+ if (ancestor.getId().equals(typeParameterDeclaration.getContainerId())) {
+ return Optional.of(ancestor.typeParametersMap().getValue(typeParameterDeclaration));
+ }
+ }
+ return Optional.empty();
+ }
+
+ public abstract ResolvedType toRawType();
+
+ //
+ // Protected methods
+ //
+
+ protected abstract ResolvedReferenceType create(ResolvedReferenceTypeDeclaration typeDeclaration, List<ResolvedType> typeParameters);
+
+ protected ResolvedReferenceType create(ResolvedReferenceTypeDeclaration typeDeclaration, ResolvedTypeParametersMap typeParametersMap) {
+ return create(typeDeclaration, typeDeclaration.getTypeParameters().stream()
+ .map(typeParametersMap::getValue)
+ .collect(Collectors.toList()));
+ }
+
+ protected abstract ResolvedReferenceType create(ResolvedReferenceTypeDeclaration typeDeclaration);
+
+ protected boolean isCorrespondingBoxingType(String typeName) {
+ switch (typeName) {
+ case "boolean":
+ return getQualifiedName().equals(Boolean.class.getCanonicalName());
+ case "char":
+ return getQualifiedName().equals(Character.class.getCanonicalName());
+ case "byte":
+ return getQualifiedName().equals(Byte.class.getCanonicalName());
+ case "short":
+ return getQualifiedName().equals(Short.class.getCanonicalName());
+ case "int":
+ return getQualifiedName().equals(Integer.class.getCanonicalName());
+ case "long":
+ return getQualifiedName().equals(Long.class.getCanonicalName());
+ case "float":
+ return getQualifiedName().equals(Float.class.getCanonicalName());
+ case "double":
+ return getQualifiedName().equals(Double.class.getCanonicalName());
+ default:
+ throw new UnsupportedOperationException(typeName);
+ }
+ }
+
+ protected boolean compareConsideringTypeParameters(ResolvedReferenceType other) {
+ if (other.equals(this)) {
+ return true;
+ }
+ if (this.getQualifiedName().equals(other.getQualifiedName())) {
+ if (this.isRawType() || other.isRawType()) {
+ return true;
+ }
+ if (this.typeParametersValues().size() != other.typeParametersValues().size()) {
+ throw new IllegalStateException();
+ }
+ for (int i = 0; i < typeParametersValues().size(); i++) {
+ ResolvedType thisParam = typeParametersValues().get(i);
+ ResolvedType otherParam = other.typeParametersValues().get(i);
+ if (!thisParam.equals(otherParam)) {
+ if (thisParam instanceof ResolvedWildcard) {
+ ResolvedWildcard thisParamAsWildcard = (ResolvedWildcard) thisParam;
+ if (thisParamAsWildcard.isSuper() && otherParam.isAssignableBy(thisParamAsWildcard.getBoundedType())) {
+ // ok
+ } else if (thisParamAsWildcard.isExtends() && thisParamAsWildcard.getBoundedType().isAssignableBy(otherParam)) {
+ // ok
+ } else if (!thisParamAsWildcard.isBounded()) {
+ // ok
+ } else {
+ return false;
+ }
+ } else {
+ if (thisParam instanceof ResolvedTypeVariable && otherParam instanceof ResolvedTypeVariable) {
+ List<ResolvedType> thisBounds = thisParam.asTypeVariable().asTypeParameter().getBounds().stream().map(bound -> bound.getType()).collect(Collectors.toList());
+ List<ResolvedType> otherBounds = otherParam.asTypeVariable().asTypeParameter().getBounds().stream().map(bound -> bound.getType()).collect(Collectors.toList());
+ if (thisBounds.size() == otherBounds.size() && otherBounds.containsAll(thisBounds)) {
+ return true;
+ }
+ }
+ return false;
+ }
+ }
+ }
+ return true;
+ }
+ return false;
+ }
+
+ //
+ // Private methods
+ //
+
+ private static List<ResolvedType> deriveParams(ResolvedReferenceTypeDeclaration typeDeclaration) {
+ return typeDeclaration.getTypeParameters().stream().map((tp) -> new ResolvedTypeVariable(tp)).collect(Collectors.toList());
+ }
+
+ public abstract ResolvedReferenceType deriveTypeParameters(ResolvedTypeParametersMap typeParametersMap);
+}
diff --git a/javaparser-core/src/main/java/com/github/javaparser/resolution/types/ResolvedType.java b/javaparser-core/src/main/java/com/github/javaparser/resolution/types/ResolvedType.java
new file mode 100644
index 000000000..4f6857f99
--- /dev/null
+++ b/javaparser-core/src/main/java/com/github/javaparser/resolution/types/ResolvedType.java
@@ -0,0 +1,181 @@
+/*
+ * Copyright (C) 2007-2010 Júlio Vilmar Gesser.
+ * Copyright (C) 2011, 2013-2016 The JavaParser Team.
+ *
+ * This file is part of JavaParser.
+ *
+ * JavaParser can be used either under the terms of
+ * a) the GNU Lesser General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ * b) the terms of the Apache License
+ *
+ * You should have received a copy of both licenses in LICENCE.LGPL and
+ * LICENCE.APACHE. Please refer to those files for details.
+ *
+ * JavaParser is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License for more details.
+ */
+
+package com.github.javaparser.resolution.types;
+
+import com.github.javaparser.resolution.declarations.ResolvedTypeParameterDeclaration;
+
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+/**
+ * A resolved type. It could be a primitive type or a reference type (enum, class, interface). In the later case it
+ * could take type typeParametersValues (other TypeUsages). It could also be a TypeVariable, like in:
+ * <p>
+ * class A&lt;Bgt; { }
+ * <p>
+ * where B is a TypeVariable. It could also be Wildcard Type, possibly with constraints.
+ *
+ * @author Federico Tomassetti
+ */
+public interface ResolvedType {
+
+ ///
+ /// Relation with other types
+ ///
+
+ /**
+ * Does this type represent an array?
+ */
+ default boolean isArray() {
+ return false;
+ }
+
+ default int arrayLevel() {
+ if (isArray()) {
+ return 1 + this.asArrayType().getComponentType().arrayLevel();
+ } else {
+ return 0;
+ }
+ }
+
+ /**
+ * Is this a primitive type?
+ */
+ default boolean isPrimitive() {
+ return false;
+ }
+
+ /**
+ * Is this the null type?
+ */
+ default boolean isNull() {
+ return false;
+ }
+
+ /**
+ * Is this a non primitive value?
+ */
+ default boolean isReference() {
+ return isReferenceType() || isArray() || isTypeVariable() || isNull() || isWildcard();
+ }
+
+ /**
+ * Is this a lambda constraint type?
+ */
+ default boolean isConstraint() { return false; }
+
+ /**
+ * Can this be seen as a ReferenceTypeUsage?
+ * In other words: is this a reference to a class, an interface or an enum?
+ */
+ default boolean isReferenceType() {
+ return false;
+ }
+
+ default boolean isVoid() {
+ return false;
+ }
+
+ default boolean isTypeVariable() {
+ return false;
+ }
+
+ default boolean isWildcard() {
+ return false;
+ }
+
+ ///
+ /// Downcasting
+ ///
+
+ default ResolvedArrayType asArrayType() {
+ throw new UnsupportedOperationException(String.format("%s is not an Array", this));
+ }
+
+ default ResolvedReferenceType asReferenceType() {
+ throw new UnsupportedOperationException(String.format("%s is not a Reference Type", this));
+ }
+
+ default ResolvedTypeParameterDeclaration asTypeParameter() {
+ throw new UnsupportedOperationException(String.format("%s is not a Type parameter", this));
+ }
+
+ default ResolvedTypeVariable asTypeVariable() {
+ throw new UnsupportedOperationException(String.format("%s is not a Type variable", this));
+ }
+
+ default ResolvedPrimitiveType asPrimitive() {
+ throw new UnsupportedOperationException(String.format("%s is not a Primitive type", this));
+ }
+
+ default ResolvedWildcard asWildcard() {
+ throw new UnsupportedOperationException(String.format("%s is not a Wildcard", this));
+ }
+
+ default ResolvedLambdaConstraintType asConstraintType() {
+ throw new UnsupportedOperationException(String.format("%s is not a constraint type", this));
+ }
+
+ ///
+ /// Naming
+ ///
+
+ String describe();
+
+ ///
+ /// TypeParameters
+ ///
+
+ /**
+ * Replace all variables referring to the given TypeParameter with the given value.
+ * By replacing these values I could also infer some type equivalence.
+ * Those would be collected in the given map.
+ */
+ default ResolvedType replaceTypeVariables(ResolvedTypeParameterDeclaration tp, ResolvedType replaced, Map<ResolvedTypeParameterDeclaration, ResolvedType> inferredTypes) {
+ return this;
+ }
+
+ /**
+ * This is like ({@link #replaceTypeVariables(ResolvedTypeParameterDeclaration, ResolvedType, Map)} but ignores the inferred values.
+ */
+ default ResolvedType replaceTypeVariables(ResolvedTypeParameterDeclaration tp, ResolvedType replaced) {
+ return replaceTypeVariables(tp, replaced, new HashMap<>());
+ }
+
+ /**
+ * Does this type mention at all, directly or indirectly, the given type parameters?
+ */
+ default boolean mention(List<ResolvedTypeParameterDeclaration> typeParameters) {
+ throw new UnsupportedOperationException(this.getClass().getCanonicalName());
+ }
+
+ ///
+ /// Assignability
+ ///
+
+ /**
+ * This method checks if ThisType t = new OtherType() would compile.
+ */
+ boolean isAssignableBy(ResolvedType other);
+
+}
diff --git a/javaparser-core/src/main/java/com/github/javaparser/resolution/types/ResolvedTypeTransformer.java b/javaparser-core/src/main/java/com/github/javaparser/resolution/types/ResolvedTypeTransformer.java
new file mode 100644
index 000000000..a5eaebe7e
--- /dev/null
+++ b/javaparser-core/src/main/java/com/github/javaparser/resolution/types/ResolvedTypeTransformer.java
@@ -0,0 +1,30 @@
+/*
+ * Copyright (C) 2007-2010 Júlio Vilmar Gesser.
+ * Copyright (C) 2011, 2013-2016 The JavaParser Team.
+ *
+ * This file is part of JavaParser.
+ *
+ * JavaParser can be used either under the terms of
+ * a) the GNU Lesser General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ * b) the terms of the Apache License
+ *
+ * You should have received a copy of both licenses in LICENCE.LGPL and
+ * LICENCE.APACHE. Please refer to those files for details.
+ *
+ * JavaParser is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License for more details.
+ */
+
+package com.github.javaparser.resolution.types;
+
+/**
+ * @author Federico Tomassetti
+ */
+@FunctionalInterface
+public interface ResolvedTypeTransformer {
+ ResolvedType transform(ResolvedType type);
+}
diff --git a/javaparser-core/src/main/java/com/github/javaparser/resolution/types/ResolvedTypeVariable.java b/javaparser-core/src/main/java/com/github/javaparser/resolution/types/ResolvedTypeVariable.java
new file mode 100644
index 000000000..5e91057b9
--- /dev/null
+++ b/javaparser-core/src/main/java/com/github/javaparser/resolution/types/ResolvedTypeVariable.java
@@ -0,0 +1,129 @@
+/*
+ * Copyright (C) 2007-2010 Júlio Vilmar Gesser.
+ * Copyright (C) 2011, 2013-2016 The JavaParser Team.
+ *
+ * This file is part of JavaParser.
+ *
+ * JavaParser can be used either under the terms of
+ * a) the GNU Lesser General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ * b) the terms of the Apache License
+ *
+ * You should have received a copy of both licenses in LICENCE.LGPL and
+ * LICENCE.APACHE. Please refer to those files for details.
+ *
+ * JavaParser is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License for more details.
+ */
+
+package com.github.javaparser.resolution.types;
+
+import com.github.javaparser.resolution.declarations.ResolvedTypeParameterDeclaration;
+
+import java.util.List;
+import java.util.Map;
+
+/**
+ * From JLS 4.4: A type variable is introduced by the declaration of a type parameter of a generic class,
+ * interface, method, or constructor (§8.1.2, §9.1.2, §8.4.4, §8.8.4).
+ *
+ * @author Federico Tomassetti
+ */
+public class ResolvedTypeVariable implements ResolvedType {
+
+ private ResolvedTypeParameterDeclaration typeParameter;
+
+ public ResolvedTypeVariable(ResolvedTypeParameterDeclaration typeParameter) {
+ this.typeParameter = typeParameter;
+ }
+
+ @Override
+ public String toString() {
+ return "TypeVariable {" + typeParameter.getQualifiedName() + "}";
+ }
+
+ public String qualifiedName() {
+ return this.typeParameter.getQualifiedName();
+ }
+
+ @Override
+ public boolean equals(Object o) {
+ if (this == o) return true;
+ if (o == null || getClass() != o.getClass()) return false;
+
+ ResolvedTypeVariable that = (ResolvedTypeVariable) o;
+
+ if (!typeParameter.getName().equals(that.typeParameter.getName())) return false;
+ if (typeParameter.declaredOnType() != that.typeParameter.declaredOnType()) return false;
+ if (typeParameter.declaredOnMethod() != that.typeParameter.declaredOnMethod()) return false;
+
+ return true;
+ }
+
+ @Override
+ public int hashCode() {
+ return typeParameter.hashCode();
+ }
+
+ @Override
+ public boolean isArray() {
+ return false;
+ }
+
+ @Override
+ public boolean isPrimitive() {
+ return false;
+ }
+
+ @Override
+ public ResolvedType replaceTypeVariables(ResolvedTypeParameterDeclaration tpToBeReplaced, ResolvedType replaced, Map<ResolvedTypeParameterDeclaration, ResolvedType> inferredTypes) {
+ if(tpToBeReplaced.getName().equals(this.typeParameter.getName())){
+ inferredTypes.put(this.asTypeParameter(), replaced);
+ return replaced;
+ } else {
+ return this;
+ }
+ }
+
+ @Override
+ public boolean isReferenceType() {
+ return false;
+ }
+
+ @Override
+ public String describe() {
+ return typeParameter.getName();
+ }
+
+ @Override
+ public ResolvedTypeParameterDeclaration asTypeParameter() {
+ return typeParameter;
+ }
+
+ @Override
+ public ResolvedTypeVariable asTypeVariable() {
+ return this;
+ }
+
+ @Override
+ public boolean isTypeVariable() {
+ return true;
+ }
+
+ @Override
+ public boolean isAssignableBy(ResolvedType other) {
+ if (other.isTypeVariable()) {
+ return describe().equals(other.describe());
+ } else {
+ return true;
+ }
+ }
+
+ @Override
+ public boolean mention(List<ResolvedTypeParameterDeclaration> typeParameters) {
+ return typeParameters.contains(typeParameter);
+ }
+}
diff --git a/javaparser-core/src/main/java/com/github/javaparser/resolution/types/ResolvedUnionType.java b/javaparser-core/src/main/java/com/github/javaparser/resolution/types/ResolvedUnionType.java
new file mode 100644
index 000000000..845fb8491
--- /dev/null
+++ b/javaparser-core/src/main/java/com/github/javaparser/resolution/types/ResolvedUnionType.java
@@ -0,0 +1,69 @@
+/*
+ * Copyright (C) 2007-2010 Júlio Vilmar Gesser.
+ * Copyright (C) 2011, 2013-2016 The JavaParser Team.
+ *
+ * This file is part of JavaParser.
+ *
+ * JavaParser can be used either under the terms of
+ * a) the GNU Lesser General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ * b) the terms of the Apache License
+ *
+ * You should have received a copy of both licenses in LICENCE.LGPL and
+ * LICENCE.APACHE. Please refer to those files for details.
+ *
+ * JavaParser is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License for more details.
+ */
+
+package com.github.javaparser.resolution.types;
+
+import java.util.Collection;
+import java.util.HashSet;
+import java.util.LinkedList;
+import java.util.List;
+import java.util.stream.Collectors;
+
+/**
+ * A union type is defined in java as list of types separates by pipes.
+ *
+ * @author Federico Tomassetti
+ */
+public class ResolvedUnionType implements ResolvedType {
+ private List<ResolvedType> elements;
+
+ public ResolvedUnionType(Collection<ResolvedType> elements) {
+ if (elements.size() < 2) {
+ throw new IllegalArgumentException("An union type should have at least two elements. This has " + elements.size());
+ }
+ this.elements = new LinkedList<>(elements);
+ }
+
+ @Override
+ public boolean equals(Object o) {
+ if (this == o) return true;
+ if (o == null || getClass() != o.getClass()) return false;
+
+ ResolvedUnionType that = (ResolvedUnionType) o;
+
+ return new HashSet<>(elements).equals(new HashSet<>(that.elements));
+ }
+
+ @Override
+ public int hashCode() {
+ return new HashSet<>(elements).hashCode();
+ }
+
+ @Override
+ public String describe() {
+ return String.join(" | ", elements.stream().map(ResolvedType::describe).collect(Collectors.toList()));
+ }
+
+ @Override
+ public boolean isAssignableBy(ResolvedType other) {
+ return elements.stream().allMatch(e -> e.isAssignableBy(other));
+ }
+}
diff --git a/javaparser-core/src/main/java/com/github/javaparser/resolution/types/ResolvedVoidType.java b/javaparser-core/src/main/java/com/github/javaparser/resolution/types/ResolvedVoidType.java
new file mode 100644
index 000000000..b8f219453
--- /dev/null
+++ b/javaparser-core/src/main/java/com/github/javaparser/resolution/types/ResolvedVoidType.java
@@ -0,0 +1,49 @@
+/*
+ * Copyright (C) 2007-2010 Júlio Vilmar Gesser.
+ * Copyright (C) 2011, 2013-2016 The JavaParser Team.
+ *
+ * This file is part of JavaParser.
+ *
+ * JavaParser can be used either under the terms of
+ * a) the GNU Lesser General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ * b) the terms of the Apache License
+ *
+ * You should have received a copy of both licenses in LICENCE.LGPL and
+ * LICENCE.APACHE. Please refer to those files for details.
+ *
+ * JavaParser is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License for more details.
+ */
+
+package com.github.javaparser.resolution.types;
+
+/**
+ * The special type void.
+ *
+ * @author Federico Tomassetti
+ */
+public class ResolvedVoidType implements ResolvedType {
+ public static final ResolvedType INSTANCE = new ResolvedVoidType();
+
+ private ResolvedVoidType() {
+ }
+
+ @Override
+ public String describe() {
+ return "void";
+ }
+
+ @Override
+ public boolean isAssignableBy(ResolvedType other) {
+ throw new UnsupportedOperationException();
+ }
+
+ @Override
+ public boolean isVoid() {
+ return true;
+ }
+}
diff --git a/javaparser-core/src/main/java/com/github/javaparser/resolution/types/ResolvedWildcard.java b/javaparser-core/src/main/java/com/github/javaparser/resolution/types/ResolvedWildcard.java
new file mode 100644
index 000000000..51fd099e4
--- /dev/null
+++ b/javaparser-core/src/main/java/com/github/javaparser/resolution/types/ResolvedWildcard.java
@@ -0,0 +1,183 @@
+/*
+ * Copyright (C) 2007-2010 Júlio Vilmar Gesser.
+ * Copyright (C) 2011, 2013-2016 The JavaParser Team.
+ *
+ * This file is part of JavaParser.
+ *
+ * JavaParser can be used either under the terms of
+ * a) the GNU Lesser General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ * b) the terms of the Apache License
+ *
+ * You should have received a copy of both licenses in LICENCE.LGPL and
+ * LICENCE.APACHE. Please refer to those files for details.
+ *
+ * JavaParser is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License for more details.
+ */
+
+package com.github.javaparser.resolution.types;
+
+import com.github.javaparser.resolution.declarations.ResolvedTypeParameterDeclaration;
+
+import java.util.List;
+import java.util.Map;
+
+/**
+ * A wildcard can be:
+ * - unbounded (?)
+ * - have a lower bound (? super Number)
+ * - have an upper bound (? extends Number)
+ * It is not possible to have both a lower and an upper bound at the same time.
+ *
+ * @author Federico Tomassetti
+ */
+public class ResolvedWildcard implements ResolvedType {
+
+ public static ResolvedWildcard UNBOUNDED = new ResolvedWildcard(null, null);
+
+ private BoundType type;
+ private ResolvedType boundedType;
+
+ private ResolvedWildcard(BoundType type, ResolvedType boundedType) {
+ if (type == null && boundedType != null) {
+ throw new IllegalArgumentException();
+ }
+ if (type != null && boundedType == null) {
+ throw new IllegalArgumentException();
+ }
+ this.type = type;
+ this.boundedType = boundedType;
+ }
+
+ public static ResolvedWildcard superBound(ResolvedType type) {
+ return new ResolvedWildcard(BoundType.SUPER, type);
+ }
+
+ public static ResolvedWildcard extendsBound(ResolvedType type) {
+ return new ResolvedWildcard(BoundType.EXTENDS, type);
+ }
+
+ @Override
+ public String toString() {
+ return "WildcardUsage{" +
+ "type=" + type +
+ ", boundedType=" + boundedType +
+ '}';
+ }
+
+ public boolean isWildcard() {
+ return true;
+ }
+
+ public ResolvedWildcard asWildcard() {
+ return this;
+ }
+
+ @Override
+ public boolean equals(Object o) {
+ if (this == o) return true;
+ if (!(o instanceof ResolvedWildcard)) return false;
+
+ ResolvedWildcard that = (ResolvedWildcard) o;
+
+ if (boundedType != null ? !boundedType.equals(that.boundedType) : that.boundedType != null) return false;
+ if (type != that.type) return false;
+
+ return true;
+ }
+
+ @Override
+ public int hashCode() {
+ int result = type != null ? type.hashCode() : 0;
+ result = 31 * result + (boundedType != null ? boundedType.hashCode() : 0);
+ return result;
+ }
+
+ @Override
+ public String describe() {
+ if (type == null) {
+ return "?";
+ } else if (type == BoundType.SUPER) {
+ return "? super " + boundedType.describe();
+ } else if (type == BoundType.EXTENDS) {
+ return "? extends " + boundedType.describe();
+ } else {
+ throw new UnsupportedOperationException();
+ }
+ }
+
+ public boolean isSuper() {
+ return type == BoundType.SUPER;
+ }
+
+ public boolean isExtends() {
+ return type == BoundType.EXTENDS;
+ }
+
+ public boolean isBounded() {
+ return isSuper() || isExtends();
+ }
+
+ public ResolvedType getBoundedType() {
+ if (boundedType == null) {
+ throw new IllegalStateException();
+ }
+ return boundedType;
+ }
+
+ @Override
+ public boolean isAssignableBy(ResolvedType other) {
+ if (boundedType == null) {
+ //return other.isReferenceType() && other.asReferenceType().getQualifiedName().equals(Object.class.getCanonicalName());
+ return false;
+ } else if (type == BoundType.SUPER) {
+ return boundedType.isAssignableBy(other);
+ } else if (type == BoundType.EXTENDS) {
+ return false;
+ } else {
+ throw new RuntimeException();
+ }
+ }
+
+ @Override
+ public ResolvedType replaceTypeVariables(ResolvedTypeParameterDeclaration tpToReplace, ResolvedType replaced, Map<ResolvedTypeParameterDeclaration, ResolvedType> inferredTypes) {
+ if (replaced == null) {
+ throw new IllegalArgumentException();
+ }
+ if (boundedType == null) {
+ return this;
+ }
+ ResolvedType boundedTypeReplaced = boundedType.replaceTypeVariables(tpToReplace, replaced, inferredTypes);
+ if (boundedTypeReplaced == null) {
+ throw new RuntimeException();
+ }
+ if (boundedTypeReplaced != boundedType) {
+ return new ResolvedWildcard(type, boundedTypeReplaced);
+ } else {
+ return this;
+ }
+ }
+
+ @Override
+ public boolean mention(List<ResolvedTypeParameterDeclaration> typeParameters) {
+ return boundedType != null && boundedType.mention(typeParameters);
+ }
+
+ public boolean isUpperBounded() {
+ return isSuper();
+ }
+
+ public boolean isLowerBounded() {
+ return isExtends();
+ }
+
+ public enum BoundType {
+ SUPER,
+ EXTENDS
+ }
+
+}
diff --git a/javaparser-core/src/main/java/com/github/javaparser/resolution/types/parametrization/ResolvedTypeParameterValueProvider.java b/javaparser-core/src/main/java/com/github/javaparser/resolution/types/parametrization/ResolvedTypeParameterValueProvider.java
new file mode 100644
index 000000000..c310fb5f7
--- /dev/null
+++ b/javaparser-core/src/main/java/com/github/javaparser/resolution/types/parametrization/ResolvedTypeParameterValueProvider.java
@@ -0,0 +1,72 @@
+/*
+ * Copyright (C) 2007-2010 Júlio Vilmar Gesser.
+ * Copyright (C) 2011, 2013-2016 The JavaParser Team.
+ *
+ * This file is part of JavaParser.
+ *
+ * JavaParser can be used either under the terms of
+ * a) the GNU Lesser General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ * b) the terms of the Apache License
+ *
+ * You should have received a copy of both licenses in LICENCE.LGPL and
+ * LICENCE.APACHE. Please refer to those files for details.
+ *
+ * JavaParser is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License for more details.
+ */
+
+package com.github.javaparser.resolution.types.parametrization;
+
+import com.github.javaparser.resolution.declarations.ResolvedTypeParameterDeclaration;
+import com.github.javaparser.resolution.types.ResolvedType;
+import com.github.javaparser.resolution.types.ResolvedWildcard;
+
+import java.util.Optional;
+
+/**
+ * @author Federico Tomassetti
+ */
+public interface ResolvedTypeParameterValueProvider {
+
+ /**
+ * Calculate the value for the given type parameter.
+ * It could be inherited.
+ */
+ Optional<ResolvedType> typeParamValue(ResolvedTypeParameterDeclaration typeParameterDeclaration);
+
+ /**
+ * Replace the type typeParametersValues present in the given type with the ones for which this type
+ * has a value.
+ */
+ default ResolvedType useThisTypeParametersOnTheGivenType(ResolvedType type) {
+ if (type.isTypeVariable()) {
+ ResolvedTypeParameterDeclaration typeParameter = type.asTypeParameter();
+ if (typeParameter.declaredOnType()) {
+ Optional<ResolvedType> typeParam = typeParamValue(typeParameter);
+ if (typeParam.isPresent()) {
+ type = typeParam.get();
+ }
+ }
+ }
+
+ if (type.isWildcard() && type.asWildcard().isBounded()) {
+ if (type.asWildcard().isExtends()) {
+ return ResolvedWildcard.extendsBound(useThisTypeParametersOnTheGivenType(type.asWildcard().getBoundedType()));
+ } else {
+ return ResolvedWildcard.superBound(useThisTypeParametersOnTheGivenType(type.asWildcard().getBoundedType()));
+ }
+ }
+
+ if (type.isReferenceType()) {
+ type = type.asReferenceType().transformTypeParameters(this::useThisTypeParametersOnTheGivenType);
+ }
+
+ return type;
+ }
+
+ Optional<ResolvedType> getGenericParameterByName(String name);
+}
diff --git a/javaparser-core/src/main/java/com/github/javaparser/resolution/types/parametrization/ResolvedTypeParametersMap.java b/javaparser-core/src/main/java/com/github/javaparser/resolution/types/parametrization/ResolvedTypeParametersMap.java
new file mode 100644
index 000000000..b1cb16dae
--- /dev/null
+++ b/javaparser-core/src/main/java/com/github/javaparser/resolution/types/parametrization/ResolvedTypeParametersMap.java
@@ -0,0 +1,146 @@
+/*
+ * Copyright (C) 2007-2010 Júlio Vilmar Gesser.
+ * Copyright (C) 2011, 2013-2016 The JavaParser Team.
+ *
+ * This file is part of JavaParser.
+ *
+ * JavaParser can be used either under the terms of
+ * a) the GNU Lesser General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ * b) the terms of the Apache License
+ *
+ * You should have received a copy of both licenses in LICENCE.LGPL and
+ * LICENCE.APACHE. Please refer to those files for details.
+ *
+ * JavaParser is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License for more details.
+ */
+
+package com.github.javaparser.resolution.types.parametrization;
+
+import com.github.javaparser.resolution.declarations.ResolvedTypeParameterDeclaration;
+import com.github.javaparser.resolution.types.ResolvedType;
+import com.github.javaparser.resolution.types.ResolvedTypeVariable;
+
+import java.util.*;
+
+/**
+ * A map of values associated to TypeParameters.
+ *
+ * @author Federico Tomassetti
+ */
+public class ResolvedTypeParametersMap {
+
+ public static class Builder {
+ private Map<String, ResolvedType> nameToValue;
+ private Map<String, ResolvedTypeParameterDeclaration> nameToDeclaration;
+
+ public Builder() {
+ nameToValue = new HashMap<>();
+ nameToDeclaration = new HashMap<>();
+ }
+
+ private Builder(Map<String, ResolvedType> nameToValue,
+ Map<String, ResolvedTypeParameterDeclaration> nameToDeclaration) {
+ this.nameToValue = new HashMap<>();
+ this.nameToValue.putAll(nameToValue);
+ this.nameToDeclaration = new HashMap<>();
+ this.nameToDeclaration.putAll(nameToDeclaration);
+ }
+
+ public ResolvedTypeParametersMap build() {
+ return new ResolvedTypeParametersMap(nameToValue, nameToDeclaration);
+ }
+
+ public Builder setValue(ResolvedTypeParameterDeclaration typeParameter,
+ ResolvedType value) {
+ // TODO: we shouldn't just silently overwrite existing types!
+ String qualifiedName = typeParameter.getQualifiedName();
+ nameToValue.put(qualifiedName, value);
+ nameToDeclaration.put(qualifiedName, typeParameter);
+ return this;
+ }
+ }
+
+ @Override
+ public boolean equals(Object o) {
+ if (this == o) return true;
+ if (!(o instanceof ResolvedTypeParametersMap)) return false;
+
+ ResolvedTypeParametersMap that = (ResolvedTypeParametersMap) o;
+
+ return nameToValue.equals(that.nameToValue) && nameToDeclaration.equals(that.nameToDeclaration);
+
+ }
+
+ @Override
+ public int hashCode() {
+ return nameToValue.hashCode();
+ }
+
+ @Override
+ public String toString() {
+ return "TypeParametersMap{" +
+ "nameToValue=" + nameToValue +
+ '}';
+ }
+
+ private Map<String, ResolvedType> nameToValue;
+ private Map<String, ResolvedTypeParameterDeclaration> nameToDeclaration;
+
+ public static ResolvedTypeParametersMap empty() {
+ return new Builder().build();
+ }
+
+ private ResolvedTypeParametersMap(Map<String, ResolvedType> nameToValue,
+ Map<String, ResolvedTypeParameterDeclaration> nameToDeclaration) {
+ this.nameToValue = new HashMap<>();
+ this.nameToValue.putAll(nameToValue);
+ this.nameToDeclaration = new HashMap<>();
+ this.nameToDeclaration.putAll(nameToDeclaration);
+ }
+
+ public ResolvedType getValue(ResolvedTypeParameterDeclaration typeParameter) {
+ String qualifiedName = typeParameter.getQualifiedName();
+ if (nameToValue.containsKey(qualifiedName)) {
+ return nameToValue.get(qualifiedName);
+ } else {
+ return new ResolvedTypeVariable(typeParameter);
+ }
+ }
+
+ public Optional<ResolvedType> getValueBySignature(String signature) {
+ if (nameToValue.containsKey(signature)) {
+ return Optional.of(nameToValue.get(signature));
+ } else {
+ return Optional.empty();
+ }
+ }
+
+ public List<String> getNames(){
+ return new ArrayList<>(nameToValue.keySet());
+ }
+
+ public List<ResolvedType> getTypes(){
+ return new ArrayList<>(nameToValue.values());
+ }
+
+ public Builder toBuilder() {
+ return new Builder(nameToValue, nameToDeclaration);
+ }
+
+ public boolean isEmpty() {
+ return nameToValue.isEmpty();
+ }
+
+ public ResolvedType replaceAll(ResolvedType type) {
+ Map<ResolvedTypeParameterDeclaration, ResolvedType> inferredTypes = new HashMap<>();
+ for (ResolvedTypeParameterDeclaration typeParameterDeclaration : this.nameToDeclaration.values()) {
+ type = type.replaceTypeVariables(typeParameterDeclaration, getValue(typeParameterDeclaration), inferredTypes);
+ }
+ return type;
+ }
+}
diff --git a/javaparser-core/src/main/java/com/github/javaparser/resolution/types/parametrization/ResolvedTypeParametrized.java b/javaparser-core/src/main/java/com/github/javaparser/resolution/types/parametrization/ResolvedTypeParametrized.java
new file mode 100644
index 000000000..91a792ab7
--- /dev/null
+++ b/javaparser-core/src/main/java/com/github/javaparser/resolution/types/parametrization/ResolvedTypeParametrized.java
@@ -0,0 +1,31 @@
+/*
+ * Copyright (C) 2007-2010 Júlio Vilmar Gesser.
+ * Copyright (C) 2011, 2013-2016 The JavaParser Team.
+ *
+ * This file is part of JavaParser.
+ *
+ * JavaParser can be used either under the terms of
+ * a) the GNU Lesser General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ * b) the terms of the Apache License
+ *
+ * You should have received a copy of both licenses in LICENCE.LGPL and
+ * LICENCE.APACHE. Please refer to those files for details.
+ *
+ * JavaParser is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License for more details.
+ */
+
+package com.github.javaparser.resolution.types.parametrization;
+
+/**
+ * Something which can have values for TypeParameters.
+ *
+ * @author Federico Tomassetti
+ */
+public interface ResolvedTypeParametrized {
+ ResolvedTypeParametersMap typeParametersMap();
+}