1683012de2a3a28358e848f8b145d462eb8b322baFederico Tomassetti/*
2683012de2a3a28358e848f8b145d462eb8b322baFederico Tomassetti * Copyright 2016 Federico Tomassetti
3683012de2a3a28358e848f8b145d462eb8b322baFederico Tomassetti *
4683012de2a3a28358e848f8b145d462eb8b322baFederico Tomassetti * Licensed under the Apache License, Version 2.0 (the "License");
5683012de2a3a28358e848f8b145d462eb8b322baFederico Tomassetti * you may not use this file except in compliance with the License.
6683012de2a3a28358e848f8b145d462eb8b322baFederico Tomassetti * You may obtain a copy of the License at
7683012de2a3a28358e848f8b145d462eb8b322baFederico Tomassetti *
8683012de2a3a28358e848f8b145d462eb8b322baFederico Tomassetti * http://www.apache.org/licenses/LICENSE-2.0
9683012de2a3a28358e848f8b145d462eb8b322baFederico Tomassetti *
10683012de2a3a28358e848f8b145d462eb8b322baFederico Tomassetti * Unless required by applicable law or agreed to in writing, software
11683012de2a3a28358e848f8b145d462eb8b322baFederico Tomassetti * distributed under the License is distributed on an "AS IS" BASIS,
12683012de2a3a28358e848f8b145d462eb8b322baFederico Tomassetti * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13683012de2a3a28358e848f8b145d462eb8b322baFederico Tomassetti * See the License for the specific language governing permissions and
14683012de2a3a28358e848f8b145d462eb8b322baFederico Tomassetti * limitations under the License.
15683012de2a3a28358e848f8b145d462eb8b322baFederico Tomassetti */
16683012de2a3a28358e848f8b145d462eb8b322baFederico Tomassetti
179c53c2cbc607ea694438ade8630be0c155a33162Federico Tomassettipackage com.github.javaparser.symbolsolver.javaparsermodel;
18d787c16867577551b1711d01f382a26af1d7a322Federico Tomassetti
1949719b4acbe10e3714ceb4f7040acac34709f558Federico Tomassettiimport com.github.javaparser.ast.CompilationUnit;
2049719b4acbe10e3714ceb4f7040acac34709f558Federico Tomassettiimport com.github.javaparser.ast.Node;
21d787c16867577551b1711d01f382a26af1d7a322Federico Tomassettiimport com.github.javaparser.ast.body.*;
22cb5ffb7fdd56f1b768d25da330fa3b29ecb74eafFederico Tomassettiimport com.github.javaparser.ast.expr.*;
23d787c16867577551b1711d01f382a26af1d7a322Federico Tomassettiimport com.github.javaparser.ast.stmt.*;
24e46b2e316d95fe409d88d9918e31379ad09c159bmalte_langkabelimport com.github.javaparser.ast.type.TypeParameter;
25c3dc3669e86f005080c02e62162356022eafaac1Federico Tomassettiimport com.github.javaparser.resolution.declarations.ResolvedReferenceTypeDeclaration;
261e7780e554428a10c73de88ca64e5933b2291593Federico Tomassettiimport com.github.javaparser.symbolsolver.core.resolution.Context;
279c53c2cbc607ea694438ade8630be0c155a33162Federico Tomassettiimport com.github.javaparser.symbolsolver.javaparsermodel.contexts.*;
28e46b2e316d95fe409d88d9918e31379ad09c159bmalte_langkabelimport com.github.javaparser.symbolsolver.javaparsermodel.declarations.JavaParserAnnotationDeclaration;
29e46b2e316d95fe409d88d9918e31379ad09c159bmalte_langkabelimport com.github.javaparser.symbolsolver.javaparsermodel.declarations.JavaParserClassDeclaration;
30e46b2e316d95fe409d88d9918e31379ad09c159bmalte_langkabelimport com.github.javaparser.symbolsolver.javaparsermodel.declarations.JavaParserEnumDeclaration;
31e46b2e316d95fe409d88d9918e31379ad09c159bmalte_langkabelimport com.github.javaparser.symbolsolver.javaparsermodel.declarations.JavaParserInterfaceDeclaration;
32e46b2e316d95fe409d88d9918e31379ad09c159bmalte_langkabelimport com.github.javaparser.symbolsolver.javaparsermodel.declarations.JavaParserTypeParameter;
339c53c2cbc607ea694438ade8630be0c155a33162Federico Tomassettiimport com.github.javaparser.symbolsolver.javaparsermodel.declarators.FieldSymbolDeclarator;
349c53c2cbc607ea694438ade8630be0c155a33162Federico Tomassettiimport com.github.javaparser.symbolsolver.javaparsermodel.declarators.NoSymbolDeclarator;
359c53c2cbc607ea694438ade8630be0c155a33162Federico Tomassettiimport com.github.javaparser.symbolsolver.javaparsermodel.declarators.ParameterSymbolDeclarator;
361e7780e554428a10c73de88ca64e5933b2291593Federico Tomassettiimport com.github.javaparser.symbolsolver.javaparsermodel.declarators.VariableSymbolDeclarator;
371e7780e554428a10c73de88ca64e5933b2291593Federico Tomassettiimport com.github.javaparser.symbolsolver.model.resolution.TypeSolver;
381e7780e554428a10c73de88ca64e5933b2291593Federico Tomassettiimport com.github.javaparser.symbolsolver.resolution.SymbolDeclarator;
39d787c16867577551b1711d01f382a26af1d7a322Federico Tomassetti
4099c0277ff34b0d97af1019ac91f20a19db364410Federico Tomassettiimport static com.github.javaparser.symbolsolver.javaparser.Navigator.getParentNode;
41b54617e765d73b3ce0d187cf12ad8da382bce439Danny van Bruggenimport static com.github.javaparser.symbolsolver.javaparser.Navigator.requireParentNode;
423e4b012ca278ee33e9e02984367028cb1adf4bf5Federico Tomassetti
43c746c4ef7711a05c27827ab749d96155046a4f91Federico Tomassetti/**
44c746c4ef7711a05c27827ab749d96155046a4f91Federico Tomassetti * @author Federico Tomassetti
45c746c4ef7711a05c27827ab749d96155046a4f91Federico Tomassetti */
46d787c16867577551b1711d01f382a26af1d7a322Federico Tomassettipublic class JavaParserFactory {
47d787c16867577551b1711d01f382a26af1d7a322Federico Tomassetti
4849719b4acbe10e3714ceb4f7040acac34709f558Federico Tomassetti    public static Context getContext(Node node, TypeSolver typeSolver) {
49c1e95efcb4b0a373530aa107edb2164bf6c21ac7Federico Tomassetti        if (node == null) {
50478a9ba268137913d67438b1e3c8f61e5e0976a5Federico Tomassetti            throw new NullPointerException("Node should not be null");
51c1e95efcb4b0a373530aa107edb2164bf6c21ac7Federico Tomassetti        } else if (node instanceof CompilationUnit) {
5249719b4acbe10e3714ceb4f7040acac34709f558Federico Tomassetti            return new CompilationUnitContext((CompilationUnit) node, typeSolver);
53bac18a129c45335e69d811b3872fcb938e1f0ff8Federico Tomassetti        } else if (node instanceof ForeachStmt) {
5449719b4acbe10e3714ceb4f7040acac34709f558Federico Tomassetti            return new ForechStatementContext((ForeachStmt) node, typeSolver);
55bac18a129c45335e69d811b3872fcb938e1f0ff8Federico Tomassetti        } else if (node instanceof ForStmt) {
5649719b4acbe10e3714ceb4f7040acac34709f558Federico Tomassetti            return new ForStatementContext((ForStmt) node, typeSolver);
5749719b4acbe10e3714ceb4f7040acac34709f558Federico Tomassetti        } else if (node instanceof LambdaExpr) {
580e81f51c40996b42cb262dc2397126cee8f60965Federico Tomassetti            return new LambdaExprContext((LambdaExpr) node, typeSolver);
59d787c16867577551b1711d01f382a26af1d7a322Federico Tomassetti        } else if (node instanceof MethodDeclaration) {
6049719b4acbe10e3714ceb4f7040acac34709f558Federico Tomassetti            return new MethodContext((MethodDeclaration) node, typeSolver);
61ee35b15a04539af508d29081ac5c7f8f6fadba4aFederico Tomassetti        } else if (node instanceof ConstructorDeclaration) {
6249719b4acbe10e3714ceb4f7040acac34709f558Federico Tomassetti            return new ConstructorContext((ConstructorDeclaration) node, typeSolver);
63d787c16867577551b1711d01f382a26af1d7a322Federico Tomassetti        } else if (node instanceof ClassOrInterfaceDeclaration) {
6449719b4acbe10e3714ceb4f7040acac34709f558Federico Tomassetti            return new ClassOrInterfaceDeclarationContext((ClassOrInterfaceDeclaration) node, typeSolver);
652f49331fb22511346eea8800d27907de44409d5bFederico Tomassetti        } else if (node instanceof MethodCallExpr) {
6649719b4acbe10e3714ceb4f7040acac34709f558Federico Tomassetti            return new MethodCallExprContext((MethodCallExpr) node, typeSolver);
67d787c16867577551b1711d01f382a26af1d7a322Federico Tomassetti        } else if (node instanceof EnumDeclaration) {
6849719b4acbe10e3714ceb4f7040acac34709f558Federico Tomassetti            return new EnumDeclarationContext((EnumDeclaration) node, typeSolver);
6980f951258992f75441239c79e0f31eda7d47e107Federico Tomassetti        } else if (node instanceof FieldAccessExpr) {
700e81f51c40996b42cb262dc2397126cee8f60965Federico Tomassetti            return new FieldAccessContext((FieldAccessExpr) node, typeSolver);
71d0348de241a6cf6be9c51500870ee1fb26172101Federico Tomassetti        } else if (node instanceof SwitchEntryStmt) {
720e81f51c40996b42cb262dc2397126cee8f60965Federico Tomassetti            return new SwitchEntryContext((SwitchEntryStmt) node, typeSolver);
730317a878f854ddf986b70febd30d3c209ae49150Federico Tomassetti        } else if (node instanceof TryStmt) {
740317a878f854ddf986b70febd30d3c209ae49150Federico Tomassetti            return new TryWithResourceContext((TryStmt) node, typeSolver);
75bac18a129c45335e69d811b3872fcb938e1f0ff8Federico Tomassetti        } else if (node instanceof Statement) {
76b54617e765d73b3ce0d187cf12ad8da382bce439Danny van Bruggen            return new StatementContext<>((Statement) node, typeSolver);
77c990d23490f5c4ac4322119b03d5951b63eef055Fred Lefévère-Laoide        } else if (node instanceof CatchClause) {
78cb5ffb7fdd56f1b768d25da330fa3b29ecb74eafFederico Tomassetti            return new CatchClauseContext((CatchClause) node, typeSolver);
792eb011fa9f43f30e3cb8bcad8c40520bb80437c7Enno Boland        } else if (node instanceof ObjectCreationExpr &&
802eb011fa9f43f30e3cb8bcad8c40520bb80437c7Enno Boland            ((ObjectCreationExpr) node).getAnonymousClassBody().isPresent()) {
812eb011fa9f43f30e3cb8bcad8c40520bb80437c7Enno Boland            return new AnonymousClassDeclarationContext((ObjectCreationExpr) node, typeSolver);
82d787c16867577551b1711d01f382a26af1d7a322Federico Tomassetti        } else {
83cb5ffb7fdd56f1b768d25da330fa3b29ecb74eafFederico Tomassetti            if (node instanceof NameExpr) {
84cb5ffb7fdd56f1b768d25da330fa3b29ecb74eafFederico Tomassetti                // 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)
85cb5ffb7fdd56f1b768d25da330fa3b29ecb74eafFederico Tomassetti                if (node.getParentNode().isPresent() && node.getParentNode().get() instanceof FieldAccessExpr && node.getParentNode().get().getParentNode().isPresent()) {
86cb5ffb7fdd56f1b768d25da330fa3b29ecb74eafFederico Tomassetti                    return getContext(node.getParentNode().get().getParentNode().get(), typeSolver);
87cb5ffb7fdd56f1b768d25da330fa3b29ecb74eafFederico Tomassetti                }
88c990d23490f5c4ac4322119b03d5951b63eef055Fred Lefévère-Laoide            }
89b54617e765d73b3ce0d187cf12ad8da382bce439Danny van Bruggen            final Node parentNode = requireParentNode(node);
90478a9ba268137913d67438b1e3c8f61e5e0976a5Federico Tomassetti            if (parentNode instanceof ObjectCreationExpr && node == ((ObjectCreationExpr) parentNode).getType()) {
91b54617e765d73b3ce0d187cf12ad8da382bce439Danny van Bruggen                return getContext(requireParentNode(parentNode), typeSolver);
92150cf7cfd77ccfcf18384cacf4c03cd3dc6308d3Enno Boland            }
93478a9ba268137913d67438b1e3c8f61e5e0976a5Federico Tomassetti            if (parentNode == null) {
94478a9ba268137913d67438b1e3c8f61e5e0976a5Federico Tomassetti                throw new IllegalStateException("The AST node does not appear to be inserted in a propert AST, therefore we cannot resolve symbols correctly");
95478a9ba268137913d67438b1e3c8f61e5e0976a5Federico Tomassetti            }
96150cf7cfd77ccfcf18384cacf4c03cd3dc6308d3Enno Boland            return getContext(parentNode, typeSolver);
97d787c16867577551b1711d01f382a26af1d7a322Federico Tomassetti        }
98d787c16867577551b1711d01f382a26af1d7a322Federico Tomassetti    }
99d787c16867577551b1711d01f382a26af1d7a322Federico Tomassetti
10049719b4acbe10e3714ceb4f7040acac34709f558Federico Tomassetti    public static SymbolDeclarator getSymbolDeclarator(Node node, TypeSolver typeSolver) {
101c8d91389efa6f0d989d1b7d1e1aebec9d04106e7Federico Tomassetti        if (node instanceof FieldDeclaration) {
1022f49331fb22511346eea8800d27907de44409d5bFederico Tomassetti            return new FieldSymbolDeclarator((FieldDeclaration) node, typeSolver);
103b931fdff234a0313a34e920059c1f5135fdd5204Federico Tomassetti        } else if (node instanceof Parameter) {
1042f49331fb22511346eea8800d27907de44409d5bFederico Tomassetti            return new ParameterSymbolDeclarator((Parameter) node, typeSolver);
10552ce3a035f37392b37e54c9c7d9b003356d77643Federico Tomassetti        } else if (node instanceof ExpressionStmt) {
1066c297529e31036058837adbaa57cee652d4cc918Federico Tomassetti            ExpressionStmt expressionStmt = (ExpressionStmt) node;
10752ce3a035f37392b37e54c9c7d9b003356d77643Federico Tomassetti            if (expressionStmt.getExpression() instanceof VariableDeclarationExpr) {
1086c297529e31036058837adbaa57cee652d4cc918Federico Tomassetti                return new VariableSymbolDeclarator((VariableDeclarationExpr) (expressionStmt.getExpression()), typeSolver);
10952ce3a035f37392b37e54c9c7d9b003356d77643Federico Tomassetti            } else {
110b54617e765d73b3ce0d187cf12ad8da382bce439Danny van Bruggen                return new NoSymbolDeclarator<>(expressionStmt, typeSolver);
11152ce3a035f37392b37e54c9c7d9b003356d77643Federico Tomassetti            }
1126c297529e31036058837adbaa57cee652d4cc918Federico Tomassetti        } else if (node instanceof IfStmt) {
113b54617e765d73b3ce0d187cf12ad8da382bce439Danny van Bruggen            return new NoSymbolDeclarator<>((IfStmt) node, typeSolver);
114bac18a129c45335e69d811b3872fcb938e1f0ff8Federico Tomassetti        } else if (node instanceof ForeachStmt) {
11549719b4acbe10e3714ceb4f7040acac34709f558Federico Tomassetti            ForeachStmt foreachStmt = (ForeachStmt) node;
116b54617e765d73b3ce0d187cf12ad8da382bce439Danny van Bruggen            return new VariableSymbolDeclarator(foreachStmt.getVariable(), typeSolver);
117c8d91389efa6f0d989d1b7d1e1aebec9d04106e7Federico Tomassetti        } else {
118b54617e765d73b3ce0d187cf12ad8da382bce439Danny van Bruggen            return new NoSymbolDeclarator<>(node, typeSolver);
119c8d91389efa6f0d989d1b7d1e1aebec9d04106e7Federico Tomassetti        }
120d787c16867577551b1711d01f382a26af1d7a322Federico Tomassetti    }
121e46b2e316d95fe409d88d9918e31379ad09c159bmalte_langkabel
122c3dc3669e86f005080c02e62162356022eafaac1Federico Tomassetti    public static ResolvedReferenceTypeDeclaration toTypeDeclaration(Node node, TypeSolver typeSolver) {
123e46b2e316d95fe409d88d9918e31379ad09c159bmalte_langkabel        if (node instanceof ClassOrInterfaceDeclaration) {
124e46b2e316d95fe409d88d9918e31379ad09c159bmalte_langkabel            if (((ClassOrInterfaceDeclaration) node).isInterface()) {
125e46b2e316d95fe409d88d9918e31379ad09c159bmalte_langkabel                return new JavaParserInterfaceDeclaration((ClassOrInterfaceDeclaration) node, typeSolver);
126e46b2e316d95fe409d88d9918e31379ad09c159bmalte_langkabel            } else {
127e46b2e316d95fe409d88d9918e31379ad09c159bmalte_langkabel                return new JavaParserClassDeclaration((ClassOrInterfaceDeclaration) node, typeSolver);
128e46b2e316d95fe409d88d9918e31379ad09c159bmalte_langkabel            }
129e46b2e316d95fe409d88d9918e31379ad09c159bmalte_langkabel        } else if (node instanceof TypeParameter) {
130e46b2e316d95fe409d88d9918e31379ad09c159bmalte_langkabel            return new JavaParserTypeParameter((TypeParameter) node, typeSolver);
131e46b2e316d95fe409d88d9918e31379ad09c159bmalte_langkabel        } else if (node instanceof EnumDeclaration) {
132e46b2e316d95fe409d88d9918e31379ad09c159bmalte_langkabel            return new JavaParserEnumDeclaration((EnumDeclaration) node, typeSolver);
133e46b2e316d95fe409d88d9918e31379ad09c159bmalte_langkabel        } else if (node instanceof AnnotationDeclaration) {
134e46b2e316d95fe409d88d9918e31379ad09c159bmalte_langkabel            return new JavaParserAnnotationDeclaration((AnnotationDeclaration) node, typeSolver);
135e46b2e316d95fe409d88d9918e31379ad09c159bmalte_langkabel        } else {
136e46b2e316d95fe409d88d9918e31379ad09c159bmalte_langkabel            throw new IllegalArgumentException(node.getClass().getCanonicalName());
137e46b2e316d95fe409d88d9918e31379ad09c159bmalte_langkabel        }
138e46b2e316d95fe409d88d9918e31379ad09c159bmalte_langkabel    }
139d787c16867577551b1711d01f382a26af1d7a322Federico Tomassetti}
140