diff --git a/java-symbol-solver-core/src/main/java/com/github/javaparser/symbolsolver/javaparsermodel/contexts/CompilationUnitContext.java b/java-symbol-solver-core/src/main/java/com/github/javaparser/symbolsolver/javaparsermodel/contexts/CompilationUnitContext.java index 90ad704703..252aec4a00 100644 --- a/java-symbol-solver-core/src/main/java/com/github/javaparser/symbolsolver/javaparsermodel/contexts/CompilationUnitContext.java +++ b/java-symbol-solver-core/src/main/java/com/github/javaparser/symbolsolver/javaparsermodel/contexts/CompilationUnitContext.java @@ -17,11 +17,13 @@ package com.github.javaparser.symbolsolver.javaparsermodel.contexts; import com.github.javaparser.ast.CompilationUnit; +import com.github.javaparser.ast.body.AnnotationDeclaration; import com.github.javaparser.ast.body.ClassOrInterfaceDeclaration; import com.github.javaparser.ast.body.TypeDeclaration; import com.github.javaparser.ast.imports.*; import com.github.javaparser.ast.type.ClassOrInterfaceType; import com.github.javaparser.symbolsolver.javaparsermodel.JavaParserFacade; +import com.github.javaparser.symbolsolver.javaparsermodel.declarations.JavaParserAnnotationDeclaration; import com.github.javaparser.symbolsolver.model.declarations.MethodDeclaration; import com.github.javaparser.symbolsolver.model.declarations.ValueDeclaration; import com.github.javaparser.symbolsolver.model.resolution.SymbolReference; @@ -109,8 +111,10 @@ public SymbolReference modifiers) { return AccessLevel.PACKAGE_PROTECTED; } } + + public static String containerName(String base, Node container) { + if (container instanceof com.github.javaparser.ast.body.ClassOrInterfaceDeclaration) { + String b = containerName(base, getParentNode(container)); + String cn = ((com.github.javaparser.ast.body.ClassOrInterfaceDeclaration) container).getName(); + if (b.isEmpty()) { + return cn; + } else { + return b + "." + cn; + } + } else if (container instanceof CompilationUnit) { + Optional p = ((CompilationUnit) container).getPackage(); + if (p.isPresent()) { + String b = p.get().getName().toString(); + if (base.isEmpty()) { + return b; + } else { + return b + "." + base; + } + } else { + return base; + } + } else if (container != null) { + return containerName(base, getParentNode(container)); + } else { + return base; + } + } } diff --git a/java-symbol-solver-core/src/main/java/com/github/javaparser/symbolsolver/javaparsermodel/declarations/JavaParserAnnotationDeclaration.java b/java-symbol-solver-core/src/main/java/com/github/javaparser/symbolsolver/javaparsermodel/declarations/JavaParserAnnotationDeclaration.java new file mode 100644 index 0000000000..6d51de104b --- /dev/null +++ b/java-symbol-solver-core/src/main/java/com/github/javaparser/symbolsolver/javaparsermodel/declarations/JavaParserAnnotationDeclaration.java @@ -0,0 +1,76 @@ +package com.github.javaparser.symbolsolver.javaparsermodel.declarations; + +import com.github.javaparser.symbolsolver.logic.AbstractTypeDeclaration; +import com.github.javaparser.symbolsolver.model.declarations.*; +import com.github.javaparser.symbolsolver.model.resolution.TypeSolver; +import com.github.javaparser.symbolsolver.model.typesystem.ReferenceType; +import com.github.javaparser.symbolsolver.model.typesystem.Type; + +import java.util.List; +import java.util.Set; + +import static com.github.javaparser.symbolsolver.javaparser.Navigator.getParentNode; + +/** + * @author Federico Tomassetti + */ +public class JavaParserAnnotationDeclaration extends AbstractTypeDeclaration implements AnnotationDeclaration { + + private com.github.javaparser.ast.body.AnnotationDeclaration wrappedNode; + private TypeSolver typeSolver; + + public JavaParserAnnotationDeclaration(com.github.javaparser.ast.body.AnnotationDeclaration wrappedNode, TypeSolver typeSolver) { + this.wrappedNode = wrappedNode; + this.typeSolver = typeSolver; + } + + @Override + public List getAncestors() { + throw new UnsupportedOperationException(); + } + + @Override + public List getAllFields() { + throw new UnsupportedOperationException(); + } + + @Override + public Set getDeclaredMethods() { + throw new UnsupportedOperationException(); + } + + @Override + public boolean isAssignableBy(Type type) { + throw new UnsupportedOperationException(); + } + + @Override + public boolean isAssignableBy(ReferenceTypeDeclaration other) { + throw new UnsupportedOperationException(); + } + + @Override + public boolean hasDirectlyAnnotation(String qualifiedName) { + throw new UnsupportedOperationException(); + } + + @Override + public String getQualifiedName() { + String containerName = Helper.containerName("", getParentNode(wrappedNode)); + if (containerName.isEmpty()) { + return wrappedNode.getName(); + } else { + return containerName + "." + wrappedNode.getName(); + } + } + + @Override + public String getName() { + return wrappedNode.getName(); + } + + @Override + public List getTypeParameters() { + throw new UnsupportedOperationException(); + } +} diff --git a/java-symbol-solver-core/src/main/java/com/github/javaparser/symbolsolver/javaparsermodel/declarations/JavaParserClassDeclaration.java b/java-symbol-solver-core/src/main/java/com/github/javaparser/symbolsolver/javaparsermodel/declarations/JavaParserClassDeclaration.java index a3fdbae14d..72903c600f 100644 --- a/java-symbol-solver-core/src/main/java/com/github/javaparser/symbolsolver/javaparsermodel/declarations/JavaParserClassDeclaration.java +++ b/java-symbol-solver-core/src/main/java/com/github/javaparser/symbolsolver/javaparsermodel/declarations/JavaParserClassDeclaration.java @@ -16,14 +16,13 @@ package com.github.javaparser.symbolsolver.javaparsermodel.declarations; -import com.github.javaparser.ast.CompilationUnit; import com.github.javaparser.ast.Node; import com.github.javaparser.ast.NodeList; -import com.github.javaparser.ast.PackageDeclaration; import com.github.javaparser.ast.body.BodyDeclaration; import com.github.javaparser.ast.body.ClassOrInterfaceDeclaration; import com.github.javaparser.ast.body.EnumDeclaration; import com.github.javaparser.ast.body.VariableDeclarator; +import com.github.javaparser.ast.expr.AnnotationExpr; import com.github.javaparser.ast.type.ClassOrInterfaceType; import com.github.javaparser.symbolsolver.core.resolution.Context; import com.github.javaparser.symbolsolver.javaparsermodel.JavaParserFacade; @@ -149,7 +148,7 @@ public String getName() { @Override public ReferenceTypeImpl getSuperClass() { if (wrappedNode.getExtends().isEmpty()) { - return new ReferenceTypeImpl(typeSolver.getRoot().solveType("java.lang.Object").asType().asClass(), typeSolver); + return new ReferenceTypeImpl(typeSolver.getRoot().solveType(Object.class.getCanonicalName()).asType().asClass(), typeSolver); } else { SymbolReference ref = solveType(wrappedNode.getExtends().get(0).getName(), typeSolver); if (!ref.isSolved()) { @@ -198,7 +197,12 @@ public List getConstructors() { @Override public boolean hasDirectlyAnnotation(String canonicalName) { - throw new UnsupportedOperationException(); + for (AnnotationExpr annotationExpr : wrappedNode.getAnnotations()) { + if (solveType(annotationExpr.getName().getName(), typeSolver).getCorrespondingDeclaration().getQualifiedName().equals(canonicalName)) { + return true; + } + } + return false; } @Override @@ -208,7 +212,7 @@ public boolean isInterface() { @Override public String getQualifiedName() { - String containerName = containerName("", getParentNode(wrappedNode)); + String containerName = Helper.containerName("", getParentNode(wrappedNode)); if (containerName.isEmpty()) { return wrappedNode.getName(); } else { @@ -376,34 +380,6 @@ protected ReferenceType object() { /// Private methods /// - private String containerName(String base, Node container) { - if (container instanceof com.github.javaparser.ast.body.ClassOrInterfaceDeclaration) { - String b = containerName(base, getParentNode(container)); - String cn = ((com.github.javaparser.ast.body.ClassOrInterfaceDeclaration) container).getName(); - if (b.isEmpty()) { - return cn; - } else { - return b + "." + cn; - } - } else if (container instanceof CompilationUnit) { - Optional p = ((CompilationUnit) container).getPackage(); - if (p.isPresent()) { - String b = p.get().getName().toString(); - if (base.isEmpty()) { - return b; - } else { - return b + "." + base; - } - } else { - return base; - } - } else if (container != null) { - return containerName(base, getParentNode(container)); - } else { - return base; - } - } - private ReferenceTypeImpl toTypeUsage(ClassOrInterfaceType type, TypeSolver typeSolver) { SymbolReference ancestor = solveType(type.getName(), typeSolver.getRoot()); if (!ancestor.isSolved()) { diff --git a/java-symbol-solver-core/src/main/java/com/github/javaparser/symbolsolver/javaparsermodel/declarations/JavaParserEnumDeclaration.java b/java-symbol-solver-core/src/main/java/com/github/javaparser/symbolsolver/javaparsermodel/declarations/JavaParserEnumDeclaration.java index f920032fe0..f524dc2463 100644 --- a/java-symbol-solver-core/src/main/java/com/github/javaparser/symbolsolver/javaparsermodel/declarations/JavaParserEnumDeclaration.java +++ b/java-symbol-solver-core/src/main/java/com/github/javaparser/symbolsolver/javaparsermodel/declarations/JavaParserEnumDeclaration.java @@ -16,9 +16,7 @@ package com.github.javaparser.symbolsolver.javaparsermodel.declarations; -import com.github.javaparser.ast.CompilationUnit; import com.github.javaparser.ast.Node; -import com.github.javaparser.ast.PackageDeclaration; import com.github.javaparser.ast.body.BodyDeclaration; import com.github.javaparser.ast.body.EnumConstantDeclaration; import com.github.javaparser.ast.body.VariableDeclarator; @@ -143,7 +141,7 @@ public boolean isInterface() { @Override public String getQualifiedName() { - String containerName = containerName("", getParentNode(wrappedNode)); + String containerName = Helper.containerName("", getParentNode(wrappedNode)); if (containerName.isEmpty()) { return wrappedNode.getName(); } else { @@ -151,34 +149,6 @@ public String getQualifiedName() { } } - private String containerName(String base, Node container) { - if (container instanceof com.github.javaparser.ast.body.ClassOrInterfaceDeclaration) { - String b = containerName(base, getParentNode(container)); - String cn = ((com.github.javaparser.ast.body.ClassOrInterfaceDeclaration) container).getName(); - if (b.isEmpty()) { - return cn; - } else { - return b + "." + cn; - } - } else if (container instanceof CompilationUnit) { - Optional p = ((CompilationUnit) container).getPackage(); - if (p.isPresent()) { - String b = p.get().getName().toString(); - if (base.isEmpty()) { - return b; - } else { - return b + "." + base; - } - } else { - return base; - } - } else if (container != null) { - return containerName(base, getParentNode(container)); - } else { - return base; - } - } - @Override public boolean isAssignableBy(Type type) { if (type.isNull()) { diff --git a/java-symbol-solver-core/src/main/java/com/github/javaparser/symbolsolver/javaparsermodel/declarations/JavaParserInterfaceDeclaration.java b/java-symbol-solver-core/src/main/java/com/github/javaparser/symbolsolver/javaparsermodel/declarations/JavaParserInterfaceDeclaration.java index b3a7ec9a16..588b19e2c9 100644 --- a/java-symbol-solver-core/src/main/java/com/github/javaparser/symbolsolver/javaparsermodel/declarations/JavaParserInterfaceDeclaration.java +++ b/java-symbol-solver-core/src/main/java/com/github/javaparser/symbolsolver/javaparsermodel/declarations/JavaParserInterfaceDeclaration.java @@ -16,9 +16,7 @@ package com.github.javaparser.symbolsolver.javaparsermodel.declarations; -import com.github.javaparser.ast.CompilationUnit; import com.github.javaparser.ast.Node; -import com.github.javaparser.ast.PackageDeclaration; import com.github.javaparser.ast.body.BodyDeclaration; import com.github.javaparser.ast.body.ClassOrInterfaceDeclaration; import com.github.javaparser.ast.body.EnumDeclaration; @@ -126,7 +124,7 @@ public List getInterfacesExtended() { @Override public String getQualifiedName() { - String containerName = containerName("", getParentNode(wrappedNode)); + String containerName = Helper.containerName("", getParentNode(wrappedNode)); if (containerName.isEmpty()) { return wrappedNode.getName(); } else { @@ -146,34 +144,6 @@ public boolean isAssignableBy(ReferenceTypeDeclaration other) { return false; } - private String containerName(String base, Node container) { - if (container instanceof ClassOrInterfaceDeclaration) { - String b = containerName(base, getParentNode(container)); - String cn = ((ClassOrInterfaceDeclaration) container).getName(); - if (b.isEmpty()) { - return cn; - } else { - return b + "." + cn; - } - } else if (container instanceof CompilationUnit) { - Optional p = ((CompilationUnit) container).getPackage(); - if (p.isPresent()) { - String b = p.get().getName().toString(); - if (base.isEmpty()) { - return b; - } else { - return b + "." + base; - } - } else { - return base; - } - } else if (container != null) { - return containerName(base, getParentNode(container)); - } else { - return base; - } - } - @Override public boolean isAssignableBy(Type type) { if (type.isNull()) { diff --git a/java-symbol-solver-core/src/test/java/com/github/javaparser/symbolsolver/javaparsermodel/declarations/JavaParserClassDeclarationTest.java b/java-symbol-solver-core/src/test/java/com/github/javaparser/symbolsolver/javaparsermodel/declarations/JavaParserClassDeclarationTest.java index 1a1927d88d..7dd23445e9 100644 --- a/java-symbol-solver-core/src/test/java/com/github/javaparser/symbolsolver/javaparsermodel/declarations/JavaParserClassDeclarationTest.java +++ b/java-symbol-solver-core/src/test/java/com/github/javaparser/symbolsolver/javaparsermodel/declarations/JavaParserClassDeclarationTest.java @@ -823,8 +823,46 @@ public void testSolveMethodNotExistingBecauseOfTypeParameters() { // hasDirectlyAnnotation + @Test + public void testHasDirectlyAnnotation() throws FileNotFoundException { + TypeSolver typeSolver = new ReflectionTypeSolver(); + + CompilationUnit cu = JavaParser.parse(adaptPath(new File("src/test/resources/Annotations.java.txt"))); + + JavaParserClassDeclaration ca = new JavaParserClassDeclaration(Navigator.demandClass(cu, "CA"), typeSolver); + assertEquals(true, ca.hasDirectlyAnnotation("foo.bar.MyAnnotation")); + assertEquals(false, ca.hasDirectlyAnnotation("foo.bar.MyAnnotation2")); + assertEquals(false, ca.hasDirectlyAnnotation("MyAnnotation")); + assertEquals(false, ca.hasDirectlyAnnotation("foo.bar.MyUnexistingAnnotation")); + + JavaParserClassDeclaration cb = new JavaParserClassDeclaration(Navigator.demandClass(cu, "CB"), typeSolver); + assertEquals(false, cb.hasDirectlyAnnotation("foo.bar.MyAnnotation")); + assertEquals(true, cb.hasDirectlyAnnotation("foo.bar.MyAnnotation2")); + assertEquals(false, cb.hasDirectlyAnnotation("MyAnnotation")); + assertEquals(false, cb.hasDirectlyAnnotation("foo.bar.MyUnexistingAnnotation")); + } + // hasAnnotation + @Test + public void testHasAnnotation() throws FileNotFoundException { + TypeSolver typeSolver = new ReflectionTypeSolver(); + + CompilationUnit cu = JavaParser.parse(adaptPath(new File("src/test/resources/Annotations.java.txt"))); + + JavaParserClassDeclaration ca = new JavaParserClassDeclaration(Navigator.demandClass(cu, "CA"), typeSolver); + assertEquals(true, ca.hasAnnotation("foo.bar.MyAnnotation")); + assertEquals(false, ca.hasAnnotation("foo.bar.MyAnnotation2")); + assertEquals(false, ca.hasAnnotation("MyAnnotation")); + assertEquals(false, ca.hasAnnotation("foo.bar.MyUnexistingAnnotation")); + + JavaParserClassDeclaration cb = new JavaParserClassDeclaration(Navigator.demandClass(cu, "CB"), typeSolver); + assertEquals(true, cb.hasAnnotation("foo.bar.MyAnnotation")); + assertEquals(true, cb.hasAnnotation("foo.bar.MyAnnotation2")); + assertEquals(false, cb.hasAnnotation("MyAnnotation")); + assertEquals(false, cb.hasAnnotation("foo.bar.MyUnexistingAnnotation")); + } + /// /// /// diff --git a/java-symbol-solver-core/src/test/resources/Annotations.java.txt b/java-symbol-solver-core/src/test/resources/Annotations.java.txt new file mode 100644 index 0000000000..cde899bd07 --- /dev/null +++ b/java-symbol-solver-core/src/test/resources/Annotations.java.txt @@ -0,0 +1,18 @@ +package foo.bar; + +public @interface MyAnnotation { +} + +public @interface MyAnnotation2 { +} + +@MyAnnotation +class CA { + +} + +@MyAnnotation2 +class CB extends CA { + +} + diff --git a/java-symbol-solver-model/src/main/java/com/github/javaparser/symbolsolver/model/declarations/AnnotationDeclaration.java b/java-symbol-solver-model/src/main/java/com/github/javaparser/symbolsolver/model/declarations/AnnotationDeclaration.java new file mode 100644 index 0000000000..3949862280 --- /dev/null +++ b/java-symbol-solver-model/src/main/java/com/github/javaparser/symbolsolver/model/declarations/AnnotationDeclaration.java @@ -0,0 +1,7 @@ +package com.github.javaparser.symbolsolver.model.declarations; + +/** + * @author Federico Tomassetti + */ +public interface AnnotationDeclaration extends ReferenceTypeDeclaration { +} diff --git a/java-symbol-solver-model/src/main/java/com/github/javaparser/symbolsolver/model/declarations/ReferenceTypeDeclaration.java b/java-symbol-solver-model/src/main/java/com/github/javaparser/symbolsolver/model/declarations/ReferenceTypeDeclaration.java index cefde78036..c3d6294754 100644 --- a/java-symbol-solver-model/src/main/java/com/github/javaparser/symbolsolver/model/declarations/ReferenceTypeDeclaration.java +++ b/java-symbol-solver-model/src/main/java/com/github/javaparser/symbolsolver/model/declarations/ReferenceTypeDeclaration.java @@ -99,6 +99,8 @@ default boolean hasVisibleField(String name) { /** * Return a list of all fields, either declared in this declaration or inherited. + * + * Note that they could refer to inherited type variables. */ List getAllFields();