aboutsummaryrefslogtreecommitdiffstats
path: root/javaparser-symbol-solver-core/src/main/java/com/github/javaparser/symbolsolver/javaparsermodel
diff options
context:
space:
mode:
authorandroid-build-team Robot <android-build-team-robot@google.com>2018-03-04 08:21:35 +0000
committerandroid-build-team Robot <android-build-team-robot@google.com>2018-03-04 08:21:35 +0000
commitb4c1397d5df9370f6358d4f8e9efd27e0f67dec1 (patch)
tree6789ec288d344cf5fd5d057bcf1efc9545b1af28 /javaparser-symbol-solver-core/src/main/java/com/github/javaparser/symbolsolver/javaparsermodel
parent92d661a1d239131fb5c1e019a8f2ac7584d2d3f6 (diff)
parent1afe9e0652b9b53edade5aa276162abe27b32a67 (diff)
downloadplatform_external_javaparser-android-9.0.0_r7.tar.gz
platform_external_javaparser-android-9.0.0_r7.tar.bz2
platform_external_javaparser-android-9.0.0_r7.zip
Snap for 4632767 from 1afe9e0652b9b53edade5aa276162abe27b32a67 to pi-releaseandroid-wear-9.0.0_r9android-wear-9.0.0_r8android-wear-9.0.0_r7android-wear-9.0.0_r6android-wear-9.0.0_r5android-wear-9.0.0_r4android-wear-9.0.0_r3android-wear-9.0.0_r23android-wear-9.0.0_r22android-wear-9.0.0_r21android-wear-9.0.0_r20android-wear-9.0.0_r2android-wear-9.0.0_r19android-wear-9.0.0_r18android-wear-9.0.0_r17android-wear-9.0.0_r16android-wear-9.0.0_r15android-wear-9.0.0_r14android-wear-9.0.0_r13android-wear-9.0.0_r12android-wear-9.0.0_r11android-wear-9.0.0_r10android-wear-9.0.0_r1android-vts-9.0_r9android-vts-9.0_r8android-vts-9.0_r7android-vts-9.0_r6android-vts-9.0_r5android-vts-9.0_r4android-vts-9.0_r14android-vts-9.0_r13android-vts-9.0_r12android-vts-9.0_r11android-vts-9.0_r10android-cts-9.0_r9android-cts-9.0_r8android-cts-9.0_r7android-cts-9.0_r6android-cts-9.0_r5android-cts-9.0_r4android-cts-9.0_r3android-cts-9.0_r2android-cts-9.0_r13android-cts-9.0_r12android-cts-9.0_r11android-cts-9.0_r10android-cts-9.0_r1android-9.0.0_r9android-9.0.0_r8android-9.0.0_r7android-9.0.0_r60android-9.0.0_r6android-9.0.0_r59android-9.0.0_r58android-9.0.0_r57android-9.0.0_r56android-9.0.0_r55android-9.0.0_r54android-9.0.0_r53android-9.0.0_r52android-9.0.0_r51android-9.0.0_r50android-9.0.0_r5android-9.0.0_r49android-9.0.0_r48android-9.0.0_r3android-9.0.0_r2android-9.0.0_r18android-9.0.0_r17android-9.0.0_r10android-9.0.0_r1security-pi-releasepie-vts-releasepie-security-releasepie-s2-releasepie-release-2pie-releasepie-r2-s2-releasepie-r2-s1-releasepie-r2-releasepie-platform-releasepie-gsipie-cuttlefish-testingpie-cts-release
Change-Id: Ibe65883e94ed5a7272dff3f100393987a1cf3da2
Diffstat (limited to 'javaparser-symbol-solver-core/src/main/java/com/github/javaparser/symbolsolver/javaparsermodel')
-rw-r--r--javaparser-symbol-solver-core/src/main/java/com/github/javaparser/symbolsolver/javaparsermodel/DefaultVisitorAdapter.java475
-rw-r--r--javaparser-symbol-solver-core/src/main/java/com/github/javaparser/symbolsolver/javaparsermodel/JavaParserFacade.java562
-rw-r--r--javaparser-symbol-solver-core/src/main/java/com/github/javaparser/symbolsolver/javaparsermodel/JavaParserFactory.java139
-rw-r--r--javaparser-symbol-solver-core/src/main/java/com/github/javaparser/symbolsolver/javaparsermodel/LambdaArgumentTypePlaceholder.java72
-rw-r--r--javaparser-symbol-solver-core/src/main/java/com/github/javaparser/symbolsolver/javaparsermodel/TypeExtractor.java517
-rw-r--r--javaparser-symbol-solver-core/src/main/java/com/github/javaparser/symbolsolver/javaparsermodel/UnsolvedSymbolException.java71
-rw-r--r--javaparser-symbol-solver-core/src/main/java/com/github/javaparser/symbolsolver/javaparsermodel/contexts/AbstractJavaParserContext.java193
-rw-r--r--javaparser-symbol-solver-core/src/main/java/com/github/javaparser/symbolsolver/javaparsermodel/contexts/AbstractMethodLikeDeclarationContext.java101
-rw-r--r--javaparser-symbol-solver-core/src/main/java/com/github/javaparser/symbolsolver/javaparsermodel/contexts/AnonymousClassDeclarationContext.java186
-rw-r--r--javaparser-symbol-solver-core/src/main/java/com/github/javaparser/symbolsolver/javaparsermodel/contexts/CatchClauseContext.java54
-rw-r--r--javaparser-symbol-solver-core/src/main/java/com/github/javaparser/symbolsolver/javaparsermodel/contexts/ClassOrInterfaceDeclarationContext.java109
-rw-r--r--javaparser-symbol-solver-core/src/main/java/com/github/javaparser/symbolsolver/javaparsermodel/contexts/CompilationUnitContext.java291
-rw-r--r--javaparser-symbol-solver-core/src/main/java/com/github/javaparser/symbolsolver/javaparsermodel/contexts/ConstructorContext.java35
-rw-r--r--javaparser-symbol-solver-core/src/main/java/com/github/javaparser/symbolsolver/javaparsermodel/contexts/ContextHelper.java74
-rw-r--r--javaparser-symbol-solver-core/src/main/java/com/github/javaparser/symbolsolver/javaparsermodel/contexts/EnumDeclarationContext.java82
-rw-r--r--javaparser-symbol-solver-core/src/main/java/com/github/javaparser/symbolsolver/javaparsermodel/contexts/FieldAccessContext.java104
-rw-r--r--javaparser-symbol-solver-core/src/main/java/com/github/javaparser/symbolsolver/javaparsermodel/contexts/ForStatementContext.java70
-rw-r--r--javaparser-symbol-solver-core/src/main/java/com/github/javaparser/symbolsolver/javaparsermodel/contexts/ForechStatementContext.java61
-rw-r--r--javaparser-symbol-solver-core/src/main/java/com/github/javaparser/symbolsolver/javaparsermodel/contexts/JavaParserTypeDeclarationAdapter.java133
-rw-r--r--javaparser-symbol-solver-core/src/main/java/com/github/javaparser/symbolsolver/javaparsermodel/contexts/LambdaExprContext.java193
-rw-r--r--javaparser-symbol-solver-core/src/main/java/com/github/javaparser/symbolsolver/javaparsermodel/contexts/MethodCallExprContext.java433
-rw-r--r--javaparser-symbol-solver-core/src/main/java/com/github/javaparser/symbolsolver/javaparsermodel/contexts/MethodContext.java35
-rw-r--r--javaparser-symbol-solver-core/src/main/java/com/github/javaparser/symbolsolver/javaparsermodel/contexts/StatementContext.java200
-rw-r--r--javaparser-symbol-solver-core/src/main/java/com/github/javaparser/symbolsolver/javaparsermodel/contexts/SwitchEntryContext.java80
-rw-r--r--javaparser-symbol-solver-core/src/main/java/com/github/javaparser/symbolsolver/javaparsermodel/contexts/TryWithResourceContext.java88
-rw-r--r--javaparser-symbol-solver-core/src/main/java/com/github/javaparser/symbolsolver/javaparsermodel/declarations/DefaultConstructorDeclaration.java82
-rw-r--r--javaparser-symbol-solver-core/src/main/java/com/github/javaparser/symbolsolver/javaparsermodel/declarations/Helper.java85
-rw-r--r--javaparser-symbol-solver-core/src/main/java/com/github/javaparser/symbolsolver/javaparsermodel/declarations/JavaParserAnnotationDeclaration.java103
-rw-r--r--javaparser-symbol-solver-core/src/main/java/com/github/javaparser/symbolsolver/javaparsermodel/declarations/JavaParserAnnotationMemberDeclaration.java40
-rw-r--r--javaparser-symbol-solver-core/src/main/java/com/github/javaparser/symbolsolver/javaparsermodel/declarations/JavaParserAnonymousClassDeclaration.java205
-rw-r--r--javaparser-symbol-solver-core/src/main/java/com/github/javaparser/symbolsolver/javaparsermodel/declarations/JavaParserClassDeclaration.java397
-rw-r--r--javaparser-symbol-solver-core/src/main/java/com/github/javaparser/symbolsolver/javaparsermodel/declarations/JavaParserConstructorDeclaration.java103
-rw-r--r--javaparser-symbol-solver-core/src/main/java/com/github/javaparser/symbolsolver/javaparsermodel/declarations/JavaParserEnumConstantDeclaration.java59
-rw-r--r--javaparser-symbol-solver-core/src/main/java/com/github/javaparser/symbolsolver/javaparsermodel/declarations/JavaParserEnumDeclaration.java350
-rw-r--r--javaparser-symbol-solver-core/src/main/java/com/github/javaparser/symbolsolver/javaparsermodel/declarations/JavaParserFieldDeclaration.java121
-rw-r--r--javaparser-symbol-solver-core/src/main/java/com/github/javaparser/symbolsolver/javaparsermodel/declarations/JavaParserInterfaceDeclaration.java335
-rw-r--r--javaparser-symbol-solver-core/src/main/java/com/github/javaparser/symbolsolver/javaparsermodel/declarations/JavaParserMethodDeclaration.java167
-rw-r--r--javaparser-symbol-solver-core/src/main/java/com/github/javaparser/symbolsolver/javaparsermodel/declarations/JavaParserParameterDeclaration.java100
-rw-r--r--javaparser-symbol-solver-core/src/main/java/com/github/javaparser/symbolsolver/javaparsermodel/declarations/JavaParserSymbolDeclaration.java171
-rw-r--r--javaparser-symbol-solver-core/src/main/java/com/github/javaparser/symbolsolver/javaparsermodel/declarations/JavaParserTypeAdapter.java140
-rw-r--r--javaparser-symbol-solver-core/src/main/java/com/github/javaparser/symbolsolver/javaparsermodel/declarations/JavaParserTypeParameter.java223
-rw-r--r--javaparser-symbol-solver-core/src/main/java/com/github/javaparser/symbolsolver/javaparsermodel/declarations/JavaParserTypeVariableDeclaration.java187
-rw-r--r--javaparser-symbol-solver-core/src/main/java/com/github/javaparser/symbolsolver/javaparsermodel/declarators/AbstractSymbolDeclarator.java35
-rw-r--r--javaparser-symbol-solver-core/src/main/java/com/github/javaparser/symbolsolver/javaparsermodel/declarators/FieldSymbolDeclarator.java46
-rw-r--r--javaparser-symbol-solver-core/src/main/java/com/github/javaparser/symbolsolver/javaparsermodel/declarators/NoSymbolDeclarator.java40
-rw-r--r--javaparser-symbol-solver-core/src/main/java/com/github/javaparser/symbolsolver/javaparsermodel/declarators/ParameterSymbolDeclarator.java42
-rw-r--r--javaparser-symbol-solver-core/src/main/java/com/github/javaparser/symbolsolver/javaparsermodel/declarators/VariableSymbolDeclarator.java52
-rw-r--r--javaparser-symbol-solver-core/src/main/java/com/github/javaparser/symbolsolver/javaparsermodel/package-info.java20
48 files changed, 7461 insertions, 0 deletions
diff --git a/javaparser-symbol-solver-core/src/main/java/com/github/javaparser/symbolsolver/javaparsermodel/DefaultVisitorAdapter.java b/javaparser-symbol-solver-core/src/main/java/com/github/javaparser/symbolsolver/javaparsermodel/DefaultVisitorAdapter.java
new file mode 100644
index 000000000..499ef3bd0
--- /dev/null
+++ b/javaparser-symbol-solver-core/src/main/java/com/github/javaparser/symbolsolver/javaparsermodel/DefaultVisitorAdapter.java
@@ -0,0 +1,475 @@
+package com.github.javaparser.symbolsolver.javaparsermodel;
+
+import com.github.javaparser.ast.*;
+import com.github.javaparser.ast.body.*;
+import com.github.javaparser.ast.comments.BlockComment;
+import com.github.javaparser.ast.comments.JavadocComment;
+import com.github.javaparser.ast.comments.LineComment;
+import com.github.javaparser.ast.expr.*;
+import com.github.javaparser.ast.modules.*;
+import com.github.javaparser.ast.stmt.*;
+import com.github.javaparser.ast.type.*;
+import com.github.javaparser.ast.visitor.GenericVisitor;
+import com.github.javaparser.resolution.types.ResolvedType;
+
+public class DefaultVisitorAdapter implements GenericVisitor<ResolvedType, Boolean> {
+ @Override
+ public ResolvedType visit(CompilationUnit node, Boolean aBoolean) {
+ throw new UnsupportedOperationException(node.getClass().getCanonicalName());
+ }
+
+ @Override
+ public ResolvedType visit(PackageDeclaration node, Boolean aBoolean) {
+ throw new UnsupportedOperationException(node.getClass().getCanonicalName());
+ }
+
+ @Override
+ public ResolvedType visit(TypeParameter node, Boolean aBoolean) {
+ throw new UnsupportedOperationException(node.getClass().getCanonicalName());
+ }
+
+ @Override
+ public ResolvedType visit(LineComment node, Boolean aBoolean) {
+ throw new UnsupportedOperationException(node.getClass().getCanonicalName());
+ }
+
+ @Override
+ public ResolvedType visit(BlockComment node, Boolean aBoolean) {
+ throw new UnsupportedOperationException(node.getClass().getCanonicalName());
+ }
+
+ @Override
+ public ResolvedType visit(ClassOrInterfaceDeclaration node, Boolean aBoolean) {
+ throw new UnsupportedOperationException(node.getClass().getCanonicalName());
+ }
+
+ @Override
+ public ResolvedType visit(EnumDeclaration node, Boolean aBoolean) {
+ throw new UnsupportedOperationException(node.getClass().getCanonicalName());
+ }
+
+ @Override
+ public ResolvedType visit(EnumConstantDeclaration node, Boolean aBoolean) {
+ throw new UnsupportedOperationException(node.getClass().getCanonicalName());
+ }
+
+ @Override
+ public ResolvedType visit(AnnotationDeclaration node, Boolean aBoolean) {
+ throw new UnsupportedOperationException(node.getClass().getCanonicalName());
+ }
+
+ @Override
+ public ResolvedType visit(AnnotationMemberDeclaration node, Boolean aBoolean) {
+ throw new UnsupportedOperationException(node.getClass().getCanonicalName());
+ }
+
+ @Override
+ public ResolvedType visit(FieldDeclaration node, Boolean aBoolean) {
+ throw new UnsupportedOperationException(node.getClass().getCanonicalName());
+ }
+
+ @Override
+ public ResolvedType visit(VariableDeclarator node, Boolean aBoolean) {
+ throw new UnsupportedOperationException(node.getClass().getCanonicalName());
+ }
+
+ @Override
+ public ResolvedType visit(ConstructorDeclaration node, Boolean aBoolean) {
+ throw new UnsupportedOperationException(node.getClass().getCanonicalName());
+ }
+
+ @Override
+ public ResolvedType visit(MethodDeclaration node, Boolean aBoolean) {
+ throw new UnsupportedOperationException(node.getClass().getCanonicalName());
+ }
+
+ @Override
+ public ResolvedType visit(Parameter node, Boolean aBoolean) {
+ throw new UnsupportedOperationException(node.getClass().getCanonicalName());
+ }
+
+ @Override
+ public ResolvedType visit(InitializerDeclaration node, Boolean aBoolean) {
+ throw new UnsupportedOperationException(node.getClass().getCanonicalName());
+ }
+
+ @Override
+ public ResolvedType visit(JavadocComment node, Boolean aBoolean) {
+ throw new UnsupportedOperationException(node.getClass().getCanonicalName());
+ }
+
+ @Override
+ public ResolvedType visit(ClassOrInterfaceType node, Boolean aBoolean) {
+ throw new UnsupportedOperationException(node.getClass().getCanonicalName());
+ }
+
+ @Override
+ public ResolvedType visit(PrimitiveType node, Boolean aBoolean) {
+ throw new UnsupportedOperationException(node.getClass().getCanonicalName());
+ }
+
+ @Override
+ public ResolvedType visit(ArrayType node, Boolean aBoolean) {
+ throw new UnsupportedOperationException(node.getClass().getCanonicalName());
+ }
+
+ @Override
+ public ResolvedType visit(ArrayCreationLevel node, Boolean aBoolean) {
+ throw new UnsupportedOperationException(node.getClass().getCanonicalName());
+ }
+
+ @Override
+ public ResolvedType visit(IntersectionType node, Boolean aBoolean) {
+ throw new UnsupportedOperationException(node.getClass().getCanonicalName());
+ }
+
+ @Override
+ public ResolvedType visit(UnionType node, Boolean aBoolean) {
+ throw new UnsupportedOperationException(node.getClass().getCanonicalName());
+ }
+
+ @Override
+ public ResolvedType visit(VoidType node, Boolean aBoolean) {
+ throw new UnsupportedOperationException(node.getClass().getCanonicalName());
+ }
+
+ @Override
+ public ResolvedType visit(WildcardType node, Boolean aBoolean) {
+ throw new UnsupportedOperationException(node.getClass().getCanonicalName());
+ }
+
+ @Override
+ public ResolvedType visit(UnknownType node, Boolean aBoolean) {
+ throw new UnsupportedOperationException(node.getClass().getCanonicalName());
+ }
+
+ @Override
+ public ResolvedType visit(ArrayAccessExpr node, Boolean aBoolean) {
+ throw new UnsupportedOperationException(node.getClass().getCanonicalName());
+ }
+
+ @Override
+ public ResolvedType visit(ArrayCreationExpr node, Boolean aBoolean) {
+ throw new UnsupportedOperationException(node.getClass().getCanonicalName());
+ }
+
+ @Override
+ public ResolvedType visit(ArrayInitializerExpr node, Boolean aBoolean) {
+ throw new UnsupportedOperationException(node.getClass().getCanonicalName());
+ }
+
+ @Override
+ public ResolvedType visit(AssignExpr node, Boolean aBoolean) {
+ throw new UnsupportedOperationException(node.getClass().getCanonicalName());
+ }
+
+ @Override
+ public ResolvedType visit(BinaryExpr node, Boolean aBoolean) {
+ throw new UnsupportedOperationException(node.getClass().getCanonicalName());
+ }
+
+ @Override
+ public ResolvedType visit(CastExpr node, Boolean aBoolean) {
+ throw new UnsupportedOperationException(node.getClass().getCanonicalName());
+ }
+
+ @Override
+ public ResolvedType visit(ClassExpr node, Boolean aBoolean) {
+ throw new UnsupportedOperationException(node.getClass().getCanonicalName());
+ }
+
+ @Override
+ public ResolvedType visit(ConditionalExpr node, Boolean aBoolean) {
+ throw new UnsupportedOperationException(node.getClass().getCanonicalName());
+ }
+
+ @Override
+ public ResolvedType visit(EnclosedExpr node, Boolean aBoolean) {
+ throw new UnsupportedOperationException(node.getClass().getCanonicalName());
+ }
+
+ @Override
+ public ResolvedType visit(FieldAccessExpr node, Boolean aBoolean) {
+ throw new UnsupportedOperationException(node.getClass().getCanonicalName());
+ }
+
+ @Override
+ public ResolvedType visit(InstanceOfExpr node, Boolean aBoolean) {
+ throw new UnsupportedOperationException(node.getClass().getCanonicalName());
+ }
+
+ @Override
+ public ResolvedType visit(StringLiteralExpr node, Boolean aBoolean) {
+ throw new UnsupportedOperationException(node.getClass().getCanonicalName());
+ }
+
+ @Override
+ public ResolvedType visit(IntegerLiteralExpr node, Boolean aBoolean) {
+ throw new UnsupportedOperationException(node.getClass().getCanonicalName());
+ }
+
+ @Override
+ public ResolvedType visit(LongLiteralExpr node, Boolean aBoolean) {
+ throw new UnsupportedOperationException(node.getClass().getCanonicalName());
+ }
+
+ @Override
+ public ResolvedType visit(CharLiteralExpr node, Boolean aBoolean) {
+ throw new UnsupportedOperationException(node.getClass().getCanonicalName());
+ }
+
+ @Override
+ public ResolvedType visit(DoubleLiteralExpr node, Boolean aBoolean) {
+ throw new UnsupportedOperationException(node.getClass().getCanonicalName());
+ }
+
+ @Override
+ public ResolvedType visit(BooleanLiteralExpr node, Boolean aBoolean) {
+ throw new UnsupportedOperationException(node.getClass().getCanonicalName());
+ }
+
+ @Override
+ public ResolvedType visit(NullLiteralExpr node, Boolean aBoolean) {
+ throw new UnsupportedOperationException(node.getClass().getCanonicalName());
+ }
+
+ @Override
+ public ResolvedType visit(MethodCallExpr node, Boolean aBoolean) {
+ throw new UnsupportedOperationException(node.getClass().getCanonicalName());
+ }
+
+ @Override
+ public ResolvedType visit(NameExpr node, Boolean aBoolean) {
+ throw new UnsupportedOperationException(node.getClass().getCanonicalName());
+ }
+
+ @Override
+ public ResolvedType visit(ObjectCreationExpr node, Boolean aBoolean) {
+ throw new UnsupportedOperationException(node.getClass().getCanonicalName());
+ }
+
+ @Override
+ public ResolvedType visit(ThisExpr node, Boolean aBoolean) {
+ throw new UnsupportedOperationException(node.getClass().getCanonicalName());
+ }
+
+ @Override
+ public ResolvedType visit(SuperExpr node, Boolean aBoolean) {
+ throw new UnsupportedOperationException(node.getClass().getCanonicalName());
+ }
+
+ @Override
+ public ResolvedType visit(UnaryExpr node, Boolean aBoolean) {
+ throw new UnsupportedOperationException(node.getClass().getCanonicalName());
+ }
+
+ @Override
+ public ResolvedType visit(VariableDeclarationExpr node, Boolean aBoolean) {
+ throw new UnsupportedOperationException(node.getClass().getCanonicalName());
+ }
+
+ @Override
+ public ResolvedType visit(MarkerAnnotationExpr node, Boolean aBoolean) {
+ throw new UnsupportedOperationException(node.getClass().getCanonicalName());
+ }
+
+ @Override
+ public ResolvedType visit(SingleMemberAnnotationExpr node, Boolean aBoolean) {
+ throw new UnsupportedOperationException(node.getClass().getCanonicalName());
+ }
+
+ @Override
+ public ResolvedType visit(NormalAnnotationExpr node, Boolean aBoolean) {
+ throw new UnsupportedOperationException(node.getClass().getCanonicalName());
+ }
+
+ @Override
+ public ResolvedType visit(MemberValuePair node, Boolean aBoolean) {
+ throw new UnsupportedOperationException(node.getClass().getCanonicalName());
+ }
+
+ @Override
+ public ResolvedType visit(ExplicitConstructorInvocationStmt node, Boolean aBoolean) {
+ throw new UnsupportedOperationException(node.getClass().getCanonicalName());
+ }
+
+ @Override
+ public ResolvedType visit(LocalClassDeclarationStmt node, Boolean aBoolean) {
+ throw new UnsupportedOperationException(node.getClass().getCanonicalName());
+ }
+
+ @Override
+ public ResolvedType visit(AssertStmt node, Boolean aBoolean) {
+ throw new UnsupportedOperationException(node.getClass().getCanonicalName());
+ }
+
+ @Override
+ public ResolvedType visit(BlockStmt node, Boolean aBoolean) {
+ throw new UnsupportedOperationException(node.getClass().getCanonicalName());
+ }
+
+ @Override
+ public ResolvedType visit(LabeledStmt node, Boolean aBoolean) {
+ throw new UnsupportedOperationException(node.getClass().getCanonicalName());
+ }
+
+ @Override
+ public ResolvedType visit(EmptyStmt node, Boolean aBoolean) {
+ throw new UnsupportedOperationException(node.getClass().getCanonicalName());
+ }
+
+ @Override
+ public ResolvedType visit(ExpressionStmt node, Boolean aBoolean) {
+ throw new UnsupportedOperationException(node.getClass().getCanonicalName());
+ }
+
+ @Override
+ public ResolvedType visit(SwitchStmt node, Boolean aBoolean) {
+ throw new UnsupportedOperationException(node.getClass().getCanonicalName());
+ }
+
+ @Override
+ public ResolvedType visit(SwitchEntryStmt node, Boolean aBoolean) {
+ throw new UnsupportedOperationException(node.getClass().getCanonicalName());
+ }
+
+ @Override
+ public ResolvedType visit(BreakStmt node, Boolean aBoolean) {
+ throw new UnsupportedOperationException(node.getClass().getCanonicalName());
+ }
+
+ @Override
+ public ResolvedType visit(ReturnStmt node, Boolean aBoolean) {
+ throw new UnsupportedOperationException(node.getClass().getCanonicalName());
+ }
+
+ @Override
+ public ResolvedType visit(IfStmt node, Boolean aBoolean) {
+ throw new UnsupportedOperationException(node.getClass().getCanonicalName());
+ }
+
+ @Override
+ public ResolvedType visit(WhileStmt node, Boolean aBoolean) {
+ throw new UnsupportedOperationException(node.getClass().getCanonicalName());
+ }
+
+ @Override
+ public ResolvedType visit(ContinueStmt node, Boolean aBoolean) {
+ throw new UnsupportedOperationException(node.getClass().getCanonicalName());
+ }
+
+ @Override
+ public ResolvedType visit(DoStmt node, Boolean aBoolean) {
+ throw new UnsupportedOperationException(node.getClass().getCanonicalName());
+ }
+
+ @Override
+ public ResolvedType visit(ForeachStmt node, Boolean aBoolean) {
+ throw new UnsupportedOperationException(node.getClass().getCanonicalName());
+ }
+
+ @Override
+ public ResolvedType visit(ForStmt node, Boolean aBoolean) {
+ throw new UnsupportedOperationException(node.getClass().getCanonicalName());
+ }
+
+ @Override
+ public ResolvedType visit(ThrowStmt node, Boolean aBoolean) {
+ throw new UnsupportedOperationException(node.getClass().getCanonicalName());
+ }
+
+ @Override
+ public ResolvedType visit(SynchronizedStmt node, Boolean aBoolean) {
+ throw new UnsupportedOperationException(node.getClass().getCanonicalName());
+ }
+
+ @Override
+ public ResolvedType visit(TryStmt node, Boolean aBoolean) {
+ throw new UnsupportedOperationException(node.getClass().getCanonicalName());
+ }
+
+ @Override
+ public ResolvedType visit(CatchClause node, Boolean aBoolean) {
+ throw new UnsupportedOperationException(node.getClass().getCanonicalName());
+ }
+
+ @Override
+ public ResolvedType visit(LambdaExpr node, Boolean aBoolean) {
+ throw new UnsupportedOperationException(node.getClass().getCanonicalName());
+ }
+
+ @Override
+ public ResolvedType visit(MethodReferenceExpr node, Boolean aBoolean) {
+ throw new UnsupportedOperationException(node.getClass().getCanonicalName());
+ }
+
+ @Override
+ public ResolvedType visit(TypeExpr node, Boolean aBoolean) {
+ throw new UnsupportedOperationException(node.getClass().getCanonicalName());
+ }
+
+ @Override
+ public ResolvedType visit(NodeList node, Boolean aBoolean) {
+ throw new UnsupportedOperationException(node.getClass().getCanonicalName());
+ }
+
+ @Override
+ public ResolvedType visit(Name node, Boolean aBoolean) {
+ throw new UnsupportedOperationException(node.getClass().getCanonicalName());
+ }
+
+ @Override
+ public ResolvedType visit(SimpleName node, Boolean aBoolean) {
+ throw new UnsupportedOperationException(node.getClass().getCanonicalName());
+ }
+
+ @Override
+ public ResolvedType visit(ImportDeclaration node, Boolean aBoolean) {
+ throw new UnsupportedOperationException(node.getClass().getCanonicalName());
+ }
+
+ @Override
+ public ResolvedType visit(ModuleDeclaration node, Boolean arg) {
+ throw new UnsupportedOperationException(node.getClass().getCanonicalName());
+ }
+
+ @Override
+ public ResolvedType visit(ModuleRequiresStmt node, Boolean arg) {
+ throw new UnsupportedOperationException(node.getClass().getCanonicalName());
+ }
+
+ @Override
+ public ResolvedType visit(ModuleExportsStmt node, Boolean arg) {
+ throw new UnsupportedOperationException(node.getClass().getCanonicalName());
+ }
+
+ @Override
+ public ResolvedType visit(ModuleProvidesStmt node, Boolean arg) {
+ throw new UnsupportedOperationException(node.getClass().getCanonicalName());
+ }
+
+ @Override
+ public ResolvedType visit(ModuleUsesStmt node, Boolean arg) {
+ throw new UnsupportedOperationException(node.getClass().getCanonicalName());
+ }
+
+ @Override
+ public ResolvedType visit(ModuleOpensStmt node, Boolean arg) {
+ throw new UnsupportedOperationException(node.getClass().getCanonicalName());
+ }
+
+ @Override
+ public ResolvedType visit(UnparsableStmt node, Boolean arg) {
+ throw new UnsupportedOperationException(node.getClass().getCanonicalName());
+ }
+
+ @Override
+ public ResolvedType visit(ReceiverParameter node, Boolean arg) {
+ throw new UnsupportedOperationException(node.getClass().getCanonicalName());
+ }
+
+ @Override
+ public ResolvedType visit(VarType node, Boolean arg) {
+ throw new UnsupportedOperationException(node.getClass().getCanonicalName());
+ }
+}
diff --git a/javaparser-symbol-solver-core/src/main/java/com/github/javaparser/symbolsolver/javaparsermodel/JavaParserFacade.java b/javaparser-symbol-solver-core/src/main/java/com/github/javaparser/symbolsolver/javaparsermodel/JavaParserFacade.java
new file mode 100644
index 000000000..f73dd986c
--- /dev/null
+++ b/javaparser-symbol-solver-core/src/main/java/com/github/javaparser/symbolsolver/javaparsermodel/JavaParserFacade.java
@@ -0,0 +1,562 @@
+/*
+ * Copyright 2016 Federico Tomassetti
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.github.javaparser.symbolsolver.javaparsermodel;
+
+import com.github.javaparser.ast.CompilationUnit;
+import com.github.javaparser.ast.Node;
+import com.github.javaparser.ast.NodeList;
+import com.github.javaparser.ast.body.*;
+import com.github.javaparser.ast.body.EnumDeclaration;
+import com.github.javaparser.ast.expr.*;
+import com.github.javaparser.ast.stmt.ExplicitConstructorInvocationStmt;
+import com.github.javaparser.ast.type.*;
+import com.github.javaparser.resolution.MethodUsage;
+import com.github.javaparser.resolution.UnsolvedSymbolException;
+import com.github.javaparser.resolution.declarations.*;
+import com.github.javaparser.resolution.types.*;
+import com.github.javaparser.symbolsolver.core.resolution.Context;
+import com.github.javaparser.symbolsolver.javaparsermodel.contexts.FieldAccessContext;
+import com.github.javaparser.symbolsolver.javaparsermodel.declarations.*;
+import com.github.javaparser.symbolsolver.model.resolution.SymbolReference;
+import com.github.javaparser.symbolsolver.model.resolution.TypeSolver;
+import com.github.javaparser.symbolsolver.model.typesystem.*;
+import com.github.javaparser.symbolsolver.reflectionmodel.ReflectionClassDeclaration;
+import com.github.javaparser.symbolsolver.resolution.ConstructorResolutionLogic;
+import com.github.javaparser.symbolsolver.resolution.SymbolSolver;
+
+import java.util.*;
+import java.util.logging.ConsoleHandler;
+import java.util.logging.Level;
+import java.util.logging.Logger;
+import java.util.stream.Collectors;
+
+import static com.github.javaparser.symbolsolver.javaparser.Navigator.requireParentNode;
+
+/**
+ * Class to be used by final users to solve symbols for JavaParser ASTs.
+ *
+ * @author Federico Tomassetti
+ */
+public class JavaParserFacade {
+
+ private static Logger logger = Logger.getLogger(JavaParserFacade.class.getCanonicalName());
+
+ static {
+ logger.setLevel(Level.INFO);
+ ConsoleHandler consoleHandler = new ConsoleHandler();
+ consoleHandler.setLevel(Level.INFO);
+ logger.addHandler(consoleHandler);
+ }
+
+ private static Map<TypeSolver, JavaParserFacade> instances = new WeakHashMap<>();
+ private TypeSolver typeSolver;
+ private SymbolSolver symbolSolver;
+ private Map<Node, ResolvedType> cacheWithLambdasSolved = new IdentityHashMap<>();
+ private Map<Node, ResolvedType> cacheWithoutLambdasSolved = new IdentityHashMap<>();
+ private TypeExtractor typeExtractor;
+
+ private JavaParserFacade(TypeSolver typeSolver) {
+ this.typeSolver = typeSolver.getRoot();
+ this.symbolSolver = new SymbolSolver(typeSolver);
+ this.typeExtractor = new TypeExtractor(typeSolver, this);
+ }
+
+ public TypeSolver getTypeSolver() {
+ return typeSolver;
+ }
+
+ public SymbolSolver getSymbolSolver() {
+ return symbolSolver;
+ }
+
+ public static JavaParserFacade get(TypeSolver typeSolver) {
+ return instances.computeIfAbsent(typeSolver, JavaParserFacade::new);
+ }
+
+ /**
+ * This method is used to clear internal caches for the sake of releasing memory.
+ */
+ public static void clearInstances() {
+ instances.clear();
+ }
+
+ protected static ResolvedType solveGenericTypes(ResolvedType type, Context context, TypeSolver typeSolver) {
+ if (type.isTypeVariable()) {
+ return context.solveGenericType(type.describe(), typeSolver).orElse(type);
+ }
+ if (type.isWildcard()) {
+ if (type.asWildcard().isExtends() || type.asWildcard().isSuper()) {
+ ResolvedWildcard wildcardUsage = type.asWildcard();
+ ResolvedType boundResolved = solveGenericTypes(wildcardUsage.getBoundedType(), context, typeSolver);
+ if (wildcardUsage.isExtends()) {
+ return ResolvedWildcard.extendsBound(boundResolved);
+ } else {
+ return ResolvedWildcard.superBound(boundResolved);
+ }
+ }
+ }
+ return type;
+ }
+
+ public SymbolReference<? extends ResolvedValueDeclaration> solve(NameExpr nameExpr) {
+ return symbolSolver.solveSymbol(nameExpr.getName().getId(), nameExpr);
+ }
+
+ public SymbolReference<? extends ResolvedValueDeclaration> solve(SimpleName nameExpr) {
+ return symbolSolver.solveSymbol(nameExpr.getId(), nameExpr);
+ }
+
+ public SymbolReference<? extends ResolvedValueDeclaration> solve(Expression expr) {
+ return expr.toNameExpr().map(this::solve).orElseThrow(() -> new IllegalArgumentException(expr.getClass().getCanonicalName()));
+ }
+
+ public SymbolReference<ResolvedMethodDeclaration> solve(MethodCallExpr methodCallExpr) {
+ return solve(methodCallExpr, true);
+ }
+
+ public SymbolReference<ResolvedConstructorDeclaration> solve(ObjectCreationExpr objectCreationExpr) {
+ return solve(objectCreationExpr, true);
+ }
+
+ public SymbolReference<ResolvedConstructorDeclaration> solve(ExplicitConstructorInvocationStmt explicitConstructorInvocationStmt) {
+ return solve(explicitConstructorInvocationStmt, true);
+ }
+
+ public SymbolReference<ResolvedConstructorDeclaration> solve(ExplicitConstructorInvocationStmt explicitConstructorInvocationStmt, boolean solveLambdas) {
+ List<ResolvedType> argumentTypes = new LinkedList<>();
+ List<LambdaArgumentTypePlaceholder> placeholders = new LinkedList<>();
+
+ solveArguments(explicitConstructorInvocationStmt, explicitConstructorInvocationStmt.getArguments(), solveLambdas, argumentTypes, placeholders);
+
+ Optional<ClassOrInterfaceDeclaration> optAncestor = explicitConstructorInvocationStmt.getAncestorOfType(ClassOrInterfaceDeclaration.class);
+ if (!optAncestor.isPresent()) {
+ return SymbolReference.unsolved(ResolvedConstructorDeclaration.class);
+ }
+ ClassOrInterfaceDeclaration classNode = optAncestor.get();
+ ResolvedTypeDeclaration typeDecl = null;
+ if (!explicitConstructorInvocationStmt.isThis()) {
+ ResolvedType classDecl = JavaParserFacade.get(typeSolver).convert(classNode.getExtendedTypes(0), classNode);
+ if (classDecl.isReferenceType()) {
+ typeDecl = classDecl.asReferenceType().getTypeDeclaration();
+ }
+ } else {
+ SymbolReference<ResolvedTypeDeclaration> sr = JavaParserFactory.getContext(classNode, typeSolver).solveType(classNode.getNameAsString(), typeSolver);
+ if (sr.isSolved()) {
+ typeDecl = sr.getCorrespondingDeclaration();
+ }
+ }
+ if (typeDecl == null) {
+ return SymbolReference.unsolved(ResolvedConstructorDeclaration.class);
+ }
+ SymbolReference<ResolvedConstructorDeclaration> res = ConstructorResolutionLogic.findMostApplicable(((ResolvedClassDeclaration) typeDecl).getConstructors(), argumentTypes, typeSolver);
+ for (LambdaArgumentTypePlaceholder placeholder : placeholders) {
+ placeholder.setMethod(res);
+ }
+ return res;
+ }
+
+ public SymbolReference<ResolvedTypeDeclaration> solve(ThisExpr node) {
+ // If 'this' is prefixed by a class eg. MyClass.this
+ if (node.getClassExpr().isPresent()) {
+ // Get the class name
+ String className = node.getClassExpr().get().toString();
+ // Attempt to resolve using a typeSolver
+ SymbolReference<ResolvedReferenceTypeDeclaration> clazz = typeSolver.tryToSolveType(className);
+ if (clazz.isSolved()) {
+ return SymbolReference.solved(clazz.getCorrespondingDeclaration());
+ }
+ // Attempt to resolve locally in Compilation unit
+ Optional<CompilationUnit> cu = node.getAncestorOfType(CompilationUnit.class);
+ if (cu.isPresent()) {
+ Optional<ClassOrInterfaceDeclaration> classByName = cu.get().getClassByName(className);
+ if (classByName.isPresent()) {
+ return SymbolReference.solved(getTypeDeclaration(classByName.get()));
+ }
+ }
+ }
+ return SymbolReference.solved(getTypeDeclaration(findContainingTypeDeclOrObjectCreationExpr(node)));
+ }
+
+ /**
+ * Given a constructor call find out to which constructor declaration it corresponds.
+ */
+ public SymbolReference<ResolvedConstructorDeclaration> solve(ObjectCreationExpr objectCreationExpr, boolean solveLambdas) {
+ List<ResolvedType> argumentTypes = new LinkedList<>();
+ List<LambdaArgumentTypePlaceholder> placeholders = new LinkedList<>();
+
+ solveArguments(objectCreationExpr, objectCreationExpr.getArguments(), solveLambdas, argumentTypes, placeholders);
+
+ ResolvedType classDecl = JavaParserFacade.get(typeSolver).convert(objectCreationExpr.getType(), objectCreationExpr);
+ if (!classDecl.isReferenceType()) {
+ return SymbolReference.unsolved(ResolvedConstructorDeclaration.class);
+ }
+ SymbolReference<ResolvedConstructorDeclaration> res = ConstructorResolutionLogic.findMostApplicable(((ResolvedClassDeclaration) classDecl.asReferenceType().getTypeDeclaration()).getConstructors(), argumentTypes, typeSolver);
+ for (LambdaArgumentTypePlaceholder placeholder : placeholders) {
+ placeholder.setMethod(res);
+ }
+ return res;
+ }
+
+ private void solveArguments(Node node, NodeList<Expression> args, boolean solveLambdas, List<ResolvedType> argumentTypes,
+ List<LambdaArgumentTypePlaceholder> placeholders) {
+ int i = 0;
+ for (Expression parameterValue : args) {
+ if (parameterValue instanceof LambdaExpr || parameterValue instanceof MethodReferenceExpr) {
+ LambdaArgumentTypePlaceholder placeholder = new LambdaArgumentTypePlaceholder(i);
+ argumentTypes.add(placeholder);
+ placeholders.add(placeholder);
+ } else {
+ try {
+ argumentTypes.add(JavaParserFacade.get(typeSolver).getType(parameterValue, solveLambdas));
+ } catch (com.github.javaparser.resolution.UnsolvedSymbolException e) {
+ throw e;
+ } catch (Exception e) {
+ throw new RuntimeException(String.format("Unable to calculate the type of a parameter of a method call. Method call: %s, Parameter: %s",
+ node, parameterValue), e);
+ }
+ }
+ i++;
+ }
+ }
+
+ /**
+ * Given a method call find out to which method declaration it corresponds.
+ */
+ public SymbolReference<ResolvedMethodDeclaration> solve(MethodCallExpr methodCallExpr, boolean solveLambdas) {
+ List<ResolvedType> argumentTypes = new LinkedList<>();
+ List<LambdaArgumentTypePlaceholder> placeholders = new LinkedList<>();
+
+ solveArguments(methodCallExpr, methodCallExpr.getArguments(), solveLambdas, argumentTypes, placeholders);
+
+ SymbolReference<ResolvedMethodDeclaration> res = JavaParserFactory.getContext(methodCallExpr, typeSolver).solveMethod(methodCallExpr.getName().getId(), argumentTypes, false, typeSolver);
+ for (LambdaArgumentTypePlaceholder placeholder : placeholders) {
+ placeholder.setMethod(res);
+ }
+ return res;
+ }
+
+ public SymbolReference<ResolvedAnnotationDeclaration> solve(AnnotationExpr annotationExpr) {
+ Context context = JavaParserFactory.getContext(annotationExpr, typeSolver);
+ SymbolReference<ResolvedTypeDeclaration> typeDeclarationSymbolReference = context.solveType(annotationExpr.getNameAsString(), typeSolver);
+ ResolvedAnnotationDeclaration annotationDeclaration = (ResolvedAnnotationDeclaration) typeDeclarationSymbolReference.getCorrespondingDeclaration();
+ if (typeDeclarationSymbolReference.isSolved()) {
+ return SymbolReference.solved(annotationDeclaration);
+ } else {
+ return SymbolReference.unsolved(ResolvedAnnotationDeclaration.class);
+ }
+ }
+
+ public SymbolReference<ResolvedFieldDeclaration> solve(FieldAccessExpr fieldAccessExpr) {
+ return ((FieldAccessContext) JavaParserFactory.getContext(fieldAccessExpr, typeSolver)).solveField(fieldAccessExpr.getName().getId(), typeSolver);
+ }
+
+ public ResolvedType getType(Node node) {
+ return getType(node, true);
+ }
+
+ public ResolvedType getType(Node node, boolean solveLambdas) {
+ if (solveLambdas) {
+ if (!cacheWithLambdasSolved.containsKey(node)) {
+ ResolvedType res = getTypeConcrete(node, solveLambdas);
+
+ cacheWithLambdasSolved.put(node, res);
+
+ boolean secondPassNecessary = false;
+ if (node instanceof MethodCallExpr) {
+ MethodCallExpr methodCallExpr = (MethodCallExpr) node;
+ for (Node arg : methodCallExpr.getArguments()) {
+ if (!cacheWithLambdasSolved.containsKey(arg)) {
+ getType(arg, true);
+ secondPassNecessary = true;
+ }
+ }
+ }
+ if (secondPassNecessary) {
+ cacheWithLambdasSolved.remove(node);
+ cacheWithLambdasSolved.put(node, getType(node, true));
+ }
+ logger.finer("getType on " + node + " -> " + res);
+ }
+ return cacheWithLambdasSolved.get(node);
+ } else {
+ Optional<ResolvedType> res = find(cacheWithLambdasSolved, node);
+ if (res.isPresent()) {
+ return res.get();
+ }
+ res = find(cacheWithoutLambdasSolved, node);
+ if (!res.isPresent()) {
+ ResolvedType resType = getTypeConcrete(node, solveLambdas);
+ cacheWithoutLambdasSolved.put(node, resType);
+ logger.finer("getType on " + node + " (no solveLambdas) -> " + res);
+ return resType;
+ }
+ return res.get();
+ }
+ }
+
+ private Optional<ResolvedType> find(Map<Node, ResolvedType> map, Node node) {
+ if (map.containsKey(node)) {
+ return Optional.of(map.get(node));
+ }
+ if (node instanceof LambdaExpr) {
+ return find(map, (LambdaExpr) node);
+ } else {
+ return Optional.empty();
+ }
+ }
+
+ /**
+ * For some reasons LambdaExprs are duplicate and the equals method is not implemented correctly.
+ */
+ private Optional<ResolvedType> find(Map<Node, ResolvedType> map, LambdaExpr lambdaExpr) {
+ for (Node key : map.keySet()) {
+ if (key instanceof LambdaExpr) {
+ LambdaExpr keyLambdaExpr = (LambdaExpr) key;
+ if (keyLambdaExpr.toString().equals(lambdaExpr.toString()) && requireParentNode(keyLambdaExpr) == requireParentNode(lambdaExpr)) {
+ return Optional.of(map.get(keyLambdaExpr));
+ }
+ }
+ }
+ return Optional.empty();
+ }
+
+ protected MethodUsage toMethodUsage(MethodReferenceExpr methodReferenceExpr) {
+ if (!(methodReferenceExpr.getScope() instanceof TypeExpr)) {
+ throw new UnsupportedOperationException();
+ }
+ TypeExpr typeExpr = (TypeExpr) methodReferenceExpr.getScope();
+ if (!(typeExpr.getType() instanceof com.github.javaparser.ast.type.ClassOrInterfaceType)) {
+ throw new UnsupportedOperationException(typeExpr.getType().getClass().getCanonicalName());
+ }
+ ClassOrInterfaceType classOrInterfaceType = (ClassOrInterfaceType) typeExpr.getType();
+ SymbolReference<ResolvedTypeDeclaration> typeDeclarationSymbolReference = JavaParserFactory.getContext(classOrInterfaceType, typeSolver).solveType(classOrInterfaceType.getName().getId(), typeSolver);
+ if (!typeDeclarationSymbolReference.isSolved()) {
+ throw new UnsupportedOperationException();
+ }
+ List<MethodUsage> methodUsages = ((ResolvedReferenceTypeDeclaration) typeDeclarationSymbolReference.getCorrespondingDeclaration()).getAllMethods().stream().filter(it -> it.getName().equals(methodReferenceExpr.getIdentifier())).collect(Collectors.toList());
+ switch (methodUsages.size()) {
+ case 0:
+ throw new UnsupportedOperationException();
+ case 1:
+ return methodUsages.get(0);
+ default:
+ throw new UnsupportedOperationException();
+ }
+ }
+
+ protected ResolvedType getBinaryTypeConcrete(Node left, Node right, boolean solveLambdas) {
+ ResolvedType leftType = getTypeConcrete(left, solveLambdas);
+ ResolvedType rightType = getTypeConcrete(right, solveLambdas);
+ if (rightType.isAssignableBy(leftType)) {
+ return rightType;
+ }
+ return leftType;
+ }
+
+
+ /**
+ * Should return more like a TypeApplication: a TypeDeclaration and possible typeParametersValues or array
+ * modifiers.
+ */
+ private ResolvedType getTypeConcrete(Node node, boolean solveLambdas) {
+ if (node == null) throw new IllegalArgumentException();
+ return node.accept(typeExtractor, solveLambdas);
+ }
+
+ protected com.github.javaparser.ast.body.TypeDeclaration<?> findContainingTypeDecl(Node node) {
+ if (node instanceof ClassOrInterfaceDeclaration) {
+ return (ClassOrInterfaceDeclaration) node;
+ }
+ if (node instanceof EnumDeclaration) {
+ return (EnumDeclaration) node;
+ }
+ return findContainingTypeDecl(requireParentNode(node));
+
+ }
+
+ protected Node findContainingTypeDeclOrObjectCreationExpr(Node node) {
+ if (node instanceof ClassOrInterfaceDeclaration) {
+ return node;
+ }
+ if (node instanceof EnumDeclaration) {
+ return node;
+ }
+ Node parent = requireParentNode(node);
+ if (parent instanceof ObjectCreationExpr && !((ObjectCreationExpr) parent).getArguments().contains(node)) {
+ return parent;
+ }
+ return findContainingTypeDeclOrObjectCreationExpr(parent);
+ }
+
+ public ResolvedType convertToUsageVariableType(VariableDeclarator var) {
+ return get(typeSolver).convertToUsage(var.getType(), var);
+ }
+
+ public ResolvedType convertToUsage(com.github.javaparser.ast.type.Type type, Node context) {
+ if (type.isUnknownType()) {
+ throw new IllegalArgumentException("Inferred lambda parameter type");
+ }
+ return convertToUsage(type, JavaParserFactory.getContext(context, typeSolver));
+ }
+
+ public ResolvedType convertToUsage(com.github.javaparser.ast.type.Type type) {
+ return convertToUsage(type, type);
+ }
+
+ // This is an hack around an issue in JavaParser
+ private String qName(ClassOrInterfaceType classOrInterfaceType) {
+ String name = classOrInterfaceType.getName().getId();
+ if (classOrInterfaceType.getScope().isPresent()) {
+ return qName(classOrInterfaceType.getScope().get()) + "." + name;
+ }
+ return name;
+ }
+
+ protected ResolvedType convertToUsage(com.github.javaparser.ast.type.Type type, Context context) {
+ if (context == null) {
+ throw new NullPointerException("Context should not be null");
+ }
+ if (type instanceof ClassOrInterfaceType) {
+ ClassOrInterfaceType classOrInterfaceType = (ClassOrInterfaceType) type;
+ String name = qName(classOrInterfaceType);
+ SymbolReference<ResolvedTypeDeclaration> ref = context.solveType(name, typeSolver);
+ if (!ref.isSolved()) {
+ throw new UnsolvedSymbolException(name);
+ }
+ ResolvedTypeDeclaration typeDeclaration = ref.getCorrespondingDeclaration();
+ List<ResolvedType> typeParameters = Collections.emptyList();
+ if (classOrInterfaceType.getTypeArguments().isPresent()) {
+ typeParameters = classOrInterfaceType.getTypeArguments().get().stream().map((pt) -> convertToUsage(pt, context)).collect(Collectors.toList());
+ }
+ if (typeDeclaration.isTypeParameter()) {
+ if (typeDeclaration instanceof ResolvedTypeParameterDeclaration) {
+ return new ResolvedTypeVariable((ResolvedTypeParameterDeclaration) typeDeclaration);
+ } else {
+ JavaParserTypeVariableDeclaration javaParserTypeVariableDeclaration = (JavaParserTypeVariableDeclaration) typeDeclaration;
+ return new ResolvedTypeVariable(javaParserTypeVariableDeclaration.asTypeParameter());
+ }
+ } else {
+ return new ReferenceTypeImpl((ResolvedReferenceTypeDeclaration) typeDeclaration, typeParameters, typeSolver);
+ }
+ } else if (type instanceof com.github.javaparser.ast.type.PrimitiveType) {
+ return ResolvedPrimitiveType.byName(((com.github.javaparser.ast.type.PrimitiveType) type).getType().name());
+ } else if (type instanceof WildcardType) {
+ WildcardType wildcardType = (WildcardType) type;
+ if (wildcardType.getExtendedType().isPresent() && !wildcardType.getSuperType().isPresent()) {
+ return ResolvedWildcard.extendsBound(convertToUsage(wildcardType.getExtendedType().get(), context)); // removed (ReferenceTypeImpl)
+ } else if (!wildcardType.getExtendedType().isPresent() && wildcardType.getSuperType().isPresent()) {
+ return ResolvedWildcard.superBound(convertToUsage(wildcardType.getSuperType().get(), context)); // removed (ReferenceTypeImpl)
+ } else if (!wildcardType.getExtendedType().isPresent() && !wildcardType.getSuperType().isPresent()) {
+ return ResolvedWildcard.UNBOUNDED;
+ } else {
+ throw new UnsupportedOperationException(wildcardType.toString());
+ }
+ } else if (type instanceof com.github.javaparser.ast.type.VoidType) {
+ return ResolvedVoidType.INSTANCE;
+ } else if (type instanceof com.github.javaparser.ast.type.ArrayType) {
+ com.github.javaparser.ast.type.ArrayType jpArrayType = (com.github.javaparser.ast.type.ArrayType) type;
+ return new ResolvedArrayType(convertToUsage(jpArrayType.getComponentType(), context));
+ } else if (type instanceof UnionType) {
+ UnionType unionType = (UnionType) type;
+ return new ResolvedUnionType(unionType.getElements().stream().map(el -> convertToUsage(el, context)).collect(Collectors.toList()));
+ } else if (type instanceof VarType) {
+ Node parent = type.getParentNode().get();
+ if (!(parent instanceof VariableDeclarator)) {
+ throw new IllegalStateException("Trying to resolve a `var` which is not in a variable declaration.");
+ }
+ final VariableDeclarator variableDeclarator = (VariableDeclarator) parent;
+ return variableDeclarator.getInitializer()
+ .map(Expression::calculateResolvedType)
+ .orElseThrow(() -> new IllegalStateException("Cannot resolve `var` which has no initializer."));
+ } else {
+ throw new UnsupportedOperationException(type.getClass().getCanonicalName());
+ }
+ }
+
+
+ public ResolvedType convert(Type type, Node node) {
+ return convert(type, JavaParserFactory.getContext(node, typeSolver));
+ }
+
+ public ResolvedType convert(com.github.javaparser.ast.type.Type type, Context context) {
+ return convertToUsage(type, context);
+ }
+
+ public MethodUsage solveMethodAsUsage(MethodCallExpr call) {
+ List<ResolvedType> params = new ArrayList<>();
+ if (call.getArguments() != null) {
+ for (Expression param : call.getArguments()) {
+ //getTypeConcrete(Node node, boolean solveLambdas)
+ try {
+ params.add(getType(param, false));
+ } catch (Exception e) {
+ throw new RuntimeException(String.format("Error calculating the type of parameter %s of method call %s", param, call), e);
+ }
+ //params.add(getTypeConcrete(param, false));
+ }
+ }
+ Context context = JavaParserFactory.getContext(call, typeSolver);
+ Optional<MethodUsage> methodUsage = context.solveMethodAsUsage(call.getName().getId(), params, typeSolver);
+ if (!methodUsage.isPresent()) {
+ throw new RuntimeException("Method '" + call.getName() + "' cannot be resolved in context "
+ + call + " (line: " + call.getRange().map(r -> "" + r.begin.line).orElse("??") + ") " + context + ". Parameter types: " + params);
+ }
+ return methodUsage.get();
+ }
+
+ public ResolvedReferenceTypeDeclaration getTypeDeclaration(Node node) {
+ if (node instanceof TypeDeclaration) {
+ return getTypeDeclaration((TypeDeclaration) node);
+ } else if (node instanceof ObjectCreationExpr) {
+ return new JavaParserAnonymousClassDeclaration((ObjectCreationExpr) node, typeSolver);
+ } else {
+ throw new IllegalArgumentException();
+ }
+ }
+
+ public ResolvedReferenceTypeDeclaration getTypeDeclaration(ClassOrInterfaceDeclaration classOrInterfaceDeclaration) {
+ return JavaParserFactory.toTypeDeclaration(classOrInterfaceDeclaration, typeSolver);
+ }
+
+ /**
+ * "this" inserted in the given point, which type would have?
+ */
+ public ResolvedType getTypeOfThisIn(Node node) {
+ // TODO consider static methods
+ if (node instanceof ClassOrInterfaceDeclaration) {
+ return new ReferenceTypeImpl(getTypeDeclaration((ClassOrInterfaceDeclaration) node), typeSolver);
+ } else if (node instanceof EnumDeclaration) {
+ JavaParserEnumDeclaration enumDeclaration = new JavaParserEnumDeclaration((EnumDeclaration) node, typeSolver);
+ return new ReferenceTypeImpl(enumDeclaration, typeSolver);
+ } else if (node instanceof ObjectCreationExpr && ((ObjectCreationExpr) node).getAnonymousClassBody().isPresent()) {
+ JavaParserAnonymousClassDeclaration anonymousDeclaration = new JavaParserAnonymousClassDeclaration((ObjectCreationExpr) node, typeSolver);
+ return new ReferenceTypeImpl(anonymousDeclaration, typeSolver);
+ }
+ return getTypeOfThisIn(requireParentNode(node));
+ }
+
+ public ResolvedReferenceTypeDeclaration getTypeDeclaration(com.github.javaparser.ast.body.TypeDeclaration<?> typeDeclaration) {
+ return JavaParserFactory.toTypeDeclaration(typeDeclaration, typeSolver);
+ }
+
+ public ResolvedType classToResolvedType(Class<?> clazz) {
+ if (clazz.isPrimitive()) {
+ return ResolvedPrimitiveType.byName(clazz.getName());
+ }
+ return new ReferenceTypeImpl(new ReflectionClassDeclaration(String.class, typeSolver), typeSolver);
+ }
+}
diff --git a/javaparser-symbol-solver-core/src/main/java/com/github/javaparser/symbolsolver/javaparsermodel/JavaParserFactory.java b/javaparser-symbol-solver-core/src/main/java/com/github/javaparser/symbolsolver/javaparsermodel/JavaParserFactory.java
new file mode 100644
index 000000000..8bd3496fd
--- /dev/null
+++ b/javaparser-symbol-solver-core/src/main/java/com/github/javaparser/symbolsolver/javaparsermodel/JavaParserFactory.java
@@ -0,0 +1,139 @@
+/*
+ * Copyright 2016 Federico Tomassetti
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.github.javaparser.symbolsolver.javaparsermodel;
+
+import com.github.javaparser.ast.CompilationUnit;
+import com.github.javaparser.ast.Node;
+import com.github.javaparser.ast.body.*;
+import com.github.javaparser.ast.expr.*;
+import com.github.javaparser.ast.stmt.*;
+import com.github.javaparser.ast.type.TypeParameter;
+import com.github.javaparser.resolution.declarations.ResolvedReferenceTypeDeclaration;
+import com.github.javaparser.symbolsolver.core.resolution.Context;
+import com.github.javaparser.symbolsolver.javaparsermodel.contexts.*;
+import com.github.javaparser.symbolsolver.javaparsermodel.declarations.JavaParserAnnotationDeclaration;
+import com.github.javaparser.symbolsolver.javaparsermodel.declarations.JavaParserClassDeclaration;
+import com.github.javaparser.symbolsolver.javaparsermodel.declarations.JavaParserEnumDeclaration;
+import com.github.javaparser.symbolsolver.javaparsermodel.declarations.JavaParserInterfaceDeclaration;
+import com.github.javaparser.symbolsolver.javaparsermodel.declarations.JavaParserTypeParameter;
+import com.github.javaparser.symbolsolver.javaparsermodel.declarators.FieldSymbolDeclarator;
+import com.github.javaparser.symbolsolver.javaparsermodel.declarators.NoSymbolDeclarator;
+import com.github.javaparser.symbolsolver.javaparsermodel.declarators.ParameterSymbolDeclarator;
+import com.github.javaparser.symbolsolver.javaparsermodel.declarators.VariableSymbolDeclarator;
+import com.github.javaparser.symbolsolver.model.resolution.TypeSolver;
+import com.github.javaparser.symbolsolver.resolution.SymbolDeclarator;
+
+import static com.github.javaparser.symbolsolver.javaparser.Navigator.getParentNode;
+import static com.github.javaparser.symbolsolver.javaparser.Navigator.requireParentNode;
+
+/**
+ * @author Federico Tomassetti
+ */
+public class JavaParserFactory {
+
+ public static Context getContext(Node node, TypeSolver typeSolver) {
+ if (node == null) {
+ throw new NullPointerException("Node should not be null");
+ } else if (node instanceof CompilationUnit) {
+ return new CompilationUnitContext((CompilationUnit) node, typeSolver);
+ } else if (node instanceof ForeachStmt) {
+ return new ForechStatementContext((ForeachStmt) node, typeSolver);
+ } else if (node instanceof ForStmt) {
+ return new ForStatementContext((ForStmt) node, typeSolver);
+ } else if (node instanceof LambdaExpr) {
+ return new LambdaExprContext((LambdaExpr) node, typeSolver);
+ } else if (node instanceof MethodDeclaration) {
+ return new MethodContext((MethodDeclaration) node, typeSolver);
+ } else if (node instanceof ConstructorDeclaration) {
+ return new ConstructorContext((ConstructorDeclaration) node, typeSolver);
+ } else if (node instanceof ClassOrInterfaceDeclaration) {
+ return new ClassOrInterfaceDeclarationContext((ClassOrInterfaceDeclaration) node, typeSolver);
+ } else if (node instanceof MethodCallExpr) {
+ return new MethodCallExprContext((MethodCallExpr) node, typeSolver);
+ } else if (node instanceof EnumDeclaration) {
+ return new EnumDeclarationContext((EnumDeclaration) node, typeSolver);
+ } else if (node instanceof FieldAccessExpr) {
+ return new FieldAccessContext((FieldAccessExpr) node, typeSolver);
+ } else if (node instanceof SwitchEntryStmt) {
+ return new SwitchEntryContext((SwitchEntryStmt) node, typeSolver);
+ } else if (node instanceof TryStmt) {
+ return new TryWithResourceContext((TryStmt) node, typeSolver);
+ } else if (node instanceof Statement) {
+ return new StatementContext<>((Statement) node, typeSolver);
+ } else if (node instanceof CatchClause) {
+ return new CatchClauseContext((CatchClause) node, typeSolver);
+ } else if (node instanceof ObjectCreationExpr &&
+ ((ObjectCreationExpr) node).getAnonymousClassBody().isPresent()) {
+ return new AnonymousClassDeclarationContext((ObjectCreationExpr) node, typeSolver);
+ } else {
+ if (node instanceof NameExpr) {
+ // to resolve a name when in a fieldAccess context, we can get to the grand parent to prevent a infinite loop if the name is the same as the field (ie x.x)
+ if (node.getParentNode().isPresent() && node.getParentNode().get() instanceof FieldAccessExpr && node.getParentNode().get().getParentNode().isPresent()) {
+ return getContext(node.getParentNode().get().getParentNode().get(), typeSolver);
+ }
+ }
+ final Node parentNode = requireParentNode(node);
+ if (parentNode instanceof ObjectCreationExpr && node == ((ObjectCreationExpr) parentNode).getType()) {
+ return getContext(requireParentNode(parentNode), typeSolver);
+ }
+ if (parentNode == null) {
+ throw new IllegalStateException("The AST node does not appear to be inserted in a propert AST, therefore we cannot resolve symbols correctly");
+ }
+ return getContext(parentNode, typeSolver);
+ }
+ }
+
+ public static SymbolDeclarator getSymbolDeclarator(Node node, TypeSolver typeSolver) {
+ if (node instanceof FieldDeclaration) {
+ return new FieldSymbolDeclarator((FieldDeclaration) node, typeSolver);
+ } else if (node instanceof Parameter) {
+ return new ParameterSymbolDeclarator((Parameter) node, typeSolver);
+ } else if (node instanceof ExpressionStmt) {
+ ExpressionStmt expressionStmt = (ExpressionStmt) node;
+ if (expressionStmt.getExpression() instanceof VariableDeclarationExpr) {
+ return new VariableSymbolDeclarator((VariableDeclarationExpr) (expressionStmt.getExpression()), typeSolver);
+ } else {
+ return new NoSymbolDeclarator<>(expressionStmt, typeSolver);
+ }
+ } else if (node instanceof IfStmt) {
+ return new NoSymbolDeclarator<>((IfStmt) node, typeSolver);
+ } else if (node instanceof ForeachStmt) {
+ ForeachStmt foreachStmt = (ForeachStmt) node;
+ return new VariableSymbolDeclarator(foreachStmt.getVariable(), typeSolver);
+ } else {
+ return new NoSymbolDeclarator<>(node, typeSolver);
+ }
+ }
+
+ public static ResolvedReferenceTypeDeclaration toTypeDeclaration(Node node, TypeSolver typeSolver) {
+ if (node instanceof ClassOrInterfaceDeclaration) {
+ if (((ClassOrInterfaceDeclaration) node).isInterface()) {
+ return new JavaParserInterfaceDeclaration((ClassOrInterfaceDeclaration) node, typeSolver);
+ } else {
+ return new JavaParserClassDeclaration((ClassOrInterfaceDeclaration) node, typeSolver);
+ }
+ } else if (node instanceof TypeParameter) {
+ return new JavaParserTypeParameter((TypeParameter) node, typeSolver);
+ } else if (node instanceof EnumDeclaration) {
+ return new JavaParserEnumDeclaration((EnumDeclaration) node, typeSolver);
+ } else if (node instanceof AnnotationDeclaration) {
+ return new JavaParserAnnotationDeclaration((AnnotationDeclaration) node, typeSolver);
+ } else {
+ throw new IllegalArgumentException(node.getClass().getCanonicalName());
+ }
+ }
+}
diff --git a/javaparser-symbol-solver-core/src/main/java/com/github/javaparser/symbolsolver/javaparsermodel/LambdaArgumentTypePlaceholder.java b/javaparser-symbol-solver-core/src/main/java/com/github/javaparser/symbolsolver/javaparsermodel/LambdaArgumentTypePlaceholder.java
new file mode 100644
index 000000000..c0e35bf43
--- /dev/null
+++ b/javaparser-symbol-solver-core/src/main/java/com/github/javaparser/symbolsolver/javaparsermodel/LambdaArgumentTypePlaceholder.java
@@ -0,0 +1,72 @@
+/*
+ * Copyright 2016 Federico Tomassetti
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.github.javaparser.symbolsolver.javaparsermodel;
+
+import com.github.javaparser.resolution.declarations.ResolvedMethodLikeDeclaration;
+import com.github.javaparser.resolution.types.ResolvedType;
+import com.github.javaparser.symbolsolver.model.resolution.SymbolReference;
+
+/**
+ * Placeholder used to represent a lambda argument type while it is being
+ * calculated.
+ *
+ * @author Federico Tomassetti
+ */
+public class LambdaArgumentTypePlaceholder implements ResolvedType {
+
+ private int pos;
+ private SymbolReference<? extends ResolvedMethodLikeDeclaration> method;
+
+ public LambdaArgumentTypePlaceholder(int pos) {
+ this.pos = pos;
+ }
+
+ @Override
+ public boolean isArray() {
+ return false;
+ }
+
+ @Override
+ public boolean isPrimitive() {
+ return false;
+ }
+
+ @Override
+ public boolean isReferenceType() {
+ return false;
+ }
+
+ @Override
+ public String describe() {
+ throw new UnsupportedOperationException();
+ }
+
+ @Override
+ public boolean isTypeVariable() {
+ return false;
+ }
+
+ public void setMethod(SymbolReference<? extends ResolvedMethodLikeDeclaration> method) {
+ this.method = method;
+ }
+
+ @Override
+ public boolean isAssignableBy(ResolvedType other) {
+ throw new UnsupportedOperationException();
+ }
+
+}
diff --git a/javaparser-symbol-solver-core/src/main/java/com/github/javaparser/symbolsolver/javaparsermodel/TypeExtractor.java b/javaparser-symbol-solver-core/src/main/java/com/github/javaparser/symbolsolver/javaparsermodel/TypeExtractor.java
new file mode 100644
index 000000000..44c8d2715
--- /dev/null
+++ b/javaparser-symbol-solver-core/src/main/java/com/github/javaparser/symbolsolver/javaparsermodel/TypeExtractor.java
@@ -0,0 +1,517 @@
+package com.github.javaparser.symbolsolver.javaparsermodel;
+
+import com.github.javaparser.ast.CompilationUnit;
+import com.github.javaparser.ast.body.ClassOrInterfaceDeclaration;
+import com.github.javaparser.ast.body.FieldDeclaration;
+import com.github.javaparser.ast.body.Parameter;
+import com.github.javaparser.ast.body.VariableDeclarator;
+import com.github.javaparser.ast.expr.*;
+import com.github.javaparser.ast.stmt.BlockStmt;
+import com.github.javaparser.ast.stmt.ExpressionStmt;
+import com.github.javaparser.ast.stmt.ReturnStmt;
+import com.github.javaparser.ast.type.UnknownType;
+import com.github.javaparser.resolution.MethodUsage;
+import com.github.javaparser.resolution.UnsolvedSymbolException;
+import com.github.javaparser.resolution.declarations.ResolvedClassDeclaration;
+import com.github.javaparser.resolution.declarations.ResolvedMethodDeclaration;
+import com.github.javaparser.resolution.declarations.ResolvedReferenceTypeDeclaration;
+import com.github.javaparser.resolution.declarations.ResolvedTypeDeclaration;
+import com.github.javaparser.resolution.types.ResolvedArrayType;
+import com.github.javaparser.resolution.types.ResolvedPrimitiveType;
+import com.github.javaparser.resolution.types.ResolvedType;
+import com.github.javaparser.resolution.types.ResolvedVoidType;
+import com.github.javaparser.symbolsolver.core.resolution.Context;
+import com.github.javaparser.symbolsolver.javaparsermodel.declarations.JavaParserSymbolDeclaration;
+import com.github.javaparser.symbolsolver.logic.FunctionalInterfaceLogic;
+import com.github.javaparser.symbolsolver.logic.InferenceContext;
+import com.github.javaparser.symbolsolver.model.resolution.SymbolReference;
+import com.github.javaparser.symbolsolver.model.resolution.TypeSolver;
+import com.github.javaparser.symbolsolver.model.resolution.Value;
+import com.github.javaparser.symbolsolver.model.typesystem.*;
+import com.github.javaparser.symbolsolver.reflectionmodel.MyObjectProvider;
+import com.github.javaparser.symbolsolver.reflectionmodel.ReflectionClassDeclaration;
+import com.github.javaparser.symbolsolver.resolution.SymbolSolver;
+import com.github.javaparser.symbolsolver.resolution.typesolvers.ReflectionTypeSolver;
+import com.google.common.collect.ImmutableList;
+
+import java.util.List;
+import java.util.Optional;
+import java.util.logging.ConsoleHandler;
+import java.util.logging.Level;
+import java.util.logging.Logger;
+
+import static com.github.javaparser.symbolsolver.javaparser.Navigator.requireParentNode;
+import static com.github.javaparser.symbolsolver.javaparsermodel.JavaParserFacade.solveGenericTypes;
+
+public class TypeExtractor extends DefaultVisitorAdapter {
+
+ private static Logger logger = Logger.getLogger(TypeExtractor.class.getCanonicalName());
+
+ static {
+ logger.setLevel(Level.INFO);
+ ConsoleHandler consoleHandler = new ConsoleHandler();
+ consoleHandler.setLevel(Level.INFO);
+ logger.addHandler(consoleHandler);
+ }
+
+ private TypeSolver typeSolver;
+ private JavaParserFacade facade;
+
+ public TypeExtractor(TypeSolver typeSolver, JavaParserFacade facade) {
+ this.typeSolver = typeSolver;
+ this.facade = facade;
+ }
+
+ @Override
+ public ResolvedType visit(VariableDeclarator node, Boolean solveLambdas) {
+ if (requireParentNode(node) instanceof FieldDeclaration) {
+ return facade.convertToUsageVariableType(node);
+ } else if (requireParentNode(node) instanceof VariableDeclarationExpr) {
+ return facade.convertToUsageVariableType(node);
+ }
+ throw new UnsupportedOperationException(requireParentNode(node).getClass().getCanonicalName());
+ }
+
+ @Override
+ public ResolvedType visit(Parameter node, Boolean solveLambdas) {
+ if (node.getType() instanceof UnknownType) {
+ throw new IllegalStateException("Parameter has unknown type: " + node);
+ }
+ return facade.convertToUsage(node.getType(), node);
+ }
+
+
+ @Override
+ public ResolvedType visit(ArrayAccessExpr node, Boolean solveLambdas) {
+ ResolvedType arrayUsageType = node.getName().accept(this, solveLambdas);
+ if (arrayUsageType.isArray()) {
+ return ((ResolvedArrayType) arrayUsageType).getComponentType();
+ }
+ return arrayUsageType;
+ }
+
+ @Override
+ public ResolvedType visit(ArrayCreationExpr node, Boolean solveLambdas) {
+ ResolvedType res = facade.convertToUsage(node.getElementType(), JavaParserFactory.getContext(node, typeSolver));
+ for (int i = 0; i < node.getLevels().size(); i++) {
+ res = new ResolvedArrayType(res);
+ }
+ return res;
+ }
+
+ @Override
+ public ResolvedType visit(ArrayInitializerExpr node, Boolean solveLambdas) {
+ throw new UnsupportedOperationException(node.getClass().getCanonicalName());
+ }
+
+ @Override
+ public ResolvedType visit(AssignExpr node, Boolean solveLambdas) {
+ return node.getTarget().accept(this, solveLambdas);
+ }
+
+ @Override
+ public ResolvedType visit(BinaryExpr node, Boolean solveLambdas) {
+ switch (node.getOperator()) {
+ case PLUS:
+ case MINUS:
+ case DIVIDE:
+ case MULTIPLY:
+ return facade.getBinaryTypeConcrete(node.getLeft(), node.getRight(), solveLambdas);
+ case LESS_EQUALS:
+ case LESS:
+ case GREATER:
+ case GREATER_EQUALS:
+ case EQUALS:
+ case NOT_EQUALS:
+ case OR:
+ case AND:
+ return ResolvedPrimitiveType.BOOLEAN;
+ case BINARY_AND:
+ case BINARY_OR:
+ case SIGNED_RIGHT_SHIFT:
+ case UNSIGNED_RIGHT_SHIFT:
+ case LEFT_SHIFT:
+ case REMAINDER:
+ case XOR:
+ return node.getLeft().accept(this, solveLambdas);
+ default:
+ throw new UnsupportedOperationException("Operator " + node.getOperator().name());
+ }
+ }
+
+ @Override
+ public ResolvedType visit(CastExpr node, Boolean solveLambdas) {
+ return facade.convertToUsage(node.getType(), JavaParserFactory.getContext(node, typeSolver));
+ }
+
+ @Override
+ public ResolvedType visit(ClassExpr node, Boolean solveLambdas) {
+ // This implementation does not regard the actual type argument of the ClassExpr.
+ com.github.javaparser.ast.type.Type astType = node.getType();
+ ResolvedType jssType = facade.convertToUsage(astType, node.getType());
+ return new ReferenceTypeImpl(new ReflectionClassDeclaration(Class.class, typeSolver), ImmutableList.of(jssType), typeSolver);
+ }
+
+ @Override
+ public ResolvedType visit(ConditionalExpr node, Boolean solveLambdas) {
+ return node.getThenExpr().accept(this, solveLambdas);
+ }
+
+ @Override
+ public ResolvedType visit(EnclosedExpr node, Boolean solveLambdas) {
+ return node.getInner().accept(this, solveLambdas);
+ }
+
+ /**
+ * Java Parser can't differentiate between packages, internal types, and fields.
+ * All three are lumped together into FieldAccessExpr. We need to differentiate them.
+ */
+ private ResolvedType solveDotExpressionType(ResolvedReferenceTypeDeclaration parentType, FieldAccessExpr node) {
+ // Fields and internal type declarations cannot have the same name.
+ // Thus, these checks will always be mutually exclusive.
+ if (parentType.hasField(node.getName().getId())) {
+ return parentType.getField(node.getName().getId()).getType();
+ } else if (parentType.hasInternalType(node.getName().getId())) {
+ return new ReferenceTypeImpl(parentType.getInternalType(node.getName().getId()), typeSolver);
+ } else {
+ throw new UnsolvedSymbolException(node.getName().getId());
+ }
+ }
+
+ @Override
+ public ResolvedType visit(FieldAccessExpr node, Boolean solveLambdas) {
+ // We should understand if this is a static access
+ if (node.getScope() instanceof NameExpr ||
+ node.getScope() instanceof FieldAccessExpr) {
+ Expression staticValue = node.getScope();
+ SymbolReference<ResolvedTypeDeclaration> typeAccessedStatically = JavaParserFactory.getContext(node, typeSolver).solveType(staticValue.toString(), typeSolver);
+ if (typeAccessedStatically.isSolved()) {
+ // TODO here maybe we have to substitute type typeParametersValues
+ return solveDotExpressionType(
+ typeAccessedStatically.getCorrespondingDeclaration().asReferenceType(), node);
+ }
+ } else if (node.getScope() instanceof ThisExpr) {
+ // If we are accessing through a 'this' expression, first resolve the type
+ // corresponding to 'this'
+ SymbolReference<ResolvedTypeDeclaration> solve = facade.solve((ThisExpr) node.getScope());
+ // If found get it's declaration and get the field in there
+ if (solve.isSolved()) {
+ ResolvedTypeDeclaration correspondingDeclaration = solve.getCorrespondingDeclaration();
+ if (correspondingDeclaration instanceof ResolvedReferenceTypeDeclaration) {
+ return solveDotExpressionType(correspondingDeclaration.asReferenceType(), node);
+ }
+ }
+
+ } else if (node.getScope().toString().indexOf('.') > 0) {
+ // try to find fully qualified name
+ SymbolReference<ResolvedReferenceTypeDeclaration> sr = typeSolver.tryToSolveType(node.getScope().toString());
+ if (sr.isSolved()) {
+ return solveDotExpressionType(sr.getCorrespondingDeclaration(), node);
+ }
+ }
+ Optional<Value> value = Optional.empty();
+ try {
+ value = new SymbolSolver(typeSolver).solveSymbolAsValue(node.getName().getId(), node);
+ } catch (com.github.javaparser.resolution.UnsolvedSymbolException use) {
+ // This node may have a package name as part of its fully qualified name.
+ // We should solve for the type declaration inside this package.
+ SymbolReference<ResolvedReferenceTypeDeclaration> sref = typeSolver.tryToSolveType(node.toString());
+ if (sref.isSolved()) {
+ return new ReferenceTypeImpl(sref.getCorrespondingDeclaration(), typeSolver);
+ }
+ }
+ if (value.isPresent()) {
+ return value.get().getType();
+ }
+ throw new com.github.javaparser.resolution.UnsolvedSymbolException(node.getName().getId());
+ }
+
+ @Override
+ public ResolvedType visit(InstanceOfExpr node, Boolean solveLambdas) {
+ return ResolvedPrimitiveType.BOOLEAN;
+ }
+
+ @Override
+ public ResolvedType visit(StringLiteralExpr node, Boolean solveLambdas) {
+ return new ReferenceTypeImpl(new ReflectionTypeSolver().solveType(String.class.getCanonicalName()), typeSolver);
+ }
+
+ @Override
+ public ResolvedType visit(IntegerLiteralExpr node, Boolean solveLambdas) {
+ return ResolvedPrimitiveType.INT;
+ }
+
+ @Override
+ public ResolvedType visit(LongLiteralExpr node, Boolean solveLambdas) {
+ return ResolvedPrimitiveType.LONG;
+ }
+
+ @Override
+ public ResolvedType visit(CharLiteralExpr node, Boolean solveLambdas) {
+ return ResolvedPrimitiveType.CHAR;
+ }
+
+ @Override
+ public ResolvedType visit(DoubleLiteralExpr node, Boolean solveLambdas) {
+ if (node.getValue().toLowerCase().endsWith("f")) {
+ return ResolvedPrimitiveType.FLOAT;
+ }
+ return ResolvedPrimitiveType.DOUBLE;
+ }
+
+ @Override
+ public ResolvedType visit(BooleanLiteralExpr node, Boolean solveLambdas) {
+ return ResolvedPrimitiveType.BOOLEAN;
+ }
+
+ @Override
+ public ResolvedType visit(NullLiteralExpr node, Boolean solveLambdas) {
+ return NullType.INSTANCE;
+ }
+
+ @Override
+ public ResolvedType visit(MethodCallExpr node, Boolean solveLambdas) {
+ logger.finest("getType on method call " + node);
+ // first solve the method
+ MethodUsage ref = facade.solveMethodAsUsage(node);
+ logger.finest("getType on method call " + node + " resolved to " + ref);
+ logger.finest("getType on method call " + node + " return type is " + ref.returnType());
+ return ref.returnType();
+ // the type is the return type of the method
+ }
+
+ @Override
+ public ResolvedType visit(NameExpr node, Boolean solveLambdas) {
+ logger.finest("getType on name expr " + node);
+ Optional<Value> value = new SymbolSolver(typeSolver).solveSymbolAsValue(node.getName().getId(), node);
+ if (!value.isPresent()) {
+ throw new com.github.javaparser.resolution.UnsolvedSymbolException("Solving " + node, node.getName().getId());
+ } else {
+ return value.get().getType();
+ }
+ }
+
+ @Override
+ public ResolvedType visit(ObjectCreationExpr node, Boolean solveLambdas) {
+ return facade.convertToUsage(node.getType(), node);
+ }
+
+ @Override
+ public ResolvedType visit(ThisExpr node, Boolean solveLambdas) {
+ // If 'this' is prefixed by a class eg. MyClass.this
+ if (node.getClassExpr().isPresent()) {
+ // Get the class name
+ String className = node.getClassExpr().get().toString();
+ // Attempt to resolve using a typeSolver
+ SymbolReference<ResolvedReferenceTypeDeclaration> clazz = typeSolver.tryToSolveType(className);
+ if (clazz.isSolved()) {
+ return new ReferenceTypeImpl(clazz.getCorrespondingDeclaration(), typeSolver);
+ }
+ // Attempt to resolve locally in Compilation unit
+ Optional<CompilationUnit> cu = node.getAncestorOfType(CompilationUnit.class);
+ if (cu.isPresent()) {
+ Optional<ClassOrInterfaceDeclaration> classByName = cu.get().getClassByName(className);
+ if (classByName.isPresent()) {
+ return new ReferenceTypeImpl(facade.getTypeDeclaration(classByName.get()), typeSolver);
+ }
+ }
+
+ }
+ return new ReferenceTypeImpl(facade.getTypeDeclaration(facade.findContainingTypeDeclOrObjectCreationExpr(node)), typeSolver);
+ }
+
+ @Override
+ public ResolvedType visit(SuperExpr node, Boolean solveLambdas) {
+ ResolvedTypeDeclaration typeOfNode = facade.getTypeDeclaration(facade.findContainingTypeDecl(node));
+ if (typeOfNode instanceof ResolvedClassDeclaration) {
+ return ((ResolvedClassDeclaration) typeOfNode).getSuperClass();
+ } else {
+ throw new UnsupportedOperationException(node.getClass().getCanonicalName());
+ }
+ }
+
+ @Override
+ public ResolvedType visit(UnaryExpr node, Boolean solveLambdas) {
+ switch (node.getOperator()) {
+ case MINUS:
+ case PLUS:
+ return node.getExpression().accept(this, solveLambdas);
+ case LOGICAL_COMPLEMENT:
+ return ResolvedPrimitiveType.BOOLEAN;
+ case POSTFIX_DECREMENT:
+ case PREFIX_DECREMENT:
+ case POSTFIX_INCREMENT:
+ case PREFIX_INCREMENT:
+ return node.getExpression().accept(this, solveLambdas);
+ default:
+ throw new UnsupportedOperationException(node.getOperator().name());
+ }
+ }
+
+ @Override
+ public ResolvedType visit(VariableDeclarationExpr node, Boolean solveLambdas) {
+ if (node.getVariables().size() != 1) {
+ throw new UnsupportedOperationException();
+ }
+ return facade.convertToUsageVariableType(node.getVariables().get(0));
+ }
+
+
+ @Override
+ public ResolvedType visit(LambdaExpr node, Boolean solveLambdas) {
+ if (requireParentNode(node) instanceof MethodCallExpr) {
+ MethodCallExpr callExpr = (MethodCallExpr) requireParentNode(node);
+ int pos = JavaParserSymbolDeclaration.getParamPos(node);
+ SymbolReference<ResolvedMethodDeclaration> refMethod = facade.solve(callExpr);
+ if (!refMethod.isSolved()) {
+ throw new com.github.javaparser.resolution.UnsolvedSymbolException(requireParentNode(node).toString(), callExpr.getName().getId());
+ }
+ logger.finest("getType on lambda expr " + refMethod.getCorrespondingDeclaration().getName());
+ if (solveLambdas) {
+
+ // The type parameter referred here should be the java.util.stream.Stream.T
+ ResolvedType result = refMethod.getCorrespondingDeclaration().getParam(pos).getType();
+
+ if (callExpr.getScope().isPresent()) {
+ Expression scope = callExpr.getScope().get();
+
+ // If it is a static call we should not try to get the type of the scope
+ boolean staticCall = false;
+ if (scope instanceof NameExpr) {
+ NameExpr nameExpr = (NameExpr) scope;
+ try {
+ SymbolReference<ResolvedTypeDeclaration> type = JavaParserFactory.getContext(nameExpr, typeSolver).solveType(nameExpr.getName().getId(), typeSolver);
+ if (type.isSolved()) {
+ staticCall = true;
+ }
+ } catch (Exception e) {
+
+ }
+ }
+
+ if (!staticCall) {
+ ResolvedType scopeType = facade.getType(scope);
+ if (scopeType.isReferenceType()) {
+ result = scopeType.asReferenceType().useThisTypeParametersOnTheGivenType(result);
+ }
+ }
+ }
+
+ // We need to replace the type variables
+ Context ctx = JavaParserFactory.getContext(node, typeSolver);
+ result = solveGenericTypes(result, ctx, typeSolver);
+
+ //We should find out which is the functional method (e.g., apply) and replace the params of the
+ //solveLambdas with it, to derive so the values. We should also consider the value returned by the
+ //lambdas
+ Optional<MethodUsage> functionalMethod = FunctionalInterfaceLogic.getFunctionalMethod(result);
+ if (functionalMethod.isPresent()) {
+ LambdaExpr lambdaExpr = node;
+
+ InferenceContext lambdaCtx = new InferenceContext(MyObjectProvider.INSTANCE);
+ InferenceContext funcInterfaceCtx = new InferenceContext(MyObjectProvider.INSTANCE);
+
+ // At this point parameterType
+ // if Function<T=? super Stream.T, ? extends map.R>
+ // we should replace Stream.T
+ ResolvedType functionalInterfaceType = ReferenceTypeImpl.undeterminedParameters(functionalMethod.get().getDeclaration().declaringType(), typeSolver);
+
+ lambdaCtx.addPair(result, functionalInterfaceType);
+
+ ResolvedType actualType;
+
+ if (lambdaExpr.getBody() instanceof ExpressionStmt) {
+ actualType = facade.getType(((ExpressionStmt) lambdaExpr.getBody()).getExpression());
+ } else if (lambdaExpr.getBody() instanceof BlockStmt) {
+ BlockStmt blockStmt = (BlockStmt) lambdaExpr.getBody();
+
+ // Get all the return statements in the lambda block
+ List<ReturnStmt> returnStmts = blockStmt.findAll(ReturnStmt.class);
+
+ if (returnStmts.size() > 0) {
+ actualType = returnStmts.stream()
+ .map(returnStmt -> returnStmt.getExpression().map(e -> facade.getType(e)).orElse(ResolvedVoidType.INSTANCE))
+ .filter(x -> x != null && !x.isVoid() && !x.isNull())
+ .findFirst()
+ .orElse(ResolvedVoidType.INSTANCE);
+
+ } else {
+ return ResolvedVoidType.INSTANCE;
+ }
+
+
+ } else {
+ throw new UnsupportedOperationException();
+ }
+
+ ResolvedType formalType = functionalMethod.get().returnType();
+
+ // Infer the functional interfaces' return vs actual type
+ funcInterfaceCtx.addPair(formalType, actualType);
+ // Substitute to obtain a new type
+ ResolvedType functionalTypeWithReturn = funcInterfaceCtx.resolve(funcInterfaceCtx.addSingle(functionalInterfaceType));
+
+ // if the functional method returns void anyway
+ // we don't need to bother inferring types
+ if (!(formalType instanceof ResolvedVoidType)) {
+ lambdaCtx.addPair(result, functionalTypeWithReturn);
+ result = lambdaCtx.resolve(lambdaCtx.addSingle(result));
+ }
+ }
+
+ return result;
+ } else {
+ return refMethod.getCorrespondingDeclaration().getParam(pos).getType();
+ }
+ } else {
+ throw new UnsupportedOperationException("The type of a lambda expr depends on the position and its return value");
+ }
+ }
+
+ @Override
+ public ResolvedType visit(MethodReferenceExpr node, Boolean solveLambdas) {
+ if (requireParentNode(node) instanceof MethodCallExpr) {
+ MethodCallExpr callExpr = (MethodCallExpr) requireParentNode(node);
+ int pos = JavaParserSymbolDeclaration.getParamPos(node);
+ SymbolReference<ResolvedMethodDeclaration> refMethod = facade.solve(callExpr, false);
+ if (!refMethod.isSolved()) {
+ throw new com.github.javaparser.resolution.UnsolvedSymbolException(requireParentNode(node).toString(), callExpr.getName().getId());
+ }
+ logger.finest("getType on method reference expr " + refMethod.getCorrespondingDeclaration().getName());
+ //logger.finest("Method param " + refMethod.getCorrespondingDeclaration().getParam(pos));
+ if (solveLambdas) {
+ MethodUsage usage = facade.solveMethodAsUsage(callExpr);
+ ResolvedType result = usage.getParamType(pos);
+ // We need to replace the type variables
+ Context ctx = JavaParserFactory.getContext(node, typeSolver);
+ result = solveGenericTypes(result, ctx, typeSolver);
+
+ //We should find out which is the functional method (e.g., apply) and replace the params of the
+ //solveLambdas with it, to derive so the values. We should also consider the value returned by the
+ //lambdas
+ if (FunctionalInterfaceLogic.getFunctionalMethod(result).isPresent()) {
+ MethodReferenceExpr methodReferenceExpr = node;
+
+ ResolvedType actualType = facade.toMethodUsage(methodReferenceExpr).returnType();
+ ResolvedType formalType = FunctionalInterfaceLogic.getFunctionalMethod(result).get().returnType();
+
+ InferenceContext inferenceContext = new InferenceContext(MyObjectProvider.INSTANCE);
+ inferenceContext.addPair(formalType, actualType);
+ result = inferenceContext.resolve(inferenceContext.addSingle(result));
+ }
+
+ return result;
+ }
+ return refMethod.getCorrespondingDeclaration().getParam(pos).getType();
+ }
+ throw new UnsupportedOperationException("The type of a method reference expr depends on the position and its return value");
+ }
+
+ @Override
+ public ResolvedType visit(FieldDeclaration node, Boolean solveLambdas) {
+ if (node.getVariables().size() == 1) {
+ return node.getVariables().get(0).accept(this, solveLambdas);
+ }
+ throw new IllegalArgumentException("Cannot resolve the type of a field with multiple variable declarations. Pick one");
+ }
+}
diff --git a/javaparser-symbol-solver-core/src/main/java/com/github/javaparser/symbolsolver/javaparsermodel/UnsolvedSymbolException.java b/javaparser-symbol-solver-core/src/main/java/com/github/javaparser/symbolsolver/javaparsermodel/UnsolvedSymbolException.java
new file mode 100644
index 000000000..f7ab7d11e
--- /dev/null
+++ b/javaparser-symbol-solver-core/src/main/java/com/github/javaparser/symbolsolver/javaparsermodel/UnsolvedSymbolException.java
@@ -0,0 +1,71 @@
+/*
+ * Copyright 2016 Federico Tomassetti
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.github.javaparser.symbolsolver.javaparsermodel;
+
+import com.github.javaparser.symbolsolver.core.resolution.Context;
+import com.github.javaparser.symbolsolver.model.resolution.TypeSolver;
+
+/**
+ * @author Federico Tomassetti
+ *
+ * @deprecated Use {@link com.github.javaparser.resolution.UnsolvedSymbolException} instead
+ */
+// Use the one in model instead
+@Deprecated
+public class UnsolvedSymbolException extends RuntimeException {
+
+ private String context;
+ private String name;
+ private TypeSolver typeSolver;
+
+ @Deprecated
+ public UnsolvedSymbolException(String name, TypeSolver typeSolver) {
+ super("Unsolved symbol : " + name + " using typesolver " + typeSolver);
+ this.typeSolver = typeSolver;
+ this.name = name;
+ }
+
+ @Deprecated
+ public UnsolvedSymbolException(Context context, String name) {
+ super("Unsolved symbol in " + context + " : " + name);
+ this.context = context.toString();
+ this.name = name;
+ }
+
+ @Deprecated
+ public UnsolvedSymbolException(String context, String name) {
+ super("Unsolved symbol in " + context + " : " + name);
+ this.context = context;
+ this.name = name;
+ }
+
+ @Deprecated
+ public UnsolvedSymbolException(String name) {
+ super("Unsolved symbol : " + name);
+ this.context = "unknown";
+ this.name = name;
+ }
+
+ @Override
+ public String toString() {
+ return "UnsolvedSymbolException{" +
+ "context='" + context + '\'' +
+ ", name='" + name + '\'' +
+ ", typeSolver=" + typeSolver +
+ '}';
+ }
+}
diff --git a/javaparser-symbol-solver-core/src/main/java/com/github/javaparser/symbolsolver/javaparsermodel/contexts/AbstractJavaParserContext.java b/javaparser-symbol-solver-core/src/main/java/com/github/javaparser/symbolsolver/javaparsermodel/contexts/AbstractJavaParserContext.java
new file mode 100644
index 000000000..cc008a527
--- /dev/null
+++ b/javaparser-symbol-solver-core/src/main/java/com/github/javaparser/symbolsolver/javaparsermodel/contexts/AbstractJavaParserContext.java
@@ -0,0 +1,193 @@
+/*
+ * Copyright 2016 Federico Tomassetti
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.github.javaparser.symbolsolver.javaparsermodel.contexts;
+
+import com.github.javaparser.ast.Node;
+import com.github.javaparser.ast.expr.Expression;
+import com.github.javaparser.ast.expr.FieldAccessExpr;
+import com.github.javaparser.ast.expr.MethodCallExpr;
+import com.github.javaparser.ast.expr.NameExpr;
+import com.github.javaparser.resolution.declarations.ResolvedValueDeclaration;
+import com.github.javaparser.resolution.declarations.ResolvedReferenceTypeDeclaration;
+import com.github.javaparser.resolution.declarations.ResolvedTypeDeclaration;
+import com.github.javaparser.resolution.declarations.ResolvedTypeParameterDeclaration;
+import com.github.javaparser.resolution.types.ResolvedType;
+import com.github.javaparser.symbolsolver.core.resolution.Context;
+import com.github.javaparser.symbolsolver.javaparsermodel.JavaParserFacade;
+import com.github.javaparser.symbolsolver.javaparsermodel.JavaParserFactory;
+import com.github.javaparser.symbolsolver.model.resolution.SymbolReference;
+import com.github.javaparser.symbolsolver.model.resolution.TypeSolver;
+import com.github.javaparser.symbolsolver.model.resolution.Value;
+import com.github.javaparser.symbolsolver.reflectionmodel.ReflectionClassDeclaration;
+import com.github.javaparser.symbolsolver.resolution.SymbolDeclarator;
+
+import java.util.*;
+
+import static com.github.javaparser.symbolsolver.javaparser.Navigator.getParentNode;
+import static com.github.javaparser.symbolsolver.javaparser.Navigator.requireParentNode;
+import static java.util.Collections.*;
+
+/**
+ * @author Federico Tomassetti
+ */
+public abstract class AbstractJavaParserContext<N extends Node> implements Context {
+
+ protected N wrappedNode;
+ protected TypeSolver typeSolver;
+
+ ///
+ /// Static methods
+ ///
+
+ public static SymbolReference<ResolvedValueDeclaration> solveWith(SymbolDeclarator symbolDeclarator, String name) {
+ for (ResolvedValueDeclaration decl : symbolDeclarator.getSymbolDeclarations()) {
+ if (decl.getName().equals(name)) {
+ return SymbolReference.solved(decl);
+ }
+ }
+ return SymbolReference.unsolved(ResolvedValueDeclaration.class);
+ }
+
+ ///
+ /// Constructors
+ ///
+
+ public AbstractJavaParserContext(N wrappedNode, TypeSolver typeSolver) {
+ if (wrappedNode == null) {
+ throw new NullPointerException();
+ }
+ this.wrappedNode = wrappedNode;
+ this.typeSolver = typeSolver;
+ }
+
+ ///
+ /// Public methods
+ ///
+
+ @Override
+ public boolean equals(Object o) {
+ if (this == o) return true;
+ if (o == null || getClass() != o.getClass()) return false;
+
+ AbstractJavaParserContext<?> that = (AbstractJavaParserContext<?>) o;
+
+ if (wrappedNode != null ? !wrappedNode.equals(that.wrappedNode) : that.wrappedNode != null) return false;
+
+ return true;
+ }
+
+ @Override
+ public int hashCode() {
+ return wrappedNode != null ? wrappedNode.hashCode() : 0;
+ }
+
+ @Override
+ public Optional<ResolvedType> solveGenericType(String name, TypeSolver typeSolver) {
+ Context parent = getParent();
+ if (parent == null) {
+ return Optional.empty();
+ } else {
+ return parent.solveGenericType(name, typeSolver);
+ }
+ }
+
+ @Override
+ public final Context getParent() {
+ Node parent = wrappedNode.getParentNode().orElse(null);
+ if (parent instanceof MethodCallExpr) {
+ MethodCallExpr parentCall = (MethodCallExpr) parent;
+ boolean found = false;
+ if (parentCall.getArguments() != null) {
+ for (Expression expression : parentCall.getArguments()) {
+ if (expression == wrappedNode) {
+ found = true;
+ }
+ }
+ }
+ if (found) {
+ Node notMethod = parent;
+ while (notMethod instanceof MethodCallExpr) {
+ notMethod = requireParentNode(notMethod);
+ }
+ return JavaParserFactory.getContext(notMethod, typeSolver);
+ }
+ }
+ Node notMethod = parent;
+ while (notMethod instanceof MethodCallExpr || notMethod instanceof FieldAccessExpr) {
+ notMethod = notMethod.getParentNode().orElse(null);
+ }
+ if (notMethod == null) {
+ return null;
+ }
+ return JavaParserFactory.getContext(notMethod, typeSolver);
+ }
+
+ ///
+ /// Protected methods
+ ///
+
+ protected Optional<Value> solveWithAsValue(SymbolDeclarator symbolDeclarator, String name, TypeSolver typeSolver) {
+ return symbolDeclarator.getSymbolDeclarations().stream()
+ .filter(d -> d.getName().equals(name))
+ .map(Value::from)
+ .findFirst();
+ }
+
+ protected Collection<ResolvedReferenceTypeDeclaration> findTypeDeclarations(Optional<Expression> optScope, TypeSolver typeSolver) {
+ if (optScope.isPresent()) {
+ Expression scope = optScope.get();
+
+ // consider static methods
+ if (scope instanceof NameExpr) {
+ NameExpr scopeAsName = (NameExpr) scope;
+ SymbolReference<ResolvedTypeDeclaration> symbolReference = this.solveType(scopeAsName.getName().getId(), typeSolver);
+ if (symbolReference.isSolved() && symbolReference.getCorrespondingDeclaration().isType()) {
+ return singletonList(symbolReference.getCorrespondingDeclaration().asReferenceType());
+ }
+ }
+
+ ResolvedType typeOfScope;
+ try {
+ typeOfScope = JavaParserFacade.get(typeSolver).getType(scope);
+ } catch (Exception e) {
+ throw new RuntimeException("Issue calculating the type of the scope of " + this, e);
+ }
+ if (typeOfScope.isWildcard()) {
+ if (typeOfScope.asWildcard().isExtends() || typeOfScope.asWildcard().isSuper()) {
+ return singletonList(typeOfScope.asWildcard().getBoundedType().asReferenceType().getTypeDeclaration());
+ } else {
+ return singletonList(new ReflectionClassDeclaration(Object.class, typeSolver).asReferenceType());
+ }
+ } else if (typeOfScope.isArray()) {
+ // method call on array are Object methods
+ return singletonList(new ReflectionClassDeclaration(Object.class, typeSolver).asReferenceType());
+ } else if (typeOfScope.isTypeVariable()) {
+ Collection<ResolvedReferenceTypeDeclaration> result = new ArrayList<>();
+ for (ResolvedTypeParameterDeclaration.Bound bound : typeOfScope.asTypeParameter().getBounds()) {
+ result.add(bound.getType().asReferenceType().getTypeDeclaration());
+ }
+ return result;
+ } else if (typeOfScope.isConstraint()) {
+ return singletonList(typeOfScope.asConstraintType().getBound().asReferenceType().getTypeDeclaration());
+ }
+ return singletonList(typeOfScope.asReferenceType().getTypeDeclaration());
+ }
+ ResolvedType typeOfScope = JavaParserFacade.get(typeSolver).getTypeOfThisIn(wrappedNode);
+ return singletonList(typeOfScope.asReferenceType().getTypeDeclaration());
+ }
+
+}
diff --git a/javaparser-symbol-solver-core/src/main/java/com/github/javaparser/symbolsolver/javaparsermodel/contexts/AbstractMethodLikeDeclarationContext.java b/javaparser-symbol-solver-core/src/main/java/com/github/javaparser/symbolsolver/javaparsermodel/contexts/AbstractMethodLikeDeclarationContext.java
new file mode 100644
index 000000000..d611d71a5
--- /dev/null
+++ b/javaparser-symbol-solver-core/src/main/java/com/github/javaparser/symbolsolver/javaparsermodel/contexts/AbstractMethodLikeDeclarationContext.java
@@ -0,0 +1,101 @@
+package com.github.javaparser.symbolsolver.javaparsermodel.contexts;
+
+import com.github.javaparser.ast.Node;
+import com.github.javaparser.ast.body.Parameter;
+import com.github.javaparser.ast.nodeTypes.NodeWithParameters;
+import com.github.javaparser.ast.nodeTypes.NodeWithTypeParameters;
+import com.github.javaparser.resolution.declarations.ResolvedMethodDeclaration;
+import com.github.javaparser.resolution.declarations.ResolvedTypeDeclaration;
+import com.github.javaparser.resolution.declarations.ResolvedValueDeclaration;
+import com.github.javaparser.resolution.types.ResolvedType;
+import com.github.javaparser.resolution.types.ResolvedTypeVariable;
+import com.github.javaparser.symbolsolver.javaparsermodel.JavaParserFacade;
+import com.github.javaparser.symbolsolver.javaparsermodel.JavaParserFactory;
+import com.github.javaparser.symbolsolver.javaparsermodel.declarations.JavaParserTypeParameter;
+import com.github.javaparser.symbolsolver.model.resolution.SymbolReference;
+import com.github.javaparser.symbolsolver.model.resolution.TypeSolver;
+import com.github.javaparser.symbolsolver.model.resolution.Value;
+import com.github.javaparser.symbolsolver.resolution.SymbolDeclarator;
+
+import java.util.List;
+import java.util.Optional;
+
+/**
+ * @author Federico Tomassetti
+ */
+public abstract class AbstractMethodLikeDeclarationContext
+ <T extends Node & NodeWithParameters<T> & NodeWithTypeParameters<T>> extends AbstractJavaParserContext<T> {
+
+ public AbstractMethodLikeDeclarationContext(T wrappedNode, TypeSolver typeSolver) {
+ super(wrappedNode, typeSolver);
+ }
+
+ public final SymbolReference<? extends ResolvedValueDeclaration> solveSymbol(String name, TypeSolver typeSolver) {
+ for (Parameter parameter : wrappedNode.getParameters()) {
+ SymbolDeclarator sb = JavaParserFactory.getSymbolDeclarator(parameter, typeSolver);
+ SymbolReference<? extends ResolvedValueDeclaration> symbolReference = AbstractJavaParserContext.solveWith(sb, name);
+ if (symbolReference.isSolved()) {
+ return symbolReference;
+ }
+ }
+
+ // if nothing is found we should ask the parent context
+ return getParent().solveSymbol(name, typeSolver);
+ }
+
+ @Override
+ public final Optional<ResolvedType> solveGenericType(String name, TypeSolver typeSolver) {
+ for (com.github.javaparser.ast.type.TypeParameter tp : wrappedNode.getTypeParameters()) {
+ if (tp.getName().getId().equals(name)) {
+ return Optional.of(new ResolvedTypeVariable(new JavaParserTypeParameter(tp, typeSolver)));
+ }
+ }
+ return super.solveGenericType(name, typeSolver);
+ }
+
+ @Override
+ public final Optional<Value> solveSymbolAsValue(String name, TypeSolver typeSolver) {
+ for (Parameter parameter : wrappedNode.getParameters()) {
+ SymbolDeclarator sb = JavaParserFactory.getSymbolDeclarator(parameter, typeSolver);
+ Optional<Value> symbolReference = solveWithAsValue(sb, name, typeSolver);
+ if (symbolReference.isPresent()) {
+ // Perform parameter type substitution as needed
+ return symbolReference;
+ }
+ }
+
+ // if nothing is found we should ask the parent context
+ return getParent().solveSymbolAsValue(name, typeSolver);
+ }
+
+ @Override
+ public final SymbolReference<ResolvedTypeDeclaration> solveType(String name, TypeSolver typeSolver) {
+ if (wrappedNode.getTypeParameters() != null) {
+ for (com.github.javaparser.ast.type.TypeParameter tp : wrappedNode.getTypeParameters()) {
+ if (tp.getName().getId().equals(name)) {
+ return SymbolReference.solved(new JavaParserTypeParameter(tp, typeSolver));
+ }
+ }
+ }
+
+ // Local types
+ List<com.github.javaparser.ast.body.TypeDeclaration> localTypes = wrappedNode.findAll(
+ com.github.javaparser.ast.body.TypeDeclaration.class);
+ for (com.github.javaparser.ast.body.TypeDeclaration<?> localType : localTypes) {
+ if (localType.getName().getId().equals(name)) {
+ return SymbolReference.solved(JavaParserFacade.get(typeSolver).getTypeDeclaration(localType));
+ } else if (name.startsWith(String.format("%s.", localType.getName()))) {
+ return JavaParserFactory.getContext(localType, typeSolver).solveType(
+ name.substring(localType.getName().getId().length() + 1), typeSolver);
+ }
+ }
+
+ return getParent().solveType(name, typeSolver);
+ }
+
+ @Override
+ public final SymbolReference<ResolvedMethodDeclaration> solveMethod(
+ String name, List<ResolvedType> argumentsTypes, boolean staticOnly, TypeSolver typeSolver) {
+ return getParent().solveMethod(name, argumentsTypes, false, typeSolver);
+ }
+}
diff --git a/javaparser-symbol-solver-core/src/main/java/com/github/javaparser/symbolsolver/javaparsermodel/contexts/AnonymousClassDeclarationContext.java b/javaparser-symbol-solver-core/src/main/java/com/github/javaparser/symbolsolver/javaparsermodel/contexts/AnonymousClassDeclarationContext.java
new file mode 100644
index 000000000..48133596a
--- /dev/null
+++ b/javaparser-symbol-solver-core/src/main/java/com/github/javaparser/symbolsolver/javaparsermodel/contexts/AnonymousClassDeclarationContext.java
@@ -0,0 +1,186 @@
+package com.github.javaparser.symbolsolver.javaparsermodel.contexts;
+
+import com.github.javaparser.ast.NodeList;
+import com.github.javaparser.ast.expr.ObjectCreationExpr;
+import com.github.javaparser.ast.nodeTypes.NodeWithTypeArguments;
+import com.github.javaparser.ast.type.TypeParameter;
+import com.github.javaparser.resolution.declarations.ResolvedMethodDeclaration;
+import com.github.javaparser.resolution.declarations.ResolvedTypeDeclaration;
+import com.github.javaparser.resolution.declarations.ResolvedValueDeclaration;
+import com.github.javaparser.resolution.types.ResolvedReferenceType;
+import com.github.javaparser.resolution.types.ResolvedType;
+import com.github.javaparser.symbolsolver.javaparsermodel.JavaParserFacade;
+import com.github.javaparser.symbolsolver.javaparsermodel.JavaParserFactory;
+import com.github.javaparser.symbolsolver.javaparsermodel.declarations
+ .JavaParserAnonymousClassDeclaration;
+import com.github.javaparser.symbolsolver.javaparsermodel.declarations.JavaParserTypeParameter;
+import com.github.javaparser.symbolsolver.model.resolution.SymbolReference;
+import com.github.javaparser.symbolsolver.model.resolution.TypeSolver;
+import com.github.javaparser.symbolsolver.reflectionmodel.ReflectionClassDeclaration;
+import com.github.javaparser.symbolsolver.resolution.MethodResolutionLogic;
+import com.google.common.base.Preconditions;
+
+import java.util.List;
+import java.util.Optional;
+import java.util.stream.Collectors;
+
+/**
+ * A symbol resolution context for an object creation node.
+ */
+public class AnonymousClassDeclarationContext extends AbstractJavaParserContext<ObjectCreationExpr> {
+
+ private final JavaParserAnonymousClassDeclaration myDeclaration =
+ new JavaParserAnonymousClassDeclaration(wrappedNode, typeSolver);
+
+ public AnonymousClassDeclarationContext(ObjectCreationExpr node, TypeSolver typeSolver) {
+ super(node, typeSolver);
+ Preconditions.checkArgument(node.getAnonymousClassBody().isPresent(),
+ "An anonymous class must have a body");
+ }
+
+ @Override
+ public SymbolReference<ResolvedMethodDeclaration> solveMethod(String name,
+ List<ResolvedType> argumentsTypes,
+ boolean staticOnly,
+ TypeSolver typeSolver) {
+ List<ResolvedMethodDeclaration> candidateMethods =
+ myDeclaration
+ .getDeclaredMethods()
+ .stream()
+ .filter(m -> m.getName().equals(name) && (!staticOnly || m.isStatic()))
+ .collect(Collectors.toList());
+
+ if (!Object.class.getCanonicalName().equals(myDeclaration.getQualifiedName())) {
+ for (ResolvedReferenceType ancestor : myDeclaration.getAncestors()) {
+ SymbolReference<ResolvedMethodDeclaration> res =
+ MethodResolutionLogic.solveMethodInType(ancestor.getTypeDeclaration(),
+ name,
+ argumentsTypes,
+ staticOnly,
+ typeSolver);
+ // consider methods from superclasses and only default methods from interfaces :
+ // not true, we should keep abstract as a valid candidate
+ // abstract are removed in MethodResolutionLogic.isApplicable is necessary
+ if (res.isSolved()) {
+ candidateMethods.add(res.getCorrespondingDeclaration());
+ }
+ }
+ }
+
+ // We want to avoid infinite recursion when a class is using its own method
+ // see issue #75
+ if (candidateMethods.isEmpty()) {
+ SymbolReference<ResolvedMethodDeclaration> parentSolution =
+ getParent().solveMethod(name, argumentsTypes, staticOnly, typeSolver);
+ if (parentSolution.isSolved()) {
+ candidateMethods.add(parentSolution.getCorrespondingDeclaration());
+ }
+ }
+
+ // if is interface and candidate method list is empty, we should check the Object Methods
+ if (candidateMethods.isEmpty() && myDeclaration.getSuperTypeDeclaration().isInterface()) {
+ SymbolReference<ResolvedMethodDeclaration> res =
+ MethodResolutionLogic.solveMethodInType(new ReflectionClassDeclaration(Object.class,
+ typeSolver),
+ name,
+ argumentsTypes,
+ false,
+ typeSolver);
+ if (res.isSolved()) {
+ candidateMethods.add(res.getCorrespondingDeclaration());
+ }
+ }
+
+ return MethodResolutionLogic.findMostApplicable(candidateMethods,
+ name,
+ argumentsTypes,
+ typeSolver);
+ }
+
+ @Override
+ public SymbolReference<ResolvedTypeDeclaration> solveType(String name, TypeSolver typeSolver) {
+ List<com.github.javaparser.ast.body.TypeDeclaration> typeDeclarations =
+ myDeclaration
+ .findMembersOfKind(com.github.javaparser.ast.body.TypeDeclaration.class);
+
+ Optional<SymbolReference<ResolvedTypeDeclaration>> exactMatch =
+ typeDeclarations
+ .stream()
+ .filter(internalType -> internalType.getName().getId().equals(name))
+ .findFirst()
+ .map(internalType ->
+ SymbolReference.solved(
+ JavaParserFacade.get(typeSolver).getTypeDeclaration(internalType)));
+
+ if(exactMatch.isPresent()){
+ return exactMatch.get();
+ }
+
+ Optional<SymbolReference<ResolvedTypeDeclaration>> recursiveMatch =
+ typeDeclarations
+ .stream()
+ .filter(internalType -> name.startsWith(String.format("%s.", internalType.getName())))
+ .findFirst()
+ .map(internalType ->
+ JavaParserFactory
+ .getContext(internalType, typeSolver)
+ .solveType(name.substring(internalType.getName().getId().length() + 1),
+ typeSolver));
+
+ if (recursiveMatch.isPresent()) {
+ return recursiveMatch.get();
+ }
+
+ Optional<SymbolReference<ResolvedTypeDeclaration>> typeArgumentsMatch =
+ wrappedNode
+ .getTypeArguments()
+ .map(nodes ->
+ ((NodeWithTypeArguments<?>) nodes).getTypeArguments()
+ .orElse(new NodeList<>()))
+ .orElse(new NodeList<>())
+ .stream()
+ .filter(type -> type.toString().equals(name))
+ .findFirst()
+ .map(matchingType ->
+ SymbolReference.solved(
+ new JavaParserTypeParameter(new TypeParameter(matchingType.toString()),
+ typeSolver)));
+
+ if (typeArgumentsMatch.isPresent()) {
+ return typeArgumentsMatch.get();
+ }
+
+ // Look into extended classes and implemented interfaces
+ for (ResolvedReferenceType ancestor : myDeclaration.getAncestors()) {
+ // look at names of extended classes and implemented interfaces (this may not be important because they are checked in CompilationUnitContext)
+ if (ancestor.getTypeDeclaration().getName().equals(name)) {
+ return SymbolReference.solved(ancestor.getTypeDeclaration());
+ }
+ // look into internal types of extended classes and implemented interfaces
+ try {
+ for (ResolvedTypeDeclaration internalTypeDeclaration : ancestor.getTypeDeclaration().internalTypes()) {
+ if (internalTypeDeclaration.getName().equals(name)) {
+ return SymbolReference.solved(internalTypeDeclaration);
+ }
+ }
+ } catch (UnsupportedOperationException e) {
+ // just continue using the next ancestor
+ }
+ }
+
+ return getParent().solveType(name, typeSolver);
+ }
+
+ @Override
+ public SymbolReference<? extends ResolvedValueDeclaration> solveSymbol(String name,
+ TypeSolver typeSolver) {
+ Preconditions.checkArgument(typeSolver != null);
+
+ if (myDeclaration.hasVisibleField(name)) {
+ return SymbolReference.solved(myDeclaration.getVisibleField(name));
+ }
+
+ return getParent().solveSymbol(name, typeSolver);
+ }
+
+}
diff --git a/javaparser-symbol-solver-core/src/main/java/com/github/javaparser/symbolsolver/javaparsermodel/contexts/CatchClauseContext.java b/javaparser-symbol-solver-core/src/main/java/com/github/javaparser/symbolsolver/javaparsermodel/contexts/CatchClauseContext.java
new file mode 100644
index 000000000..4683f272a
--- /dev/null
+++ b/javaparser-symbol-solver-core/src/main/java/com/github/javaparser/symbolsolver/javaparsermodel/contexts/CatchClauseContext.java
@@ -0,0 +1,54 @@
+package com.github.javaparser.symbolsolver.javaparsermodel.contexts;
+
+import com.github.javaparser.ast.stmt.CatchClause;
+import com.github.javaparser.resolution.declarations.ResolvedMethodDeclaration;
+import com.github.javaparser.resolution.declarations.ResolvedValueDeclaration;
+import com.github.javaparser.resolution.types.ResolvedType;
+import com.github.javaparser.symbolsolver.javaparsermodel.JavaParserFactory;
+import com.github.javaparser.symbolsolver.model.resolution.SymbolReference;
+import com.github.javaparser.symbolsolver.model.resolution.TypeSolver;
+import com.github.javaparser.symbolsolver.model.resolution.Value;
+import com.github.javaparser.symbolsolver.resolution.SymbolDeclarator;
+
+import java.util.List;
+import java.util.Optional;
+
+/**
+ * @author Fred Lefévère-Laoide
+ */
+public class CatchClauseContext extends AbstractJavaParserContext<CatchClause> {
+
+ public CatchClauseContext(CatchClause wrappedNode, TypeSolver typeSolver) {
+ super(wrappedNode, typeSolver);
+ }
+
+ public final SymbolReference<? extends ResolvedValueDeclaration> solveSymbol(String name, TypeSolver typeSolver) {
+ SymbolDeclarator sb = JavaParserFactory.getSymbolDeclarator(wrappedNode.getParameter(), typeSolver);
+ SymbolReference<? extends ResolvedValueDeclaration> symbolReference = AbstractJavaParserContext.solveWith(sb, name);
+ if (symbolReference.isSolved()) {
+ return symbolReference;
+ }
+
+ // if nothing is found we should ask the parent context
+ return getParent().solveSymbol(name, typeSolver);
+ }
+
+ @Override
+ public final Optional<Value> solveSymbolAsValue(String name, TypeSolver typeSolver) {
+ SymbolDeclarator sb = JavaParserFactory.getSymbolDeclarator(wrappedNode.getParameter(), typeSolver);
+ Optional<Value> symbolReference = solveWithAsValue(sb, name, typeSolver);
+ if (symbolReference.isPresent()) {
+ // Perform parameter type substitution as needed
+ return symbolReference;
+ }
+
+ // if nothing is found we should ask the parent context
+ return getParent().solveSymbolAsValue(name, typeSolver);
+ }
+
+ @Override
+ public final SymbolReference<ResolvedMethodDeclaration> solveMethod(
+ String name, List<ResolvedType> argumentsTypes, boolean staticOnly, TypeSolver typeSolver) {
+ return getParent().solveMethod(name, argumentsTypes, false, typeSolver);
+ }
+}
diff --git a/javaparser-symbol-solver-core/src/main/java/com/github/javaparser/symbolsolver/javaparsermodel/contexts/ClassOrInterfaceDeclarationContext.java b/javaparser-symbol-solver-core/src/main/java/com/github/javaparser/symbolsolver/javaparsermodel/contexts/ClassOrInterfaceDeclarationContext.java
new file mode 100644
index 000000000..01f4b050c
--- /dev/null
+++ b/javaparser-symbol-solver-core/src/main/java/com/github/javaparser/symbolsolver/javaparsermodel/contexts/ClassOrInterfaceDeclarationContext.java
@@ -0,0 +1,109 @@
+/*
+ * Copyright 2016 Federico Tomassetti
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.github.javaparser.symbolsolver.javaparsermodel.contexts;
+
+import com.github.javaparser.ast.body.ClassOrInterfaceDeclaration;
+import com.github.javaparser.resolution.declarations.ResolvedReferenceTypeDeclaration;
+import com.github.javaparser.resolution.declarations.*;
+import com.github.javaparser.resolution.types.ResolvedType;
+import com.github.javaparser.resolution.types.ResolvedTypeVariable;
+import com.github.javaparser.symbolsolver.javaparsermodel.JavaParserFacade;
+import com.github.javaparser.symbolsolver.javaparsermodel.declarations.JavaParserTypeParameter;
+import com.github.javaparser.symbolsolver.model.resolution.SymbolReference;
+import com.github.javaparser.symbolsolver.model.resolution.TypeSolver;
+import com.github.javaparser.symbolsolver.model.resolution.Value;
+
+import java.util.List;
+import java.util.Optional;
+
+/**
+ * @author Federico Tomassetti
+ */
+public class ClassOrInterfaceDeclarationContext extends AbstractJavaParserContext<ClassOrInterfaceDeclaration> {
+
+ private JavaParserTypeDeclarationAdapter javaParserTypeDeclarationAdapter;
+
+ ///
+ /// Constructors
+ ///
+
+ public ClassOrInterfaceDeclarationContext(ClassOrInterfaceDeclaration wrappedNode, TypeSolver typeSolver) {
+ super(wrappedNode, typeSolver);
+ this.javaParserTypeDeclarationAdapter = new JavaParserTypeDeclarationAdapter(wrappedNode, typeSolver,
+ getDeclaration(), this);
+ }
+
+ ///
+ /// Public methods
+ ///
+
+ @Override
+ public SymbolReference<? extends ResolvedValueDeclaration> solveSymbol(String name, TypeSolver typeSolver) {
+ if (typeSolver == null) throw new IllegalArgumentException();
+
+ if (this.getDeclaration().hasVisibleField(name)) {
+ return SymbolReference.solved(this.getDeclaration().getVisibleField(name));
+ }
+
+ // then to parent
+ return getParent().solveSymbol(name, typeSolver);
+ }
+
+ @Override
+ public Optional<Value> solveSymbolAsValue(String name, TypeSolver typeSolver) {
+ if (typeSolver == null) throw new IllegalArgumentException();
+
+ if (this.getDeclaration().hasVisibleField(name)) {
+ return Optional.of(Value.from(this.getDeclaration().getVisibleField(name)));
+ }
+
+ // then to parent
+ return getParent().solveSymbolAsValue(name, typeSolver);
+ }
+
+ @Override
+ public Optional<ResolvedType> solveGenericType(String name, TypeSolver typeSolver) {
+ for (com.github.javaparser.ast.type.TypeParameter tp : wrappedNode.getTypeParameters()) {
+ if (tp.getName().getId().equals(name)) {
+ return Optional.of(new ResolvedTypeVariable(new JavaParserTypeParameter(tp, typeSolver)));
+ }
+ }
+ return getParent().solveGenericType(name, typeSolver);
+ }
+
+ @Override
+ public SymbolReference<ResolvedTypeDeclaration> solveType(String name, TypeSolver typeSolver) {
+ return javaParserTypeDeclarationAdapter.solveType(name, typeSolver);
+ }
+
+ @Override
+ public SymbolReference<ResolvedMethodDeclaration> solveMethod(String name, List<ResolvedType> argumentsTypes, boolean staticOnly, TypeSolver typeSolver) {
+ return javaParserTypeDeclarationAdapter.solveMethod(name, argumentsTypes, staticOnly, typeSolver);
+ }
+
+ public SymbolReference<ResolvedConstructorDeclaration> solveConstructor(List<ResolvedType> argumentsTypes, TypeSolver typeSolver) {
+ return javaParserTypeDeclarationAdapter.solveConstructor(argumentsTypes, typeSolver);
+ }
+
+ ///
+ /// Private methods
+ ///
+
+ private ResolvedReferenceTypeDeclaration getDeclaration() {
+ return JavaParserFacade.get(typeSolver).getTypeDeclaration(this.wrappedNode);
+ }
+}
diff --git a/javaparser-symbol-solver-core/src/main/java/com/github/javaparser/symbolsolver/javaparsermodel/contexts/CompilationUnitContext.java b/javaparser-symbol-solver-core/src/main/java/com/github/javaparser/symbolsolver/javaparsermodel/contexts/CompilationUnitContext.java
new file mode 100644
index 000000000..e6a4aa0d5
--- /dev/null
+++ b/javaparser-symbol-solver-core/src/main/java/com/github/javaparser/symbolsolver/javaparsermodel/contexts/CompilationUnitContext.java
@@ -0,0 +1,291 @@
+/*
+ * Copyright 2016 Federico Tomassetti
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.github.javaparser.symbolsolver.javaparsermodel.contexts;
+
+import com.github.javaparser.ast.CompilationUnit;
+import com.github.javaparser.ast.ImportDeclaration;
+import com.github.javaparser.ast.body.AnnotationDeclaration;
+import com.github.javaparser.ast.body.ClassOrInterfaceDeclaration;
+import com.github.javaparser.ast.body.EnumDeclaration;
+import com.github.javaparser.ast.body.TypeDeclaration;
+import com.github.javaparser.ast.expr.MethodCallExpr;
+import com.github.javaparser.ast.expr.Name;
+import com.github.javaparser.ast.type.ClassOrInterfaceType;
+import com.github.javaparser.resolution.declarations.ResolvedMethodDeclaration;
+import com.github.javaparser.resolution.declarations.ResolvedReferenceTypeDeclaration;
+import com.github.javaparser.resolution.declarations.ResolvedTypeDeclaration;
+import com.github.javaparser.resolution.declarations.ResolvedValueDeclaration;
+import com.github.javaparser.resolution.types.ResolvedType;
+import com.github.javaparser.symbolsolver.javaparsermodel.JavaParserFacade;
+import com.github.javaparser.symbolsolver.javaparsermodel.declarations.JavaParserAnnotationDeclaration;
+import com.github.javaparser.symbolsolver.javaparsermodel.declarations.JavaParserEnumDeclaration;
+import com.github.javaparser.symbolsolver.model.resolution.SymbolReference;
+import com.github.javaparser.symbolsolver.model.resolution.TypeSolver;
+import com.github.javaparser.symbolsolver.resolution.MethodResolutionLogic;
+import com.github.javaparser.symbolsolver.resolution.SymbolSolver;
+
+import java.util.List;
+
+/**
+ * @author Federico Tomassetti
+ */
+public class CompilationUnitContext extends AbstractJavaParserContext<CompilationUnit> {
+
+ ///
+ /// Static methods
+ ///
+
+ private static boolean isQualifiedName(String name) {
+ return name.contains(".");
+ }
+
+ ///
+ /// Constructors
+ ///
+
+ public CompilationUnitContext(CompilationUnit wrappedNode, TypeSolver typeSolver) {
+ super(wrappedNode, typeSolver);
+ }
+
+ ///
+ /// Public methods
+ ///
+
+ @Override
+ public SymbolReference<? extends ResolvedValueDeclaration> solveSymbol(String name, TypeSolver typeSolver) {
+
+ // solve absolute references
+ String itName = name;
+ while (itName.contains(".")) {
+ String typeName = getType(itName);
+ String memberName = getMember(itName);
+ SymbolReference<ResolvedTypeDeclaration> type = this.solveType(typeName, typeSolver);
+ if (type.isSolved()) {
+ return new SymbolSolver(typeSolver).solveSymbolInType(type.getCorrespondingDeclaration(), memberName);
+ } else {
+ itName = typeName;
+ }
+ }
+
+ // Look among statically imported values
+ if (wrappedNode.getImports() != null) {
+ for (ImportDeclaration importDecl : wrappedNode.getImports()) {
+ if(importDecl.isStatic()){
+ if(importDecl.isAsterisk()) {
+ String qName = importDecl.getNameAsString();
+ ResolvedTypeDeclaration importedType = typeSolver.solveType(qName);
+ SymbolReference<? extends ResolvedValueDeclaration> ref = new SymbolSolver(typeSolver).solveSymbolInType(importedType, name);
+ if (ref.isSolved()) {
+ return ref;
+ }
+ } else{
+ String whole = importDecl.getNameAsString();
+
+ // split in field/method name and type name
+ String memberName = getMember(whole);
+ String typeName = getType(whole);
+
+ if (memberName.equals(name)) {
+ ResolvedTypeDeclaration importedType = typeSolver.solveType(typeName);
+ return new SymbolSolver(typeSolver).solveSymbolInType(importedType, memberName);
+ }
+ }
+ }
+ }
+ }
+
+ return SymbolReference.unsolved(ResolvedValueDeclaration.class);
+ }
+
+ @Override
+ public SymbolReference<ResolvedTypeDeclaration> solveType(String name, TypeSolver typeSolver) {
+ if (wrappedNode.getTypes() != null) {
+ for (TypeDeclaration<?> type : wrappedNode.getTypes()) {
+ if (type.getName().getId().equals(name)) {
+ if (type instanceof ClassOrInterfaceDeclaration) {
+ return SymbolReference.solved(JavaParserFacade.get(typeSolver).getTypeDeclaration((ClassOrInterfaceDeclaration) type));
+ } else if (type instanceof AnnotationDeclaration) {
+ return SymbolReference.solved(new JavaParserAnnotationDeclaration((AnnotationDeclaration) type, typeSolver));
+ } else if (type instanceof EnumDeclaration) {
+ return SymbolReference.solved(new JavaParserEnumDeclaration((EnumDeclaration) type, typeSolver));
+ } else {
+ throw new UnsupportedOperationException(type.getClass().getCanonicalName());
+ }
+ }
+ }
+ }
+
+ if (wrappedNode.getImports() != null) {
+ int dotPos = name.indexOf('.');
+ String prefix = null;
+ if (dotPos > -1) {
+ prefix = name.substring(0, dotPos);
+ }
+ // look into type imports
+ for (ImportDeclaration importDecl : wrappedNode.getImports()) {
+ if (!importDecl.isAsterisk()) {
+ String qName = importDecl.getNameAsString();
+ boolean defaultPackage = !importDecl.getName().getQualifier().isPresent();
+ boolean found = !defaultPackage && importDecl.getName().getIdentifier().equals(name);
+ if (!found) {
+ if (prefix != null) {
+ found = qName.endsWith("." + prefix);
+ if (found) {
+ qName = qName + name.substring(dotPos);
+ }
+ }
+ }
+ if (found) {
+ SymbolReference<ResolvedReferenceTypeDeclaration> ref = typeSolver.tryToSolveType(qName);
+ if (ref.isSolved()) {
+ return SymbolReference.adapt(ref, ResolvedTypeDeclaration.class);
+ }
+ }
+ }
+ }
+ // look into type imports on demand
+ for (ImportDeclaration importDecl : wrappedNode.getImports()) {
+ if (importDecl.isAsterisk()) {
+ String qName = importDecl.getNameAsString() + "." + name;
+ SymbolReference<ResolvedReferenceTypeDeclaration> ref = typeSolver.tryToSolveType(qName);
+ if (ref.isSolved()) {
+ return SymbolReference.adapt(ref, ResolvedTypeDeclaration.class);
+ }
+ }
+ }
+ }
+
+ // Look in current package
+ if (this.wrappedNode.getPackageDeclaration().isPresent()) {
+ String qName = this.wrappedNode.getPackageDeclaration().get().getName().toString() + "." + name;
+ SymbolReference<ResolvedReferenceTypeDeclaration> ref = typeSolver.tryToSolveType(qName);
+ if (ref.isSolved()) {
+ return SymbolReference.adapt(ref, ResolvedTypeDeclaration.class);
+ }
+ } else {
+ // look for classes in the default package
+ String qName = name;
+ SymbolReference<ResolvedReferenceTypeDeclaration> ref = typeSolver.tryToSolveType(qName);
+ if (ref.isSolved()) {
+ return SymbolReference.adapt(ref, ResolvedTypeDeclaration.class);
+ }
+ }
+
+ // Look in the java.lang package
+ SymbolReference<ResolvedReferenceTypeDeclaration> ref = typeSolver.tryToSolveType("java.lang." + name);
+ if (ref.isSolved()) {
+ return SymbolReference.adapt(ref, ResolvedTypeDeclaration.class);
+ }
+
+ // DO NOT look for absolute name if this name is not qualified: you cannot import classes from the default package
+ if (isQualifiedName(name)) {
+ return SymbolReference.adapt(typeSolver.tryToSolveType(name), ResolvedTypeDeclaration.class);
+ } else {
+ return SymbolReference.unsolved(ResolvedReferenceTypeDeclaration.class);
+ }
+ }
+
+ private String qName(ClassOrInterfaceType type) {
+ if (type.getScope().isPresent()) {
+ return qName(type.getScope().get()) + "." + type.getName().getId();
+ } else {
+ return type.getName().getId();
+ }
+ }
+
+ private String qName(Name name) {
+ if (name.getQualifier().isPresent()) {
+ return qName(name.getQualifier().get()) + "." + name.getId();
+ } else {
+ return name.getId();
+ }
+ }
+
+ private String toSimpleName(String qName) {
+ String[] parts = qName.split("\\.");
+ return parts[parts.length - 1];
+ }
+
+ private String packageName(String qName) {
+ int lastDot = qName.lastIndexOf('.');
+ if (lastDot == -1) {
+ throw new UnsupportedOperationException();
+ } else {
+ return qName.substring(0, lastDot);
+ }
+ }
+
+ @Override
+ public SymbolReference<ResolvedMethodDeclaration> solveMethod(String name, List<ResolvedType> argumentsTypes, boolean staticOnly, TypeSolver typeSolver) {
+ for (ImportDeclaration importDecl : wrappedNode.getImports()) {
+ if(importDecl.isStatic()){
+ if(importDecl.isAsterisk()){
+ String importString = importDecl.getNameAsString();
+
+ if (this.wrappedNode.getPackageDeclaration().isPresent()
+ && this.wrappedNode.getPackageDeclaration().get().getName().getIdentifier().equals(packageName(importString))
+ && this.wrappedNode.getTypes().stream().anyMatch(it -> it.getName().getIdentifier().equals(toSimpleName(importString)))) {
+ // We are using a static import on a type defined in this file. It means the value was not found at
+ // a lower level so this will fail
+ return SymbolReference.unsolved(ResolvedMethodDeclaration.class);
+ }
+
+ ResolvedTypeDeclaration ref = typeSolver.solveType(importString);
+ SymbolReference<ResolvedMethodDeclaration> method = MethodResolutionLogic.solveMethodInType(ref, name, argumentsTypes, true, typeSolver);
+
+ if (method.isSolved()) {
+ return method;
+ }
+ } else{
+ String qName = importDecl.getNameAsString();
+
+ if (qName.equals(name) || qName.endsWith("." + name)) {
+ String typeName = getType(qName);
+ ResolvedTypeDeclaration ref = typeSolver.solveType(typeName);
+ SymbolReference<ResolvedMethodDeclaration> method = MethodResolutionLogic.solveMethodInType(ref, name, argumentsTypes, true, typeSolver);
+ if (method.isSolved()) {
+ return method;
+ }
+ }
+ }
+ }
+ }
+ return SymbolReference.unsolved(ResolvedMethodDeclaration.class);
+ }
+
+ ///
+ /// Private methods
+ ///
+
+ private String getType(String qName) {
+ int index = qName.lastIndexOf('.');
+ if (index == -1) {
+ throw new UnsupportedOperationException();
+ }
+ String typeName = qName.substring(0, index);
+ return typeName;
+ }
+
+ private String getMember(String qName) {
+ int index = qName.lastIndexOf('.');
+ if (index == -1) {
+ throw new UnsupportedOperationException();
+ }
+ String memberName = qName.substring(index + 1);
+ return memberName;
+ }
+}
diff --git a/javaparser-symbol-solver-core/src/main/java/com/github/javaparser/symbolsolver/javaparsermodel/contexts/ConstructorContext.java b/javaparser-symbol-solver-core/src/main/java/com/github/javaparser/symbolsolver/javaparsermodel/contexts/ConstructorContext.java
new file mode 100644
index 000000000..bebaa7313
--- /dev/null
+++ b/javaparser-symbol-solver-core/src/main/java/com/github/javaparser/symbolsolver/javaparsermodel/contexts/ConstructorContext.java
@@ -0,0 +1,35 @@
+/*
+ * Copyright 2016 Federico Tomassetti
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.github.javaparser.symbolsolver.javaparsermodel.contexts;
+
+import com.github.javaparser.ast.body.ConstructorDeclaration;
+import com.github.javaparser.symbolsolver.model.resolution.TypeSolver;
+
+/**
+ * @author Federico Tomassetti
+ */
+public class ConstructorContext extends AbstractMethodLikeDeclarationContext<ConstructorDeclaration> {
+
+ ///
+ /// Constructors
+ ///
+
+ public ConstructorContext(ConstructorDeclaration wrappedNode, TypeSolver typeSolver) {
+ super(wrappedNode, typeSolver);
+ }
+
+}
diff --git a/javaparser-symbol-solver-core/src/main/java/com/github/javaparser/symbolsolver/javaparsermodel/contexts/ContextHelper.java b/javaparser-symbol-solver-core/src/main/java/com/github/javaparser/symbolsolver/javaparsermodel/contexts/ContextHelper.java
new file mode 100644
index 000000000..e0eda24b0
--- /dev/null
+++ b/javaparser-symbol-solver-core/src/main/java/com/github/javaparser/symbolsolver/javaparsermodel/contexts/ContextHelper.java
@@ -0,0 +1,74 @@
+/*
+ * Copyright 2016 Federico Tomassetti
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.github.javaparser.symbolsolver.javaparsermodel.contexts;
+
+import com.github.javaparser.resolution.MethodUsage;
+import com.github.javaparser.resolution.declarations.ResolvedTypeDeclaration;
+import com.github.javaparser.resolution.types.ResolvedType;
+import com.github.javaparser.symbolsolver.core.resolution.Context;
+import com.github.javaparser.symbolsolver.javaparsermodel.declarations.JavaParserAnonymousClassDeclaration;
+import com.github.javaparser.symbolsolver.javaparsermodel.declarations.JavaParserClassDeclaration;
+import com.github.javaparser.symbolsolver.javaparsermodel.declarations.JavaParserEnumDeclaration;
+import com.github.javaparser.symbolsolver.javaparsermodel.declarations.JavaParserInterfaceDeclaration;
+import com.github.javaparser.symbolsolver.javassistmodel.JavassistClassDeclaration;
+import com.github.javaparser.symbolsolver.javassistmodel.JavassistEnumDeclaration;
+import com.github.javaparser.symbolsolver.javassistmodel.JavassistInterfaceDeclaration;
+import com.github.javaparser.symbolsolver.model.resolution.TypeSolver;
+import com.github.javaparser.symbolsolver.reflectionmodel.ReflectionClassDeclaration;
+import com.github.javaparser.symbolsolver.reflectionmodel.ReflectionEnumDeclaration;
+import com.github.javaparser.symbolsolver.reflectionmodel.ReflectionInterfaceDeclaration;
+
+import java.util.List;
+import java.util.Optional;
+
+/**
+ * @author Federico Tomassetti
+ */
+public class ContextHelper {
+
+ private ContextHelper() {
+ // prevent instantiation
+ }
+
+ public static Optional<MethodUsage> solveMethodAsUsage(ResolvedTypeDeclaration typeDeclaration, String name,
+ List<ResolvedType> argumentsTypes, TypeSolver typeSolver,
+ Context invokationContext, List<ResolvedType> typeParameters) {
+ if (typeDeclaration instanceof JavassistClassDeclaration) {
+ return ((JavassistClassDeclaration) typeDeclaration).solveMethodAsUsage(name, argumentsTypes, typeSolver, invokationContext, typeParameters);
+ } else if (typeDeclaration instanceof JavassistInterfaceDeclaration) {
+ return ((JavassistInterfaceDeclaration) typeDeclaration).solveMethodAsUsage(name, argumentsTypes, typeSolver, invokationContext, typeParameters);
+ } else if (typeDeclaration instanceof JavassistEnumDeclaration) {
+ return ((JavassistEnumDeclaration) typeDeclaration).solveMethodAsUsage(name, argumentsTypes, typeSolver, invokationContext, typeParameters);
+ } else if (typeDeclaration instanceof ReflectionClassDeclaration) {
+ return ((ReflectionClassDeclaration) typeDeclaration).solveMethodAsUsage(name, argumentsTypes, typeSolver, invokationContext, typeParameters);
+ } else if (typeDeclaration instanceof ReflectionInterfaceDeclaration) {
+ return ((ReflectionInterfaceDeclaration) typeDeclaration).solveMethodAsUsage(name, argumentsTypes, typeSolver, invokationContext, typeParameters);
+ } else if (typeDeclaration instanceof ReflectionEnumDeclaration) {
+ return ((ReflectionEnumDeclaration) typeDeclaration).solveMethodAsUsage(name, argumentsTypes, typeSolver, invokationContext, typeParameters);
+ } else if (typeDeclaration instanceof JavaParserClassDeclaration) {
+ return ((JavaParserClassDeclaration) typeDeclaration).getContext().solveMethodAsUsage(name, argumentsTypes, typeSolver);
+ } else if (typeDeclaration instanceof JavaParserInterfaceDeclaration) {
+ return ((JavaParserInterfaceDeclaration) typeDeclaration).getContext().solveMethodAsUsage(name, argumentsTypes, typeSolver);
+ } else if (typeDeclaration instanceof JavaParserEnumDeclaration) {
+ return ((JavaParserEnumDeclaration) typeDeclaration).getContext().solveMethodAsUsage(name, argumentsTypes, typeSolver);
+ } else if (typeDeclaration instanceof JavaParserAnonymousClassDeclaration) {
+ return ((JavaParserAnonymousClassDeclaration) typeDeclaration).getContext().solveMethodAsUsage(name, argumentsTypes, typeSolver);
+ }
+ throw new UnsupportedOperationException(typeDeclaration.toString());
+ }
+
+}
diff --git a/javaparser-symbol-solver-core/src/main/java/com/github/javaparser/symbolsolver/javaparsermodel/contexts/EnumDeclarationContext.java b/javaparser-symbol-solver-core/src/main/java/com/github/javaparser/symbolsolver/javaparsermodel/contexts/EnumDeclarationContext.java
new file mode 100644
index 000000000..7f2365fe7
--- /dev/null
+++ b/javaparser-symbol-solver-core/src/main/java/com/github/javaparser/symbolsolver/javaparsermodel/contexts/EnumDeclarationContext.java
@@ -0,0 +1,82 @@
+/*
+ * Copyright 2016 Federico Tomassetti
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.github.javaparser.symbolsolver.javaparsermodel.contexts;
+
+import com.github.javaparser.ast.body.EnumConstantDeclaration;
+import com.github.javaparser.ast.body.EnumDeclaration;
+import com.github.javaparser.resolution.declarations.ResolvedMethodDeclaration;
+import com.github.javaparser.resolution.declarations.ResolvedReferenceTypeDeclaration;
+import com.github.javaparser.resolution.declarations.ResolvedTypeDeclaration;
+import com.github.javaparser.resolution.declarations.ResolvedValueDeclaration;
+import com.github.javaparser.resolution.types.ResolvedType;
+import com.github.javaparser.symbolsolver.javaparsermodel.declarations.JavaParserEnumConstantDeclaration;
+import com.github.javaparser.symbolsolver.javaparsermodel.declarations.JavaParserEnumDeclaration;
+import com.github.javaparser.symbolsolver.model.resolution.SymbolReference;
+import com.github.javaparser.symbolsolver.model.resolution.TypeSolver;
+
+import java.util.List;
+
+/**
+ * @author Federico Tomassetti
+ */
+public class EnumDeclarationContext extends AbstractJavaParserContext<EnumDeclaration> {
+
+ private JavaParserTypeDeclarationAdapter javaParserTypeDeclarationAdapter;
+
+ public EnumDeclarationContext(EnumDeclaration wrappedNode, TypeSolver typeSolver) {
+ super(wrappedNode, typeSolver);
+ this.javaParserTypeDeclarationAdapter = new JavaParserTypeDeclarationAdapter(wrappedNode, typeSolver,
+ getDeclaration(), this);
+ }
+
+ @Override
+ public SymbolReference<? extends ResolvedValueDeclaration> solveSymbol(String name, TypeSolver typeSolver) {
+ if (typeSolver == null) throw new IllegalArgumentException();
+
+ // among constants
+ for (EnumConstantDeclaration constant : wrappedNode.getEntries()) {
+ if (constant.getName().getId().equals(name)) {
+ return SymbolReference.solved(new JavaParserEnumConstantDeclaration(constant, typeSolver));
+ }
+ }
+
+ if (this.getDeclaration().hasField(name)) {
+ return SymbolReference.solved(this.getDeclaration().getField(name));
+ }
+
+ // then to parent
+ return getParent().solveSymbol(name, typeSolver);
+ }
+
+ @Override
+ public SymbolReference<ResolvedTypeDeclaration> solveType(String name, TypeSolver typeSolver) {
+ return javaParserTypeDeclarationAdapter.solveType(name, typeSolver);
+ }
+
+ @Override
+ public SymbolReference<ResolvedMethodDeclaration> solveMethod(String name, List<ResolvedType> argumentsTypes, boolean staticOnly, TypeSolver typeSolver) {
+ return javaParserTypeDeclarationAdapter.solveMethod(name, argumentsTypes, staticOnly, typeSolver);
+ }
+
+ ///
+ /// Private methods
+ ///
+
+ private ResolvedReferenceTypeDeclaration getDeclaration() {
+ return new JavaParserEnumDeclaration(this.wrappedNode, typeSolver);
+ }
+}
diff --git a/javaparser-symbol-solver-core/src/main/java/com/github/javaparser/symbolsolver/javaparsermodel/contexts/FieldAccessContext.java b/javaparser-symbol-solver-core/src/main/java/com/github/javaparser/symbolsolver/javaparsermodel/contexts/FieldAccessContext.java
new file mode 100644
index 000000000..65ccedf00
--- /dev/null
+++ b/javaparser-symbol-solver-core/src/main/java/com/github/javaparser/symbolsolver/javaparsermodel/contexts/FieldAccessContext.java
@@ -0,0 +1,104 @@
+/*
+ * Copyright 2016 Federico Tomassetti
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.github.javaparser.symbolsolver.javaparsermodel.contexts;
+
+import com.github.javaparser.ast.expr.Expression;
+import com.github.javaparser.ast.expr.FieldAccessExpr;
+import com.github.javaparser.ast.expr.ThisExpr;
+import com.github.javaparser.resolution.declarations.ResolvedMethodDeclaration;
+import com.github.javaparser.resolution.declarations.ResolvedReferenceTypeDeclaration;
+import com.github.javaparser.resolution.declarations.ResolvedTypeDeclaration;
+import com.github.javaparser.resolution.declarations.ResolvedValueDeclaration;
+import com.github.javaparser.resolution.declarations.ResolvedFieldDeclaration;
+import com.github.javaparser.resolution.types.ResolvedPrimitiveType;
+import com.github.javaparser.resolution.types.ResolvedType;
+import com.github.javaparser.symbolsolver.javaparsermodel.JavaParserFacade;
+import com.github.javaparser.symbolsolver.javaparsermodel.JavaParserFactory;
+import com.github.javaparser.symbolsolver.model.resolution.SymbolReference;
+import com.github.javaparser.symbolsolver.model.resolution.TypeSolver;
+import com.github.javaparser.symbolsolver.model.resolution.Value;
+import com.github.javaparser.symbolsolver.resolution.SymbolSolver;
+
+import java.util.Collection;
+import java.util.List;
+import java.util.Optional;
+
+import static com.github.javaparser.symbolsolver.javaparser.Navigator.getParentNode;
+import static com.github.javaparser.symbolsolver.javaparser.Navigator.requireParentNode;
+
+/**
+ * @author Federico Tomassetti
+ */
+public class FieldAccessContext extends AbstractJavaParserContext<FieldAccessExpr> {
+
+ private static final String ARRAY_LENGTH_FIELD_NAME = "length";
+
+ public FieldAccessContext(FieldAccessExpr wrappedNode, TypeSolver typeSolver) {
+ super(wrappedNode, typeSolver);
+ }
+
+ @Override
+ public SymbolReference<? extends ResolvedValueDeclaration> solveSymbol(String name, TypeSolver typeSolver) {
+ if (wrappedNode.getName().toString().equals(name)) {
+ if (wrappedNode.getScope() instanceof ThisExpr) {
+ ResolvedType typeOfThis = JavaParserFacade.get(typeSolver).getTypeOfThisIn(wrappedNode);
+ return new SymbolSolver(typeSolver).solveSymbolInType(typeOfThis.asReferenceType().getTypeDeclaration(), name);
+ }
+ }
+ return JavaParserFactory.getContext(requireParentNode(wrappedNode), typeSolver).solveSymbol(name, typeSolver);
+ }
+
+ @Override
+ public SymbolReference<ResolvedTypeDeclaration> solveType(String name, TypeSolver typeSolver) {
+ return JavaParserFactory.getContext(requireParentNode(wrappedNode), typeSolver).solveType(name, typeSolver);
+ }
+
+ @Override
+ public SymbolReference<ResolvedMethodDeclaration> solveMethod(String name, List<ResolvedType> parameterTypes, boolean staticOnly, TypeSolver typeSolver) {
+ return JavaParserFactory.getContext(requireParentNode(wrappedNode), typeSolver).solveMethod(name, parameterTypes, false, typeSolver);
+ }
+
+ @Override
+ public Optional<Value> solveSymbolAsValue(String name, TypeSolver typeSolver) {
+ Expression scope = wrappedNode.getScope();
+ if (wrappedNode.getName().toString().equals(name)) {
+ ResolvedType typeOfScope = JavaParserFacade.get(typeSolver).getType(scope);
+ if (typeOfScope.isArray() && name.equals(ARRAY_LENGTH_FIELD_NAME)) {
+ return Optional.of(new Value(ResolvedPrimitiveType.INT, ARRAY_LENGTH_FIELD_NAME));
+ }
+ if (typeOfScope.isReferenceType()) {
+ Optional<ResolvedType> typeUsage = typeOfScope.asReferenceType().getFieldType(name);
+ return typeUsage.map(resolvedType -> new Value(resolvedType, name));
+ } else {
+ return Optional.empty();
+ }
+ } else {
+ return getParent().solveSymbolAsValue(name, typeSolver);
+ }
+ }
+
+ public SymbolReference<ResolvedFieldDeclaration> solveField(String name, TypeSolver typeSolver) {
+ Collection<ResolvedReferenceTypeDeclaration> rrtds = findTypeDeclarations(Optional.of(wrappedNode.getScope()), typeSolver);
+ for (ResolvedReferenceTypeDeclaration rrtd : rrtds) {
+ try {
+ return SymbolReference.solved(rrtd.getField(wrappedNode.getName().getId()));
+ } catch (Throwable t) {
+ }
+ }
+ return SymbolReference.unsolved(ResolvedFieldDeclaration.class);
+ }
+}
diff --git a/javaparser-symbol-solver-core/src/main/java/com/github/javaparser/symbolsolver/javaparsermodel/contexts/ForStatementContext.java b/javaparser-symbol-solver-core/src/main/java/com/github/javaparser/symbolsolver/javaparsermodel/contexts/ForStatementContext.java
new file mode 100644
index 000000000..cf3fe3b0c
--- /dev/null
+++ b/javaparser-symbol-solver-core/src/main/java/com/github/javaparser/symbolsolver/javaparsermodel/contexts/ForStatementContext.java
@@ -0,0 +1,70 @@
+/*
+ * Copyright 2016 Federico Tomassetti
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.github.javaparser.symbolsolver.javaparsermodel.contexts;
+
+import com.github.javaparser.ast.body.VariableDeclarator;
+import com.github.javaparser.ast.expr.AssignExpr;
+import com.github.javaparser.ast.expr.Expression;
+import com.github.javaparser.ast.expr.MethodCallExpr;
+import com.github.javaparser.ast.expr.VariableDeclarationExpr;
+import com.github.javaparser.ast.nodeTypes.NodeWithStatements;
+import com.github.javaparser.ast.stmt.ForStmt;
+import com.github.javaparser.resolution.declarations.ResolvedMethodDeclaration;
+import com.github.javaparser.resolution.declarations.ResolvedValueDeclaration;
+import com.github.javaparser.resolution.types.ResolvedType;
+import com.github.javaparser.symbolsolver.javaparsermodel.declarations.JavaParserSymbolDeclaration;
+import com.github.javaparser.symbolsolver.model.resolution.SymbolReference;
+import com.github.javaparser.symbolsolver.model.resolution.TypeSolver;
+
+import java.util.List;
+
+import static com.github.javaparser.symbolsolver.javaparser.Navigator.requireParentNode;
+
+public class ForStatementContext extends AbstractJavaParserContext<ForStmt> {
+
+ public ForStatementContext(ForStmt wrappedNode, TypeSolver typeSolver) {
+ super(wrappedNode, typeSolver);
+ }
+
+ @Override
+ public SymbolReference<? extends ResolvedValueDeclaration> solveSymbol(String name, TypeSolver typeSolver) {
+ for (Expression expression : wrappedNode.getInitialization()) {
+ if (expression instanceof VariableDeclarationExpr) {
+ VariableDeclarationExpr variableDeclarationExpr = (VariableDeclarationExpr) expression;
+ for (VariableDeclarator variableDeclarator : variableDeclarationExpr.getVariables()) {
+ if (variableDeclarator.getName().getId().equals(name)) {
+ return SymbolReference.solved(JavaParserSymbolDeclaration.localVar(variableDeclarator, typeSolver));
+ }
+ }
+ } else if (!(expression instanceof AssignExpr || expression instanceof MethodCallExpr)) {
+ throw new UnsupportedOperationException(expression.getClass().getCanonicalName());
+ }
+ }
+
+ if (requireParentNode(wrappedNode) instanceof NodeWithStatements) {
+ return StatementContext.solveInBlock(name, typeSolver, wrappedNode);
+ } else {
+ return getParent().solveSymbol(name, typeSolver);
+ }
+ }
+
+ @Override
+ public SymbolReference<ResolvedMethodDeclaration> solveMethod(String name, List<ResolvedType> argumentsTypes,
+ boolean staticOnly, TypeSolver typeSolver) {
+ return getParent().solveMethod(name, argumentsTypes, false, typeSolver);
+ }
+}
diff --git a/javaparser-symbol-solver-core/src/main/java/com/github/javaparser/symbolsolver/javaparsermodel/contexts/ForechStatementContext.java b/javaparser-symbol-solver-core/src/main/java/com/github/javaparser/symbolsolver/javaparsermodel/contexts/ForechStatementContext.java
new file mode 100644
index 000000000..ba412023d
--- /dev/null
+++ b/javaparser-symbol-solver-core/src/main/java/com/github/javaparser/symbolsolver/javaparsermodel/contexts/ForechStatementContext.java
@@ -0,0 +1,61 @@
+/*
+ * Copyright 2016 Federico Tomassetti
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.github.javaparser.symbolsolver.javaparsermodel.contexts;
+
+import com.github.javaparser.ast.body.VariableDeclarator;
+import com.github.javaparser.ast.stmt.BlockStmt;
+import com.github.javaparser.ast.stmt.ForeachStmt;
+import com.github.javaparser.resolution.declarations.ResolvedMethodDeclaration;
+import com.github.javaparser.resolution.declarations.ResolvedValueDeclaration;
+import com.github.javaparser.resolution.types.ResolvedType;
+import com.github.javaparser.symbolsolver.javaparsermodel.declarations.JavaParserSymbolDeclaration;
+import com.github.javaparser.symbolsolver.model.resolution.SymbolReference;
+import com.github.javaparser.symbolsolver.model.resolution.TypeSolver;
+
+import java.util.List;
+
+import static com.github.javaparser.symbolsolver.javaparser.Navigator.requireParentNode;
+
+public class ForechStatementContext extends AbstractJavaParserContext<ForeachStmt> {
+
+ public ForechStatementContext(ForeachStmt wrappedNode, TypeSolver typeSolver) {
+ super(wrappedNode, typeSolver);
+ }
+
+ @Override
+ public SymbolReference<? extends ResolvedValueDeclaration> solveSymbol(String name, TypeSolver typeSolver) {
+ if (wrappedNode.getVariable().getVariables().size() != 1) {
+ throw new IllegalStateException();
+ }
+ VariableDeclarator variableDeclarator = wrappedNode.getVariable().getVariables().get(0);
+ if (variableDeclarator.getName().getId().equals(name)) {
+ return SymbolReference.solved(JavaParserSymbolDeclaration.localVar(variableDeclarator, typeSolver));
+ } else {
+ if (requireParentNode(wrappedNode) instanceof BlockStmt) {
+ return StatementContext.solveInBlock(name, typeSolver, wrappedNode);
+ } else {
+ return getParent().solveSymbol(name, typeSolver);
+ }
+ }
+ }
+
+ @Override
+ public SymbolReference<ResolvedMethodDeclaration> solveMethod(String name, List<ResolvedType> argumentsTypes,
+ boolean staticOnly, TypeSolver typeSolver) {
+ return getParent().solveMethod(name, argumentsTypes, false, typeSolver);
+ }
+}
diff --git a/javaparser-symbol-solver-core/src/main/java/com/github/javaparser/symbolsolver/javaparsermodel/contexts/JavaParserTypeDeclarationAdapter.java b/javaparser-symbol-solver-core/src/main/java/com/github/javaparser/symbolsolver/javaparsermodel/contexts/JavaParserTypeDeclarationAdapter.java
new file mode 100644
index 000000000..993f42d29
--- /dev/null
+++ b/javaparser-symbol-solver-core/src/main/java/com/github/javaparser/symbolsolver/javaparsermodel/contexts/JavaParserTypeDeclarationAdapter.java
@@ -0,0 +1,133 @@
+package com.github.javaparser.symbolsolver.javaparsermodel.contexts;
+
+import com.github.javaparser.ast.body.BodyDeclaration;
+import com.github.javaparser.ast.nodeTypes.NodeWithTypeParameters;
+import com.github.javaparser.ast.type.TypeParameter;
+import com.github.javaparser.resolution.declarations.*;
+import com.github.javaparser.resolution.types.ResolvedReferenceType;
+import com.github.javaparser.resolution.types.ResolvedType;
+import com.github.javaparser.symbolsolver.core.resolution.Context;
+import com.github.javaparser.symbolsolver.javaparsermodel.JavaParserFacade;
+import com.github.javaparser.symbolsolver.javaparsermodel.JavaParserFactory;
+import com.github.javaparser.symbolsolver.javaparsermodel.declarations.JavaParserTypeParameter;
+import com.github.javaparser.symbolsolver.model.resolution.SymbolReference;
+import com.github.javaparser.symbolsolver.model.resolution.TypeSolver;
+import com.github.javaparser.symbolsolver.reflectionmodel.*;
+import com.github.javaparser.symbolsolver.resolution.ConstructorResolutionLogic;
+import com.github.javaparser.symbolsolver.resolution.MethodResolutionLogic;
+
+import java.util.List;
+import java.util.stream.Collectors;
+
+/**
+ * @author Federico Tomassetti
+ */
+public class JavaParserTypeDeclarationAdapter {
+
+ private com.github.javaparser.ast.body.TypeDeclaration<?> wrappedNode;
+ private TypeSolver typeSolver;
+ private Context context;
+ private ResolvedReferenceTypeDeclaration typeDeclaration;
+
+ public JavaParserTypeDeclarationAdapter(com.github.javaparser.ast.body.TypeDeclaration<?> wrappedNode, TypeSolver typeSolver,
+ ResolvedReferenceTypeDeclaration typeDeclaration,
+ Context context) {
+ this.wrappedNode = wrappedNode;
+ this.typeSolver = typeSolver;
+ this.typeDeclaration = typeDeclaration;
+ this.context = context;
+ }
+
+ public SymbolReference<ResolvedTypeDeclaration> solveType(String name, TypeSolver typeSolver) {
+ if (this.wrappedNode.getName().getId().equals(name)) {
+ return SymbolReference.solved(JavaParserFacade.get(typeSolver).getTypeDeclaration(wrappedNode));
+ }
+
+ // Internal classes
+ for (BodyDeclaration<?> member : this.wrappedNode.getMembers()) {
+ if (member instanceof com.github.javaparser.ast.body.TypeDeclaration) {
+ com.github.javaparser.ast.body.TypeDeclaration<?> internalType = (com.github.javaparser.ast.body.TypeDeclaration<?>) member;
+ if (internalType.getName().getId().equals(name)) {
+ return SymbolReference.solved(JavaParserFacade.get(typeSolver).getTypeDeclaration(internalType));
+ } else if (name.startsWith(String.format("%s.%s", wrappedNode.getName(), internalType.getName()))) {
+ return JavaParserFactory.getContext(internalType, typeSolver).solveType(name.substring(wrappedNode.getName().getId().length() + 1), typeSolver);
+ } else if (name.startsWith(String.format("%s.", internalType.getName()))) {
+ return JavaParserFactory.getContext(internalType, typeSolver).solveType(name.substring(internalType.getName().getId().length() + 1), typeSolver);
+ }
+ }
+ }
+
+ if (wrappedNode instanceof NodeWithTypeParameters) {
+ NodeWithTypeParameters<?> nodeWithTypeParameters = (NodeWithTypeParameters<?>) wrappedNode;
+ for (TypeParameter astTpRaw : nodeWithTypeParameters.getTypeParameters()) {
+ TypeParameter astTp = astTpRaw;
+ if (astTp.getName().getId().equals(name)) {
+ return SymbolReference.solved(new JavaParserTypeParameter(astTp, typeSolver));
+ }
+ }
+ }
+
+ // Look into extended classes and implemented interfaces
+ for (ResolvedReferenceType ancestor : this.typeDeclaration.getAncestors()) {
+ try {
+ for (ResolvedTypeDeclaration internalTypeDeclaration : ancestor.getTypeDeclaration().internalTypes()) {
+ if (internalTypeDeclaration.getName().equals(name)) {
+ return SymbolReference.solved(internalTypeDeclaration);
+ }
+ }
+ } catch (UnsupportedOperationException e) {
+ // just continue using the next ancestor
+ }
+ }
+
+ return context.getParent().solveType(name, typeSolver);
+ }
+
+ public SymbolReference<ResolvedMethodDeclaration> solveMethod(String name, List<ResolvedType> argumentsTypes, boolean staticOnly, TypeSolver typeSolver) {
+ List<ResolvedMethodDeclaration> candidateMethods = typeDeclaration.getDeclaredMethods().stream()
+ .filter(m -> m.getName().equals(name))
+ .filter(m -> !staticOnly || (staticOnly && m.isStatic()))
+ .collect(Collectors.toList());
+ // We want to avoid infinite recursion in case of Object having Object as ancestor
+ if (!Object.class.getCanonicalName().equals(typeDeclaration.getQualifiedName())) {
+ for (ResolvedReferenceType ancestor : typeDeclaration.getAncestors()) {
+ // Avoid recursion on self
+ if (typeDeclaration != ancestor.getTypeDeclaration()) {
+ SymbolReference<ResolvedMethodDeclaration> res = MethodResolutionLogic
+ .solveMethodInType(ancestor.getTypeDeclaration(), name, argumentsTypes, staticOnly, typeSolver);
+ // consider methods from superclasses and only default methods from interfaces :
+ // not true, we should keep abstract as a valid candidate
+ // abstract are removed in MethodResolutionLogic.isApplicable is necessary
+ if (res.isSolved()) {
+ candidateMethods.add(res.getCorrespondingDeclaration());
+ }
+ }
+ }
+ }
+ // We want to avoid infinite recursion when a class is using its own method
+ // see issue #75
+ if (candidateMethods.isEmpty()) {
+ SymbolReference<ResolvedMethodDeclaration> parentSolution = context.getParent().solveMethod(name, argumentsTypes, staticOnly, typeSolver);
+ if (parentSolution.isSolved()) {
+ candidateMethods.add(parentSolution.getCorrespondingDeclaration());
+ }
+ }
+
+ // if is interface and candidate method list is empty, we should check the Object Methods
+ if (candidateMethods.isEmpty() && typeDeclaration.isInterface()) {
+ SymbolReference<ResolvedMethodDeclaration> res = MethodResolutionLogic.solveMethodInType(new ReflectionClassDeclaration(Object.class, typeSolver), name, argumentsTypes, false, typeSolver);
+ if (res.isSolved()) {
+ candidateMethods.add(res.getCorrespondingDeclaration());
+ }
+ }
+
+ return MethodResolutionLogic.findMostApplicable(candidateMethods, name, argumentsTypes, typeSolver);
+ }
+
+ public SymbolReference<ResolvedConstructorDeclaration> solveConstructor(List<ResolvedType> argumentsTypes, TypeSolver typeSolver) {
+ if (typeDeclaration instanceof ResolvedClassDeclaration) {
+ return ConstructorResolutionLogic.findMostApplicable(((ResolvedClassDeclaration) typeDeclaration).getConstructors(), argumentsTypes, typeSolver);
+ }
+ return SymbolReference.unsolved(ResolvedConstructorDeclaration.class);
+ }
+}
diff --git a/javaparser-symbol-solver-core/src/main/java/com/github/javaparser/symbolsolver/javaparsermodel/contexts/LambdaExprContext.java b/javaparser-symbol-solver-core/src/main/java/com/github/javaparser/symbolsolver/javaparsermodel/contexts/LambdaExprContext.java
new file mode 100644
index 000000000..3c34facfe
--- /dev/null
+++ b/javaparser-symbol-solver-core/src/main/java/com/github/javaparser/symbolsolver/javaparsermodel/contexts/LambdaExprContext.java
@@ -0,0 +1,193 @@
+/*
+ * Copyright 2016 Federico Tomassetti
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.github.javaparser.symbolsolver.javaparsermodel.contexts;
+
+import com.github.javaparser.ast.body.Parameter;
+import com.github.javaparser.ast.body.VariableDeclarator;
+import com.github.javaparser.ast.expr.Expression;
+import com.github.javaparser.ast.expr.LambdaExpr;
+import com.github.javaparser.ast.expr.MethodCallExpr;
+import com.github.javaparser.resolution.MethodUsage;
+import com.github.javaparser.resolution.declarations.ResolvedMethodDeclaration;
+import com.github.javaparser.resolution.declarations.ResolvedTypeDeclaration;
+import com.github.javaparser.resolution.declarations.ResolvedTypeParameterDeclaration;
+import com.github.javaparser.resolution.declarations.ResolvedValueDeclaration;
+import com.github.javaparser.resolution.types.ResolvedLambdaConstraintType;
+import com.github.javaparser.resolution.types.ResolvedType;
+import com.github.javaparser.symbolsolver.javaparsermodel.JavaParserFacade;
+import com.github.javaparser.symbolsolver.javaparsermodel.JavaParserFactory;
+import com.github.javaparser.symbolsolver.logic.FunctionalInterfaceLogic;
+import com.github.javaparser.symbolsolver.logic.InferenceContext;
+import com.github.javaparser.symbolsolver.model.resolution.SymbolReference;
+import com.github.javaparser.symbolsolver.model.resolution.TypeSolver;
+import com.github.javaparser.symbolsolver.model.resolution.Value;
+import com.github.javaparser.symbolsolver.model.typesystem.ReferenceTypeImpl;
+import com.github.javaparser.symbolsolver.reflectionmodel.MyObjectProvider;
+import com.github.javaparser.symbolsolver.resolution.SymbolDeclarator;
+
+import java.util.*;
+
+import static com.github.javaparser.symbolsolver.javaparser.Navigator.requireParentNode;
+
+/**
+ * @author Federico Tomassetti
+ */
+public class LambdaExprContext extends AbstractJavaParserContext<LambdaExpr> {
+
+ public LambdaExprContext(LambdaExpr wrappedNode, TypeSolver typeSolver) {
+ super(wrappedNode, typeSolver);
+ }
+
+ @Override
+ public Optional<Value> solveSymbolAsValue(String name, TypeSolver typeSolver) {
+ for (Parameter parameter : wrappedNode.getParameters()) {
+ SymbolDeclarator sb = JavaParserFactory.getSymbolDeclarator(parameter, typeSolver);
+ int index = 0;
+ for (ResolvedValueDeclaration decl : sb.getSymbolDeclarations()) {
+ if (decl.getName().equals(name)) {
+ if (requireParentNode(wrappedNode) instanceof MethodCallExpr) {
+ MethodCallExpr methodCallExpr = (MethodCallExpr) requireParentNode(wrappedNode);
+ MethodUsage methodUsage = JavaParserFacade.get(typeSolver).solveMethodAsUsage(methodCallExpr);
+ int i = pos(methodCallExpr, wrappedNode);
+ ResolvedType lambdaType = methodUsage.getParamTypes().get(i);
+
+ // Get the functional method in order for us to resolve it's type arguments properly
+ Optional<MethodUsage> functionalMethodOpt = FunctionalInterfaceLogic.getFunctionalMethod(lambdaType);
+ if (functionalMethodOpt.isPresent()){
+ MethodUsage functionalMethod = functionalMethodOpt.get();
+ InferenceContext inferenceContext = new InferenceContext(MyObjectProvider.INSTANCE);
+
+ // Resolve each type variable of the lambda, and use this later to infer the type of each
+ // implicit parameter
+ inferenceContext.addPair(lambdaType, new ReferenceTypeImpl(lambdaType.asReferenceType().getTypeDeclaration(), typeSolver));
+
+ // Find the position of this lambda argument
+ boolean found = false;
+ int lambdaParamIndex;
+ for (lambdaParamIndex = 0; lambdaParamIndex < wrappedNode.getParameters().size(); lambdaParamIndex++){
+ if (wrappedNode.getParameter(lambdaParamIndex).getName().getIdentifier().equals(name)){
+ found = true;
+ break;
+ }
+ }
+ if (!found) { return Optional.empty(); }
+
+ // Now resolve the argument type using the inference context
+ ResolvedType argType = inferenceContext.resolve(inferenceContext.addSingle(functionalMethod.getParamType(lambdaParamIndex)));
+
+ ResolvedLambdaConstraintType conType;
+ if (argType.isWildcard()){
+ conType = ResolvedLambdaConstraintType.bound(argType.asWildcard().getBoundedType());
+ } else {
+ conType = ResolvedLambdaConstraintType.bound(argType);
+ }
+ Value value = new Value(conType, name);
+ return Optional.of(value);
+ } else{
+ return Optional.empty();
+ }
+ } else if (requireParentNode(wrappedNode) instanceof VariableDeclarator) {
+ VariableDeclarator variableDeclarator = (VariableDeclarator) requireParentNode(wrappedNode);
+ ResolvedType t = JavaParserFacade.get(typeSolver).convertToUsageVariableType(variableDeclarator);
+ Optional<MethodUsage> functionalMethod = FunctionalInterfaceLogic.getFunctionalMethod(t);
+ if (functionalMethod.isPresent()) {
+ ResolvedType lambdaType = functionalMethod.get().getParamType(index);
+
+ // Replace parameter from declarator
+ Map<ResolvedTypeParameterDeclaration, ResolvedType> inferredTypes = new HashMap<>();
+ if (lambdaType.isReferenceType()) {
+ for (com.github.javaparser.utils.Pair<ResolvedTypeParameterDeclaration, ResolvedType> entry : lambdaType.asReferenceType().getTypeParametersMap()) {
+ if (entry.b.isTypeVariable() && entry.b.asTypeParameter().declaredOnType()) {
+ ResolvedType ot = t.asReferenceType().typeParametersMap().getValue(entry.a);
+ lambdaType = lambdaType.replaceTypeVariables(entry.a, ot, inferredTypes);
+ }
+ }
+ } else if (lambdaType.isTypeVariable() && lambdaType.asTypeParameter().declaredOnType()) {
+ lambdaType = t.asReferenceType().typeParametersMap().getValue(lambdaType.asTypeParameter());
+ }
+
+ Value value = new Value(lambdaType, name);
+ return Optional.of(value);
+ } else {
+ throw new UnsupportedOperationException();
+ }
+ } else {
+ throw new UnsupportedOperationException();
+ }
+ }
+ index++;
+ }
+ }
+
+ // if nothing is found we should ask the parent context
+ return getParent().solveSymbolAsValue(name, typeSolver);
+ }
+
+ @Override
+ public SymbolReference<? extends ResolvedValueDeclaration> solveSymbol(String name, TypeSolver typeSolver) {
+ for (Parameter parameter : wrappedNode.getParameters()) {
+ SymbolDeclarator sb = JavaParserFactory.getSymbolDeclarator(parameter, typeSolver);
+ SymbolReference<ResolvedValueDeclaration> symbolReference = solveWith(sb, name);
+ if (symbolReference.isSolved()) {
+ return symbolReference;
+ }
+ }
+
+ // if nothing is found we should ask the parent context
+ return getParent().solveSymbol(name, typeSolver);
+ }
+
+ @Override
+ public SymbolReference<ResolvedTypeDeclaration> solveType(String name, TypeSolver typeSolver) {
+ return getParent().solveType(name, typeSolver);
+ }
+
+ @Override
+ public SymbolReference<ResolvedMethodDeclaration> solveMethod(
+ String name, List<ResolvedType> argumentsTypes, boolean staticOnly, TypeSolver typeSolver) {
+ return getParent().solveMethod(name, argumentsTypes, false, typeSolver);
+ }
+
+ ///
+ /// Protected methods
+ ///
+
+ protected final Optional<Value> solveWithAsValue(SymbolDeclarator symbolDeclarator, String name, TypeSolver typeSolver) {
+ for (ResolvedValueDeclaration decl : symbolDeclarator.getSymbolDeclarations()) {
+ if (decl.getName().equals(name)) {
+
+ throw new UnsupportedOperationException();
+ }
+ }
+ return Optional.empty();
+ }
+
+ ///
+ /// Private methods
+ ///
+
+ private int pos(MethodCallExpr callExpr, Expression param) {
+ int i = 0;
+ for (Expression p : callExpr.getArguments()) {
+ if (p == param) {
+ return i;
+ }
+ i++;
+ }
+ throw new IllegalArgumentException();
+ }
+}
diff --git a/javaparser-symbol-solver-core/src/main/java/com/github/javaparser/symbolsolver/javaparsermodel/contexts/MethodCallExprContext.java b/javaparser-symbol-solver-core/src/main/java/com/github/javaparser/symbolsolver/javaparsermodel/contexts/MethodCallExprContext.java
new file mode 100644
index 000000000..ca9f07c42
--- /dev/null
+++ b/javaparser-symbol-solver-core/src/main/java/com/github/javaparser/symbolsolver/javaparsermodel/contexts/MethodCallExprContext.java
@@ -0,0 +1,433 @@
+/*
+ * Copyright 2016 Federico Tomassetti
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.github.javaparser.symbolsolver.javaparsermodel.contexts;
+
+import com.github.javaparser.ast.expr.Expression;
+import com.github.javaparser.ast.expr.MethodCallExpr;
+import com.github.javaparser.ast.expr.NameExpr;
+import com.github.javaparser.resolution.MethodUsage;
+import com.github.javaparser.resolution.UnsolvedSymbolException;
+import com.github.javaparser.resolution.declarations.*;
+import com.github.javaparser.resolution.types.*;
+import com.github.javaparser.symbolsolver.core.resolution.Context;
+import com.github.javaparser.symbolsolver.javaparsermodel.JavaParserFacade;
+import com.github.javaparser.symbolsolver.model.resolution.SymbolReference;
+import com.github.javaparser.symbolsolver.model.resolution.TypeSolver;
+import com.github.javaparser.symbolsolver.model.resolution.Value;
+import com.github.javaparser.symbolsolver.model.typesystem.*;
+import com.github.javaparser.symbolsolver.reflectionmodel.ReflectionClassDeclaration;
+import com.github.javaparser.symbolsolver.resolution.MethodResolutionLogic;
+import com.github.javaparser.utils.Pair;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.Optional;
+
+public class MethodCallExprContext extends AbstractJavaParserContext<MethodCallExpr> {
+
+ ///
+ /// Constructors
+ ///
+
+ public MethodCallExprContext(MethodCallExpr wrappedNode, TypeSolver typeSolver) {
+ super(wrappedNode, typeSolver);
+ }
+
+ ///
+ /// Public methods
+ ///
+
+ @Override
+ public Optional<ResolvedType> solveGenericType(String name, TypeSolver typeSolver) {
+ if(wrappedNode.getScope().isPresent()){
+ ResolvedType typeOfScope = JavaParserFacade.get(typeSolver).getType(wrappedNode.getScope().get());
+ Optional<ResolvedType> res = typeOfScope.asReferenceType().getGenericParameterByName(name);
+ return res;
+ } else{
+ return Optional.empty();
+ }
+ }
+
+ @Override
+ public String toString() {
+ return "MethodCallExprContext{wrapped=" + wrappedNode + "}";
+ }
+
+ @Override
+ public Optional<MethodUsage> solveMethodAsUsage(String name, List<ResolvedType> argumentsTypes, TypeSolver typeSolver) {
+ if (wrappedNode.getScope().isPresent()) {
+ Expression scope = wrappedNode.getScope().get();
+ // Consider static method calls
+ if (scope instanceof NameExpr) {
+ String className = ((NameExpr) scope).getName().getId();
+ SymbolReference<ResolvedTypeDeclaration> ref = solveType(className, typeSolver);
+ if (ref.isSolved()) {
+ SymbolReference<ResolvedMethodDeclaration> m = MethodResolutionLogic.solveMethodInType(ref.getCorrespondingDeclaration(), name, argumentsTypes, typeSolver);
+ if (m.isSolved()) {
+ MethodUsage methodUsage = new MethodUsage(m.getCorrespondingDeclaration());
+ methodUsage = resolveMethodTypeParametersFromExplicitList(typeSolver, methodUsage);
+ methodUsage = resolveMethodTypeParameters(methodUsage, argumentsTypes);
+ return Optional.of(methodUsage);
+ } else {
+ throw new UnsolvedSymbolException(ref.getCorrespondingDeclaration().toString(),
+ "Method '" + name + "' with parameterTypes " + argumentsTypes);
+ }
+ }
+ }
+
+ ResolvedType typeOfScope = JavaParserFacade.get(typeSolver).getType(scope);
+ // we can replace the parameter types from the scope into the typeParametersValues
+
+ Map<ResolvedTypeParameterDeclaration, ResolvedType> inferredTypes = new HashMap<>();
+ for (int i = 0; i < argumentsTypes.size(); i++) {
+ // by replacing types I can also find new equivalences
+ // for example if I replace T=U with String because I know that T=String I can derive that also U equal String
+ ResolvedType originalArgumentType = argumentsTypes.get(i);
+ ResolvedType updatedArgumentType = usingParameterTypesFromScope(typeOfScope, originalArgumentType, inferredTypes);
+ argumentsTypes.set(i, updatedArgumentType);
+ }
+ for (int i = 0; i < argumentsTypes.size(); i++) {
+ ResolvedType updatedArgumentType = applyInferredTypes(argumentsTypes.get(i), inferredTypes);
+ argumentsTypes.set(i, updatedArgumentType);
+ }
+
+ return solveMethodAsUsage(typeOfScope, name, argumentsTypes, typeSolver, this);
+ } else {
+ Context parentContext = getParent();
+ while (parentContext instanceof MethodCallExprContext) {
+ parentContext = parentContext.getParent();
+ }
+ return parentContext.solveMethodAsUsage(name, argumentsTypes, typeSolver);
+ }
+ }
+
+ private MethodUsage resolveMethodTypeParametersFromExplicitList(TypeSolver typeSolver, MethodUsage methodUsage) {
+ if (wrappedNode.getTypeArguments().isPresent()) {
+ final List<ResolvedType> typeArguments = new ArrayList<>();
+ for (com.github.javaparser.ast.type.Type ty : wrappedNode.getTypeArguments().get()) {
+ typeArguments.add(JavaParserFacade.get(typeSolver).convertToUsage(ty));
+ }
+
+ List<ResolvedTypeParameterDeclaration> tyParamDecls = methodUsage.getDeclaration().getTypeParameters();
+ if (tyParamDecls.size() == typeArguments.size()) {
+ for (int i = 0; i < tyParamDecls.size(); i++) {
+ methodUsage = methodUsage.replaceTypeParameter(tyParamDecls.get(i), typeArguments.get(i));
+ }
+ }
+ }
+
+ return methodUsage;
+ }
+
+ @Override
+ public SymbolReference<? extends ResolvedValueDeclaration> solveSymbol(String name, TypeSolver typeSolver) {
+ return getParent().solveSymbol(name, typeSolver);
+ }
+
+ @Override
+ public Optional<Value> solveSymbolAsValue(String name, TypeSolver typeSolver) {
+ Context parentContext = getParent();
+ return parentContext.solveSymbolAsValue(name, typeSolver);
+ }
+
+ @Override
+ public SymbolReference<ResolvedMethodDeclaration> solveMethod(String name, List<ResolvedType> argumentsTypes, boolean staticOnly, TypeSolver typeSolver) {
+ Collection<ResolvedReferenceTypeDeclaration> rrtds = findTypeDeclarations(wrappedNode.getScope(), typeSolver);
+ for (ResolvedReferenceTypeDeclaration rrtd : rrtds) {
+ SymbolReference<ResolvedMethodDeclaration> res = MethodResolutionLogic.solveMethodInType(rrtd, name, argumentsTypes, false, typeSolver);
+ if (res.isSolved()) {
+ return res;
+ }
+ }
+ return SymbolReference.unsolved(ResolvedMethodDeclaration.class);
+ }
+
+ ///
+ /// Private methods
+ ///
+
+ private Optional<MethodUsage> solveMethodAsUsage(ResolvedReferenceType refType, String name,
+ List<ResolvedType> argumentsTypes, TypeSolver typeSolver,
+ Context invokationContext) {
+ Optional<MethodUsage> ref = ContextHelper.solveMethodAsUsage(refType.getTypeDeclaration(), name, argumentsTypes, typeSolver, invokationContext, refType.typeParametersValues());
+ if (ref.isPresent()) {
+ MethodUsage methodUsage = ref.get();
+
+ methodUsage = resolveMethodTypeParametersFromExplicitList(typeSolver, methodUsage);
+
+ // At this stage I should derive from the context and the value some information on the type parameters
+ // for example, when calling:
+ // myStream.collect(Collectors.toList())
+ // I should be able to figure out that considering the type of the stream (e.g., Stream<String>)
+ // and considering that Stream has this method:
+ //
+ // <R,A> R collect(Collector<? super T,A,R> collector)
+ //
+ // and collector has this method:
+ //
+ // static <T> Collector<T,?,List<T>> toList()
+ //
+ // In this case collect.R has to be equal to List<toList.T>
+ // And toList.T has to be equal to ? super Stream.T
+ // Therefore R has to be equal to List<? super Stream.T>.
+ // In our example Stream.T equal to String, so the R (and the result of the call to collect) is
+ // List<? super String>
+
+ Map<ResolvedTypeParameterDeclaration, ResolvedType> derivedValues = new HashMap<>();
+ for (int i = 0; i < methodUsage.getParamTypes().size(); i++) {
+ ResolvedParameterDeclaration parameter = methodUsage.getDeclaration().getParam(i);
+ ResolvedType parameterType = parameter.getType();
+ if (parameter.isVariadic()) {
+ parameterType = parameterType.asArrayType().getComponentType();
+ }
+ inferTypes(argumentsTypes.get(i), parameterType, derivedValues);
+ }
+
+ for (Map.Entry<ResolvedTypeParameterDeclaration, ResolvedType> entry : derivedValues.entrySet()){
+ methodUsage = methodUsage.replaceTypeParameter(entry.getKey(), entry.getValue());
+ }
+
+ ResolvedType returnType = refType.useThisTypeParametersOnTheGivenType(methodUsage.returnType());
+ if (returnType != methodUsage.returnType()) {
+ methodUsage = methodUsage.replaceReturnType(returnType);
+ }
+ for (int i = 0; i < methodUsage.getParamTypes().size(); i++) {
+ ResolvedType replaced = refType.useThisTypeParametersOnTheGivenType(methodUsage.getParamTypes().get(i));
+ methodUsage = methodUsage.replaceParamType(i, replaced);
+ }
+ return Optional.of(methodUsage);
+ } else {
+ return ref;
+ }
+ }
+
+ private void inferTypes(ResolvedType source, ResolvedType target, Map<ResolvedTypeParameterDeclaration, ResolvedType> mappings) {
+ if (source.equals(target)) {
+ return;
+ }
+ if (source.isReferenceType() && target.isReferenceType()) {
+ ResolvedReferenceType sourceRefType = source.asReferenceType();
+ ResolvedReferenceType targetRefType = target.asReferenceType();
+ if (sourceRefType.getQualifiedName().equals(targetRefType.getQualifiedName())) {
+ if (!sourceRefType.isRawType() && !targetRefType.isRawType()) {
+ for (int i = 0; i < sourceRefType.typeParametersValues().size(); i++) {
+ inferTypes(sourceRefType.typeParametersValues().get(i), targetRefType.typeParametersValues().get(i), mappings);
+ }
+ }
+ }
+ return;
+ }
+ if (source.isReferenceType() && target.isWildcard()) {
+ if (target.asWildcard().isBounded()) {
+ inferTypes(source, target.asWildcard().getBoundedType(), mappings);
+ return;
+ }
+ return;
+ }
+ if (source.isWildcard() && target.isWildcard()) {
+ if (source.asWildcard().isBounded() && target.asWildcard().isBounded()){
+ inferTypes(source.asWildcard().getBoundedType(), target.asWildcard().getBoundedType(), mappings);
+ }
+ return;
+ }
+ if (source.isReferenceType() && target.isTypeVariable()) {
+ mappings.put(target.asTypeParameter(), source);
+ return;
+ }
+ if (source.isWildcard() && target.isTypeVariable()) {
+ mappings.put(target.asTypeParameter(), source);
+ return;
+ }
+ if (source.isArray() && target.isWildcard()){
+ if(target.asWildcard().isBounded()){
+ inferTypes(source, target.asWildcard().getBoundedType(), mappings);
+ return;
+ }
+ return;
+ }
+ if (source.isArray() && target.isTypeVariable()) {
+ mappings.put(target.asTypeParameter(), source);
+ return;
+ }
+
+ if (source.isWildcard() && target.isReferenceType()){
+ if (source.asWildcard().isBounded()){
+ inferTypes(source.asWildcard().getBoundedType(), target, mappings);
+ }
+ return;
+ }
+ if (source.isConstraint() && target.isReferenceType()){
+ inferTypes(source.asConstraintType().getBound(), target, mappings);
+ return;
+ }
+
+ if (source.isConstraint() && target.isTypeVariable()){
+ inferTypes(source.asConstraintType().getBound(), target, mappings);
+ return;
+ }
+ if (source.isTypeVariable() && target.isTypeVariable()) {
+ mappings.put(target.asTypeParameter(), source);
+ return;
+ }
+ if (source.isPrimitive() || target.isPrimitive()) {
+ return;
+ }
+ if (source.isNull()) {
+ return;
+ }
+ throw new RuntimeException(source.describe() + " " + target.describe());
+ }
+
+ private MethodUsage resolveMethodTypeParameters(MethodUsage methodUsage, List<ResolvedType> actualParamTypes) {
+ Map<ResolvedTypeParameterDeclaration, ResolvedType> matchedTypeParameters = new HashMap<>();
+
+ if (methodUsage.getDeclaration().hasVariadicParameter()) {
+ if (actualParamTypes.size() == methodUsage.getDeclaration().getNumberOfParams()) {
+ // the varargs parameter is an Array, so extract the inner type
+ ResolvedType expectedType =
+ methodUsage.getDeclaration().getLastParam().getType().asArrayType().getComponentType();
+ // the varargs corresponding type can be either T or Array<T>
+ ResolvedType actualType =
+ actualParamTypes.get(actualParamTypes.size() - 1).isArray() ?
+ actualParamTypes.get(actualParamTypes.size() - 1).asArrayType().getComponentType() :
+ actualParamTypes.get(actualParamTypes.size() - 1);
+ if (!expectedType.isAssignableBy(actualType)) {
+ for (ResolvedTypeParameterDeclaration tp : methodUsage.getDeclaration().getTypeParameters()) {
+ expectedType = MethodResolutionLogic.replaceTypeParam(expectedType, tp, typeSolver);
+ }
+ }
+ if (!expectedType.isAssignableBy(actualType)) {
+ // ok, then it needs to be wrapped
+ throw new UnsupportedOperationException(
+ String.format("Unable to resolve the type typeParametersValues in a MethodUsage. Expected type: %s, Actual type: %s. Method Declaration: %s. MethodUsage: %s",
+ expectedType,
+ actualType,
+ methodUsage.getDeclaration(),
+ methodUsage));
+ }
+ // match only the varargs type
+ matchTypeParameters(expectedType, actualType, matchedTypeParameters);
+ } else {
+ return methodUsage;
+ }
+ }
+
+ int until = methodUsage.getDeclaration().hasVariadicParameter() ?
+ actualParamTypes.size() - 1 :
+ actualParamTypes.size();
+
+ for (int i = 0; i < until; i++) {
+ ResolvedType expectedType = methodUsage.getParamType(i);
+ ResolvedType actualType = actualParamTypes.get(i);
+ matchTypeParameters(expectedType, actualType, matchedTypeParameters);
+ }
+ for (ResolvedTypeParameterDeclaration tp : matchedTypeParameters.keySet()) {
+ methodUsage = methodUsage.replaceTypeParameter(tp, matchedTypeParameters.get(tp));
+ }
+ return methodUsage;
+ }
+
+ private void matchTypeParameters(ResolvedType expectedType, ResolvedType actualType, Map<ResolvedTypeParameterDeclaration, ResolvedType> matchedTypeParameters) {
+ if (expectedType.isTypeVariable()) {
+ if (!actualType.isTypeVariable() && !actualType.isReferenceType()) {
+ throw new UnsupportedOperationException(actualType.getClass().getCanonicalName());
+ }
+ matchedTypeParameters.put(expectedType.asTypeParameter(), actualType);
+ } else if (expectedType.isArray()) {
+ if (!actualType.isArray()) {
+ throw new UnsupportedOperationException(actualType.getClass().getCanonicalName());
+ }
+ matchTypeParameters(
+ expectedType.asArrayType().getComponentType(),
+ actualType.asArrayType().getComponentType(),
+ matchedTypeParameters);
+ } else if (expectedType.isReferenceType()) {
+ // avoid cases where the actual type has no type parameters but the expected one has. Such as: "classX extends classY<Integer>"
+ if (actualType.isReferenceType() && actualType.asReferenceType().typeParametersValues().size() > 0) {
+ int i = 0;
+ for (ResolvedType tp : expectedType.asReferenceType().typeParametersValues()) {
+ matchTypeParameters(tp, actualType.asReferenceType().typeParametersValues().get(i), matchedTypeParameters);
+ i++;
+ }
+ }
+ } else if (expectedType.isPrimitive()) {
+ // nothing to do
+ } else if (expectedType.isWildcard()) {
+ // nothing to do
+ } else {
+ throw new UnsupportedOperationException(expectedType.getClass().getCanonicalName());
+ }
+ }
+
+ private Optional<MethodUsage> solveMethodAsUsage(ResolvedTypeVariable tp, String name, List<ResolvedType> argumentsTypes, TypeSolver typeSolver, Context invokationContext) {
+ for (ResolvedTypeParameterDeclaration.Bound bound : tp.asTypeParameter().getBounds()) {
+ Optional<MethodUsage> methodUsage = solveMethodAsUsage(bound.getType(), name, argumentsTypes, typeSolver, invokationContext);
+ if (methodUsage.isPresent()) {
+ return methodUsage;
+ }
+ }
+ return Optional.empty();
+ }
+
+ private Optional<MethodUsage> solveMethodAsUsage(ResolvedType type, String name, List<ResolvedType> argumentsTypes, TypeSolver typeSolver, Context invokationContext) {
+ if (type instanceof ResolvedReferenceType) {
+ return solveMethodAsUsage((ResolvedReferenceType) type, name, argumentsTypes, typeSolver, invokationContext);
+ } else if (type instanceof ResolvedTypeVariable) {
+ return solveMethodAsUsage((ResolvedTypeVariable) type, name, argumentsTypes, typeSolver, invokationContext);
+ } else if (type instanceof ResolvedWildcard) {
+ ResolvedWildcard wildcardUsage = (ResolvedWildcard) type;
+ if (wildcardUsage.isSuper()) {
+ return solveMethodAsUsage(wildcardUsage.getBoundedType(), name, argumentsTypes, typeSolver, invokationContext);
+ } else if (wildcardUsage.isExtends()) {
+ throw new UnsupportedOperationException("extends wildcard");
+ } else {
+ throw new UnsupportedOperationException("unbounded wildcard");
+ }
+ } else if (type instanceof ResolvedLambdaConstraintType){
+ ResolvedLambdaConstraintType constraintType = (ResolvedLambdaConstraintType) type;
+ return solveMethodAsUsage(constraintType.getBound(), name, argumentsTypes, typeSolver, invokationContext);
+ } else if (type instanceof ResolvedArrayType) {
+ // An array inherits methods from Object not from it's component type
+ return solveMethodAsUsage(new ReferenceTypeImpl(new ReflectionClassDeclaration(Object.class, typeSolver), typeSolver), name, argumentsTypes, typeSolver, invokationContext);
+ } else {
+ throw new UnsupportedOperationException("type usage: " + type.getClass().getCanonicalName());
+ }
+ }
+
+ private ResolvedType usingParameterTypesFromScope(ResolvedType scope, ResolvedType type, Map<ResolvedTypeParameterDeclaration, ResolvedType> inferredTypes) {
+ if (type.isReferenceType()) {
+ for (Pair<ResolvedTypeParameterDeclaration, ResolvedType> entry : type.asReferenceType().getTypeParametersMap()) {
+ if (entry.a.declaredOnType() && scope.asReferenceType().getGenericParameterByName(entry.a.getName()).isPresent()) {
+ type = type.replaceTypeVariables(entry.a, scope.asReferenceType().getGenericParameterByName(entry.a.getName()).get(), inferredTypes);
+ }
+ }
+ return type;
+ } else {
+ return type;
+ }
+ }
+
+ private ResolvedType applyInferredTypes(ResolvedType type, Map<ResolvedTypeParameterDeclaration, ResolvedType> inferredTypes) {
+ for (ResolvedTypeParameterDeclaration tp : inferredTypes.keySet()) {
+ type = type.replaceTypeVariables(tp, inferredTypes.get(tp), inferredTypes);
+ }
+ return type;
+ }
+}
diff --git a/javaparser-symbol-solver-core/src/main/java/com/github/javaparser/symbolsolver/javaparsermodel/contexts/MethodContext.java b/javaparser-symbol-solver-core/src/main/java/com/github/javaparser/symbolsolver/javaparsermodel/contexts/MethodContext.java
new file mode 100644
index 000000000..9a7530b18
--- /dev/null
+++ b/javaparser-symbol-solver-core/src/main/java/com/github/javaparser/symbolsolver/javaparsermodel/contexts/MethodContext.java
@@ -0,0 +1,35 @@
+/*
+ * Copyright 2016 Federico Tomassetti
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.github.javaparser.symbolsolver.javaparsermodel.contexts;
+
+import com.github.javaparser.ast.body.MethodDeclaration;
+import com.github.javaparser.symbolsolver.model.resolution.TypeSolver;
+
+/**
+ * @author Federico Tomassetti
+ */
+public class MethodContext extends AbstractMethodLikeDeclarationContext<MethodDeclaration> {
+
+ ///
+ /// Constructors
+ ///
+
+ public MethodContext(MethodDeclaration wrappedNode, TypeSolver typeSolver) {
+ super(wrappedNode, typeSolver);
+ }
+
+}
diff --git a/javaparser-symbol-solver-core/src/main/java/com/github/javaparser/symbolsolver/javaparsermodel/contexts/StatementContext.java b/javaparser-symbol-solver-core/src/main/java/com/github/javaparser/symbolsolver/javaparsermodel/contexts/StatementContext.java
new file mode 100644
index 000000000..8acab7a8a
--- /dev/null
+++ b/javaparser-symbol-solver-core/src/main/java/com/github/javaparser/symbolsolver/javaparsermodel/contexts/StatementContext.java
@@ -0,0 +1,200 @@
+/*
+ * Copyright 2016 Federico Tomassetti
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.github.javaparser.symbolsolver.javaparsermodel.contexts;
+
+import com.github.javaparser.ast.expr.LambdaExpr;
+import com.github.javaparser.ast.nodeTypes.NodeWithStatements;
+import com.github.javaparser.ast.stmt.IfStmt;
+import com.github.javaparser.ast.stmt.Statement;
+import com.github.javaparser.resolution.declarations.ResolvedMethodDeclaration;
+import com.github.javaparser.resolution.declarations.ResolvedTypeDeclaration;
+import com.github.javaparser.resolution.declarations.ResolvedValueDeclaration;
+import com.github.javaparser.resolution.types.ResolvedType;
+import com.github.javaparser.symbolsolver.core.resolution.Context;
+import com.github.javaparser.symbolsolver.javaparsermodel.JavaParserFactory;
+import com.github.javaparser.symbolsolver.model.resolution.SymbolReference;
+import com.github.javaparser.symbolsolver.model.resolution.TypeSolver;
+import com.github.javaparser.symbolsolver.model.resolution.Value;
+import com.github.javaparser.symbolsolver.resolution.SymbolDeclarator;
+
+import java.util.List;
+import java.util.Optional;
+
+import static com.github.javaparser.symbolsolver.javaparser.Navigator.requireParentNode;
+
+/**
+ * @author Federico Tomassetti
+ */
+public class StatementContext<N extends Statement> extends AbstractJavaParserContext<N> {
+
+ public StatementContext(N wrappedNode, TypeSolver typeSolver) {
+ super(wrappedNode, typeSolver);
+ }
+
+ public static SymbolReference<? extends ResolvedValueDeclaration> solveInBlock(String name, TypeSolver typeSolver, Statement stmt) {
+ if (!(requireParentNode(stmt) instanceof NodeWithStatements)) {
+ throw new IllegalArgumentException();
+ }
+ NodeWithStatements<?> blockStmt = (NodeWithStatements<?>) requireParentNode(stmt);
+ int position = -1;
+ for (int i = 0; i < blockStmt.getStatements().size(); i++) {
+ if (blockStmt.getStatements().get(i).equals(stmt)) {
+ position = i;
+ }
+ }
+ if (position == -1) {
+ throw new RuntimeException();
+ }
+ for (int i = position - 1; i >= 0; i--) {
+ SymbolDeclarator symbolDeclarator = JavaParserFactory.getSymbolDeclarator(blockStmt.getStatements().get(i), typeSolver);
+ SymbolReference<? extends ResolvedValueDeclaration> symbolReference = solveWith(symbolDeclarator, name);
+ if (symbolReference.isSolved()) {
+ return symbolReference;
+ }
+ }
+
+ // if nothing is found we should ask the parent context
+ return JavaParserFactory.getContext(requireParentNode(stmt), typeSolver).solveSymbol(name, typeSolver);
+ }
+
+ public static Optional<Value> solveInBlockAsValue(String name, TypeSolver typeSolver, Statement stmt) {
+ if (!(requireParentNode(stmt) instanceof NodeWithStatements)) {
+ throw new IllegalArgumentException();
+ }
+ NodeWithStatements<?> blockStmt = (NodeWithStatements<?>) requireParentNode(stmt);
+ int position = -1;
+ for (int i = 0; i < blockStmt.getStatements().size(); i++) {
+ if (blockStmt.getStatements().get(i).equals(stmt)) {
+ position = i;
+ }
+ }
+ if (position == -1) {
+ throw new RuntimeException();
+ }
+ for (int i = position - 1; i >= 0; i--) {
+ SymbolDeclarator symbolDeclarator = JavaParserFactory.getSymbolDeclarator(blockStmt.getStatements().get(i), typeSolver);
+ SymbolReference<? extends ResolvedValueDeclaration> symbolReference = solveWith(symbolDeclarator, name);
+ if (symbolReference.isSolved()) {
+ return Optional.of(Value.from(symbolReference.getCorrespondingDeclaration()));
+ }
+ }
+
+ // if nothing is found we should ask the parent context
+ return JavaParserFactory.getContext(requireParentNode(stmt), typeSolver).solveSymbolAsValue(name, typeSolver);
+ }
+
+ @Override
+ public Optional<Value> solveSymbolAsValue(String name, TypeSolver typeSolver) {
+
+ // if we're in a multiple Variable declaration line (for ex: double a=0, b=a;)
+ SymbolDeclarator symbolDeclarator = JavaParserFactory.getSymbolDeclarator(wrappedNode, typeSolver);
+ Optional<Value> symbolReference = solveWithAsValue(symbolDeclarator, name, typeSolver);
+ if (symbolReference.isPresent()) {
+ return symbolReference;
+ }
+
+ // we should look in all the statements preceding, treating them as SymbolDeclarators
+ if (requireParentNode(wrappedNode) instanceof com.github.javaparser.ast.body.MethodDeclaration) {
+ return getParent().solveSymbolAsValue(name, typeSolver);
+ }
+ if (requireParentNode(wrappedNode) instanceof LambdaExpr) {
+ return getParent().solveSymbolAsValue(name, typeSolver);
+ }
+ if (requireParentNode(wrappedNode) instanceof IfStmt) {
+ return getParent().solveSymbolAsValue(name, typeSolver);
+ }
+ if (!(requireParentNode(wrappedNode) instanceof NodeWithStatements)) {
+ return getParent().solveSymbolAsValue(name, typeSolver);
+ }
+ NodeWithStatements<?> nodeWithStmt = (NodeWithStatements<?>) requireParentNode(wrappedNode);
+ int position = -1;
+ for (int i = 0; i < nodeWithStmt.getStatements().size(); i++) {
+ if (nodeWithStmt.getStatements().get(i).equals(wrappedNode)) {
+ position = i;
+ }
+ }
+ if (position == -1) {
+ throw new RuntimeException();
+ }
+ for (int i = position - 1; i >= 0; i--) {
+ symbolDeclarator = JavaParserFactory.getSymbolDeclarator(nodeWithStmt.getStatements().get(i), typeSolver);
+ symbolReference = solveWithAsValue(symbolDeclarator, name, typeSolver);
+ if (symbolReference.isPresent()) {
+ return symbolReference;
+ }
+ }
+
+ // if nothing is found we should ask the parent context
+ Context parentContext = getParent();
+ return parentContext.solveSymbolAsValue(name, typeSolver);
+ }
+
+ @Override
+ public SymbolReference<? extends ResolvedValueDeclaration> solveSymbol(String name, TypeSolver typeSolver) {
+
+ // if we're in a multiple Variable declaration line (for ex: double a=0, b=a;)
+ SymbolDeclarator symbolDeclarator = JavaParserFactory.getSymbolDeclarator(wrappedNode, typeSolver);
+ SymbolReference<? extends ResolvedValueDeclaration> symbolReference = solveWith(symbolDeclarator, name);
+ if (symbolReference.isSolved()) {
+ return symbolReference;
+ }
+
+ // we should look in all the statements preceding, treating them as SymbolDeclarators
+ if (requireParentNode(wrappedNode) instanceof com.github.javaparser.ast.body.MethodDeclaration) {
+ return getParent().solveSymbol(name, typeSolver);
+ }
+ if (requireParentNode(wrappedNode) instanceof com.github.javaparser.ast.body.ConstructorDeclaration) {
+ return getParent().solveSymbol(name, typeSolver);
+ }
+ if (requireParentNode(wrappedNode) instanceof LambdaExpr) {
+ return getParent().solveSymbol(name, typeSolver);
+ }
+ if (!(requireParentNode(wrappedNode) instanceof NodeWithStatements)) {
+ return getParent().solveSymbol(name, typeSolver);
+ }
+ NodeWithStatements<?> nodeWithStmt = (NodeWithStatements<?>) requireParentNode(wrappedNode);
+ int position = -1;
+ for (int i = 0; i < nodeWithStmt.getStatements().size(); i++) {
+ if (nodeWithStmt.getStatements().get(i).equals(wrappedNode)) {
+ position = i;
+ }
+ }
+ if (position == -1) {
+ throw new RuntimeException();
+ }
+ for (int i = position - 1; i >= 0; i--) {
+ symbolDeclarator = JavaParserFactory.getSymbolDeclarator(nodeWithStmt.getStatements().get(i), typeSolver);
+ symbolReference = solveWith(symbolDeclarator, name);
+ if (symbolReference.isSolved()) {
+ return symbolReference;
+ }
+ }
+
+ // if nothing is found we should ask the parent context
+ return getParent().solveSymbol(name, typeSolver);
+ }
+
+ @Override
+ public SymbolReference<ResolvedMethodDeclaration> solveMethod(String name, List<ResolvedType> argumentsTypes, boolean staticOnly, TypeSolver typeSolver) {
+ return getParent().solveMethod(name, argumentsTypes, false, typeSolver);
+ }
+
+ @Override
+ public SymbolReference<ResolvedTypeDeclaration> solveType(String name, TypeSolver typeSolver) {
+ return getParent().solveType(name, typeSolver);
+ }
+}
diff --git a/javaparser-symbol-solver-core/src/main/java/com/github/javaparser/symbolsolver/javaparsermodel/contexts/SwitchEntryContext.java b/javaparser-symbol-solver-core/src/main/java/com/github/javaparser/symbolsolver/javaparsermodel/contexts/SwitchEntryContext.java
new file mode 100644
index 000000000..15967295b
--- /dev/null
+++ b/javaparser-symbol-solver-core/src/main/java/com/github/javaparser/symbolsolver/javaparsermodel/contexts/SwitchEntryContext.java
@@ -0,0 +1,80 @@
+/*
+ * Copyright 2016 Federico Tomassetti
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.github.javaparser.symbolsolver.javaparsermodel.contexts;
+
+import com.github.javaparser.ast.stmt.Statement;
+import com.github.javaparser.ast.stmt.SwitchEntryStmt;
+import com.github.javaparser.ast.stmt.SwitchStmt;
+import com.github.javaparser.resolution.declarations.ResolvedMethodDeclaration;
+import com.github.javaparser.resolution.declarations.ResolvedValueDeclaration;
+import com.github.javaparser.resolution.types.ResolvedType;
+import com.github.javaparser.symbolsolver.javaparsermodel.JavaParserFacade;
+import com.github.javaparser.symbolsolver.javaparsermodel.JavaParserFactory;
+import com.github.javaparser.symbolsolver.model.resolution.SymbolReference;
+import com.github.javaparser.symbolsolver.model.resolution.TypeSolver;
+import com.github.javaparser.symbolsolver.model.typesystem.ReferenceTypeImpl;
+import com.github.javaparser.symbolsolver.resolution.SymbolDeclarator;
+
+import java.util.List;
+
+import static com.github.javaparser.symbolsolver.javaparser.Navigator.requireParentNode;
+
+/**
+ * @author Federico Tomassetti
+ */
+public class SwitchEntryContext extends AbstractJavaParserContext<SwitchEntryStmt> {
+
+ public SwitchEntryContext(SwitchEntryStmt wrappedNode, TypeSolver typeSolver) {
+ super(wrappedNode, typeSolver);
+ }
+
+ @Override
+ public SymbolReference<? extends ResolvedValueDeclaration> solveSymbol(String name, TypeSolver typeSolver) {
+ SwitchStmt switchStmt = (SwitchStmt) requireParentNode(wrappedNode);
+ ResolvedType type = JavaParserFacade.get(typeSolver).getType(switchStmt.getSelector());
+ if (type.isReferenceType() && type.asReferenceType().getTypeDeclaration().isEnum()) {
+ if (type instanceof ReferenceTypeImpl) {
+ ReferenceTypeImpl typeUsageOfTypeDeclaration = (ReferenceTypeImpl) type;
+ if (typeUsageOfTypeDeclaration.getTypeDeclaration().hasField(name)) {
+ return SymbolReference.solved(typeUsageOfTypeDeclaration.getTypeDeclaration().getField(name));
+ }
+ } else {
+ throw new UnsupportedOperationException();
+ }
+ }
+
+ // look for declaration in other switch statements
+ for (SwitchEntryStmt seStmt : switchStmt.getEntries()) {
+ if (!seStmt.equals(wrappedNode)) {
+ for (Statement stmt : seStmt.getStatements()) {
+ SymbolDeclarator symbolDeclarator = JavaParserFactory.getSymbolDeclarator(stmt, typeSolver);
+ SymbolReference<? extends ResolvedValueDeclaration> symbolReference = solveWith(symbolDeclarator, name);
+ if (symbolReference.isSolved()) {
+ return symbolReference;
+ }
+ }
+ }
+ }
+
+ return getParent().solveSymbol(name, typeSolver);
+ }
+
+ @Override
+ public SymbolReference<ResolvedMethodDeclaration> solveMethod(String name, List<ResolvedType> argumentsTypes, boolean staticOnly, TypeSolver typeSolver) {
+ return getParent().solveMethod(name, argumentsTypes, false, typeSolver);
+ }
+}
diff --git a/javaparser-symbol-solver-core/src/main/java/com/github/javaparser/symbolsolver/javaparsermodel/contexts/TryWithResourceContext.java b/javaparser-symbol-solver-core/src/main/java/com/github/javaparser/symbolsolver/javaparsermodel/contexts/TryWithResourceContext.java
new file mode 100644
index 000000000..80932e563
--- /dev/null
+++ b/javaparser-symbol-solver-core/src/main/java/com/github/javaparser/symbolsolver/javaparsermodel/contexts/TryWithResourceContext.java
@@ -0,0 +1,88 @@
+/*
+ * Copyright 2016 Federico Tomassetti
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.github.javaparser.symbolsolver.javaparsermodel.contexts;
+
+import com.github.javaparser.ast.body.VariableDeclarator;
+import com.github.javaparser.ast.expr.Expression;
+import com.github.javaparser.ast.expr.VariableDeclarationExpr;
+import com.github.javaparser.ast.stmt.BlockStmt;
+import com.github.javaparser.ast.stmt.TryStmt;
+import com.github.javaparser.resolution.declarations.ResolvedMethodDeclaration;
+import com.github.javaparser.resolution.declarations.ResolvedValueDeclaration;
+import com.github.javaparser.resolution.types.ResolvedType;
+import com.github.javaparser.symbolsolver.javaparsermodel.declarations.JavaParserSymbolDeclaration;
+import com.github.javaparser.symbolsolver.model.resolution.SymbolReference;
+import com.github.javaparser.symbolsolver.model.resolution.TypeSolver;
+import com.github.javaparser.symbolsolver.model.resolution.Value;
+
+import java.util.List;
+import java.util.Optional;
+
+import static com.github.javaparser.symbolsolver.javaparser.Navigator.getParentNode;
+import static com.github.javaparser.symbolsolver.javaparser.Navigator.requireParentNode;
+
+public class TryWithResourceContext extends AbstractJavaParserContext<TryStmt> {
+
+ public TryWithResourceContext(TryStmt wrappedNode, TypeSolver typeSolver) {
+ super(wrappedNode, typeSolver);
+ }
+
+ @Override
+ public Optional<Value> solveSymbolAsValue(String name, TypeSolver typeSolver) {
+ for (Expression expr : wrappedNode.getResources()) {
+ if (expr instanceof VariableDeclarationExpr) {
+ for (VariableDeclarator v : ((VariableDeclarationExpr)expr).getVariables()) {
+ if (v.getName().getIdentifier().equals(name)) {
+ JavaParserSymbolDeclaration decl = JavaParserSymbolDeclaration.localVar(v, typeSolver);
+ return Optional.of(Value.from(decl));
+ }
+ }
+ }
+ }
+
+ if (requireParentNode(wrappedNode) instanceof BlockStmt) {
+ return StatementContext.solveInBlockAsValue(name, typeSolver, wrappedNode);
+ } else {
+ return getParent().solveSymbolAsValue(name, typeSolver);
+ }
+ }
+
+ @Override
+ public SymbolReference<? extends ResolvedValueDeclaration> solveSymbol(String name, TypeSolver typeSolver) {
+ for (Expression expr : wrappedNode.getResources()) {
+ if (expr instanceof VariableDeclarationExpr) {
+ for (VariableDeclarator v : ((VariableDeclarationExpr)expr).getVariables()) {
+ if (v.getName().getIdentifier().equals(name)) {
+ return SymbolReference.solved(JavaParserSymbolDeclaration.localVar(v, typeSolver));
+ }
+ }
+ }
+ }
+
+ if (requireParentNode(wrappedNode) instanceof BlockStmt) {
+ return StatementContext.solveInBlock(name, typeSolver, wrappedNode);
+ } else {
+ return getParent().solveSymbol(name, typeSolver);
+ }
+ }
+
+ @Override
+ public SymbolReference<ResolvedMethodDeclaration> solveMethod(String name, List<ResolvedType> argumentsTypes,
+ boolean staticOnly, TypeSolver typeSolver) {
+ return getParent().solveMethod(name, argumentsTypes, false, typeSolver);
+ }
+}
diff --git a/javaparser-symbol-solver-core/src/main/java/com/github/javaparser/symbolsolver/javaparsermodel/declarations/DefaultConstructorDeclaration.java b/javaparser-symbol-solver-core/src/main/java/com/github/javaparser/symbolsolver/javaparsermodel/declarations/DefaultConstructorDeclaration.java
new file mode 100644
index 000000000..aff7c7c85
--- /dev/null
+++ b/javaparser-symbol-solver-core/src/main/java/com/github/javaparser/symbolsolver/javaparsermodel/declarations/DefaultConstructorDeclaration.java
@@ -0,0 +1,82 @@
+/*
+ * Copyright 2016 Federico Tomassetti
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.github.javaparser.symbolsolver.javaparsermodel.declarations;
+
+import com.github.javaparser.ast.AccessSpecifier;
+import com.github.javaparser.resolution.declarations.ResolvedClassDeclaration;
+import com.github.javaparser.resolution.declarations.ResolvedConstructorDeclaration;
+import com.github.javaparser.resolution.declarations.ResolvedParameterDeclaration;
+import com.github.javaparser.resolution.declarations.ResolvedTypeParameterDeclaration;
+import com.github.javaparser.resolution.types.ResolvedType;
+
+import java.util.Collections;
+import java.util.List;
+
+/**
+ * This represents the default constructor added by the compiler for objects not declaring one.
+ * It takes no parameters. See JLS 8.8.9 for details.
+ *
+ * @author Federico Tomassetti
+ */
+class DefaultConstructorDeclaration implements ResolvedConstructorDeclaration {
+
+ private ResolvedClassDeclaration classDeclaration;
+
+ DefaultConstructorDeclaration(ResolvedClassDeclaration classDeclaration) {
+ this.classDeclaration = classDeclaration;
+ }
+
+ @Override
+ public ResolvedClassDeclaration declaringType() {
+ return classDeclaration;
+ }
+
+ @Override
+ public int getNumberOfParams() {
+ return 0;
+ }
+
+ @Override
+ public ResolvedParameterDeclaration getParam(int i) {
+ throw new UnsupportedOperationException("The default constructor has not parameters");
+ }
+
+ @Override
+ public String getName() {
+ return classDeclaration.getName();
+ }
+
+ @Override
+ public AccessSpecifier accessSpecifier() {
+ return AccessSpecifier.PUBLIC;
+ }
+
+ @Override
+ public List<ResolvedTypeParameterDeclaration> getTypeParameters() {
+ return Collections.emptyList();
+ }
+
+ @Override
+ public int getNumberOfSpecifiedExceptions() {
+ return 0;
+ }
+
+ @Override
+ public ResolvedType getSpecifiedException(int index) {
+ throw new UnsupportedOperationException("The default constructor does not throw exceptions");
+ }
+}
diff --git a/javaparser-symbol-solver-core/src/main/java/com/github/javaparser/symbolsolver/javaparsermodel/declarations/Helper.java b/javaparser-symbol-solver-core/src/main/java/com/github/javaparser/symbolsolver/javaparsermodel/declarations/Helper.java
new file mode 100644
index 000000000..d34e16412
--- /dev/null
+++ b/javaparser-symbol-solver-core/src/main/java/com/github/javaparser/symbolsolver/javaparsermodel/declarations/Helper.java
@@ -0,0 +1,85 @@
+/*
+ * Copyright 2016 Federico Tomassetti
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.github.javaparser.symbolsolver.javaparsermodel.declarations;
+
+import com.github.javaparser.ast.*;
+
+import java.util.EnumSet;
+import java.util.Optional;
+
+import static com.github.javaparser.symbolsolver.javaparser.Navigator.getParentNode;
+
+/**
+ * @author Federico Tomassetti
+ */
+class Helper {
+
+ public static AccessSpecifier toAccessLevel(EnumSet<Modifier> modifiers) {
+ if (modifiers.contains(Modifier.PRIVATE)) {
+ return AccessSpecifier.PRIVATE;
+ } else if (modifiers.contains(Modifier.PROTECTED)) {
+ return AccessSpecifier.PROTECTED;
+ } else if (modifiers.contains(Modifier.PUBLIC)) {
+ return AccessSpecifier.PUBLIC;
+ } else {
+ return AccessSpecifier.DEFAULT;
+ }
+ }
+
+ static String containerName(Node container) {
+ String packageName = getPackageName(container);
+ String className = getClassName("", container);
+ return packageName +
+ ((!packageName.isEmpty() && !className.isEmpty()) ? "." : "") +
+ className;
+ }
+
+ static String getPackageName(Node container) {
+ if (container instanceof CompilationUnit) {
+ Optional<PackageDeclaration> p = ((CompilationUnit) container).getPackageDeclaration();
+ if (p.isPresent()) {
+ return p.get().getName().toString();
+ }
+ } else if (container != null) {
+ return getPackageName(container.getParentNode().orElse(null));
+ }
+ return "";
+ }
+
+ static String getClassName(String base, Node container) {
+ if (container instanceof com.github.javaparser.ast.body.ClassOrInterfaceDeclaration) {
+ String b = getClassName(base, container.getParentNode().orElse(null));
+ String cn = ((com.github.javaparser.ast.body.ClassOrInterfaceDeclaration) container).getName().getId();
+ if (b.isEmpty()) {
+ return cn;
+ } else {
+ return b + "." + cn;
+ }
+ } else if (container instanceof com.github.javaparser.ast.body.EnumDeclaration) {
+ String b = getClassName(base, container.getParentNode().orElse(null));
+ String cn = ((com.github.javaparser.ast.body.EnumDeclaration) container).getName().getId();
+ if (b.isEmpty()) {
+ return cn;
+ } else {
+ return b + "." + cn;
+ }
+ } else if (container != null) {
+ return getClassName(base, container.getParentNode().orElse(null));
+ }
+ return base;
+ }
+}
diff --git a/javaparser-symbol-solver-core/src/main/java/com/github/javaparser/symbolsolver/javaparsermodel/declarations/JavaParserAnnotationDeclaration.java b/javaparser-symbol-solver-core/src/main/java/com/github/javaparser/symbolsolver/javaparsermodel/declarations/JavaParserAnnotationDeclaration.java
new file mode 100644
index 000000000..1f6c6f33f
--- /dev/null
+++ b/javaparser-symbol-solver-core/src/main/java/com/github/javaparser/symbolsolver/javaparsermodel/declarations/JavaParserAnnotationDeclaration.java
@@ -0,0 +1,103 @@
+package com.github.javaparser.symbolsolver.javaparsermodel.declarations;
+
+import com.github.javaparser.ast.body.AnnotationDeclaration;
+import com.github.javaparser.ast.body.AnnotationMemberDeclaration;
+import com.github.javaparser.resolution.declarations.*;
+import com.github.javaparser.resolution.types.ResolvedReferenceType;
+import com.github.javaparser.resolution.types.ResolvedType;
+import com.github.javaparser.symbolsolver.logic.AbstractTypeDeclaration;
+import com.github.javaparser.symbolsolver.model.resolution.TypeSolver;
+
+import java.util.List;
+import java.util.Optional;
+import java.util.Set;
+import java.util.stream.Collectors;
+
+import static com.github.javaparser.symbolsolver.javaparser.Navigator.getParentNode;
+
+/**
+ * @author Federico Tomassetti
+ */
+public class JavaParserAnnotationDeclaration extends AbstractTypeDeclaration implements ResolvedAnnotationDeclaration {
+
+ private com.github.javaparser.ast.body.AnnotationDeclaration wrappedNode;
+ private TypeSolver typeSolver;
+
+ public JavaParserAnnotationDeclaration(AnnotationDeclaration wrappedNode, TypeSolver typeSolver) {
+ this.wrappedNode = wrappedNode;
+ this.typeSolver = typeSolver;
+ }
+
+ @Override
+ public List<ResolvedReferenceType> getAncestors() {
+ throw new UnsupportedOperationException();
+ }
+
+ @Override
+ public List<ResolvedFieldDeclaration> getAllFields() {
+ throw new UnsupportedOperationException();
+ }
+
+ @Override
+ public Set<ResolvedMethodDeclaration> getDeclaredMethods() {
+ throw new UnsupportedOperationException();
+ }
+
+ @Override
+ public boolean isAssignableBy(ResolvedType type) {
+ throw new UnsupportedOperationException();
+ }
+
+ @Override
+ public boolean isAssignableBy(ResolvedReferenceTypeDeclaration other) {
+ throw new UnsupportedOperationException();
+ }
+
+ @Override
+ public boolean hasDirectlyAnnotation(String qualifiedName) {
+ throw new UnsupportedOperationException();
+ }
+
+ @Override
+ public String getPackageName() {
+ return Helper.getPackageName(wrappedNode);
+ }
+
+ @Override
+ public String getClassName() {
+ return Helper.getClassName("", wrappedNode);
+ }
+
+ @Override
+ public String getQualifiedName() {
+ String containerName = Helper.containerName(wrappedNode.getParentNode().orElse(null));
+ if (containerName.isEmpty()) {
+ return wrappedNode.getName().getId();
+ } else {
+ return containerName + "." + wrappedNode.getName();
+ }
+ }
+
+ @Override
+ public String getName() {
+ return wrappedNode.getName().getId();
+ }
+
+ @Override
+ public List<ResolvedTypeParameterDeclaration> getTypeParameters() {
+ throw new UnsupportedOperationException();
+ }
+
+ @Override
+ public Optional<ResolvedReferenceTypeDeclaration> containerType() {
+ throw new UnsupportedOperationException("containerType is not supported for " + this.getClass().getCanonicalName());
+ }
+
+ @Override
+ public List<ResolvedAnnotationMemberDeclaration> getAnnotationMembers() {
+ return wrappedNode.getMembers().stream()
+ .filter(m -> m instanceof AnnotationMemberDeclaration)
+ .map(m -> new JavaParserAnnotationMemberDeclaration((AnnotationMemberDeclaration)m, typeSolver))
+ .collect(Collectors.toList());
+ }
+}
diff --git a/javaparser-symbol-solver-core/src/main/java/com/github/javaparser/symbolsolver/javaparsermodel/declarations/JavaParserAnnotationMemberDeclaration.java b/javaparser-symbol-solver-core/src/main/java/com/github/javaparser/symbolsolver/javaparsermodel/declarations/JavaParserAnnotationMemberDeclaration.java
new file mode 100644
index 000000000..2a603daf8
--- /dev/null
+++ b/javaparser-symbol-solver-core/src/main/java/com/github/javaparser/symbolsolver/javaparsermodel/declarations/JavaParserAnnotationMemberDeclaration.java
@@ -0,0 +1,40 @@
+package com.github.javaparser.symbolsolver.javaparsermodel.declarations;
+
+import com.github.javaparser.ast.body.AnnotationMemberDeclaration;
+import com.github.javaparser.ast.expr.Expression;
+import com.github.javaparser.resolution.declarations.ResolvedAnnotationMemberDeclaration;
+import com.github.javaparser.resolution.types.ResolvedType;
+import com.github.javaparser.symbolsolver.model.resolution.TypeSolver;
+
+/**
+ * @author Federico Tomassetti
+ */
+public class JavaParserAnnotationMemberDeclaration implements ResolvedAnnotationMemberDeclaration {
+
+ private com.github.javaparser.ast.body.AnnotationMemberDeclaration wrappedNode;
+ private TypeSolver typeSolver;
+
+ public AnnotationMemberDeclaration getWrappedNode() {
+ return wrappedNode;
+ }
+
+ public JavaParserAnnotationMemberDeclaration(AnnotationMemberDeclaration wrappedNode, TypeSolver typeSolver) {
+ this.wrappedNode = wrappedNode;
+ this.typeSolver = typeSolver;
+ }
+
+ @Override
+ public Expression getDefaultValue() {
+ throw new UnsupportedOperationException();
+ }
+
+ @Override
+ public ResolvedType getType() {
+ throw new UnsupportedOperationException();
+ }
+
+ @Override
+ public String getName() {
+ return wrappedNode.getNameAsString();
+ }
+}
diff --git a/javaparser-symbol-solver-core/src/main/java/com/github/javaparser/symbolsolver/javaparsermodel/declarations/JavaParserAnonymousClassDeclaration.java b/javaparser-symbol-solver-core/src/main/java/com/github/javaparser/symbolsolver/javaparsermodel/declarations/JavaParserAnonymousClassDeclaration.java
new file mode 100644
index 000000000..3d2cb8f69
--- /dev/null
+++ b/javaparser-symbol-solver-core/src/main/java/com/github/javaparser/symbolsolver/javaparsermodel/declarations/JavaParserAnonymousClassDeclaration.java
@@ -0,0 +1,205 @@
+package com.github.javaparser.symbolsolver.javaparsermodel.declarations;
+
+import static com.github.javaparser.symbolsolver.javaparser.Navigator.getParentNode;
+
+import com.github.javaparser.ast.AccessSpecifier;
+import com.github.javaparser.ast.Node;
+import com.github.javaparser.ast.expr.ObjectCreationExpr;
+import com.github.javaparser.resolution.declarations.*;
+import com.github.javaparser.resolution.types.ResolvedReferenceType;
+import com.github.javaparser.resolution.types.ResolvedType;
+import com.github.javaparser.symbolsolver.core.resolution.Context;
+import com.github.javaparser.symbolsolver.javaparsermodel.JavaParserFacade;
+import com.github.javaparser.symbolsolver.javaparsermodel.JavaParserFactory;
+import com.github.javaparser.symbolsolver.logic.AbstractClassDeclaration;
+import com.github.javaparser.symbolsolver.model.resolution.TypeSolver;
+import com.github.javaparser.symbolsolver.model.typesystem.ReferenceTypeImpl;
+import com.google.common.collect.ImmutableList;
+import com.google.common.collect.Lists;
+
+import java.util.*;
+import java.util.stream.Collectors;
+
+/**
+ * An anonymous class declaration representation.
+ */
+public class JavaParserAnonymousClassDeclaration extends AbstractClassDeclaration {
+
+ private final TypeSolver typeSolver;
+ private final ObjectCreationExpr wrappedNode;
+ private final ResolvedTypeDeclaration superTypeDeclaration;
+ private final String name = "Anonymous-" + UUID.randomUUID();
+
+ public JavaParserAnonymousClassDeclaration(ObjectCreationExpr wrappedNode,
+ TypeSolver typeSolver) {
+ this.typeSolver = typeSolver;
+ this.wrappedNode = wrappedNode;
+ superTypeDeclaration =
+ JavaParserFactory.getContext(wrappedNode.getParentNode().get(), typeSolver)
+ .solveType(wrappedNode.getType().getName().getId(), typeSolver)
+ .getCorrespondingDeclaration();
+ }
+
+ public ResolvedTypeDeclaration getSuperTypeDeclaration() {
+ return superTypeDeclaration;
+ }
+
+ public <T extends Node> List<T> findMembersOfKind(final Class<T> memberClass) {
+ if (wrappedNode.getAnonymousClassBody().isPresent()) {
+ return wrappedNode
+ .getAnonymousClassBody()
+ .get()
+ .stream()
+ .filter(node -> memberClass.isAssignableFrom(node.getClass()))
+ .map(memberClass::cast)
+ .collect(Collectors.toList());
+ } else {
+ return Collections.emptyList();
+ }
+ }
+
+ public Context getContext() {
+ return JavaParserFactory.getContext(wrappedNode, typeSolver);
+ }
+
+ @Override
+ protected ResolvedReferenceType object() {
+ return new ReferenceTypeImpl(typeSolver.solveType(Object.class.getCanonicalName()), typeSolver);
+ }
+
+ @Override
+ public ResolvedReferenceType getSuperClass() {
+ return new ReferenceTypeImpl(superTypeDeclaration.asReferenceType(), typeSolver);
+ }
+
+ @Override
+ public List<ResolvedReferenceType> getInterfaces() {
+ return
+ superTypeDeclaration
+ .asReferenceType().getAncestors()
+ .stream()
+ .filter(type -> type.getTypeDeclaration().isInterface())
+ .collect(Collectors.toList());
+ }
+
+ @Override
+ public List<ResolvedConstructorDeclaration> getConstructors() {
+ return
+ findMembersOfKind(com.github.javaparser.ast.body.ConstructorDeclaration.class)
+ .stream()
+ .map(ctor -> new JavaParserConstructorDeclaration(this, ctor, typeSolver))
+ .collect(Collectors.toList());
+ }
+
+ @Override
+ public AccessSpecifier accessSpecifier() {
+ return AccessSpecifier.PRIVATE;
+ }
+
+ @Override
+ public List<ResolvedReferenceType> getAncestors() {
+ return
+ ImmutableList.
+ <ResolvedReferenceType>builder()
+ .add(getSuperClass())
+ .addAll(superTypeDeclaration.asReferenceType().getAncestors())
+ .build();
+ }
+
+ @Override
+ public List<ResolvedFieldDeclaration> getAllFields() {
+
+ List<JavaParserFieldDeclaration> myFields =
+ findMembersOfKind(com.github.javaparser.ast.body.FieldDeclaration.class)
+ .stream()
+ .flatMap(field ->
+ field.getVariables().stream()
+ .map(variable -> new JavaParserFieldDeclaration(variable,
+ typeSolver)))
+ .collect(Collectors.toList());
+
+ List<ResolvedFieldDeclaration> superClassFields =
+ getSuperClass().getTypeDeclaration().getAllFields();
+
+ List<ResolvedFieldDeclaration> interfaceFields =
+ getInterfaces().stream()
+ .flatMap(inteface -> inteface.getTypeDeclaration().getAllFields().stream())
+ .collect(Collectors.toList());
+
+ return
+ ImmutableList
+ .<ResolvedFieldDeclaration>builder()
+ .addAll(myFields)
+ .addAll(superClassFields)
+ .addAll(interfaceFields)
+ .build();
+ }
+
+ @Override
+ public Set<ResolvedMethodDeclaration> getDeclaredMethods() {
+ return
+ findMembersOfKind(com.github.javaparser.ast.body.MethodDeclaration.class)
+ .stream()
+ .map(method -> new JavaParserMethodDeclaration(method, typeSolver))
+ .collect(Collectors.toSet());
+ }
+
+ @Override
+ public boolean isAssignableBy(ResolvedType type) {
+ return false;
+ }
+
+ @Override
+ public boolean isAssignableBy(ResolvedReferenceTypeDeclaration other) {
+ return false;
+ }
+
+ @Override
+ public boolean hasDirectlyAnnotation(String qualifiedName) {
+ return false;
+ }
+
+ @Override
+ public String getPackageName() {
+ return Helper.getPackageName(wrappedNode);
+ }
+
+ @Override
+ public String getClassName() {
+ return Helper.getClassName("", wrappedNode);
+ }
+
+ @Override
+ public String getQualifiedName() {
+ String containerName = Helper.containerName(wrappedNode.getParentNode().orElse(null));
+ if (containerName.isEmpty()) {
+ return getName();
+ } else {
+ return containerName + "." + getName();
+ }
+ }
+
+ @Override
+ public Set<ResolvedReferenceTypeDeclaration> internalTypes() {
+ return
+ findMembersOfKind(com.github.javaparser.ast.body.TypeDeclaration.class)
+ .stream()
+ .map(typeMember -> JavaParserFacade.get(typeSolver).getTypeDeclaration(typeMember))
+ .collect(Collectors.toSet());
+ }
+
+ @Override
+ public String getName() {
+ return name;
+ }
+
+ @Override
+ public List<ResolvedTypeParameterDeclaration> getTypeParameters() {
+ return Lists.newArrayList();
+ }
+
+ @Override
+ public Optional<ResolvedReferenceTypeDeclaration> containerType() {
+ throw new UnsupportedOperationException("containerType is not supported for " + this.getClass().getCanonicalName());
+ }
+}
diff --git a/javaparser-symbol-solver-core/src/main/java/com/github/javaparser/symbolsolver/javaparsermodel/declarations/JavaParserClassDeclaration.java b/javaparser-symbol-solver-core/src/main/java/com/github/javaparser/symbolsolver/javaparsermodel/declarations/JavaParserClassDeclaration.java
new file mode 100644
index 000000000..bb9f91cc6
--- /dev/null
+++ b/javaparser-symbol-solver-core/src/main/java/com/github/javaparser/symbolsolver/javaparsermodel/declarations/JavaParserClassDeclaration.java
@@ -0,0 +1,397 @@
+/*
+ * Copyright 2016 Federico Tomassetti
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.github.javaparser.symbolsolver.javaparsermodel.declarations;
+
+import com.github.javaparser.ast.AccessSpecifier;
+import com.github.javaparser.ast.Node;
+import com.github.javaparser.ast.body.*;
+import com.github.javaparser.ast.expr.AnnotationExpr;
+import com.github.javaparser.ast.type.ClassOrInterfaceType;
+import com.github.javaparser.resolution.UnsolvedSymbolException;
+import com.github.javaparser.resolution.declarations.*;
+import com.github.javaparser.resolution.types.ResolvedReferenceType;
+import com.github.javaparser.resolution.types.ResolvedType;
+import com.github.javaparser.symbolsolver.core.resolution.Context;
+import com.github.javaparser.symbolsolver.javaparsermodel.JavaParserFacade;
+import com.github.javaparser.symbolsolver.javaparsermodel.JavaParserFactory;
+import com.github.javaparser.symbolsolver.logic.AbstractClassDeclaration;
+import com.github.javaparser.symbolsolver.model.resolution.SymbolReference;
+import com.github.javaparser.symbolsolver.model.resolution.TypeSolver;
+import com.github.javaparser.symbolsolver.model.typesystem.LazyType;
+import com.github.javaparser.symbolsolver.model.typesystem.ReferenceTypeImpl;
+import com.github.javaparser.symbolsolver.resolution.SymbolSolver;
+import com.google.common.collect.ImmutableList;
+
+import java.util.*;
+import java.util.stream.Collectors;
+
+/**
+ * @author Federico Tomassetti
+ */
+public class JavaParserClassDeclaration extends AbstractClassDeclaration {
+
+ ///
+ /// Fields
+ ///
+
+ private TypeSolver typeSolver;
+ private com.github.javaparser.ast.body.ClassOrInterfaceDeclaration wrappedNode;
+ private JavaParserTypeAdapter<ClassOrInterfaceDeclaration> javaParserTypeAdapter;
+
+ ///
+ /// Constructors
+ ///
+
+ public JavaParserClassDeclaration(com.github.javaparser.ast.body.ClassOrInterfaceDeclaration wrappedNode,
+ TypeSolver typeSolver) {
+ if (wrappedNode.isInterface()) {
+ throw new IllegalArgumentException("Interface given");
+ }
+ this.wrappedNode = wrappedNode;
+ this.typeSolver = typeSolver;
+ this.javaParserTypeAdapter = new JavaParserTypeAdapter<>(wrappedNode, typeSolver);
+ }
+
+ ///
+ /// Public methods: from Object
+ ///
+
+ @Override
+ public boolean equals(Object o) {
+ if (this == o) return true;
+ if (o == null || getClass() != o.getClass()) return false;
+
+ JavaParserClassDeclaration that = (JavaParserClassDeclaration) o;
+
+ if (!wrappedNode.equals(that.wrappedNode)) return false;
+
+ return true;
+ }
+
+ @Override
+ public int hashCode() {
+ return wrappedNode.hashCode();
+ }
+
+ @Override
+ public String toString() {
+ return "JavaParserClassDeclaration{" +
+ "wrappedNode=" + wrappedNode +
+ '}';
+ }
+
+ ///
+ /// Public methods: fields
+ ///
+
+ @Override
+ public List<ResolvedFieldDeclaration> getAllFields() {
+ List<ResolvedFieldDeclaration> fields = javaParserTypeAdapter.getFieldsForDeclaredVariables();
+
+ getAncestors().forEach(ancestor -> ancestor.getTypeDeclaration().getAllFields().forEach(f -> {
+ fields.add(new ResolvedFieldDeclaration() {
+
+ @Override
+ public AccessSpecifier accessSpecifier() {
+ return f.accessSpecifier();
+ }
+
+ @Override
+ public String getName() {
+ return f.getName();
+ }
+
+ @Override
+ public ResolvedType getType() {
+ return ancestor.useThisTypeParametersOnTheGivenType(f.getType());
+ }
+
+ @Override
+ public boolean isStatic() {
+ return f.isStatic();
+ }
+
+ @Override
+ public ResolvedTypeDeclaration declaringType() {
+ return f.declaringType();
+ }
+ });
+ }));
+
+ return fields;
+ }
+
+ ///
+ /// Public methods
+ ///
+
+ public SymbolReference<ResolvedMethodDeclaration> solveMethod(String name, List<ResolvedType> parameterTypes) {
+ Context ctx = getContext();
+ return ctx.solveMethod(name, parameterTypes, false, typeSolver);
+ }
+
+ @Deprecated
+ public Context getContext() {
+ return JavaParserFactory.getContext(wrappedNode, typeSolver);
+ }
+
+ public ResolvedType getUsage(Node node) {
+ throw new UnsupportedOperationException();
+ }
+
+ @Override
+ public String getName() {
+ return wrappedNode.getName().getId();
+ }
+
+ @Override
+ public ResolvedReferenceType getSuperClass() {
+ if (wrappedNode.getExtendedTypes().isEmpty()) {
+ return object();
+ } else {
+ return toReferenceType(wrappedNode.getExtendedTypes().get(0));
+ }
+ }
+
+ @Override
+ public List<ResolvedReferenceType> getInterfaces() {
+ List<ResolvedReferenceType> interfaces = new ArrayList<>();
+ if (wrappedNode.getImplementedTypes() != null) {
+ for (ClassOrInterfaceType t : wrappedNode.getImplementedTypes()) {
+ interfaces.add(toReferenceType(t));
+ }
+ }
+ return interfaces;
+ }
+
+ @Override
+ public List<ResolvedConstructorDeclaration> getConstructors() {
+ List<ResolvedConstructorDeclaration> declared = new LinkedList<>();
+ for (BodyDeclaration<?> member : wrappedNode.getMembers()) {
+ if (member instanceof com.github.javaparser.ast.body.ConstructorDeclaration) {
+ com.github.javaparser.ast.body.ConstructorDeclaration constructorDeclaration = (com.github.javaparser.ast.body.ConstructorDeclaration) member;
+ declared.add(new JavaParserConstructorDeclaration(this, constructorDeclaration, typeSolver));
+ }
+ }
+ if (declared.isEmpty()) {
+ // If there are no constructors insert the default constructor
+ return ImmutableList.of(new DefaultConstructorDeclaration(this));
+ } else {
+ return declared;
+ }
+ }
+
+ @Override
+ public boolean hasDirectlyAnnotation(String canonicalName) {
+ for (AnnotationExpr annotationExpr : wrappedNode.getAnnotations()) {
+ if (solveType(annotationExpr.getName().getId(), typeSolver).getCorrespondingDeclaration().getQualifiedName().equals(canonicalName)) {
+ return true;
+ }
+ }
+ return false;
+ }
+
+ @Override
+ public boolean isInterface() {
+ return wrappedNode.isInterface();
+ }
+
+ @Override
+ public String getPackageName() {
+ return javaParserTypeAdapter.getPackageName();
+ }
+
+ @Override
+ public String getClassName() {
+ return javaParserTypeAdapter.getClassName();
+ }
+
+ @Override
+ public String getQualifiedName() {
+ return javaParserTypeAdapter.getQualifiedName();
+ }
+
+ @Override
+ public boolean isAssignableBy(ResolvedReferenceTypeDeclaration other) {
+ return javaParserTypeAdapter.isAssignableBy(other);
+ }
+
+ @Override
+ public boolean isAssignableBy(ResolvedType type) {
+ return javaParserTypeAdapter.isAssignableBy(type);
+ }
+
+ @Override
+ public boolean canBeAssignedTo(ResolvedReferenceTypeDeclaration other) {
+ // TODO consider generic types
+ if (this.getQualifiedName().equals(other.getQualifiedName())) {
+ return true;
+ }
+ ResolvedClassDeclaration superclass = (ResolvedClassDeclaration) getSuperClass().getTypeDeclaration();
+ if (superclass != null) {
+ // We want to avoid infinite recursion in case of Object having Object as ancestor
+ if (Object.class.getCanonicalName().equals(superclass.getQualifiedName())) {
+ return true;
+ }
+ if (superclass.canBeAssignedTo(other)) {
+ return true;
+ }
+ }
+
+ if (this.wrappedNode.getImplementedTypes() != null) {
+ for (ClassOrInterfaceType type : wrappedNode.getImplementedTypes()) {
+ ResolvedReferenceTypeDeclaration ancestor = (ResolvedReferenceTypeDeclaration) new SymbolSolver(typeSolver).solveType(type);
+ if (ancestor.canBeAssignedTo(other)) {
+ return true;
+ }
+ }
+ }
+
+ return false;
+ }
+
+ @Override
+ public boolean isTypeParameter() {
+ return false;
+ }
+
+ @Deprecated
+ public SymbolReference<ResolvedTypeDeclaration> solveType(String name, TypeSolver typeSolver) {
+ if (this.wrappedNode.getName().getId().equals(name)) {
+ return SymbolReference.solved(this);
+ }
+ SymbolReference<ResolvedTypeDeclaration> ref = javaParserTypeAdapter.solveType(name, typeSolver);
+ if (ref.isSolved()) {
+ return ref;
+ }
+
+ String prefix = wrappedNode.getName() + ".";
+ if (name.startsWith(prefix) && name.length() > prefix.length()) {
+ return new JavaParserClassDeclaration(this.wrappedNode, typeSolver).solveType(name.substring(prefix.length()), typeSolver);
+ }
+
+ return getContext().getParent().solveType(name, typeSolver);
+ }
+
+ @Override
+ public List<ResolvedReferenceType> getAncestors() {
+ 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()))) {
+ ResolvedReferenceType superclass = getSuperClass();
+ if (superclass != null) {
+ ancestors.add(superclass);
+ }
+ if (wrappedNode.getImplementedTypes() != null) {
+ for (ClassOrInterfaceType implemented : wrappedNode.getImplementedTypes()) {
+ ResolvedReferenceType ancestor = toReferenceType(implemented);
+ ancestors.add(ancestor);
+ }
+ }
+ }
+
+ return ancestors;
+ }
+
+ @Override
+ public Set<ResolvedMethodDeclaration> getDeclaredMethods() {
+ Set<ResolvedMethodDeclaration> methods = new HashSet<>();
+ for (BodyDeclaration<?> member : wrappedNode.getMembers()) {
+ if (member instanceof com.github.javaparser.ast.body.MethodDeclaration) {
+ methods.add(new JavaParserMethodDeclaration((com.github.javaparser.ast.body.MethodDeclaration) member, typeSolver));
+ }
+ }
+ return methods;
+ }
+
+ @Override
+ public List<ResolvedTypeParameterDeclaration> getTypeParameters() {
+ return this.wrappedNode.getTypeParameters().stream().map(
+ (tp) -> new JavaParserTypeParameter(tp, typeSolver)
+ ).collect(Collectors.toList());
+ }
+
+ /**
+ * Returns the JavaParser node associated with this JavaParserClassDeclaration.
+ *
+ * @return A visitable JavaParser node wrapped by this object.
+ */
+ public com.github.javaparser.ast.body.ClassOrInterfaceDeclaration getWrappedNode() {
+ return wrappedNode;
+ }
+
+ @Override
+ public AccessSpecifier accessSpecifier() {
+ return Helper.toAccessLevel(wrappedNode.getModifiers());
+ }
+
+ ///
+ /// Protected methods
+ ///
+
+ @Override
+ protected ResolvedReferenceType object() {
+ return new ReferenceTypeImpl(typeSolver.solveType(Object.class.getCanonicalName()), typeSolver);
+ }
+
+ @Override
+ public Set<ResolvedReferenceTypeDeclaration> internalTypes() {
+ Set<ResolvedReferenceTypeDeclaration> res = new HashSet<>();
+ for (BodyDeclaration<?> member : this.wrappedNode.getMembers()) {
+ if (member instanceof com.github.javaparser.ast.body.TypeDeclaration) {
+ res.add(JavaParserFacade.get(typeSolver).getTypeDeclaration((com.github.javaparser.ast.body.TypeDeclaration)member));
+ }
+ }
+ return res;
+ }
+
+ @Override
+ public Optional<ResolvedReferenceTypeDeclaration> containerType() {
+ return javaParserTypeAdapter.containerType();
+ }
+
+ ///
+ /// Private methods
+ ///
+
+ private ResolvedReferenceType toReferenceType(ClassOrInterfaceType classOrInterfaceType) {
+ String className = classOrInterfaceType.getName().getId();
+ if (classOrInterfaceType.getScope().isPresent()) {
+ // look for the qualified name (for example class of type Rectangle2D.Double)
+ className = classOrInterfaceType.getScope().get().toString() + "." + className;
+ }
+ SymbolReference<ResolvedTypeDeclaration> ref = solveType(className, typeSolver);
+ if (!ref.isSolved()) {
+ Optional<ClassOrInterfaceType> localScope = classOrInterfaceType.getScope();
+ if (localScope.isPresent()) {
+ String localName = localScope.get().getName().getId() + "." + classOrInterfaceType.getName().getId();
+ ref = solveType(localName, typeSolver);
+ }
+ }
+ if (!ref.isSolved()) {
+ throw new UnsolvedSymbolException(classOrInterfaceType.getName().getId());
+ }
+ if (!classOrInterfaceType.getTypeArguments().isPresent()) {
+ return new ReferenceTypeImpl(ref.getCorrespondingDeclaration().asReferenceType(), typeSolver);
+ }
+ List<ResolvedType> superClassTypeParameters = classOrInterfaceType.getTypeArguments().get()
+ .stream().map(ta -> new LazyType(v -> JavaParserFacade.get(typeSolver).convert(ta, ta)))
+ .collect(Collectors.toList());
+ return new ReferenceTypeImpl(ref.getCorrespondingDeclaration().asReferenceType(), superClassTypeParameters, typeSolver);
+ }
+}
diff --git a/javaparser-symbol-solver-core/src/main/java/com/github/javaparser/symbolsolver/javaparsermodel/declarations/JavaParserConstructorDeclaration.java b/javaparser-symbol-solver-core/src/main/java/com/github/javaparser/symbolsolver/javaparsermodel/declarations/JavaParserConstructorDeclaration.java
new file mode 100644
index 000000000..e9500fed2
--- /dev/null
+++ b/javaparser-symbol-solver-core/src/main/java/com/github/javaparser/symbolsolver/javaparsermodel/declarations/JavaParserConstructorDeclaration.java
@@ -0,0 +1,103 @@
+/*
+ * Copyright 2016 Federico Tomassetti
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.github.javaparser.symbolsolver.javaparsermodel.declarations;
+
+import com.github.javaparser.ast.AccessSpecifier;
+import com.github.javaparser.resolution.declarations.ResolvedClassDeclaration;
+import com.github.javaparser.resolution.declarations.ResolvedConstructorDeclaration;
+import com.github.javaparser.resolution.declarations.ResolvedParameterDeclaration;
+import com.github.javaparser.resolution.declarations.ResolvedTypeParameterDeclaration;
+import com.github.javaparser.resolution.types.ResolvedType;
+import com.github.javaparser.symbolsolver.javaparsermodel.JavaParserFacade;
+import com.github.javaparser.symbolsolver.model.resolution.TypeSolver;
+
+import java.util.List;
+import java.util.stream.Collectors;
+
+/**
+ * @author Federico Tomassetti
+ */
+public class JavaParserConstructorDeclaration implements ResolvedConstructorDeclaration {
+
+ private ResolvedClassDeclaration classDeclaration;
+ private com.github.javaparser.ast.body.ConstructorDeclaration wrappedNode;
+ private TypeSolver typeSolver;
+
+ JavaParserConstructorDeclaration(ResolvedClassDeclaration classDeclaration, com.github.javaparser.ast.body.ConstructorDeclaration wrappedNode,
+ TypeSolver typeSolver) {
+ this.classDeclaration = classDeclaration;
+ this.wrappedNode = wrappedNode;
+ this.typeSolver = typeSolver;
+ }
+
+ @Override
+ public ResolvedClassDeclaration declaringType() {
+ return classDeclaration;
+ }
+
+ @Override
+ public int getNumberOfParams() {
+ return this.wrappedNode.getParameters().size();
+ }
+
+ @Override
+ public ResolvedParameterDeclaration getParam(int i) {
+ if (i < 0 || i >= getNumberOfParams()) {
+ throw new IllegalArgumentException(String.format("No param with index %d. Number of params: %d", i, getNumberOfParams()));
+ }
+ return new JavaParserParameterDeclaration(wrappedNode.getParameters().get(i), typeSolver);
+ }
+
+ @Override
+ public String getName() {
+ return this.classDeclaration.getName();
+ }
+
+ /**
+ * Returns the JavaParser node associated with this JavaParserConstructorDeclaration.
+ *
+ * @return A visitable JavaParser node wrapped by this object.
+ */
+ public com.github.javaparser.ast.body.ConstructorDeclaration getWrappedNode() {
+ return wrappedNode;
+ }
+
+ @Override
+ public AccessSpecifier accessSpecifier() {
+ return Helper.toAccessLevel(wrappedNode.getModifiers());
+ }
+
+ @Override
+ public List<ResolvedTypeParameterDeclaration> getTypeParameters() {
+ return this.wrappedNode.getTypeParameters().stream().map((astTp) -> new JavaParserTypeParameter(astTp, typeSolver)).collect(Collectors.toList());
+ }
+
+ @Override
+ public int getNumberOfSpecifiedExceptions() {
+ return wrappedNode.getThrownExceptions().size();
+ }
+
+ @Override
+ public ResolvedType getSpecifiedException(int index) {
+ if (index < 0 || index >= getNumberOfSpecifiedExceptions()) {
+ throw new IllegalArgumentException(String.format("No exception with index %d. Number of exceptions: %d",
+ index, getNumberOfSpecifiedExceptions()));
+ }
+ return JavaParserFacade.get(typeSolver)
+ .convert(wrappedNode.getThrownExceptions().get(index), wrappedNode);
+ }
+}
diff --git a/javaparser-symbol-solver-core/src/main/java/com/github/javaparser/symbolsolver/javaparsermodel/declarations/JavaParserEnumConstantDeclaration.java b/javaparser-symbol-solver-core/src/main/java/com/github/javaparser/symbolsolver/javaparsermodel/declarations/JavaParserEnumConstantDeclaration.java
new file mode 100644
index 000000000..6f909582d
--- /dev/null
+++ b/javaparser-symbol-solver-core/src/main/java/com/github/javaparser/symbolsolver/javaparsermodel/declarations/JavaParserEnumConstantDeclaration.java
@@ -0,0 +1,59 @@
+/*
+ * Copyright 2016 Federico Tomassetti
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.github.javaparser.symbolsolver.javaparsermodel.declarations;
+
+import com.github.javaparser.ast.body.EnumDeclaration;
+import com.github.javaparser.resolution.declarations.ResolvedEnumConstantDeclaration;
+import com.github.javaparser.resolution.types.ResolvedType;
+import com.github.javaparser.symbolsolver.model.resolution.TypeSolver;
+import com.github.javaparser.symbolsolver.model.typesystem.ReferenceTypeImpl;
+
+import static com.github.javaparser.symbolsolver.javaparser.Navigator.requireParentNode;
+
+/**
+ * @author Federico Tomassetti
+ */
+public class JavaParserEnumConstantDeclaration implements ResolvedEnumConstantDeclaration {
+
+ private TypeSolver typeSolver;
+ private com.github.javaparser.ast.body.EnumConstantDeclaration wrappedNode;
+
+ public JavaParserEnumConstantDeclaration(com.github.javaparser.ast.body.EnumConstantDeclaration wrappedNode, TypeSolver typeSolver) {
+ this.wrappedNode = wrappedNode;
+ this.typeSolver = typeSolver;
+ }
+
+ @Override
+ public ResolvedType getType() {
+ return new ReferenceTypeImpl(new JavaParserEnumDeclaration((EnumDeclaration) requireParentNode(wrappedNode), typeSolver), typeSolver);
+ }
+
+ @Override
+ public String getName() {
+ return wrappedNode.getName().getId();
+ }
+
+ /**
+ * Returns the JavaParser node associated with this JavaParserEnumConstantDeclaration.
+ *
+ * @return A visitable JavaParser node wrapped by this object.
+ */
+ public com.github.javaparser.ast.body.EnumConstantDeclaration getWrappedNode() {
+ return wrappedNode;
+ }
+
+}
diff --git a/javaparser-symbol-solver-core/src/main/java/com/github/javaparser/symbolsolver/javaparsermodel/declarations/JavaParserEnumDeclaration.java b/javaparser-symbol-solver-core/src/main/java/com/github/javaparser/symbolsolver/javaparsermodel/declarations/JavaParserEnumDeclaration.java
new file mode 100644
index 000000000..818c0604c
--- /dev/null
+++ b/javaparser-symbol-solver-core/src/main/java/com/github/javaparser/symbolsolver/javaparsermodel/declarations/JavaParserEnumDeclaration.java
@@ -0,0 +1,350 @@
+/*
+ * Copyright 2016 Federico Tomassetti
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.github.javaparser.symbolsolver.javaparsermodel.declarations;
+
+import com.github.javaparser.ast.AccessSpecifier;
+import com.github.javaparser.ast.Node;
+import com.github.javaparser.ast.body.BodyDeclaration;
+import com.github.javaparser.ast.body.EnumConstantDeclaration;
+import com.github.javaparser.ast.type.ClassOrInterfaceType;
+import com.github.javaparser.resolution.MethodUsage;
+import com.github.javaparser.resolution.UnsolvedSymbolException;
+import com.github.javaparser.resolution.declarations.*;
+import com.github.javaparser.resolution.types.ResolvedArrayType;
+import com.github.javaparser.resolution.types.ResolvedReferenceType;
+import com.github.javaparser.resolution.types.ResolvedType;
+import com.github.javaparser.resolution.types.parametrization.ResolvedTypeParametersMap;
+import com.github.javaparser.symbolsolver.core.resolution.Context;
+import com.github.javaparser.symbolsolver.javaparsermodel.JavaParserFacade;
+import com.github.javaparser.symbolsolver.javaparsermodel.JavaParserFactory;
+import com.github.javaparser.symbolsolver.logic.AbstractTypeDeclaration;
+import com.github.javaparser.symbolsolver.model.resolution.SymbolReference;
+import com.github.javaparser.symbolsolver.model.resolution.TypeSolver;
+import com.github.javaparser.symbolsolver.model.typesystem.ReferenceTypeImpl;
+import com.github.javaparser.symbolsolver.reflectionmodel.ReflectionFactory;
+import com.github.javaparser.symbolsolver.resolution.SymbolSolver;
+
+import java.io.Serializable;
+import java.util.*;
+import java.util.stream.Collectors;
+
+/**
+ * @author Federico Tomassetti
+ */
+public class JavaParserEnumDeclaration extends AbstractTypeDeclaration implements ResolvedEnumDeclaration {
+
+ private TypeSolver typeSolver;
+ private com.github.javaparser.ast.body.EnumDeclaration wrappedNode;
+ private JavaParserTypeAdapter<com.github.javaparser.ast.body.EnumDeclaration> javaParserTypeAdapter;
+
+ public JavaParserEnumDeclaration(com.github.javaparser.ast.body.EnumDeclaration wrappedNode, TypeSolver typeSolver) {
+ this.wrappedNode = wrappedNode;
+ this.typeSolver = typeSolver;
+ this.javaParserTypeAdapter = new JavaParserTypeAdapter<>(wrappedNode, typeSolver);
+ }
+
+ @Override
+ public String toString() {
+ return "JavaParserEnumDeclaration{" +
+ "wrappedNode=" + wrappedNode +
+ '}';
+ }
+
+ @Override
+ public Set<ResolvedMethodDeclaration> getDeclaredMethods() {
+ Set<ResolvedMethodDeclaration> methods = new HashSet<>();
+ for (BodyDeclaration<?> member : wrappedNode.getMembers()) {
+ if (member instanceof com.github.javaparser.ast.body.MethodDeclaration) {
+ methods.add(new JavaParserMethodDeclaration((com.github.javaparser.ast.body.MethodDeclaration) member, typeSolver));
+ }
+ }
+ return methods;
+ }
+
+ public Context getContext() {
+ return JavaParserFactory.getContext(wrappedNode, typeSolver);
+ }
+
+ @Override
+ public String getName() {
+ return wrappedNode.getName().getId();
+ }
+
+ @Override
+ public boolean isField() {
+ return false;
+ }
+
+ @Override
+ public boolean isParameter() {
+ return false;
+ }
+
+ @Override
+ public boolean isType() {
+ return true;
+ }
+
+ @Override
+ public boolean hasDirectlyAnnotation(String canonicalName) {
+ throw new UnsupportedOperationException();
+ }
+
+ @Override
+ public boolean canBeAssignedTo(ResolvedReferenceTypeDeclaration other) {
+ String otherName = other.getQualifiedName();
+ // Enums cannot be extended
+ if (otherName.equals(this.getQualifiedName())) {
+ return true;
+ }
+ if (otherName.equals(Enum.class.getCanonicalName())) {
+ return true;
+ }
+ // Enum implements Comparable and Serializable
+ if (otherName.equals(Comparable.class.getCanonicalName())) {
+ return true;
+ }
+ if (otherName.equals(Serializable.class.getCanonicalName())) {
+ return true;
+ }
+ if (otherName.equals(Object.class.getCanonicalName())) {
+ return true;
+ }
+ return false;
+ }
+
+ @Override
+ public boolean isClass() {
+ return false;
+ }
+
+ @Override
+ public boolean isInterface() {
+ return false;
+ }
+
+ @Override
+ public String getPackageName() {
+ return javaParserTypeAdapter.getPackageName();
+ }
+
+ @Override
+ public String getClassName() {
+ return javaParserTypeAdapter.getClassName();
+ }
+
+ @Override
+ public String getQualifiedName() {
+ return javaParserTypeAdapter.getQualifiedName();
+ }
+
+ @Override
+ public boolean isAssignableBy(ResolvedReferenceTypeDeclaration other) {
+ return javaParserTypeAdapter.isAssignableBy(other);
+ }
+
+ @Override
+ public boolean isAssignableBy(ResolvedType type) {
+ return javaParserTypeAdapter.isAssignableBy(type);
+ }
+
+ @Override
+ public boolean isTypeParameter() {
+ return false;
+ }
+
+ @Override
+ public boolean equals(Object o) {
+ if (this == o) return true;
+ if (o == null || getClass() != o.getClass()) return false;
+
+ JavaParserEnumDeclaration that = (JavaParserEnumDeclaration) o;
+
+ if (!wrappedNode.equals(that.wrappedNode)) return false;
+
+ return true;
+ }
+
+ @Override
+ public int hashCode() {
+ return wrappedNode.hashCode();
+ }
+
+ @Deprecated
+ public Optional<MethodUsage> solveMethodAsUsage(String name, List<ResolvedType> parameterTypes,
+ TypeSolver typeSolver, Context invokationContext, List<ResolvedType> typeParameterValues) {
+ if (name.equals("values") && parameterTypes.isEmpty()) {
+ return Optional.of(new ValuesMethod(this, typeSolver).getUsage(null));
+ }
+ // TODO add methods inherited from Enum
+ return getContext().solveMethodAsUsage(name, parameterTypes, typeSolver);
+ }
+
+ @Override
+ public List<ResolvedFieldDeclaration> getAllFields() {
+ List<ResolvedFieldDeclaration> fields = javaParserTypeAdapter.getFieldsForDeclaredVariables();
+
+ if (this.wrappedNode.getEntries() != null) {
+ for (EnumConstantDeclaration member : this.wrappedNode.getEntries()) {
+ fields.add(new JavaParserFieldDeclaration(member, typeSolver));
+ }
+ }
+
+ return fields;
+ }
+
+ @Override
+ public List<ResolvedReferenceType> getAncestors() {
+ List<ResolvedReferenceType> ancestors = new ArrayList<>();
+ ResolvedReferenceType enumClass = ReflectionFactory.typeUsageFor(Enum.class, typeSolver).asReferenceType();
+ ResolvedTypeParameterDeclaration eTypeParameter = enumClass.getTypeDeclaration().getTypeParameters().get(0);
+ enumClass = enumClass.deriveTypeParameters(new ResolvedTypeParametersMap.Builder().setValue(eTypeParameter, new ReferenceTypeImpl(this, typeSolver)).build());
+ ancestors.add(enumClass);
+ if (wrappedNode.getImplementedTypes() != null) {
+ for (ClassOrInterfaceType implementedType : wrappedNode.getImplementedTypes()) {
+ SymbolReference<ResolvedTypeDeclaration> implementedDeclRef = new SymbolSolver(typeSolver).solveTypeInType(this, implementedType.getName().getId());
+ if (!implementedDeclRef.isSolved()) {
+ throw new UnsolvedSymbolException(implementedType.getName().getId());
+ }
+ ancestors.add(new ReferenceTypeImpl((ResolvedReferenceTypeDeclaration) implementedDeclRef.getCorrespondingDeclaration(), typeSolver));
+ }
+ }
+ return ancestors;
+ }
+
+ @Override
+ public List<ResolvedTypeParameterDeclaration> getTypeParameters() {
+ return Collections.emptyList();
+ }
+
+ /**
+ * Returns the JavaParser node associated with this JavaParserEnumDeclaration.
+ *
+ * @return A visitable JavaParser node wrapped by this object.
+ */
+ public com.github.javaparser.ast.body.EnumDeclaration getWrappedNode() {
+ return wrappedNode;
+ }
+
+ @Override
+ public List<ResolvedEnumConstantDeclaration> getEnumConstants() {
+ return wrappedNode.getEntries().stream()
+ .map(entry -> new JavaParserEnumConstantDeclaration(entry, typeSolver))
+ .collect(Collectors.toList());
+ }
+
+ // Needed by ContextHelper
+ public static class ValuesMethod implements ResolvedMethodDeclaration {
+
+ private JavaParserEnumDeclaration enumDeclaration;
+ private TypeSolver typeSolver;
+
+ public ValuesMethod(JavaParserEnumDeclaration enumDeclaration, TypeSolver typeSolver) {
+ this.enumDeclaration = enumDeclaration;
+ this.typeSolver = typeSolver;
+ }
+
+ @Override
+ public ResolvedReferenceTypeDeclaration declaringType() {
+ return enumDeclaration;
+ }
+
+ @Override
+ public ResolvedType getReturnType() {
+ return new ResolvedArrayType(new ReferenceTypeImpl(enumDeclaration, typeSolver));
+ }
+
+ @Override
+ public int getNumberOfParams() {
+ return 0;
+ }
+
+ @Override
+ public ResolvedParameterDeclaration getParam(int i) {
+ throw new UnsupportedOperationException();
+ }
+
+ public MethodUsage getUsage(Node node) {
+ throw new UnsupportedOperationException();
+ }
+
+ public MethodUsage resolveTypeVariables(Context context, List<ResolvedType> parameterTypes) {
+ return new MethodUsage(this);
+ }
+
+ @Override
+ public boolean isAbstract() {
+ throw new UnsupportedOperationException();
+ }
+
+ @Override
+ public boolean isDefaultMethod() {
+ return false;
+ }
+
+ @Override
+ public boolean isStatic() {
+ return false;
+ }
+
+ @Override
+ public String getName() {
+ return "values";
+ }
+
+ @Override
+ public List<ResolvedTypeParameterDeclaration> getTypeParameters() {
+ return Collections.emptyList();
+ }
+
+ @Override
+ public AccessSpecifier accessSpecifier() {
+ return Helper.toAccessLevel(enumDeclaration.getWrappedNode().getModifiers());
+ }
+
+ @Override
+ public int getNumberOfSpecifiedExceptions() {
+ return 0;
+ }
+
+ @Override
+ public ResolvedType getSpecifiedException(int index) {
+ throw new UnsupportedOperationException("The values method of an enum does not throw any exception");
+ }
+ }
+
+ @Override
+ public AccessSpecifier accessSpecifier() {
+ throw new UnsupportedOperationException();
+ }
+
+ @Override
+ public Set<ResolvedReferenceTypeDeclaration> internalTypes() {
+ Set<ResolvedReferenceTypeDeclaration> res = new HashSet<>();
+ for (BodyDeclaration<?> member : this.wrappedNode.getMembers()) {
+ if (member instanceof com.github.javaparser.ast.body.TypeDeclaration) {
+ res.add(JavaParserFacade.get(typeSolver).getTypeDeclaration((com.github.javaparser.ast.body.TypeDeclaration)member));
+ }
+ }
+ return res;
+ }
+
+ @Override
+ public Optional<ResolvedReferenceTypeDeclaration> containerType() {
+ return javaParserTypeAdapter.containerType();
+ }
+}
diff --git a/javaparser-symbol-solver-core/src/main/java/com/github/javaparser/symbolsolver/javaparsermodel/declarations/JavaParserFieldDeclaration.java b/javaparser-symbol-solver-core/src/main/java/com/github/javaparser/symbolsolver/javaparsermodel/declarations/JavaParserFieldDeclaration.java
new file mode 100644
index 000000000..1c9e00511
--- /dev/null
+++ b/javaparser-symbol-solver-core/src/main/java/com/github/javaparser/symbolsolver/javaparsermodel/declarations/JavaParserFieldDeclaration.java
@@ -0,0 +1,121 @@
+/*
+ * Copyright 2016 Federico Tomassetti
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.github.javaparser.symbolsolver.javaparsermodel.declarations;
+
+import com.github.javaparser.ast.AccessSpecifier;
+import com.github.javaparser.ast.Modifier;
+import com.github.javaparser.ast.body.EnumConstantDeclaration;
+import com.github.javaparser.ast.body.VariableDeclarator;
+import com.github.javaparser.resolution.declarations.ResolvedFieldDeclaration;
+import com.github.javaparser.resolution.declarations.ResolvedTypeDeclaration;
+import com.github.javaparser.resolution.types.ResolvedType;
+import com.github.javaparser.symbolsolver.javaparser.Navigator;
+import com.github.javaparser.symbolsolver.javaparsermodel.JavaParserFacade;
+import com.github.javaparser.symbolsolver.model.resolution.TypeSolver;
+import com.github.javaparser.symbolsolver.model.typesystem.ReferenceTypeImpl;
+
+import java.util.Optional;
+
+import static com.github.javaparser.symbolsolver.javaparser.Navigator.getParentNode;
+import static com.github.javaparser.symbolsolver.javaparser.Navigator.requireParentNode;
+
+/**
+ * @author Federico Tomassetti
+ */
+public class JavaParserFieldDeclaration implements ResolvedFieldDeclaration {
+
+ private VariableDeclarator variableDeclarator;
+ private com.github.javaparser.ast.body.FieldDeclaration wrappedNode;
+ private EnumConstantDeclaration enumConstantDeclaration;
+ private TypeSolver typeSolver;
+
+ public JavaParserFieldDeclaration(VariableDeclarator variableDeclarator, TypeSolver typeSolver) {
+ if (typeSolver == null) {
+ throw new IllegalArgumentException("typeSolver should not be null");
+ }
+ this.variableDeclarator = variableDeclarator;
+ this.typeSolver = typeSolver;
+ if (!(requireParentNode(variableDeclarator) instanceof com.github.javaparser.ast.body.FieldDeclaration)) {
+ throw new IllegalStateException(requireParentNode(variableDeclarator).getClass().getCanonicalName());
+ }
+ this.wrappedNode = (com.github.javaparser.ast.body.FieldDeclaration) requireParentNode(variableDeclarator);
+ }
+
+ public JavaParserFieldDeclaration(EnumConstantDeclaration enumConstantDeclaration, TypeSolver typeSolver) {
+ if (typeSolver == null) {
+ throw new IllegalArgumentException("typeSolver should not be null");
+ }
+ this.enumConstantDeclaration = enumConstantDeclaration;
+ this.typeSolver = typeSolver;
+ }
+
+ @Override
+ public ResolvedType getType() {
+ if (enumConstantDeclaration != null) {
+ com.github.javaparser.ast.body.EnumDeclaration enumDeclaration = (com.github.javaparser.ast.body.EnumDeclaration) requireParentNode(enumConstantDeclaration);
+ return new ReferenceTypeImpl(new JavaParserEnumDeclaration(enumDeclaration, typeSolver), typeSolver);
+ }
+ return JavaParserFacade.get(typeSolver).convert(variableDeclarator.getType(), wrappedNode);
+ }
+
+ @Override
+ public String getName() {
+ if (enumConstantDeclaration != null) {
+ return enumConstantDeclaration.getName().getId();
+ } else {
+ return variableDeclarator.getName().getId();
+ }
+ }
+
+ @Override
+ public boolean isStatic() {
+ return wrappedNode.getModifiers().contains(Modifier.STATIC);
+ }
+
+ @Override
+ public boolean isField() {
+ return true;
+ }
+
+ /**
+ * Returns the JavaParser node associated with this JavaParserFieldDeclaration.
+ *
+ * @return A visitable JavaParser node wrapped by this object.
+ */
+ public com.github.javaparser.ast.body.FieldDeclaration getWrappedNode() {
+ return wrappedNode;
+ }
+
+ @Override
+ public String toString() {
+ return "JPField{" + getName() + "}";
+ }
+
+ @Override
+ public AccessSpecifier accessSpecifier() {
+ return Helper.toAccessLevel(wrappedNode.getModifiers());
+ }
+
+ @Override
+ public ResolvedTypeDeclaration declaringType() {
+ Optional<com.github.javaparser.ast.body.TypeDeclaration> typeDeclaration = wrappedNode.findParent(com.github.javaparser.ast.body.TypeDeclaration.class);
+ if (typeDeclaration.isPresent()) {
+ return JavaParserFacade.get(typeSolver).getTypeDeclaration(typeDeclaration.get());
+ }
+ throw new IllegalStateException();
+ }
+}
diff --git a/javaparser-symbol-solver-core/src/main/java/com/github/javaparser/symbolsolver/javaparsermodel/declarations/JavaParserInterfaceDeclaration.java b/javaparser-symbol-solver-core/src/main/java/com/github/javaparser/symbolsolver/javaparsermodel/declarations/JavaParserInterfaceDeclaration.java
new file mode 100644
index 000000000..34955a0c0
--- /dev/null
+++ b/javaparser-symbol-solver-core/src/main/java/com/github/javaparser/symbolsolver/javaparsermodel/declarations/JavaParserInterfaceDeclaration.java
@@ -0,0 +1,335 @@
+/*
+ * Copyright 2016 Federico Tomassetti
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.github.javaparser.symbolsolver.javaparsermodel.declarations;
+
+import com.github.javaparser.ast.AccessSpecifier;
+import com.github.javaparser.ast.Node;
+import com.github.javaparser.ast.body.BodyDeclaration;
+import com.github.javaparser.ast.body.ClassOrInterfaceDeclaration;
+import com.github.javaparser.ast.expr.AnnotationExpr;
+import com.github.javaparser.ast.type.ClassOrInterfaceType;
+import com.github.javaparser.resolution.UnsolvedSymbolException;
+import com.github.javaparser.resolution.declarations.*;
+import com.github.javaparser.resolution.types.ResolvedReferenceType;
+import com.github.javaparser.resolution.types.ResolvedType;
+import com.github.javaparser.symbolsolver.core.resolution.Context;
+import com.github.javaparser.symbolsolver.javaparsermodel.JavaParserFacade;
+import com.github.javaparser.symbolsolver.javaparsermodel.JavaParserFactory;
+import com.github.javaparser.symbolsolver.logic.AbstractTypeDeclaration;
+import com.github.javaparser.symbolsolver.model.resolution.SymbolReference;
+import com.github.javaparser.symbolsolver.model.resolution.TypeSolver;
+import com.github.javaparser.symbolsolver.model.typesystem.LazyType;
+import com.github.javaparser.symbolsolver.model.typesystem.ReferenceTypeImpl;
+import com.github.javaparser.symbolsolver.resolution.SymbolSolver;
+
+import java.util.*;
+import java.util.stream.Collectors;
+
+/**
+ * @author Federico Tomassetti
+ */
+public class JavaParserInterfaceDeclaration extends AbstractTypeDeclaration implements ResolvedInterfaceDeclaration {
+
+ private TypeSolver typeSolver;
+ private ClassOrInterfaceDeclaration wrappedNode;
+ private JavaParserTypeAdapter<ClassOrInterfaceDeclaration> javaParserTypeAdapter;
+
+ public JavaParserInterfaceDeclaration(ClassOrInterfaceDeclaration wrappedNode, TypeSolver typeSolver) {
+ if (!wrappedNode.isInterface()) {
+ throw new IllegalArgumentException();
+ }
+ this.wrappedNode = wrappedNode;
+ this.typeSolver = typeSolver;
+ this.javaParserTypeAdapter = new JavaParserTypeAdapter<>(wrappedNode, typeSolver);
+ }
+
+ @Override
+ public Set<ResolvedMethodDeclaration> getDeclaredMethods() {
+ Set<ResolvedMethodDeclaration> methods = new HashSet<>();
+ for (BodyDeclaration<?> member : wrappedNode.getMembers()) {
+ if (member instanceof com.github.javaparser.ast.body.MethodDeclaration) {
+ methods.add(new JavaParserMethodDeclaration((com.github.javaparser.ast.body.MethodDeclaration) member, typeSolver));
+ }
+ }
+ return methods;
+ }
+
+ public Context getContext() {
+ return JavaParserFactory.getContext(wrappedNode, typeSolver);
+ }
+
+ public ResolvedType getUsage(Node node) {
+ throw new UnsupportedOperationException();
+ }
+
+ @Override
+ public boolean equals(Object o) {
+ if (this == o) return true;
+ if (o == null || getClass() != o.getClass()) return false;
+
+ JavaParserInterfaceDeclaration that = (JavaParserInterfaceDeclaration) o;
+
+ if (!wrappedNode.equals(that.wrappedNode)) return false;
+
+ return true;
+ }
+
+ @Override
+ public int hashCode() {
+ return wrappedNode.hashCode();
+ }
+
+ @Override
+ public String getName() {
+ return wrappedNode.getName().getId();
+ }
+
+ @Override
+ public ResolvedInterfaceDeclaration asInterface() {
+ return this;
+ }
+
+ @Override
+ public boolean hasDirectlyAnnotation(String canonicalName) {
+ for (AnnotationExpr annotationExpr : wrappedNode.getAnnotations()) {
+ if (solveType(annotationExpr.getName().getId(), typeSolver).getCorrespondingDeclaration().getQualifiedName().equals(canonicalName)) {
+ return true;
+ }
+ }
+ return false;
+ }
+
+ @Override
+ public boolean isInterface() {
+ return true;
+ }
+
+ @Override
+ public List<ResolvedReferenceType> getInterfacesExtended() {
+ List<ResolvedReferenceType> interfaces = new ArrayList<>();
+ if (wrappedNode.getImplementedTypes() != null) {
+ for (ClassOrInterfaceType t : wrappedNode.getImplementedTypes()) {
+ interfaces.add(new ReferenceTypeImpl(solveType(t.getName().getId(), typeSolver).getCorrespondingDeclaration().asInterface(), typeSolver));
+ }
+ }
+ return interfaces;
+ }
+
+ @Override
+ public String getPackageName() {
+ return javaParserTypeAdapter.getPackageName();
+ }
+
+ @Override
+ public String getClassName() {
+ return javaParserTypeAdapter.getClassName();
+ }
+
+ @Override
+ public String getQualifiedName() {
+ return javaParserTypeAdapter.getQualifiedName();
+ }
+
+ @Override
+ public boolean isAssignableBy(ResolvedReferenceTypeDeclaration other) {
+ return javaParserTypeAdapter.isAssignableBy(other);
+ }
+
+ @Override
+ public boolean isAssignableBy(ResolvedType type) {
+ return javaParserTypeAdapter.isAssignableBy(type);
+ }
+
+ @Override
+ public boolean canBeAssignedTo(ResolvedReferenceTypeDeclaration other) {
+ // TODO consider generic types
+ if (this.getQualifiedName().equals(other.getQualifiedName())) {
+ return true;
+ }
+ if (this.wrappedNode.getExtendedTypes() != null) {
+ for (ClassOrInterfaceType type : wrappedNode.getExtendedTypes()) {
+ ResolvedReferenceTypeDeclaration ancestor = (ResolvedReferenceTypeDeclaration) new SymbolSolver(typeSolver).solveType(type);
+ if (ancestor.canBeAssignedTo(other)) {
+ return true;
+ }
+ }
+ }
+
+ if (this.wrappedNode.getImplementedTypes() != null) {
+ for (ClassOrInterfaceType type : wrappedNode.getImplementedTypes()) {
+ ResolvedReferenceTypeDeclaration ancestor = (ResolvedReferenceTypeDeclaration) new SymbolSolver(typeSolver).solveType(type);
+ if (ancestor.canBeAssignedTo(other)) {
+ return true;
+ }
+ }
+ }
+
+ return false;
+ }
+
+ @Override
+ public boolean isTypeParameter() {
+ return false;
+ }
+
+ @Override
+ public List<ResolvedFieldDeclaration> getAllFields() {
+ List<ResolvedFieldDeclaration> fields = javaParserTypeAdapter.getFieldsForDeclaredVariables();
+
+ getAncestors().forEach(ancestor -> ancestor.getTypeDeclaration().getAllFields().forEach(f -> {
+ fields.add(new ResolvedFieldDeclaration() {
+
+ @Override
+ public AccessSpecifier accessSpecifier() {
+ return f.accessSpecifier();
+ }
+
+ @Override
+ public String getName() {
+ return f.getName();
+ }
+
+ @Override
+ public ResolvedType getType() {
+ return ancestor.useThisTypeParametersOnTheGivenType(f.getType());
+ }
+
+ @Override
+ public boolean isStatic() {
+ return f.isStatic();
+ }
+
+ @Override
+ public ResolvedTypeDeclaration declaringType() {
+ return f.declaringType();
+ }
+ });
+ }));
+
+ return fields;
+ }
+
+
+ @Override
+ public String toString() {
+ return "JavaParserInterfaceDeclaration{" +
+ "wrappedNode=" + wrappedNode +
+ '}';
+ }
+
+ @Deprecated
+ public SymbolReference<ResolvedTypeDeclaration> solveType(String name, TypeSolver typeSolver) {
+ if (this.wrappedNode.getName().getId().equals(name)) {
+ return SymbolReference.solved(this);
+ }
+ SymbolReference<ResolvedTypeDeclaration> ref = javaParserTypeAdapter.solveType(name, typeSolver);
+ if (ref.isSolved()) {
+ return ref;
+ }
+
+ String prefix = wrappedNode.getName() + ".";
+ if (name.startsWith(prefix) && name.length() > prefix.length()) {
+ return new JavaParserInterfaceDeclaration(this.wrappedNode, typeSolver).solveType(name.substring(prefix.length()), typeSolver);
+ }
+
+ return getContext().getParent().solveType(name, typeSolver);
+ }
+
+ @Override
+ public List<ResolvedReferenceType> getAncestors() {
+ List<ResolvedReferenceType> ancestors = new ArrayList<>();
+ if (wrappedNode.getExtendedTypes() != null) {
+ for (ClassOrInterfaceType extended : wrappedNode.getExtendedTypes()) {
+ ancestors.add(toReferenceType(extended));
+ }
+ }
+ if (wrappedNode.getImplementedTypes() != null) {
+ for (ClassOrInterfaceType implemented : wrappedNode.getImplementedTypes()) {
+ ancestors.add(toReferenceType(implemented));
+ }
+ }
+ return ancestors;
+ }
+
+ @Override
+ public List<ResolvedTypeParameterDeclaration> getTypeParameters() {
+ if (this.wrappedNode.getTypeParameters() == null) {
+ return Collections.emptyList();
+ } else {
+ return this.wrappedNode.getTypeParameters().stream().map(
+ (tp) -> new JavaParserTypeParameter(tp, typeSolver)
+ ).collect(Collectors.toList());
+ }
+ }
+
+ /**
+ * Returns the JavaParser node associated with this JavaParserInterfaceDeclaration.
+ *
+ * @return A visitable JavaParser node wrapped by this object.
+ */
+ public ClassOrInterfaceDeclaration getWrappedNode() {
+ return wrappedNode;
+ }
+
+ @Override
+ public AccessSpecifier accessSpecifier() {
+ return Helper.toAccessLevel(wrappedNode.getModifiers());
+ }
+
+ @Override
+ public Set<ResolvedReferenceTypeDeclaration> internalTypes() {
+ Set<ResolvedReferenceTypeDeclaration> res = new HashSet<>();
+ for (BodyDeclaration<?> member : this.wrappedNode.getMembers()) {
+ if (member instanceof com.github.javaparser.ast.body.TypeDeclaration) {
+ res.add(JavaParserFacade.get(typeSolver).getTypeDeclaration((com.github.javaparser.ast.body.TypeDeclaration)member));
+ }
+ }
+ return res;
+ }
+
+ @Override
+ public Optional<ResolvedReferenceTypeDeclaration> containerType() {
+ return javaParserTypeAdapter.containerType();
+ }
+
+ ///
+ /// Private methods
+ ///
+
+ private ResolvedReferenceType toReferenceType(ClassOrInterfaceType classOrInterfaceType) {
+ SymbolReference<? extends ResolvedTypeDeclaration> ref = null;
+ if (classOrInterfaceType.toString().indexOf('.') > -1) {
+ ref = typeSolver.tryToSolveType(classOrInterfaceType.toString());
+ }
+ if (ref == null || !ref.isSolved()) {
+ ref = solveType(classOrInterfaceType.toString(), typeSolver);
+ }
+ if (!ref.isSolved()) {
+ ref = solveType(classOrInterfaceType.getName().getId(), typeSolver);
+ }
+ if (!ref.isSolved()) {
+ throw new UnsolvedSymbolException(classOrInterfaceType.getName().getId());
+ }
+ if (!classOrInterfaceType.getTypeArguments().isPresent()) {
+ return new ReferenceTypeImpl(ref.getCorrespondingDeclaration().asReferenceType(), typeSolver);
+ }
+ List<ResolvedType> superClassTypeParameters = classOrInterfaceType.getTypeArguments().get()
+ .stream().map(ta -> new LazyType(v -> JavaParserFacade.get(typeSolver).convert(ta, ta)))
+ .collect(Collectors.toList());
+ return new ReferenceTypeImpl(ref.getCorrespondingDeclaration().asReferenceType(), superClassTypeParameters, typeSolver);
+ }
+}
diff --git a/javaparser-symbol-solver-core/src/main/java/com/github/javaparser/symbolsolver/javaparsermodel/declarations/JavaParserMethodDeclaration.java b/javaparser-symbol-solver-core/src/main/java/com/github/javaparser/symbolsolver/javaparsermodel/declarations/JavaParserMethodDeclaration.java
new file mode 100644
index 000000000..4f3cb3569
--- /dev/null
+++ b/javaparser-symbol-solver-core/src/main/java/com/github/javaparser/symbolsolver/javaparsermodel/declarations/JavaParserMethodDeclaration.java
@@ -0,0 +1,167 @@
+/*
+ * Copyright 2016 Federico Tomassetti
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.github.javaparser.symbolsolver.javaparsermodel.declarations;
+
+import com.github.javaparser.ast.AccessSpecifier;
+import com.github.javaparser.ast.Node;
+import com.github.javaparser.ast.expr.ObjectCreationExpr;
+import com.github.javaparser.resolution.MethodUsage;
+import com.github.javaparser.resolution.declarations.ResolvedMethodDeclaration;
+import com.github.javaparser.resolution.declarations.ResolvedParameterDeclaration;
+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.symbolsolver.core.resolution.Context;
+import com.github.javaparser.symbolsolver.declarations.common.MethodDeclarationCommonLogic;
+import com.github.javaparser.symbolsolver.javaparsermodel.JavaParserFacade;
+import com.github.javaparser.symbolsolver.javaparsermodel.JavaParserFactory;
+import com.github.javaparser.symbolsolver.model.resolution.TypeSolver;
+
+import java.util.List;
+import java.util.stream.Collectors;
+
+import static com.github.javaparser.symbolsolver.javaparser.Navigator.requireParentNode;
+
+/**
+ * @author Federico Tomassetti
+ */
+public class JavaParserMethodDeclaration implements ResolvedMethodDeclaration {
+
+ private com.github.javaparser.ast.body.MethodDeclaration wrappedNode;
+ private TypeSolver typeSolver;
+
+ public JavaParserMethodDeclaration(com.github.javaparser.ast.body.MethodDeclaration wrappedNode, TypeSolver typeSolver) {
+ this.wrappedNode = wrappedNode;
+ this.typeSolver = typeSolver;
+ }
+
+ @Override
+ public String toString() {
+ return "JavaParserMethodDeclaration{" +
+ "wrappedNode=" + wrappedNode +
+ ", typeSolver=" + typeSolver +
+ '}';
+ }
+
+ @Override
+ public ResolvedReferenceTypeDeclaration declaringType() {
+ if (requireParentNode(wrappedNode) instanceof ObjectCreationExpr) {
+ ObjectCreationExpr parentNode = (ObjectCreationExpr) requireParentNode(wrappedNode);
+ return new JavaParserAnonymousClassDeclaration(parentNode, typeSolver);
+ }
+ return JavaParserFactory.toTypeDeclaration(requireParentNode(wrappedNode), typeSolver);
+ }
+
+ @Override
+ public ResolvedType getReturnType() {
+ return JavaParserFacade.get(typeSolver).convert(wrappedNode.getType(), getContext());
+ }
+
+ @Override
+ public int getNumberOfParams() {
+ return wrappedNode.getParameters().size();
+ }
+
+ @Override
+ public ResolvedParameterDeclaration getParam(int i) {
+ if (i < 0 || i >= getNumberOfParams()) {
+ throw new IllegalArgumentException(String.format("No param with index %d. Number of params: %d", i, getNumberOfParams()));
+ }
+ return new JavaParserParameterDeclaration(wrappedNode.getParameters().get(i), typeSolver);
+ }
+
+ public MethodUsage getUsage(Node node) {
+ throw new UnsupportedOperationException();
+ }
+
+ public MethodUsage resolveTypeVariables(Context context, List<ResolvedType> parameterTypes) {
+ return new MethodDeclarationCommonLogic(this, typeSolver).resolveTypeVariables(context, parameterTypes);
+ }
+
+ private Context getContext() {
+ return JavaParserFactory.getContext(wrappedNode, typeSolver);
+ }
+
+ @Override
+ public boolean isAbstract() {
+ return !wrappedNode.getBody().isPresent();
+ }
+
+ @Override
+ public String getName() {
+ return wrappedNode.getName().getId();
+ }
+
+ @Override
+ public boolean isField() {
+ throw new UnsupportedOperationException();
+ }
+
+ @Override
+ public boolean isParameter() {
+ throw new UnsupportedOperationException();
+ }
+
+ @Override
+ public boolean isType() {
+ throw new UnsupportedOperationException();
+ }
+
+ @Override
+ public List<ResolvedTypeParameterDeclaration> getTypeParameters() {
+ return this.wrappedNode.getTypeParameters().stream().map((astTp) -> new JavaParserTypeParameter(astTp, typeSolver)).collect(Collectors.toList());
+ }
+
+ @Override
+ public boolean isDefaultMethod() {
+ return wrappedNode.isDefault();
+ }
+
+ @Override
+ public boolean isStatic() {
+ return wrappedNode.isStatic();
+ }
+
+ /**
+ * Returns the JavaParser node associated with this JavaParserMethodDeclaration.
+ *
+ * @return A visitable JavaParser node wrapped by this object.
+ */
+ public com.github.javaparser.ast.body.MethodDeclaration getWrappedNode() {
+ return wrappedNode;
+ }
+
+ @Override
+ public AccessSpecifier accessSpecifier() {
+ return Helper.toAccessLevel(wrappedNode.getModifiers());
+ }
+
+ @Override
+ public int getNumberOfSpecifiedExceptions() {
+ return wrappedNode.getThrownExceptions().size();
+ }
+
+ @Override
+ public ResolvedType getSpecifiedException(int index) {
+ if (index < 0 || index >= getNumberOfSpecifiedExceptions()) {
+ throw new IllegalArgumentException(String.format("No exception with index %d. Number of exceptions: %d",
+ index, getNumberOfSpecifiedExceptions()));
+ }
+ return JavaParserFacade.get(typeSolver).convert(wrappedNode.getThrownExceptions()
+ .get(index), wrappedNode);
+ }
+}
diff --git a/javaparser-symbol-solver-core/src/main/java/com/github/javaparser/symbolsolver/javaparsermodel/declarations/JavaParserParameterDeclaration.java b/javaparser-symbol-solver-core/src/main/java/com/github/javaparser/symbolsolver/javaparsermodel/declarations/JavaParserParameterDeclaration.java
new file mode 100644
index 000000000..cba7d32b1
--- /dev/null
+++ b/javaparser-symbol-solver-core/src/main/java/com/github/javaparser/symbolsolver/javaparsermodel/declarations/JavaParserParameterDeclaration.java
@@ -0,0 +1,100 @@
+/*
+ * Copyright 2016 Federico Tomassetti
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.github.javaparser.symbolsolver.javaparsermodel.declarations;
+
+import com.github.javaparser.ast.body.Parameter;
+import com.github.javaparser.ast.type.UnknownType;
+import com.github.javaparser.resolution.declarations.ResolvedParameterDeclaration;
+import com.github.javaparser.resolution.types.ResolvedArrayType;
+import com.github.javaparser.resolution.types.ResolvedType;
+import com.github.javaparser.symbolsolver.javaparsermodel.JavaParserFacade;
+import com.github.javaparser.symbolsolver.javaparsermodel.JavaParserFactory;
+import com.github.javaparser.symbolsolver.javaparsermodel.contexts.LambdaExprContext;
+import com.github.javaparser.symbolsolver.model.resolution.TypeSolver;
+import com.github.javaparser.symbolsolver.model.resolution.Value;
+
+import java.util.Optional;
+
+/**
+ * @author Federico Tomassetti
+ */
+public class JavaParserParameterDeclaration implements ResolvedParameterDeclaration {
+
+ private Parameter wrappedNode;
+ private TypeSolver typeSolver;
+
+ public JavaParserParameterDeclaration(Parameter wrappedNode, TypeSolver typeSolver) {
+ this.wrappedNode = wrappedNode;
+ this.typeSolver = typeSolver;
+ }
+
+ @Override
+ public String getName() {
+ return wrappedNode.getName().getId();
+ }
+
+ @Override
+ public boolean isField() {
+ return false;
+ }
+
+ @Override
+ public boolean isParameter() {
+ return true;
+ }
+
+ @Override
+ public boolean isVariadic() {
+ return wrappedNode.isVarArgs();
+ }
+
+ @Override
+ public boolean isType() {
+ throw new UnsupportedOperationException();
+ }
+
+ @Override
+ public ResolvedType getType() {
+ if (wrappedNode.getType() instanceof UnknownType && JavaParserFactory.getContext(wrappedNode, typeSolver) instanceof LambdaExprContext) {
+ Optional<Value> value = JavaParserFactory.getContext(wrappedNode, typeSolver).solveSymbolAsValue(wrappedNode.getNameAsString(), typeSolver);
+ if (value.isPresent()) {
+ return value.get().getType();
+ }
+ }
+ ResolvedType res = JavaParserFacade.get(typeSolver).convert(wrappedNode.getType(), wrappedNode);
+ if (isVariadic()) {
+ res = new ResolvedArrayType(res);
+ }
+ return res;
+ }
+
+ @Override
+ public ResolvedParameterDeclaration asParameter() {
+ return this;
+ }
+
+ /**
+ * Returns the JavaParser node associated with this JavaParserParameterDeclaration.
+ *
+ * @return A visitable JavaParser node wrapped by this object.
+ */
+ public Parameter getWrappedNode() {
+ return wrappedNode;
+ }
+
+
+}
diff --git a/javaparser-symbol-solver-core/src/main/java/com/github/javaparser/symbolsolver/javaparsermodel/declarations/JavaParserSymbolDeclaration.java b/javaparser-symbol-solver-core/src/main/java/com/github/javaparser/symbolsolver/javaparsermodel/declarations/JavaParserSymbolDeclaration.java
new file mode 100644
index 000000000..f1f1ffb69
--- /dev/null
+++ b/javaparser-symbol-solver-core/src/main/java/com/github/javaparser/symbolsolver/javaparsermodel/declarations/JavaParserSymbolDeclaration.java
@@ -0,0 +1,171 @@
+/*
+ * Copyright 2016 Federico Tomassetti
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.github.javaparser.symbolsolver.javaparsermodel.declarations;
+
+import com.github.javaparser.ast.Node;
+import com.github.javaparser.ast.body.FieldDeclaration;
+import com.github.javaparser.ast.body.Parameter;
+import com.github.javaparser.ast.body.VariableDeclarator;
+import com.github.javaparser.ast.expr.LambdaExpr;
+import com.github.javaparser.ast.expr.MethodCallExpr;
+import com.github.javaparser.ast.expr.VariableDeclarationExpr;
+import com.github.javaparser.resolution.declarations.ResolvedTypeDeclaration;
+import com.github.javaparser.resolution.declarations.ResolvedValueDeclaration;
+import com.github.javaparser.resolution.types.ResolvedArrayType;
+import com.github.javaparser.resolution.types.ResolvedPrimitiveType;
+import com.github.javaparser.resolution.types.ResolvedType;
+import com.github.javaparser.symbolsolver.javaparsermodel.JavaParserFacade;
+import com.github.javaparser.symbolsolver.javaparsermodel.JavaParserFactory;
+import com.github.javaparser.symbolsolver.model.resolution.TypeSolver;
+
+import static com.github.javaparser.symbolsolver.javaparser.Navigator.requireParentNode;
+
+/**
+ * @author Federico Tomassetti
+ */
+public class JavaParserSymbolDeclaration implements ResolvedValueDeclaration {
+
+ private String name;
+ private Node wrappedNode;
+ private boolean field;
+ private boolean parameter;
+ private boolean variable;
+ private TypeSolver typeSolver;
+
+ private JavaParserSymbolDeclaration(Node wrappedNode, String name, TypeSolver typeSolver, boolean field, boolean parameter, boolean variable) {
+ this.name = name;
+ this.wrappedNode = wrappedNode;
+ this.field = field;
+ this.variable = variable;
+ this.parameter = parameter;
+ this.typeSolver = typeSolver;
+ }
+
+ public static JavaParserFieldDeclaration field(VariableDeclarator wrappedNode, TypeSolver typeSolver) {
+ return new JavaParserFieldDeclaration(wrappedNode, typeSolver);
+ }
+
+ public static JavaParserParameterDeclaration parameter(Parameter parameter, TypeSolver typeSolver) {
+ return new JavaParserParameterDeclaration(parameter, typeSolver);
+ }
+
+ public static JavaParserSymbolDeclaration localVar(VariableDeclarator variableDeclarator, TypeSolver typeSolver) {
+ return new JavaParserSymbolDeclaration(variableDeclarator, variableDeclarator.getName().getId(), typeSolver, false, false, true);
+ }
+
+ public static int getParamPos(Parameter parameter) {
+ int pos = 0;
+ for (Node node : requireParentNode(parameter).getChildNodes()) {
+ if (node == parameter) {
+ return pos;
+ } else if (node instanceof Parameter) {
+ pos++;
+ }
+ }
+ return pos;
+ }
+
+ public static int getParamPos(Node node) {
+ if (requireParentNode(node) instanceof MethodCallExpr) {
+ MethodCallExpr call = (MethodCallExpr) requireParentNode(node);
+ for (int i = 0; i < call.getArguments().size(); i++) {
+ if (call.getArguments().get(i) == node) return i;
+ }
+ throw new IllegalStateException();
+ }
+ throw new IllegalArgumentException();
+ }
+
+ @Override
+ public String toString() {
+ return "JavaParserSymbolDeclaration{" +
+ "name='" + name + '\'' +
+ ", wrappedNode=" + wrappedNode +
+ '}';
+ }
+
+ @Override
+ public String getName() {
+ return name;
+ }
+
+ @Override
+ public boolean isField() {
+ return field;
+ }
+
+ @Override
+ public boolean isParameter() {
+ return parameter;
+ }
+
+ @Override
+ public boolean isType() {
+ return false;
+ }
+
+ @Override
+ public ResolvedType getType() {
+ if (wrappedNode instanceof Parameter) {
+ Parameter parameter = (Parameter) wrappedNode;
+ if (requireParentNode(wrappedNode) instanceof LambdaExpr) {
+ int pos = getParamPos(parameter);
+ ResolvedType lambdaType = JavaParserFacade.get(typeSolver).getType(requireParentNode(wrappedNode));
+
+ // TODO understand from the context to which method this corresponds
+ //MethodDeclaration methodDeclaration = JavaParserFacade.get(typeSolver).getMethodCalled
+ //MethodDeclaration methodCalled = JavaParserFacade.get(typeSolver).solve()
+ throw new UnsupportedOperationException(wrappedNode.getClass().getCanonicalName());
+ } else {
+ final ResolvedType rawType;
+ if (parameter.getType() instanceof com.github.javaparser.ast.type.PrimitiveType) {
+ rawType = ResolvedPrimitiveType.byName(((com.github.javaparser.ast.type.PrimitiveType) parameter.getType()).getType().name());
+ } else {
+ rawType = JavaParserFacade.get(typeSolver).convertToUsage(parameter.getType(), wrappedNode);
+ }
+ if (parameter.isVarArgs()) {
+ return new ResolvedArrayType(rawType);
+ }
+ return rawType;
+ }
+ } else if (wrappedNode instanceof VariableDeclarator) {
+ VariableDeclarator variableDeclarator = (VariableDeclarator) wrappedNode;
+ if (requireParentNode(wrappedNode) instanceof VariableDeclarationExpr) {
+ return JavaParserFacade.get(typeSolver).convert(variableDeclarator.getType(), JavaParserFactory.getContext(wrappedNode, typeSolver));
+ } else if (requireParentNode(wrappedNode) instanceof FieldDeclaration) {
+ return JavaParserFacade.get(typeSolver).convert(variableDeclarator.getType(), JavaParserFactory.getContext(wrappedNode, typeSolver));
+ }
+ }
+ throw new UnsupportedOperationException(wrappedNode.getClass().getCanonicalName());
+ }
+
+ @Override
+ public ResolvedTypeDeclaration asType() {
+ throw new UnsupportedOperationException(this.getClass().getCanonicalName() + ": wrapping " + this.getWrappedNode().getClass().getCanonicalName());
+ }
+
+ /**
+ * Returns the JavaParser node associated with this JavaParserSymbolDeclaration.
+ *
+ * @return A visitable JavaParser node wrapped by this object.
+ */
+ public Node getWrappedNode() {
+ return wrappedNode;
+ }
+
+
+}
diff --git a/javaparser-symbol-solver-core/src/main/java/com/github/javaparser/symbolsolver/javaparsermodel/declarations/JavaParserTypeAdapter.java b/javaparser-symbol-solver-core/src/main/java/com/github/javaparser/symbolsolver/javaparsermodel/declarations/JavaParserTypeAdapter.java
new file mode 100644
index 000000000..198083f7a
--- /dev/null
+++ b/javaparser-symbol-solver-core/src/main/java/com/github/javaparser/symbolsolver/javaparsermodel/declarations/JavaParserTypeAdapter.java
@@ -0,0 +1,140 @@
+package com.github.javaparser.symbolsolver.javaparsermodel.declarations;
+
+import com.github.javaparser.ast.Node;
+import com.github.javaparser.ast.NodeList;
+import com.github.javaparser.ast.body.BodyDeclaration;
+import com.github.javaparser.ast.body.ClassOrInterfaceDeclaration;
+import com.github.javaparser.ast.body.EnumDeclaration;
+import com.github.javaparser.ast.body.VariableDeclarator;
+import com.github.javaparser.ast.nodeTypes.NodeWithMembers;
+import com.github.javaparser.ast.nodeTypes.NodeWithSimpleName;
+import com.github.javaparser.ast.nodeTypes.NodeWithTypeParameters;
+import com.github.javaparser.ast.type.TypeParameter;
+import com.github.javaparser.resolution.declarations.ResolvedFieldDeclaration;
+import com.github.javaparser.resolution.declarations.ResolvedReferenceTypeDeclaration;
+import com.github.javaparser.resolution.declarations.ResolvedTypeDeclaration;
+import com.github.javaparser.resolution.types.ResolvedReferenceType;
+import com.github.javaparser.resolution.types.ResolvedType;
+import com.github.javaparser.symbolsolver.javaparsermodel.JavaParserFactory;
+import com.github.javaparser.symbolsolver.model.resolution.SymbolReference;
+import com.github.javaparser.symbolsolver.model.resolution.TypeSolver;
+import com.github.javaparser.symbolsolver.model.typesystem.ReferenceTypeImpl;
+import com.github.javaparser.symbolsolver.resolution.SymbolSolver;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Optional;
+
+import static com.github.javaparser.symbolsolver.javaparser.Navigator.getParentNode;
+
+/**
+ * @author Federico Tomassetti
+ */
+public class JavaParserTypeAdapter<T extends Node & NodeWithSimpleName<T> & NodeWithMembers<T>> {
+
+ private T wrappedNode;
+ private TypeSolver typeSolver;
+
+ public JavaParserTypeAdapter(T wrappedNode, TypeSolver typeSolver) {
+ this.wrappedNode = wrappedNode;
+ this.typeSolver = typeSolver;
+ }
+
+ public String getPackageName() {
+ return Helper.getPackageName(wrappedNode);
+ }
+
+ public String getClassName() {
+ return Helper.getClassName("", wrappedNode);
+ }
+
+ public String getQualifiedName() {
+ String containerName = Helper.containerName(getParentNode(wrappedNode));
+ if (containerName.isEmpty()) {
+ return wrappedNode.getName().getId();
+ } else {
+ return containerName + "." + wrappedNode.getName().getId();
+ }
+ }
+
+ public boolean isAssignableBy(ResolvedReferenceTypeDeclaration other) {
+ List<ResolvedReferenceType> ancestorsOfOther = other.getAllAncestors();
+ ancestorsOfOther.add(new ReferenceTypeImpl(other, typeSolver));
+ for (ResolvedReferenceType ancestorOfOther : ancestorsOfOther) {
+ if (ancestorOfOther.getQualifiedName().equals(this.getQualifiedName())) {
+ return true;
+ }
+ }
+ return false;
+ }
+
+ public boolean isAssignableBy(ResolvedType type) {
+ if (type.isNull()) {
+ return true;
+ }
+ if (type.isReferenceType()) {
+ ResolvedReferenceTypeDeclaration other = typeSolver.solveType(type.describe());
+ return isAssignableBy(other);
+ } else {
+ throw new UnsupportedOperationException();
+ }
+ }
+
+ public SymbolReference<ResolvedTypeDeclaration> solveType(String name, TypeSolver typeSolver) {
+ if(wrappedNode instanceof NodeWithTypeParameters<?>) {
+ NodeList<TypeParameter> typeParameters = ((NodeWithTypeParameters<?>) wrappedNode).getTypeParameters();
+ for (com.github.javaparser.ast.type.TypeParameter typeParameter : typeParameters) {
+ if (typeParameter.getName().getId().equals(name)) {
+ return SymbolReference.solved(new JavaParserTypeVariableDeclaration(typeParameter, typeSolver));
+ }
+ }
+ }
+
+ // Internal classes
+ for (BodyDeclaration<?> member : this.wrappedNode.getMembers()) {
+ if (member instanceof com.github.javaparser.ast.body.TypeDeclaration) {
+ com.github.javaparser.ast.body.TypeDeclaration<?> internalType = (com.github.javaparser.ast.body.TypeDeclaration<?>) member;
+ String prefix = internalType.getName() + ".";
+ if (internalType.getName().getId().equals(name)) {
+ if (internalType instanceof ClassOrInterfaceDeclaration) {
+ return SymbolReference.solved(new JavaParserClassDeclaration((com.github.javaparser.ast.body.ClassOrInterfaceDeclaration) internalType, typeSolver));
+ } else if (internalType instanceof EnumDeclaration) {
+ return SymbolReference.solved(new JavaParserEnumDeclaration((com.github.javaparser.ast.body.EnumDeclaration) internalType, typeSolver));
+ } else {
+ throw new UnsupportedOperationException();
+ }
+ } else if (name.startsWith(prefix) && name.length() > prefix.length()) {
+ if (internalType instanceof ClassOrInterfaceDeclaration) {
+ return new JavaParserClassDeclaration((com.github.javaparser.ast.body.ClassOrInterfaceDeclaration) internalType, typeSolver).solveType(name.substring(prefix.length()), typeSolver);
+ } else if (internalType instanceof EnumDeclaration) {
+ return new SymbolSolver(typeSolver).solveTypeInType(new JavaParserEnumDeclaration((com.github.javaparser.ast.body.EnumDeclaration) internalType, typeSolver), name.substring(prefix.length()));
+ } else {
+ throw new UnsupportedOperationException();
+ }
+ }
+ }
+ }
+ return SymbolReference.unsolved(ResolvedTypeDeclaration.class);
+ }
+
+ public Optional<ResolvedReferenceTypeDeclaration> containerType() {
+ return wrappedNode
+ .getParentNode()
+ .map(node -> JavaParserFactory.toTypeDeclaration(node, typeSolver));
+ }
+
+ public List<ResolvedFieldDeclaration> getFieldsForDeclaredVariables() {
+ List<ResolvedFieldDeclaration> fields = new ArrayList<>();
+ if (wrappedNode.getMembers() != null) {
+ for (BodyDeclaration<?> member : this.wrappedNode.getMembers()) {
+ if (member instanceof com.github.javaparser.ast.body.FieldDeclaration) {
+ com.github.javaparser.ast.body.FieldDeclaration field = (com.github.javaparser.ast.body.FieldDeclaration) member;
+ for (VariableDeclarator vd : field.getVariables()) {
+ fields.add(new JavaParserFieldDeclaration(vd, typeSolver));
+ }
+ }
+ }
+ }
+ return fields;
+ }
+}
diff --git a/javaparser-symbol-solver-core/src/main/java/com/github/javaparser/symbolsolver/javaparsermodel/declarations/JavaParserTypeParameter.java b/javaparser-symbol-solver-core/src/main/java/com/github/javaparser/symbolsolver/javaparsermodel/declarations/JavaParserTypeParameter.java
new file mode 100644
index 000000000..0d1f42e68
--- /dev/null
+++ b/javaparser-symbol-solver-core/src/main/java/com/github/javaparser/symbolsolver/javaparsermodel/declarations/JavaParserTypeParameter.java
@@ -0,0 +1,223 @@
+/*
+ * Copyright 2016 Federico Tomassetti
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.github.javaparser.symbolsolver.javaparsermodel.declarations;
+
+import com.github.javaparser.ast.Node;
+import com.github.javaparser.ast.body.ClassOrInterfaceDeclaration;
+import com.github.javaparser.ast.type.ClassOrInterfaceType;
+import com.github.javaparser.resolution.declarations.*;
+import com.github.javaparser.resolution.types.ResolvedReferenceType;
+import com.github.javaparser.resolution.types.ResolvedType;
+import com.github.javaparser.symbolsolver.core.resolution.Context;
+import com.github.javaparser.symbolsolver.javaparsermodel.JavaParserFacade;
+import com.github.javaparser.symbolsolver.logic.AbstractTypeDeclaration;
+import com.github.javaparser.symbolsolver.model.resolution.SymbolReference;
+import com.github.javaparser.symbolsolver.model.resolution.TypeSolver;
+import com.github.javaparser.symbolsolver.model.typesystem.ReferenceTypeImpl;
+
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
+import java.util.Optional;
+import java.util.Set;
+import java.util.stream.Collectors;
+
+import static com.github.javaparser.symbolsolver.javaparser.Navigator.requireParentNode;
+
+/**
+ * @author Federico Tomassetti
+ */
+public class JavaParserTypeParameter extends AbstractTypeDeclaration implements ResolvedTypeParameterDeclaration {
+
+ private com.github.javaparser.ast.type.TypeParameter wrappedNode;
+ private TypeSolver typeSolver;
+
+ public JavaParserTypeParameter(com.github.javaparser.ast.type.TypeParameter wrappedNode, TypeSolver typeSolver) {
+ this.wrappedNode = wrappedNode;
+ this.typeSolver = typeSolver;
+ }
+
+ @Override
+ public Set<ResolvedMethodDeclaration> getDeclaredMethods() {
+ return Collections.emptySet();
+ }
+
+ public SymbolReference<ResolvedMethodDeclaration> solveMethod(String name, List<ResolvedType> parameterTypes) {
+ return getContext().solveMethod(name, parameterTypes, false, typeSolver);
+ }
+
+ @Override
+ public boolean equals(Object o) {
+ if (this == o) return true;
+ if (!(o instanceof JavaParserTypeParameter)) return false;
+
+ JavaParserTypeParameter that = (JavaParserTypeParameter) o;
+
+ if (wrappedNode != null ? !wrappedNode.equals(that.wrappedNode) : that.wrappedNode != null) return false;
+
+ return true;
+ }
+
+ @Override
+ public int hashCode() {
+ int result = wrappedNode != null ? wrappedNode.hashCode() : 0;
+ result = 31 * result + (typeSolver != null ? typeSolver.hashCode() : 0);
+ return result;
+ }
+
+ @Override
+ public String getName() {
+ return wrappedNode.getName().getId();
+ }
+
+ @Override
+ public boolean isAssignableBy(ResolvedReferenceTypeDeclaration other) {
+ return isAssignableBy(new ReferenceTypeImpl(other, typeSolver));
+ }
+
+ @Override
+ public String getContainerQualifiedName() {
+ ResolvedTypeParametrizable container = getContainer();
+ if (container instanceof ResolvedReferenceTypeDeclaration) {
+ return ((ResolvedReferenceTypeDeclaration) container).getQualifiedName();
+ } else if (container instanceof JavaParserConstructorDeclaration) {
+ return ((JavaParserConstructorDeclaration) container).getQualifiedSignature();
+ } else {
+ return ((JavaParserMethodDeclaration) container).getQualifiedSignature();
+ }
+ }
+
+ @Override
+ public String getContainerId() {
+ ResolvedTypeParametrizable container = getContainer();
+ if (container instanceof ResolvedReferenceTypeDeclaration) {
+ return ((ResolvedReferenceTypeDeclaration) container).getId();
+ } else if (container instanceof JavaParserConstructorDeclaration) {
+ return ((JavaParserConstructorDeclaration) container).getQualifiedSignature();
+ } else {
+ return ((JavaParserMethodDeclaration) container).getQualifiedSignature();
+ }
+ }
+
+ @Override
+ public ResolvedTypeParametrizable getContainer() {
+ Node parentNode = requireParentNode(wrappedNode);
+ if (parentNode instanceof com.github.javaparser.ast.body.ClassOrInterfaceDeclaration) {
+ com.github.javaparser.ast.body.ClassOrInterfaceDeclaration jpTypeDeclaration = (com.github.javaparser.ast.body.ClassOrInterfaceDeclaration) parentNode;
+ return JavaParserFacade.get(typeSolver).getTypeDeclaration(jpTypeDeclaration);
+ } else if (parentNode instanceof com.github.javaparser.ast.body.ConstructorDeclaration){
+ com.github.javaparser.ast.body.ConstructorDeclaration jpConstructorDeclaration = (com.github.javaparser.ast.body.ConstructorDeclaration) parentNode;
+ Optional<ClassOrInterfaceDeclaration> jpTypeDeclaration = jpConstructorDeclaration.getAncestorOfType(com.github.javaparser.ast.body.ClassOrInterfaceDeclaration.class);
+ if (jpTypeDeclaration.isPresent()) {
+ ResolvedReferenceTypeDeclaration typeDeclaration = JavaParserFacade.get(typeSolver).getTypeDeclaration(jpTypeDeclaration.get());
+ if (typeDeclaration.isClass()) {
+ return new JavaParserConstructorDeclaration(typeDeclaration.asClass(), jpConstructorDeclaration, typeSolver);
+ }
+ }
+ } else {
+ com.github.javaparser.ast.body.MethodDeclaration jpMethodDeclaration = (com.github.javaparser.ast.body.MethodDeclaration) parentNode;
+ return new JavaParserMethodDeclaration(jpMethodDeclaration, typeSolver);
+ }
+ throw new UnsupportedOperationException();
+ }
+
+ @Override
+ public String getQualifiedName() {
+ return String.format("%s.%s", getContainerQualifiedName(), getName());
+ }
+
+ @Override
+ public List<Bound> getBounds() {
+ return wrappedNode.getTypeBound().stream().map((astB) -> toBound(astB, typeSolver)).collect(Collectors.toList());
+ }
+
+ private Bound toBound(ClassOrInterfaceType classOrInterfaceType, TypeSolver typeSolver) {
+ ResolvedType type = JavaParserFacade.get(typeSolver).convertToUsage(classOrInterfaceType, classOrInterfaceType);
+ return Bound.extendsBound(type);
+ }
+
+ public Context getContext() {
+ throw new UnsupportedOperationException();
+ }
+
+ public ResolvedType getUsage(Node node) {
+ throw new UnsupportedOperationException();
+ }
+
+ @Override
+ public boolean isAssignableBy(ResolvedType type) {
+ throw new UnsupportedOperationException();
+ }
+
+ @Override
+ public ResolvedFieldDeclaration getField(String name) {
+ throw new UnsupportedOperationException();
+ }
+
+ @Override
+ public boolean hasField(String name) {
+ return false;
+ }
+
+ @Override
+ public List<ResolvedFieldDeclaration> getAllFields() {
+ return new ArrayList<>();
+ }
+
+ @Override
+ public List<ResolvedReferenceType> getAncestors() {
+ throw new UnsupportedOperationException();
+ }
+
+ @Override
+ public boolean isTypeParameter() {
+ return true;
+ }
+
+ @Override
+ public boolean hasDirectlyAnnotation(String canonicalName) {
+ throw new UnsupportedOperationException();
+ }
+
+ @Override
+ public List<ResolvedTypeParameterDeclaration> getTypeParameters() {
+ return Collections.emptyList();
+ }
+
+ /**
+ * Returns the JavaParser node associated with this JavaParserTypeParameter.
+ *
+ * @return A visitable JavaParser node wrapped by this object.
+ */
+ public com.github.javaparser.ast.type.TypeParameter getWrappedNode() {
+ return wrappedNode;
+ }
+
+ @Override
+ public String toString() {
+ return "JPTypeParameter(" + wrappedNode.getName() + ", bounds=" + wrappedNode.getTypeBound() + ")";
+ }
+
+ @Override
+ public Optional<ResolvedReferenceTypeDeclaration> containerType() {
+ ResolvedTypeParametrizable container = getContainer();
+ if (container instanceof ResolvedReferenceTypeDeclaration) {
+ return Optional.of((ResolvedReferenceTypeDeclaration) container);
+ }
+ return Optional.empty();
+ }
+}
diff --git a/javaparser-symbol-solver-core/src/main/java/com/github/javaparser/symbolsolver/javaparsermodel/declarations/JavaParserTypeVariableDeclaration.java b/javaparser-symbol-solver-core/src/main/java/com/github/javaparser/symbolsolver/javaparsermodel/declarations/JavaParserTypeVariableDeclaration.java
new file mode 100644
index 000000000..a602ebf19
--- /dev/null
+++ b/javaparser-symbol-solver-core/src/main/java/com/github/javaparser/symbolsolver/javaparsermodel/declarations/JavaParserTypeVariableDeclaration.java
@@ -0,0 +1,187 @@
+/*
+ * Copyright 2016 Federico Tomassetti
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.github.javaparser.symbolsolver.javaparsermodel.declarations;
+
+import com.github.javaparser.ast.Node;
+import com.github.javaparser.ast.type.TypeParameter;
+import com.github.javaparser.resolution.declarations.ResolvedFieldDeclaration;
+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.ResolvedReferenceType;
+import com.github.javaparser.resolution.types.ResolvedType;
+import com.github.javaparser.symbolsolver.core.resolution.Context;
+import com.github.javaparser.symbolsolver.logic.AbstractTypeDeclaration;
+import com.github.javaparser.symbolsolver.model.resolution.SymbolReference;
+import com.github.javaparser.symbolsolver.model.resolution.TypeSolver;
+import com.github.javaparser.symbolsolver.model.typesystem.ReferenceTypeImpl;
+
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
+import java.util.Optional;
+import java.util.Set;
+
+/**
+ * @author Federico Tomassetti
+ */
+public class JavaParserTypeVariableDeclaration extends AbstractTypeDeclaration {
+
+ private TypeParameter wrappedNode;
+ private TypeSolver typeSolver;
+
+ public JavaParserTypeVariableDeclaration(TypeParameter wrappedNode, TypeSolver typeSolver) {
+ this.wrappedNode = wrappedNode;
+ this.typeSolver = typeSolver;
+ }
+
+ @Override
+ public boolean isAssignableBy(ResolvedReferenceTypeDeclaration other) {
+ return isAssignableBy(new ReferenceTypeImpl(other, typeSolver));
+ }
+
+ @Override
+ public String getPackageName() {
+ return Helper.getPackageName(wrappedNode);
+ }
+
+ @Override
+ public String getClassName() {
+ return Helper.getClassName("", wrappedNode);
+ }
+
+ @Override
+ public String getQualifiedName() {
+ return getName();
+ }
+
+ public Context getContext() {
+ throw new UnsupportedOperationException();
+ }
+
+ @Override
+ public String toString() {
+ return "JavaParserTypeVariableDeclaration{" +
+ wrappedNode.getName() +
+ '}';
+ }
+
+ public SymbolReference<ResolvedMethodDeclaration> solveMethod(String name, List<ResolvedType> parameterTypes) {
+ throw new UnsupportedOperationException();
+ }
+
+ public ResolvedType getUsage(Node node) {
+ throw new UnsupportedOperationException();
+ }
+
+ @Override
+ public boolean isAssignableBy(ResolvedType type) {
+ if (type.isTypeVariable()) {
+ throw new UnsupportedOperationException("Is this type variable declaration assignable by " + type.describe());
+ } else {
+ throw new UnsupportedOperationException("Is this type variable declaration assignable by " + type);
+ }
+ }
+
+ @Override
+ public boolean isTypeParameter() {
+ return true;
+ }
+
+ @Override
+ public ResolvedFieldDeclaration getField(String name) {
+ throw new UnsupportedOperationException();
+ }
+
+ @Override
+ public boolean hasField(String name) {
+ return false;
+ }
+
+ @Override
+ public List<ResolvedFieldDeclaration> getAllFields() {
+ return new ArrayList<>();
+ }
+
+ @Override
+ public List<ResolvedReferenceType> getAncestors() {
+ throw new UnsupportedOperationException();
+ }
+
+ @Override
+ public Set<ResolvedMethodDeclaration> getDeclaredMethods() {
+ return Collections.emptySet();
+ }
+
+ @Override
+ public String getName() {
+ return wrappedNode.getName().getId();
+ }
+
+ @Override
+ public boolean isField() {
+ throw new UnsupportedOperationException();
+ }
+
+ @Override
+ public boolean isParameter() {
+ throw new UnsupportedOperationException();
+ }
+
+ @Override
+ public boolean isType() {
+ return true;
+ }
+
+ @Override
+ public boolean hasDirectlyAnnotation(String canonicalName) {
+ throw new UnsupportedOperationException();
+ }
+
+ @Override
+ public boolean isClass() {
+ return false;
+ }
+
+ @Override
+ public boolean isInterface() {
+ return false;
+ }
+
+ @Override
+ public List<ResolvedTypeParameterDeclaration> getTypeParameters() {
+ return Collections.emptyList();
+ }
+
+ public ResolvedTypeParameterDeclaration asTypeParameter() {
+ return new JavaParserTypeParameter(this.wrappedNode, typeSolver);
+ }
+
+ /**
+ * Returns the JavaParser node associated with this JavaParserTypeVariableDeclaration.
+ *
+ * @return A visitable JavaParser node wrapped by this object.
+ */
+ public TypeParameter getWrappedNode() {
+ return wrappedNode;
+ }
+
+ @Override
+ public Optional<ResolvedReferenceTypeDeclaration> containerType() {
+ return asTypeParameter().containerType();
+ }
+}
diff --git a/javaparser-symbol-solver-core/src/main/java/com/github/javaparser/symbolsolver/javaparsermodel/declarators/AbstractSymbolDeclarator.java b/javaparser-symbol-solver-core/src/main/java/com/github/javaparser/symbolsolver/javaparsermodel/declarators/AbstractSymbolDeclarator.java
new file mode 100644
index 000000000..14fdafcd0
--- /dev/null
+++ b/javaparser-symbol-solver-core/src/main/java/com/github/javaparser/symbolsolver/javaparsermodel/declarators/AbstractSymbolDeclarator.java
@@ -0,0 +1,35 @@
+/*
+ * Copyright 2016 Federico Tomassetti
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.github.javaparser.symbolsolver.javaparsermodel.declarators;
+
+import com.github.javaparser.ast.Node;
+import com.github.javaparser.symbolsolver.model.resolution.TypeSolver;
+import com.github.javaparser.symbolsolver.resolution.SymbolDeclarator;
+
+/**
+ * @author Federico Tomassetti
+ */
+public abstract class AbstractSymbolDeclarator<N extends Node> implements SymbolDeclarator {
+
+ protected N wrappedNode;
+ protected TypeSolver typeSolver;
+
+ public AbstractSymbolDeclarator(N wrappedNode, TypeSolver typeSolver) {
+ this.wrappedNode = wrappedNode;
+ this.typeSolver = typeSolver;
+ }
+}
diff --git a/javaparser-symbol-solver-core/src/main/java/com/github/javaparser/symbolsolver/javaparsermodel/declarators/FieldSymbolDeclarator.java b/javaparser-symbol-solver-core/src/main/java/com/github/javaparser/symbolsolver/javaparsermodel/declarators/FieldSymbolDeclarator.java
new file mode 100644
index 000000000..dddf7a538
--- /dev/null
+++ b/javaparser-symbol-solver-core/src/main/java/com/github/javaparser/symbolsolver/javaparsermodel/declarators/FieldSymbolDeclarator.java
@@ -0,0 +1,46 @@
+/*
+ * Copyright 2016 Federico Tomassetti
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.github.javaparser.symbolsolver.javaparsermodel.declarators;
+
+import com.github.javaparser.ast.body.FieldDeclaration;
+import com.github.javaparser.ast.body.VariableDeclarator;
+import com.github.javaparser.resolution.declarations.ResolvedValueDeclaration;
+import com.github.javaparser.symbolsolver.javaparsermodel.declarations.JavaParserSymbolDeclaration;
+import com.github.javaparser.symbolsolver.model.resolution.TypeSolver;
+
+import java.util.LinkedList;
+import java.util.List;
+
+/**
+ * @author Federico Tomassetti
+ */
+public class FieldSymbolDeclarator extends AbstractSymbolDeclarator<FieldDeclaration> {
+
+ public FieldSymbolDeclarator(FieldDeclaration wrappedNode, TypeSolver typeSolver) {
+ super(wrappedNode, typeSolver);
+ }
+
+ @Override
+ public List<ResolvedValueDeclaration> getSymbolDeclarations() {
+ List<ResolvedValueDeclaration> symbols = new LinkedList<>();
+ for (VariableDeclarator v : wrappedNode.getVariables()) {
+ symbols.add(JavaParserSymbolDeclaration.field(v, typeSolver));
+ }
+ return symbols;
+ }
+
+}
diff --git a/javaparser-symbol-solver-core/src/main/java/com/github/javaparser/symbolsolver/javaparsermodel/declarators/NoSymbolDeclarator.java b/javaparser-symbol-solver-core/src/main/java/com/github/javaparser/symbolsolver/javaparsermodel/declarators/NoSymbolDeclarator.java
new file mode 100644
index 000000000..e950b70ee
--- /dev/null
+++ b/javaparser-symbol-solver-core/src/main/java/com/github/javaparser/symbolsolver/javaparsermodel/declarators/NoSymbolDeclarator.java
@@ -0,0 +1,40 @@
+/*
+ * Copyright 2016 Federico Tomassetti
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.github.javaparser.symbolsolver.javaparsermodel.declarators;
+
+import com.github.javaparser.ast.Node;
+import com.github.javaparser.resolution.declarations.ResolvedValueDeclaration;
+import com.github.javaparser.symbolsolver.model.resolution.TypeSolver;
+
+import java.util.Collections;
+import java.util.List;
+
+/**
+ * @author Federico Tomassetti
+ */
+public class NoSymbolDeclarator<N extends Node> extends AbstractSymbolDeclarator<N> {
+
+ public NoSymbolDeclarator(N wrappedNode, TypeSolver typeSolver) {
+ super(wrappedNode, typeSolver);
+ }
+
+ @Override
+ public List<ResolvedValueDeclaration> getSymbolDeclarations() {
+ return Collections.emptyList();
+ }
+
+}
diff --git a/javaparser-symbol-solver-core/src/main/java/com/github/javaparser/symbolsolver/javaparsermodel/declarators/ParameterSymbolDeclarator.java b/javaparser-symbol-solver-core/src/main/java/com/github/javaparser/symbolsolver/javaparsermodel/declarators/ParameterSymbolDeclarator.java
new file mode 100644
index 000000000..45d8e160f
--- /dev/null
+++ b/javaparser-symbol-solver-core/src/main/java/com/github/javaparser/symbolsolver/javaparsermodel/declarators/ParameterSymbolDeclarator.java
@@ -0,0 +1,42 @@
+/*
+ * Copyright 2016 Federico Tomassetti
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.github.javaparser.symbolsolver.javaparsermodel.declarators;
+
+import com.github.javaparser.ast.body.Parameter;
+import com.github.javaparser.resolution.declarations.ResolvedValueDeclaration;
+import com.github.javaparser.symbolsolver.javaparsermodel.declarations.JavaParserSymbolDeclaration;
+import com.github.javaparser.symbolsolver.model.resolution.TypeSolver;
+
+import java.util.LinkedList;
+import java.util.List;
+
+/**
+ * @author Federico Tomassetti
+ */
+public class ParameterSymbolDeclarator extends AbstractSymbolDeclarator<Parameter> {
+
+ public ParameterSymbolDeclarator(Parameter wrappedNode, TypeSolver typeSolver) {
+ super(wrappedNode, typeSolver);
+ }
+
+ @Override
+ public List<ResolvedValueDeclaration> getSymbolDeclarations() {
+ List<ResolvedValueDeclaration> symbols = new LinkedList<>();
+ symbols.add(JavaParserSymbolDeclaration.parameter(wrappedNode, typeSolver));
+ return symbols;
+ }
+}
diff --git a/javaparser-symbol-solver-core/src/main/java/com/github/javaparser/symbolsolver/javaparsermodel/declarators/VariableSymbolDeclarator.java b/javaparser-symbol-solver-core/src/main/java/com/github/javaparser/symbolsolver/javaparsermodel/declarators/VariableSymbolDeclarator.java
new file mode 100644
index 000000000..88865de0d
--- /dev/null
+++ b/javaparser-symbol-solver-core/src/main/java/com/github/javaparser/symbolsolver/javaparsermodel/declarators/VariableSymbolDeclarator.java
@@ -0,0 +1,52 @@
+/*
+ * Copyright 2016 Federico Tomassetti
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.github.javaparser.symbolsolver.javaparsermodel.declarators;
+
+import com.github.javaparser.ast.body.FieldDeclaration;
+import com.github.javaparser.ast.expr.VariableDeclarationExpr;
+import com.github.javaparser.resolution.declarations.ResolvedValueDeclaration;
+import com.github.javaparser.symbolsolver.javaparsermodel.declarations.JavaParserSymbolDeclaration;
+import com.github.javaparser.symbolsolver.model.resolution.TypeSolver;
+
+import java.util.LinkedList;
+import java.util.List;
+import java.util.stream.Collectors;
+
+import static com.github.javaparser.symbolsolver.javaparser.Navigator.getParentNode;
+
+/**
+ * @author Federico Tomassetti
+ */
+public class VariableSymbolDeclarator extends AbstractSymbolDeclarator<VariableDeclarationExpr> {
+
+ public VariableSymbolDeclarator(VariableDeclarationExpr wrappedNode, TypeSolver typeSolver) {
+ super(wrappedNode, typeSolver);
+ wrappedNode.getParentNode().ifPresent(p -> {
+ if (p instanceof FieldDeclaration) {
+ throw new IllegalArgumentException();
+ }
+ });
+ }
+
+ @Override
+ public List<ResolvedValueDeclaration> getSymbolDeclarations() {
+ return wrappedNode.getVariables().stream()
+ .map(v -> JavaParserSymbolDeclaration.localVar(v, typeSolver))
+ .collect(Collectors.toCollection(LinkedList::new));
+ }
+
+}
diff --git a/javaparser-symbol-solver-core/src/main/java/com/github/javaparser/symbolsolver/javaparsermodel/package-info.java b/javaparser-symbol-solver-core/src/main/java/com/github/javaparser/symbolsolver/javaparsermodel/package-info.java
new file mode 100644
index 000000000..9ddf1cf01
--- /dev/null
+++ b/javaparser-symbol-solver-core/src/main/java/com/github/javaparser/symbolsolver/javaparsermodel/package-info.java
@@ -0,0 +1,20 @@
+/*
+ * Copyright 2016 Federico Tomassetti
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/**
+ * Implementation of model based on JavaParser.
+ */
+package com.github.javaparser.symbolsolver.javaparsermodel; \ No newline at end of file