Home | History | Annotate | Download | only in javaparsermodel
      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