Comments (5)
As in IntelliJ IDEA Ctrl + Alt +H or Alt + F7, I wan to find all in project to analysis.
I found the wrong way to use AST,
AST only has language, it can't find which class the method belongs to.
CompilationUnit cu = StaticJavaParser.parse(s);
cu.findAll(MethodCallExpr.class).forEach(a -> {
List<String> list = a.getArguments().stream().map(Objects::toString).collect(Collectors.toList());
String join = String.join(", ", list);
System.out.println(a.getName() + "(" + join + ")");
});
from javasymbolsolver-maven-sample.
I want to resolve the calling relationship, but I do nโt know how to use
Hi, could you give an example of what you mean by the calling relationship please?
from javasymbolsolver-maven-sample.
Hi,
This file may give you some additional information about how to setup the symbol solver -- note that the snippet you posted has no configuration set, therefore does only AST parsing.
At the moment, JavaParser has functionality to go from a usage to its declaration (if wanting the other way around - from a declaration to its usages - then you should implement this).
This can be done via:
- Get a
MethodCallExpr
(as you have done with thefindAll
) - Resolve it - this gives you a
MethodUsage
MethodUsage#getDeclaration()
will then give you access to where it is declared (e.g. you can find the class/interface and the compilation unit as ancestors).
If you would like to go the other way, you can create a lookup table for the references you are interested in (e.g. only method usages for classes within packages you have created, ignoring fields and local variables and JDK classes). Such a lookup table could be a HashMap, with the declaration as the key and a collection of method usages as the value.
Hope this helps!
from javasymbolsolver-maven-sample.
thanks!
The problem is solved.
my program has some exceptions,
and "FieldAccessExpr" do not parse to own field:
MethodCallExpr: Unsolved symbol in m.findAll(MethodCallExpr.class).forEach(expr -> {
try {
String call = expr.resolve().getQualifiedSignature();
if (call.startsWith("java")) {
return;
}
put(methodCallMap, usage, call);
put(methodUsageMap, call, usage);
} catch (Exception e) {
System.err.println("MethodCallExpr: " + e.getLocalizedMessage());
}
}) : m.findAll(MethodCallExpr.class)
MethodCallExpr: Unsolved symbol in expr.resolve().getQualifiedSignature() : expr.resolve()
MethodCallExpr: Unsolved symbol in expr.resolve() : expr
MethodCallExpr: Unsolved symbol in m.findAll(FieldAccessExpr.class).forEach(expr -> {
try {
ResolvedFieldDeclaration field = expr.resolve().asField();
String className = field.declaringType().getQualifiedName();
if (className.startsWith("java")) {
return;
}
String call = className + "." + field.getName();
put(fieldCallMap, usage, call);
put(fieldUsageMap, call, usage);
} catch (Exception e) {
System.err.println("FieldAccessExpr: " + e.getLocalizedMessage());
}
}) : m.findAll(FieldAccessExpr.class)
MethodCallExpr: Unsolved symbol in expr.resolve().asField() : expr.resolve()
MethodCallExpr: Unsolved symbol in expr.resolve() : expr
MethodCallExpr: Unable to calculate the type of a parameter of a method call. Method call: System.out.println(" L " + k2), Parameter: " L " + k2
MethodCallExpr: Unsolved symbol in v2.forEach(usage -> {
System.out.println(" L " + usage);
}) : v2
MethodCallExpr: Unable to calculate the type of a parameter of a method call. Method call: System.out.println(" L " + usage), Parameter: " L " + usage
fieldCall
L com.yourorganization.maven_sample.MethodCall.main(java.lang.String[])
L com.yourorganization.maven_sample.B.METHOD_CALL
L com.yourorganization.maven_sample.B.STRING_CALL
methodCall
...
package com.yourorganization.maven_sample;
import com.github.javaparser.StaticJavaParser;
import com.github.javaparser.ast.CompilationUnit;
import com.github.javaparser.ast.expr.FieldAccessExpr;
import com.github.javaparser.ast.expr.MethodCallExpr;
import com.github.javaparser.resolution.declarations.ResolvedFieldDeclaration;
import com.github.javaparser.symbolsolver.JavaSymbolSolver;
import com.github.javaparser.symbolsolver.resolution.typesolvers.ClassLoaderTypeSolver;
import com.github.javaparser.symbolsolver.resolution.typesolvers.CombinedTypeSolver;
import java.io.File;
import java.lang.reflect.Field;
import java.nio.charset.StandardCharsets;
import java.nio.file.Files;
import java.util.*;
public class MethodCall {
private static final String CLASS_PATH = ClassLoader.getSystemClassLoader().getResource("").getPath();
private static final File PROJECT_FILE = new File(CLASS_PATH).getParentFile().getParentFile();
private static final File SRC_MAIN_JAVA_FILE = new File(PROJECT_FILE, "/src/main/java");
private static final String FILE_NAME = MethodCall.class.getName().replace('.', '/') + ".java";
private static final File FILE = new File(SRC_MAIN_JAVA_FILE, FILE_NAME);
private static final String FIELD_USAGE = "fieldUsage";
static final String METHOD_USAGE = "methodUsage";;
protected static final String STRING_USAGE = "stringUsage";
public static final String FIELD_CALL = "fieldCall";
public static void main(String[] args) throws Exception {
Map<String, Map<String, Set<String>>> map = new LinkedHashMap<>();
Map<String, Set<String>> fieldCallMap = new LinkedHashMap<>();
Map<String, Set<String>> methodCallMap = new LinkedHashMap<>();
Map<String, Set<String>> stringCallMap = new LinkedHashMap<>();
Map<String, Set<String>> fieldUsageMap = new LinkedHashMap<>();
Map<String, Set<String>> methodUsageMap = new LinkedHashMap<>();
Map<String, Set<String>> stringUsageMap = new LinkedHashMap<>();
map.put(FIELD_CALL, fieldCallMap);
map.put(B.METHOD_CALL, methodCallMap);
map.put(B.STRING_CALL, stringCallMap);
map.put(FIELD_USAGE, fieldUsageMap);
map.put(METHOD_USAGE, methodUsageMap);
map.put(STRING_USAGE, stringUsageMap);
byte[] bytes = Files.readAllBytes(FILE.getAbsoluteFile().toPath());
String s = new String(bytes, StandardCharsets.UTF_8);
CombinedTypeSolver combinedTypeSolver = new CombinedTypeSolver();
combinedTypeSolver.add(new ClassLoaderTypeSolver(ClassLoader.getSystemClassLoader()));
JavaSymbolSolver symbolSolver = new JavaSymbolSolver(combinedTypeSolver);
StaticJavaParser.getConfiguration().setSymbolResolver(symbolSolver);
CompilationUnit cu = StaticJavaParser.parse(s);
cu.getTypes().forEach(t -> {
String typeName = t.resolve().getQualifiedName();
t.getMembers().forEach(m -> {
String usage;
if (m.isMethodDeclaration()) {
usage = m.asMethodDeclaration().resolve().getQualifiedSignature();
} else if (m.isFieldDeclaration()) {
ResolvedFieldDeclaration field = m.asFieldDeclaration().resolve();
String name = field.getName();
usage = typeName + "." + name;
if (field.isStatic()
&& "java.lang.String".equals(field.getType().describe())) {
try {
Class<?> c = Class.forName(typeName);
Field f = c.getDeclaredField(name);
String call = f.get(c).toString();
put(stringCallMap, usage, call);
put(stringUsageMap, call, usage);
} catch (Exception e) {
System.err.println("FieldDeclaration: " + e.getLocalizedMessage());
}
}
} else {
usage = typeName;
}
// skip MethodReferenceExpr
m.findAll(MethodCallExpr.class).forEach(expr -> {
try {
String call = expr.resolve().getQualifiedSignature();
if (call.startsWith("java")) {
return;
}
put(methodCallMap, usage, call);
put(methodUsageMap, call, usage);
} catch (Exception e) {
System.err.println("MethodCallExpr: " + e.getLocalizedMessage());
}
});
m.findAll(FieldAccessExpr.class).forEach(expr -> {
try {
ResolvedFieldDeclaration field = expr.resolve().asField();
String className = field.declaringType().getQualifiedName();
if (className.startsWith("java")) {
return;
}
String call = className + "." + field.getName();
put(fieldCallMap, usage, call);
put(fieldUsageMap, call, usage);
} catch (Exception e) {
System.err.println("FieldAccessExpr: " + e.getLocalizedMessage());
}
});
});
});
map.forEach((k, v) -> {
System.out.println();
System.out.println(k);
v.forEach((k2, v2) -> {
System.out.println(" L " + k2);
v2.forEach(usage -> {
System.out.println(" L " + usage);
});
});
});
}
public static void put(Map<String, Set<String>> map, String key, String value) {
Set<String> set = map.get(key);
if (set == null) {
set = new LinkedHashSet<>();
map.put(key, set);
}
set.add(value);
}
}
class B{
static final String METHOD_USAGE = "methodUsage";;
protected static final String METHOD_CALL = "methodCall";
public static final String STRING_CALL = "stringCall";
}
from javasymbolsolver-maven-sample.
I dev a tool: https://github.com/LinWanCen/java-to-diagrams
from javasymbolsolver-maven-sample.
Related Issues (6)
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
๐ Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
D3
Bring data to life with SVG, Canvas and HTML. ๐๐๐
-
Recommend Topics
-
javascript
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
-
web
Some thing interesting about web. New door for the world.
-
server
A server is a program made to process requests and deliver data to clients.
-
Machine learning
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google โค๏ธ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from javasymbolsolver-maven-sample.