data: indexing java

* expanded appsettings to include java specific stuff
* added java indexer as separate project that can be build via its build script
* added dependencies for java indexer to the setup folder
* added license files for these dependencies.
* added sample project for java. this is just to test java on other machines and can be removed again in the future.
* the java parser test suite is currently uncommented because java is not running on every machine.
* added some more node types
* removed TokenComponentAccess::AccessType and replaced all its usages by using AccessKind
* moved access components from edges to nodes
* using recordReference of ParserClient for java
* removed recording access specifier of inheritance edges.
* added styles for new node types
This commit is contained in:
malte_langkabel
2016-08-04 09:20:13 +02:00
parent 05c06a6102
commit b072972b50
122 changed files with 7291 additions and 696 deletions
+50
View File
@@ -0,0 +1,50 @@
#!/bin/bash
# prerequirements: java/bin in path
ABORT="\033[31mAbort:\033[00m"
SUCCESS="\033[32mSuccess:\033[00m"
INFO="\033[33mInfo:\033[00m"
# Determine current platform
PLATFORM='unknown'
if [ "$(uname)" == "Darwin" ]; then
PLATFORM='MacOS'
elif [ "$(expr substr $(uname -s) 1 5)" == "Linux" ]; then
PLATFORM='Linux'
elif [ "$(expr substr $(uname -s) 1 10)" == "MINGW32_NT" ]; then
PLATFORM='Windows'
fi
if [ $PLATFORM == "Windows" ]; then
ORIGINAL_PATH_TO_SCRIPT="${0}"
CLEANED_PATH_TO_SCRIPT="${ORIGINAL_PATH_TO_SCRIPT//\\//}"
ROOT_DIR=`dirname "$CLEANED_PATH_TO_SCRIPT"`
else
ROOT_DIR="$( cd "$( dirname "$0" )" && pwd )"
fi
ROOT_DIR=$ROOT_DIR/..
cd $ROOT_DIR
mkdir -p classes
LIB_DIR="./lib/"
CLASSPATH=""
CLASSPATH+=$LIB_DIR"java-symbol-solver-core-0.2.0-SNAPSHOT.jar;"
CLASSPATH+=$LIB_DIR"java-symbol-solver-logic-0.2.0-SNAPSHOT.jar;"
CLASSPATH+=$LIB_DIR"java-symbol-solver-model-0.2.0-SNAPSHOT.jar;"
CLASSPATH+=$LIB_DIR"javaparser-core-2.4.1-SNAPSHOT.jar;"
javac.exe -d ./classes -classpath $CLASSPATH src/io/coati/*.java
mkdir -p bin
cd classes
jar cvf ../bin/java-indexer.jar io/coati/*.class
cd ..
rm -rf classes
+224
View File
@@ -0,0 +1,224 @@
package io.coati;
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.stmt.*;
import com.github.javaparser.ast.type.*;
import me.tomassetti.symbolsolver.model.resolution.TypeSolver;
public class ASTDumper extends JavaAstVisitor{
public ASTDumper(int callbackId, String filePath, TypeSolver typeSolver) {
super(callbackId, filePath, typeSolver);
}
int indent = 0;
String indentSymbol = "| ";
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 NameExpr)
{
line += " [" + ((NameExpr)n).getName() + "]";
}
else if (n instanceof ClassOrInterfaceType)
{
line += " [" + ((ClassOrInterfaceType)n).getName() + "]";
}
System.out.println(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(EmptyTypeDeclaration 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(VariableDeclaratorId 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(MultiTypeParameter 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(ReferenceType 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(IntegerLiteralMinValueExpr n, Void v) { dump(n); indent++; super.visit(n, v); indent--; }
public void visit(LongLiteralMinValueExpr 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(QualifiedNameExpr 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(TypeDeclarationStmt 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--; }
}
+44
View File
@@ -0,0 +1,44 @@
package io.coati;
import com.github.javaparser.ast.AccessSpecifier;
public enum AccessKind
{ // these values need to be the same as AccesType 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,45 @@
package io.coati;
import java.util.List;
import com.github.javaparser.ast.TypeParameter;
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.getName();
}
public List<TypeParameter> getTypeParameters()
{
return m_decl.getTypeParameters();
}
public List<Parameter> getParameters()
{
return m_decl.getParameters();
}
public Type getType()
{
return new UnknownType();
}
}
@@ -0,0 +1,17 @@
package io.coati;
import java.util.List;
import com.github.javaparser.ast.TypeParameter;
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 List<TypeParameter> getTypeParameters();
public List<Parameter> getParameters();
public Type getType();
}
@@ -0,0 +1,44 @@
package io.coati;
import java.util.List;
import com.github.javaparser.ast.TypeParameter;
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.getName();
}
public List<TypeParameter> getTypeParameters()
{
return m_decl.getTypeParameters();
}
public List<Parameter> getParameters()
{
return m_decl.getParameters();
}
public Type getType()
{
return m_decl.getType();
}
}
@@ -0,0 +1,16 @@
package io.coati;
public class DeclContext
{
private String m_name = null;
public DeclContext(String name)
{
m_name = name;
}
public String getName()
{
return m_name;
}
}
+61
View File
@@ -0,0 +1,61 @@
package io.coati;
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,761 @@
package io.coati;
import java.lang.String;
import java.util.List;
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.ModifierSet;
import com.github.javaparser.ast.body.Parameter;
import com.github.javaparser.ast.body.VariableDeclarator;
import com.github.javaparser.ast.body.VariableDeclaratorId;
import com.github.javaparser.ast.comments.BlockComment;
import com.github.javaparser.ast.comments.LineComment;
import com.github.javaparser.ast.expr.MethodCallExpr;
import com.github.javaparser.ast.expr.NameExpr;
import com.github.javaparser.ast.expr.VariableDeclarationExpr;
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.VoidType;
import com.github.javaparser.ast.ImportDeclaration;
import com.github.javaparser.ast.Node;
import com.github.javaparser.ast.PackageDeclaration;
import com.github.javaparser.ast.TypeParameter;
import me.tomassetti.symbolsolver.javaparsermodel.JavaParserFacade;
import me.tomassetti.symbolsolver.javaparsermodel.UnsolvedSymbolException;
import me.tomassetti.symbolsolver.javaparsermodel.declarations.JavaParserMethodDeclaration;
import me.tomassetti.symbolsolver.javaparsermodel.declarations.JavaParserSymbolDeclaration;
import me.tomassetti.symbolsolver.model.declarations.MethodAmbiguityException;
import me.tomassetti.symbolsolver.model.declarations.TypeDeclaration;
import me.tomassetti.symbolsolver.model.declarations.ValueDeclaration;
import me.tomassetti.symbolsolver.model.invokations.MethodUsage;
import me.tomassetti.symbolsolver.model.resolution.SymbolReference;
import me.tomassetti.symbolsolver.model.resolution.TypeSolver;
import me.tomassetti.symbolsolver.model.typesystem.*;
public class JavaAstVisitor extends JavaAstVisitorAdapter
{
private int m_callbackId = -1;
private String m_filePath;
private TypeSolver m_typeSolver;
private List<DeclContext> m_context = new ArrayList<DeclContext>();
private boolean m_verbose = false;
public JavaAstVisitor(int callbackId, String filePath, TypeSolver typeSolver)
{
m_callbackId = callbackId;
m_filePath = filePath;
m_typeSolver = typeSolver;
String[] filePathParts = filePath.split("/");
String fileName = filePathParts[filePathParts.length - 1];
m_context.add(new DeclContext(fileName + "\t\r"));
}
// --- record declarations ---
@Override public void visit(final PackageDeclaration n, final Void v)
{
NameExpr nameExpr = n.getName();
String packageName = JavaDeclNameResolver.getQualifiedName(nameExpr).toNameHierarchy();
JavaIndexer.recordSymbolWithScope(
m_callbackId, packageName, SymbolType.PACKAGE,
nameExpr.getBeginLine(), nameExpr.getBeginColumn(), nameExpr.getEndLine(), nameExpr.getEndColumn(),
n.getBeginLine(), n.getBeginColumn(), n.getEndLine(), n.getEndColumn(),
AccessKind.NONE, false
);
super.visit(n, v);
}
@Override public void visit(final ClassOrInterfaceDeclaration n, final Void v)
{
NameExpr nameExpr = n.getNameExpr();
String qualifiedName = JavaDeclNameResolver.getQualifiedDeclName(n, m_typeSolver).toNameHierarchy();
JavaIndexer.recordSymbolWithScope(
m_callbackId, qualifiedName, (n.isInterface() ? SymbolType.INTERFACE : SymbolType.CLASS),
nameExpr.getBeginLine(), nameExpr.getBeginColumn(), nameExpr.getEndLine(), nameExpr.getEndColumn(),
n.getBeginLine(), n.getBeginColumn(), n.getEndLine(), n.getEndColumn(),
AccessKind.fromAccessSpecifier(ModifierSet.getAccessSpecifier(n.getModifiers())), false
);
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 += "\n";
qualifiedName += n.getName() + "\t\r";
JavaIndexer.recordSymbol(
m_callbackId, qualifiedName, SymbolType.TYPE_PARAMETER,
n.getBeginLine(), n.getBeginColumn(), n.getBeginLine(), n.getBeginColumn() + n.getName().length() - 1,
AccessKind.TYPE_PARAMETER, false
);
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)
{
NameExpr nameExpr = n.getNameExpr();
String qualifiedName = JavaDeclNameResolver.getQualifiedDeclName(n, m_typeSolver).toNameHierarchy();
JavaIndexer.recordSymbolWithScope(
m_callbackId, qualifiedName, SymbolType.ENUM,
nameExpr.getBeginLine(), nameExpr.getBeginColumn(), nameExpr.getEndLine(), nameExpr.getEndColumn(),
n.getBeginLine(), n.getBeginColumn(), n.getEndLine(), n.getEndColumn(),
AccessKind.fromAccessSpecifier(ModifierSet.getAccessSpecifier(n.getModifiers())), false
);
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 = JavaDeclNameResolver.getQualifiedDeclName(n, m_typeSolver).toNameHierarchy();
JavaIndexer.recordSymbol(
m_callbackId, qualifiedName, SymbolType.ENUM_CONSTANT,
n.getBeginLine(), n.getBeginColumn(), n.getEndLine(), n.getEndColumn(),
AccessKind.NONE, false
);
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)
{
NameExpr nameExpr = n.getNameExpr();
String qualifiedName = JavaDeclNameResolver.getQualifiedDeclName(n, m_typeSolver).toNameHierarchy();
JavaIndexer.recordSymbolWithScope(
m_callbackId, qualifiedName, SymbolType.METHOD,
nameExpr.getBeginLine(), nameExpr.getBeginColumn(), nameExpr.getEndLine(), nameExpr.getEndColumn(),
n.getBeginLine(), n.getBeginColumn(), n.getEndLine(), n.getEndColumn(),
AccessKind.fromAccessSpecifier(ModifierSet.getAccessSpecifier(n.getModifiers())), false
);
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)
{
NameExpr nameExpr = n.getNameExpr();
String qualifiedName = JavaDeclNameResolver.getQualifiedDeclName(n, m_typeSolver).toNameHierarchy();
JavaIndexer.recordSymbolWithScope(
m_callbackId, qualifiedName, SymbolType.METHOD,
nameExpr.getBeginLine(), nameExpr.getBeginColumn(), nameExpr.getEndLine(), nameExpr.getEndColumn(),
n.getBeginLine(), n.getBeginColumn(), n.getEndLine(), n.getEndColumn(),
AccessKind.fromAccessSpecifier(ModifierSet.getAccessSpecifier(n.getModifiers())), false
);
/// test this!
Node parent = n.getParentNode();
me.tomassetti.symbolsolver.model.declarations.MethodDeclaration overridden = getOverridden(n, parent);
if (overridden != null && (overridden instanceof JavaParserMethodDeclaration))
{
String overriddenName = JavaDeclNameResolver.getQualifiedDeclName(((JavaParserMethodDeclaration)overridden).getWrappedNode(), m_typeSolver).toNameHierarchy();
JavaIndexer.recordReference(
m_callbackId, ReferenceKind.OVERRIDE, overriddenName, qualifiedName,
nameExpr.getBeginLine(), nameExpr.getBeginColumn(), nameExpr.getEndLine(), nameExpr.getEndColumn()
);
}
List<DeclContext> parentContext = m_context;
m_context = new ArrayList<DeclContext>();
m_context.add(new DeclContext(qualifiedName));
super.visit(n, v);
m_context = parentContext;
}
private me.tomassetti.symbolsolver.model.declarations.MethodDeclaration getOverridden(MethodDeclaration overrider, Node searchScope)
{
List<ClassOrInterfaceType> ancestors = new ArrayList<>();
if (searchScope instanceof ClassOrInterfaceDeclaration)
{
ancestors.addAll(((ClassOrInterfaceDeclaration)searchScope).getImplements());
ancestors.addAll(((ClassOrInterfaceDeclaration)searchScope).getExtends());
}
if (searchScope instanceof EnumDeclaration)
{
ancestors.addAll(((EnumDeclaration)searchScope).getImplements());
}
if (!ancestors.isEmpty())
{
List<TypeUsage> parameterTypes = new ArrayList<>();
for (Parameter parameter: overrider.getParameters())
{
Type parameterType = parameter.getType();
parameterTypes.add(JavaParserFacade.get(m_typeSolver).convert(parameterType, parameterType));
}
for (ClassOrInterfaceType ancestor: ancestors)
{
try
{
TypeUsage ancestorTypeUsage = JavaParserFacade.get(m_typeSolver).convert(ancestor, ancestor);
if (ancestorTypeUsage.isReferenceType())
{
SymbolReference<me.tomassetti.symbolsolver.model.declarations.MethodDeclaration> solvedMethod = ancestorTypeUsage.asReferenceTypeUsage().solveMethod(overrider.getName(), parameterTypes);
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.
}
}
}
return null;
}
@Override public void visit(final FieldDeclaration n, final Void v)
{
List<DeclContext> parentContext = m_context;
m_context = new ArrayList<DeclContext>();
List<VariableDeclarator> variableDeclarators = n.getVariables();
for (int i = 0; i < variableDeclarators.size(); i++)
{
VariableDeclarator varDecl = variableDeclarators.get(i);
String qualifiedName = JavaDeclNameResolver.getQualifiedDeclName(varDecl, m_typeSolver).toNameHierarchy();
VariableDeclaratorId varDeclId = varDecl.getId();
JavaIndexer.recordSymbol(
m_callbackId, qualifiedName, SymbolType.FIELD,
varDeclId.getBeginLine(), varDeclId.getBeginColumn(), varDeclId.getEndLine(), varDeclId.getEndColumn(),
AccessKind.fromAccessSpecifier(ModifierSet.getAccessSpecifier(n.getModifiers())), false
);
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.getVars())
{
VariableDeclaratorId identifier = declarator.getId();
String qualifiedName = m_filePath + "<" + identifier.getBeginLine() + ":" + identifier.getBeginColumn() + ">";
JavaIndexer.recordLocalSymbol(
m_callbackId, qualifiedName,
identifier.getBeginLine(), identifier.getBeginColumn(), identifier.getEndLine(), identifier.getEndColumn()
);
}
// don't change the context here.
super.visit(n, v);
}
@Override public void visit(final Parameter n, final Void v)
{
VariableDeclaratorId identifier = n.getId();
String qualifiedName = m_filePath + "<" + identifier.getBeginLine() + ":" + identifier.getBeginColumn() + ">";
JavaIndexer.recordLocalSymbol(
m_callbackId, qualifiedName,
identifier.getBeginLine(), identifier.getBeginColumn(), identifier.getEndLine(), identifier.getEndColumn()
);
// don't change the context here.
super.visit(n, v);
}
// --- record references ---
@Override public void visit(final ImportDeclaration n, final Void v)
{
if (n.isAsterisk())
{
NameExpr nameExpr = n.getName();
String importedName = JavaDeclNameResolver.getQualifiedName(nameExpr).toNameHierarchy();
for (DeclContext context: m_context)
{
JavaIndexer.recordReference(
m_callbackId, ReferenceKind.IMPORT,
importedName, context.getName(),
nameExpr.getBeginLine(), nameExpr.getBeginColumn(), nameExpr.getEndLine(), nameExpr.getEndColumn()
);
}
}
else
{
try
{
NameExpr nameExpr = n.getName();
JavaDeclName importedDeclName = null;
SymbolReference<TypeDeclaration> symbolReference = m_typeSolver.tryToSolveType(
JavaDeclNameResolver.getQualifiedName(nameExpr).toString()
);
if (symbolReference.isSolved())
{
importedDeclName = JavaDeclNameResolver.getQualifiedDeclName(symbolReference.getCorrespondingDeclaration(), m_typeSolver);
}
if (importedDeclName != null)
{
String importedName = importedDeclName.toNameHierarchy();
for (DeclContext context: m_context)
{
JavaIndexer.recordReference(
m_callbackId, ReferenceKind.IMPORT,
importedName, context.getName(),
nameExpr.getBeginLine(), nameExpr.getBeginColumn(), nameExpr.getEndLine(), nameExpr.getEndColumn()
);
}
}
}
catch (Exception e)
{
if (m_verbose)
{
System.out.println(e + " at location " + n.getBeginLine() + ", " + n.getBeginColumn());
}
}
}
super.visit(n, v);
}
@Override public void visit(final ClassOrInterfaceType n, final Void v)
{
try
{
for (DeclContext context: m_context)
{
String referencedName = JavaTypeNameResolver.getQualifiedTypeName(n, m_typeSolver).toNameHierarchy();
int beginLine = n.getBeginLine();
int beginColumn = n.getBeginColumn();
int endLine = n.getBeginLine();
int endColumn = n.getBeginColumn() + n.getName().length() - 1;
if (n.getScope() != null)
{
endLine = n.getScope().getEndLine();
endColumn = n.getScope().getEndColumn() + n.getName().length() + 1; // +1 for separator
}
JavaIndexer.recordReference(
m_callbackId, getTypeReferenceKind(), referencedName, context.getName(),
beginLine, beginColumn, endLine, endColumn
);
}
}
catch (Exception e)
{
if (m_verbose)
{
System.out.println(e + " at location " + n.getBeginLine() + ", " + n.getBeginColumn());
}
}
super.visit(n, v);
}
@Override public void visit(final PrimitiveType n, final Void v)
{
try
{
String referencedName = JavaTypeNameResolver.getQualifiedTypeName(n, m_typeSolver).toNameHierarchy();
JavaIndexer.recordSymbolWithoutLocation(
m_callbackId, referencedName, SymbolType.BUILTIN_TYPE,
AccessKind.NONE, true
);
for (DeclContext context: m_context)
{
JavaIndexer.recordReference(
m_callbackId, getTypeReferenceKind(), referencedName, context.getName(),
n.getBeginLine(), n.getBeginColumn(), n.getEndLine(), n.getEndColumn()
);
}
}
catch (Exception e)
{
if (m_verbose)
{
System.out.println(e + " at location " + n.getBeginLine() + ", " + n.getBeginColumn());
}
}
super.visit(n, v);
}
@Override public void visit(final VoidType n, final Void v)
{
try
{
String referencedName = JavaTypeNameResolver.getQualifiedTypeName(n, m_typeSolver).toNameHierarchy();
JavaIndexer.recordSymbolWithoutLocation(
m_callbackId, referencedName, SymbolType.BUILTIN_TYPE,
AccessKind.NONE, true
);
for (DeclContext context: m_context)
{
JavaIndexer.recordReference(
m_callbackId, getTypeReferenceKind(), referencedName, context.getName(),
n.getBeginLine(), n.getBeginColumn(), n.getEndLine(), n.getEndColumn()
);
}
}
catch (Exception e)
{
if (m_verbose)
{
System.out.println(e + " at location " + n.getBeginLine() + ", " + n.getBeginColumn());
}
}
super.visit(n, v);
}
@Override public void visit(final NameExpr n, final Void v)
{
try
{
recordRef(n);
}
catch (Exception e)
{
if (m_verbose)
{
System.out.println(e + " at location " + n.getBeginLine() + ", " + n.getBeginColumn());
}
}
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();
if (valueDecl instanceof JavaParserSymbolDeclaration)
{
Node wrappedNode = null;
if (valueDecl instanceof JavaParserSymbolDeclaration)
{
wrappedNode = ((JavaParserSymbolDeclaration)valueDecl).getWrappedNode();
}
if (wrappedNode != null)
{
if (wrappedNode instanceof Parameter)
{
VariableDeclaratorId identifier = ((Parameter)wrappedNode).getId();
String qualifiedName = m_filePath + "<" + identifier.getBeginLine() + ":" + identifier.getBeginColumn() + ">";
JavaIndexer.recordLocalSymbol(
m_callbackId, qualifiedName,
e.getBeginLine(), e.getBeginColumn(), e.getEndLine(), e.getEndColumn()
);
}
else if (wrappedNode instanceof VariableDeclarator)
{
if (getFieldDeclarationInParentHierarchy(wrappedNode) != null)
{
String qualifiedName = JavaDeclNameResolver.getQualifiedDeclName((VariableDeclarator)wrappedNode, m_typeSolver).toNameHierarchy();
for (DeclContext context: m_context)
{
JavaIndexer.recordReference(
m_callbackId, ReferenceKind.USAGE, qualifiedName, context.getName(),
e.getBeginLine(), e.getBeginColumn(), e.getEndLine(), e.getEndColumn()
);
}
}
else
{
VariableDeclaratorId identifier = ((VariableDeclarator)wrappedNode).getId();
String qualifiedName = m_filePath + "<" + identifier.getBeginLine() + ":" + identifier.getBeginColumn() + ">";
JavaIndexer.recordLocalSymbol(
m_callbackId, qualifiedName,
e.getBeginLine(), e.getBeginColumn(), e.getEndLine(), e.getEndColumn()
);
}
}
}
}
}
}
private static FieldDeclaration getFieldDeclarationInParentHierarchy(Node decl)
{
FieldDeclaration context = null;
{
Node parentNode = decl.getParentNode();
while (parentNode != null && !(parentNode instanceof FieldDeclaration))
{
parentNode = parentNode.getParentNode();
}
if (parentNode != null)
{
context = (FieldDeclaration)parentNode;
}
}
return context;
}
@Override public void visit(final MethodCallExpr n, final Void v)
{
String qualifiedName = "";
if (m_context.size() > 0)
{
try
{
MethodUsage solvedMethod = JavaParserFacade.get(m_typeSolver).solveMethodAsUsage(n);
qualifiedName = getQualifiedName(solvedMethod);
}
catch (UnsupportedOperationException e)
{
if (m_verbose)
{
System.out.println(e + " at location " + n.getBeginLine() + ", " + n.getBeginColumn());
}
}
catch (MethodAmbiguityException e)
{
if (m_verbose)
{
System.out.println(e + " at location " + n.getBeginLine() + ", " + n.getBeginColumn());
}
}
catch(StackOverflowError e)
{
if (m_verbose)
{
System.out.println(e + " at location " + n.getBeginLine() + ", " + n.getBeginColumn());
}
}
catch (Exception e)
{
if (m_verbose)
{
System.out.println(e + " at location " + n.getBeginLine() + ", " + n.getBeginColumn());
}
}
}
if (!qualifiedName.isEmpty())
{
NameExpr nameExpr = n.getNameExpr();
for (DeclContext context: m_context)
{
JavaIndexer.recordReference(
m_callbackId, ReferenceKind.CALL, qualifiedName, context.getName(),
nameExpr.getBeginLine(), nameExpr.getBeginColumn(), nameExpr.getEndLine(), nameExpr.getEndColumn()
);
}
}
super.visit(n, v);
}
/*
@Override public void visit(final ObjectCreationExpr n, final Void v)
{
String qualifiedName = "";
if (m_context.size() > 0)
{
try
{
ClassOrInterfaceDeclaration decl = Utility.getJavaparserDeclForType(n.getType(), m_typeSolver);
if (decl != null)
{
TODO: implement when there is a method to get the constructor decl for a constructor expression.
for (BodyDeclaration member: decl.getMembers())
{
if (member instanceof ConstructorDeclaration)
{
ConstructorDeclaration constructorDecl = (ConstructorDeclaration)member;
for (Expression arg: n.getArgs())
{
JavaParserFacade.get(m_typeSolver).getType(arg).asReferenceTypeUsage().getQualifiedName();
}
constructorDecl.getParameters().get(0).getType().;
}
}
}
qualifiedName = getQualifiedName(methodUsage.get());
}
catch (UnsupportedOperationException e)
{
if (m_verbose)
{
System.out.println(e + " at location " + n.getBeginLine() + ", " + n.getBeginColumn());
}
}
catch (MethodAmbiguityException e)
{
if (m_verbose)
{
System.out.println(e + " at location " + n.getBeginLine() + ", " + n.getBeginColumn());
}
}
catch(StackOverflowError e)
{
if (m_verbose)
{
System.out.println(e + " at location " + n.getBeginLine() + ", " + n.getBeginColumn());
}
}
catch (Exception e)
{
if (m_verbose)
{
System.out.println(e + " at location " + n.getBeginLine() + ", " + n.getBeginColumn());
}
}
}
if (!qualifiedName.isEmpty())
{
ClassOrInterfaceType type = n.getType();
for (DeclContext context: m_context)
{
JavaIndexer.recordRef(
m_callbackId, ReferenceType.CALL.getValue(), qualifiedName, context.getName(),
type.getBeginLine(), type.getBeginColumn(), type.getEndLine(), type.getEndColumn()
);
}
}
super.visit(n, v);
}
*/
private String getQualifiedName(MethodUsage solvedMethod)
{
me.tomassetti.symbolsolver.model.declarations.MethodDeclaration methodDecl = solvedMethod.getDeclaration();
String qualifiedName = "";
if (methodDecl instanceof JavaParserMethodDeclaration)
{
MethodDeclaration wrappedNode = ((JavaParserMethodDeclaration)methodDecl).getWrappedNode();
qualifiedName = JavaDeclNameResolver.getQualifiedDeclName(wrappedNode, m_typeSolver).toNameHierarchy();
}
else // todo: move this implementation somewhere else
{
qualifiedName = solvedMethod.declaringType().getQualifiedName();
qualifiedName = qualifiedName.replace(".", "\t\r\n");
qualifiedName += "\t\r\n" + solvedMethod.getName() + "\t";
String returnType = solvedMethod.returnType().describe();
qualifiedName += returnType;
// qualifiedName += returnType.substring(returnType.lastIndexOf(".") + 1);
qualifiedName += "\r(";
for (int i = 0; i < solvedMethod.getParamTypes().size(); i++)
{
if(i != 0)
{
qualifiedName += (", ");
}
String paramType = solvedMethod.getParamTypes().get(i).describe();
qualifiedName += paramType;
// qualifiedName += paramType.substring(paramType.lastIndexOf(".") + 1);
}
qualifiedName = qualifiedName.concat(")");
}
return qualifiedName;
}
@Override public void visit(final LineComment n, final Void v)
{
JavaIndexer.recordComment(
m_callbackId,
n.getBeginLine(), n.getBeginColumn(), n.getEndLine(), n.getEndColumn()
);
}
@Override public void visit(final BlockComment n, final Void v)
{
JavaIndexer.recordComment(
m_callbackId,
n.getBeginLine(), n.getBeginColumn(), n.getEndLine(), n.getEndColumn()
);
}
}
File diff suppressed because it is too large Load Diff
+147
View File
@@ -0,0 +1,147 @@
package io.coati;
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 toNameHierarchy()
{
String nameHierarchy = "";
if (m_parent != null)
{
nameHierarchy = m_parent.toNameHierarchy();
nameHierarchy += "\n";
}
nameHierarchy += m_name;
nameHierarchy += getTypeParameterString();
nameHierarchy += "\t";
if (m_returnTypeName != null)
{
nameHierarchy += m_returnTypeName.toString();
}
nameHierarchy += "\r";
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;
}
private 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,312 @@
package io.coati;
import java.util.ArrayList;
import java.util.List;
import com.github.javaparser.ast.CompilationUnit;
import com.github.javaparser.ast.Node;
import com.github.javaparser.ast.PackageDeclaration;
import com.github.javaparser.ast.TypeParameter;
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.NameExpr;
import com.github.javaparser.ast.expr.QualifiedNameExpr;
import me.tomassetti.symbolsolver.javaparsermodel.declarations.JavaParserClassDeclaration;
import me.tomassetti.symbolsolver.javaparsermodel.declarations.JavaParserInterfaceDeclaration;
import me.tomassetti.symbolsolver.model.resolution.TypeSolver;
public class JavaDeclNameResolver extends JavaNameResolver
{
public JavaDeclNameResolver(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)
{
JavaDeclNameResolver resolver = new JavaDeclNameResolver(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
{
CompilationUnit compilationUnit = getCompilationUnitContext(decl);
if (compilationUnit != null)
{
PackageDeclaration packageDecl = compilationUnit.getPackage();
if (packageDecl != null)
{
declName.setParent(getQualifiedName(packageDecl.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)
{
JavaDeclNameResolver resolver = new JavaDeclNameResolver(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
{
CompilationUnit compilationUnit = getCompilationUnitContext(decl);
if (compilationUnit != null)
{
PackageDeclaration packageDecl = compilationUnit.getPackage();
if (packageDecl != null)
{
declName.setParent(getQualifiedName(packageDecl.getName()));
}
}
else
{
throw new UnsupportedOperationException();
}
}
}
return declName;
}
public static JavaDeclName getQualifiedDeclName(me.tomassetti.symbolsolver.model.declarations.TypeDeclaration typeDecl, TypeSolver typeSolver)
{
return getQualifiedDeclName(typeDecl, typeSolver, null);
}
public static JavaDeclName getQualifiedDeclName(me.tomassetti.symbolsolver.model.declarations.TypeDeclaration typeDecl, TypeSolver typeSolver, ArrayList<BodyDeclaration> ignoredContexts)
{
JavaDeclNameResolver resolver = new JavaDeclNameResolver(typeSolver, ignoredContexts);
return resolver.getQualifiedDeclName(typeDecl);
}
public JavaDeclName getQualifiedDeclName(me.tomassetti.symbolsolver.model.declarations.TypeDeclaration typeDecl)
{
JavaDeclName declName = null;
if (typeDecl != null)
{
ClassOrInterfaceDeclaration decl = null;
if (typeDecl instanceof JavaParserClassDeclaration)
{
decl = ((JavaParserClassDeclaration)typeDecl).getWrappedNode();
}
else if (typeDecl instanceof JavaParserInterfaceDeclaration)
{
decl = ((JavaParserInterfaceDeclaration)typeDecl).getWrappedNode();
}
if (decl != null)
{
declName = JavaDeclNameResolver.getQualifiedDeclName(decl, m_typeSolver, m_ignoredContexts);
}
else
{
declName = JavaDeclName.fromDotSeparatedString(typeDecl.getQualifiedName());
}
}
return declName;
}
public JavaDeclName getDeclName(VariableDeclarator decl)
{
return new JavaDeclName(decl.getId().getName());
}
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).getName());
}
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).getName(), getTypeParameterNames((TypeDeclaration)decl));
}
}
return declName;
}
private static List<String> getTypeParameterNames(TypeDeclaration decl)
{
List<TypeParameter> typeParameters = null;
if (decl instanceof ClassOrInterfaceDeclaration)
{
typeParameters = ((ClassOrInterfaceDeclaration)decl).getTypeParameters();
}
return getTypeParameterNames(typeParameters);
}
private static List<String> getTypeParameterNames(List<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).getName());
}
}
return typeParameterNames;
}
public static JavaDeclName getQualifiedName(NameExpr nameExpr)
{
JavaDeclName declName = new JavaDeclName(nameExpr.getName());
if (nameExpr instanceof QualifiedNameExpr)
{
declName.setParent(getQualifiedName(((QualifiedNameExpr)nameExpr).getQualifier()));
}
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 = JavaTypeNameResolver.getQualifiedTypeName(decl.getType(), m_typeSolver, ignoredContextsForTypes);
List<JavaTypeName> parameterNames = new ArrayList<>();
for (Parameter parameter: decl.getParameters())
{
parameterNames.add(JavaTypeNameResolver.getQualifiedTypeName(parameter.getType(), m_typeSolver, ignoredContextsForTypes));
}
return new JavaDeclName(name, typeParameterNames, returnTypeName, parameterNames);
}
private static BodyDeclaration getBodyDeclContext(Node decl)
{
BodyDeclaration context = null;
Node parentNode = decl.getParentNode();
while (
parentNode != null &&
!(
parentNode instanceof BodyDeclaration &&
(!(parentNode instanceof FieldDeclaration))
)
)
{
parentNode = parentNode.getParentNode();
}
if (parentNode != null)
{
context = (BodyDeclaration)parentNode;
}
return context;
}
private static CompilationUnit getCompilationUnitContext(Node decl)
{
CompilationUnit context = null;
{
Node parentNode = decl.getParentNode();
while (parentNode != null && !(parentNode instanceof CompilationUnit))
{
parentNode = parentNode.getParentNode();
}
if (parentNode != null)
{
context = (CompilationUnit)parentNode;
}
}
return context;
}
}
+182
View File
@@ -0,0 +1,182 @@
package io.coati;
import java.io.File;
import java.io.IOException;
import java.io.StringReader;
import java.lang.String;
import com.github.javaparser.ast.CompilationUnit;
import com.github.javaparser.JavaParser;
import com.github.javaparser.ParseException;
import com.github.javaparser.Token;
import me.tomassetti.symbolsolver.javaparsermodel.JavaParserFacade;
import me.tomassetti.symbolsolver.resolution.typesolvers.CombinedTypeSolver;
import me.tomassetti.symbolsolver.resolution.typesolvers.JarTypeSolver;
import me.tomassetti.symbolsolver.resolution.typesolvers.JavaParserTypeSolver;
import me.tomassetti.symbolsolver.resolution.typesolvers.JreTypeSolver;
public class JavaIndexer
{
public static void processFile(int address, String filePath, String fileContent, String classPath)
{
System.out.println("indexing file: " + filePath);
try
{
CombinedTypeSolver typeSolver = new CombinedTypeSolver();
typeSolver.add(new JreTypeSolver());
for (String path: classPath.split("\\;"))
{
if (path.endsWith(".jar"))
{
try
{
JarTypeSolver jarTypeSolver = new JarTypeSolver(path);
typeSolver.add(jarTypeSolver);
}
catch (IOException e)
{
System.out.println("unable to add jar file: " + path);
}
}
else
{
JavaParserTypeSolver solver = new JavaParserTypeSolver(new File(path));
typeSolver.add(solver);
}
}
CompilationUnit cu = JavaParser.parse(new StringReader(fileContent), true);
JavaAstVisitor astVisitor = new JavaAstVisitor(address, filePath, typeSolver);
// JavaAstVisitor astVisitor = new ASTDumper(address, filePath, typeSolver);
cu.accept(astVisitor, null);
}
catch (ParseException e)
{
if (e.expectedTokenSequences == null || e.expectedTokenSequences.length == 0)
{
Token token = e.currentToken;
recordError(
address, e.getMessage(), true, true,
token.beginLine, token.beginColumn, token.endLine, token.endColumn
);
}
else
{
Token token = e.currentToken.next;
recordError(
address, "Encountered unexpected token.", true, true,
token.beginLine, token.beginColumn, token.endLine, token.endColumn
);
}
}
JavaParserFacade.clearCaches();
// String fileName = filePath.substring(filePath.lastIndexOf("/"), filePath.lastIndexOf(".java"));
// System.gc();
// HeapDumper.dumpHeap("D:/dump/" + fileName, false);
}
static public void recordSymbol(
int address, String symbolName, SymbolType symbolType,
int beginLine, int beginColumn, int endLine, int endColumn,
AccessKind access, boolean isImplicit
)
{
recordSymbol(
address, symbolName, symbolType.getValue(),
beginLine, beginColumn, endLine, endColumn,
access.getValue(), (isImplicit ? 1 : 0)
);
}
static public void recordSymbolWithoutLocation(
int address, String symbolName, SymbolType symbolType,
AccessKind access, boolean isImplicit
)
{
recordSymbolWithoutLocation(
address, symbolName, symbolType.getValue(),
access.getValue(), (isImplicit ? 1 : 0)
);
}
static public void recordSymbolWithScope(
int address, String symbolName, SymbolType symbolType,
int beginLine, int beginColumn, int endLine, int endColumn,
int scopeBeginLine, int scopeBeginColumn, int scopeEndLine, int scopeEndColumn,
AccessKind access, boolean isImplicit
)
{
recordSymbolWithScope(
address, symbolName, symbolType.getValue(),
beginLine, beginColumn, endLine, endColumn,
scopeBeginLine, scopeBeginColumn, scopeEndLine, scopeEndColumn,
access.getValue(), (isImplicit ? 1 : 0)
);
}
static public void recordReference(
int address, ReferenceKind referenceKind, String referencedName, String contextName,
int beginLine, int beginColumn, int endLine, int endColumn
)
{
recordReference(
address, referenceKind.getValue(), referencedName, contextName,
beginLine, beginColumn, endLine, endColumn
);
}
static public void recordError(
int address, String message, boolean fatal, boolean indexed, int beginLine, int beginColumn, int endLine, int endColumn
)
{
recordError(
address, message, (fatal ? 1 : 0), (indexed ? 1 : 0),
beginLine, beginColumn, endLine, endColumn
);
}
static private native void recordSymbol(
int address, String symbolName, int symbolType,
int beginLine, int beginColumn, int endLine, int endColumn,
int access, int isImplicit
);
static private native void recordSymbolWithoutLocation(
int address, String symbolName, int symbolType,
int access, int isImplicit
);
static private native void recordSymbolWithScope(
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 isImplicit
);
static private native void recordReference(
int address, int referenceKind, String referencedName, String contextName, int beginLine, int beginColumn, int endLine, int endColumn
);
static native void recordLocalSymbol(
int address, String symbolName, int beginLine, int beginColumn, int endLine, int endColumn
);
static 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 io.coati;
import java.util.ArrayList;
import com.github.javaparser.ast.body.BodyDeclaration;
import me.tomassetti.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;
}
}
+100
View File
@@ -0,0 +1,100 @@
package io.coati;
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 toNameHierarchy()
{
String nameHierarchy = "";
if (m_parent != null)
{
nameHierarchy = m_parent.toNameHierarchy();
nameHierarchy += "\n";
}
nameHierarchy += m_name;
nameHierarchy += getTypeArgumentString();
nameHierarchy += "\t\r";
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,130 @@
package io.coati;
import java.util.ArrayList;
import java.util.List;
import com.github.javaparser.ast.Node;
import com.github.javaparser.ast.body.BodyDeclaration;
import com.github.javaparser.ast.type.*;
import me.tomassetti.symbolsolver.javaparsermodel.JavaParserFacade;
import me.tomassetti.symbolsolver.javaparsermodel.declarations.JavaParserTypeParameter;
import me.tomassetti.symbolsolver.model.resolution.TypeParameter;
import me.tomassetti.symbolsolver.model.resolution.TypeSolver;
import me.tomassetti.symbolsolver.model.typesystem.TypeParameterUsage;
import me.tomassetti.symbolsolver.model.typesystem.TypeUsage;
public class JavaTypeNameResolver extends JavaNameResolver
{
public JavaTypeNameResolver(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)
{
JavaTypeNameResolver resolver = new JavaTypeNameResolver(typeSolver, ignoredContexts);
return resolver.getQualifiedTypeName(type);
}
public JavaTypeName getQualifiedTypeName(Type type)
{
String fallbackTypeName = type.toString();
if (type instanceof ClassOrInterfaceType)
{
try
{
TypeUsage typeUsage = JavaParserFacade.get(m_typeSolver).convert(type, type);
if (typeUsage.isReferenceType())
{
JavaDeclName declName = JavaDeclNameResolver.getQualifiedDeclName(typeUsage.asReferenceTypeUsage().getTypeDeclaration(), m_typeSolver, m_ignoredContexts);
if (declName != null)
{
List<JavaTypeName> typeArgumentNames = new ArrayList<>();
for (Type typeArgument: ((ClassOrInterfaceType)type).getTypeArgs())
{
typeArgumentNames.add(getQualifiedTypeName(typeArgument, m_typeSolver, m_ignoredContexts));
}
JavaTypeName ret = new JavaTypeName(declName.getName(), typeArgumentNames, declName.getParent());
return ret;
}
}
else if (typeUsage instanceof TypeParameterUsage)
{
TypeParameter typeParam = typeUsage.asTypeParameter();
if (typeParam instanceof JavaParserTypeParameter)
{
com.github.javaparser.ast.TypeParameter jpTypeParameter = ((JavaParserTypeParameter)typeParam).getWrappedNode();
Node genericDecl = jpTypeParameter.getParentNode();
if (genericDecl instanceof BodyDeclaration)
{
JavaDeclName genericName = null;
if (!ignoresContext((BodyDeclaration)genericDecl))
{
genericName = JavaDeclNameResolver.getQualifiedDeclName((BodyDeclaration)genericDecl, m_typeSolver, m_ignoredContexts);
}
return new JavaTypeName(jpTypeParameter.getName(), genericName);
}
}
else
{
// do we need to handle using type parameters of external code?
}
}
}
catch (Exception e)
{
// log...
}
}
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 ReferenceType)
{
ReferenceType referenceType = (ReferenceType)type;
boolean isArray = (referenceType.getArrayCount() == 0); // TODO: regard array info!
return getQualifiedTypeName(referenceType.getType());
}
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("error-type", null);
}
}
@@ -0,0 +1,31 @@
package io.coati;
public enum ReferenceKind
{
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;
}
}
+37
View File
@@ -0,0 +1,37 @@
package io.coati;
public enum SymbolType
{ // these values need to be the same as SymbolType 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 SymbolType(int value)
{
this.m_value = value;
}
public int getValue()
{
return m_value;
}
}