├── .gitignore
├── src
├── test
│ └── java
│ │ └── com
│ │ └── github
│ │ └── linzeqipku
│ │ └── javacode_to_neo4j
│ │ └── JavaCodeGraphBuilderTest.java
└── main
│ └── java
│ └── com
│ └── github
│ └── linzeqipku
│ └── javacode_to_neo4j
│ ├── infos
│ ├── JavaFieldInfo.java
│ ├── JavaClassInfo.java
│ ├── JavaProjectInfo.java
│ └── JavaMethodInfo.java
│ ├── JavaCodeGraphBuilder.java
│ ├── NameResolver.java
│ └── JavaASTVisitor.java
├── README.md
└── pom.xml
/.gitignore:
--------------------------------------------------------------------------------
1 | target/
2 |
3 | .idea/
4 | *.iml
--------------------------------------------------------------------------------
/src/test/java/com/github/linzeqipku/javacode_to_neo4j/JavaCodeGraphBuilderTest.java:
--------------------------------------------------------------------------------
1 | package com.github.linzeqipku.javacode_to_neo4j;
2 |
3 | import org.junit.Test;
4 |
5 | import java.io.IOException;
6 |
7 | public class JavaCodeGraphBuilderTest {
8 |
9 | private static final String GRAPH_DIR_PATH="E:/dc/graph.db";
10 | private static final String SRC_DIR_PATH="E:/dc/data/sourcecode";
11 |
12 | @Test
13 | public void testCodeGraphBuilder() throws IOException {
14 | JavaCodeGraphBuilder.process(GRAPH_DIR_PATH,SRC_DIR_PATH);
15 | }
16 |
17 | }
18 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # javacode-to-neo4j
2 |
3 | Parse java source code, extract code entities (classes, interfaces, methods and fields) and static dependencies (inheritance, invocation, decleration, etc.), then store them into a neo4j graph database.
4 |
5 | ### Usage example
6 |
7 | ``
8 | JavaCodeGraphBuilder.process(GRAPH_DIR_PATH,SRC_DIR_PATH);
9 | ``
10 |
11 | see [the test case](https://github.com/linzeqipku/javacode-to-neo4j/blob/master/src/test/java/com/github/linzeqipku/javacode_to_neo4j/JavaCodeGraphBuilderTest.java).
12 |
13 | ### Maven
14 |
15 | Add this repository in your ``pom.xml`` file:
16 |
17 | ```
18 |
19 |
20 | linzeqipku-public-snapshots
21 | https://raw.github.com/linzeqipku/maven-repo/master/snapshots
22 |
23 |
24 | linzeqipku-public-releases
25 | https://raw.github.com/linzeqipku/maven-repo/master/releases
26 |
27 |
28 | ```
29 |
30 | Add the maven dependence:
31 |
32 | ```
33 |
34 |
35 | com.github.linzeqipku
36 | javacode-to-neo4j
37 | 1.1-SNAPSHOT
38 |
39 |
40 | ```
41 |
--------------------------------------------------------------------------------
/src/main/java/com/github/linzeqipku/javacode_to_neo4j/infos/JavaFieldInfo.java:
--------------------------------------------------------------------------------
1 | package com.github.linzeqipku.javacode_to_neo4j.infos;
2 |
3 | import com.github.linzeqipku.javacode_to_neo4j.JavaCodeGraphBuilder;
4 | import com.google.common.base.Preconditions;
5 | import lombok.Getter;
6 | import org.neo4j.unsafe.batchinsert.BatchInserter;
7 |
8 | import java.util.HashMap;
9 | import java.util.Map;
10 |
11 | public class JavaFieldInfo {
12 |
13 | @Getter private String name;
14 | @Getter private String fullName;
15 | @Getter private String type;
16 | @Getter private String visibility;
17 | @Getter private boolean isStatic;
18 | @Getter private boolean isFinal;
19 | @Getter private String comment;
20 |
21 | @Getter private String belongTo;
22 | @Getter private String fullType;
23 | @Getter private long nodeId;
24 |
25 | public JavaFieldInfo(BatchInserter inserter, String name, String fullName, String type, String visibility, boolean isStatic, boolean isFinal, String comment, String belongTo, String fullType) {
26 | Preconditions.checkArgument(name!=null);
27 | this.name = name;
28 | Preconditions.checkArgument(fullName!=null);
29 | this.fullName = fullName;
30 | Preconditions.checkArgument(type!=null);
31 | this.type = type;
32 | Preconditions.checkArgument(visibility!=null);
33 | this.visibility = visibility;
34 | this.isStatic = isStatic;
35 | this.isFinal = isFinal;
36 | Preconditions.checkArgument(comment!=null);
37 | this.comment = comment;
38 | Preconditions.checkArgument(belongTo!=null);
39 | this.belongTo = belongTo;
40 | Preconditions.checkArgument(fullType!=null);
41 | this.fullType = fullType;
42 | nodeId=createNode(inserter);
43 | }
44 |
45 | private long createNode(BatchInserter inserter){
46 | Map map=new HashMap<>();
47 | map.put(JavaCodeGraphBuilder.NAME,name);
48 | map.put(JavaCodeGraphBuilder.FULLNAME,fullName);
49 | map.put(JavaCodeGraphBuilder.TYPE_STR,type);
50 | map.put(JavaCodeGraphBuilder.VISIBILITY,visibility);
51 | map.put(JavaCodeGraphBuilder.IS_STATIC,isStatic);
52 | map.put(JavaCodeGraphBuilder.IS_FINAL,isFinal);
53 | map.put(JavaCodeGraphBuilder.COMMENT,comment);
54 | return inserter.createNode(map, JavaCodeGraphBuilder.FIELD);
55 | }
56 |
57 | }
--------------------------------------------------------------------------------
/src/main/java/com/github/linzeqipku/javacode_to_neo4j/infos/JavaClassInfo.java:
--------------------------------------------------------------------------------
1 | package com.github.linzeqipku.javacode_to_neo4j.infos;
2 |
3 | import com.github.linzeqipku.javacode_to_neo4j.JavaCodeGraphBuilder;
4 | import com.google.common.base.Preconditions;
5 | import lombok.Getter;
6 | import org.neo4j.unsafe.batchinsert.BatchInserter;
7 |
8 | import java.util.HashMap;
9 | import java.util.Map;
10 |
11 | public class JavaClassInfo {
12 |
13 | @Getter private final String name;
14 | @Getter private final String fullName;
15 | @Getter private final boolean isInterface;
16 | @Getter private final String visibility;
17 | @Getter private final boolean isAbstract;
18 | @Getter private final boolean isFinal;
19 | @Getter private final String comment;
20 | @Getter private final String content;
21 |
22 | @Getter private final String superClassType;
23 | @Getter private final String superInterfaceTypes;
24 | @Getter private long nodeId;
25 |
26 | public JavaClassInfo(BatchInserter inserter, String name, String fullName, boolean isInterface, String visibility, boolean isAbstract, boolean isFinal, String comment, String content, String superClassType, String superInterfaceTypes) {
27 | Preconditions.checkArgument(name!=null);
28 | this.name = name;
29 | Preconditions.checkArgument(fullName!=null);
30 | this.fullName = fullName;
31 | this.isInterface = isInterface;
32 | Preconditions.checkArgument(visibility!=null);
33 | this.visibility = visibility;
34 | this.isAbstract = isAbstract;
35 | this.isFinal = isFinal;
36 | Preconditions.checkArgument(comment!=null);
37 | this.comment = comment;
38 | Preconditions.checkArgument(content!=null);
39 | this.content = content;
40 | Preconditions.checkArgument(superClassType!=null);
41 | this.superClassType = superClassType;
42 | Preconditions.checkArgument(superInterfaceTypes!=null);
43 | this.superInterfaceTypes = superInterfaceTypes;
44 | nodeId=createNode(inserter);
45 | }
46 |
47 | private long createNode(BatchInserter inserter){
48 | Map map=new HashMap<>();
49 | map.put(JavaCodeGraphBuilder.NAME,name);
50 | map.put(JavaCodeGraphBuilder.FULLNAME,fullName);
51 | map.put(JavaCodeGraphBuilder.IS_INTERFACE,isInterface);
52 | map.put(JavaCodeGraphBuilder.VISIBILITY,visibility);
53 | map.put(JavaCodeGraphBuilder.IS_ABSTRACT,isAbstract);
54 | map.put(JavaCodeGraphBuilder.IS_FINAL,isFinal);
55 | map.put(JavaCodeGraphBuilder.COMMENT,comment);
56 | map.put(JavaCodeGraphBuilder.CONTENT,content);
57 | return inserter.createNode(map, JavaCodeGraphBuilder.CLASS);
58 | }
59 |
60 | }
--------------------------------------------------------------------------------
/pom.xml:
--------------------------------------------------------------------------------
1 |
2 |
5 | 4.0.0
6 |
7 | com.github.linzeqipku
8 | javacode-to-neo4j
9 | 1.1-SNAPSHOT
10 |
11 |
12 |
13 |
14 |
15 | org.apache.maven.plugins
16 | maven-compiler-plugin
17 | 3.1
18 |
19 | 1.8
20 | 1.8
21 |
22 |
23 |
24 | org.apache.maven.plugins
25 | maven-surefire-plugin
26 |
27 | true
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 | junit
36 | junit
37 | 4.12
38 | test
39 |
40 |
41 | org.projectlombok
42 | lombok
43 | 1.16.20
44 | provided
45 |
46 |
47 | com.google.guava
48 | guava
49 | 24.0-jre
50 |
51 |
52 | commons-io
53 | commons-io
54 | 2.6
55 |
56 |
57 | org.eclipse.jdt
58 | org.eclipse.jdt.core
59 | 3.10.0
60 |
61 |
62 | org.neo4j
63 | neo4j
64 | 3.3.0
65 |
66 |
67 |
68 |
69 |
70 | repo
71 | https://raw.github.com/linzeqipku/maven-repo/master/releases
72 |
73 |
74 | snapshot-repo
75 | https://raw.github.com/linzeqipku/maven-repo/master/snapshots
76 |
77 |
78 |
79 |
--------------------------------------------------------------------------------
/src/main/java/com/github/linzeqipku/javacode_to_neo4j/infos/JavaProjectInfo.java:
--------------------------------------------------------------------------------
1 | package com.github.linzeqipku.javacode_to_neo4j.infos;
2 |
3 | import com.github.linzeqipku.javacode_to_neo4j.JavaCodeGraphBuilder;
4 | import org.eclipse.jdt.core.dom.IMethodBinding;
5 | import org.neo4j.unsafe.batchinsert.BatchInserter;
6 |
7 | import java.util.HashMap;
8 | import java.util.HashSet;
9 | import java.util.Map;
10 | import java.util.Set;
11 |
12 |
13 | public class JavaProjectInfo {
14 |
15 | private Map classInfoMap = new HashMap<>();
16 | private Map methodInfoMap = new HashMap<>();
17 | private Map fieldInfoMap = new HashMap<>();
18 |
19 | private Map methodBindingMap=new HashMap<>();
20 |
21 | public void addClassInfo(JavaClassInfo info){
22 | classInfoMap.put(info.getFullName(),info);
23 | }
24 |
25 | public void addMethodInfo(JavaMethodInfo info){
26 | methodInfoMap.put(info.getFullName(),info);
27 | methodBindingMap.put(info.getMethodBinding(),info);
28 | }
29 |
30 | public void addFieldInfo(JavaFieldInfo info){
31 | fieldInfoMap.put(info.getFullName(),info);
32 | }
33 |
34 | public void parseRels(BatchInserter inserter){
35 | methodInfoMap.values().forEach(info->methodBindingMap.put(info.getMethodBinding(),info));
36 | classInfoMap.values().forEach(classInfo->{
37 | findJavaClassInfo(classInfo.getSuperClassType()).forEach(superClassInfo->inserter.createRelationship(classInfo.getNodeId(),superClassInfo.getNodeId(), JavaCodeGraphBuilder.EXTEND,new HashMap<>()));
38 | findJavaClassInfo(classInfo.getSuperInterfaceTypes()).forEach(superInterfaceInfo->inserter.createRelationship(classInfo.getNodeId(),superInterfaceInfo.getNodeId(), JavaCodeGraphBuilder.IMPLEMENT,new HashMap<>()));
39 | });
40 | methodInfoMap.values().forEach(methodInfo->{
41 | findJavaClassInfo(methodInfo.getBelongTo()).forEach(owner->inserter.createRelationship(owner.getNodeId(),methodInfo.getNodeId(), JavaCodeGraphBuilder.HAVE_METHOD,new HashMap<>()));
42 | findJavaClassInfo(methodInfo.getFullParams()).forEach(param->inserter.createRelationship(methodInfo.getNodeId(),param.getNodeId(), JavaCodeGraphBuilder.PARAM_TYPE,new HashMap<>()));
43 | findJavaClassInfo(methodInfo.getFullReturnType()).forEach(rt->inserter.createRelationship(methodInfo.getNodeId(),rt.getNodeId(), JavaCodeGraphBuilder.RETURN_TYPE,new HashMap<>()));
44 | findJavaClassInfo(methodInfo.getThrowTypes()).forEach(tr->inserter.createRelationship(methodInfo.getNodeId(),tr.getNodeId(), JavaCodeGraphBuilder.THROW_TYPE,new HashMap<>()));
45 | findJavaClassInfo(methodInfo.getFullVariables()).forEach(var->inserter.createRelationship(methodInfo.getNodeId(),var.getNodeId(), JavaCodeGraphBuilder.VARIABLE_TYPE,new HashMap<>()));
46 | methodInfo.getMethodCalls().forEach(call->{
47 | if (methodBindingMap.containsKey(call))
48 | inserter.createRelationship(methodInfo.getNodeId(),methodBindingMap.get(call).getNodeId(), JavaCodeGraphBuilder.METHOD_CALL,new HashMap<>());
49 | });
50 | findJavaFieldInfo(methodInfo.getFieldAccesses()).forEach(access->inserter.createRelationship(methodInfo.getNodeId(),access.getNodeId(), JavaCodeGraphBuilder.FIELD_ACCESS,new HashMap<>()));
51 | });
52 | fieldInfoMap.values().forEach(fieldInfo->{
53 | findJavaClassInfo(fieldInfo.getBelongTo()).forEach(owner->inserter.createRelationship(owner.getNodeId(),fieldInfo.getNodeId(), JavaCodeGraphBuilder.HAVE_FIELD,new HashMap<>()));
54 | findJavaClassInfo(fieldInfo.getFullType()).forEach(type->inserter.createRelationship(fieldInfo.getNodeId(),type.getNodeId(), JavaCodeGraphBuilder.FIELD_TYPE,new HashMap<>()));
55 | });
56 | }
57 |
58 | private Set findJavaClassInfo(String str){
59 | Set r=new HashSet<>();
60 | String[] tokens=str.split("[^\\w\\.]+");
61 | for (String token:tokens)
62 | if (classInfoMap.containsKey(token))
63 | r.add(classInfoMap.get(token));
64 | return r;
65 | }
66 |
67 | private Set findJavaFieldInfo(String str){
68 | Set r=new HashSet<>();
69 | String[] tokens=str.split("[^\\w\\.]+");
70 | for (String token:tokens)
71 | if (fieldInfoMap.containsKey(token))
72 | r.add(fieldInfoMap.get(token));
73 | return r;
74 | }
75 |
76 | }
77 |
--------------------------------------------------------------------------------
/src/main/java/com/github/linzeqipku/javacode_to_neo4j/infos/JavaMethodInfo.java:
--------------------------------------------------------------------------------
1 | package com.github.linzeqipku.javacode_to_neo4j.infos;
2 |
3 | import com.github.linzeqipku.javacode_to_neo4j.JavaCodeGraphBuilder;
4 | import com.google.common.base.Preconditions;
5 | import lombok.Getter;
6 | import org.eclipse.jdt.core.dom.IMethodBinding;
7 | import org.neo4j.unsafe.batchinsert.BatchInserter;
8 |
9 | import java.util.HashMap;
10 | import java.util.Map;
11 | import java.util.Set;
12 |
13 | public class JavaMethodInfo {
14 |
15 | @Getter private String name;
16 | @Getter private String fullName;
17 | @Getter private String returnType;
18 | @Getter private String visibility;
19 | @Getter private boolean isConstruct;
20 | @Getter private boolean isAbstract;
21 | @Getter private boolean isFinal;
22 | @Getter private boolean isStatic;
23 | @Getter private boolean isSynchronized;
24 | @Getter private String content;
25 | @Getter private String comment;
26 | @Getter private String params;
27 |
28 | @Getter private IMethodBinding methodBinding;
29 | @Getter private String fullReturnType;
30 | @Getter private String belongTo;
31 | @Getter private String fullParams;
32 | @Getter private String fullVariables;
33 | @Getter private Set methodCalls;
34 | @Getter private String fieldAccesses;
35 | @Getter private String throwTypes;
36 | @Getter private long nodeId;
37 |
38 | public JavaMethodInfo(BatchInserter inserter, String name, String fullName, String returnType, String visibility, boolean isConstruct, boolean isAbstract,
39 | boolean isFinal, boolean isStatic, boolean isSynchronized, String content, String comment, String params, IMethodBinding methodBinding,
40 | String fullReturnType, String belongTo, String fullParams, String fullVariables, Set methodCalls, String fieldAccesses, String throwTypes) {
41 | Preconditions.checkArgument(name!=null);
42 | this.name = name;
43 | Preconditions.checkArgument(fullName!=null);
44 | this.fullName = fullName;
45 | Preconditions.checkArgument(returnType!=null);
46 | this.returnType = returnType;
47 | Preconditions.checkArgument(visibility!=null);
48 | this.visibility = visibility;
49 | this.isConstruct = isConstruct;
50 | this.isAbstract = isAbstract;
51 | this.isFinal = isFinal;
52 | this.isStatic = isStatic;
53 | this.isSynchronized = isSynchronized;
54 | Preconditions.checkArgument(content!=null);
55 | this.content = content;
56 | Preconditions.checkArgument(comment!=null);
57 | this.comment = comment;
58 | Preconditions.checkArgument(params!=null);
59 | this.params = params;
60 | Preconditions.checkArgument(methodBinding!=null);
61 | this.methodBinding = methodBinding;
62 | Preconditions.checkArgument(fullReturnType!=null);
63 | this.fullReturnType = fullReturnType;
64 | Preconditions.checkArgument(belongTo!=null);
65 | this.belongTo = belongTo;
66 | Preconditions.checkArgument(fullParams!=null);
67 | this.fullParams = fullParams;
68 | Preconditions.checkArgument(fullVariables!=null);
69 | this.fullVariables = fullVariables;
70 | Preconditions.checkArgument(methodCalls!=null);
71 | this.methodCalls = methodCalls;
72 | Preconditions.checkArgument(fieldAccesses!=null);
73 | this.fieldAccesses = fieldAccesses;
74 | Preconditions.checkArgument(throwTypes!=null);
75 | this.throwTypes = throwTypes;
76 | nodeId=createNode(inserter);
77 | }
78 |
79 | private long createNode(BatchInserter inserter){
80 | Map map=new HashMap<>();
81 | map.put(JavaCodeGraphBuilder.NAME, name);
82 | map.put(JavaCodeGraphBuilder.FULLNAME, fullName);
83 | map.put(JavaCodeGraphBuilder.RETURN_TYPE_STR, returnType);
84 | map.put(JavaCodeGraphBuilder.VISIBILITY, visibility);
85 | map.put(JavaCodeGraphBuilder.IS_CONSTRUCTOR, isConstruct);
86 | map.put(JavaCodeGraphBuilder.IS_ABSTRACT, isAbstract);
87 | map.put(JavaCodeGraphBuilder.IS_STATIC, isStatic);
88 | map.put(JavaCodeGraphBuilder.IS_FINAL, isFinal);
89 | map.put(JavaCodeGraphBuilder.IS_SYNCHRONIZED, isSynchronized);
90 | map.put(JavaCodeGraphBuilder.CONTENT, content);
91 | map.put(JavaCodeGraphBuilder.COMMENT, comment);
92 | map.put(JavaCodeGraphBuilder.PARAM_TYPE_STR, params);
93 | return inserter.createNode(map, JavaCodeGraphBuilder.METHOD);
94 | }
95 |
96 | }
--------------------------------------------------------------------------------
/src/main/java/com/github/linzeqipku/javacode_to_neo4j/JavaCodeGraphBuilder.java:
--------------------------------------------------------------------------------
1 | package com.github.linzeqipku.javacode_to_neo4j;
2 |
3 | import com.github.linzeqipku.javacode_to_neo4j.infos.JavaProjectInfo;
4 | import org.apache.commons.io.FileUtils;
5 | import org.eclipse.jdt.core.JavaCore;
6 | import org.eclipse.jdt.core.dom.AST;
7 | import org.eclipse.jdt.core.dom.ASTParser;
8 | import org.eclipse.jdt.core.dom.CompilationUnit;
9 | import org.eclipse.jdt.core.dom.FileASTRequestor;
10 | import org.neo4j.graphdb.Label;
11 | import org.neo4j.graphdb.RelationshipType;
12 | import org.neo4j.unsafe.batchinsert.BatchInserter;
13 | import org.neo4j.unsafe.batchinsert.BatchInserters;
14 |
15 | import java.io.File;
16 | import java.io.IOException;
17 | import java.util.*;
18 |
19 | public class JavaCodeGraphBuilder {
20 |
21 | public static final Label CLASS = Label.label("Class");
22 | public static final Label METHOD = Label.label("Method");
23 | public static final Label FIELD = Label.label("Field");
24 | public static final RelationshipType EXTEND = RelationshipType.withName("extend");
25 | public static final RelationshipType IMPLEMENT = RelationshipType.withName("implement");
26 | public static final RelationshipType HAVE_METHOD = RelationshipType.withName("haveMethod");
27 | public static final RelationshipType PARAM_TYPE = RelationshipType.withName("paramType");
28 | public static final RelationshipType RETURN_TYPE = RelationshipType.withName("returnType");
29 | public static final RelationshipType THROW_TYPE = RelationshipType.withName("throwType");
30 | public static final RelationshipType METHOD_CALL = RelationshipType.withName("methodCall");
31 | public static final RelationshipType VARIABLE_TYPE = RelationshipType.withName("variableType");
32 | public static final RelationshipType HAVE_FIELD = RelationshipType.withName("haveField");
33 | public static final RelationshipType FIELD_TYPE = RelationshipType.withName("fieldType");
34 | public static final RelationshipType FIELD_ACCESS = RelationshipType.withName("fieldAccess");
35 | public static final String NAME = "name";
36 | public static final String FULLNAME = "fullName";
37 | public static final String IS_INTERFACE = "isInterface";
38 | public static final String VISIBILITY = "visibility";
39 | public static final String IS_ABSTRACT = "isAbstract";
40 | public static final String IS_FINAL="isFinal";
41 | public static final String COMMENT="comment";
42 | public static final String CONTENT="content";
43 | public static final String RETURN_TYPE_STR="returnType";
44 | public static final String TYPE_STR="type";
45 | public static final String PARAM_TYPE_STR="paramType";
46 | public static final String IS_CONSTRUCTOR="isConstructor";
47 | public static final String IS_STATIC="isStatic";
48 | public static final String IS_SYNCHRONIZED="isSynchronized";
49 | private String srcDir;
50 | private BatchInserter inserter= null;
51 |
52 | public static void process(String graphDirPath,String srcDir) throws IOException {
53 | new JavaCodeGraphBuilder(graphDirPath,srcDir).process();
54 | }
55 |
56 | private JavaCodeGraphBuilder(String graphDirPath, String srcDir) throws IOException {
57 | this.srcDir=srcDir;
58 | inserter = BatchInserters.inserter(new File(graphDirPath));
59 | }
60 |
61 | private void process() {
62 | JavaProjectInfo javaProjectInfo = new JavaProjectInfo();
63 | Collection javaFiles = FileUtils.listFiles(new File(srcDir), new String[]{"java"}, true);
64 | Set srcPathSet = new HashSet<>();
65 | Set srcFolderSet = new HashSet<>();
66 | for (File javaFile : javaFiles) {
67 | String srcPath = javaFile.getAbsolutePath();
68 | String srcFolderPath = javaFile.getParentFile().getAbsolutePath();
69 | srcPathSet.add(srcPath);
70 | srcFolderSet.add(srcFolderPath);
71 | }
72 | String[] srcPaths = new String[srcPathSet.size()];
73 | srcPathSet.toArray(srcPaths);
74 | NameResolver.setSrcPathSet(srcPathSet);
75 | String[] srcFolderPaths = new String[srcFolderSet.size()];
76 | srcFolderSet.toArray(srcFolderPaths);
77 | ASTParser parser = ASTParser.newParser(AST.JLS8);
78 | parser.setKind(ASTParser.K_COMPILATION_UNIT);
79 | parser.setEnvironment(null, srcFolderPaths, null, true);
80 | parser.setResolveBindings(true);
81 | Map options = new Hashtable<>();
82 | options.put(JavaCore.COMPILER_CODEGEN_TARGET_PLATFORM, JavaCore.VERSION_1_8);
83 | options.put(JavaCore.COMPILER_SOURCE, JavaCore.VERSION_1_8);
84 | options.put(JavaCore.COMPILER_DOC_COMMENT_SUPPORT, JavaCore.ENABLED);
85 | parser.setCompilerOptions(options);
86 | parser.setBindingsRecovery(true);
87 | parser.createASTs(srcPaths, null, new String[]{}, new FileASTRequestor() {
88 | @Override
89 | public void acceptAST(String sourceFilePath, CompilationUnit javaUnit) {
90 | try {
91 | javaUnit.accept(new JavaASTVisitor(javaProjectInfo, FileUtils.readFileToString(new File(sourceFilePath),"utf-8"),inserter));
92 | } catch (IOException e) {
93 | e.printStackTrace();
94 | }
95 | }
96 | }, null);
97 | javaProjectInfo.parseRels(inserter);
98 | inserter.shutdown();
99 | }
100 |
101 | }
102 |
--------------------------------------------------------------------------------
/src/main/java/com/github/linzeqipku/javacode_to_neo4j/NameResolver.java:
--------------------------------------------------------------------------------
1 | package com.github.linzeqipku.javacode_to_neo4j;
2 |
3 | import org.eclipse.jdt.core.dom.*;
4 |
5 | import java.util.Set;
6 |
7 | /**
8 | * Evaluates fully qualified name of TypeDeclaration, Type and Name objects.
9 | */
10 | public class NameResolver {
11 |
12 | private static Set srcPathSet=null;
13 |
14 | /**
15 | * Evaluates fully qualified name of the TypeDeclaration object.
16 | */
17 | public static String getFullName(TypeDeclaration decl) {
18 | String name = decl.getName().getIdentifier();
19 | ASTNode parent = decl.getParent();
20 | // resolve full name e.g.: A.B
21 | while (parent != null && parent.getClass() == TypeDeclaration.class) {
22 | name = ((TypeDeclaration) parent).getName().getIdentifier() + "." + name;
23 | parent = parent.getParent();
24 | }
25 | // resolve fully qualified name e.g.: some.package.A.B
26 | if (decl.getRoot().getClass() == CompilationUnit.class) {
27 | CompilationUnit root = (CompilationUnit) decl.getRoot();
28 | if (root.getPackage() != null) {
29 | PackageDeclaration pack = root.getPackage();
30 | name = pack.getName().getFullyQualifiedName() + "." + name;
31 | }
32 | }
33 | return name;
34 | }
35 |
36 | /**
37 | * Evaluates fully qualified name of the Type object.
38 | */
39 | public static String getFullName(Type t) {
40 | if (t == null)
41 | return "";
42 |
43 | if (t.isNameQualifiedType()){
44 | return ((NameQualifiedType)t).getQualifier().getFullyQualifiedName();
45 | }
46 | if (t.isPrimitiveType()){
47 | return ((PrimitiveType)t).toString();
48 | }
49 | if (t.isQualifiedType()){
50 | QualifiedType t0 = (QualifiedType) t;
51 | return getFullName(t0.getQualifier()) + "." + t0.getName().getIdentifier();
52 | }
53 | if (t.isSimpleType()){
54 | return getFullName(((SimpleType)t).getName());
55 | }
56 | if (t.isWildcardType()){
57 | return "? (extends|super) "+getFullName(((WildcardType)t).getBound());
58 | }
59 |
60 | if (t.isParameterizedType()) {
61 | ParameterizedType t0=((ParameterizedType) t);
62 | String s=getFullName(t0.getType())+"<";
63 | for (Object type:t0.typeArguments())
64 | s+=getFullName((Type)type)+",";
65 | return s.substring(0,s.length()-1)+">";
66 | }
67 | if (t.isUnionType()) {
68 | UnionType t0=(UnionType)t;
69 | String s="";
70 | for (Object type:t0.types())
71 | s+=getFullName((Type)type)+"|";
72 | return s.substring(0,s.length()-1);
73 | }
74 | if (t.isIntersectionType()){
75 | IntersectionType t0=(IntersectionType)t;
76 | String s="";
77 | for (Object type:t0.types())
78 | s+=getFullName((Type)type)+"&";
79 | return s.substring(0,s.length()-1);
80 | }
81 | if (t.isArrayType()){
82 | return getFullName(((ArrayType)t).getElementType())+"[]";
83 | }
84 | return "";
85 | }
86 |
87 | /**
88 | * Evaluates fully qualified name of the Name object.
89 | */
90 | private static String getFullName(Name name) {
91 | // check if the root node is a CompilationUnit
92 | if (name.getRoot().getClass() != CompilationUnit.class) {
93 | // cannot resolve a full name, CompilationUnit root node is missing
94 | return name.getFullyQualifiedName();
95 | }
96 | // get the root node
97 | CompilationUnit root = (CompilationUnit) name.getRoot();
98 | // check if the name is declared in the same file
99 | TypeDeclVisitor tdVisitor = new TypeDeclVisitor(name.getFullyQualifiedName());
100 | root.accept(tdVisitor);
101 | if (tdVisitor.getFound()) {
102 | // the name is the use of the TypeDeclaration in the same file
103 | return getFullName(tdVisitor.getTypeDecl());
104 | }
105 | // check if the name is declared in the same package or imported
106 | PckgImprtVisitor piVisitor = new PckgImprtVisitor(name.getFullyQualifiedName());
107 | root.accept(piVisitor);
108 | if (piVisitor.getFound()) {
109 | // the name is declared in the same package or imported
110 | return piVisitor.getFullName();
111 | }
112 | // could be a class from the java.lang (String) or a param name (T, E,...)
113 | return name.getFullyQualifiedName();
114 | }
115 |
116 | public static void setSrcPathSet(Set srcPathSet) {
117 | NameResolver.srcPathSet = srcPathSet;
118 | }
119 |
120 | private static class PckgImprtVisitor extends ASTVisitor {
121 | private boolean found = false;
122 | private String fullName;
123 | private String name;
124 | private String[] nameParts;
125 |
126 | PckgImprtVisitor(String aName) {
127 | super();
128 | name = aName;
129 | nameParts = name.split("\\.");
130 | }
131 |
132 | private void checkInDir(String dirName) {
133 | String name=dirName+"."+nameParts[0] + ".java";
134 | for (String fileName:srcPathSet){
135 | fileName=fileName.replace("\\", ".").replace("/", ".");
136 | if (fileName.contains(name)){
137 | fullName = dirName;
138 | for (String namePart : nameParts) {
139 | fullName += "." + namePart;
140 | }
141 | found = true;
142 | }
143 | }
144 | }
145 |
146 | public boolean visit(PackageDeclaration node) {
147 | String pckgName = node.getName().getFullyQualifiedName();
148 | checkInDir(pckgName);
149 | return true;
150 | }
151 |
152 | public boolean visit(ImportDeclaration node) {
153 | if (node.isOnDemand()) {
154 | String pckgName = node.getName().getFullyQualifiedName();
155 | checkInDir(pckgName);
156 | } else {
157 | String importName = node.getName().getFullyQualifiedName();
158 | if (importName.endsWith("." + nameParts[0])) {
159 | fullName = importName;
160 | for (int i = 1; i < nameParts.length; i++) {
161 | fullName += "." + nameParts[i];
162 | }
163 | found = true;
164 | }
165 | }
166 | return true;
167 | }
168 |
169 | boolean getFound() {
170 | return found;
171 | }
172 |
173 | String getFullName() {
174 | return fullName;
175 | }
176 |
177 | }
178 |
179 | private static class TypeDeclVisitor extends ASTVisitor {
180 | private boolean found = false;
181 | private TypeDeclaration typeDecl;
182 | private String name;
183 |
184 | TypeDeclVisitor(String aName) {
185 | super();
186 | name = aName;
187 | }
188 |
189 | public boolean visit(TypeDeclaration node) {
190 | if (getFullName(node).endsWith("." + name)) {
191 | found = true;
192 | typeDecl = node;
193 | }
194 | return true;
195 | }
196 |
197 | boolean getFound() {
198 | return found;
199 | }
200 |
201 | TypeDeclaration getTypeDecl() {
202 | return typeDecl;
203 | }
204 | }
205 | }
206 |
--------------------------------------------------------------------------------
/src/main/java/com/github/linzeqipku/javacode_to_neo4j/JavaASTVisitor.java:
--------------------------------------------------------------------------------
1 | package com.github.linzeqipku.javacode_to_neo4j;
2 |
3 | import com.github.linzeqipku.javacode_to_neo4j.infos.JavaClassInfo;
4 | import com.github.linzeqipku.javacode_to_neo4j.infos.JavaFieldInfo;
5 | import com.github.linzeqipku.javacode_to_neo4j.infos.JavaMethodInfo;
6 | import com.github.linzeqipku.javacode_to_neo4j.infos.JavaProjectInfo;
7 | import org.eclipse.jdt.core.dom.*;
8 | import org.neo4j.unsafe.batchinsert.BatchInserter;
9 |
10 | import java.util.ArrayList;
11 | import java.util.HashSet;
12 | import java.util.List;
13 | import java.util.Set;
14 | import java.util.stream.Collectors;
15 |
16 | public class JavaASTVisitor extends ASTVisitor {
17 |
18 | private JavaProjectInfo javaProjectInfo;
19 | private String sourceContent;
20 | private BatchInserter inserter;
21 |
22 | public JavaASTVisitor(JavaProjectInfo javaProjectInfo, String sourceContent, BatchInserter inserter) {
23 | this.javaProjectInfo = javaProjectInfo;
24 | this.sourceContent = sourceContent;
25 | this.inserter=inserter;
26 | }
27 |
28 | @Override
29 | public boolean visit(TypeDeclaration node) {
30 | JavaClassInfo javaClassInfo = createJavaClassInfo(node);
31 | javaProjectInfo.addClassInfo(javaClassInfo);
32 |
33 | MethodDeclaration[] methodDeclarations = node.getMethods();
34 | for (MethodDeclaration methodDeclaration : methodDeclarations) {
35 | JavaMethodInfo javaMethodInfo = createJavaMethodInfo(methodDeclaration, javaClassInfo.getFullName());
36 | if (javaMethodInfo!=null)
37 | javaProjectInfo.addMethodInfo(javaMethodInfo);
38 | }
39 |
40 | FieldDeclaration[] fieldDeclarations = node.getFields();
41 | for (FieldDeclaration fieldDeclaration : fieldDeclarations) {
42 | List javaFieldInfos = createJavaFieldInfos(fieldDeclaration, javaClassInfo.getFullName());
43 | for (JavaFieldInfo javaFieldInfo : javaFieldInfos)
44 | javaProjectInfo.addFieldInfo(javaFieldInfo);
45 | }
46 | System.out.println("Class "+javaClassInfo.getFullName()+" parsed. ("+javaClassInfo.getNodeId()+").");
47 | return false;
48 | }
49 |
50 | private JavaClassInfo createJavaClassInfo(TypeDeclaration node){
51 | String name = node.getName().getFullyQualifiedName();
52 | String fullName = NameResolver.getFullName(node);
53 | boolean isInterface = node.isInterface();
54 | String visibility = JavaASTVisitor.getVisibility(node.getModifiers());
55 | boolean isAbstract = Modifier.isAbstract(node.getModifiers());
56 | boolean isFinal = Modifier.isFinal(node.getModifiers());
57 | String comment = node.getJavadoc()==null?"":sourceContent.substring(node.getJavadoc().getStartPosition(), node.getJavadoc().getStartPosition() + node.getJavadoc().getLength());
58 | String content = sourceContent.substring(node.getStartPosition(), node.getStartPosition() + node.getLength());
59 | String superClassType = node.getSuperclassType() == null ? "java.lang.Object" : NameResolver.getFullName(node.getSuperclassType());
60 | String superInterfaceTypes = String.join(", ",(List)node.superInterfaceTypes().stream().map(n-> NameResolver.getFullName((Type) n)).collect(Collectors.toList()));
61 | return new JavaClassInfo(inserter,name,fullName,isInterface,visibility,isAbstract,isFinal,comment,content,superClassType,superInterfaceTypes);
62 | }
63 |
64 | private JavaMethodInfo createJavaMethodInfo(MethodDeclaration node, String belongTo) {
65 | IMethodBinding methodBinding = node.resolveBinding();
66 | if (methodBinding==null)
67 | return null;
68 | String name = node.getName().getFullyQualifiedName();
69 | Type type = node.getReturnType2();
70 | String returnType = type == null ? "void" : type.toString();
71 | String fullReturnType = NameResolver.getFullName(type);
72 | String visibility = getVisibility(node.getModifiers());
73 | boolean isConstruct = node.isConstructor();
74 | boolean isAbstract = Modifier.isAbstract(node.getModifiers());
75 | boolean isFinal = Modifier.isFinal(node.getModifiers());
76 | boolean isStatic = Modifier.isStatic(node.getModifiers());
77 | boolean isSynchronized = Modifier.isSynchronized(node.getModifiers());
78 | String content = sourceContent.substring(node.getStartPosition(), node.getStartPosition() + node.getLength());
79 | String comment = node.getJavadoc()==null?"":sourceContent.substring(node.getJavadoc().getStartPosition(), node.getJavadoc().getStartPosition() + node.getJavadoc().getLength());
80 | String params = String.join(", ", (List)node.parameters().stream().map(n->{
81 | SingleVariableDeclaration param=(SingleVariableDeclaration)n;
82 | return (Modifier.isFinal(param.getModifiers()) ? "final " : "") + param.getType().toString() + " " + param.getName().getFullyQualifiedName();
83 | }).collect(Collectors.toList()));
84 | String fullName=belongTo+"."+name+"( "+params+" )";
85 | String fullParams = String.join(", ", (List)node.parameters().stream().map(n->{
86 | SingleVariableDeclaration param=(SingleVariableDeclaration)n;
87 | return NameResolver.getFullName(param.getType());
88 | }).collect(Collectors.toList()));
89 | String throwTypes = String.join(", ", (List)node.thrownExceptionTypes().stream().map(n-> NameResolver.getFullName((Type)n)).collect(Collectors.toList()));
90 | Set methodCalls=new HashSet<>();
91 | StringBuilder fullVariables=new StringBuilder();
92 | StringBuilder fieldAccesses=new StringBuilder();
93 | parseMethodBody(methodCalls, fullVariables, fieldAccesses, node.getBody());
94 | JavaMethodInfo info= new JavaMethodInfo(inserter,name,fullName,returnType,visibility,isConstruct,isAbstract,
95 | isFinal,isStatic,isSynchronized,content,comment,params,methodBinding,
96 | fullReturnType,belongTo,fullParams,fullVariables.toString(), methodCalls, fieldAccesses.toString(), throwTypes);
97 | return info;
98 | }
99 |
100 | private List createJavaFieldInfos(FieldDeclaration node, String belongTo) {
101 | List r=new ArrayList<>();
102 | String type=node.getType().toString();
103 | String fullType= NameResolver.getFullName(node.getType());
104 | String visibility=getVisibility(node.getModifiers());
105 | boolean isStatic=Modifier.isStatic(node.getModifiers());
106 | boolean isFinal=Modifier.isFinal(node.getModifiers());
107 | String comment=node.getJavadoc()==null?"":sourceContent.substring(node.getJavadoc().getStartPosition(), node.getJavadoc().getStartPosition() + node.getJavadoc().getLength());
108 | node.fragments().forEach(n->{
109 | VariableDeclarationFragment fragment=(VariableDeclarationFragment)n;
110 | String name=fragment.getName().getFullyQualifiedName();
111 | String fullName=belongTo+"."+name;
112 | r.add(new JavaFieldInfo(inserter,name,fullName,type,visibility,isStatic,isFinal,comment,belongTo,fullType));
113 | });
114 | return r;
115 | }
116 |
117 | private void parseMethodBody(Set methodCalls, StringBuilder fullVariables, StringBuilder fieldAccesses, Block methodBody) {
118 | if (methodBody == null)
119 | return;
120 | List statementList = methodBody.statements();
121 | List statements = new ArrayList<>();
122 | for (int i = 0; i < statementList.size(); i++) {
123 | statements.add(statementList.get(i));
124 | }
125 | for (int i = 0; i < statements.size(); i++) {
126 |
127 | if (statements.get(i).getNodeType() == ASTNode.BLOCK) {
128 | List blockStatements = ((Block) statements.get(i)).statements();
129 | for (int j = 0; j < blockStatements.size(); j++) {
130 | statements.add(i + j + 1, blockStatements.get(j));
131 | }
132 | continue;
133 | }
134 | if (statements.get(i).getNodeType() == ASTNode.ASSERT_STATEMENT) {
135 | Expression expression = ((AssertStatement) statements.get(i)).getExpression();
136 | if (expression != null) {
137 | parseExpression(methodCalls,fullVariables,fieldAccesses, expression);
138 | }
139 | expression = ((AssertStatement) statements.get(i)).getMessage();
140 | if (expression != null) {
141 | parseExpression(methodCalls,fullVariables,fieldAccesses, expression);
142 | }
143 | }
144 |
145 | if (statements.get(i).getNodeType() == ASTNode.DO_STATEMENT) {
146 | Expression expression = ((DoStatement) statements.get(i)).getExpression();
147 | if (expression != null) {
148 | parseExpression(methodCalls,fullVariables,fieldAccesses, expression);
149 | }
150 | Statement doBody = ((DoStatement) statements.get(i)).getBody();
151 | if (doBody != null) {
152 | statements.add(i + 1, doBody);
153 | }
154 | }
155 | if (statements.get(i).getNodeType() == ASTNode.ENHANCED_FOR_STATEMENT) {
156 | Expression expression = ((EnhancedForStatement) statements.get(i)).getExpression();
157 | Type type = ((EnhancedForStatement) statements.get(i)).getParameter().getType();
158 | fullVariables.append(NameResolver.getFullName(type)+", ");
159 | if (expression != null) {
160 | parseExpression(methodCalls,fullVariables,fieldAccesses, expression);
161 | }
162 | Statement forBody = ((EnhancedForStatement) statements.get(i)).getBody();
163 | if (forBody != null) {
164 | statements.add(i + 1, forBody);
165 | }
166 | }
167 | if (statements.get(i).getNodeType() == ASTNode.EXPRESSION_STATEMENT) {
168 | Expression expression = ((ExpressionStatement) statements.get(i)).getExpression();
169 | if (expression != null) {
170 | parseExpression(methodCalls,fullVariables,fieldAccesses, expression);
171 | }
172 | }
173 | if (statements.get(i).getNodeType() == ASTNode.FOR_STATEMENT) {
174 | List list = ((ForStatement) statements.get(i)).initializers();
175 | for (int j = 0; j < list.size(); j++) {
176 | parseExpression(methodCalls,fullVariables,fieldAccesses, list.get(j));
177 | }
178 | Expression expression = ((ForStatement) statements.get(i)).getExpression();
179 | if (expression != null) {
180 | parseExpression(methodCalls,fullVariables,fieldAccesses, expression);
181 | }
182 | Statement forBody = ((ForStatement) statements.get(i)).getBody();
183 | if (forBody != null) {
184 | statements.add(i + 1, forBody);
185 | }
186 | }
187 | if (statements.get(i).getNodeType() == ASTNode.IF_STATEMENT) {
188 | Expression expression = ((IfStatement) statements.get(i)).getExpression();
189 | if (expression != null) {
190 | parseExpression(methodCalls,fullVariables,fieldAccesses, expression);
191 | }
192 | Statement thenStatement = ((IfStatement) statements.get(i)).getThenStatement();
193 | Statement elseStatement = ((IfStatement) statements.get(i)).getElseStatement();
194 | if (elseStatement != null) {
195 | statements.add(i + 1, elseStatement);
196 | }
197 | if (thenStatement != null) {
198 | statements.add(i + 1, thenStatement);
199 | }
200 | }
201 | if (statements.get(i).getNodeType() == ASTNode.RETURN_STATEMENT) {
202 | Expression expression = ((ReturnStatement) statements.get(i)).getExpression();
203 | if (expression != null) {
204 | parseExpression(methodCalls,fullVariables,fieldAccesses, expression);
205 | }
206 | }
207 | if (statements.get(i).getNodeType() == ASTNode.SWITCH_STATEMENT) {
208 | Expression expression = ((SwitchStatement) statements.get(i)).getExpression();
209 | if (expression != null) {
210 | parseExpression(methodCalls,fullVariables,fieldAccesses, expression);
211 | }
212 | List switchStatements = ((SwitchStatement) statements.get(i)).statements();
213 | for (int j = 0; j < switchStatements.size(); j++) {
214 | statements.add(i + j + 1, switchStatements.get(j));
215 | }
216 | }
217 | if (statements.get(i).getNodeType() == ASTNode.THROW_STATEMENT) {
218 | Expression expression = ((ThrowStatement) statements.get(i)).getExpression();
219 | if (expression != null) {
220 | parseExpression(methodCalls,fullVariables,fieldAccesses, expression);
221 | }
222 | }
223 | if (statements.get(i).getNodeType() == ASTNode.TRY_STATEMENT) {
224 | Statement tryStatement = ((TryStatement) statements.get(i)).getBody();
225 | if (tryStatement != null) {
226 | statements.add(i + 1, tryStatement);
227 | }
228 | continue;
229 | }
230 | if (statements.get(i).getNodeType() == ASTNode.VARIABLE_DECLARATION_STATEMENT) {
231 | Type type = ((VariableDeclarationStatement) statements.get(i)).getType();
232 | fullVariables.append(NameResolver.getFullName(type)+", ");
233 | ((VariableDeclarationStatement) statements.get(i)).fragments().forEach(n->parseExpression(methodCalls,fullVariables,fieldAccesses, ((VariableDeclaration)n).getInitializer()));
234 | }
235 | if (statements.get(i).getNodeType() == ASTNode.WHILE_STATEMENT) {
236 | Expression expression = ((WhileStatement) statements.get(i)).getExpression();
237 | if (expression != null) {
238 | parseExpression(methodCalls,fullVariables,fieldAccesses, expression);
239 | }
240 | Statement whileBody = ((WhileStatement) statements.get(i)).getBody();
241 | if (whileBody != null) {
242 | statements.add(i + 1, whileBody);
243 | }
244 | }
245 | }
246 | }
247 |
248 | private void parseExpression(Set methodCalls, StringBuilder fullVariables, StringBuilder fieldAccesses, Expression expression) {
249 | if (expression == null) {
250 | return;
251 | }//System.out.println(expression.toString()+" "+Annotation.nodeClassForType(expression.getNodeType()));
252 | if (expression.getNodeType() == ASTNode.ARRAY_INITIALIZER) {
253 | List expressions = ((ArrayInitializer) expression).expressions();
254 | for (Expression expression2 : expressions) {
255 | parseExpression(methodCalls,fullVariables,fieldAccesses, expression2);
256 | }
257 | }
258 | if (expression.getNodeType() == ASTNode.CAST_EXPRESSION) {
259 | parseExpression(methodCalls,fullVariables,fieldAccesses, ((CastExpression) expression).getExpression());
260 | }
261 | if (expression.getNodeType() == ASTNode.CONDITIONAL_EXPRESSION) {
262 | parseExpression(methodCalls,fullVariables,fieldAccesses, ((ConditionalExpression) expression).getExpression());
263 | parseExpression(methodCalls,fullVariables,fieldAccesses, ((ConditionalExpression) expression).getElseExpression());
264 | parseExpression(methodCalls,fullVariables,fieldAccesses, ((ConditionalExpression) expression).getThenExpression());
265 | }
266 | if (expression.getNodeType() == ASTNode.INFIX_EXPRESSION) {
267 | parseExpression(methodCalls,fullVariables,fieldAccesses, ((InfixExpression) expression).getLeftOperand());
268 | parseExpression(methodCalls,fullVariables,fieldAccesses, ((InfixExpression) expression).getRightOperand());
269 | }
270 | if (expression.getNodeType() == ASTNode.INSTANCEOF_EXPRESSION) {
271 | parseExpression(methodCalls,fullVariables,fieldAccesses, ((InstanceofExpression) expression).getLeftOperand());
272 | }
273 | if (expression.getNodeType() == ASTNode.PARENTHESIZED_EXPRESSION) {
274 | parseExpression(methodCalls,fullVariables,fieldAccesses, ((ParenthesizedExpression) expression).getExpression());
275 | }
276 | if (expression.getNodeType() == ASTNode.POSTFIX_EXPRESSION) {
277 | parseExpression(methodCalls,fullVariables,fieldAccesses, ((PostfixExpression) expression).getOperand());
278 | }
279 | if (expression.getNodeType() == ASTNode.PREFIX_EXPRESSION) {
280 | parseExpression(methodCalls,fullVariables,fieldAccesses, ((PrefixExpression) expression).getOperand());
281 | }
282 | if (expression.getNodeType() == ASTNode.THIS_EXPRESSION) {
283 | parseExpression(methodCalls,fullVariables,fieldAccesses, ((ThisExpression) expression).getQualifier());
284 | }
285 | if (expression.getNodeType() == ASTNode.METHOD_INVOCATION) {
286 | List arguments = ((MethodInvocation) expression).arguments();
287 | IMethodBinding methodBinding = ((MethodInvocation) expression).resolveMethodBinding();
288 | if (methodBinding != null)
289 | methodCalls.add(methodBinding);
290 | for (Expression exp : arguments)
291 | parseExpression(methodCalls,fullVariables,fieldAccesses, exp);
292 | parseExpression(methodCalls,fullVariables,fieldAccesses, ((MethodInvocation) expression).getExpression());
293 | }
294 | if (expression.getNodeType() == ASTNode.ASSIGNMENT) {
295 | parseExpression(methodCalls,fullVariables,fieldAccesses, ((Assignment) expression).getLeftHandSide());
296 | parseExpression(methodCalls,fullVariables,fieldAccesses, ((Assignment) expression).getRightHandSide());
297 | }
298 | if (expression.getNodeType() == ASTNode.QUALIFIED_NAME) {
299 | if (((QualifiedName) expression).getQualifier().resolveTypeBinding() != null) {
300 | String name = ((QualifiedName) expression).getQualifier().resolveTypeBinding().getQualifiedName() + "." + ((QualifiedName) expression).getName().getIdentifier();
301 | fieldAccesses.append(name+", ");
302 | }
303 | parseExpression(methodCalls,fullVariables,fieldAccesses, ((QualifiedName) expression).getQualifier());
304 | }
305 | }
306 |
307 | private static String getVisibility(int modifiers){
308 | if (Modifier.isPrivate(modifiers))
309 | return "private";
310 | if (Modifier.isProtected(modifiers))
311 | return "protected";
312 | if (Modifier.isPublic(modifiers))
313 | return "public";
314 | return "package";
315 | }
316 |
317 | }
318 |
--------------------------------------------------------------------------------