Eclipse JDT:如何查找JDK MethodInvocation和ClassInstanceCreation [英] Eclipse JDT: How to find JDK MethodInvocation and ClassInstanceCreation

查看:203
本文介绍了Eclipse JDT:如何查找JDK MethodInvocation和ClassInstanceCreation的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在使用 Eclipse JDT ASTVisitor 从Java源文件中查找Java方法调用和类实例创建。

I am using Eclipse JDT ASTVisitor to find Java method invocations and class instance creations from java source files.

现在,我可以找到所有这些。但是我无法判断这些方法调用和类实例创建是否是否来自JDK库

Now, I can find all of these. But I can not judge whether these method invocations and class instance creations is from JDK library or not.

因此,如何获得JDK库方法调用(例如:InputStream.read())和类实例(例如:new String())?

So, How can I get the JDK library method invocations (eg: InputStream.read()) and class instance (eg: new String())?

以下是我的代码。

JdtAstUtil.java

JdtAstUtil.java

import java.io.BufferedInputStream;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import org.eclipse.jdt.core.dom.AST;
import org.eclipse.jdt.core.dom.ASTParser;
import org.eclipse.jdt.core.dom.CompilationUnit;

public class JdtAstUtil {
    /**
     * get compilation unit of source code
     * @param javaFilePath
     * @return CompilationUnit
     */
    public static CompilationUnit getCompilationUnit(String javaFilePath){
        byte[] input = null;
        try {
            BufferedInputStream bufferedInputStream = new BufferedInputStream(new FileInputStream(javaFilePath));
            input = new byte[bufferedInputStream.available()];
            bufferedInputStream.read(input);
            bufferedInputStream.close();
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }
        ASTParser astParser = ASTParser.newParser(AST.JLS4);
        astParser.setSource(new String(input).toCharArray());
        astParser.setKind(ASTParser.K_COMPILATION_UNIT);
        astParser.setEnvironment(null, null, null, true);
        astParser.setResolveBindings(true);
        astParser.setBindingsRecovery(true);
        astParser.setUnitName("any_name");
        CompilationUnit result = (CompilationUnit) (astParser.createAST(null));
        return result;
    }
}  

DemoVisitor.java

DemoVisitor.java

import org.eclipse.jdt.core.dom.*;

public class DemoVisitor extends ASTVisitor {

    @Override
    public boolean visit(MethodInvocation node) {
        System.out.println("MethodInvocation:\t" + node.toString());
        System.out.println("\tExpression: " + node.getExpression());
        Expression expression = node.getExpression();
        if(expression != null) {
            ITypeBinding  typeBinding = expression.resolveTypeBinding();
            if (typeBinding != null) {
                System.out.println("\tType: " + typeBinding.getName());
            }
        }
        System.out.println("\tName: " + node.getName());
        // System.out.println("\t" + node.resolveMethodBinding());
        return true;
    }

    public void endVisit(ClassInstanceCreation node) {
        System.out.println("ClassInstanceCreation:\t" + node.toString());
        System.out.println("\tType: " + node.getType().toString());
    }
}  

DemoVisitorTest.java

DemoVisitorTest.java

import org.eclipse.jdt.core.dom.CompilationUnit;

public class DemoVisitorTest {

    public DemoVisitorTest(String path) {
        CompilationUnit comp = JdtAstUtil.getCompilationUnit(path);
        DemoVisitor visitor = new DemoVisitor();
        comp.accept(visitor);
    }
    public static void main(String args[]) {
        DemoVisitorTest test = new DemoVisitorTest
                ("/home/luckcul/developSpace/test/test.java");
    }
}  

我使用上面的代码来解析以下测试。

I used the above codes to parse the following test.java file.

test.java

test.java

package com.mtihc.minecraft.myhelppages;

import java.util.Arrays;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import org.bukkit.ChatColor;
import org.bukkit.command.Command;
import org.bukkit.command.CommandExecutor;
import org.bukkit.command.CommandSender;

public class HelpCommandExecutor implements CommandExecutor {

    /***
     * Copies bytes from a large (over 2GB) InputStream to an OutputStream.
     * This method uses the provided buffer, so there is no need to use a
     * BufferedInputStream.
     * @param input the InputStream to read from
    * */
    public static long copyLarge(final InputStream input,
                                 final OutputStream output, final byte[] buffer) throws IOException {
        long count = 0;
        int n;
        CommandExecutor t = new CommandExecutor(new String());
        while (EOF != (n = input.read(buffer))) {
            output.write(buffer, 0, n);
        t.test();
            count += n;
        }
        return count;
    }
}

最后,我得到了这些:

ClassInstanceCreation:  new String()
    Type: String
ClassInstanceCreation:  new CommandExecutor(new String())
    Type: CommandExecutor
MethodInvocation:   input.read(buffer)
    Expression: input
    Type: InputStream
    Name: read
MethodInvocation:   output.write(buffer,0,n)
    Expression: output
    Type: OutputStream
    Name: write
MethodInvocation:   t.test()
    Expression: t
    Type: CommandExecutor
    Name: test

在此示例中,我只想获取 new来自JDK库的String(),InputStream.read(),OutputStream.write()

In this example, I only want to get new String(), InputStream.read(), OutputStream.write(), which is from JDK library.

如何修改代码解决我的问题?

How can I modify my codes to solve my problems ?

推荐答案

您可能想使用JDT的Java模型来查找有关被调用方法的声明类。策略的基本(未经测试)草图:

You may want to use the JDT's Java Model to find out about the declaring class of the invoked method. Basic (untested) sketch of a strategy:

ITypeBinding declaringType = invocation.resolveMethodBinding().getDeclaringClass();
IJavaProject javaProject = JavaCore.create(iProject); // assumes you have an IProject
IType type = javaProject.findType(declaringType.getQualifiedName());
IJavaElement root = type.getAncestor(IJavaElement.PACKAGE_FRAGMENT_ROOT);
IClasspathEntry cpEntry = ((IPackageFragmentRoot) root).getRawClasspathEntry();

对于JDK类型, cpEntry 应该是 getEntryKind() CPE_CONTAINER 及其 getPath()应该以 org.eclipse.jdt.launching.JRE_CONTAINER开头。。

For JDK types, cpEntry should be of getEntryKind() CPE_CONTAINER, and its getPath() should start with "org.eclipse.jdt.launching.JRE_CONTAINER".

这篇关于Eclipse JDT:如何查找JDK MethodInvocation和ClassInstanceCreation的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆