├── .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 | --------------------------------------------------------------------------------