build: renaming to sourcetrail

This commit is contained in:
Andreas Stallinger
2017-04-07 13:19:09 +02:00
parent 8391a6da57
commit 045a259b2e
224 changed files with 885 additions and 4271 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,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,61 @@
package com.sourcetrail;
import javax.management.MBeanServer;
import java.lang.management.ManagementFactory;
import com.sun.management.HotSpotDiagnosticMXBean;
public class HeapDumper {
// This is the name of the HotSpot Diagnostic MBean
private static final String HOTSPOT_BEAN_NAME =
"com.sun.management:type=HotSpotDiagnostic";
// field to store the hotspot diagnostic MBean
private static volatile HotSpotDiagnosticMXBean hotspotMBean;
/*\*
\* Call this method from your application whenever you
\* want to dump the heap snapshot into a file.
\*
\* @param fileName name of the heap dump file
\* @param live flag that tells whether to dump
\* only the live objects
\*/
static void dumpHeap(String fileName, boolean live) {
// initialize hotspot diagnostic MBean
initHotspotMBean();
try {
hotspotMBean.dumpHeap(fileName, live);
} catch (RuntimeException re) {
throw re;
} catch (Exception exp) {
throw new RuntimeException(exp);
}
}
// initialize the hotspot diagnostic MBean field
private static void initHotspotMBean() {
if (hotspotMBean == null) {
synchronized (HeapDumper.class) {
if (hotspotMBean == null) {
hotspotMBean = getHotspotMBean();
}
}
}
}
// get the hotspot diagnostic MBean from the
// platform MBean server
private static HotSpotDiagnosticMXBean getHotspotMBean() {
try {
MBeanServer server = ManagementFactory.getPlatformMBeanServer();
HotSpotDiagnosticMXBean bean =
ManagementFactory.newPlatformMXBeanProxy(server,
HOTSPOT_BEAN_NAME, HotSpotDiagnosticMXBean.class);
return bean;
} catch (RuntimeException re) {
throw re;
} catch (Exception exp) {
throw new RuntimeException(exp);
}
}
}
@@ -0,0 +1,972 @@
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.methods.MethodUsage;
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 JavaAstVisitor extends JavaAstVisitorAdapter
{
protected int m_callbackId = -1;
private String m_filePath;
private FileContent m_fileContent;
private TypeSolver m_typeSolver;
private List<DeclContext> m_context = new ArrayList<DeclContext>();
public JavaAstVisitor(int callbackId, String filePath, FileContent fileContent, TypeSolver typeSolver)
{
m_callbackId = callbackId;
m_filePath = filePath;
m_fileContent = fileContent;
m_typeSolver = typeSolver;
m_context.add(new DeclContext(filePath + "\ts\tp"));
}
// --- record declarations ---
@Override public void visit(final PackageDeclaration n, final Void v)
{
Name name = n.getName();
JavaIndexer.recordSymbolWithLocationAndScope(
m_callbackId,
JavaparserDeclNameResolver.getQualifiedName(name).toSerializedNameHierarchy(),
SymbolKind.PACKAGE,
name.getRange(),
n.getRange(),
AccessKind.NONE,
DefinitionKind.EXPLICIT
);
while (name.getQualifier().isPresent())
{
name = name.getQualifier().get();
JavaIndexer.recordSymbol(
m_callbackId,
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();
JavaIndexer.recordSymbolWithLocationAndScope(
m_callbackId, 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
));
}
JavaIndexer.recordSymbolWithLocation(
m_callbackId, 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();
JavaIndexer.recordSymbolWithLocationAndScope(
m_callbackId, 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();
JavaIndexer.recordSymbolWithLocation(
m_callbackId, 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();
JavaIndexer.recordSymbolWithLocationAndScope(
m_callbackId, 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();
JavaIndexer.recordSymbolWithLocationAndScope(
m_callbackId, 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();
JavaIndexer.recordReference(
m_callbackId, 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();
JavaIndexer.recordSymbolWithLocation(
m_callbackId, 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 + ">";
JavaIndexer.recordLocalSymbol(
m_callbackId, 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 + ">";
JavaIndexer.recordLocalSymbol(
m_callbackId, 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() || !n.isStatic())
{
String importedName = JavaparserDeclNameResolver.getQualifiedName(name).toSerializedNameHierarchy();
for (DeclContext context: m_context)
{
JavaIndexer.recordReference(
m_callbackId, ReferenceKind.IMPORT,
importedName, context.getName(),
name.getRange()
);
}
}
else
{
try
{
String typeName = name.getQualifier().get().asString();
String memberName = name.getIdentifier();
List<JavaDeclName> importedDeclNames = new ArrayList<>();
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)
{
JavaIndexer.recordReference(
m_callbackId, ReferenceKind.IMPORT,
nameHierarchy, context.getName(),
n.getRange()
);
}
}
}
else
{
JavaIndexer.recordError(
m_callbackId, "Import not found.", 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
));
}
}
JavaIndexer.recordReference(
m_callbackId, 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();
JavaIndexer.recordSymbol(
m_callbackId, referencedName, SymbolKind.BUILTIN_TYPE,
AccessKind.NONE,
DefinitionKind.EXPLICIT
);
for (DeclContext context: m_context)
{
JavaIndexer.recordReference(
m_callbackId, 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();
JavaIndexer.recordSymbol(
m_callbackId, referencedName, SymbolKind.BUILTIN_TYPE,
AccessKind.NONE,
DefinitionKind.EXPLICIT
);
for (DeclContext context: m_context)
{
JavaIndexer.recordReference(
m_callbackId, 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)
{
JavaIndexer.recordReference(
m_callbackId, 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)
{
JavaIndexer.recordReference(
m_callbackId, 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 + ">";
JavaIndexer.recordLocalSymbol(
m_callbackId, 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)
{
JavaIndexer.recordReference(
m_callbackId, 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 + ">";
JavaIndexer.recordLocalSymbol(
m_callbackId, 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)
{
JavaIndexer.recordReference(
m_callbackId, 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 + "";
}
JavaIndexer.logError(m_callbackId, e + " at " + m_filePath + "<"+ beginLine + ", " + beginColumn + ">");
JavaIndexer.recordSymbolWithLocation(
m_callbackId, "unsolved-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)
{
JavaIndexer.recordReference(
m_callbackId, 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 = 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 = 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 + ">";
JavaIndexer.recordLocalSymbol(m_callbackId, qualifiedName, range.begin.line, range.begin.column, range.begin.line, range.begin.column);
JavaIndexer.recordLocalSymbol(m_callbackId, qualifiedName, range.end.line, range.end.column, range.end.line, range.end.column);
}
@Override public void visit(final LineComment n, final Void v)
{
JavaIndexer.recordComment(
m_callbackId,
n.getRange()
);
super.visit(n, v);
}
@Override public void visit(final BlockComment n, final Void v)
{
JavaIndexer.recordComment(
m_callbackId,
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 JavaAstVisitorAdapter 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,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 = "";
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,318 @@
package com.sourcetrail;
import java.io.File;
import java.io.IOException;
import java.io.StringReader;
import java.lang.String;
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.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
{
public static void processFile(int address, String filePath, String fileContent, String classPath, int verbose)
{
logInfo(address, "indexing source file: " + filePath);
try
{
CombinedTypeSolver typeSolver = new CombinedTypeSolver();
typeSolver.add(new ReflectionTypeSolver());
for (String path: classPath.split("\\;"))
{
if (path.endsWith(".jar"))
{
try
{
JarTypeSolver solver = new JarTypeSolver(path);
typeSolver.add(solver);
}
catch (IOException e)
{
System.out.println("unable to add jar file: " + path);
}
}
else if (!path.isEmpty())
{
JavaParserTypeSolver solver = new JavaParserTypeSolver(new File(path));
typeSolver.add(solver);
}
}
CompilationUnit cu = JavaParser.parse(new StringReader(fileContent));
JavaAstVisitor astVisitor = (
verbose == 1 ?
new JavaVerboseAstVisitor(address, filePath, new FileContent(fileContent), typeSolver) :
new JavaAstVisitor(address, filePath, new FileContent(fileContent), typeSolver)
);
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(")")
));
recordError(
address, "Encountered unexpected token.", true, true,
Range.range(startLine, startColumn, startLine, startColumn)
);
}
else
{
Optional<Range> range = problem.getRange();
if (range.isPresent())
{
recordError(
address, problem.toString(), true, true,
range.get()
);
}
}
}
}
JavaParserFacade.clearInstances();
}
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;
}
// helpers
static public void recordSymbol(
int address, String symbolName, SymbolKind symbolType,
AccessKind access, DefinitionKind definitionKind
)
{
recordSymbol(
address, symbolName, symbolType.getValue(),
access.getValue(), definitionKind.getValue()
);
}
static public void recordSymbolWithLocation(
int address, String symbolName, SymbolKind symbolType,
Optional<Range> range,
AccessKind access, DefinitionKind definitionKind
)
{
recordSymbolWithLocation(
address, symbolName, symbolType,
range.orElse(Range.range(0, 0, 0, 0)),
access, definitionKind
);
}
static public void recordSymbolWithLocation(
int address, String symbolName, SymbolKind symbolType,
Range range,
AccessKind access, DefinitionKind definitionKind
)
{
recordSymbolWithLocation(
address, symbolName, symbolType.getValue(),
range.begin.line, range.begin.column, range.end.line, range.end.column,
access.getValue(), definitionKind.getValue()
);
}
static public void recordSymbolWithLocationAndScope(
int address, String symbolName, SymbolKind symbolType,
Optional<Range> range,
Optional<Range> scopeRange,
AccessKind access, DefinitionKind definitionKind
)
{
recordSymbolWithLocationAndScope(
address, symbolName, symbolType,
range.orElse(Range.range(0, 0, 0, 0)),
scopeRange.orElse(Range.range(0, 0, 0, 0)),
access, definitionKind
);
}
static public void recordSymbolWithLocationAndScope(
int address, String symbolName, SymbolKind symbolType,
Range range,
Range scopeRange,
AccessKind access, DefinitionKind definitionKind
)
{
recordSymbolWithLocationAndScope(
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()
);
}
static public void recordReference(
int address, ReferenceKind referenceKind, String referencedName, String contextName,
Optional<Range> range
)
{
recordReference(
address, referenceKind, referencedName, contextName,
range.orElse(Range.range(0, 0, 0, 0))
);
}
static public void recordReference(
int address, ReferenceKind referenceKind, String referencedName, String contextName,
Range range
)
{
recordReference(
address, referenceKind.getValue(), referencedName, contextName,
range.begin.line, range.begin.column, range.end.line, range.end.column
);
}
static public void recordLocalSymbol(
int address, String symbolName,
Optional<Range> range
)
{
recordLocalSymbol(address, symbolName, range.orElse(Range.range(0, 0, 0, 0)));
}
static public void recordLocalSymbol(
int address, String symbolName,
Range range
)
{
recordLocalSymbol(
address, symbolName,
range.begin.line, range.begin.column, range.end.line, range.end.column
);
}
static public void recordComment(
int address,
Optional<Range> range
)
{
recordComment(address, range.orElse(Range.range(0, 0, 0, 0)));
}
static public void recordComment(
int address,
Range range
)
{
recordComment(
address,
range.begin.line, range.begin.column, range.end.line, range.end.column
);
}
static public void recordError(
int address, String message, boolean fatal, boolean indexed,
Optional<Range> range
)
{
recordError(
address, message, fatal, indexed,
range.orElse(Range.range(0, 0, 0, 0))
);
}
static public void recordError(
int address, String message, boolean fatal, boolean indexed,
Range range
)
{
recordError(
address, message, (fatal ? 1 : 0), (indexed ? 1 : 0),
range.begin.line, range.begin.column, range.end.line, range.end.column
);
}
// 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 private native void recordSymbol(
int address, String symbolName, int symbolType,
int access, int definitionKind
);
static private native void recordSymbolWithLocation(
int address, String symbolName, int symbolType,
int beginLine, int beginColumn, int endLine, int endColumn,
int access, int definitionKind
);
static private 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 private 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 private native void recordError(
int address, String message, int fatal, int indexed, int beginLine, int beginColumn, int endLine, int endColumn
);
}
@@ -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 = "";
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,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 JavaVerboseAstVisitor extends JavaAstVisitor{
public JavaVerboseAstVisitor(int callbackId, String filePath, FileContent fileContent, TypeSolver typeSolver) {
super(callbackId, 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;
}
JavaIndexer.logInfo(m_callbackId, 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--; }
}
@@ -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;
}
}