build: switch to Maven configuration for JavaIndexer

This commit is contained in:
malte_langkabel
2017-07-27 13:16:57 +02:00
parent 053ca3d8d1
commit 2e117c4b6d
51 changed files with 133 additions and 93 deletions
@@ -0,0 +1,44 @@
package com.sourcetrail;
import com.github.javaparser.ast.AccessSpecifier;
public enum AccessKind
{ // these values need to be the same as AccesKind in C++ code
NONE(0),
PUBLIC(1),
PROTECTED(2),
PRIVATE(3),
DEFAULT(4),
TEMPLATE_PARAMETER(5),
TYPE_PARAMETER(6);
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;
}
}
}
@@ -0,0 +1,958 @@
package com.sourcetrail;
import java.lang.String;
import java.util.List;
import java.util.Optional;
import java.util.ArrayList;
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.EnumDeclaration;
import com.github.javaparser.ast.body.FieldDeclaration;
import com.github.javaparser.ast.body.MethodDeclaration;
import com.github.javaparser.ast.body.Parameter;
import com.github.javaparser.ast.body.VariableDeclarator;
import com.github.javaparser.ast.comments.BlockComment;
import com.github.javaparser.ast.comments.LineComment;
import com.github.javaparser.ast.expr.ArrayInitializerExpr;
import com.github.javaparser.ast.expr.FieldAccessExpr;
import com.github.javaparser.ast.expr.MethodCallExpr;
import com.github.javaparser.ast.expr.Name;
import com.github.javaparser.ast.expr.NameExpr;
import com.github.javaparser.ast.expr.ObjectCreationExpr;
import com.github.javaparser.ast.expr.SimpleName;
import com.github.javaparser.ast.expr.VariableDeclarationExpr;
import com.github.javaparser.ast.stmt.BlockStmt;
import com.github.javaparser.ast.stmt.SwitchStmt;
import com.github.javaparser.ast.type.ClassOrInterfaceType;
import com.github.javaparser.ast.type.PrimitiveType;
import com.github.javaparser.ast.type.Type;
import com.github.javaparser.ast.type.TypeParameter;
import com.github.javaparser.ast.type.VoidType;
import com.github.javaparser.Position;
import com.github.javaparser.Range;
import com.github.javaparser.ast.ImportDeclaration;
import com.github.javaparser.ast.Modifier;
import com.github.javaparser.ast.Node;
import com.github.javaparser.ast.PackageDeclaration;
import com.github.javaparser.symbolsolver.javaparsermodel.JavaParserFacade;
import com.github.javaparser.symbolsolver.javaparsermodel.declarations.JavaParserConstructorDeclaration;
import com.github.javaparser.symbolsolver.javaparsermodel.declarations.JavaParserFieldDeclaration;
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.model.declarations.MethodAmbiguityException;
import com.github.javaparser.symbolsolver.model.declarations.ReferenceTypeDeclaration;
import com.github.javaparser.symbolsolver.model.declarations.ValueDeclaration;
import com.github.javaparser.symbolsolver.model.resolution.SymbolReference;
import com.github.javaparser.symbolsolver.model.resolution.TypeSolver;
import com.github.javaparser.symbolsolver.model.resolution.UnsolvedSymbolException;
import com.github.javaparser.symbolsolver.model.typesystem.*;
import com.github.javaparser.symbolsolver.resolution.MethodResolutionLogic;
public class AstVisitor extends AstVisitorAdapter
{
protected AstVisitorClient m_client = null;
private String m_filePath;
private FileContent m_fileContent;
private TypeSolver m_typeSolver;
private List<DeclContext> m_context = new ArrayList<DeclContext>();
public AstVisitor(AstVisitorClient client, String filePath, FileContent fileContent, TypeSolver typeSolver)
{
m_client = client;
m_filePath = filePath;
m_fileContent = fileContent;
m_typeSolver = typeSolver;
m_context.add(new DeclContext("/\tm" + filePath + "\ts\tp"));
}
// --- record declarations ---
@Override public void visit(final PackageDeclaration n, final Void v)
{
Name name = n.getName();
m_client.recordSymbolWithLocationAndScope(
JavaparserDeclNameResolver.getQualifiedName(name).toSerializedNameHierarchy(),
SymbolKind.PACKAGE,
name.getRange(),
n.getRange(),
AccessKind.NONE,
DefinitionKind.EXPLICIT
);
while (name.getQualifier().isPresent())
{
name = name.getQualifier().get();
m_client.recordSymbol(
JavaparserDeclNameResolver.getQualifiedName(name).toSerializedNameHierarchy(),
SymbolKind.PACKAGE,
AccessKind.NONE,
DefinitionKind.EXPLICIT
);
}
super.visit(n, v);
}
@Override public void visit(final ClassOrInterfaceDeclaration n, final Void v)
{
SimpleName name = n.getName();
String qualifiedName = JavaparserDeclNameResolver.getQualifiedDeclName(n, m_typeSolver).toSerializedNameHierarchy();
m_client.recordSymbolWithLocationAndScope(
qualifiedName, (n.isInterface() ? SymbolKind.INTERFACE : SymbolKind.CLASS),
name.getRange(),
n.getRange(),
AccessKind.fromAccessSpecifier(Modifier.getAccessSpecifier(n.getModifiers())),
DefinitionKind.EXPLICIT
);
if (n.getRange().isPresent())
{
FileContent.Location scopeStartLocation = m_fileContent.find("{", n.getBegin());
recordScope(Range.range(scopeStartLocation.line, scopeStartLocation.column, n.getRange().get().end.line, n.getRange().get().end.column));
}
List<DeclContext> parentContext = m_context;
m_context = new ArrayList<DeclContext>();
m_context.add(new DeclContext(qualifiedName));
super.visit(n, v);
m_context = parentContext;
}
@Override public void visit(final TypeParameter n, final Void v)
{
// todo: test recording of typeargument of type parameter bound type??
if (m_context.size() != 1)
{
// throw something!
}
String qualifiedName = m_context.get(0).getName();
qualifiedName += "\tn";
qualifiedName += n.getName() + "\ts\tp";
Optional<Range> range = Optional.empty();
if (n.getBegin().isPresent())
{
range = Optional.of(Range.range(
n.getBegin().get().line,
n.getBegin().get().column,
n.getBegin().get().line,
n.getBegin().get().column + n.getNameAsString().length() - 1
));
}
m_client.recordSymbolWithLocation(
qualifiedName, SymbolKind.TYPE_PARAMETER,
range,
AccessKind.TYPE_PARAMETER,
DefinitionKind.EXPLICIT
);
List<DeclContext> parentContext = m_context;
m_context = new ArrayList<DeclContext>();
m_context.add(new DeclContext(qualifiedName));
super.visit(n, v);
m_context = parentContext;
}
@Override public void visit(final EnumDeclaration n, final Void v)
{
SimpleName name = n.getName();
String qualifiedName = JavaparserDeclNameResolver.getQualifiedDeclName(n, m_typeSolver).toSerializedNameHierarchy();
m_client.recordSymbolWithLocationAndScope(
qualifiedName, SymbolKind.ENUM,
name.getRange(),
n.getRange(),
AccessKind.fromAccessSpecifier(Modifier.getAccessSpecifier(n.getModifiers())),
DefinitionKind.EXPLICIT
);
if (n.getRange().isPresent())
{
FileContent.Location scopeStartLocation = m_fileContent.find("{", n.getBegin());
recordScope(Range.range(scopeStartLocation.line, scopeStartLocation.column, n.getRange().get().end.line, n.getRange().get().end.column));
}
List<DeclContext> parentContext = m_context;
m_context = new ArrayList<DeclContext>();
m_context.add(new DeclContext(qualifiedName));
super.visit(n, v);
m_context = parentContext;
}
@Override public void visit(final EnumConstantDeclaration n, final Void v)
{
String qualifiedName = JavaparserDeclNameResolver.getQualifiedDeclName(n, m_typeSolver).toSerializedNameHierarchy();
m_client.recordSymbolWithLocation(
qualifiedName, SymbolKind.ENUM_CONSTANT,
n.getRange(),
AccessKind.NONE,
DefinitionKind.EXPLICIT
);
List<DeclContext> parentContext = m_context;
m_context = new ArrayList<DeclContext>();
m_context.add(new DeclContext(qualifiedName));
super.visit(n, v);
m_context = parentContext;
}
@Override public void visit(final ConstructorDeclaration n, final Void v)
{
SimpleName name = n.getName();
String qualifiedName = JavaparserDeclNameResolver.getQualifiedDeclName(n, m_typeSolver).toSerializedNameHierarchy();
m_client.recordSymbolWithLocationAndScope(
qualifiedName, SymbolKind.METHOD,
name.getRange(),
n.getRange(),
AccessKind.fromAccessSpecifier(Modifier.getAccessSpecifier(n.getModifiers())),
DefinitionKind.EXPLICIT
);
List<DeclContext> parentContext = m_context;
m_context = new ArrayList<DeclContext>();
m_context.add(new DeclContext(qualifiedName));
super.visit(n, v);
m_context = parentContext;
}
@Override public void visit(final MethodDeclaration n, final Void v)
{
SimpleName name = n.getName();
String qualifiedName = JavaparserDeclNameResolver.getQualifiedDeclName(n, m_typeSolver).toSerializedNameHierarchy();
m_client.recordSymbolWithLocationAndScope(
qualifiedName, SymbolKind.METHOD,
name.getRange(),
n.getRange(),
AccessKind.fromAccessSpecifier(Modifier.getAccessSpecifier(n.getModifiers())),
DefinitionKind.EXPLICIT
);
// test this!
com.github.javaparser.symbolsolver.model.declarations.MethodDeclaration overridden = getOverridden(n);
if (overridden != null && (overridden instanceof JavaParserMethodDeclaration))
{
String overriddenName = JavaparserDeclNameResolver.getQualifiedDeclName(((JavaParserMethodDeclaration)overridden).getWrappedNode(), m_typeSolver).toSerializedNameHierarchy();
m_client.recordReference(
ReferenceKind.OVERRIDE, overriddenName, qualifiedName,
name.getRange()
);
}
List<DeclContext> parentContext = m_context;
m_context = new ArrayList<DeclContext>();
m_context.add(new DeclContext(qualifiedName));
super.visit(n, v);
m_context = parentContext;
}
private com.github.javaparser.symbolsolver.model.declarations.MethodDeclaration getOverridden(MethodDeclaration overrider)
{
com.github.javaparser.ast.body.TypeDeclaration<?> scopeNode = overrider.getAncestorOfType(com.github.javaparser.ast.body.TypeDeclaration.class).get();
if (scopeNode instanceof ClassOrInterfaceDeclaration)
{
List<com.github.javaparser.symbolsolver.model.typesystem.Type> parameterTypes = new ArrayList<>();
try
{
for (Parameter parameter: overrider.getParameters())
{
Type parameterType = parameter.getType();
parameterTypes.add(JavaParserFacade.get(m_typeSolver).convert(parameterType, parameterType));
}
ReferenceTypeDeclaration scopeDecl = JavaParserFacade.get(m_typeSolver).getTypeDeclaration((ClassOrInterfaceDeclaration)scopeNode);
for (ReferenceType ancestor: scopeDecl.getAllAncestors())
{
try
{
SymbolReference<com.github.javaparser.symbolsolver.model.declarations.MethodDeclaration> solvedMethod = MethodResolutionLogic.solveMethodInType(
ancestor.getTypeDeclaration(),
overrider.getNameAsString(),
parameterTypes,
m_typeSolver
);
if (solvedMethod.isSolved())
{
return solvedMethod.getCorrespondingDeclaration();
}
}
catch (UnsolvedSymbolException e)
{
// nothing to do here, just try to solve in the next ancestor
}
catch (Exception e)
{
// hmm, maybe we should handle these cases. soon..
// don't do anything for parse exceptions. they are displayed as errors anyways.
}
}
}
catch (UnsolvedSymbolException e)
{
return null;
}
catch (ClassCastException e)
{
return null;
}
catch (Exception e)
{
return null;
}
}
return null;
}
@Override public void visit(final FieldDeclaration n, final Void v)
{
List<DeclContext> parentContext = m_context;
m_context = new ArrayList<DeclContext>();
for (VariableDeclarator declarator: n.getVariables())
{
String qualifiedName = JavaparserDeclNameResolver.getQualifiedDeclName(declarator, m_typeSolver).toSerializedNameHierarchy();
SimpleName name = declarator.getName();
m_client.recordSymbolWithLocation(
qualifiedName, SymbolKind.FIELD,
name.getRange(),
AccessKind.fromAccessSpecifier(Modifier.getAccessSpecifier(n.getModifiers())),
DefinitionKind.EXPLICIT
);
m_context.add(new DeclContext(qualifiedName));
}
super.visit(n, v);
m_context = parentContext;
}
@Override public void visit(final VariableDeclarationExpr n, final Void v)
{
for (VariableDeclarator declarator: n.getVariables())
{
SimpleName name = declarator.getName();
if (name.getBegin().isPresent())
{
String qualifiedName = m_filePath + "<" + name.getBegin().get().line + ":" + name.getBegin().get().column + ">";
m_client.recordLocalSymbol(qualifiedName, name.getRange());
}
}
// don't change the context here.
super.visit(n, v);
}
@Override public void visit(final Parameter n, final Void v)
{
SimpleName name = n.getName();
if (name.getBegin().isPresent())
{
String qualifiedName = m_filePath + "<" + name.getBegin().get().line + ":" + name.getBegin().get().column + ">";
m_client.recordLocalSymbol(qualifiedName, name.getRange());
}
// don't change the context here.
super.visit(n, v);
}
// --- record references ---
@Override
public void visit(final ImportDeclaration n, final Void v)
{
Name name = n.getName();
if (n.isAsterisk())
{
String importedName = JavaparserDeclNameResolver.getQualifiedName(name).toSerializedNameHierarchy();
for (DeclContext context: m_context)
{
m_client.recordReference(
ReferenceKind.IMPORT,
importedName, context.getName(),
name.getRange()
);
}
}
else
{
try
{
List<JavaDeclName> importedDeclNames = new ArrayList<>();
SymbolReference<ReferenceTypeDeclaration> solvedTypeDeclatarion = m_typeSolver.tryToSolveType(name.asString());
if (solvedTypeDeclatarion.isSolved())
{
importedDeclNames.add(JavaSymbolSolverDeclNameResolver.getQualifiedDeclName(solvedTypeDeclatarion.getCorrespondingDeclaration(), m_typeSolver));
}
else if (n.isStatic())
{
String typeName = name.getQualifier().get().asString();
String memberName = name.getIdentifier();
ReferenceTypeDeclaration solvedDecl = m_typeSolver.solveType(typeName);
for (com.github.javaparser.symbolsolver.model.declarations.MethodDeclaration methodDecl: solvedDecl.getDeclaredMethods()) // look for method
{
if (methodDecl.getName().equals(memberName))
{
importedDeclNames.add(
JavaSymbolSolverDeclNameResolver.getQualifiedDeclName(methodDecl, m_typeSolver
));
}
}
if (importedDeclNames.isEmpty() && solvedDecl.hasField(memberName)) // look for field
{
JavaDeclName importedTypeDeclName = JavaSymbolSolverDeclNameResolver.getQualifiedDeclName(solvedDecl, m_typeSolver);
if (importedTypeDeclName != null)
{
JavaDeclName importedDeclName = new JavaDeclName(memberName);
importedDeclName.setParent(importedTypeDeclName);
importedDeclNames.add(importedDeclName);
}
}
}
if (!importedDeclNames.isEmpty())
{
for (JavaDeclName importedDeclName: importedDeclNames)
{
String nameHierarchy = importedDeclName.toSerializedNameHierarchy();
for (DeclContext context: m_context)
{
m_client.recordReference(
ReferenceKind.IMPORT,
nameHierarchy, context.getName(),
n.getRange()
);
}
}
}
else
{
m_client.recordError("Import not found: " + name, true, true, n.getRange());
}
}
catch (Exception e)
{
recordException(e, n);
}
}
super.visit(n, v);
}
@Override public void visit(final ClassOrInterfaceType n, final Void v)
{
try
{
for (DeclContext context: m_context)
{
String referencedName = JavaparserTypeNameResolver.getQualifiedTypeName(n, m_typeSolver).toSerializedNameHierarchy();
Range range = Range.range(0, 0, 0, 0);
if (n.getRange().isPresent())
{
range = Range.range(
n.getRange().get().begin.line,
n.getRange().get().begin.column,
n.getRange().get().begin.line,
n.getRange().get().begin.column + n.getNameAsString().length() - 1
);
}
Optional<ClassOrInterfaceType> scope = n.getScope();
if (scope.isPresent())
{
Optional<Position> position = scope.get().getEnd();
if (position.isPresent())
{
range = range.withEnd(
Position.pos(position.get().line,
position.get().column + n.getNameAsString().length() + 1 // +1 for separator
));
}
}
m_client.recordReference(
getTypeReferenceKind(), referencedName, context.getName(), range
);
}
}
catch (Exception e)
{
recordException(e, n);
}
super.visit(n, v);
}
@Override public void visit(final PrimitiveType n, final Void v)
{
try
{
String referencedName = JavaparserTypeNameResolver.getQualifiedTypeName(n, m_typeSolver).toSerializedNameHierarchy();
m_client.recordSymbol(
referencedName, SymbolKind.BUILTIN_TYPE,
AccessKind.NONE,
DefinitionKind.EXPLICIT
);
for (DeclContext context: m_context)
{
m_client.recordReference(
getTypeReferenceKind(), referencedName, context.getName(),
n.getRange()
);
}
}
catch (Exception e)
{
recordException(e, n);
}
super.visit(n, v);
}
@Override public void visit(final VoidType n, final Void v)
{
try
{
String referencedName = JavaparserTypeNameResolver.getQualifiedTypeName(n, m_typeSolver).toSerializedNameHierarchy();
m_client.recordSymbol(
referencedName, SymbolKind.BUILTIN_TYPE, AccessKind.NONE, DefinitionKind.EXPLICIT
);
for (DeclContext context: m_context)
{
m_client.recordReference(
getTypeReferenceKind(), referencedName, context.getName(), n.getRange()
);
}
}
catch (Exception e)
{
recordException(e, n);
}
super.visit(n, v);
}
@Override public void visit(final FieldAccessExpr n, final Void v)
{
SimpleName fieldName = n.getField();
try
{
SymbolReference<? extends ValueDeclaration> ref = JavaParserFacade.get(m_typeSolver).solve(fieldName);
if (ref.isSolved())
{
ValueDeclaration valueDecl = ref.getCorrespondingDeclaration();
Node wrappedNode = null;
if (valueDecl instanceof JavaParserFieldDeclaration)
{
wrappedNode = ((JavaParserFieldDeclaration)valueDecl).getWrappedNode();
}
if (wrappedNode != null && wrappedNode instanceof FieldDeclaration)
{
for (VariableDeclarator var: ((FieldDeclaration)wrappedNode).getVariables())
{
if (var.getName().getIdentifier().equals(fieldName.getIdentifier()))
{
String qualifiedName = JavaparserDeclNameResolver.getQualifiedDeclName(var, m_typeSolver).toSerializedNameHierarchy();
for (DeclContext context: m_context)
{
m_client.recordReference(
ReferenceKind.USAGE, qualifiedName, context.getName(),
fieldName.getRange()
);
}
}
}
}
}
}
catch (Exception e)
{
recordException(e, n);
}
super.visit(n, v);
}
@Override public void visit(final NameExpr n, final Void v)
{
try
{
recordRef(n);
}
catch (Exception e)
{
recordException(e, n);
}
super.visit(n, v);
}
private void recordRef(NameExpr e)
{
SymbolReference<? extends ValueDeclaration> ref = JavaParserFacade.get(m_typeSolver).solve(e);
if (ref.isSolved())
{
ValueDeclaration valueDecl = ref.getCorrespondingDeclaration();
Node wrappedNode = null;
if (valueDecl instanceof JavaParserSymbolDeclaration)
{
wrappedNode = ((JavaParserSymbolDeclaration)valueDecl).getWrappedNode();
}
else if (valueDecl instanceof JavaParserParameterDeclaration)
{
wrappedNode = ((JavaParserParameterDeclaration)valueDecl).getWrappedNode();
}
else if (valueDecl instanceof JavaParserFieldDeclaration)
{
wrappedNode = ((JavaParserFieldDeclaration)valueDecl).getWrappedNode();
}
if (wrappedNode != null)
{
if (wrappedNode instanceof FieldDeclaration)
{
for (VariableDeclarator var: ((FieldDeclaration)wrappedNode).getVariables())
{
if (var.getName().getIdentifier().equals(e.getName().getIdentifier()))
{
String qualifiedName = JavaparserDeclNameResolver.getQualifiedDeclName(var, m_typeSolver).toSerializedNameHierarchy();
for (DeclContext context: m_context)
{
m_client.recordReference(
ReferenceKind.USAGE, qualifiedName, context.getName(),
e.getName().getRange()
);
}
}
}
}
else if (wrappedNode instanceof Parameter)
{
SimpleName name = ((Parameter)wrappedNode).getName();
if (name.getBegin().isPresent())
{
String qualifiedName = m_filePath + "<" + name.getBegin().get().line + ":" + name.getBegin().get().column + ">";
m_client.recordLocalSymbol(
qualifiedName,
e.getRange()
);
}
}
else if (wrappedNode instanceof VariableDeclarator)
{
if (wrappedNode.getAncestorOfType(FieldDeclaration.class).isPresent())
{
String qualifiedName = JavaparserDeclNameResolver.getQualifiedDeclName((VariableDeclarator)wrappedNode, m_typeSolver).toSerializedNameHierarchy();
for (DeclContext context: m_context)
{
m_client.recordReference(
ReferenceKind.USAGE, qualifiedName, context.getName(),
e.getRange()
);
}
}
else
{
SimpleName name = ((VariableDeclarator)wrappedNode).getName();
if (name.getBegin().isPresent())
{
String qualifiedName = m_filePath + "<" + name.getBegin().get().line + ":" + name.getBegin().get().column + ">";
m_client.recordLocalSymbol(
qualifiedName,
e.getRange()
);
}
}
}
}
}
}
@Override public void visit(final MethodCallExpr n, final Void v)
{
String qualifiedName = "";
if (m_context.size() > 0)
{
try
{
SymbolReference<com.github.javaparser.symbolsolver.model.declarations.MethodDeclaration> solvedSymbol = JavaParserFacade.get(m_typeSolver).solve(n);
if (solvedSymbol.isSolved())
{
qualifiedName = getQualifiedName(solvedSymbol.getCorrespondingDeclaration());
}
else
{
throw new UnsolvedSymbolException(n.getNameAsString());
}
}
catch (UnsupportedOperationException e)
{
recordException(e, n);
}
catch (MethodAmbiguityException e)
{
recordException(e, n);
}
catch(StackOverflowError e)
{
recordError(e, n);
}
catch (Exception e)
{
recordException(e, n);
}
}
if (!qualifiedName.isEmpty())
{
SimpleName name = n.getName();
for (DeclContext context: m_context)
{
m_client.recordReference(
ReferenceKind.CALL, qualifiedName, context.getName(),
name.getRange()
);
}
}
super.visit(n, v);
}
private void recordException(Exception e, Node n)
{
recordExceptionOrError(e.getClass().getSimpleName(), n);
}
private void recordError(Error e, Node n)
{
recordExceptionOrError(e.getClass().getSimpleName(), n);
}
private void recordExceptionOrError(String e, Node n)
{
String beginLine = "?";
String beginColumn = "?";
if (n.getBegin().isPresent())
{
beginLine = n.getBegin().get().line + "";
beginColumn = n.getBegin().get().column + "";
}
m_client.logError(e + " at " + m_filePath + "<"+ beginLine + ", " + beginColumn + ">");
m_client.recordSymbolWithLocation(
".\tmunsolved-symbol\ts\tp", SymbolKind.TYPE_MAX,
n.getRange(),
AccessKind.DEFAULT,
DefinitionKind.EXPLICIT
);
}
@Override public void visit(final ObjectCreationExpr n, final Void v)
{
String qualifiedName = "";
if (m_context.size() > 0)
{
try
{
SymbolReference<com.github.javaparser.symbolsolver.model.declarations.ConstructorDeclaration> solvedSymbol = JavaParserFacade.get(m_typeSolver).solve(n);
if (solvedSymbol.isSolved())
{
qualifiedName = getQualifiedName(solvedSymbol.getCorrespondingDeclaration());
}
else
{
throw new UnsolvedSymbolException("constructor for " + n.getType().getNameAsString());
}
}
catch (UnsupportedOperationException e)
{
recordException(e, n);
}
catch (MethodAmbiguityException e)
{
recordException(e, n);
}
catch(StackOverflowError e)
{
recordError(e, n);
}
catch (Exception e)
{
recordException(e, n);
}
}
if (!qualifiedName.isEmpty())
{
ClassOrInterfaceType type = n.getType();
for (DeclContext context: m_context)
{
m_client.recordReference(
ReferenceKind.CALL, qualifiedName, context.getName(),
type.getRange()
);
}
}
super.visit(n, v);
}
private String getQualifiedName(com.github.javaparser.symbolsolver.model.declarations.MethodDeclaration method)
{
String qualifiedName = "";
if (method instanceof JavaParserMethodDeclaration)
{
MethodDeclaration wrappedNode = ((JavaParserMethodDeclaration)method).getWrappedNode();
qualifiedName = JavaparserDeclNameResolver.getQualifiedDeclName(wrappedNode, m_typeSolver).toSerializedNameHierarchy();
}
else // todo: move this implementation somewhere else
{
qualifiedName = ".\tm" + method.declaringType().getQualifiedName();
qualifiedName = qualifiedName.replace(".", "\ts\tp\tn");
qualifiedName += "\ts\tp\tn" + method.getName() + "\ts";
String returnType = method.getReturnType().describe();
qualifiedName += returnType;
// qualifiedName += returnType.substring(returnType.lastIndexOf(".") + 1);
qualifiedName += "\tp(";
for (int i = 0; i < method.getNumberOfParams(); i++)
{
if(i != 0)
{
qualifiedName += (", ");
}
String paramType = method.getParam(i).describeType();
qualifiedName += paramType;
// qualifiedName += paramType.substring(paramType.lastIndexOf(".") + 1);
}
qualifiedName = qualifiedName.concat(")");
}
return qualifiedName;
}
private String getQualifiedName(com.github.javaparser.symbolsolver.model.declarations.ConstructorDeclaration constructor)
{
String qualifiedName = "";
if (constructor instanceof JavaParserConstructorDeclaration)
{
ConstructorDeclaration wrappedNode = ((JavaParserConstructorDeclaration)constructor).getWrappedNode();
qualifiedName = JavaparserDeclNameResolver.getQualifiedDeclName(wrappedNode, m_typeSolver).toSerializedNameHierarchy();
}
else // todo: move this implementation somewhere else
{
qualifiedName = ".\tm" + constructor.declaringType().getQualifiedName();
qualifiedName = qualifiedName.replace(".", "\ts\tp\tn");
qualifiedName += "\ts\tp\tn" + constructor.getName() + "\ts\tp(";
for (int i = 0; i < constructor.getNumberOfParams(); i++)
{
if(i != 0)
{
qualifiedName += (", ");
}
String paramType = constructor.getParam(i).describeType();
qualifiedName += paramType;
// qualifiedName += paramType.substring(paramType.lastIndexOf(".") + 1);
}
qualifiedName = qualifiedName.concat(")");
}
return qualifiedName;
}
@Override public void visit(final BlockStmt n, final Void v)
{
recordScope(n.getRange());
super.visit(n, v);
}
@Override public void visit(final ArrayInitializerExpr n, final Void v)
{
recordScope(n.getRange());
super.visit(n, v);
}
@Override public void visit(final SwitchStmt n, final Void v)
{
if (n.getRange().isPresent())
{
FileContent.Location scopeStartLocation = m_fileContent.find("{", n.getBegin());
recordScope(Range.range(scopeStartLocation.line, scopeStartLocation.column, n.getRange().get().end.line, n.getRange().get().end.column));
}
super.visit(n, v);
}
private void recordScope(Optional<Range> range)
{
if (range.isPresent())
{
recordScope(range.get());
}
}
private void recordScope(Range range)
{
String qualifiedName = m_filePath + "<" + range.begin.line + ":" + range.begin.column + ">";
m_client.recordLocalSymbol(qualifiedName, Range.range(range.begin, range.begin));
m_client.recordLocalSymbol(qualifiedName, Range.range(range.end, range.end));
}
@Override public void visit(final LineComment n, final Void v)
{
m_client.recordComment(n.getRange());
super.visit(n, v);
}
@Override public void visit(final BlockComment n, final Void v)
{
m_client.recordComment(n.getRange());
super.visit(n, v);
}
}
@@ -0,0 +1,248 @@
package com.sourcetrail;
import com.github.javaparser.ast.visitor.VoidVisitorAdapter;
import com.github.javaparser.ast.*;
import com.github.javaparser.ast.body.*;
import com.github.javaparser.ast.comments.Comment;
import com.github.javaparser.ast.expr.*;
import com.github.javaparser.ast.nodeTypes.NodeWithAnnotations;
import com.github.javaparser.ast.stmt.*;
import com.github.javaparser.ast.type.*;
import java.util.Optional;
import java.util.Stack;
public abstract class AstVisitorAdapter extends VoidVisitorAdapter<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 void visit(final CompilationUnit n, Void arg)
{
m_typeRefKind.push(ReferenceKind.TYPE_USAGE);
visitComment(n.getComment(), arg);
if (n.getPackageDeclaration().isPresent())
{
n.getPackageDeclaration().get().accept(this, arg);
}
if (n.getImports() != null)
{
for (final ImportDeclaration i : n.getImports())
{
i.accept(this, arg);
}
}
if (n.getTypes() != null)
{
for (final TypeDeclaration<?> typeDeclaration : n.getTypes())
{
typeDeclaration.accept(this, arg);
}
}
m_typeRefKind.pop();
}
//- Body ----------------------------------------------
@Override public void visit(ClassOrInterfaceDeclaration n, Void arg)
{
visitComment(n.getComment(), arg);
visitAnnotations(n, arg);
n.getName().accept(this, arg);
for (final TypeParameter t : n.getTypeParameters())
{
t.accept(this, arg);
}
m_typeRefKind.push(ReferenceKind.INHERITANCE);
for (final ClassOrInterfaceType c : n.getExtendedTypes())
{
c.accept(this, arg);
}
for (final ClassOrInterfaceType c : n.getImplementedTypes())
{
c.accept(this, arg);
}
m_typeRefKind.pop();
for (final BodyDeclaration<?> member : n.getMembers())
{
member.accept(this, arg);
}
}
@Override public void visit(EnumDeclaration n, Void arg)
{
visitComment(n.getComment(), arg);
visitAnnotations(n, arg);
n.getName().accept(this, arg);
m_typeRefKind.push(ReferenceKind.INHERITANCE);
if (n.getImplementedTypes() != null)
{
for (final ClassOrInterfaceType c : n.getImplementedTypes())
{
c.accept(this, arg);
}
}
m_typeRefKind.pop();
if (n.getEntries() != null)
{
for (final EnumConstantDeclaration e : n.getEntries())
{
e.accept(this, arg);
}
}
if (n.getMembers() != null)
{
for (final BodyDeclaration<?> member : n.getMembers())
{
member.accept(this, arg);
}
}
}
//- Type ----------------------------------------------
@Override public void visit(ClassOrInterfaceType n, Void arg)
{
visitComment(n.getComment(), arg);
visitAnnotations(n, arg);
// don't visit the qualifier here.
// if (n.getScope().isPresent())
// {
// n.getScope().get().accept(this, arg);
// }
m_typeRefKind.push(ReferenceKind.TYPE_ARGUMENT);
if (n.getTypeArguments().isPresent())
{
for (final Type t : n.getTypeArguments().get())
{
t.accept(this, arg);
}
}
m_typeRefKind.pop();
}
//- Expression ----------------------------------------
@Override public void visit(MethodCallExpr n, Void arg)
{
visitComment(n.getComment(), arg);
if (n.getScope().isPresent())
{
n.getScope().get().accept(this, arg);
}
m_typeRefKind.push(ReferenceKind.TYPE_ARGUMENT);
if (n.getTypeArguments().isPresent())
{
for (final Type t : n.getTypeArguments().get())
{
t.accept(this, arg);
}
}
m_typeRefKind.pop();
n.getName().accept(this, arg);
if (n.getArguments() != null)
{
for (final Expression e : n.getArguments())
{
e.accept(this, arg);
}
}
}
@Override public void visit(ObjectCreationExpr n, Void arg)
{
visitComment(n.getComment(), arg);
if (n.getScope().isPresent())
{
n.getScope().get().accept(this, arg);
}
m_typeRefKind.push(ReferenceKind.TYPE_ARGUMENT);
if (n.getTypeArguments().isPresent())
{
for (final Type t : n.getTypeArguments().get())
{
t.accept(this, arg);
}
}
m_typeRefKind.pop();
// n.getType().accept(this, arg);
if (n.getArguments() != null)
{
for (final Expression e : n.getArguments())
{
e.accept(this, arg);
}
}
if (n.getAnonymousClassBody().isPresent())
{
for (final BodyDeclaration<?> member : n.getAnonymousClassBody().get())
{
member.accept(this, arg);
}
}
}
//- Statements ----------------------------------------
@Override public void visit(ExplicitConstructorInvocationStmt n, Void arg)
{
visitComment(n.getComment(), arg);
if (!n.isThis() && n.getExpression().isPresent())
{
n.getExpression().get().accept(this, arg);
}
m_typeRefKind.push(ReferenceKind.TYPE_ARGUMENT);
if (n.getTypeArguments().isPresent())
{
for (final Type t : n.getTypeArguments().get())
{
t.accept(this, arg);
}
}
m_typeRefKind.pop();
if (n.getArguments() != null)
{
for (final Expression e : n.getArguments())
{
e.accept(this, arg);
}
}
}
private void visitComment(final Optional<Comment> n, final Void arg)
{
if (n.isPresent())
{
n.get().accept(this, arg);
}
}
private void visitAnnotations(NodeWithAnnotations<?> n, final Void arg)
{
for (AnnotationExpr annotation : n.getAnnotations())
{
annotation.accept(this, arg);
}
}
}
@@ -0,0 +1,117 @@
package com.sourcetrail;
import java.util.Optional;
import com.github.javaparser.Range;
public abstract class AstVisitorClient
{
public void recordSymbolWithLocation(
String symbolName, SymbolKind symbolType,
Optional<Range> range,
AccessKind access, DefinitionKind definitionKind
)
{
recordSymbolWithLocation(
symbolName, symbolType,
range.orElse(Range.range(0, 0, 0, 0)),
access, definitionKind
);
}
public void recordSymbolWithLocationAndScope(
String symbolName, SymbolKind symbolType,
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
);
}
public void recordReference(
ReferenceKind referenceKind, String referencedName, String contextName,
Optional<Range> range
)
{
recordReference(
referenceKind, referencedName, contextName,
range.orElse(Range.range(0, 0, 0, 0))
);
}
public void recordLocalSymbol(
String symbolName,
Optional<Range> range
)
{
recordLocalSymbol(symbolName, range.orElse(Range.range(0, 0, 0, 0)));
}
public void recordComment(
Optional<Range> range
)
{
recordComment(range.orElse(Range.range(0, 0, 0, 0)));
}
public void recordError(
String message, boolean fatal, boolean indexed,
Optional<Range> range
)
{
recordError(
message, fatal, indexed,
range.orElse(Range.range(0, 0, 0, 0))
);
}
public abstract void logInfo(String info);
public abstract void logWarning(String warning);
public abstract void logError(String error);
public abstract void recordSymbol(
String symbolName, SymbolKind symbolType,
AccessKind access, DefinitionKind definitionKind
);
public abstract void recordSymbolWithLocation(
String symbolName, SymbolKind symbolType,
Range range,
AccessKind access, DefinitionKind definitionKind
);
public abstract void recordSymbolWithLocationAndScope(
String symbolName, SymbolKind symbolType,
Range range,
Range scopeRange,
AccessKind access, DefinitionKind definitionKind
);
public abstract void recordReference(
ReferenceKind referenceKind, String referencedName, String contextName,
Range range
);
public abstract void recordLocalSymbol(
String symbolName,
Range range
);
public abstract void recordComment(
Range range
);
public abstract void recordError(
String message, boolean fatal, boolean indexed,
Range range
);
}
@@ -0,0 +1,46 @@
package com.sourcetrail;
import java.util.List;
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 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();
}
}
@@ -0,0 +1,16 @@
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 String getName();
public NodeList<TypeParameter> getTypeParameters();
public NodeList<Parameter> getParameters();
public Type getType();
}
@@ -0,0 +1,45 @@
package com.sourcetrail;
import java.util.List;
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 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();
}
}
@@ -0,0 +1,16 @@
package com.sourcetrail;
public class DeclContext
{
private String m_name = null;
public DeclContext(String name)
{
m_name = name;
}
public String getName()
{
return m_name;
}
}
@@ -0,0 +1,20 @@
package com.sourcetrail;
public enum DefinitionKind
{ // these values need to be the same as DefinitionKind in C++ code
NONE(0),
IMPLICIT(1),
EXPLICIT(2);
private final int m_value;
private DefinitionKind(int value)
{
this.m_value = value;
}
public int getValue()
{
return m_value;
}
}
@@ -0,0 +1,57 @@
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)
{
m_lines = Arrays.asList(text.split("\\r?\\n"));
}
public Location find(String s)
{
return find(s, Position.pos(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)
{
int lineIndex = from.line - 1;
int startColumn = from.column - 1;
int column = -1;
while (lineIndex < m_lines.size())
{
column = m_lines.get(lineIndex).indexOf(s, startColumn);
if (column != -1)
{
return new Location(lineIndex + 1, column + 1);
}
startColumn = 0;
lineIndex++;
}
return new Location(0, 0);
}
}
@@ -0,0 +1,147 @@
package com.sourcetrail;
import java.util.List;
public class JavaDeclName
{
private JavaDeclName m_parent = null;
private String m_name = "";
private List<String> m_typeParameterNames = null;
private JavaTypeName m_returnTypeName = null;
private List<JavaTypeName> m_parameterNames = null;
public static JavaDeclName fromDotSeparatedString(String s)
{
JavaDeclName declName = null;
int separatorIndex = s.lastIndexOf('.');
if (separatorIndex != -1)
{
declName = new JavaDeclName(s.substring(separatorIndex + 1));
declName.setParent(JavaDeclName.fromDotSeparatedString(s.substring(0, separatorIndex)));
}
else
{
declName = new JavaDeclName(s, null);
}
return declName;
}
public JavaDeclName(String name)
{
m_name = name;
}
public JavaDeclName(String name, JavaTypeName returnTypeName, List<JavaTypeName> parameterNames)
{
m_name = name;
m_returnTypeName = returnTypeName;
m_parameterNames = parameterNames;
}
public JavaDeclName(String name, List<String> typeParameterNames)
{
m_name = name;
m_typeParameterNames = typeParameterNames;
}
public JavaDeclName(String name, List<String> typeParameterNames, JavaTypeName returnTypeName, List<JavaTypeName> parameterNames)
{
m_name = name;
m_typeParameterNames = typeParameterNames;
m_returnTypeName = returnTypeName;
m_parameterNames = parameterNames;
}
public void setParent(JavaDeclName parent)
{
m_parent = parent;
}
public JavaDeclName getParent()
{
return m_parent;
}
public String getName()
{
return m_name;
}
public String toSerializedNameHierarchy()
{
String nameHierarchy = ".\tm";
if (m_parent != null)
{
nameHierarchy = m_parent.toSerializedNameHierarchy();
nameHierarchy += "\tn";
}
nameHierarchy += m_name;
nameHierarchy += getTypeParameterString();
nameHierarchy += "\ts";
if (m_returnTypeName != null)
{
nameHierarchy += m_returnTypeName.toString();
}
nameHierarchy += "\tp";
nameHierarchy += getParameterString();
return nameHierarchy;
}
public String toString()
{
String string = "";
if (m_parent != null)
{
string = m_parent.toString();
string += ".";
}
string += m_name;
string += getTypeParameterString();
return string;
}
private String getParameterString()
{
String string = "";
if (m_parameterNames != null)
{
string += "(";
for (int i = 0; i < m_parameterNames.size(); i++)
{
if (i != 0)
{
string += ", ";
}
string += m_parameterNames.get(i).toString();
}
string += ")";
}
return string;
}
public String getTypeParameterString()
{
String string = "";
if (m_typeParameterNames != null && !m_typeParameterNames.isEmpty())
{
string += "<";
for (int i = 0; i < m_typeParameterNames.size(); i++)
{
if (i != 0)
{
string += ", ";
}
string += m_typeParameterNames.get(i);
}
string += ">";
}
return string;
}
}
@@ -0,0 +1,195 @@
package com.sourcetrail;
import java.io.File;
import java.io.IOException;
import java.io.StringReader;
import java.lang.String;
import java.util.HashMap;
import java.util.Map;
import java.util.Optional;
import com.github.javaparser.ast.CompilationUnit;
import com.github.javaparser.ast.PackageDeclaration;
import com.github.javaparser.JavaParser;
import com.github.javaparser.ParseProblemException;
import com.github.javaparser.Problem;
import com.github.javaparser.Range;
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.JavaParserTypeSolver;
import com.github.javaparser.symbolsolver.resolution.typesolvers.ReflectionTypeSolver;
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);
astVisitorClient.logInfo( "indexing source file: " + filePath);
try
{
CombinedTypeSolver combinedTypeSolver = new CombinedTypeSolver();
combinedTypeSolver.add(new ReflectionTypeSolver());
for (String path: classPath.split("\\;"))
{
if (typeSolvers.containsKey(path))
{
combinedTypeSolver.add(typeSolvers.get(path));
}
else
{
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 JavaParserTypeSolver(new File(path));
}
if (typeSolver != null)
{
typeSolvers.put(path, typeSolver);
combinedTypeSolver.add(typeSolver);
}
}
}
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())
{
String message = problem.toString();
if (message.startsWith("(line "))
{
int startLine = Integer.parseInt(message.substring(
message.indexOf("line ") + ("line ").length(),
message.indexOf(",")
));
int startColumn = Integer.parseInt(message.substring(
message.indexOf("col ") + ("col ").length(),
message.indexOf(")")
));
astVisitorClient.recordError(
"Encountered unexpected token.", true, true,
Range.range(startLine, startColumn, startLine, startColumn)
);
}
else
{
Optional<Range> range = problem.getRange();
if (range.isPresent())
{
astVisitorClient.recordError(
problem.toString(), true, true,
range.get()
);
}
}
}
}
}
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
}
return packageName;
}
public static void clearCaches()
{
typeSolvers.clear();
JavaParserFacade.clearInstances();
Runtime.getRuntime().gc();
}
// the following methods are defined in the native c++ code
static public native void logInfo(int address, String info);
static public native void logWarning(int address, String warning);
static public native void logError(int address, String error);
static public native void recordSymbol(
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
);
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
);
static public native void recordReference(
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
);
static public native void recordComment(
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
);
}
@@ -0,0 +1,106 @@
package com.sourcetrail;
import com.github.javaparser.Range;
public class JavaIndexerAstVisitorClient extends AstVisitorClient
{
private int m_address;
public JavaIndexerAstVisitorClient(int address)
{
m_address = address;
}
@Override
public void logInfo(String info)
{
JavaIndexer.logInfo(m_address, info);
}
@Override
public void logWarning(String warning)
{
JavaIndexer.logWarning(m_address, warning);
}
@Override
public void logError(String error)
{
JavaIndexer.logError(m_address, error);
}
@Override
public void recordSymbol(
String symbolName, SymbolKind symbolType,
AccessKind access, DefinitionKind definitionKind)
{
JavaIndexer.recordSymbol(
m_address, symbolName, symbolType.getValue(),
access.getValue(), definitionKind.getValue()
);
}
@Override
public void recordSymbolWithLocation(
String symbolName, SymbolKind symbolType, 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()
);
}
@Override
public void recordSymbolWithLocationAndScope(
String symbolName, SymbolKind symbolType, 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()
);
}
@Override
public void recordReference(
ReferenceKind referenceKind, String referencedName,
String contextName, Range range)
{
JavaIndexer.recordReference(
m_address, referenceKind.getValue(), referencedName, contextName,
range.begin.line, range.begin.column, range.end.line, range.end.column
);
}
@Override
public void recordLocalSymbol(String symbolName, Range range)
{
JavaIndexer.recordLocalSymbol(
m_address, symbolName,
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
);
}
@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
);
}
}
@@ -0,0 +1,42 @@
package com.sourcetrail;
import java.util.ArrayList;
import com.github.javaparser.ast.body.BodyDeclaration;
import com.github.javaparser.symbolsolver.model.resolution.TypeSolver;
public abstract class JavaNameResolver
{
TypeSolver m_typeSolver = null;
ArrayList<BodyDeclaration> m_ignoredContexts = null;
public JavaNameResolver(TypeSolver typeSolver, ArrayList<BodyDeclaration> ignoredContexts)
{
m_typeSolver = typeSolver;
if (ignoredContexts != null)
{
m_ignoredContexts = ignoredContexts;
}
else
{
m_ignoredContexts = new ArrayList<BodyDeclaration>();
}
}
protected boolean ignoresContext(BodyDeclaration context)
{
if (m_ignoredContexts != null)
{
for (BodyDeclaration ignoredContext: m_ignoredContexts)
{
if (ignoredContext.equals(context))
{
return true;
}
}
}
return false;
}
}
@@ -0,0 +1,119 @@
package com.sourcetrail;
import java.util.ArrayList;
import java.util.List;
import com.github.javaparser.ast.body.BodyDeclaration;
import com.github.javaparser.ast.body.ClassOrInterfaceDeclaration;
import com.github.javaparser.symbolsolver.javaparsermodel.declarations.JavaParserClassDeclaration;
import com.github.javaparser.symbolsolver.javaparsermodel.declarations.JavaParserInterfaceDeclaration;
import com.github.javaparser.symbolsolver.javaparsermodel.declarations.JavaParserMethodDeclaration;
import com.github.javaparser.symbolsolver.model.declarations.Declaration;
import com.github.javaparser.symbolsolver.model.declarations.MethodDeclaration;
import com.github.javaparser.symbolsolver.model.declarations.TypeDeclaration;
import com.github.javaparser.symbolsolver.model.declarations.TypeParameterDeclaration;
import com.github.javaparser.symbolsolver.model.resolution.TypeSolver;
public class JavaSymbolSolverDeclNameResolver extends JavaNameResolver
{
public JavaSymbolSolverDeclNameResolver(TypeSolver typeSolver, ArrayList<BodyDeclaration> ignoredContexts)
{
super(typeSolver, ignoredContexts);
}
public static JavaDeclName getQualifiedDeclName(Declaration decl, TypeSolver typeSolver)
{
return getQualifiedDeclName(decl, typeSolver, null);
}
public static JavaDeclName getQualifiedDeclName(Declaration decl, TypeSolver typeSolver, ArrayList<BodyDeclaration> ignoredContexts)
{
JavaSymbolSolverDeclNameResolver resolver = new JavaSymbolSolverDeclNameResolver(typeSolver, ignoredContexts);
return resolver.getQualifiedDeclName(decl);
}
public JavaDeclName getQualifiedDeclName(Declaration decl)
{
JavaDeclName declName = null;
if (decl != null)
{
if (decl instanceof TypeDeclaration)
{
TypeDeclaration typeDecl = (TypeDeclaration)decl;
ClassOrInterfaceDeclaration javaparserDecl = null;
if (typeDecl instanceof JavaParserClassDeclaration)
{
javaparserDecl = ((JavaParserClassDeclaration)typeDecl).getWrappedNode();
}
else if (typeDecl instanceof JavaParserInterfaceDeclaration)
{
javaparserDecl = ((JavaParserInterfaceDeclaration)typeDecl).getWrappedNode();
}
if (javaparserDecl != null)
{
declName = JavaparserDeclNameResolver.getQualifiedDeclName(javaparserDecl, m_typeSolver, m_ignoredContexts);
}
else
{
declName = JavaDeclName.fromDotSeparatedString(typeDecl.getQualifiedName());
}
}
else if (decl instanceof MethodDeclaration)
{
MethodDeclaration methodDecl = (MethodDeclaration)decl;
if (methodDecl instanceof JavaParserMethodDeclaration)
{
declName = JavaparserDeclNameResolver.getQualifiedDeclName(
((JavaParserMethodDeclaration)methodDecl).getWrappedNode(),
m_typeSolver,
m_ignoredContexts
);
}
else
{
// TODO: what about endless recursion regarding type parameters and return type??
List<JavaTypeName> parameterNames = new ArrayList<>();
for (int i = 0; i < methodDecl.getNumberOfParams(); i++)
{
parameterNames.add(JavaSymbolSolverTypeNameResolver.getQualifiedTypeName(
methodDecl.getParam(i).getType(), m_typeSolver, m_ignoredContexts
));
}
declName = new JavaDeclName(
methodDecl.getName(),
getTypeParameterNames(methodDecl.getTypeParameters()),
JavaSymbolSolverTypeNameResolver.getQualifiedTypeName(methodDecl.getReturnType(), m_typeSolver, m_ignoredContexts),
parameterNames
);
declName.setParent(
getQualifiedDeclName(methodDecl.declaringType(), m_typeSolver, m_ignoredContexts)
);
}
}
}
return declName;
}
private static List<String> getTypeParameterNames(List<TypeParameterDeclaration> 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).getName());
}
}
return typeParameterNames;
}
}
@@ -0,0 +1,121 @@
package com.sourcetrail;
import java.util.ArrayList;
import java.util.Optional;
import com.github.javaparser.ast.Node;
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;
public class JavaSymbolSolverTypeNameResolver extends JavaNameResolver
{
public JavaSymbolSolverTypeNameResolver(TypeSolver typeSolver, ArrayList<BodyDeclaration> ignoredContexts)
{
super(typeSolver, ignoredContexts);
}
public static JavaTypeName getQualifiedTypeName(Type type, TypeSolver typeSolver)
{
return getQualifiedTypeName(type, typeSolver, null);
}
public static JavaTypeName getQualifiedTypeName(Type type, TypeSolver typeSolver, ArrayList<BodyDeclaration> ignoredContexts)
{
JavaSymbolSolverTypeNameResolver resolver = new JavaSymbolSolverTypeNameResolver(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_typeSolver,
m_ignoredContexts
);
return new JavaTypeName(declName.getName() + declName.getTypeParameterString(), new ArrayList<JavaTypeName>(), declName.getParent());
/*
if (declName != null)
{
List<JavaTypeName> typeArgumentNames = new ArrayList<>();
for (TypeUsage typeArgument: refTypeUsage.parameters()) // don't know why this method is called "parameters()"
{
typeArgumentNames.add(getQualifiedTypeName(typeArgument, m_typeSolver, m_ignoredContexts));
}
return new JavaTypeName(declName.getName(), typeArgumentNames, declName.getParent());
}
*/
}
else if (type instanceof TypeVariable)
{
TypeParameterDeclaration typeParam = ((TypeVariable)type).asTypeParameter();
if (typeParam instanceof JavaParserTypeParameter)
{
com.github.javaparser.ast.type.TypeParameter jpTypeParameter = ((JavaParserTypeParameter)typeParam).getWrappedNode();
Optional<BodyDeclaration> genericDecl = jpTypeParameter.getAncestorOfType(BodyDeclaration.class);
if (genericDecl.isPresent())
{
JavaDeclName genericName = null;
if (!ignoresContext(genericDecl.get()))
{
genericName = JavaparserDeclNameResolver.getQualifiedDeclName(genericDecl.get(), m_typeSolver, m_ignoredContexts);
}
return new JavaTypeName(jpTypeParameter.getName().getId(), genericName);
}
}
else
{
// do we need to handle using type parameters of external code? YES! so: TODO: do this!
}
}
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 new JavaTypeName("unresolved-type", null);
}
}
@@ -0,0 +1,100 @@
package com.sourcetrail;
import java.util.List;
public class JavaTypeName
{
private JavaDeclName m_parent = null;
private String m_name = "";
private List<JavaTypeName> m_typeArgumentNames = null;
public static JavaTypeName fromDotSeparatedString(String s)
{
JavaTypeName typeName = null;
int separatorIndex = s.lastIndexOf('.');
if (separatorIndex != -1)
{
typeName = new JavaTypeName(s.substring(separatorIndex + 1), JavaDeclName.fromDotSeparatedString(s.substring(0, separatorIndex)));
}
else
{
typeName = new JavaTypeName(s, null);
}
return typeName;
}
public JavaTypeName(String name, JavaDeclName parent)
{
m_parent = parent;
m_name = name;
}
public JavaTypeName(String name, List<JavaTypeName> typeArgumentNames, JavaDeclName parent)
{
m_parent = parent;
m_name = name;
m_typeArgumentNames = typeArgumentNames;
}
public JavaDeclName getParent()
{
return m_parent;
}
public String getName()
{
return m_name;
}
public String toSerializedNameHierarchy()
{
String nameHierarchy = ".\tm";
if (m_parent != null)
{
nameHierarchy = m_parent.toSerializedNameHierarchy();
nameHierarchy += "\tn";
}
nameHierarchy += m_name;
nameHierarchy += getTypeArgumentString();
nameHierarchy += "\ts\tp";
return nameHierarchy;
}
public String toString()
{
String string = "";
if (m_parent != null)
{
string = m_parent.toString();
string += ".";
}
string += m_name;
string += getTypeArgumentString();
return string;
}
private String getTypeArgumentString()
{
String string = "";
if (m_typeArgumentNames != null && !m_typeArgumentNames.isEmpty())
{
string += "<";
for (int i = 0; i < m_typeArgumentNames.size(); i++)
{
if (i != 0)
{
string += ", ";
}
string += m_typeArgumentNames.get(i).toString();
}
string += ">";
}
return string;
}
}
@@ -0,0 +1,254 @@
package com.sourcetrail;
import java.util.ArrayList;
import java.util.List;
import java.util.Optional;
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.EmptyMemberDeclaration;
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.type.TypeParameter;
import com.github.javaparser.symbolsolver.model.resolution.TypeSolver;
public class JavaparserDeclNameResolver extends JavaNameResolver
{
public JavaparserDeclNameResolver(TypeSolver typeSolver, ArrayList<BodyDeclaration> ignoredContexts)
{
super(typeSolver, ignoredContexts);
}
public static JavaDeclName getQualifiedDeclName(VariableDeclarator decl, TypeSolver typeSolver)
{
return getQualifiedDeclName(decl, typeSolver, null);
}
public static JavaDeclName getQualifiedDeclName(VariableDeclarator decl, TypeSolver typeSolver, ArrayList<BodyDeclaration> ignoredContexts)
{
JavaparserDeclNameResolver resolver = new JavaparserDeclNameResolver(typeSolver, ignoredContexts);
return resolver.getQualifiedDeclName(decl);
}
public JavaDeclName getQualifiedDeclName(VariableDeclarator decl)
{
JavaDeclName declName = null;
if (decl != null)
{
declName = getDeclName(decl);
BodyDeclaration declContext = getBodyDeclContext(decl);
if (declContext != null)
{
if (!ignoresContext(declContext))
{
declName.setParent(getQualifiedDeclName(declContext));
}
}
else
{
Optional<CompilationUnit> compilationUnit = decl.getAncestorOfType(CompilationUnit.class);
if (compilationUnit.isPresent())
{
Optional<PackageDeclaration> packageDecl = compilationUnit.get().getPackageDeclaration();
if (packageDecl.isPresent())
{
declName.setParent(getQualifiedName(packageDecl.get().getName()));
}
}
else
{
throw new UnsupportedOperationException();
}
}
}
return declName;
}
public static JavaDeclName getQualifiedDeclName(BodyDeclaration decl, TypeSolver typeSolver)
{
return getQualifiedDeclName(decl, typeSolver, null);
}
public static JavaDeclName getQualifiedDeclName(BodyDeclaration decl, TypeSolver typeSolver, ArrayList<BodyDeclaration> ignoredContexts)
{
JavaparserDeclNameResolver resolver = new JavaparserDeclNameResolver(typeSolver, ignoredContexts);
return resolver.getQualifiedDeclName(decl);
}
public JavaDeclName getQualifiedDeclName(BodyDeclaration<?> decl)
{
JavaDeclName declName = null;
if (decl != null)
{
declName = getDeclName(decl);
BodyDeclaration declContext = getBodyDeclContext(decl);
if (declContext != null)
{
if (!ignoresContext(declContext))
{
declName.setParent(getQualifiedDeclName(declContext));
}
}
else
{
Optional<CompilationUnit> compilationUnit = decl.getAncestorOfType(CompilationUnit.class);
if (compilationUnit.isPresent())
{
Optional<PackageDeclaration> packageDecl = compilationUnit.get().getPackageDeclaration();
if (packageDecl.isPresent())
{
declName.setParent(getQualifiedName(packageDecl.get().getName()));
}
}
else
{
throw new UnsupportedOperationException();
}
}
}
return declName;
}
public JavaDeclName getDeclName(VariableDeclarator decl)
{
return new JavaDeclName(decl.getNameAsString());
}
public JavaDeclName getDeclName(BodyDeclaration decl)
{
JavaDeclName declName = null;
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 EmptyMemberDeclaration)
{
declName = new JavaDeclName("EmptyMemberDeclaration");
}
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;
}
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 <T extends CallableDecl> JavaDeclName getDeclNameOfCallable(T decl)
{
ArrayList<BodyDeclaration> ignoredContextsForTypes = new ArrayList<BodyDeclaration>(m_ignoredContexts);
ignoredContextsForTypes.add(decl.getWrappedNode()); // adding own decl
String name = decl.getName();
List<String> typeParameterNames = getTypeParameterNames(decl.getTypeParameters());
JavaTypeName returnTypeName = JavaparserTypeNameResolver.getQualifiedTypeName(decl.getType(), m_typeSolver, ignoredContextsForTypes);
List<JavaTypeName> parameterNames = new ArrayList<>();
for (Parameter parameter: decl.getParameters())
{
parameterNames.add(JavaparserTypeNameResolver.getQualifiedTypeName(parameter.getType(), m_typeSolver, ignoredContextsForTypes));
}
return new JavaDeclName(name, typeParameterNames, returnTypeName, parameterNames);
}
private static BodyDeclaration getBodyDeclContext(Node decl)
{
BodyDeclaration context = null;
Optional<Node> parentNode = decl.getParentNode();
while (
parentNode.isPresent() &&
!(
parentNode.get() instanceof BodyDeclaration &&
(!(parentNode.get() instanceof FieldDeclaration))
)
)
{
parentNode = parentNode.get().getParentNode();
}
if (parentNode.isPresent())
{
context = (BodyDeclaration)parentNode.get();
}
return context;
}
}
@@ -0,0 +1,98 @@
package com.sourcetrail;
import java.util.ArrayList;
import com.github.javaparser.ast.body.BodyDeclaration;
import com.github.javaparser.ast.type.*;
import com.github.javaparser.symbolsolver.javaparsermodel.JavaParserFacade;
import com.github.javaparser.symbolsolver.model.resolution.TypeSolver;
public class JavaparserTypeNameResolver extends JavaNameResolver
{
public JavaparserTypeNameResolver(TypeSolver typeSolver, ArrayList<BodyDeclaration> ignoredContexts)
{
super(typeSolver, ignoredContexts);
}
public static JavaTypeName getQualifiedTypeName(Type type, TypeSolver typeSolver)
{
return getQualifiedTypeName(type, typeSolver, null);
}
public static JavaTypeName getQualifiedTypeName(Type type, TypeSolver typeSolver, ArrayList<BodyDeclaration> ignoredContexts)
{
JavaparserTypeNameResolver resolver = new JavaparserTypeNameResolver(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_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_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 new JavaTypeName("unresolved-type", null);
}
}
@@ -0,0 +1,31 @@
package com.sourcetrail;
public enum ReferenceKind
{ // these values need to be the same as ReferenceKind in C++ code
UNDEFINED(0),
TYPE_USAGE(1),
USAGE(2),
CALL(3),
INHERITANCE(4),
OVERRIDE(5),
TEMPLATE_ARGUMENT(6),
TYPE_ARGUMENT(7),
TEMPLATE_DEFAULT_ARGUMENT(8),
TEMPLATE_SPECIALIZATION_OF(9),
TEMPLATE_MEMBER_SPECIALIZATION_OF(10),
INCLUDE(11),
IMPORT(12),
MACRO_USAGE(13);
private final int m_value;
private ReferenceKind(int value)
{
this.m_value = value;
}
public int getValue()
{
return m_value;
}
}
@@ -0,0 +1,37 @@
package com.sourcetrail;
public enum SymbolKind
{ // these values need to be the same as SymbolKind in C++ code
BUILTIN_TYPE(1),
CLASS(2),
ENUM(3),
ENUM_CONSTANT(4),
FIELD(5),
FUNCTION(6),
GLOBAL_VARIABLE(7),
INTERFACE(8),
LOCAL_VARIABLE(9),
MACRO(10),
METHOD(11),
NAMESPACE(12),
PACKAGE(13),
PARAMETER(14),
STRUCT(15),
TEMPLATE_PARAMETER(16),
TYPEDEF(17),
TYPE_PARAMETER(18),
UNION(19),
TYPE_MAX(20);
private final int m_value;
private SymbolKind(int value)
{
this.m_value = value;
}
public int getValue()
{
return m_value;
}
}
@@ -0,0 +1,226 @@
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 void visit(CompilationUnit n, Void v) { dump(n); indent++; super.visit(n, v); indent--; }
public void visit(PackageDeclaration n, Void v) { dump(n); indent++; super.visit(n, v); indent--; }
public void visit(ImportDeclaration n, Void v) { dump(n); indent++; super.visit(n, v); indent--; }
public void visit(TypeParameter n, Void v) { dump(n); indent++; super.visit(n, v); indent--; }
public void visit(LineComment n, Void v) { dump(n); indent++; super.visit(n, v); indent--; }
public void visit(BlockComment n, Void v) { dump(n); indent++; super.visit(n, v); indent--; }
//- Body ----------------------------------------------
public void visit(ClassOrInterfaceDeclaration n, Void v) { dump(n); indent++; super.visit(n, v); indent--; }
public void visit(EnumDeclaration n, Void v) { dump(n); indent++; super.visit(n, v); indent--; }
public void visit(EnumConstantDeclaration n, Void v) { dump(n); indent++; super.visit(n, v); indent--; }
public void visit(AnnotationDeclaration n, Void v) { dump(n); indent++; super.visit(n, v); indent--; }
public void visit(AnnotationMemberDeclaration n, Void v) { dump(n); indent++; super.visit(n, v); indent--; }
public void visit(FieldDeclaration n, Void v) { dump(n); indent++; super.visit(n, v); indent--; }
public void visit(VariableDeclarator n, Void v) { dump(n); indent++; super.visit(n, v); indent--; }
public void visit(ConstructorDeclaration n, Void v) { dump(n); indent++; super.visit(n, v); indent--; }
public void visit(MethodDeclaration n, Void v) { dump(n); indent++; super.visit(n, v); indent--; }
public void visit(Parameter n, Void v) { dump(n); indent++; super.visit(n, v); indent--; }
public void visit(EmptyMemberDeclaration n, Void v) { dump(n); indent++; super.visit(n, v); indent--; }
public void visit(InitializerDeclaration n, Void v) { dump(n); indent++; super.visit(n, v); indent--; }
public void visit(JavadocComment n, Void v) { dump(n); indent++; super.visit(n, v); indent--; }
//- Type ----------------------------------------------
public void visit(ClassOrInterfaceType n, Void v) { dump(n); indent++; super.visit(n, v); indent--; }
public void visit(PrimitiveType n, Void v) { dump(n); indent++; super.visit(n, v); indent--; }
public void visit(ArrayType n, Void v) { dump(n); indent++; super.visit(n, v); indent--; }
public void visit(ArrayCreationLevel n, Void v) { dump(n); indent++; super.visit(n, v); indent--; }
public void visit(IntersectionType n, Void v) { dump(n); indent++; super.visit(n, v); indent--; }
public void visit(UnionType n, Void v) { dump(n); indent++; super.visit(n, v); indent--; }
public void visit(VoidType n, Void v) { dump(n); indent++; super.visit(n, v); indent--; }
public void visit(WildcardType n, Void v) { dump(n); indent++; super.visit(n, v); indent--; }
public void visit(UnknownType n, Void v) { dump(n); indent++; super.visit(n, v); indent--; }
//- Expression ----------------------------------------
public void visit(ArrayAccessExpr n, Void v) { dump(n); indent++; super.visit(n, v); indent--; }
public void visit(ArrayCreationExpr n, Void v) { dump(n); indent++; super.visit(n, v); indent--; }
public void visit(ArrayInitializerExpr n, Void v) { dump(n); indent++; super.visit(n, v); indent--; }
public void visit(AssignExpr n, Void v) { dump(n); indent++; super.visit(n, v); indent--; }
public void visit(BinaryExpr n, Void v) { dump(n); indent++; super.visit(n, v); indent--; }
public void visit(CastExpr n, Void v) { dump(n); indent++; super.visit(n, v); indent--; }
public void visit(ClassExpr n, Void v) { dump(n); indent++; super.visit(n, v); indent--; }
public void visit(ConditionalExpr n, Void v) { dump(n); indent++; super.visit(n, v); indent--; }
public void visit(EnclosedExpr n, Void v) { dump(n); indent++; super.visit(n, v); indent--; }
public void visit(FieldAccessExpr n, Void v) { dump(n); indent++; super.visit(n, v); indent--; }
public void visit(InstanceOfExpr n, Void v) { dump(n); indent++; super.visit(n, v); indent--; }
public void visit(StringLiteralExpr n, Void v) { dump(n); indent++; super.visit(n, v); indent--; }
public void visit(IntegerLiteralExpr n, Void v) { dump(n); indent++; super.visit(n, v); indent--; }
public void visit(LongLiteralExpr n, Void v) { dump(n); indent++; super.visit(n, v); indent--; }
public void visit(CharLiteralExpr n, Void v) { dump(n); indent++; super.visit(n, v); indent--; }
public void visit(DoubleLiteralExpr n, Void v) { dump(n); indent++; super.visit(n, v); indent--; }
public void visit(BooleanLiteralExpr n, Void v) { dump(n); indent++; super.visit(n, v); indent--; }
public void visit(NullLiteralExpr n, Void v) { dump(n); indent++; super.visit(n, v); indent--; }
public void visit(MethodCallExpr n, Void v) { dump(n); indent++; super.visit(n, v); indent--; }
public void visit(NameExpr n, Void v) { dump(n); indent++; super.visit(n, v); indent--; }
public void visit(ObjectCreationExpr n, Void v) { dump(n); indent++; super.visit(n, v); indent--; }
public void visit(ThisExpr n, Void v) { dump(n); indent++; super.visit(n, v); indent--; }
public void visit(SuperExpr n, Void v) { dump(n); indent++; super.visit(n, v); indent--; }
public void visit(UnaryExpr n, Void v) { dump(n); indent++; super.visit(n, v); indent--; }
public void visit(VariableDeclarationExpr n, Void v) { dump(n); indent++; super.visit(n, v); indent--; }
public void visit(MarkerAnnotationExpr n, Void v) { dump(n); indent++; super.visit(n, v); indent--; }
public void visit(SingleMemberAnnotationExpr n, Void v) { dump(n); indent++; super.visit(n, v); indent--; }
public void visit(NormalAnnotationExpr n, Void v) { dump(n); indent++; super.visit(n, v); indent--; }
public void visit(MemberValuePair n, Void v) { dump(n); indent++; super.visit(n, v); indent--; }
//- Statements ----------------------------------------
public void visit(ExplicitConstructorInvocationStmt n, Void v) { dump(n); indent++; super.visit(n, v); indent--; }
public void visit(AssertStmt n, Void v) { dump(n); indent++; super.visit(n, v); indent--; }
public void visit(BlockStmt n, Void v) { dump(n); indent++; super.visit(n, v); indent--; }
public void visit(LabeledStmt n, Void v) { dump(n); indent++; super.visit(n, v); indent--; }
public void visit(EmptyStmt n, Void v) { dump(n); indent++; super.visit(n, v); indent--; }
public void visit(ExpressionStmt n, Void v) { dump(n); indent++; super.visit(n, v); indent--; }
public void visit(SwitchStmt n, Void v) { dump(n); indent++; super.visit(n, v); indent--; }
public void visit(SwitchEntryStmt n, Void v) { dump(n); indent++; super.visit(n, v); indent--; }
public void visit(BreakStmt n, Void v) { dump(n); indent++; super.visit(n, v); indent--; }
public void visit(ReturnStmt n, Void v) { dump(n); indent++; super.visit(n, v); indent--; }
public void visit(IfStmt n, Void v) { dump(n); indent++; super.visit(n, v); indent--; }
public void visit(WhileStmt n, Void v) { dump(n); indent++; super.visit(n, v); indent--; }
public void visit(ContinueStmt n, Void v) { dump(n); indent++; super.visit(n, v); indent--; }
public void visit(DoStmt n, Void v) { dump(n); indent++; super.visit(n, v); indent--; }
public void visit(ForeachStmt n, Void v) { dump(n); indent++; super.visit(n, v); indent--; }
public void visit(ForStmt n, Void v) { dump(n); indent++; super.visit(n, v); indent--; }
public void visit(ThrowStmt n, Void v) { dump(n); indent++; super.visit(n, v); indent--; }
public void visit(SynchronizedStmt n, Void v) { dump(n); indent++; super.visit(n, v); indent--; }
public void visit(TryStmt n, Void v) { dump(n); indent++; super.visit(n, v); indent--; }
public void visit(CatchClause n, Void v) { dump(n); indent++; super.visit(n, v); indent--; }
public void visit(LambdaExpr n, Void v) { dump(n); indent++; super.visit(n, v); indent--; }
public void visit(MethodReferenceExpr n, Void v) { dump(n); indent++; super.visit(n, v); indent--; }
public void visit(TypeExpr n, Void v) { dump(n); indent++; super.visit(n, v); indent--; }
}