Home | History | Annotate | Download | only in declarations
      1 package com.github.javaparser.symbolsolver.javaparsermodel.declarations;
      2 
      3 import com.github.javaparser.ast.Node;
      4 import com.github.javaparser.ast.NodeList;
      5 import com.github.javaparser.ast.body.BodyDeclaration;
      6 import com.github.javaparser.ast.body.ClassOrInterfaceDeclaration;
      7 import com.github.javaparser.ast.body.EnumDeclaration;
      8 import com.github.javaparser.ast.body.VariableDeclarator;
      9 import com.github.javaparser.ast.nodeTypes.NodeWithMembers;
     10 import com.github.javaparser.ast.nodeTypes.NodeWithSimpleName;
     11 import com.github.javaparser.ast.nodeTypes.NodeWithTypeParameters;
     12 import com.github.javaparser.ast.type.TypeParameter;
     13 import com.github.javaparser.resolution.declarations.ResolvedFieldDeclaration;
     14 import com.github.javaparser.resolution.declarations.ResolvedReferenceTypeDeclaration;
     15 import com.github.javaparser.resolution.declarations.ResolvedTypeDeclaration;
     16 import com.github.javaparser.resolution.types.ResolvedReferenceType;
     17 import com.github.javaparser.resolution.types.ResolvedType;
     18 import com.github.javaparser.symbolsolver.javaparsermodel.JavaParserFactory;
     19 import com.github.javaparser.symbolsolver.model.resolution.SymbolReference;
     20 import com.github.javaparser.symbolsolver.model.resolution.TypeSolver;
     21 import com.github.javaparser.symbolsolver.model.typesystem.ReferenceTypeImpl;
     22 import com.github.javaparser.symbolsolver.resolution.SymbolSolver;
     23 
     24 import java.util.ArrayList;
     25 import java.util.List;
     26 import java.util.Optional;
     27 
     28 import static com.github.javaparser.symbolsolver.javaparser.Navigator.getParentNode;
     29 
     30 /**
     31  * @author Federico Tomassetti
     32  */
     33 public class JavaParserTypeAdapter<T extends Node & NodeWithSimpleName<T> & NodeWithMembers<T>> {
     34 
     35     private T wrappedNode;
     36     private TypeSolver typeSolver;
     37 
     38     public JavaParserTypeAdapter(T wrappedNode, TypeSolver typeSolver) {
     39         this.wrappedNode = wrappedNode;
     40         this.typeSolver = typeSolver;
     41     }
     42 
     43     public String getPackageName() {
     44         return Helper.getPackageName(wrappedNode);
     45     }
     46 
     47     public String getClassName() {
     48         return Helper.getClassName("", wrappedNode);
     49     }
     50 
     51     public String getQualifiedName() {
     52         String containerName = Helper.containerName(getParentNode(wrappedNode));
     53         if (containerName.isEmpty()) {
     54             return wrappedNode.getName().getId();
     55         } else {
     56             return containerName + "." + wrappedNode.getName().getId();
     57         }
     58     }
     59 
     60     public boolean isAssignableBy(ResolvedReferenceTypeDeclaration other) {
     61         List<ResolvedReferenceType> ancestorsOfOther = other.getAllAncestors();
     62         ancestorsOfOther.add(new ReferenceTypeImpl(other, typeSolver));
     63         for (ResolvedReferenceType ancestorOfOther : ancestorsOfOther) {
     64             if (ancestorOfOther.getQualifiedName().equals(this.getQualifiedName())) {
     65                 return true;
     66             }
     67         }
     68         return false;
     69     }
     70 
     71     public boolean isAssignableBy(ResolvedType type) {
     72         if (type.isNull()) {
     73             return true;
     74         }
     75         if (type.isReferenceType()) {
     76             ResolvedReferenceTypeDeclaration other = typeSolver.solveType(type.describe());
     77             return isAssignableBy(other);
     78         } else {
     79             throw new UnsupportedOperationException();
     80         }
     81     }
     82 
     83     public SymbolReference<ResolvedTypeDeclaration> solveType(String name, TypeSolver typeSolver) {
     84         if(wrappedNode instanceof NodeWithTypeParameters<?>) {
     85             NodeList<TypeParameter> typeParameters = ((NodeWithTypeParameters<?>) wrappedNode).getTypeParameters();
     86             for (com.github.javaparser.ast.type.TypeParameter typeParameter : typeParameters) {
     87                 if (typeParameter.getName().getId().equals(name)) {
     88                     return SymbolReference.solved(new JavaParserTypeVariableDeclaration(typeParameter, typeSolver));
     89                 }
     90             }
     91         }
     92 
     93         // Internal classes
     94         for (BodyDeclaration<?> member : this.wrappedNode.getMembers()) {
     95             if (member instanceof com.github.javaparser.ast.body.TypeDeclaration) {
     96                 com.github.javaparser.ast.body.TypeDeclaration<?> internalType = (com.github.javaparser.ast.body.TypeDeclaration<?>) member;
     97                 String prefix = internalType.getName() + ".";
     98                 if (internalType.getName().getId().equals(name)) {
     99                     if (internalType instanceof ClassOrInterfaceDeclaration) {
    100                         return SymbolReference.solved(new JavaParserClassDeclaration((com.github.javaparser.ast.body.ClassOrInterfaceDeclaration) internalType, typeSolver));
    101                     } else if (internalType instanceof EnumDeclaration) {
    102                         return SymbolReference.solved(new JavaParserEnumDeclaration((com.github.javaparser.ast.body.EnumDeclaration) internalType, typeSolver));
    103                     } else {
    104                         throw new UnsupportedOperationException();
    105                     }
    106                 } else if (name.startsWith(prefix) && name.length() > prefix.length()) {
    107                     if (internalType instanceof ClassOrInterfaceDeclaration) {
    108                         return new JavaParserClassDeclaration((com.github.javaparser.ast.body.ClassOrInterfaceDeclaration) internalType, typeSolver).solveType(name.substring(prefix.length()), typeSolver);
    109                     } else if (internalType instanceof EnumDeclaration) {
    110                         return new SymbolSolver(typeSolver).solveTypeInType(new JavaParserEnumDeclaration((com.github.javaparser.ast.body.EnumDeclaration) internalType, typeSolver), name.substring(prefix.length()));
    111                     } else {
    112                         throw new UnsupportedOperationException();
    113                     }
    114                 }
    115             }
    116         }
    117         return SymbolReference.unsolved(ResolvedTypeDeclaration.class);
    118     }
    119 
    120     public Optional<ResolvedReferenceTypeDeclaration> containerType() {
    121         return wrappedNode
    122                 .getParentNode()
    123                 .map(node -> JavaParserFactory.toTypeDeclaration(node, typeSolver));
    124     }
    125 
    126     public List<ResolvedFieldDeclaration> getFieldsForDeclaredVariables() {
    127         List<ResolvedFieldDeclaration> fields = new ArrayList<>();
    128         if (wrappedNode.getMembers() != null) {
    129             for (BodyDeclaration<?> member : this.wrappedNode.getMembers()) {
    130                 if (member instanceof com.github.javaparser.ast.body.FieldDeclaration) {
    131                     com.github.javaparser.ast.body.FieldDeclaration field = (com.github.javaparser.ast.body.FieldDeclaration) member;
    132                     for (VariableDeclarator vd : field.getVariables()) {
    133                         fields.add(new JavaParserFieldDeclaration(vd, typeSolver));
    134                     }
    135                 }
    136             }
    137         }
    138         return fields;
    139     }
    140 }
    141