1 /* 2 * Copyright 2016 Federico Tomassetti 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 package com.github.javaparser.symbolsolver.javaparsermodel; 18 19 import com.github.javaparser.ast.CompilationUnit; 20 import com.github.javaparser.ast.Node; 21 import com.github.javaparser.ast.body.*; 22 import com.github.javaparser.ast.expr.*; 23 import com.github.javaparser.ast.stmt.*; 24 import com.github.javaparser.ast.type.TypeParameter; 25 import com.github.javaparser.resolution.declarations.ResolvedReferenceTypeDeclaration; 26 import com.github.javaparser.symbolsolver.core.resolution.Context; 27 import com.github.javaparser.symbolsolver.javaparsermodel.contexts.*; 28 import com.github.javaparser.symbolsolver.javaparsermodel.declarations.JavaParserAnnotationDeclaration; 29 import com.github.javaparser.symbolsolver.javaparsermodel.declarations.JavaParserClassDeclaration; 30 import com.github.javaparser.symbolsolver.javaparsermodel.declarations.JavaParserEnumDeclaration; 31 import com.github.javaparser.symbolsolver.javaparsermodel.declarations.JavaParserInterfaceDeclaration; 32 import com.github.javaparser.symbolsolver.javaparsermodel.declarations.JavaParserTypeParameter; 33 import com.github.javaparser.symbolsolver.javaparsermodel.declarators.FieldSymbolDeclarator; 34 import com.github.javaparser.symbolsolver.javaparsermodel.declarators.NoSymbolDeclarator; 35 import com.github.javaparser.symbolsolver.javaparsermodel.declarators.ParameterSymbolDeclarator; 36 import com.github.javaparser.symbolsolver.javaparsermodel.declarators.VariableSymbolDeclarator; 37 import com.github.javaparser.symbolsolver.model.resolution.TypeSolver; 38 import com.github.javaparser.symbolsolver.resolution.SymbolDeclarator; 39 40 import static com.github.javaparser.symbolsolver.javaparser.Navigator.getParentNode; 41 import static com.github.javaparser.symbolsolver.javaparser.Navigator.requireParentNode; 42 43 /** 44 * @author Federico Tomassetti 45 */ 46 public class JavaParserFactory { 47 48 public static Context getContext(Node node, TypeSolver typeSolver) { 49 if (node == null) { 50 throw new NullPointerException("Node should not be null"); 51 } else if (node instanceof CompilationUnit) { 52 return new CompilationUnitContext((CompilationUnit) node, typeSolver); 53 } else if (node instanceof ForeachStmt) { 54 return new ForechStatementContext((ForeachStmt) node, typeSolver); 55 } else if (node instanceof ForStmt) { 56 return new ForStatementContext((ForStmt) node, typeSolver); 57 } else if (node instanceof LambdaExpr) { 58 return new LambdaExprContext((LambdaExpr) node, typeSolver); 59 } else if (node instanceof MethodDeclaration) { 60 return new MethodContext((MethodDeclaration) node, typeSolver); 61 } else if (node instanceof ConstructorDeclaration) { 62 return new ConstructorContext((ConstructorDeclaration) node, typeSolver); 63 } else if (node instanceof ClassOrInterfaceDeclaration) { 64 return new ClassOrInterfaceDeclarationContext((ClassOrInterfaceDeclaration) node, typeSolver); 65 } else if (node instanceof MethodCallExpr) { 66 return new MethodCallExprContext((MethodCallExpr) node, typeSolver); 67 } else if (node instanceof EnumDeclaration) { 68 return new EnumDeclarationContext((EnumDeclaration) node, typeSolver); 69 } else if (node instanceof FieldAccessExpr) { 70 return new FieldAccessContext((FieldAccessExpr) node, typeSolver); 71 } else if (node instanceof SwitchEntryStmt) { 72 return new SwitchEntryContext((SwitchEntryStmt) node, typeSolver); 73 } else if (node instanceof TryStmt) { 74 return new TryWithResourceContext((TryStmt) node, typeSolver); 75 } else if (node instanceof Statement) { 76 return new StatementContext<>((Statement) node, typeSolver); 77 } else if (node instanceof CatchClause) { 78 return new CatchClauseContext((CatchClause) node, typeSolver); 79 } else if (node instanceof ObjectCreationExpr && 80 ((ObjectCreationExpr) node).getAnonymousClassBody().isPresent()) { 81 return new AnonymousClassDeclarationContext((ObjectCreationExpr) node, typeSolver); 82 } else { 83 if (node instanceof NameExpr) { 84 // 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) 85 if (node.getParentNode().isPresent() && node.getParentNode().get() instanceof FieldAccessExpr && node.getParentNode().get().getParentNode().isPresent()) { 86 return getContext(node.getParentNode().get().getParentNode().get(), typeSolver); 87 } 88 } 89 final Node parentNode = requireParentNode(node); 90 if (parentNode instanceof ObjectCreationExpr && node == ((ObjectCreationExpr) parentNode).getType()) { 91 return getContext(requireParentNode(parentNode), typeSolver); 92 } 93 if (parentNode == null) { 94 throw new IllegalStateException("The AST node does not appear to be inserted in a propert AST, therefore we cannot resolve symbols correctly"); 95 } 96 return getContext(parentNode, typeSolver); 97 } 98 } 99 100 public static SymbolDeclarator getSymbolDeclarator(Node node, TypeSolver typeSolver) { 101 if (node instanceof FieldDeclaration) { 102 return new FieldSymbolDeclarator((FieldDeclaration) node, typeSolver); 103 } else if (node instanceof Parameter) { 104 return new ParameterSymbolDeclarator((Parameter) node, typeSolver); 105 } else if (node instanceof ExpressionStmt) { 106 ExpressionStmt expressionStmt = (ExpressionStmt) node; 107 if (expressionStmt.getExpression() instanceof VariableDeclarationExpr) { 108 return new VariableSymbolDeclarator((VariableDeclarationExpr) (expressionStmt.getExpression()), typeSolver); 109 } else { 110 return new NoSymbolDeclarator<>(expressionStmt, typeSolver); 111 } 112 } else if (node instanceof IfStmt) { 113 return new NoSymbolDeclarator<>((IfStmt) node, typeSolver); 114 } else if (node instanceof ForeachStmt) { 115 ForeachStmt foreachStmt = (ForeachStmt) node; 116 return new VariableSymbolDeclarator(foreachStmt.getVariable(), typeSolver); 117 } else { 118 return new NoSymbolDeclarator<>(node, typeSolver); 119 } 120 } 121 122 public static ResolvedReferenceTypeDeclaration toTypeDeclaration(Node node, TypeSolver typeSolver) { 123 if (node instanceof ClassOrInterfaceDeclaration) { 124 if (((ClassOrInterfaceDeclaration) node).isInterface()) { 125 return new JavaParserInterfaceDeclaration((ClassOrInterfaceDeclaration) node, typeSolver); 126 } else { 127 return new JavaParserClassDeclaration((ClassOrInterfaceDeclaration) node, typeSolver); 128 } 129 } else if (node instanceof TypeParameter) { 130 return new JavaParserTypeParameter((TypeParameter) node, typeSolver); 131 } else if (node instanceof EnumDeclaration) { 132 return new JavaParserEnumDeclaration((EnumDeclaration) node, typeSolver); 133 } else if (node instanceof AnnotationDeclaration) { 134 return new JavaParserAnnotationDeclaration((AnnotationDeclaration) node, typeSolver); 135 } else { 136 throw new IllegalArgumentException(node.getClass().getCanonicalName()); 137 } 138 } 139 } 140