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:
@@ -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
|
||||
@@ -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--; }
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
@@ -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
@@ -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;
|
||||
}
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user