Giter Site home page Giter Site logo

Comments (5)

LinWanCen avatar LinWanCen commented on June 15, 2024 1

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.

MysterAitch avatar MysterAitch commented on June 15, 2024

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.

MysterAitch avatar MysterAitch commented on June 15, 2024

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.

https://www.github.com/javaparser/javasymbolsolver-maven-sample/tree/master/src%2Fmain%2Fjava%2Fcom%2Fyourorganization%2Fmaven_sample%2FMyAnalysis.java

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 the findAll)
  • 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.

LinWanCen avatar LinWanCen commented on June 15, 2024

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.

LinWanCen avatar LinWanCen commented on June 15, 2024

I dev a tool: https://github.com/LinWanCen/java-to-diagrams

from javasymbolsolver-maven-sample.

Related Issues (6)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo 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.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.