1package com.github.javaparser.symbolsolver.javaparsermodel.declarations; 2 3import com.github.javaparser.ast.Node; 4import com.github.javaparser.ast.NodeList; 5import com.github.javaparser.ast.body.BodyDeclaration; 6import com.github.javaparser.ast.body.ClassOrInterfaceDeclaration; 7import com.github.javaparser.ast.body.EnumDeclaration; 8import com.github.javaparser.ast.body.VariableDeclarator; 9import com.github.javaparser.ast.nodeTypes.NodeWithMembers; 10import com.github.javaparser.ast.nodeTypes.NodeWithSimpleName; 11import com.github.javaparser.ast.nodeTypes.NodeWithTypeParameters; 12import com.github.javaparser.ast.type.TypeParameter; 13import com.github.javaparser.resolution.declarations.ResolvedFieldDeclaration; 14import com.github.javaparser.resolution.declarations.ResolvedReferenceTypeDeclaration; 15import com.github.javaparser.resolution.declarations.ResolvedTypeDeclaration; 16import com.github.javaparser.resolution.types.ResolvedReferenceType; 17import com.github.javaparser.resolution.types.ResolvedType; 18import com.github.javaparser.symbolsolver.javaparsermodel.JavaParserFactory; 19import com.github.javaparser.symbolsolver.model.resolution.SymbolReference; 20import com.github.javaparser.symbolsolver.model.resolution.TypeSolver; 21import com.github.javaparser.symbolsolver.model.typesystem.ReferenceTypeImpl; 22import com.github.javaparser.symbolsolver.resolution.SymbolSolver; 23 24import java.util.ArrayList; 25import java.util.List; 26import java.util.Optional; 27 28import static com.github.javaparser.symbolsolver.javaparser.Navigator.getParentNode; 29 30/** 31 * @author Federico Tomassetti 32 */ 33public 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