From b9610951d87caf34a51f9b2969294211e04441c8 Mon Sep 17 00:00:00 2001 From: malte_langkabel Date: Thu, 10 Aug 2017 15:15:48 +0200 Subject: [PATCH] logic: Java anonymous class fixes * fixed solving anonymous classes * fixed solving methods declared in anonymous classes * fixed solving calls to those methods * updated JavaSymbolSolver Jars --- java_indexer/lib/java-symbol-solver-core.jar | Bin 260291 -> 260476 bytes java_indexer/lib/java-symbol-solver-logic.jar | Bin 14301 -> 14301 bytes java_indexer/lib/java-symbol-solver-model.jar | Bin 51532 -> 51532 bytes .../main/java/com/sourcetrail/AstVisitor.java | 136 ++++++------ .../com/sourcetrail/AstVisitorAdapter.java | 7 - .../com/sourcetrail/JavaNameResolver.java | 9 +- .../JavaSymbolSolverDeclNameResolver.java | 60 +++--- .../JavaSymbolSolverTypeNameResolver.java | 17 +- .../JavaparserDeclNameResolver.java | 196 +++++++++--------- .../JavaparserTypeNameResolver.java | 18 +- .../com/sourcetrail/name/JavaDeclName.java | 25 ++- src/test/JavaParserTestSuite.h | 51 ++++- 12 files changed, 294 insertions(+), 225 deletions(-) diff --git a/java_indexer/lib/java-symbol-solver-core.jar b/java_indexer/lib/java-symbol-solver-core.jar index a0e1a7d8a0bb397141f5ddfd4c41fd032799ab46..18562c83ab71b13dd07b43d957de9cd96d8ef3ba 100644 GIT binary patch delta 29243 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 ZYjpu@jjz9JWq>4K069>)dSIaf{vRLtK`sCQ delta 28872 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 delta 166 zcmcbce>a~uz?+$ci-CcIgJDSy%SK*nMrI&A*_+V~L~owL*u@HFD6+3-0W&Uh3o?Nj z&v_?sfEiU{HvC}5PStU{VC8RZR=Q^i0!gFfDEd S5$`d}0`q^G<%8*L^CAGb(>4kK diff --git a/java_indexer/lib/java-symbol-solver-model.jar b/java_indexer/lib/java-symbol-solver-model.jar index 7b322b5ae696989944eb0b5b966885adba523f0f..814428b1e44c860a3db6f5f3f36f162a069011aa 100644 GIT binary patch delta 33 ocmX>ziTTVVX5IjAW)?061`ZB}$Q;g%ysI}d1L@7XH%=4>0G&(<3;+NC delta 33 ocmX>ziTTVVX5IjAW)?061`ZB}B{?h`c~@^_2GW~%Z=5I&0Hg2 m_context = new ArrayList(); @@ -63,7 +64,7 @@ public class AstVisitor extends AstVisitorAdapter public AstVisitor(AstVisitorClient client, String filePath, FileContent fileContent, TypeSolver typeSolver) { m_client = client; - m_filePath = filePath; + m_filePath = new File(filePath); m_fileContent = fileContent; m_typeSolver = typeSolver; @@ -105,7 +106,7 @@ public class AstVisitor extends AstVisitorAdapter { SimpleName name = n.getName(); - String qualifiedName = JavaparserDeclNameResolver.getQualifiedDeclName(n, m_typeSolver).toNameHierarchy().serialize(); + String qualifiedName = JavaparserDeclNameResolver.getQualifiedDeclName(n, m_filePath, m_typeSolver).toNameHierarchy().serialize(); m_client.recordSymbolWithLocationAndScope( qualifiedName, (n.isInterface() ? SymbolKind.INTERFACE : SymbolKind.CLASS), @@ -140,7 +141,7 @@ public class AstVisitor extends AstVisitorAdapter // throw something! } - String qualifiedName = JavaparserDeclNameResolver.getQualifiedDeclName(n, m_typeSolver).toNameHierarchy().serialize(); + String qualifiedName = JavaparserDeclNameResolver.getQualifiedDeclName(n, m_filePath, m_typeSolver).toNameHierarchy().serialize(); Optional range = Optional.empty(); if (n.getBegin().isPresent()) @@ -173,7 +174,7 @@ public class AstVisitor extends AstVisitorAdapter { SimpleName name = n.getName(); - String qualifiedName = JavaparserDeclNameResolver.getQualifiedDeclName(n, m_typeSolver).toNameHierarchy().serialize(); + String qualifiedName = JavaparserDeclNameResolver.getQualifiedDeclName(n, m_filePath, m_typeSolver).toNameHierarchy().serialize(); m_client.recordSymbolWithLocationAndScope( qualifiedName, SymbolKind.ENUM, @@ -200,7 +201,7 @@ public class AstVisitor extends AstVisitorAdapter @Override public Boolean visit(final EnumConstantDeclaration n, final Void v) { - String qualifiedName = JavaparserDeclNameResolver.getQualifiedDeclName(n, m_typeSolver).toNameHierarchy().serialize(); + String qualifiedName = JavaparserDeclNameResolver.getQualifiedDeclName(n, m_filePath, m_typeSolver).toNameHierarchy().serialize(); m_client.recordSymbolWithLocation( qualifiedName, SymbolKind.ENUM_CONSTANT, @@ -222,7 +223,7 @@ public class AstVisitor extends AstVisitorAdapter { SimpleName name = n.getName(); - String qualifiedName = JavaparserDeclNameResolver.getQualifiedDeclName(n, m_typeSolver).toNameHierarchy().serialize(); + String qualifiedName = JavaparserDeclNameResolver.getQualifiedDeclName(n, m_filePath, m_typeSolver).toNameHierarchy().serialize(); m_client.recordSymbolWithLocationAndScope( qualifiedName, SymbolKind.METHOD, @@ -251,7 +252,7 @@ public class AstVisitor extends AstVisitorAdapter SimpleName name = n.getName(); - String qualifiedName = JavaparserDeclNameResolver.getQualifiedDeclName(n, m_typeSolver).toNameHierarchy().serialize(); + String qualifiedName = JavaparserDeclNameResolver.getQualifiedDeclName(n, m_filePath, m_typeSolver).toNameHierarchy().serialize(); m_client.recordSymbolWithLocationAndScope( qualifiedName, SymbolKind.METHOD, @@ -266,7 +267,8 @@ public class AstVisitor extends AstVisitorAdapter com.github.javaparser.symbolsolver.model.declarations.MethodDeclaration overridden = getOverridden(n); if (overridden != null && (overridden instanceof JavaParserMethodDeclaration)) { - String overriddenName = JavaparserDeclNameResolver.getQualifiedDeclName(((JavaParserMethodDeclaration)overridden).getWrappedNode(), m_typeSolver).toNameHierarchy().serialize(); + String overriddenName = JavaparserDeclNameResolver.getQualifiedDeclName( + ((JavaParserMethodDeclaration)overridden).getWrappedNode(), m_filePath, m_typeSolver).toNameHierarchy().serialize(); m_client.recordReference( ReferenceKind.OVERRIDE, overriddenName, qualifiedName, @@ -348,7 +350,7 @@ public class AstVisitor extends AstVisitorAdapter for (VariableDeclarator declarator: n.getVariables()) { - String qualifiedName = JavaparserDeclNameResolver.getQualifiedDeclName(declarator, m_typeSolver).toNameHierarchy().serialize(); + String qualifiedName = JavaparserDeclNameResolver.getQualifiedDeclName(declarator, m_filePath, m_typeSolver).toNameHierarchy().serialize(); SimpleName name = declarator.getName(); m_client.recordSymbolWithLocation( qualifiedName, SymbolKind.FIELD, @@ -429,7 +431,8 @@ public class AstVisitor extends AstVisitorAdapter SymbolReference solvedTypeDeclatarion = m_typeSolver.tryToSolveType(name.asString()); if (solvedTypeDeclatarion.isSolved()) { - importedDeclNames.add(JavaSymbolSolverDeclNameResolver.getQualifiedDeclName(solvedTypeDeclatarion.getCorrespondingDeclaration(), m_typeSolver)); + importedDeclNames.add(JavaSymbolSolverDeclNameResolver.getQualifiedDeclName( + solvedTypeDeclatarion.getCorrespondingDeclaration(), m_filePath, m_typeSolver)); } else if (n.isStatic()) { @@ -443,13 +446,12 @@ public class AstVisitor extends AstVisitorAdapter if (methodDecl.getName().equals(memberName)) { importedDeclNames.add( - JavaSymbolSolverDeclNameResolver.getQualifiedDeclName(methodDecl, m_typeSolver - )); + JavaSymbolSolverDeclNameResolver.getQualifiedDeclName(methodDecl, m_filePath, m_typeSolver)); } } if (importedDeclNames.isEmpty() && solvedDecl.hasField(memberName)) // look for field { - JavaDeclName importedTypeDeclName = JavaSymbolSolverDeclNameResolver.getQualifiedDeclName(solvedDecl, m_typeSolver); + JavaDeclName importedTypeDeclName = JavaSymbolSolverDeclNameResolver.getQualifiedDeclName(solvedDecl, m_filePath, m_typeSolver); if (importedTypeDeclName != null) { JavaDeclName importedDeclName = new JavaDeclName(memberName); @@ -494,7 +496,7 @@ public class AstVisitor extends AstVisitorAdapter { for (DeclContext context: m_context) { - String referencedName = JavaparserTypeNameResolver.getQualifiedTypeName(n, m_typeSolver).toNameHierarchy().serialize(); + String referencedName = JavaparserTypeNameResolver.getQualifiedTypeName(n, m_filePath, m_typeSolver).toNameHierarchy().serialize(); Range range = Range.range(0, 0, 0, 0); @@ -539,7 +541,7 @@ public class AstVisitor extends AstVisitorAdapter { try { - String referencedName = JavaparserTypeNameResolver.getQualifiedTypeName(n, m_typeSolver).toNameHierarchy().serialize(); + String referencedName = JavaparserTypeNameResolver.getQualifiedTypeName(n, m_filePath, m_typeSolver).toNameHierarchy().serialize(); m_client.recordSymbol( referencedName, SymbolKind.BUILTIN_TYPE, @@ -568,7 +570,7 @@ public class AstVisitor extends AstVisitorAdapter { try { - String referencedName = JavaparserTypeNameResolver.getQualifiedTypeName(n, m_typeSolver).toNameHierarchy().serialize(); + String referencedName = JavaparserTypeNameResolver.getQualifiedTypeName(n, m_filePath, m_typeSolver).toNameHierarchy().serialize(); m_client.recordSymbol( referencedName, SymbolKind.BUILTIN_TYPE, AccessKind.NONE, DefinitionKind.EXPLICIT @@ -613,7 +615,7 @@ public class AstVisitor extends AstVisitorAdapter { if (var.getName().getIdentifier().equals(fieldName.getIdentifier())) { - String qualifiedName = JavaparserDeclNameResolver.getQualifiedDeclName(var, m_typeSolver).toNameHierarchy().serialize(); + String qualifiedName = JavaparserDeclNameResolver.getQualifiedDeclName(var, m_filePath, m_typeSolver).toNameHierarchy().serialize(); for (DeclContext context: m_context) { m_client.recordReference( @@ -667,7 +669,7 @@ public class AstVisitor extends AstVisitorAdapter { if (var.getName().getIdentifier().equals(n.getName().getIdentifier())) { - String qualifiedName = JavaparserDeclNameResolver.getQualifiedDeclName(var, m_typeSolver).toNameHierarchy().serialize(); + String qualifiedName = JavaparserDeclNameResolver.getQualifiedDeclName(var, m_filePath, m_typeSolver).toNameHierarchy().serialize(); for (DeclContext context: m_context) { m_client.recordReference( @@ -695,7 +697,7 @@ public class AstVisitor extends AstVisitorAdapter { if (wrappedNode.getAncestorOfType(FieldDeclaration.class).isPresent()) { - String qualifiedName = JavaparserDeclNameResolver.getQualifiedDeclName((VariableDeclarator)wrappedNode, m_typeSolver).toNameHierarchy().serialize(); + String qualifiedName = JavaparserDeclNameResolver.getQualifiedDeclName((VariableDeclarator)wrappedNode, m_filePath, m_typeSolver).toNameHierarchy().serialize(); for (DeclContext context: m_context) { @@ -741,7 +743,8 @@ public class AstVisitor extends AstVisitorAdapter SymbolReference solvedSymbol = JavaParserFacade.get(m_typeSolver).solve(n); if (solvedSymbol.isSolved()) { - qualifiedName = JavaSymbolSolverDeclNameResolver.getQualifiedDeclName(solvedSymbol.getCorrespondingDeclaration(), m_typeSolver).toNameHierarchy().serialize(); + qualifiedName = JavaSymbolSolverDeclNameResolver.getQualifiedDeclName( + solvedSymbol.getCorrespondingDeclaration(), m_filePath, m_typeSolver).toNameHierarchy().serialize(); } else { @@ -815,51 +818,64 @@ public class AstVisitor extends AstVisitorAdapter @Override public Boolean visit(final ObjectCreationExpr n, final Void v) { - String qualifiedName = ""; if (m_context.size() > 0) { - try + if (n.getAnonymousClassBody().isPresent()) { - SymbolReference solvedSymbol = JavaParserFacade.get(m_typeSolver).solve(n); - if (solvedSymbol.isSolved()) - { - qualifiedName = JavaSymbolSolverDeclNameResolver.getQualifiedDeclName(solvedSymbol.getCorrespondingDeclaration(), m_typeSolver).toNameHierarchy().serialize(); - } - else - { - throw new UnsolvedSymbolException("constructor for " + n.getType().getNameAsString()); - } - } - catch (UnsupportedOperationException e) - { - recordException(e, n); - } - catch (MethodAmbiguityException e) - { - recordException(e, n); - } - catch(StackOverflowError e) - { - recordError(e, n); - } - catch (Exception e) - { - recordException(e, n); - } - } - - if (!qualifiedName.isEmpty()) - { - ClassOrInterfaceType type = n.getType(); - for (DeclContext context: m_context) - { - m_client.recordReference( - ReferenceKind.CALL, qualifiedName, context.getName(), - type.getRange() + String qualifiedName = JavaparserDeclNameResolver.getQualifiedDeclName(n, m_filePath, m_typeSolver).toNameHierarchy().serialize(); + m_client.recordSymbolWithLocationAndScope( + qualifiedName, SymbolKind.CLASS, + n.getType().getRange(), + n.getRange(), + AccessKind.NONE, + DefinitionKind.EXPLICIT ); } + else + { + String qualifiedName = ""; + try + { + SymbolReference solvedSymbol = JavaParserFacade.get(m_typeSolver).solve(n); + if (solvedSymbol.isSolved()) + { + qualifiedName = JavaSymbolSolverDeclNameResolver.getQualifiedDeclName(solvedSymbol.getCorrespondingDeclaration(), m_filePath, m_typeSolver).toNameHierarchy().serialize(); + } + else + { + throw new UnsolvedSymbolException("constructor for " + n.getType().getNameAsString()); + } + } + catch (UnsupportedOperationException e) + { + recordException(e, n); + } + catch (MethodAmbiguityException e) + { + recordException(e, n); + } + catch(StackOverflowError e) + { + recordError(e, n); + } + catch (Exception e) + { + recordException(e, n); + } + + if (!qualifiedName.isEmpty()) + { + ClassOrInterfaceType type = n.getType(); + for (DeclContext context: m_context) + { + m_client.recordReference( + ReferenceKind.CALL, qualifiedName, context.getName(), + type.getRange() + ); + } + } + } } - return super.visit(n, v); } diff --git a/java_indexer/src/main/java/com/sourcetrail/AstVisitorAdapter.java b/java_indexer/src/main/java/com/sourcetrail/AstVisitorAdapter.java index 2ea21537..fe20e55b 100644 --- a/java_indexer/src/main/java/com/sourcetrail/AstVisitorAdapter.java +++ b/java_indexer/src/main/java/com/sourcetrail/AstVisitorAdapter.java @@ -1,22 +1,15 @@ package com.sourcetrail; -import com.github.javaparser.ast.visitor.GenericListVisitorAdapter; import com.github.javaparser.ast.visitor.GenericVisitorAdapter; -import com.github.javaparser.ast.visitor.VoidVisitorAdapter; import com.github.javaparser.ast.*; import com.github.javaparser.ast.body.*; -import com.github.javaparser.ast.comments.Comment; import com.github.javaparser.ast.expr.*; -import com.github.javaparser.ast.nodeTypes.NodeWithAnnotations; import com.github.javaparser.ast.stmt.*; import com.github.javaparser.ast.type.*; -import java.util.Optional; import java.util.Stack; -import javax.annotation.Generated; - public abstract class AstVisitorAdapter extends GenericVisitorAdapter { private Stack m_typeRefKind = new Stack(); diff --git a/java_indexer/src/main/java/com/sourcetrail/JavaNameResolver.java b/java_indexer/src/main/java/com/sourcetrail/JavaNameResolver.java index 9047e762..3dcedc48 100644 --- a/java_indexer/src/main/java/com/sourcetrail/JavaNameResolver.java +++ b/java_indexer/src/main/java/com/sourcetrail/JavaNameResolver.java @@ -1,19 +1,18 @@ package com.sourcetrail; -import java.util.ArrayList; -import java.util.List; - -import com.github.javaparser.ast.body.BodyDeclaration; +import java.io.File; import com.github.javaparser.symbolsolver.model.resolution.TypeSolver; public abstract class JavaNameResolver { + File m_currentFile = null; TypeSolver m_typeSolver = null; ContextList m_ignoredContexts = null; - public JavaNameResolver(TypeSolver typeSolver, ContextList ignoredContexts) + public JavaNameResolver(File currentFile, TypeSolver typeSolver, ContextList ignoredContexts) { + m_currentFile = currentFile; m_typeSolver = typeSolver; if (ignoredContexts != null) { diff --git a/java_indexer/src/main/java/com/sourcetrail/JavaSymbolSolverDeclNameResolver.java b/java_indexer/src/main/java/com/sourcetrail/JavaSymbolSolverDeclNameResolver.java index 65c3aadf..dc1438bc 100644 --- a/java_indexer/src/main/java/com/sourcetrail/JavaSymbolSolverDeclNameResolver.java +++ b/java_indexer/src/main/java/com/sourcetrail/JavaSymbolSolverDeclNameResolver.java @@ -1,13 +1,10 @@ package com.sourcetrail; +import java.io.File; import java.util.ArrayList; import java.util.List; import java.util.Optional; -import com.github.javaparser.ast.body.BodyDeclaration; -import com.github.javaparser.ast.body.FieldDeclaration; -import com.github.javaparser.ast.body.Parameter; -import com.github.javaparser.ast.type.TypeParameter; import com.github.javaparser.symbolsolver.javaparsermodel.declarations.JavaParserAnnotationDeclaration; import com.github.javaparser.symbolsolver.javaparsermodel.declarations.JavaParserAnonymousClassDeclaration; import com.github.javaparser.symbolsolver.javaparsermodel.declarations.JavaParserClassDeclaration; @@ -21,16 +18,12 @@ import com.github.javaparser.symbolsolver.javaparsermodel.declarations.JavaParse import com.github.javaparser.symbolsolver.javaparsermodel.declarations.JavaParserSymbolDeclaration; import com.github.javaparser.symbolsolver.javaparsermodel.declarations.JavaParserTypeParameter; import com.github.javaparser.symbolsolver.javaparsermodel.declarations.JavaParserTypeVariableDeclaration; -import com.github.javaparser.symbolsolver.javassistmodel.JavassistClassDeclaration; -import com.github.javaparser.symbolsolver.javassistmodel.JavassistTypeParameter; import com.github.javaparser.symbolsolver.model.declarations.Declaration; import com.github.javaparser.symbolsolver.model.declarations.MethodDeclaration; import com.github.javaparser.symbolsolver.model.declarations.MethodLikeDeclaration; import com.github.javaparser.symbolsolver.model.declarations.ReferenceTypeDeclaration; -import com.github.javaparser.symbolsolver.model.declarations.TypeDeclaration; import com.github.javaparser.symbolsolver.model.declarations.TypeParameterDeclaration; import com.github.javaparser.symbolsolver.model.declarations.TypeParametrizable; -import com.github.javaparser.symbolsolver.model.declarations.ValueDeclaration; import com.github.javaparser.symbolsolver.model.resolution.TypeSolver; import com.sourcetrail.name.JavaDeclName; @@ -40,19 +33,19 @@ import com.sourcetrail.name.JavaVariableDeclName; public class JavaSymbolSolverDeclNameResolver extends JavaNameResolver { - public JavaSymbolSolverDeclNameResolver(TypeSolver typeSolver, ContextList ignoredContexts) + public JavaSymbolSolverDeclNameResolver(File currentFile, TypeSolver typeSolver, ContextList ignoredContexts) { - super(typeSolver, ignoredContexts); + super(currentFile, typeSolver, ignoredContexts); } - public static JavaDeclName getQualifiedDeclName(Declaration decl, TypeSolver typeSolver) + public static JavaDeclName getQualifiedDeclName(Declaration decl, File currentFile, TypeSolver typeSolver) { - return getQualifiedDeclName(decl, typeSolver, null); + return getQualifiedDeclName(decl, currentFile, typeSolver, null); } - public static JavaDeclName getQualifiedDeclName(Declaration decl, TypeSolver typeSolver, ContextList ignoredContexts) + public static JavaDeclName getQualifiedDeclName(Declaration decl, File currentFile, TypeSolver typeSolver, ContextList ignoredContexts) { - JavaSymbolSolverDeclNameResolver resolver = new JavaSymbolSolverDeclNameResolver(typeSolver, ignoredContexts); + JavaSymbolSolverDeclNameResolver resolver = new JavaSymbolSolverDeclNameResolver(currentFile, typeSolver, ignoredContexts); return resolver.getQualifiedDeclName(decl); } @@ -69,44 +62,44 @@ public class JavaSymbolSolverDeclNameResolver extends JavaNameResolver } if (decl instanceof JavaParserAnonymousClassDeclaration) { - // TODO: implement + // TODO: implement maybe the case is new XXX { methods and stuff }.doSomething(); System.out.println("solving name of JavaParserAnonymousClassDeclaration not implemented"); declName = JavaDeclName.unsolved(); } else if (decl instanceof JavaParserClassDeclaration) { declName = JavaparserDeclNameResolver.getQualifiedDeclName( - ((JavaParserClassDeclaration)decl).getWrappedNode(), m_typeSolver, m_ignoredContexts); + ((JavaParserClassDeclaration)decl).getWrappedNode(), m_currentFile, m_typeSolver, m_ignoredContexts); } else if (decl instanceof JavaParserConstructorDeclaration) { declName = JavaparserDeclNameResolver.getQualifiedDeclName( - ((JavaParserConstructorDeclaration)decl).getWrappedNode(), m_typeSolver, m_ignoredContexts); + ((JavaParserConstructorDeclaration)decl).getWrappedNode(), m_currentFile, m_typeSolver, m_ignoredContexts); } else if (decl instanceof JavaParserEnumDeclaration) { declName = JavaparserDeclNameResolver.getQualifiedDeclName( - ((JavaParserEnumDeclaration)decl).getWrappedNode(), m_typeSolver, m_ignoredContexts); + ((JavaParserEnumDeclaration)decl).getWrappedNode(), m_currentFile, m_typeSolver, m_ignoredContexts); } else if (decl instanceof JavaParserEnumConstantDeclaration) { declName = JavaparserDeclNameResolver.getQualifiedDeclName( - ((JavaParserEnumConstantDeclaration)decl).getWrappedNode(), m_typeSolver, m_ignoredContexts); + ((JavaParserEnumConstantDeclaration)decl).getWrappedNode(), m_currentFile, m_typeSolver, m_ignoredContexts); } else if (decl instanceof JavaParserFieldDeclaration) { declName = JavaparserDeclNameResolver.getQualifiedDeclName( - ((JavaParserFieldDeclaration)decl).getWrappedNode(), m_typeSolver, m_ignoredContexts); + ((JavaParserFieldDeclaration)decl).getWrappedNode(), m_currentFile, m_typeSolver, m_ignoredContexts); } else if (decl instanceof JavaParserInterfaceDeclaration) { declName = JavaparserDeclNameResolver.getQualifiedDeclName( - ((JavaParserInterfaceDeclaration)decl).getWrappedNode(), m_typeSolver, m_ignoredContexts); + ((JavaParserInterfaceDeclaration)decl).getWrappedNode(), m_currentFile, m_typeSolver, m_ignoredContexts); } else if (decl instanceof JavaParserMethodDeclaration) { declName = JavaparserDeclNameResolver.getQualifiedDeclName( - ((JavaParserMethodDeclaration)decl).getWrappedNode(), m_typeSolver, m_ignoredContexts); + ((JavaParserMethodDeclaration)decl).getWrappedNode(), m_currentFile, m_typeSolver, m_ignoredContexts); } else if (decl instanceof JavaParserParameterDeclaration) { @@ -121,12 +114,12 @@ public class JavaSymbolSolverDeclNameResolver extends JavaNameResolver else if (decl instanceof JavaParserTypeParameter) { declName = JavaparserDeclNameResolver.getQualifiedDeclName( - ((JavaParserTypeParameter)decl).getWrappedNode(), m_typeSolver, m_ignoredContexts); + ((JavaParserTypeParameter)decl).getWrappedNode(), m_currentFile, m_typeSolver, m_ignoredContexts); } else if (decl instanceof JavaParserTypeVariableDeclaration) { declName = JavaparserDeclNameResolver.getQualifiedDeclName( - ((JavaParserTypeVariableDeclaration)decl).getWrappedNode(), m_typeSolver, m_ignoredContexts); + ((JavaParserTypeVariableDeclaration)decl).getWrappedNode(), m_currentFile, m_typeSolver, m_ignoredContexts); } else { @@ -144,7 +137,7 @@ public class JavaSymbolSolverDeclNameResolver extends JavaNameResolver Optional containerType = ((ReferenceTypeDeclaration) decl).containerType(); if (containerType.isPresent()) { - declName.setParent(getQualifiedDeclName(containerType.get(), m_typeSolver, m_ignoredContexts)); + declName.setParent(getQualifiedDeclName(containerType.get(), m_currentFile, m_typeSolver, m_ignoredContexts)); } else { @@ -160,11 +153,11 @@ public class JavaSymbolSolverDeclNameResolver extends JavaNameResolver { if (container instanceof ReferenceTypeDeclaration) { - declName.setParent(getQualifiedDeclName((ReferenceTypeDeclaration) container, m_typeSolver, m_ignoredContexts)); + declName.setParent(getQualifiedDeclName((ReferenceTypeDeclaration) container, m_currentFile, m_typeSolver, m_ignoredContexts)); } if (container instanceof MethodLikeDeclaration) { - declName.setParent(getQualifiedDeclName((MethodLikeDeclaration) container, m_typeSolver, m_ignoredContexts)); + declName.setParent(getQualifiedDeclName((MethodLikeDeclaration) container, m_currentFile, m_typeSolver, m_ignoredContexts)); } } } @@ -177,18 +170,18 @@ public class JavaSymbolSolverDeclNameResolver extends JavaNameResolver boolean isStatic = false; if (decl instanceof MethodDeclaration) { - returnTypeName = JavaSymbolSolverTypeNameResolver.getQualifiedTypeName(((MethodDeclaration)decl).getReturnType(), m_typeSolver, ignoredContextsForTypes); + returnTypeName = JavaSymbolSolverTypeNameResolver.getQualifiedTypeName(((MethodDeclaration)decl).getReturnType(), m_currentFile, m_typeSolver, ignoredContextsForTypes); isStatic = ((MethodDeclaration)decl).isStatic(); } declName = new JavaFunctionDeclName( name, typeParameters, returnTypeName, - getParameterTypeNames((MethodLikeDeclaration) decl, m_typeSolver, ignoredContextsForTypes), + getParameterTypeNames((MethodLikeDeclaration) decl, m_currentFile, m_typeSolver, ignoredContextsForTypes), isStatic); declName.setParent( - getQualifiedDeclName(((MethodLikeDeclaration) decl).declaringType(), m_typeSolver, m_ignoredContexts)); + getQualifiedDeclName(((MethodLikeDeclaration) decl).declaringType(), m_currentFile, m_typeSolver, m_ignoredContexts)); } else if (decl instanceof com.github.javaparser.symbolsolver.model.declarations.FieldDeclaration) @@ -196,12 +189,13 @@ public class JavaSymbolSolverDeclNameResolver extends JavaNameResolver com.github.javaparser.symbolsolver.model.declarations.FieldDeclaration fieldDecl = ((com.github.javaparser.symbolsolver.model.declarations.FieldDeclaration) decl); declName = new JavaVariableDeclName( name, - JavaSymbolSolverTypeNameResolver.getQualifiedTypeName(fieldDecl.getType(), m_typeSolver, m_ignoredContexts), + JavaSymbolSolverTypeNameResolver.getQualifiedTypeName(fieldDecl.getType(), m_currentFile, m_typeSolver, m_ignoredContexts), fieldDecl.isStatic()); declName.setParent( getQualifiedDeclName( fieldDecl.declaringType(), + m_currentFile, m_typeSolver, m_ignoredContexts)); } @@ -230,13 +224,13 @@ public class JavaSymbolSolverDeclNameResolver extends JavaNameResolver return typeParameterNames; } - private static List getParameterTypeNames(MethodLikeDeclaration decl, TypeSolver typeSolver, ContextList ignoredContexts) + private static List getParameterTypeNames(MethodLikeDeclaration decl, File currentFile, TypeSolver typeSolver, ContextList ignoredContexts) { List typeTypeParameterNames = new ArrayList<>(); for (int i = 0; i < decl.getNumberOfParams(); i++) { typeTypeParameterNames.add(JavaSymbolSolverTypeNameResolver.getQualifiedTypeName( - decl.getParam(i).getType(), typeSolver, ignoredContexts + decl.getParam(i).getType(), currentFile, typeSolver, ignoredContexts )); } return typeTypeParameterNames; diff --git a/java_indexer/src/main/java/com/sourcetrail/JavaSymbolSolverTypeNameResolver.java b/java_indexer/src/main/java/com/sourcetrail/JavaSymbolSolverTypeNameResolver.java index e35f838c..e9eb7bf9 100644 --- a/java_indexer/src/main/java/com/sourcetrail/JavaSymbolSolverTypeNameResolver.java +++ b/java_indexer/src/main/java/com/sourcetrail/JavaSymbolSolverTypeNameResolver.java @@ -1,5 +1,6 @@ package com.sourcetrail; +import java.io.File; import java.util.ArrayList; import java.util.List; import java.util.Optional; @@ -24,19 +25,19 @@ import com.sourcetrail.name.JavaTypeName; public class JavaSymbolSolverTypeNameResolver extends JavaNameResolver { - public JavaSymbolSolverTypeNameResolver(TypeSolver typeSolver, ContextList ignoredContexts) + public JavaSymbolSolverTypeNameResolver(File currentFile, TypeSolver typeSolver, ContextList ignoredContexts) { - super(typeSolver, ignoredContexts); + super(currentFile, typeSolver, ignoredContexts); } - public static JavaTypeName getQualifiedTypeName(Type type, TypeSolver typeSolver) + public static JavaTypeName getQualifiedTypeName(Type type, File currentFile, TypeSolver typeSolver) { - return getQualifiedTypeName(type, typeSolver, null); + return getQualifiedTypeName(type, currentFile, typeSolver, null); } - public static JavaTypeName getQualifiedTypeName(Type type, TypeSolver typeSolver, ContextList ignoredContexts) + public static JavaTypeName getQualifiedTypeName(Type type, File currentFile, TypeSolver typeSolver, ContextList ignoredContexts) { - JavaSymbolSolverTypeNameResolver resolver = new JavaSymbolSolverTypeNameResolver(typeSolver, ignoredContexts); + JavaSymbolSolverTypeNameResolver resolver = new JavaSymbolSolverTypeNameResolver(currentFile, typeSolver, ignoredContexts); return resolver.getQualifiedTypeName(type); } @@ -67,7 +68,8 @@ public class JavaSymbolSolverTypeNameResolver extends JavaNameResolver ReferenceType refTypeUsage = (ReferenceType)type; JavaDeclName declName = JavaSymbolSolverDeclNameResolver.getQualifiedDeclName( - refTypeUsage.getTypeDeclaration(), + refTypeUsage.getTypeDeclaration(), + m_currentFile, m_typeSolver, m_ignoredContexts); return new JavaTypeName(declName.getName() + declName.getTypeParameterString(), new ArrayList(), declName.getParent()); @@ -76,6 +78,7 @@ public class JavaSymbolSolverTypeNameResolver extends JavaNameResolver { JavaDeclName declName = JavaSymbolSolverDeclNameResolver.getQualifiedDeclName( ((TypeVariable)type).asTypeParameter(), + m_currentFile, m_typeSolver, m_ignoredContexts); return new JavaTypeName(declName.getName(), new ArrayList(), declName.getParent()); diff --git a/java_indexer/src/main/java/com/sourcetrail/JavaparserDeclNameResolver.java b/java_indexer/src/main/java/com/sourcetrail/JavaparserDeclNameResolver.java index c18b309d..11ff0631 100644 --- a/java_indexer/src/main/java/com/sourcetrail/JavaparserDeclNameResolver.java +++ b/java_indexer/src/main/java/com/sourcetrail/JavaparserDeclNameResolver.java @@ -1,9 +1,11 @@ package com.sourcetrail; +import java.io.File; import java.util.ArrayList; import java.util.List; import java.util.Optional; +import com.github.javaparser.Position; import com.github.javaparser.ast.CompilationUnit; import com.github.javaparser.ast.Node; import com.github.javaparser.ast.NodeList; @@ -20,6 +22,7 @@ import com.github.javaparser.ast.body.Parameter; import com.github.javaparser.ast.body.TypeDeclaration; import com.github.javaparser.ast.body.VariableDeclarator; import com.github.javaparser.ast.expr.Name; +import com.github.javaparser.ast.expr.ObjectCreationExpr; import com.github.javaparser.ast.type.TypeParameter; import com.github.javaparser.symbolsolver.model.resolution.TypeSolver; @@ -30,19 +33,19 @@ import com.sourcetrail.name.JavaVariableDeclName; public class JavaparserDeclNameResolver extends JavaNameResolver { - public JavaparserDeclNameResolver(TypeSolver typeSolver, ContextList ignoredContexts) + public JavaparserDeclNameResolver(File currentFile, TypeSolver typeSolver, ContextList ignoredContexts) { - super(typeSolver, ignoredContexts); + super(currentFile, typeSolver, ignoredContexts); } - public static JavaDeclName getQualifiedDeclName(VariableDeclarator decl, TypeSolver typeSolver) + public static JavaDeclName getQualifiedDeclName(VariableDeclarator decl, File currentFile, TypeSolver typeSolver) { - return getQualifiedDeclName(decl, typeSolver, null); + return getQualifiedDeclName(decl, currentFile, typeSolver, null); } - public static JavaDeclName getQualifiedDeclName(VariableDeclarator decl, TypeSolver typeSolver, ContextList ignoredContexts) + public static JavaDeclName getQualifiedDeclName(VariableDeclarator decl, File currentFile, TypeSolver typeSolver, ContextList ignoredContexts) { - JavaparserDeclNameResolver resolver = new JavaparserDeclNameResolver(typeSolver, ignoredContexts); + JavaparserDeclNameResolver resolver = new JavaparserDeclNameResolver(currentFile, typeSolver, ignoredContexts); return resolver.getQualifiedDeclName(decl); } @@ -53,31 +56,9 @@ public class JavaparserDeclNameResolver extends JavaNameResolver if (decl != null) { declName = getDeclName(decl); - - BodyDeclaration declContext = getBodyDeclContext(decl); - if (declContext != null) + if (!declName.getIsUnsolved()) { - if (!m_ignoredContexts.contains(declContext)) - { - declName.setParent(getQualifiedDeclName(declContext)); - } - } - else - { - Optional compilationUnit = decl.getAncestorOfType(CompilationUnit.class); - - if (compilationUnit.isPresent()) - { - Optional packageDecl = compilationUnit.get().getPackageDeclaration(); - if (packageDecl.isPresent()) - { - declName.setParent(getQualifiedName(packageDecl.get().getName())); - } - } - else - { - throw new UnsupportedOperationException(); - } + declName.setParent(getQualifiedContextName(decl)); } } return declName; @@ -85,7 +66,7 @@ public class JavaparserDeclNameResolver extends JavaNameResolver public JavaDeclName getDeclName(VariableDeclarator decl) { - JavaTypeName typeName = JavaparserTypeNameResolver.getQualifiedTypeName(decl.getType(), m_typeSolver, m_ignoredContexts.copy()); + JavaTypeName typeName = JavaparserTypeNameResolver.getQualifiedTypeName(decl.getType(), m_currentFile, m_typeSolver, m_ignoredContexts.copy()); boolean isStatic = false; Optional fieldDeclaration = decl.getAncestorOfType(FieldDeclaration.class); @@ -97,14 +78,14 @@ public class JavaparserDeclNameResolver extends JavaNameResolver return new JavaVariableDeclName(decl.getNameAsString(), typeName, isStatic); } - public static JavaDeclName getQualifiedDeclName(BodyDeclaration decl, TypeSolver typeSolver) + public static JavaDeclName getQualifiedDeclName(BodyDeclaration decl, File currentFile, TypeSolver typeSolver) { - return getQualifiedDeclName(decl, typeSolver, null); + return getQualifiedDeclName(decl, currentFile, typeSolver, null); } - public static JavaDeclName getQualifiedDeclName(BodyDeclaration decl, TypeSolver typeSolver, ContextList ignoredContexts) + public static JavaDeclName getQualifiedDeclName(BodyDeclaration decl, File currentFile, TypeSolver typeSolver, ContextList ignoredContexts) { - JavaparserDeclNameResolver resolver = new JavaparserDeclNameResolver(typeSolver, ignoredContexts); + JavaparserDeclNameResolver resolver = new JavaparserDeclNameResolver(currentFile, typeSolver, ignoredContexts); return resolver.getQualifiedDeclName(decl); } @@ -115,31 +96,9 @@ public class JavaparserDeclNameResolver extends JavaNameResolver if (decl != null) { declName = getDeclName(decl); - - BodyDeclaration declContext = getBodyDeclContext(decl); - if (declContext != null) + if (!declName.getIsUnsolved()) { - if (!m_ignoredContexts.contains(declContext)) - { - declName.setParent(getQualifiedDeclName(declContext)); - } - } - else - { - Optional compilationUnit = decl.getAncestorOfType(CompilationUnit.class); - - if (compilationUnit.isPresent()) - { - Optional packageDecl = compilationUnit.get().getPackageDeclaration(); - if (packageDecl.isPresent()) - { - declName.setParent(getQualifiedName(packageDecl.get().getName())); - } - } - else - { - throw new UnsupportedOperationException(); - } + declName.setParent(getQualifiedContextName(decl)); } } @@ -187,14 +146,14 @@ public class JavaparserDeclNameResolver extends JavaNameResolver return declName; } - public static JavaDeclName getQualifiedDeclName(TypeParameter decl, TypeSolver typeSolver) + public static JavaDeclName getQualifiedDeclName(TypeParameter decl, File currentFile, TypeSolver typeSolver) { - return getQualifiedDeclName(decl, typeSolver, null); + return getQualifiedDeclName(decl, currentFile, typeSolver, null); } - public static JavaDeclName getQualifiedDeclName(TypeParameter decl, TypeSolver typeSolver, ContextList ignoredContexts) + public static JavaDeclName getQualifiedDeclName(TypeParameter decl, File currentFile, TypeSolver typeSolver, ContextList ignoredContexts) { - JavaparserDeclNameResolver resolver = new JavaparserDeclNameResolver(typeSolver, ignoredContexts); + JavaparserDeclNameResolver resolver = new JavaparserDeclNameResolver(currentFile, typeSolver, ignoredContexts); return resolver.getQualifiedDeclName(decl); } @@ -205,18 +164,10 @@ public class JavaparserDeclNameResolver extends JavaNameResolver if (decl != null) { declName = getDeclName(decl); - - BodyDeclaration declContext = getBodyDeclContext(decl); - if (declContext != null) + + if (!declName.getIsUnsolved()) { - if (!m_ignoredContexts.contains(declContext)) - { - declName.setParent(getQualifiedDeclName(declContext)); - } - } - else - { - throw new UnsupportedOperationException("no appropriate parent found for TypeParameter"); + declName.setParent(getQualifiedContextName(decl)); } } return declName; @@ -227,6 +178,42 @@ public class JavaparserDeclNameResolver extends JavaNameResolver return new JavaDeclName(decl.getName().asString()); } + public static JavaDeclName getQualifiedDeclName(ObjectCreationExpr anonymousClassDecl, File currentFile, TypeSolver typeSolver) + { + return getQualifiedDeclName(anonymousClassDecl, currentFile, typeSolver, null); + } + + public static JavaDeclName getQualifiedDeclName(ObjectCreationExpr anonymousClassDecl, File currentFile, TypeSolver typeSolver, ContextList ignoredContexts) + { + JavaparserDeclNameResolver resolver = new JavaparserDeclNameResolver(currentFile, typeSolver, ignoredContexts); + return resolver.getQualifiedDeclName(anonymousClassDecl); + } + + public JavaDeclName getQualifiedDeclName(ObjectCreationExpr anonymousClassDecl) + { + JavaDeclName declName = JavaDeclName.unsolved(); + + if (anonymousClassDecl != null) + { + declName = getDeclName(anonymousClassDecl); + if (!declName.getIsUnsolved()) + { + declName.setParent(getQualifiedContextName(anonymousClassDecl)); + } + } + return declName; + } + + public JavaDeclName getDeclName(ObjectCreationExpr anonymousClassDecl) + { + if (anonymousClassDecl.getAnonymousClassBody().isPresent()) + { + Position position = anonymousClassDecl.getBegin().orElse(new Position(0, 0)); + return JavaDeclName.anonymousClass(m_currentFile.getName(), position.line, position.column); + } + return JavaDeclName.unsolved(); + } + private static List getTypeParameterNames(TypeDeclaration decl) { NodeList typeParameters = null; @@ -261,6 +248,39 @@ public class JavaparserDeclNameResolver extends JavaNameResolver return declName; } + private JavaDeclName getQualifiedContextName(Node decl) + { + Node parentNode = decl.getParentNode().orElse(null); + if (parentNode == null) + { + return null; + } + + if (parentNode instanceof BodyDeclaration && !(parentNode instanceof FieldDeclaration)) + { + if (m_ignoredContexts.contains((BodyDeclaration) parentNode)) + { + return null; + } + return getQualifiedDeclName((BodyDeclaration) parentNode); + } + else if (parentNode instanceof CompilationUnit) + { + Optional packageDecl = ((CompilationUnit) parentNode).getPackageDeclaration(); + if (packageDecl.isPresent()) + { + return getQualifiedName(packageDecl.get().getName()); + } + return null; + } + else if (parentNode instanceof ObjectCreationExpr && ((ObjectCreationExpr) parentNode).getAnonymousClassBody().isPresent()) + { + return getQualifiedDeclName((ObjectCreationExpr) parentNode); + } + + return getQualifiedContextName(parentNode); + } + private JavaDeclName getDeclNameOfCallable(T decl) { ContextList ignoredContextsForTypes = m_ignoredContexts.copy(); @@ -269,13 +289,13 @@ public class JavaparserDeclNameResolver extends JavaNameResolver List parameterNames = new ArrayList<>(); for (Parameter parameter: decl.getParameters()) { - parameterNames.add(JavaparserTypeNameResolver.getQualifiedTypeName(parameter.getType(), m_typeSolver, ignoredContextsForTypes)); + parameterNames.add(JavaparserTypeNameResolver.getQualifiedTypeName(parameter.getType(), m_currentFile, m_typeSolver, ignoredContextsForTypes)); } JavaTypeName returnType = new JavaTypeName("", null); if (decl.isMethod()) { - returnType = JavaparserTypeNameResolver.getQualifiedTypeName(decl.getType(), m_typeSolver, ignoredContextsForTypes); + returnType = JavaparserTypeNameResolver.getQualifiedTypeName(decl.getType(), m_currentFile, m_typeSolver, ignoredContextsForTypes); } return new JavaFunctionDeclName( @@ -286,28 +306,4 @@ public class JavaparserDeclNameResolver extends JavaNameResolver decl.isStatic() ); } - - private static BodyDeclaration getBodyDeclContext(Node decl) - { - BodyDeclaration context = null; - - Optional parentNode = decl.getParentNode(); - while ( - parentNode.isPresent() && - !( - parentNode.get() instanceof BodyDeclaration && - (!(parentNode.get() instanceof FieldDeclaration)) - ) - ) - { - parentNode = parentNode.get().getParentNode(); - } - - if (parentNode.isPresent()) - { - context = (BodyDeclaration)parentNode.get(); - } - - return context; - } } diff --git a/java_indexer/src/main/java/com/sourcetrail/JavaparserTypeNameResolver.java b/java_indexer/src/main/java/com/sourcetrail/JavaparserTypeNameResolver.java index ec615afb..edb31be2 100644 --- a/java_indexer/src/main/java/com/sourcetrail/JavaparserTypeNameResolver.java +++ b/java_indexer/src/main/java/com/sourcetrail/JavaparserTypeNameResolver.java @@ -1,5 +1,7 @@ package com.sourcetrail; +import java.io.File; + import com.github.javaparser.ast.type.*; import com.github.javaparser.symbolsolver.javaparsermodel.JavaParserFacade; import com.github.javaparser.symbolsolver.model.resolution.TypeSolver; @@ -8,19 +10,19 @@ import com.sourcetrail.name.JavaTypeName; public class JavaparserTypeNameResolver extends JavaNameResolver { - public JavaparserTypeNameResolver(TypeSolver typeSolver, ContextList ignoredContexts) + public JavaparserTypeNameResolver(File currentFile, TypeSolver typeSolver, ContextList ignoredContexts) { - super(typeSolver, ignoredContexts); + super(currentFile, typeSolver, ignoredContexts); } - public static JavaTypeName getQualifiedTypeName(Type type, TypeSolver typeSolver) + public static JavaTypeName getQualifiedTypeName(Type type, File currentFile, TypeSolver typeSolver) { - return getQualifiedTypeName(type, typeSolver, null); + return getQualifiedTypeName(type, currentFile, typeSolver, null); } - public static JavaTypeName getQualifiedTypeName(Type type, TypeSolver typeSolver, ContextList ignoredContexts) + public static JavaTypeName getQualifiedTypeName(Type type, File currentFile, TypeSolver typeSolver, ContextList ignoredContexts) { - JavaparserTypeNameResolver resolver = new JavaparserTypeNameResolver(typeSolver, ignoredContexts); + JavaparserTypeNameResolver resolver = new JavaparserTypeNameResolver(currentFile, typeSolver, ignoredContexts); return resolver.getQualifiedTypeName(type); } @@ -34,6 +36,7 @@ public class JavaparserTypeNameResolver extends JavaNameResolver { return JavaSymbolSolverTypeNameResolver.getQualifiedTypeName( JavaParserFacade.get(m_typeSolver).convert(type, type), + m_currentFile, m_typeSolver, m_ignoredContexts ); @@ -53,7 +56,8 @@ public class JavaparserTypeNameResolver extends JavaNameResolver else if (type instanceof TypeParameter) { return JavaSymbolSolverTypeNameResolver.getQualifiedTypeName( - JavaParserFacade.get(m_typeSolver).convert(type, type), + JavaParserFacade.get(m_typeSolver).convert(type, type), + m_currentFile, m_typeSolver, m_ignoredContexts ); diff --git a/java_indexer/src/main/java/com/sourcetrail/name/JavaDeclName.java b/java_indexer/src/main/java/com/sourcetrail/name/JavaDeclName.java index a4a77476..031ebd9c 100644 --- a/java_indexer/src/main/java/com/sourcetrail/name/JavaDeclName.java +++ b/java_indexer/src/main/java/com/sourcetrail/name/JavaDeclName.java @@ -7,10 +7,21 @@ public class JavaDeclName private JavaDeclName m_parent = null; private String m_name = ""; private List m_typeParameterNames = null; - + private boolean m_isUnsolved = false; + private boolean m_isAnonymous = false; + public static JavaDeclName unsolved() { - return new JavaDeclName("unsolved-symbol"); + JavaDeclName declName = new JavaDeclName("unsolved-symbol"); + declName.m_isUnsolved = true; + return declName; + } + + public static JavaDeclName anonymousClass(String fileName, int line, int col) + { + JavaDeclName declName = new JavaDeclName("anonymous class (" + fileName + "<" + line + ":" + col + ">)"); + declName.m_isAnonymous = true; + return declName; } public static JavaDeclName fromDotSeparatedString(String s) @@ -57,6 +68,16 @@ public class JavaDeclName return m_name; } + public boolean getIsUnsolved() + { + return m_isUnsolved; + } + + public boolean getIsAnonymous() + { + return m_isAnonymous; + } + public NameHierarchy toNameHierarchy() { NameHierarchy nameHierarchy; diff --git a/src/test/JavaParserTestSuite.h b/src/test/JavaParserTestSuite.h index 79628b95..a1179959 100644 --- a/src/test/JavaParserTestSuite.h +++ b/src/test/JavaParserTestSuite.h @@ -158,6 +158,49 @@ public: )); } + void test_java_parser_finds_anonymous_class_declaration() + { + std::shared_ptr client = parseCode( + "package foo;\n" + "public class A\n" + "{\n" + " interface I { }\n" + " public void bar()\n" + " {\n" + " I i = new I() { };\n" + " };\n" + "}\n" + ); + + TS_ASSERT(utility::containsElement( + client->classes, "foo.A.bar.anonymous class (input.cc<7:9>) <7:9 <7:13 7:13> 7:19>" + )); + } + + void test_java_parser_finds_method_declaration_in_anonymous_class() + { + std::shared_ptr client = parseCode( + "package foo;\n" + "public class A\n" + "{\n" + " interface I {\n" + " public void foo();\n" + " }\n" + " public void bar()\n" + " {\n" + " I i = new I()\n" + " {\n" + " public void foo() {}\n" + " };\n" + " };\n" + "}\n" + ); + + TS_ASSERT(utility::containsElement( + client->methods, "public void foo.A.bar.anonymous class (input.cc<9:9>).foo() <11:4 <11:16 11:18> 11:23>" + )); + } + void test_java_parser_finds_method_declaration_with_static_keyword_in_signature() { std::shared_ptr client = parseCode( @@ -250,7 +293,7 @@ public: )); } - void test_java_parser_finds_definition_of_method_parameter() + void test_java_parser_finds_declaration_of_method_parameter() { std::shared_ptr client = parseCode( "package foo;\n" @@ -267,7 +310,7 @@ public: )); } - void test_java_parser_finds_definition_of_local_variable() + void test_java_parser_finds_declaration_of_local_variable() { std::shared_ptr client = parseCode( "package foo;\n" @@ -285,7 +328,7 @@ public: )); } - void test_java_parser_finds_definition_of_type_parameter_of_class() + void test_java_parser_finds_declaration_of_type_parameter_of_class() { std::shared_ptr client = parseCode( "public class A \n" @@ -298,7 +341,7 @@ public: )); } - void test_java_parser_finds_definition_of_type_parameter_of_method() + void test_java_parser_finds_declaration_of_type_parameter_of_method() { std::shared_ptr client = parseCode( "public class A\n"