src: moved Java indexer from JavaSymbolSolver to Eclipse JDT

* added some more tests
* changed 3rd party licenses respectively

fortune cookie message = Your present plans are going to succeed.
This commit is contained in:
mlangkabel
2017-09-07 12:40:34 +02:00
parent 6cf0b87f7b
commit 5c614c77e2
51 changed files with 2518 additions and 3480 deletions
Binary file not shown.
Binary file not shown.
Binary file not shown.
+3 -44
View File
@@ -8,7 +8,6 @@
<url>http://maven.apache.org</url>
<properties>
<java.version>1.8</java.version>
<javasymbolsolver.version>x.x.x</javasymbolsolver.version>
</properties>
<build>
@@ -27,49 +26,9 @@
<dependencies>
<dependency>
<groupId>org.dummy</groupId>
<artifactId>java-symbol-solver-core</artifactId>
<version>${javasymbolsolver.version}</version>
<scope>system</scope>
<systemPath>${project.basedir}/lib/java-symbol-solver-core.jar</systemPath>
</dependency>
<dependency>
<groupId>org.dummy</groupId>
<artifactId>java-symbol-solver-logic</artifactId>
<version>${javasymbolsolver.version}</version>
<scope>system</scope>
<systemPath>${project.basedir}/lib/java-symbol-solver-logic.jar</systemPath>
</dependency>
<dependency>
<groupId>org.dummy</groupId>
<artifactId>java-symbol-solver-model</artifactId>
<version>${javasymbolsolver.version}</version>
<scope>system</scope>
<systemPath>${project.basedir}/lib/java-symbol-solver-model.jar</systemPath>
</dependency>
<dependency>
<groupId>com.github.javaparser</groupId>
<artifactId>javaparser-core</artifactId>
<version>3.3.0</version>
<scope>compile</scope>
</dependency>
<dependency>
<groupId>org.javassist</groupId>
<artifactId>javassist</artifactId>
<version>3.19.0-GA</version>
<scope>compile</scope>
</dependency>
<dependency>
<groupId>com.google.guava</groupId>
<artifactId>guava</artifactId>
<version>21.0</version>
<scope>compile</scope>
</dependency>
<dependency>
<groupId>io.javaslang</groupId>
<artifactId>javaslang</artifactId>
<version>2.0.3</version>
<scope>compile</scope>
<groupId>org.eclipse.jdt</groupId>
<artifactId>org.eclipse.jdt.core</artifactId>
<version>3.12.3</version>
</dependency>
</dependencies>
</project>
@@ -1,6 +1,6 @@
package com.sourcetrail;
import com.github.javaparser.ast.AccessSpecifier;
import org.eclipse.jdt.core.dom.Modifier;
public enum AccessKind
{ // these values need to be the same as AccesKind in C++ code
@@ -14,31 +14,23 @@ public enum AccessKind
private final int m_value;
private AccessKind(int value)
{
this.m_value = value;
}
public int getValue()
{
return m_value;
}
public static AccessKind fromAccessSpecifier(AccessSpecifier specifier)
{
switch (specifier)
{
case PUBLIC:
return AccessKind.PUBLIC;
case PROTECTED:
return AccessKind.PROTECTED;
case PRIVATE:
return AccessKind.PRIVATE;
case DEFAULT:
return AccessKind.DEFAULT;
default:
return AccessKind.NONE;
}
}
private AccessKind(int value)
{
this.m_value = value;
}
public int getValue()
{
return m_value;
}
public static AccessKind fromModifiers(int modifiers)
{
if ((modifiers & Modifier.PUBLIC) != 0) { return AccessKind.PUBLIC; }
if ((modifiers & Modifier.PROTECTED) != 0) { return AccessKind.PROTECTED; }
if ((modifiers & Modifier.PRIVATE) != 0) { return AccessKind.PRIVATE; }
if ((modifiers & Modifier.DEFAULT) != 0) { return AccessKind.DEFAULT; }
return AccessKind.DEFAULT;
}
}
File diff suppressed because it is too large Load Diff
@@ -1,269 +0,0 @@
package com.sourcetrail;
import com.github.javaparser.ast.visitor.GenericVisitorAdapter;
import com.github.javaparser.ast.*;
import com.github.javaparser.ast.body.*;
import com.github.javaparser.ast.expr.*;
import com.github.javaparser.ast.stmt.*;
import com.github.javaparser.ast.type.*;
import java.util.Stack;
public abstract class AstVisitorAdapter extends GenericVisitorAdapter<Boolean, Void>
{
private Stack<ReferenceKind> m_typeRefKind = new Stack<ReferenceKind>();
protected ReferenceKind getTypeReferenceKind()
{
if (!m_typeRefKind.isEmpty())
{
return m_typeRefKind.peek();
}
return ReferenceKind.TYPE_USAGE;
}
//- Compilation Unit ----------------------------------
@Override public Boolean visit(final CompilationUnit n, Void arg)
{
m_typeRefKind.push(ReferenceKind.TYPE_USAGE);
Boolean result = super.visit(n, arg);
m_typeRefKind.pop();
return result;
}
//- Body ----------------------------------------------
@Override public Boolean visit(ClassOrInterfaceDeclaration n, Void arg)
{
Boolean result;
{
result = n.getTypeParameters().accept(this, arg);
if (result != null)
return result;
}
{
result = n.getMembers().accept(this, arg);
if (result != null)
return result;
}
{
result = n.getName().accept(this, arg);
if (result != null)
return result;
}
{
result = n.getAnnotations().accept(this, arg);
if (result != null)
return result;
}
if (n.getComment().isPresent()) {
result = n.getComment().get().accept(this, arg);
if (result != null)
return result;
}
m_typeRefKind.push(ReferenceKind.INHERITANCE);
{
result = n.getExtendedTypes().accept(this, arg);
if (result != null)
return result;
}
{
result = n.getImplementedTypes().accept(this, arg);
if (result != null)
return result;
}
m_typeRefKind.pop();
return null;
}
@Override public Boolean visit(EnumDeclaration n, Void arg)
{
Boolean result;
{
result = n.getEntries().accept(this, arg);
if (result != null)
return result;
}
{
result = n.getMembers().accept(this, arg);
if (result != null)
return result;
}
{
result = n.getName().accept(this, arg);
if (result != null)
return result;
}
{
result = n.getAnnotations().accept(this, arg);
if (result != null)
return result;
}
if (n.getComment().isPresent()) {
result = n.getComment().get().accept(this, arg);
if (result != null)
return result;
}
m_typeRefKind.push(ReferenceKind.INHERITANCE);
{
result = n.getImplementedTypes().accept(this, arg);
if (result != null)
return result;
}
m_typeRefKind.pop();
return null;
}
//- Type ----------------------------------------------
@Override public Boolean visit(ClassOrInterfaceType n, Void arg)
{
Boolean result;
{
result = n.getName().accept(this, arg);
if (result != null)
return result;
}
// don't visit the qualifier here.
// if (n.getScope().isPresent()) {
// result = n.getScope().get().accept(this, arg);
// if (result != null)
// return result;
// }
{
result = n.getAnnotations().accept(this, arg);
if (result != null)
return result;
}
if (n.getComment().isPresent()) {
result = n.getComment().get().accept(this, arg);
if (result != null)
return result;
}
m_typeRefKind.push(ReferenceKind.TYPE_ARGUMENT);
if (n.getTypeArguments().isPresent()) {
result = n.getTypeArguments().get().accept(this, arg);
if (result != null)
return result;
}
m_typeRefKind.pop();
return null;
}
//- Expression ----------------------------------------
@Override public Boolean visit(MethodCallExpr n, Void arg)
{
Boolean result;
{
result = n.getArguments().accept(this, arg);
if (result != null)
return result;
}
{
result = n.getName().accept(this, arg);
if (result != null)
return result;
}
if (n.getScope().isPresent()) {
result = n.getScope().get().accept(this, arg);
if (result != null)
return result;
}
if (n.getComment().isPresent()) {
result = n.getComment().get().accept(this, arg);
if (result != null)
return result;
}
m_typeRefKind.push(ReferenceKind.TYPE_ARGUMENT);
if (n.getTypeArguments().isPresent()) {
result = n.getTypeArguments().get().accept(this, arg);
if (result != null)
return result;
}
m_typeRefKind.pop();
return null;
}
@Override public Boolean visit(ObjectCreationExpr n, Void arg)
{
Boolean result;
if (n.getAnonymousClassBody().isPresent()) {
result = n.getAnonymousClassBody().get().accept(this, arg);
if (result != null)
return result;
}
{
result = n.getArguments().accept(this, arg);
if (result != null)
return result;
}
if (n.getScope().isPresent()) {
result = n.getScope().get().accept(this, arg);
if (result != null)
return result;
}
// {
// result = n.getType().accept(this, arg);
// if (result != null)
// return result;
// }
if (n.getComment().isPresent()) {
result = n.getComment().get().accept(this, arg);
if (result != null)
return result;
}
m_typeRefKind.push(ReferenceKind.TYPE_ARGUMENT);
if (n.getTypeArguments().isPresent()) {
result = n.getTypeArguments().get().accept(this, arg);
if (result != null)
return result;
}
m_typeRefKind.pop();
return null;
}
//- Statements ----------------------------------------
@Override public Boolean visit(ExplicitConstructorInvocationStmt n, Void arg)
{
Boolean result;
{
result = n.getArguments().accept(this, arg);
if (result != null)
return result;
}
if (n.getExpression().isPresent()) {
result = n.getExpression().get().accept(this, arg);
if (result != null)
return result;
}
if (n.getComment().isPresent()) {
result = n.getComment().get().accept(this, arg);
if (result != null)
return result;
}
m_typeRefKind.push(ReferenceKind.TYPE_ARGUMENT);
if (n.getTypeArguments().isPresent()) {
result = n.getTypeArguments().get().accept(this, arg);
if (result != null)
return result;
}
m_typeRefKind.pop();
return null;
}
}
@@ -2,73 +2,63 @@ package com.sourcetrail;
import java.util.Optional;
import com.github.javaparser.Range;
import com.sourcetrail.name.NameHierarchy;
public abstract class AstVisitorClient
{
public void recordSymbolWithLocation(
String symbolName, SymbolKind symbolType,
Optional<Range> range,
AccessKind access, DefinitionKind definitionKind
)
NameHierarchy symbolName, SymbolKind symbolKind,
Optional<Range> range,
AccessKind access, DefinitionKind definitionKind)
{
recordSymbolWithLocation(
symbolName, symbolType,
range.orElse(Range.range(0, 0, 0, 0)),
access, definitionKind
);
symbolName, symbolKind,
range.orElse(new Range(0, 0, 0, 0)),
access, definitionKind);
}
public void recordSymbolWithLocationAndScope(
String symbolName, SymbolKind symbolType,
Optional<Range> range,
Optional<Range> scopeRange,
AccessKind access, DefinitionKind definitionKind
)
NameHierarchy symbolName, SymbolKind symbolKind,
Optional<Range> range,
Optional<Range> scopeRange,
AccessKind access, DefinitionKind definitionKind)
{
recordSymbolWithLocationAndScope(
symbolName, symbolType,
range.orElse(Range.range(0, 0, 0, 0)),
scopeRange.orElse(Range.range(0, 0, 0, 0)),
access, definitionKind
);
symbolName, symbolKind,
range.orElse(new Range(0, 0, 0, 0)),
scopeRange.orElse(new Range(0, 0, 0, 0)),
access, definitionKind);
}
public void recordReference(
ReferenceKind referenceKind, String referencedName, String contextName,
Optional<Range> range
)
ReferenceKind referenceKind, NameHierarchy referencedName, NameHierarchy contextName,
Optional<Range> range)
{
recordReference(
referenceKind, referencedName, contextName,
range.orElse(Range.range(0, 0, 0, 0))
);
referenceKind, referencedName, contextName,
range.orElse(new Range(0, 0, 0, 0)));
}
public void recordLocalSymbol(
String symbolName,
Optional<Range> range
)
NameHierarchy symbolName,
Optional<Range> range)
{
recordLocalSymbol(symbolName, range.orElse(Range.range(0, 0, 0, 0)));
recordLocalSymbol(symbolName, range.orElse(new Range(0, 0, 0, 0)));
}
public void recordComment(
Optional<Range> range
)
Optional<Range> range)
{
recordComment(range.orElse(Range.range(0, 0, 0, 0)));
recordComment(range.orElse(new Range(0, 0, 0, 0)));
}
public void recordError(
String message, boolean fatal, boolean indexed,
Optional<Range> range
)
Optional<Range> range)
{
recordError(
message, fatal, indexed,
range.orElse(Range.range(0, 0, 0, 0))
);
message, fatal, indexed,
range.orElse(new Range(0, 0, 0, 0)));
}
public abstract boolean getInterrupted();
@@ -80,40 +70,33 @@ public abstract class AstVisitorClient
public abstract void logError(String error);
public abstract void recordSymbol(
String symbolName, SymbolKind symbolType,
AccessKind access, DefinitionKind definitionKind
);
NameHierarchy symbolName, SymbolKind symbolKind,
AccessKind access, DefinitionKind definitionKind);
public abstract void recordSymbolWithLocation(
String symbolName, SymbolKind symbolType,
Range range,
AccessKind access, DefinitionKind definitionKind
);
NameHierarchy symbolName, SymbolKind symbolKind,
Range range,
AccessKind access, DefinitionKind definitionKind);
public abstract void recordSymbolWithLocationAndScope(
String symbolName, SymbolKind symbolType,
Range range,
Range scopeRange,
AccessKind access, DefinitionKind definitionKind
);
NameHierarchy symbolName, SymbolKind symbolKind,
Range range,
Range scopeRange,
AccessKind access, DefinitionKind definitionKind);
public abstract void recordReference(
ReferenceKind referenceKind, String referencedName, String contextName,
Range range
);
ReferenceKind referenceKind, NameHierarchy referencedName, NameHierarchy contextName,
Range range);
public abstract void recordLocalSymbol(
String symbolName,
Range range
);
NameHierarchy symbolName,
Range range);
public abstract void recordComment(
Range range
);
Range range);
public abstract void recordError(
String message, boolean fatal, boolean indexed,
Range range
);
String message, boolean fatal, boolean indexed,
Range range);
}
@@ -1,54 +0,0 @@
package com.sourcetrail;
import com.github.javaparser.ast.type.TypeParameter;
import com.github.javaparser.ast.NodeList;
import com.github.javaparser.ast.body.BodyDeclaration;
import com.github.javaparser.ast.body.ConstructorDeclaration;
import com.github.javaparser.ast.body.Parameter;
import com.github.javaparser.ast.type.Type;
import com.github.javaparser.ast.type.UnknownType;
public class CallableConstructorDecl implements CallableDecl
{
private ConstructorDeclaration m_decl;
public CallableConstructorDecl(ConstructorDeclaration decl)
{
m_decl = decl;
}
public BodyDeclaration getWrappedNode()
{
return m_decl;
}
public boolean isMethod()
{
return false;
}
public String getName()
{
return m_decl.getNameAsString();
}
public NodeList<TypeParameter> getTypeParameters()
{
return m_decl.getTypeParameters();
}
public NodeList<Parameter> getParameters()
{
return m_decl.getParameters();
}
public Type getType()
{
return new UnknownType();
}
public boolean isStatic()
{
return m_decl.isStatic();
}
}
@@ -1,18 +0,0 @@
package com.sourcetrail;
import com.github.javaparser.ast.type.TypeParameter;
import com.github.javaparser.ast.NodeList;
import com.github.javaparser.ast.body.BodyDeclaration;
import com.github.javaparser.ast.body.Parameter;
import com.github.javaparser.ast.type.Type;
public interface CallableDecl
{
public BodyDeclaration getWrappedNode();
public boolean isMethod();
public String getName();
public NodeList<TypeParameter> getTypeParameters();
public NodeList<Parameter> getParameters();
public Type getType();
public boolean isStatic();
}
@@ -1,53 +0,0 @@
package com.sourcetrail;
import com.github.javaparser.ast.type.TypeParameter;
import com.github.javaparser.ast.NodeList;
import com.github.javaparser.ast.body.BodyDeclaration;
import com.github.javaparser.ast.body.MethodDeclaration;
import com.github.javaparser.ast.body.Parameter;
import com.github.javaparser.ast.type.Type;
public class CallableMethodDecl implements CallableDecl
{
private MethodDeclaration m_decl;
public CallableMethodDecl(MethodDeclaration decl)
{
m_decl = decl;
}
public BodyDeclaration getWrappedNode()
{
return m_decl;
}
public boolean isMethod()
{
return true;
}
public String getName()
{
return m_decl.getNameAsString();
}
public NodeList<TypeParameter> getTypeParameters()
{
return m_decl.getTypeParameters();
}
public NodeList<Parameter> getParameters()
{
return m_decl.getParameters();
}
public Type getType()
{
return m_decl.getType();
}
public boolean isStatic()
{
return m_decl.isStatic();
}
}
@@ -0,0 +1,387 @@
package com.sourcetrail;
import java.io.File;
import java.util.List;
import java.util.Stack;
import org.eclipse.jdt.core.dom.ASTNode;
import org.eclipse.jdt.core.dom.ClassInstanceCreation;
import org.eclipse.jdt.core.dom.CompilationUnit;
import org.eclipse.jdt.core.dom.ConstructorInvocation;
import org.eclipse.jdt.core.dom.CreationReference;
import org.eclipse.jdt.core.dom.EnumConstantDeclaration;
import org.eclipse.jdt.core.dom.EnumDeclaration;
import org.eclipse.jdt.core.dom.FieldDeclaration;
import org.eclipse.jdt.core.dom.ImportDeclaration;
import org.eclipse.jdt.core.dom.Javadoc;
import org.eclipse.jdt.core.dom.MethodInvocation;
import org.eclipse.jdt.core.dom.NameQualifiedType;
import org.eclipse.jdt.core.dom.ParameterizedType;
import org.eclipse.jdt.core.dom.QualifiedType;
import org.eclipse.jdt.core.dom.SuperConstructorInvocation;
import org.eclipse.jdt.core.dom.SuperMethodInvocation;
import org.eclipse.jdt.core.dom.SuperMethodReference;
import org.eclipse.jdt.core.dom.TypeDeclaration;
import org.eclipse.jdt.core.dom.TypeMethodReference;
import org.eclipse.jdt.core.dom.VariableDeclarationFragment;
public class ContextAwareAstVisitor extends AstVisitor
{
private Stack<ReferenceKind> m_typeRefKind = new Stack<>();
public ContextAwareAstVisitor(AstVisitorClient client, File filePath, String fileContent, CompilationUnit compilationUnit)
{
super(client, filePath, fileContent, compilationUnit);
}
@Override
public boolean visit(TypeDeclaration node)
{
boolean visitChildren = super.visit(node);
if (visitChildren)
{
acceptChild(node.getJavadoc());
acceptChildren(node.modifiers());
acceptChild(node.getName());
acceptChildren(node.typeParameters());
{
m_typeRefKind.push(ReferenceKind.INHERITANCE);
acceptChild(node.getSuperclassType());
acceptChildren(node.superInterfaceTypes());
m_typeRefKind.pop();
}
acceptChildren(node.bodyDeclarations());
}
return false;
}
@Override
public boolean visit(EnumDeclaration node)
{
boolean visitChildren = super.visit(node);
if (visitChildren)
{
acceptChild(node.getJavadoc());
acceptChildren(node.modifiers());
acceptChild(node.getName());
{
m_typeRefKind.push(ReferenceKind.INHERITANCE);
acceptChildren(node.superInterfaceTypes());
m_typeRefKind.pop();
}
acceptChildren(node.enumConstants());
acceptChildren(node.bodyDeclarations());
}
return false;
}
@Override
public boolean visit(EnumConstantDeclaration node)
{
boolean visitChildren = super.visit(node);
if (visitChildren)
{
// we don't visit and record the name of enum constant declarations because
// this would create an unwanted self-reference.
acceptChild(node.getJavadoc());
acceptChildren(node.modifiers());
acceptChildren(node.arguments());
acceptChild(node.getAnonymousClassDeclaration());
}
return false;
}
@Override
public boolean visit(VariableDeclarationFragment node)
{
boolean visitChildren = super.visit(node);
if (visitChildren)
{
// we don't visit and record the name of field declarations because
// this would create an unwanted self-reference.
if (!(node.getParent() instanceof FieldDeclaration))
{
acceptChild(node.getName());
}
acceptChildren(node.extraDimensions());
acceptChild(node.getInitializer());
}
return false;
}
@Override
public boolean visit(ClassInstanceCreation node)
{
boolean visitChildren = super.visit(node);
if (visitChildren)
{
acceptChild(node.getExpression());
{
m_typeRefKind.push(ReferenceKind.TYPE_ARGUMENT);
acceptChildren(node.typeArguments());
m_typeRefKind.pop();
}
if (node.getAnonymousClassDeclaration() != null)
{
m_typeRefKind.push(ReferenceKind.INHERITANCE);
acceptChild(node.getType());
m_typeRefKind.pop();
}
else
{
acceptChild(node.getType());
}
acceptChildren(node.arguments());
acceptChild(node.getAnonymousClassDeclaration());
}
return false;
}
@Override
public boolean visit(ParameterizedType node)
{
boolean visitChildren = super.visit(node);
if (visitChildren)
{
acceptChild(node.getType());
{
m_typeRefKind.push(ReferenceKind.TYPE_ARGUMENT);
acceptChildren(node.typeArguments());
m_typeRefKind.pop();
}
}
return false;
}
@Override
public boolean visit(QualifiedType node)
{
// We don't want to visit the qualifier right now.
boolean visitChildren = super.visit(node);
if (visitChildren)
{
acceptChildren(node.annotations());
acceptChild(node.getName());
}
return false;
}
@Override
public boolean visit(NameQualifiedType node)
{
// We don't want to visit the qualifier right now.
boolean visitChildren = super.visit(node);
if (visitChildren)
{
acceptChildren(node.annotations());
acceptChild(node.getName());
}
return false;
}
@Override
public boolean visit(final ImportDeclaration node)
{
// We don't want to visit the name of the ImportDeclaration because this could cause a self reference.
super.visit(node);
return false;
}
@Override
public boolean visit(MethodInvocation node)
{
boolean visitChildren = super.visit(node);
if (visitChildren)
{
acceptChild(node.getExpression());
{
m_typeRefKind.push(ReferenceKind.TYPE_ARGUMENT);
acceptChildren(node.typeArguments());
m_typeRefKind.pop();
}
acceptChild(node.getName());
acceptChildren(node.arguments());
}
return false;
}
@Override
public boolean visit(SuperMethodInvocation node)
{
// We don't want to visit the qualifier right now.
boolean visitChildren = super.visit(node);
if (visitChildren)
{
{
m_typeRefKind.push(ReferenceKind.TYPE_ARGUMENT);
acceptChildren(node.typeArguments());
m_typeRefKind.pop();
}
acceptChild(node.getName());
acceptChildren(node.arguments());
}
return false;
}
@Override
public boolean visit(ConstructorInvocation node)
{
boolean visitChildren = super.visit(node);
if (visitChildren)
{
{
m_typeRefKind.push(ReferenceKind.TYPE_ARGUMENT);
acceptChildren(node.typeArguments());
m_typeRefKind.pop();
}
acceptChildren(node.arguments());
}
return false;
}
@Override
public boolean visit(SuperConstructorInvocation node)
{
boolean visitChildren = super.visit(node);
if (visitChildren)
{
acceptChild(node.getExpression());
{
m_typeRefKind.push(ReferenceKind.TYPE_ARGUMENT);
acceptChildren(node.typeArguments());
m_typeRefKind.pop();
}
acceptChildren(node.arguments());
}
return false;
}
@Override
public boolean visit(CreationReference node)
{
// We don't want to visit the qualifying type right now.
boolean visitChildren = super.visit(node);
if (visitChildren)
{
{
m_typeRefKind.push(ReferenceKind.TYPE_ARGUMENT);
acceptChildren(node.typeArguments());
m_typeRefKind.pop();
}
}
return false;
}
@Override
public boolean visit(SuperMethodReference node)
{
// We don't want to visit qualifiers right now.
boolean visitChildren = super.visit(node);
if (visitChildren)
{
{
m_typeRefKind.push(ReferenceKind.TYPE_ARGUMENT);
acceptChildren(node.typeArguments());
m_typeRefKind.pop();
}
acceptChild(node.getName());
}
return false;
}
@Override
public boolean visit(TypeMethodReference node)
{
// We don't want to visit the qualifying type right now.
boolean visitChildren = super.visit(node);
if (visitChildren)
{
{
m_typeRefKind.push(ReferenceKind.TYPE_ARGUMENT);
acceptChildren(node.typeArguments());
m_typeRefKind.pop();
}
acceptChild(node.getName());
}
return false;
}
@Override
public boolean visit(Javadoc node)
{
// We don't want to visit symbol references inside Javadoc right now.
super.visit( node);
return false;
}
@Override
protected ReferenceKind getTypeReferenceKind()
{
if (!m_typeRefKind.isEmpty())
{
return m_typeRefKind.peek();
}
return ReferenceKind.TYPE_USAGE;
}
private void acceptChild(ASTNode node)
{
if (node != null)
{
node.accept(this);
}
}
private void acceptChildren(List<?> nodes)
{
if (nodes != null)
{
for (Object node: nodes)
{
if (node instanceof ASTNode)
{
acceptChild((ASTNode) node);
}
}
}
}
}
@@ -1,57 +1,33 @@
package com.sourcetrail;
import java.util.ArrayList;
import java.util.List;
import java.util.HashSet;
import java.util.Set;
import com.github.javaparser.ast.body.BodyDeclaration;
import com.github.javaparser.symbolsolver.model.declarations.TypeParametrizable;
import org.eclipse.jdt.core.dom.IBinding;
public class ContextList
{
private List<BodyDeclaration> m_bodyDeclarations = new ArrayList<>();
private List<TypeParametrizable> m_typeParameterizables = new ArrayList<>();
private Set<String> m_bindingKeys = new HashSet<>();
public ContextList copy()
{
ContextList contextList = new ContextList();
contextList.m_bodyDeclarations = new ArrayList<>(m_bodyDeclarations);
contextList.m_typeParameterizables = new ArrayList<>(m_typeParameterizables);
contextList.m_bindingKeys = new HashSet<>(m_bindingKeys);
return contextList;
}
public void add(BodyDeclaration v)
public void add(IBinding v)
{
m_bodyDeclarations.add(v);
}
public boolean contains(BodyDeclaration v)
{
for (BodyDeclaration bodyDeclaration: m_bodyDeclarations)
if (v != null)
{
if (bodyDeclaration.equals(v))
{
return true;
}
m_bindingKeys.add(v.getKey());
}
return false;
}
public void add(TypeParametrizable v)
public boolean contains(IBinding v)
{
m_typeParameterizables.add(v);
}
public boolean contains(TypeParametrizable v)
{
for (TypeParametrizable typeParameterizable: m_typeParameterizables)
{
if (typeParameterizable.toString().equals(v.toString()))
{
return true;
}
}
return false;
return v != null && m_bindingKeys.contains(v.getKey());
}
}
@@ -1,16 +0,0 @@
package com.sourcetrail;
public class DeclContext
{
private String m_name = null;
public DeclContext(String name)
{
m_name = name;
}
public String getName()
{
return m_name;
}
}
@@ -2,24 +2,9 @@ package com.sourcetrail;
import java.util.Arrays;
import java.util.List;
import java.util.Optional;
import com.github.javaparser.Position;
public class FileContent
{
public class Location
{
public int line;
public int column;
Location(int line, int column)
{
this.line = line;
this.column = column;
}
}
private List<String> m_lines;
public FileContent(String text)
@@ -27,17 +12,12 @@ public class FileContent
m_lines = Arrays.asList(text.split("\\r?\\n"));
}
public Location find(String s)
public Position findStartPosition(String s)
{
return find(s, Position.pos(1, 1));
return findStartPosition(s, new Position(1, 1));
}
public Location find(String s, Optional<Position> from)
{
return find(s, from.orElse(Position.pos(1, 1)));
}
public Location find(String s, Position from)
public Position findStartPosition(String s, Position from)
{
int lineIndex = from.line - 1;
int startColumn = from.column - 1;
@@ -47,11 +27,25 @@ public class FileContent
column = m_lines.get(lineIndex).indexOf(s, startColumn);
if (column != -1)
{
return new Location(lineIndex + 1, column + 1);
return new Position(lineIndex + 1, column + 1);
}
startColumn = 0;
lineIndex++;
}
return new Location(0, 0);
return new Position(0, 0);
}
public Range findRange(String s)
{
return findRange(s, new Position(1, 1));
}
public Range findRange(String s, Position from)
{
Position startPosition = findStartPosition(s, from);
return new Range(
startPosition,
new Position(startPosition.line, startPosition.column + s.length() - 1));
}
}
@@ -1,147 +1,128 @@
package com.sourcetrail;
import java.io.File;
import java.io.IOException;
import java.io.StringReader;
import java.util.HashMap;
import java.util.Map;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.Hashtable;
import com.github.javaparser.JavaParser;
import com.github.javaparser.ParseProblemException;
import com.github.javaparser.Position;
import com.github.javaparser.Problem;
import com.github.javaparser.Range;
import com.github.javaparser.ast.CompilationUnit;
import com.github.javaparser.ast.PackageDeclaration;
import com.github.javaparser.symbolsolver.javaparser.Navigator;
import com.github.javaparser.symbolsolver.javaparsermodel.JavaParserFacade;
import com.github.javaparser.symbolsolver.model.resolution.TypeSolver;
import com.github.javaparser.symbolsolver.resolution.typesolvers.CombinedTypeSolver;
import com.github.javaparser.symbolsolver.resolution.typesolvers.JarTypeSolver;
import com.github.javaparser.symbolsolver.resolution.typesolvers.ReflectionTypeSolver;
import com.sourcetrail.typesolver.SynchronizedJavaParserTypeSolver;
import org.eclipse.jdt.core.JavaCore;
import org.eclipse.jdt.core.compiler.IProblem;
import org.eclipse.jdt.core.dom.AST;
import org.eclipse.jdt.core.dom.ASTParser;
import org.eclipse.jdt.core.dom.ASTVisitor;
import org.eclipse.jdt.core.dom.BlockComment;
import org.eclipse.jdt.core.dom.Comment;
import org.eclipse.jdt.core.dom.CompilationUnit;
import org.eclipse.jdt.core.dom.LineComment;
import org.eclipse.jdt.core.dom.PackageDeclaration;
public class JavaIndexer
{
private static Map<String, TypeSolver> typeSolvers = new HashMap<>();
{
public static void processFile(int address, String filePath, String fileContent, String classPath, int verbose)
{
AstVisitorClient astVisitorClient = new JavaIndexerAstVisitorClient(address);
processFile(new JavaIndexerAstVisitorClient(address), filePath, fileContent, classPath, verbose);
}
public static void processFile(AstVisitorClient astVisitorClient, String filePath, String fileContent, String classPath, int verbose)
{
astVisitorClient.logInfo("indexing source file: " + filePath);
try
{
CombinedTypeSolver combinedTypeSolver = new CombinedTypeSolver();
Path path = Paths.get(filePath);
ASTParser parser = ASTParser.newParser(AST.JLS8);
parser.setResolveBindings(true); // solve "bindings" like the declatarion of the type used in a var decl
parser.setKind(ASTParser.K_COMPILATION_UNIT); // specify to parse the entire compilation unit
parser.setBindingsRecovery(true); // also return bindings that are not resolved completely
parser.setStatementsRecovery(true);
Hashtable<String, String> options = JavaCore.getOptions();
JavaCore.setComplianceOptions(JavaCore.VERSION_1_8, options);
parser.setCompilerOptions(options);
parser.setUnitName(path.getFileName().toString());
combinedTypeSolver.add(new ReflectionTypeSolver());
synchronized (typeSolvers)
String sources = "";
String classpath = "";
for (String classPathEntry: classPath.split("\\;"))
{
if (classPathEntry.endsWith(".jar"))
{
for (String path: classPath.split("\\;"))
if (!classpath.isEmpty())
{
if (typeSolvers.containsKey(path))
{
combinedTypeSolver.add(typeSolvers.get(path));
}
else
{
try
{
TypeSolver typeSolver = null;
if (path.endsWith(".jar"))
{
try
{
typeSolver = new JarTypeSolver(path);
}
catch (IOException e)
{
System.out.println("unable to add jar file: " + path);
}
}
else if (!path.isEmpty())
{
typeSolver = new SynchronizedJavaParserTypeSolver(new File(path));
}
if (typeSolver != null)
{
typeSolvers.put(path, typeSolver);
combinedTypeSolver.add(typeSolver);
}
}
catch (Exception e)
{
astVisitorClient.logWarning("unable to add dependency: " + path);
}
}
classpath += ";";
}
classpath += classPathEntry;
}
CompilationUnit cu = JavaParser.parse(new StringReader(fileContent));
AstVisitor astVisitor = (
verbose == 1 ?
new VerboseAstVisitor(astVisitorClient, filePath, new FileContent(fileContent), combinedTypeSolver) :
new AstVisitor(astVisitorClient, filePath, new FileContent(fileContent), combinedTypeSolver)
);
cu.accept(astVisitor, null);
}
catch (ParseProblemException e)
{
for (Problem problem: e.getProblems())
else if (!classPathEntry.isEmpty())
{
// "Parse error. Found \"package\", expected one of \";\" \"@\" \"\\u001a\" \"abstract\" \"class\" \"default\" \"enum\" \"final\" \"import\" \"interface\" \"module\" \"native\" \"open\" \"private\" \"protected\" \"public\" \"static\" \"stric...
String message = problem.toString();
if (message.startsWith("Parse error. Found "))
if (!sources.isEmpty())
{
message = "Encountered unexpected token.";
}
Range range = new Range(new Position(0, 0), new Position(0, 0));
if (problem.getLocation().isPresent())
{
range = problem.getLocation().get().toRange();
sources += ";";
}
astVisitorClient.recordError(message, true, true, range);
sources += classPathEntry;
}
}
parser.setEnvironment(new String[] {classpath} , new String[] {sources}, new String[] {"UTF-8"}, true);
parser.setSource(fileContent.toCharArray());
CompilationUnit cu = (CompilationUnit) parser.createAST(null);
ASTVisitor visitor;
if (verbose != 0)
{
visitor = new VerboseContextAwareAstVisitor(astVisitorClient, path.toFile(), fileContent, cu);
}
else
{
visitor = new ContextAwareAstVisitor(astVisitorClient, path.toFile(), fileContent, cu);
}
cu.accept(visitor);
for (IProblem problem: cu.getProblems())
{
if (problem.isError())
{
Range range = new Range(
cu.getLineNumber(problem.getSourceStart()),
cu.getColumnNumber(problem.getSourceStart() + 1),
cu.getLineNumber(problem.getSourceEnd()),
cu.getColumnNumber(problem.getSourceEnd()) + 1);
astVisitorClient.recordError(problem.getMessage(), false, true, range);
}
}
for (Object commentObject: cu.getCommentList())
{
if ((commentObject instanceof LineComment) || (commentObject instanceof BlockComment))
{
((Comment) commentObject).accept(visitor);
}
}
}
public static String getPackageName(String fileContent)
{
String packageName = "";
try
{
CompilationUnit cu = JavaParser.parse(new StringReader(fileContent));
PackageDeclaration pd = Navigator.findNodeOfGivenClass(cu, PackageDeclaration.class);
if (pd != null)
{
packageName = JavaparserDeclNameResolver.getQualifiedName(pd.getName()).toString();
}
}
catch (ParseProblemException e)
{
// do nothing
}
catch (IllegalArgumentException e)
{
// do nothing
}
ASTParser parser = ASTParser.newParser(AST.JLS8);
parser.setKind(ASTParser.K_COMPILATION_UNIT); // specify to parse the entire compilation unit
parser.setSource(fileContent.toCharArray());
CompilationUnit cu = (CompilationUnit) parser.createAST(null);
PackageDeclaration packageDeclaration = cu.getPackage();
if (packageDeclaration != null)
{
packageName = packageDeclaration.getName().getFullyQualifiedName();
}
return packageName;
}
public static void clearCaches()
{
typeSolvers.clear();
JavaParserFacade.clearInstances();
Runtime.getRuntime().gc();
}
@@ -158,36 +139,30 @@ public class JavaIndexer
static public native void logError(int address, String error);
static public native void recordSymbol(
int address, String symbolName, int symbolType,
int access, int definitionKind
);
int address, String symbolName, int symbolType,
int access, int definitionKind);
static public native void recordSymbolWithLocation(
int address, String symbolName, int symbolType,
int beginLine, int beginColumn, int endLine, int endColumn,
int access, int definitionKind
);
int address, String symbolName, int symbolType,
int beginLine, int beginColumn, int endLine, int endColumn,
int access, int definitionKind);
static public native void recordSymbolWithLocationAndScope(
int address, String symbolName, int symbolType,
int beginLine, int beginColumn, int endLine, int endColumn,
int scopeBeginLine, int scopeBeginColumn, int scopeEndLine, int scopeEndColumn,
int access, int definitionKind
int address, String symbolName, int symbolType,
int beginLine, int beginColumn, int endLine, int endColumn,
int scopeBeginLine, int scopeBeginColumn, int scopeEndLine, int scopeEndColumn,
int access, int definitionKind
);
static public native void recordReference(
int address, int referenceKind, String referencedName, String contextName, int beginLine, int beginColumn, int endLine, int endColumn
);
int address, int referenceKind, String referencedName, String contextName, int beginLine, int beginColumn, int endLine, int endColumn);
static public native void recordLocalSymbol(
int address, String symbolName, int beginLine, int beginColumn, int endLine, int endColumn
);
int address, String symbolName, int beginLine, int beginColumn, int endLine, int endColumn);
static public native void recordComment(
int address, int beginLine, int beginColumn, int endLine, int endColumn
);
int address, int beginLine, int beginColumn, int endLine, int endColumn);
static public native void recordError(
int address, String message, int fatal, int indexed, int beginLine, int beginColumn, int endLine, int endColumn
);
int address, String message, int fatal, int indexed, int beginLine, int beginColumn, int endLine, int endColumn);
}
@@ -1,6 +1,6 @@
package com.sourcetrail;
import com.github.javaparser.Range;
import com.sourcetrail.name.NameHierarchy;
public class JavaIndexerAstVisitorClient extends AstVisitorClient
{
@@ -37,76 +37,68 @@ public class JavaIndexerAstVisitorClient extends AstVisitorClient
@Override
public void recordSymbol(
String symbolName, SymbolKind symbolType,
AccessKind access, DefinitionKind definitionKind)
NameHierarchy symbolName, SymbolKind symbolKind,
AccessKind access, DefinitionKind definitionKind)
{
JavaIndexer.recordSymbol(
m_address, symbolName, symbolType.getValue(),
access.getValue(), definitionKind.getValue()
);
m_address, symbolName.serialize(), symbolKind.getValue(),
access.getValue(), definitionKind.getValue());
}
@Override
public void recordSymbolWithLocation(
String symbolName, SymbolKind symbolType, Range range,
AccessKind access, DefinitionKind definitionKind)
NameHierarchy symbolName, SymbolKind symbolKind, Range range,
AccessKind access, DefinitionKind definitionKind)
{
JavaIndexer.recordSymbolWithLocation(
m_address, symbolName, symbolType.getValue(),
range.begin.line, range.begin.column, range.end.line, range.end.column,
access.getValue(), definitionKind.getValue()
);
m_address, symbolName.serialize(), symbolKind.getValue(),
range.begin.line, range.begin.column, range.end.line, range.end.column,
access.getValue(), definitionKind.getValue());
}
@Override
public void recordSymbolWithLocationAndScope(
String symbolName, SymbolKind symbolType, Range range,
Range scopeRange, AccessKind access, DefinitionKind definitionKind)
NameHierarchy symbolName, SymbolKind symbolKind, Range range,
Range scopeRange, AccessKind access, DefinitionKind definitionKind)
{
JavaIndexer.recordSymbolWithLocationAndScope(
m_address, symbolName, symbolType.getValue(),
range.begin.line, range.begin.column, range.end.line, range.end.column,
scopeRange.begin.line, scopeRange.begin.column, scopeRange.end.line, scopeRange.end.column,
access.getValue(), definitionKind.getValue()
);
m_address, symbolName.serialize(), symbolKind.getValue(),
range.begin.line, range.begin.column, range.end.line, range.end.column,
scopeRange.begin.line, scopeRange.begin.column, scopeRange.end.line, scopeRange.end.column,
access.getValue(), definitionKind.getValue());
}
@Override
public void recordReference(
ReferenceKind referenceKind, String referencedName,
String contextName, Range range)
ReferenceKind referenceKind, NameHierarchy referencedName,
NameHierarchy contextName, Range range)
{
JavaIndexer.recordReference(
m_address, referenceKind.getValue(), referencedName, contextName,
range.begin.line, range.begin.column, range.end.line, range.end.column
);
m_address, referenceKind.getValue(), referencedName.serialize(), contextName.serialize(),
range.begin.line, range.begin.column, range.end.line, range.end.column);
}
@Override
public void recordLocalSymbol(String symbolName, Range range)
public void recordLocalSymbol(NameHierarchy symbolName, Range range)
{
JavaIndexer.recordLocalSymbol(
m_address, symbolName,
range.begin.line, range.begin.column, range.end.line, range.end.column
);
m_address, symbolName.serialize(),
range.begin.line, range.begin.column, range.end.line, range.end.column);
}
@Override
public void recordComment(Range range)
{
JavaIndexer.recordComment(
m_address,
range.begin.line, range.begin.column, range.end.line, range.end.column
);
m_address,
range.begin.line, range.begin.column, range.end.line, range.end.column);
}
@Override
public void recordError(String message, boolean fatal, boolean indexed, Range range)
{
JavaIndexer.recordError(
m_address, message, (fatal ? 1 : 0), (indexed ? 1 : 0),
range.begin.line, range.begin.column, range.end.line, range.end.column
);
m_address, message, (fatal ? 1 : 0), (indexed ? 1 : 0),
range.begin.line, range.begin.column, range.end.line, range.end.column);
}
}
@@ -1,26 +0,0 @@
package com.sourcetrail;
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(File currentFile, TypeSolver typeSolver, ContextList ignoredContexts)
{
m_currentFile = currentFile;
m_typeSolver = typeSolver;
if (ignoredContexts != null)
{
m_ignoredContexts = ignoredContexts;
}
else
{
m_ignoredContexts = new ContextList();
}
}
}
@@ -1,239 +0,0 @@
package com.sourcetrail;
import java.io.File;
import java.util.ArrayList;
import java.util.List;
import java.util.Optional;
import com.github.javaparser.symbolsolver.javaparsermodel.declarations.JavaParserAnnotationDeclaration;
import com.github.javaparser.symbolsolver.javaparsermodel.declarations.JavaParserAnonymousClassDeclaration;
import com.github.javaparser.symbolsolver.javaparsermodel.declarations.JavaParserClassDeclaration;
import com.github.javaparser.symbolsolver.javaparsermodel.declarations.JavaParserConstructorDeclaration;
import com.github.javaparser.symbolsolver.javaparsermodel.declarations.JavaParserEnumConstantDeclaration;
import com.github.javaparser.symbolsolver.javaparsermodel.declarations.JavaParserEnumDeclaration;
import com.github.javaparser.symbolsolver.javaparsermodel.declarations.JavaParserFieldDeclaration;
import com.github.javaparser.symbolsolver.javaparsermodel.declarations.JavaParserInterfaceDeclaration;
import com.github.javaparser.symbolsolver.javaparsermodel.declarations.JavaParserMethodDeclaration;
import com.github.javaparser.symbolsolver.javaparsermodel.declarations.JavaParserParameterDeclaration;
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.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.TypeParameterDeclaration;
import com.github.javaparser.symbolsolver.model.declarations.TypeParametrizable;
import com.github.javaparser.symbolsolver.model.resolution.TypeSolver;
import com.sourcetrail.name.JavaDeclName;
import com.sourcetrail.name.JavaFunctionDeclName;
import com.sourcetrail.name.JavaTypeName;
import com.sourcetrail.name.JavaVariableDeclName;
public class JavaSymbolSolverDeclNameResolver extends JavaNameResolver
{
public JavaSymbolSolverDeclNameResolver(File currentFile, TypeSolver typeSolver, ContextList ignoredContexts)
{
super(currentFile, typeSolver, ignoredContexts);
}
public static JavaDeclName getQualifiedDeclName(Declaration decl, File currentFile, TypeSolver typeSolver)
{
return getQualifiedDeclName(decl, currentFile, typeSolver, null);
}
public static JavaDeclName getQualifiedDeclName(Declaration decl, File currentFile, TypeSolver typeSolver, ContextList ignoredContexts)
{
JavaSymbolSolverDeclNameResolver resolver = new JavaSymbolSolverDeclNameResolver(currentFile, typeSolver, ignoredContexts);
return resolver.getQualifiedDeclName(decl);
}
public JavaDeclName getQualifiedDeclName(Declaration decl)
{
JavaDeclName declName = null;
if (decl instanceof JavaParserAnnotationDeclaration)
{
// TODO: implement
System.out.println("solving name of JavaParserAnnotationDeclaration not implemented");
declName = JavaDeclName.unsolved();
}
if (decl instanceof JavaParserAnonymousClassDeclaration)
{
// 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_currentFile, m_typeSolver, m_ignoredContexts);
}
else if (decl instanceof JavaParserConstructorDeclaration)
{
declName = JavaparserDeclNameResolver.getQualifiedDeclName(
((JavaParserConstructorDeclaration)decl).getWrappedNode(), m_currentFile, m_typeSolver, m_ignoredContexts);
}
else if (decl instanceof JavaParserEnumDeclaration)
{
declName = JavaparserDeclNameResolver.getQualifiedDeclName(
((JavaParserEnumDeclaration)decl).getWrappedNode(), m_currentFile, m_typeSolver, m_ignoredContexts);
}
else if (decl instanceof JavaParserEnumConstantDeclaration)
{
declName = JavaparserDeclNameResolver.getQualifiedDeclName(
((JavaParserEnumConstantDeclaration)decl).getWrappedNode(), m_currentFile, m_typeSolver, m_ignoredContexts);
}
else if (decl instanceof JavaParserFieldDeclaration)
{
declName = JavaparserDeclNameResolver.getQualifiedDeclName(
((JavaParserFieldDeclaration)decl).getWrappedNode(), m_currentFile, m_typeSolver, m_ignoredContexts);
}
else if (decl instanceof JavaParserInterfaceDeclaration)
{
declName = JavaparserDeclNameResolver.getQualifiedDeclName(
((JavaParserInterfaceDeclaration)decl).getWrappedNode(), m_currentFile, m_typeSolver, m_ignoredContexts);
}
else if (decl instanceof JavaParserMethodDeclaration)
{
declName = JavaparserDeclNameResolver.getQualifiedDeclName(
((JavaParserMethodDeclaration)decl).getWrappedNode(), m_currentFile, m_typeSolver, m_ignoredContexts);
}
else if (decl instanceof JavaParserParameterDeclaration)
{
System.out.println("solving name of JavaParserParameterDeclaration not implemented");
declName = JavaDeclName.unsolved();
}
else if (decl instanceof JavaParserSymbolDeclaration)
{
System.out.println("solving name of JavaParserSymbolDeclaration not implemented");
declName = JavaDeclName.unsolved();
}
else if (decl instanceof JavaParserTypeParameter)
{
declName = JavaparserDeclNameResolver.getQualifiedDeclName(
((JavaParserTypeParameter)decl).getWrappedNode(), m_currentFile, m_typeSolver, m_ignoredContexts);
}
else if (decl instanceof JavaParserTypeVariableDeclaration)
{
declName = JavaparserDeclNameResolver.getQualifiedDeclName(
((JavaParserTypeVariableDeclaration)decl).getWrappedNode(), m_currentFile, m_typeSolver, m_ignoredContexts);
}
else
{
String name = decl.getName();
List<String> typeParameters = new ArrayList<>();
if (decl instanceof TypeParametrizable)
{
typeParameters = getTypeParameterNames((TypeParametrizable) decl);
}
if (decl instanceof ReferenceTypeDeclaration)
{
declName = new JavaDeclName(name, typeParameters);
Optional<ReferenceTypeDeclaration> containerType = ((ReferenceTypeDeclaration) decl).containerType();
if (containerType.isPresent())
{
declName.setParent(getQualifiedDeclName(containerType.get(), m_currentFile, m_typeSolver, m_ignoredContexts));
}
else
{
declName.setParent(JavaDeclName.fromDotSeparatedString(((ReferenceTypeDeclaration) decl).getPackageName()));
}
}
else if (decl instanceof TypeParameterDeclaration)
{
declName = new JavaDeclName(name);
TypeParametrizable container = ((TypeParameterDeclaration) decl).getContainer();
if (!m_ignoredContexts.contains(container))
{
if (container instanceof ReferenceTypeDeclaration)
{
declName.setParent(getQualifiedDeclName((ReferenceTypeDeclaration) container, m_currentFile, m_typeSolver, m_ignoredContexts));
}
if (container instanceof MethodLikeDeclaration)
{
declName.setParent(getQualifiedDeclName((MethodLikeDeclaration) container, m_currentFile, m_typeSolver, m_ignoredContexts));
}
}
}
else if (decl instanceof MethodLikeDeclaration)
{
ContextList ignoredContextsForTypes = m_ignoredContexts.copy();
ignoredContextsForTypes.add((MethodLikeDeclaration) decl); // adding own decl
JavaTypeName returnTypeName = new JavaTypeName("", null);
boolean isStatic = false;
if (decl instanceof MethodDeclaration)
{
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_currentFile, m_typeSolver, ignoredContextsForTypes),
isStatic);
declName.setParent(
getQualifiedDeclName(((MethodLikeDeclaration) decl).declaringType(), m_currentFile, m_typeSolver, m_ignoredContexts));
}
else if (decl instanceof com.github.javaparser.symbolsolver.model.declarations.FieldDeclaration)
{
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_currentFile, m_typeSolver, m_ignoredContexts),
fieldDecl.isStatic());
declName.setParent(
getQualifiedDeclName(
fieldDecl.declaringType(),
m_currentFile,
m_typeSolver,
m_ignoredContexts));
}
}
if (declName == null)
{
System.out.println("Unable to resolve qualified declaration name of " + decl.getClass().toString() + ": " + decl.toString());
declName = JavaDeclName.unsolved();
}
return declName;
}
private static List<String> getTypeParameterNames(TypeParametrizable decl)
{
List<String> typeParameterNames = new ArrayList<>();
List<TypeParameterDeclaration> typeParameters = decl.getTypeParameters();
if (typeParameters != null && typeParameters.size() > 0)
{
for (int i = 0; i < typeParameters.size(); i++)
{
typeParameterNames.add(typeParameters.get(i).getName());
}
}
return typeParameterNames;
}
private static List<JavaTypeName> getParameterTypeNames(MethodLikeDeclaration decl, File currentFile, TypeSolver typeSolver, ContextList ignoredContexts)
{
List<JavaTypeName> typeTypeParameterNames = new ArrayList<>();
for (int i = 0; i < decl.getNumberOfParams(); i++)
{
typeTypeParameterNames.add(JavaSymbolSolverTypeNameResolver.getQualifiedTypeName(
decl.getParam(i).getType(), currentFile, typeSolver, ignoredContexts
));
}
return typeTypeParameterNames;
}
}
@@ -1,99 +0,0 @@
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.symbolsolver.javaparsermodel.LambdaArgumentTypePlaceholder;
import com.github.javaparser.symbolsolver.javaparsermodel.declarations.JavaParserTypeParameter;
import com.github.javaparser.symbolsolver.logic.InferenceVariableType;
import com.github.javaparser.symbolsolver.model.declarations.TypeParameterDeclaration;
import com.github.javaparser.symbolsolver.model.resolution.TypeSolver;
import com.github.javaparser.symbolsolver.model.typesystem.ArrayType;
import com.github.javaparser.symbolsolver.model.typesystem.NullType;
import com.github.javaparser.symbolsolver.model.typesystem.PrimitiveType;
import com.github.javaparser.symbolsolver.model.typesystem.ReferenceType;
import com.github.javaparser.symbolsolver.model.typesystem.Type;
import com.github.javaparser.symbolsolver.model.typesystem.TypeVariable;
import com.github.javaparser.symbolsolver.model.typesystem.VoidType;
import com.github.javaparser.symbolsolver.model.typesystem.Wildcard;
import com.sourcetrail.name.JavaDeclName;
import com.sourcetrail.name.JavaTypeName;
public class JavaSymbolSolverTypeNameResolver extends JavaNameResolver
{
public JavaSymbolSolverTypeNameResolver(File currentFile, TypeSolver typeSolver, ContextList ignoredContexts)
{
super(currentFile, typeSolver, ignoredContexts);
}
public static JavaTypeName getQualifiedTypeName(Type type, File currentFile, TypeSolver typeSolver)
{
return getQualifiedTypeName(type, currentFile, typeSolver, null);
}
public static JavaTypeName getQualifiedTypeName(Type type, File currentFile, TypeSolver typeSolver, ContextList ignoredContexts)
{
JavaSymbolSolverTypeNameResolver resolver = new JavaSymbolSolverTypeNameResolver(currentFile, typeSolver, ignoredContexts);
return resolver.getQualifiedTypeName(type);
}
public JavaTypeName getQualifiedTypeName(Type type)
{
if (type instanceof ArrayType)
{
return getQualifiedTypeName(((ArrayType)type).getComponentType());
}
else if (type instanceof LambdaArgumentTypePlaceholder)
{
}
else if (type instanceof InferenceVariableType)
{
}
else if (type instanceof NullType)
{
return JavaTypeName.fromDotSeparatedString(type.describe());
}
else if (type instanceof PrimitiveType)
{
return JavaTypeName.fromDotSeparatedString(type.describe());
}
else if (type instanceof ReferenceType)
{
ReferenceType refTypeUsage = (ReferenceType)type;
JavaDeclName declName = JavaSymbolSolverDeclNameResolver.getQualifiedDeclName(
refTypeUsage.getTypeDeclaration(),
m_currentFile,
m_typeSolver,
m_ignoredContexts);
return new JavaTypeName(declName.getName() + declName.getTypeParameterString(), new ArrayList<JavaTypeName>(), declName.getParent());
}
else if (type instanceof TypeVariable)
{
JavaDeclName declName = JavaSymbolSolverDeclNameResolver.getQualifiedDeclName(
((TypeVariable)type).asTypeParameter(),
m_currentFile,
m_typeSolver,
m_ignoredContexts);
return new JavaTypeName(declName.getName(), new ArrayList<JavaTypeName>(), declName.getParent());
}
else if (type instanceof VoidType)
{
return JavaTypeName.fromDotSeparatedString(type.describe());
}
else if (type instanceof Wildcard)
{
return new JavaTypeName("?", null);
}
System.out.println("Unable to resolve qualified name of " + type.getClass().toString() + ": " + type.toString());
return JavaTypeName.unsolved();
}
}
@@ -1,309 +0,0 @@
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;
import com.github.javaparser.ast.PackageDeclaration;
import com.github.javaparser.ast.body.AnnotationMemberDeclaration;
import com.github.javaparser.ast.body.BodyDeclaration;
import com.github.javaparser.ast.body.ClassOrInterfaceDeclaration;
import com.github.javaparser.ast.body.ConstructorDeclaration;
import com.github.javaparser.ast.body.EnumConstantDeclaration;
import com.github.javaparser.ast.body.FieldDeclaration;
import com.github.javaparser.ast.body.InitializerDeclaration;
import com.github.javaparser.ast.body.MethodDeclaration;
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;
import com.sourcetrail.name.JavaDeclName;
import com.sourcetrail.name.JavaFunctionDeclName;
import com.sourcetrail.name.JavaTypeName;
import com.sourcetrail.name.JavaVariableDeclName;
public class JavaparserDeclNameResolver extends JavaNameResolver
{
public JavaparserDeclNameResolver(File currentFile, TypeSolver typeSolver, ContextList ignoredContexts)
{
super(currentFile, typeSolver, ignoredContexts);
}
public static JavaDeclName getQualifiedDeclName(VariableDeclarator decl, File currentFile, TypeSolver typeSolver)
{
return getQualifiedDeclName(decl, currentFile, typeSolver, null);
}
public static JavaDeclName getQualifiedDeclName(VariableDeclarator decl, File currentFile, TypeSolver typeSolver, ContextList ignoredContexts)
{
JavaparserDeclNameResolver resolver = new JavaparserDeclNameResolver(currentFile, typeSolver, ignoredContexts);
return resolver.getQualifiedDeclName(decl);
}
public JavaDeclName getQualifiedDeclName(VariableDeclarator decl)
{
JavaDeclName declName = JavaDeclName.unsolved();
if (decl != null)
{
declName = getDeclName(decl);
if (!declName.getIsUnsolved())
{
declName.setParent(getQualifiedContextName(decl));
}
}
return declName;
}
public JavaDeclName getDeclName(VariableDeclarator decl)
{
JavaTypeName typeName = JavaparserTypeNameResolver.getQualifiedTypeName(decl.getType(), m_currentFile, m_typeSolver, m_ignoredContexts.copy());
boolean isStatic = false;
Optional<FieldDeclaration> fieldDeclaration = decl.getAncestorOfType(FieldDeclaration.class);
if (fieldDeclaration.isPresent())
{
isStatic = fieldDeclaration.get().isStatic();
}
return new JavaVariableDeclName(decl.getNameAsString(), typeName, isStatic);
}
public static JavaDeclName getQualifiedDeclName(BodyDeclaration decl, File currentFile, TypeSolver typeSolver)
{
return getQualifiedDeclName(decl, currentFile, typeSolver, null);
}
public static JavaDeclName getQualifiedDeclName(BodyDeclaration decl, File currentFile, TypeSolver typeSolver, ContextList ignoredContexts)
{
JavaparserDeclNameResolver resolver = new JavaparserDeclNameResolver(currentFile, typeSolver, ignoredContexts);
return resolver.getQualifiedDeclName(decl);
}
public JavaDeclName getQualifiedDeclName(BodyDeclaration<?> decl)
{
JavaDeclName declName = JavaDeclName.unsolved();
if (decl != null)
{
declName = getDeclName(decl);
if (!declName.getIsUnsolved())
{
declName.setParent(getQualifiedContextName(decl));
}
}
return declName;
}
public JavaDeclName getDeclName(BodyDeclaration decl)
{
JavaDeclName declName = JavaDeclName.unsolved();
if (decl != null)
{
if (decl instanceof AnnotationMemberDeclaration)
{
declName = new JavaDeclName("AnnotationMemberDeclaration");
}
else if (decl instanceof ConstructorDeclaration)
{
CallableConstructorDecl callableDecl = new CallableConstructorDecl((ConstructorDeclaration)decl);
declName = getDeclNameOfCallable(callableDecl);
}
else if (decl instanceof EnumConstantDeclaration)
{
declName = new JavaDeclName(((EnumConstantDeclaration)decl).getNameAsString());
}
else if (decl instanceof FieldDeclaration)
{
throw new UnsupportedOperationException();
}
else if (decl instanceof InitializerDeclaration)
{
declName = new JavaDeclName("InitializerDeclaration");
}
else if (decl instanceof MethodDeclaration)
{
CallableMethodDecl callableDecl = new CallableMethodDecl((MethodDeclaration)decl);
declName = getDeclNameOfCallable(callableDecl);
}
else if (decl instanceof TypeDeclaration)
{
declName = new JavaDeclName(((TypeDeclaration)decl).getNameAsString(), getTypeParameterNames((TypeDeclaration)decl));
}
}
return declName;
}
public static JavaDeclName getQualifiedDeclName(TypeParameter decl, File currentFile, TypeSolver typeSolver)
{
return getQualifiedDeclName(decl, currentFile, typeSolver, null);
}
public static JavaDeclName getQualifiedDeclName(TypeParameter decl, File currentFile, TypeSolver typeSolver, ContextList ignoredContexts)
{
JavaparserDeclNameResolver resolver = new JavaparserDeclNameResolver(currentFile, typeSolver, ignoredContexts);
return resolver.getQualifiedDeclName(decl);
}
public JavaDeclName getQualifiedDeclName(TypeParameter decl)
{
JavaDeclName declName = JavaDeclName.unsolved();
if (decl != null)
{
declName = getDeclName(decl);
if (!declName.getIsUnsolved())
{
declName.setParent(getQualifiedContextName(decl));
}
}
return declName;
}
public JavaDeclName getDeclName(TypeParameter decl)
{
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<String> getTypeParameterNames(TypeDeclaration decl)
{
NodeList<TypeParameter> typeParameters = null;
if (decl instanceof ClassOrInterfaceDeclaration)
{
typeParameters = (NodeList<TypeParameter>) ((ClassOrInterfaceDeclaration)decl).getTypeParameters();
}
return getTypeParameterNames(typeParameters);
}
private static List<String> getTypeParameterNames(NodeList<TypeParameter> typeParameters)
{
List<String> typeParameterNames = new ArrayList<>();
if (typeParameters != null && typeParameters.size() > 0)
{
for (int i = 0; i < typeParameters.size(); i++)
{
typeParameterNames.add(typeParameters.get(i).getNameAsString());
}
}
return typeParameterNames;
}
public static JavaDeclName getQualifiedName(Name name)
{
JavaDeclName declName = new JavaDeclName(name.getId());
if (name.getQualifier().isPresent())
{
declName.setParent(getQualifiedName(name.getQualifier().get()));
}
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<PackageDeclaration> 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 <T extends CallableDecl> JavaDeclName getDeclNameOfCallable(T decl)
{
ContextList ignoredContextsForTypes = m_ignoredContexts.copy();
ignoredContextsForTypes.add(decl.getWrappedNode()); // adding own decl
List<JavaTypeName> parameterNames = new ArrayList<>();
for (Parameter parameter: decl.getParameters())
{
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_currentFile, m_typeSolver, ignoredContextsForTypes);
}
return new JavaFunctionDeclName(
decl.getName(),
getTypeParameterNames(decl.getTypeParameters()),
returnType,
parameterNames,
decl.isStatic()
);
}
}
@@ -1,101 +0,0 @@
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;
import com.sourcetrail.name.JavaTypeName;
public class JavaparserTypeNameResolver extends JavaNameResolver
{
public JavaparserTypeNameResolver(File currentFile, TypeSolver typeSolver, ContextList ignoredContexts)
{
super(currentFile, typeSolver, ignoredContexts);
}
public static JavaTypeName getQualifiedTypeName(Type type, File currentFile, TypeSolver typeSolver)
{
return getQualifiedTypeName(type, currentFile, typeSolver, null);
}
public static JavaTypeName getQualifiedTypeName(Type type, File currentFile, TypeSolver typeSolver, ContextList ignoredContexts)
{
JavaparserTypeNameResolver resolver = new JavaparserTypeNameResolver(currentFile, typeSolver, ignoredContexts);
return resolver.getQualifiedTypeName(type);
}
public JavaTypeName getQualifiedTypeName(Type type)
{
String fallbackTypeName = type.toString();
if (type instanceof ClassOrInterfaceType)
{
try
{
return JavaSymbolSolverTypeNameResolver.getQualifiedTypeName(
JavaParserFacade.get(m_typeSolver).convert(type, type),
m_currentFile,
m_typeSolver,
m_ignoredContexts
);
}
catch (Exception e)
{
// log...
}
}
else if (type instanceof ArrayType)
{
ArrayType arrayType = (ArrayType)type;
// TODO: regard array info!
return getQualifiedTypeName(arrayType.getComponentType());
}
else if (type instanceof TypeParameter)
{
return JavaSymbolSolverTypeNameResolver.getQualifiedTypeName(
JavaParserFacade.get(m_typeSolver).convert(type, type),
m_currentFile,
m_typeSolver,
m_ignoredContexts
);
}
else if (type instanceof IntersectionType)
{
// System.out.println(" IntersectionType: " + fallbackTypeName);
return JavaTypeName.fromDotSeparatedString(type.toString());
}
else if (type instanceof PrimitiveType)
{
return JavaTypeName.fromDotSeparatedString(type.toString());
}
else if (type instanceof UnionType)
{
// System.out.println(" UnionType: " + fallbackTypeName);
return JavaTypeName.fromDotSeparatedString(type.toString());
}
else if (type instanceof UnknownType)
{
// System.out.println(" UnknownType: " + fallbackTypeName);
return JavaTypeName.fromDotSeparatedString(type.toString());
}
else if (type instanceof VoidType)
{
return JavaTypeName.fromDotSeparatedString(type.toString());
}
else if (type instanceof WildcardType)
{
// System.out.println(" WildcardType: " + fallbackTypeName);
return JavaTypeName.fromDotSeparatedString(type.toString());
}
System.out.println("Unable to resolve qualified name of " + type.getClass().toString() + ": " + fallbackTypeName);
return JavaTypeName.unsolved();
}
}
@@ -0,0 +1,17 @@
package com.sourcetrail;
public class Position
{
public int line = 0;
public int column = 0;
public Position()
{
}
public Position(int line, int column)
{
this.line = line;
this.column = column;
}
}
@@ -0,0 +1,27 @@
package com.sourcetrail;
public class Range
{
public Position begin = new Position();
public Position end = new Position();
public Range()
{
}
public Range(int beginLine, int beginColumn, int endLine, int endColumn)
{
this.begin.line = beginLine;
this.begin.column = beginColumn;
this.end.line = endLine;
this.end.column = endColumn;
}
public Range(Position begin, Position end)
{
this.begin.line = begin.line;
this.begin.column = begin.column;
this.end.line = end.line;
this.end.column = end.column;
}
}
@@ -0,0 +1,27 @@
package com.sourcetrail;
import org.eclipse.jdt.core.dom.ASTNode;
import org.eclipse.jdt.core.dom.BodyDeclaration;
import org.eclipse.jdt.core.dom.CompilationUnit;
import org.eclipse.jdt.core.dom.Javadoc;
public class Utility
{
public static Range getRange(ASTNode node, CompilationUnit compilationUnit)
{
int startPosition = node.getStartPosition() + 1;
int endPosition = node.getStartPosition() + node.getLength() - 1;
if (node instanceof BodyDeclaration && ((BodyDeclaration) node).getJavadoc() != null)
{
Javadoc javadoc = ((BodyDeclaration) node).getJavadoc();
startPosition = javadoc.getStartPosition() + javadoc.getLength() + 2;
}
return new Range(
compilationUnit.getLineNumber(startPosition),
compilationUnit.getColumnNumber(startPosition),
compilationUnit.getLineNumber(endPosition),
compilationUnit.getColumnNumber(endPosition) + 1);
}
}
@@ -1,226 +0,0 @@
package com.sourcetrail;
import com.github.javaparser.ast.*;
import com.github.javaparser.ast.body.*;
import com.github.javaparser.ast.comments.*;
import com.github.javaparser.ast.expr.*;
import com.github.javaparser.ast.nodeTypes.NodeWithName;
import com.github.javaparser.ast.stmt.*;
import com.github.javaparser.ast.type.*;
import com.github.javaparser.symbolsolver.model.resolution.TypeSolver;
public class VerboseAstVisitor extends AstVisitor{
public VerboseAstVisitor(AstVisitorClient client, String filePath, FileContent fileContent, TypeSolver typeSolver) {
super(client, filePath, fileContent, typeSolver);
}
int indent = 0;
String indentSymbol = "| ";
private String obfuscate(final String s)
{
if (s.isEmpty())
{
return "";
}
else if (s.length() <= 2)
{
return s;
}
return s.substring(0, 1) + ".." + s.substring(s.length() - 1, s.length());
}
private void dump(Node n)
{
String line = "";
for (int i = 0; i < this.indent; i++)
{
line += this.indentSymbol;
}
line += n.getClass().getName();
if (n instanceof NodeWithName<?>)
{
line += " [" + obfuscate(((NodeWithName<?>)n).getNameAsString()) + "]";
}
if (n.getBegin().isPresent())
{
line += " line: " + n.getBegin().get().line;
}
m_client.logInfo(line);
}
//- Compilation Unit ----------------------------------
public Boolean visit(CompilationUnit n, Void v) { dump(n); indent++; Boolean result = super.visit(n, v); indent--; return result; }
public Boolean visit(PackageDeclaration n, Void v) { dump(n); indent++; Boolean result = super.visit(n, v); indent--; return result; }
public Boolean visit(ImportDeclaration n, Void v) { dump(n); indent++; Boolean result = super.visit(n, v); indent--; return result; }
public Boolean visit(TypeParameter n, Void v) { dump(n); indent++; Boolean result = super.visit(n, v); indent--; return result; }
public Boolean visit(LineComment n, Void v) { dump(n); indent++; Boolean result = super.visit(n, v); indent--; return result; }
public Boolean visit(BlockComment n, Void v) { dump(n); indent++; Boolean result = super.visit(n, v); indent--; return result; }
//- Body ----------------------------------------------
public Boolean visit(ClassOrInterfaceDeclaration n, Void v) { dump(n); indent++; Boolean result = super.visit(n, v); indent--; return result; }
public Boolean visit(EnumDeclaration n, Void v) { dump(n); indent++; Boolean result = super.visit(n, v); indent--; return result; }
public Boolean visit(EnumConstantDeclaration n, Void v) { dump(n); indent++; Boolean result = super.visit(n, v); indent--; return result; }
public Boolean visit(AnnotationDeclaration n, Void v) { dump(n); indent++; Boolean result = super.visit(n, v); indent--; return result; }
public Boolean visit(AnnotationMemberDeclaration n, Void v) { dump(n); indent++; Boolean result = super.visit(n, v); indent--; return result; }
public Boolean visit(FieldDeclaration n, Void v) { dump(n); indent++; Boolean result = super.visit(n, v); indent--; return result; }
public Boolean visit(VariableDeclarator n, Void v) { dump(n); indent++; Boolean result = super.visit(n, v); indent--; return result; }
public Boolean visit(ConstructorDeclaration n, Void v) { dump(n); indent++; Boolean result = super.visit(n, v); indent--; return result; }
public Boolean visit(MethodDeclaration n, Void v) { dump(n); indent++; Boolean result = super.visit(n, v); indent--; return result; }
public Boolean visit(Parameter n, Void v) { dump(n); indent++; Boolean result = super.visit(n, v); indent--; return result; }
public Boolean visit(InitializerDeclaration n, Void v) { dump(n); indent++; Boolean result = super.visit(n, v); indent--; return result; }
public Boolean visit(JavadocComment n, Void v) { dump(n); indent++; Boolean result = super.visit(n, v); indent--; return result; }
//- Type ----------------------------------------------
public Boolean visit(ClassOrInterfaceType n, Void v) { dump(n); indent++; Boolean result = super.visit(n, v); indent--; return result; }
public Boolean visit(PrimitiveType n, Void v) { dump(n); indent++; Boolean result = super.visit(n, v); indent--; return result; }
public Boolean visit(ArrayType n, Void v) { dump(n); indent++; Boolean result = super.visit(n, v); indent--; return result; }
public Boolean visit(ArrayCreationLevel n, Void v) { dump(n); indent++; Boolean result = super.visit(n, v); indent--; return result; }
public Boolean visit(IntersectionType n, Void v) { dump(n); indent++; Boolean result = super.visit(n, v); indent--; return result; }
public Boolean visit(UnionType n, Void v) { dump(n); indent++; Boolean result = super.visit(n, v); indent--; return result; }
public Boolean visit(VoidType n, Void v) { dump(n); indent++; Boolean result = super.visit(n, v); indent--; return result; }
public Boolean visit(WildcardType n, Void v) { dump(n); indent++; Boolean result = super.visit(n, v); indent--; return result; }
public Boolean visit(UnknownType n, Void v) { dump(n); indent++; Boolean result = super.visit(n, v); indent--; return result; }
//- Expression ----------------------------------------
public Boolean visit(ArrayAccessExpr n, Void v) { dump(n); indent++; Boolean result = super.visit(n, v); indent--; return result; }
public Boolean visit(ArrayCreationExpr n, Void v) { dump(n); indent++; Boolean result = super.visit(n, v); indent--; return result; }
public Boolean visit(ArrayInitializerExpr n, Void v) { dump(n); indent++; Boolean result = super.visit(n, v); indent--; return result; }
public Boolean visit(AssignExpr n, Void v) { dump(n); indent++; Boolean result = super.visit(n, v); indent--; return result; }
public Boolean visit(BinaryExpr n, Void v) { dump(n); indent++; Boolean result = super.visit(n, v); indent--; return result; }
public Boolean visit(CastExpr n, Void v) { dump(n); indent++; Boolean result = super.visit(n, v); indent--; return result; }
public Boolean visit(ClassExpr n, Void v) { dump(n); indent++; Boolean result = super.visit(n, v); indent--; return result; }
public Boolean visit(ConditionalExpr n, Void v) { dump(n); indent++; Boolean result = super.visit(n, v); indent--; return result; }
public Boolean visit(EnclosedExpr n, Void v) { dump(n); indent++; Boolean result = super.visit(n, v); indent--; return result; }
public Boolean visit(FieldAccessExpr n, Void v) { dump(n); indent++; Boolean result = super.visit(n, v); indent--; return result; }
public Boolean visit(InstanceOfExpr n, Void v) { dump(n); indent++; Boolean result = super.visit(n, v); indent--; return result; }
public Boolean visit(StringLiteralExpr n, Void v) { dump(n); indent++; Boolean result = super.visit(n, v); indent--; return result; }
public Boolean visit(IntegerLiteralExpr n, Void v) { dump(n); indent++; Boolean result = super.visit(n, v); indent--; return result; }
public Boolean visit(LongLiteralExpr n, Void v) { dump(n); indent++; Boolean result = super.visit(n, v); indent--; return result; }
public Boolean visit(CharLiteralExpr n, Void v) { dump(n); indent++; Boolean result = super.visit(n, v); indent--; return result; }
public Boolean visit(DoubleLiteralExpr n, Void v) { dump(n); indent++; Boolean result = super.visit(n, v); indent--; return result; }
public Boolean visit(BooleanLiteralExpr n, Void v) { dump(n); indent++; Boolean result = super.visit(n, v); indent--; return result; }
public Boolean visit(NullLiteralExpr n, Void v) { dump(n); indent++; Boolean result = super.visit(n, v); indent--; return result; }
public Boolean visit(MethodCallExpr n, Void v) { dump(n); indent++; Boolean result = super.visit(n, v); indent--; return result; }
public Boolean visit(NameExpr n, Void v) { dump(n); indent++; Boolean result = super.visit(n, v); indent--; return result; }
public Boolean visit(ObjectCreationExpr n, Void v) { dump(n); indent++; Boolean result = super.visit(n, v); indent--; return result; }
public Boolean visit(ThisExpr n, Void v) { dump(n); indent++; Boolean result = super.visit(n, v); indent--; return result; }
public Boolean visit(SuperExpr n, Void v) { dump(n); indent++; Boolean result = super.visit(n, v); indent--; return result; }
public Boolean visit(UnaryExpr n, Void v) { dump(n); indent++; Boolean result = super.visit(n, v); indent--; return result; }
public Boolean visit(VariableDeclarationExpr n, Void v) { dump(n); indent++; Boolean result = super.visit(n, v); indent--; return result; }
public Boolean visit(MarkerAnnotationExpr n, Void v) { dump(n); indent++; Boolean result = super.visit(n, v); indent--; return result; }
public Boolean visit(SingleMemberAnnotationExpr n, Void v) { dump(n); indent++; Boolean result = super.visit(n, v); indent--; return result; }
public Boolean visit(NormalAnnotationExpr n, Void v) { dump(n); indent++; Boolean result = super.visit(n, v); indent--; return result; }
public Boolean visit(MemberValuePair n, Void v) { dump(n); indent++; Boolean result = super.visit(n, v); indent--; return result; }
//- Statements ----------------------------------------
public Boolean visit(ExplicitConstructorInvocationStmt n, Void v) { dump(n); indent++; Boolean result = super.visit(n, v); indent--; return result; }
public Boolean visit(AssertStmt n, Void v) { dump(n); indent++; Boolean result = super.visit(n, v); indent--; return result; }
public Boolean visit(BlockStmt n, Void v) { dump(n); indent++; Boolean result = super.visit(n, v); indent--; return result; }
public Boolean visit(LabeledStmt n, Void v) { dump(n); indent++; Boolean result = super.visit(n, v); indent--; return result; }
public Boolean visit(EmptyStmt n, Void v) { dump(n); indent++; Boolean result = super.visit(n, v); indent--; return result; }
public Boolean visit(ExpressionStmt n, Void v) { dump(n); indent++; Boolean result = super.visit(n, v); indent--; return result; }
public Boolean visit(SwitchStmt n, Void v) { dump(n); indent++; Boolean result = super.visit(n, v); indent--; return result; }
public Boolean visit(SwitchEntryStmt n, Void v) { dump(n); indent++; Boolean result = super.visit(n, v); indent--; return result; }
public Boolean visit(BreakStmt n, Void v) { dump(n); indent++; Boolean result = super.visit(n, v); indent--; return result; }
public Boolean visit(ReturnStmt n, Void v) { dump(n); indent++; Boolean result = super.visit(n, v); indent--; return result; }
public Boolean visit(IfStmt n, Void v) { dump(n); indent++; Boolean result = super.visit(n, v); indent--; return result; }
public Boolean visit(WhileStmt n, Void v) { dump(n); indent++; Boolean result = super.visit(n, v); indent--; return result; }
public Boolean visit(ContinueStmt n, Void v) { dump(n); indent++; Boolean result = super.visit(n, v); indent--; return result; }
public Boolean visit(DoStmt n, Void v) { dump(n); indent++; Boolean result = super.visit(n, v); indent--; return result; }
public Boolean visit(ForeachStmt n, Void v) { dump(n); indent++; Boolean result = super.visit(n, v); indent--; return result; }
public Boolean visit(ForStmt n, Void v) { dump(n); indent++; Boolean result = super.visit(n, v); indent--; return result; }
public Boolean visit(ThrowStmt n, Void v) { dump(n); indent++; Boolean result = super.visit(n, v); indent--; return result; }
public Boolean visit(SynchronizedStmt n, Void v) { dump(n); indent++; Boolean result = super.visit(n, v); indent--; return result; }
public Boolean visit(TryStmt n, Void v) { dump(n); indent++; Boolean result = super.visit(n, v); indent--; return result; }
public Boolean visit(CatchClause n, Void v) { dump(n); indent++; Boolean result = super.visit(n, v); indent--; return result; }
public Boolean visit(LambdaExpr n, Void v) { dump(n); indent++; Boolean result = super.visit(n, v); indent--; return result; }
public Boolean visit(MethodReferenceExpr n, Void v) { dump(n); indent++; Boolean result = super.visit(n, v); indent--; return result; }
public Boolean visit(TypeExpr n, Void v) { dump(n); indent++; Boolean result = super.visit(n, v); indent--; return result; }
public Boolean visit(UnparsableStmt n, Void v) { dump(n); indent++; Boolean result = super.visit(n, v); indent--; return result; }
}
@@ -0,0 +1,28 @@
package com.sourcetrail;
import java.io.File;
import org.eclipse.jdt.core.dom.ASTNode;
import org.eclipse.jdt.core.dom.CompilationUnit;
public class VerboseContextAwareAstVisitor extends ContextAwareAstVisitor
{
private String indentation = "";
public VerboseContextAwareAstVisitor(AstVisitorClient client, File filePath, String fileContent, CompilationUnit compilationUnit)
{
super(client, filePath, fileContent, compilationUnit);
}
public void preVisit(ASTNode node)
{
Range range = getRange(node);
m_client.logInfo(indentation + node.getClass().toString() + "[" + range.begin.line + ":" + range.begin.column + "|" + range.end.line + ":" + range.end.column + "]");
indentation += "| ";
}
public void postVisit(ASTNode node)
{
indentation = indentation.substring(0, indentation.length() - 2);
}
}
@@ -1,14 +1,19 @@
package com.sourcetrail.name;
import java.io.File;
import java.util.List;
public class JavaDeclName
import com.sourcetrail.Position;
public class JavaDeclName implements JavaSymbolName
{
private JavaDeclName m_parent = null;
private String m_name = "";
private List<String> m_typeParameterNames = null;
private boolean m_isUnsolved = false;
private boolean m_isAnonymous = false;
private boolean m_isLocal = false;
private boolean m_isGlobal = false;
public static JavaDeclName unsolved()
{
@@ -17,13 +22,33 @@ public class JavaDeclName
return declName;
}
public static JavaDeclName anonymousClass(String fileName, int line, int col)
public static JavaDeclName anonymousClass(File filePath, int line, int col)
{
JavaDeclName declName = new JavaDeclName("anonymous class (" + fileName + "<" + line + ":" + col + ">)");
JavaDeclName declName = new JavaDeclName("anonymous class (" + filePath.getName() + "<" + line + ":" + col + ">)");
declName.m_isAnonymous = true;
return declName;
}
public static JavaDeclName localSymbol(JavaDeclName methodContextName, int id)
{
JavaDeclName declName = new JavaDeclName(methodContextName + "<" + id + ">");
declName.m_isLocal = true;
return declName;
}
public static JavaDeclName globalSymbol(File fileContext, int id)
{
JavaDeclName declName = new JavaDeclName(fileContext.getName() + "<" + id + ">");
declName.m_isGlobal = true;
return declName;
}
public static JavaDeclName scope(File fileContext, Position begin)
{
JavaDeclName declName = new JavaDeclName(fileContext.getName() + "<" + begin.line + ":" + begin.column + ">");
return declName;
}
public static JavaDeclName fromDotSeparatedString(String s)
{
JavaDeclName declName = null;
@@ -78,6 +103,16 @@ public class JavaDeclName
return m_isAnonymous;
}
public boolean getIsLocal()
{
return m_isLocal;
}
public boolean getIsGlobal()
{
return m_isGlobal;
}
public NameHierarchy toNameHierarchy()
{
NameHierarchy nameHierarchy;
@@ -129,4 +164,8 @@ public class JavaDeclName
}
return string;
}
public List<String> getTypeParameterNames() {
return m_typeParameterNames;
}
}
@@ -0,0 +1,29 @@
package com.sourcetrail.name;
import java.io.File;
public class JavaFileName implements JavaSymbolName
{
private File m_filePath = null;
public JavaFileName(File filePath)
{
m_filePath = filePath;
}
@Override
public NameHierarchy toNameHierarchy()
{
NameHierarchy nameHierarchy;
if (m_filePath != null)
{
nameHierarchy = new NameHierarchy(m_filePath.toString().replaceAll("\\\\", "/"));
}
else
{
nameHierarchy = new NameHierarchy("unsolved-file");
}
nameHierarchy.setSeparator('/');
return nameHierarchy;
}
}
@@ -7,24 +7,24 @@ import java.util.Optional;
public class JavaFunctionDeclName extends JavaDeclName
{
private JavaTypeName m_returnTypeName = null;
private List<JavaTypeName> m_parameterNames = new ArrayList<>();
private List<JavaTypeName> m_parameterTypeNames = new ArrayList<>();
private boolean m_isStatic = false;
public JavaFunctionDeclName(String name, JavaTypeName returnTypeName, List<JavaTypeName> parameterNames, boolean isStatic)
public JavaFunctionDeclName(String name, JavaTypeName returnTypeName, List<JavaTypeName> parameterTypeNames, boolean isStatic)
{
super(name);
m_returnTypeName = returnTypeName;
if (m_parameterNames != null) m_parameterNames = parameterNames;
if (parameterTypeNames != null) m_parameterTypeNames = parameterTypeNames;
m_isStatic = isStatic;
}
public JavaFunctionDeclName(String name, List<String> typeParameterNames, JavaTypeName returnTypeName, List<JavaTypeName> parameterNames, boolean isStatic)
public JavaFunctionDeclName(String name, List<String> typeParameterNames, JavaTypeName returnTypeName, List<JavaTypeName> parameterTypeNames, boolean isStatic)
{
super(name, typeParameterNames);
m_returnTypeName = returnTypeName;
m_parameterNames = parameterNames;
if (parameterTypeNames != null) m_parameterTypeNames = parameterTypeNames;
m_isStatic = isStatic;
}
@@ -60,15 +60,15 @@ public class JavaFunctionDeclName extends JavaDeclName
private String getParameterString()
{
String string = "(";
if (m_parameterNames != null)
if (m_parameterTypeNames != null)
{
for (int i = 0; i < m_parameterNames.size(); i++)
for (int i = 0; i < m_parameterTypeNames.size(); i++)
{
if (i != 0)
{
string += ", ";
}
string += m_parameterNames.get(i).toString();
string += m_parameterTypeNames.get(i).toString();
}
}
string += ")";
@@ -0,0 +1,6 @@
package com.sourcetrail.name;
public interface JavaSymbolName
{
public NameHierarchy toNameHierarchy();
}
@@ -2,15 +2,19 @@ package com.sourcetrail.name;
import java.util.List;
public class JavaTypeName
public class JavaTypeName implements JavaSymbolName
{
private JavaDeclName m_parent = null;
private String m_name = "";
private List<JavaTypeName> m_typeArgumentNames = null;
private List<String> m_typeParameterNames = null;
private List<JavaTypeName> m_typeArguments = null;
private boolean m_isUnsolved = false;
public static JavaTypeName unsolved()
{
return new JavaTypeName("unsolved-type", null);
JavaTypeName typeName = new JavaTypeName("unsolved-type", null);
typeName.m_isUnsolved = true;
return typeName;
}
public static JavaTypeName fromDotSeparatedString(String s)
@@ -36,11 +40,12 @@ public class JavaTypeName
m_name = name;
}
public JavaTypeName(String name, List<JavaTypeName> typeArgumentNames, JavaDeclName parent)
public JavaTypeName(String name, List<String> typeParameterNames, List<JavaTypeName> typeArguments, JavaDeclName parent)
{
m_parent = parent;
m_name = name;
m_typeArgumentNames = typeArgumentNames;
m_typeParameterNames = typeParameterNames;
m_typeArguments = typeArguments;
}
public JavaDeclName getParent()
@@ -53,6 +58,13 @@ public class JavaTypeName
return m_name;
}
public JavaDeclName toDeclName()
{
JavaDeclName declName = new JavaDeclName(m_name, m_typeParameterNames);
declName.setParent(m_parent);
return declName;
}
public NameHierarchy toNameHierarchy()
{
NameHierarchy nameHierarchy;
@@ -89,16 +101,16 @@ public class JavaTypeName
private String getTypeArgumentString()
{
String string = "";
if (m_typeArgumentNames != null && !m_typeArgumentNames.isEmpty())
if (m_typeArguments != null && !m_typeArguments.isEmpty())
{
string += "<";
for (int i = 0; i < m_typeArgumentNames.size(); i++)
for (int i = 0; i < m_typeArguments.size(); i++)
{
if (i != 0)
{
string += ", ";
}
string += m_typeArgumentNames.get(i).toString();
string += m_typeArguments.get(i).toString();
}
string += ">";
}
@@ -7,6 +7,7 @@ import java.util.Optional;
public class NameHierarchy
{
private List<NameElement> m_elements = new ArrayList<>();
private char m_separatpr = '.';
public NameHierarchy()
{
@@ -27,6 +28,11 @@ public class NameHierarchy
m_elements.addAll(names);
}
public void setSeparator(char separator)
{
m_separatpr = separator;
}
public void push(NameElement element)
{
m_elements.add(element);
@@ -51,7 +57,7 @@ public class NameHierarchy
public String serialize()
{
String serialized = ".\tm";
String serialized = m_separatpr + "\tm";
for (int i = 0; i < m_elements.size(); i++)
{
@@ -0,0 +1,341 @@
package com.sourcetrail.name.resolver;
import java.io.File;
import java.util.ArrayList;
import java.util.List;
import java.util.Optional;
import org.eclipse.jdt.core.dom.ASTNode;
import org.eclipse.jdt.core.dom.AnonymousClassDeclaration;
import org.eclipse.jdt.core.dom.CompilationUnit;
import org.eclipse.jdt.core.dom.IBinding;
import org.eclipse.jdt.core.dom.IMethodBinding;
import org.eclipse.jdt.core.dom.IPackageBinding;
import org.eclipse.jdt.core.dom.ITypeBinding;
import org.eclipse.jdt.core.dom.IVariableBinding;
import org.eclipse.jdt.core.dom.Modifier;
import com.sourcetrail.ContextList;
import com.sourcetrail.name.JavaDeclName;
import com.sourcetrail.name.JavaFunctionDeclName;
import com.sourcetrail.name.JavaTypeName;
import com.sourcetrail.name.JavaVariableDeclName;
public class BindingNameResolver extends NameResolver
{
public static IBinding getParentBinding(IBinding binding)
{
if (binding instanceof ITypeBinding)
{
return getParentBinding((ITypeBinding) binding);
}
else if (binding instanceof IMethodBinding)
{
return ((IMethodBinding) binding).getDeclaringClass();
}
else if (binding instanceof IVariableBinding)
{
return ((IVariableBinding) binding).getDeclaringClass();
}
return null;
}
public static IBinding getParentBinding(ITypeBinding binding)
{
if (binding.isLocal() || binding.isAnonymous())
{
if (binding.getDeclaringMember() instanceof IVariableBinding)
{
IVariableBinding variableBinding = (IVariableBinding) binding.getDeclaringMember();
if (variableBinding.getDeclaringClass() != null)
{
return variableBinding.getDeclaringClass();
}
else
{
return variableBinding.getDeclaringMethod();
}
}
else
{
return binding.getDeclaringMethod();
}
}
else if (binding.isMember())
{
return binding.getDeclaringClass();
}
else if (binding.isTypeVariable())
{
if (binding.getDeclaringClass() != null)
{
return binding.getDeclaringClass();
}
else
{
return binding.getDeclaringMethod();
}
}
else if (binding.isTopLevel())
{
return binding.getPackage();
}
return null; // we don't have a parent (like void doesn't have a parent)
}
public BindingNameResolver(File currentFile, CompilationUnit compilationUnit, ContextList ignoredContexts)
{
super(currentFile, compilationUnit, ignoredContexts);
}
public static Optional<JavaTypeName> getQualifiedName(ITypeBinding binding, File currentFile, CompilationUnit compilationUnit)
{
return getQualifiedName(binding, currentFile, compilationUnit, null);
}
public static Optional<JavaTypeName> getQualifiedName(ITypeBinding binding, File currentFile, CompilationUnit compilationUnit, ContextList ignoredContexts)
{
BindingNameResolver resolver = new BindingNameResolver(currentFile, compilationUnit, ignoredContexts);
return resolver.getQualifiedName(binding);
}
public Optional<JavaTypeName> getQualifiedName(ITypeBinding binding)
{
if (binding == null)
{
return Optional.empty();
}
if (binding.isArray())
{
return getQualifiedName(binding.getElementType());
}
else if (binding.isAnonymous())
{
ASTNode node = m_compilationUnit.findDeclaringNode(binding);
if (node instanceof AnonymousClassDeclaration)
{
JavaDeclName decl = DeclNameResolver.getQualifiedDeclName((AnonymousClassDeclaration) node, m_currentFile, m_compilationUnit, m_ignoredContexts);
return Optional.of(new JavaTypeName(decl.getName(), decl.getTypeParameterNames(), null, decl.getParent()));
}
else
{
return Optional.empty();
}
}
if (binding.isParameterizedType())
{
List<JavaTypeName> typeArguments = new ArrayList<>();
for (ITypeBinding typeArgumentBinding: binding.getTypeArguments())
{
Optional<JavaTypeName> typeArgument = getQualifiedName(typeArgumentBinding);
if (typeArgument.isPresent())
{
typeArguments.add(typeArgument.get());
}
}
Optional<JavaTypeName> typeName = getQualifiedName(binding.getTypeDeclaration());
if (typeName.isPresent())
{
JavaDeclName declName = typeName.get().toDeclName();
return Optional.of(new JavaTypeName(declName.getName(), declName.getTypeParameterNames(), typeArguments, declName.getParent()));
}
else
{
return Optional.empty();
}
}
String name = binding.getName();
List<String> typeParameterNames = null;
if (binding.isGenericType())
{
typeParameterNames = new ArrayList<>();
for (ITypeBinding typeParameter: binding.getTypeParameters())
{
typeParameterNames.add(typeParameter.getName());
}
}
JavaDeclName parentDeclName = getQualifiedContextName(binding);
if (parentDeclName != null && parentDeclName.getIsUnsolved())
{
return Optional.empty();
}
// type arguments will be set in caller (which is this same method)
return Optional.of(new JavaTypeName(name, typeParameterNames, null, parentDeclName));
}
public static Optional<JavaDeclName> getQualifiedName(IMethodBinding binding, File currentFile, CompilationUnit compilationUnit)
{
return getQualifiedName(binding, currentFile, compilationUnit, null);
}
public static Optional<JavaDeclName> getQualifiedName(IMethodBinding binding, File currentFile, CompilationUnit compilationUnit, ContextList ignoredContexts)
{
BindingNameResolver resolver = new BindingNameResolver(currentFile, compilationUnit, ignoredContexts);
return resolver.getQualifiedName(binding);
}
public Optional<JavaDeclName> getQualifiedName(IMethodBinding binding)
{
if (binding == null)
{
return Optional.empty();
}
String name = binding.getName();
List<String> typeParameterNames = null;
if (binding.isGenericMethod())
{
typeParameterNames = new ArrayList<>();
for (ITypeBinding typeParameter: binding.getTypeParameters())
{
typeParameterNames.add(typeParameter.getName());
}
}
ContextList ignoredContexts = m_ignoredContexts.copy();
ignoredContexts.add(binding);
JavaTypeName returnTypeName = binding.isConstructor() ? null : getQualifiedName(binding.getReturnType(), m_currentFile, m_compilationUnit, ignoredContexts).orElse(JavaTypeName.unsolved());
List<JavaTypeName> parameterTypeNames = new ArrayList<>();
for (ITypeBinding parameterType: binding.getParameterTypes())
{
parameterTypeNames.add(getQualifiedName(parameterType, m_currentFile, m_compilationUnit, ignoredContexts).orElse(JavaTypeName.unsolved()));
}
boolean isStatic = Modifier.isStatic(binding.getModifiers());
JavaFunctionDeclName declName = new JavaFunctionDeclName(name, typeParameterNames, returnTypeName, parameterTypeNames, isStatic);
JavaDeclName parentDeclName = getQualifiedContextName(binding);
if (parentDeclName != null)
{
if (!parentDeclName.getIsUnsolved())
{
declName.setParent(parentDeclName);
}
else
{
return Optional.empty();
}
}
return Optional.of(declName);
}
public static Optional<JavaDeclName> getQualifiedName(IPackageBinding binding, File currentFile, CompilationUnit compilationUnit)
{
return getQualifiedName(binding, currentFile, compilationUnit, null);
}
public static Optional<JavaDeclName> getQualifiedName(IPackageBinding binding, File currentFile, CompilationUnit compilationUnit, ContextList ignoredContexts)
{
BindingNameResolver resolver = new BindingNameResolver(currentFile, compilationUnit, ignoredContexts);
return resolver.getQualifiedName(binding);
}
public Optional<JavaDeclName> getQualifiedName(IPackageBinding binding)
{
if (!binding.isUnnamed())
{
return Optional.of(JavaDeclName.fromDotSeparatedString(binding.getName()));
}
return Optional.empty();
}
public static JavaDeclName getQualifiedName(IVariableBinding binding, File currentFile, CompilationUnit compilationUnit)
{
return getQualifiedName(binding, currentFile, compilationUnit, null);
}
public static JavaDeclName getQualifiedName(IVariableBinding binding, File currentFile, CompilationUnit compilationUnit, ContextList ignoredContexts)
{
BindingNameResolver resolver = new BindingNameResolver(currentFile, compilationUnit, ignoredContexts);
return resolver.getQualifiedName(binding);
}
public JavaDeclName getQualifiedName(IVariableBinding binding)
{
if (binding == null)
{
return JavaDeclName.unsolved();
}
if (binding.isField() || binding.isEnumConstant())
{
JavaDeclName declName;
if (binding.isEnumConstant())
{
declName = new JavaDeclName(binding.getName());
}
else
{
JavaTypeName typeName = getQualifiedName(binding.getType()).orElse(JavaTypeName.unsolved());
declName = new JavaVariableDeclName(binding.getName(), typeName, Modifier.isStatic(binding.getModifiers()));
}
JavaDeclName parentDeclName = getQualifiedContextName(binding);
if (parentDeclName != null)
{
if (!parentDeclName.getIsUnsolved())
{
declName.setParent(parentDeclName);
}
else
{
declName = JavaDeclName.unsolved();
}
}
return declName;
}
else
{
if (binding.getDeclaringMethod() != null)
{
return JavaDeclName.localSymbol(getQualifiedName(binding.getDeclaringMethod()).orElse(JavaDeclName.unsolved()), binding.getVariableId());
}
else
{
return JavaDeclName.globalSymbol(m_currentFile, binding.getVariableId());
}
}
}
private JavaDeclName getQualifiedContextName(IBinding binding)
{
IBinding parentBinding = getParentBinding(binding);
if (parentBinding == null || m_ignoredContexts.contains(parentBinding))
{
return null;
}
if (parentBinding instanceof ITypeBinding)
{
return getQualifiedName((ITypeBinding) parentBinding).map(tn ->tn.toDeclName()).orElse(JavaDeclName.unsolved());
}
else if (parentBinding instanceof IMethodBinding)
{
return getQualifiedName((IMethodBinding) parentBinding).orElse(JavaDeclName.unsolved());
}
else if (parentBinding instanceof IVariableBinding)
{
return getQualifiedName((IVariableBinding) parentBinding);
}
else if (parentBinding instanceof IPackageBinding)
{
return getQualifiedName((IPackageBinding) parentBinding).orElse(null);
}
return null;
}
}
@@ -0,0 +1,318 @@
package com.sourcetrail.name.resolver;
import java.io.File;
import java.util.ArrayList;
import java.util.List;
import java.util.Optional;
import org.eclipse.jdt.core.dom.ASTNode;
import org.eclipse.jdt.core.dom.AnnotationTypeDeclaration;
import org.eclipse.jdt.core.dom.AnnotationTypeMemberDeclaration;
import org.eclipse.jdt.core.dom.AnonymousClassDeclaration;
import org.eclipse.jdt.core.dom.BodyDeclaration;
import org.eclipse.jdt.core.dom.CompilationUnit;
import org.eclipse.jdt.core.dom.EnumConstantDeclaration;
import org.eclipse.jdt.core.dom.EnumDeclaration;
import org.eclipse.jdt.core.dom.FieldDeclaration;
import org.eclipse.jdt.core.dom.IVariableBinding;
import org.eclipse.jdt.core.dom.Initializer;
import org.eclipse.jdt.core.dom.MethodDeclaration;
import org.eclipse.jdt.core.dom.Modifier;
import org.eclipse.jdt.core.dom.Name;
import org.eclipse.jdt.core.dom.PackageDeclaration;
import org.eclipse.jdt.core.dom.QualifiedName;
import org.eclipse.jdt.core.dom.SimpleName;
import org.eclipse.jdt.core.dom.SingleVariableDeclaration;
import org.eclipse.jdt.core.dom.TypeDeclaration;
import org.eclipse.jdt.core.dom.TypeParameter;
import org.eclipse.jdt.core.dom.VariableDeclarationFragment;
import com.sourcetrail.ContextList;
import com.sourcetrail.Position;
import com.sourcetrail.Utility;
import com.sourcetrail.name.JavaDeclName;
import com.sourcetrail.name.JavaFunctionDeclName;
import com.sourcetrail.name.JavaTypeName;
import com.sourcetrail.name.JavaVariableDeclName;
public class DeclNameResolver extends NameResolver
{
public DeclNameResolver(File currentFile, CompilationUnit compilationUnit, ContextList ignoredContexts)
{
super(currentFile, compilationUnit, ignoredContexts);
}
public static JavaDeclName getQualifiedDeclName(VariableDeclarationFragment decl, File currentFile, CompilationUnit compilationUnit)
{
return getQualifiedDeclName(decl, currentFile, compilationUnit, null);
}
public static JavaDeclName getQualifiedDeclName(VariableDeclarationFragment decl, File currentFile, CompilationUnit compilationUnit, ContextList ignoredContexts)
{
DeclNameResolver resolver = new DeclNameResolver(currentFile, compilationUnit, ignoredContexts);
return resolver.getQualifiedDeclName(decl);
}
public JavaDeclName getQualifiedDeclName(VariableDeclarationFragment decl)
{
JavaDeclName declName = JavaDeclName.unsolved();
if (decl != null)
{
declName = getDeclName(decl);
if (!declName.getIsUnsolved())
{
JavaDeclName parentDeclName = getQualifiedContextName(decl);
if (parentDeclName != null)
{
if (!parentDeclName.getIsUnsolved())
{
declName.setParent(parentDeclName);
}
else
{
declName = JavaDeclName.unsolved();
}
}
}
}
return declName;
}
public JavaDeclName getDeclName(VariableDeclarationFragment decl)
{
JavaTypeName typeName = JavaTypeName.unsolved();
boolean isStatic = false;
Optional<FieldDeclaration> fieldDeclaration = getAncestorOfType(decl, FieldDeclaration.class);
if (fieldDeclaration.isPresent())
{
if (decl.resolveBinding() instanceof IVariableBinding)
{
isStatic = Modifier.isStatic(decl.resolveBinding().getModifiers());
}
else
{
isStatic = Modifier.isStatic(fieldDeclaration.get().getModifiers());
}
typeName = BindingNameResolver.getQualifiedName(
fieldDeclaration.get().getType().resolveBinding(),
m_currentFile,
m_compilationUnit,
m_ignoredContexts.copy()).orElse(JavaTypeName.unsolved());
}
return new JavaVariableDeclName(decl.getName().getIdentifier(), typeName, isStatic);
}
public static JavaDeclName getQualifiedDeclName(BodyDeclaration decl, File currentFile, CompilationUnit compilationUnit)
{
return getQualifiedDeclName(decl, currentFile, compilationUnit, null);
}
public static JavaDeclName getQualifiedDeclName(BodyDeclaration decl, File currentFile, CompilationUnit compilationUnit, ContextList ignoredContexts)
{
DeclNameResolver resolver = new DeclNameResolver(currentFile, compilationUnit, ignoredContexts);
return resolver.getQualifiedDeclName(decl);
}
public JavaDeclName getQualifiedDeclName(BodyDeclaration decl)
{
JavaDeclName declName = JavaDeclName.unsolved();
if (decl != null)
{
declName = getDeclName(decl);
if (!declName.getIsUnsolved())
{
JavaDeclName parentDeclName = getQualifiedContextName(decl);
if (parentDeclName != null)
{
if (!parentDeclName.getIsUnsolved())
{
declName.setParent(parentDeclName);
}
else
{
declName = JavaDeclName.unsolved();
}
}
}
}
return declName;
}
public JavaDeclName getDeclName(BodyDeclaration decl)
{
JavaDeclName declName = JavaDeclName.unsolved();
if (decl != null)
{
if (decl instanceof AnnotationTypeDeclaration)
{
declName = new JavaDeclName("AnnotationTypeDeclaration");
}
else if (decl instanceof EnumDeclaration)
{
declName = new JavaDeclName(((EnumDeclaration) decl).getName().getIdentifier());
}
else if (decl instanceof TypeDeclaration)
{
TypeDeclaration typeDeclaration = (TypeDeclaration) decl;
List<String> typeParameterNames = new ArrayList<>();
for (Object typeParameter: typeDeclaration.typeParameters())
{
if (typeParameter instanceof TypeParameter)
{
typeParameterNames.add(((TypeParameter) typeParameter).getName().getIdentifier());
}
}
declName = new JavaDeclName(typeDeclaration.getName().getIdentifier(), typeParameterNames);
}
else if (decl instanceof AnnotationTypeMemberDeclaration)
{
declName = new JavaDeclName("AnnotationTypeMemberDeclaration");
}
else if (decl instanceof EnumConstantDeclaration)
{
declName = new JavaDeclName(((EnumConstantDeclaration) decl).getName().getIdentifier());
}
else if (decl instanceof FieldDeclaration)
{
declName = new JavaDeclName("FieldDeclaration");
}
else if (decl instanceof Initializer)
{
declName = new JavaDeclName("Initializer");
}
else if (decl instanceof MethodDeclaration)
{
MethodDeclaration methodDeclaration = (MethodDeclaration) decl;
List<String> typeParameterNames = new ArrayList<>();
for (Object typeParameter: methodDeclaration.typeParameters())
{
if (typeParameter instanceof TypeParameter)
{
typeParameterNames.add(((TypeParameter) typeParameter).getName().getIdentifier());
}
}
ContextList ignoredContexts = m_ignoredContexts.copy();
ignoredContexts.add(((MethodDeclaration) decl).resolveBinding());
JavaTypeName returnTypeName = methodDeclaration.isConstructor() ? null : BindingNameResolver.getQualifiedName(
methodDeclaration.getReturnType2().resolveBinding(), m_currentFile, m_compilationUnit, ignoredContexts).orElse(JavaTypeName.unsolved());
List<JavaTypeName> parameterTypeNames = new ArrayList<>();
for (Object parameter: methodDeclaration.parameters())
{
if (parameter instanceof SingleVariableDeclaration)
{
parameterTypeNames.add(BindingNameResolver.getQualifiedName(
((SingleVariableDeclaration) parameter).getType().resolveBinding(), m_currentFile, m_compilationUnit, ignoredContexts).orElse(JavaTypeName.unsolved()));
}
}
declName = new JavaFunctionDeclName(
methodDeclaration.getName().getIdentifier(),
typeParameterNames,
returnTypeName,
parameterTypeNames,
Modifier.isStatic(methodDeclaration.getModifiers()));
}
}
return declName;
}
public static JavaDeclName getQualifiedDeclName(AnonymousClassDeclaration decl, File currentFile, CompilationUnit compilationUnit)
{
return getQualifiedDeclName(decl, currentFile, compilationUnit, null);
}
public static JavaDeclName getQualifiedDeclName(AnonymousClassDeclaration decl, File currentFile, CompilationUnit compilationUnit, ContextList ignoredContexts)
{
DeclNameResolver resolver = new DeclNameResolver(currentFile, compilationUnit, ignoredContexts);
return resolver.getQualifiedDeclName(decl);
}
public JavaDeclName getQualifiedDeclName(AnonymousClassDeclaration decl)
{
JavaDeclName declName = JavaDeclName.unsolved();
if (decl != null)
{
declName = getDeclName(decl);
if (!declName.getIsUnsolved())
{
JavaDeclName parentDeclName = getQualifiedContextName(decl);
if (parentDeclName != null)
{
if (!parentDeclName.getIsUnsolved())
{
declName.setParent(parentDeclName);
}
else
{
declName = JavaDeclName.unsolved();
}
}
}
}
return declName;
}
public JavaDeclName getDeclName(AnonymousClassDeclaration decl)
{
Position pos = Utility.getRange(decl, m_compilationUnit).begin;
return JavaDeclName.anonymousClass(m_currentFile, pos.line, pos.column);
}
public static JavaDeclName getQualifiedName(Name name)
{
if (name.isSimpleName())
{
return new JavaDeclName(((SimpleName) name).getIdentifier());
}
else
{
JavaDeclName declName = new JavaDeclName(((QualifiedName) name).getName().getIdentifier());
declName.setParent(getQualifiedName(((QualifiedName) name).getQualifier()));
return declName;
}
}
private JavaDeclName getQualifiedContextName(ASTNode decl)
{
ASTNode parentNode = decl.getParent();
if (parentNode == null)
{
return null;
}
if (parentNode instanceof BodyDeclaration && !(parentNode instanceof FieldDeclaration))
{
return getQualifiedDeclName((BodyDeclaration) parentNode);
}
else if (parentNode instanceof AnonymousClassDeclaration)
{
return getQualifiedDeclName((AnonymousClassDeclaration) parentNode);
}
else if (parentNode instanceof CompilationUnit)
{
PackageDeclaration packageDecl = ((CompilationUnit) parentNode).getPackage();
if (packageDecl != null)
{
return getQualifiedName(packageDecl.getName());
}
return null;
}
return getQualifiedContextName(parentNode);
}
}
@@ -0,0 +1,45 @@
package com.sourcetrail.name.resolver;
import java.io.File;
import java.util.Optional;
import org.eclipse.jdt.core.dom.ASTNode;
import org.eclipse.jdt.core.dom.CompilationUnit;
import com.sourcetrail.ContextList;
public abstract class NameResolver
{
protected File m_currentFile = null;
protected ContextList m_ignoredContexts = null;
protected CompilationUnit m_compilationUnit = null;
static protected <N> Optional<N> getAncestorOfType(ASTNode node, Class<N> classType)
{
ASTNode parent = node.getParent();
while (parent != null)
{
if (classType.isAssignableFrom(parent.getClass()))
{
return Optional.of(classType.cast(parent));
}
parent = parent.getParent();
}
return Optional.empty();
}
public NameResolver(File currentFile, CompilationUnit compilationUnit, ContextList ignoredContexts)
{
m_currentFile = currentFile;
m_compilationUnit = compilationUnit;
if (ignoredContexts != null)
{
m_ignoredContexts = ignoredContexts;
}
else
{
m_ignoredContexts = new ContextList();
}
}
}
@@ -1,53 +0,0 @@
package com.sourcetrail.typesolver;
import java.io.File;
import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.locks.ReentrantReadWriteLock;
import com.github.javaparser.symbolsolver.model.declarations.ReferenceTypeDeclaration;
import com.github.javaparser.symbolsolver.model.resolution.SymbolReference;
import com.github.javaparser.symbolsolver.resolution.typesolvers.JavaParserTypeSolver;
public class SynchronizedJavaParserTypeSolver extends JavaParserTypeSolver
{
private ReentrantReadWriteLock lock = new ReentrantReadWriteLock();
private Map<String, SymbolReference<ReferenceTypeDeclaration>> solvedTypes = new HashMap<>();
public SynchronizedJavaParserTypeSolver(File srcDir)
{
super(srcDir);
}
@Override
public SymbolReference<ReferenceTypeDeclaration> tryToSolveType(String name)
{
SymbolReference<ReferenceTypeDeclaration> solvedType = SymbolReference.unsolved(ReferenceTypeDeclaration.class);
{
lock.readLock().lock();
if (solvedTypes.containsKey(name))
{
solvedType = solvedTypes.get(name);
}
lock.readLock().unlock();
}
if (!solvedType.isSolved())
{
solvedType = super.tryToSolveType(name);
if (solvedType.isSolved())
{
lock.writeLock().lock();
if (!solvedTypes.containsKey(name))
{
solvedTypes.put(name, solvedType);
}
lock.writeLock().unlock();
}
}
return solvedType;
}
}