Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/329.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 不使用eclipse中的AST处理解析绑定_Java_Eclipse_Parsing - Fatal编程技术网

Java 不使用eclipse中的AST处理解析绑定

Java 不使用eclipse中的AST处理解析绑定,java,eclipse,parsing,Java,Eclipse,Parsing,我正在使用EclipseJDTAST解析器来处理一些Java代码,并试图提取字段和方法声明的类型绑定。这样做的逻辑在我的Visitor类中(见下文)。不幸的是,我没有任何运气,并且没有一个绑定正在解析(它们始终为null)。有趣的是,这些绑定与EclipseAstView插件在同一代码上工作。我做错了什么 下面是一些相关的代码片段,希望能帮助人们了解到底发生了什么 ASTParser parser = ASTParser.newParser(AST.JLS3); parser.setKind(

我正在使用EclipseJDTAST解析器来处理一些Java代码,并试图提取字段和方法声明的类型绑定。这样做的逻辑在我的Visitor类中(见下文)。不幸的是,我没有任何运气,并且没有一个绑定正在解析(它们始终为null)。有趣的是,这些绑定与EclipseAstView插件在同一代码上工作。我做错了什么

下面是一些相关的代码片段,希望能帮助人们了解到底发生了什么

ASTParser parser = ASTParser.newParser(AST.JLS3); 
parser.setKind(ASTParser.K_COMPILATION_UNIT);
parser.setSource(source);
parser.setResolveBindings(true);
CompilationUnit unit = (CompilationUnit) parser.createAST(null);

GenericVisitor visitor = new GenericVisitor(outDir + "//" + file.getName() + ".xml");
visitor.process(unit);


public class GenericVisitor extends ASTVisitor 
{
    public void endVisit(FieldDeclaration node) 
    {
        String bindingInfo = "";    
        ITypeBinding binding = node.getType().resolveBinding();

        if(binding == null)
        {                    
         System.out.println("field declaration binding = null");
        }
        else
        {
         bindingInfo = binding.getQualifiedName();
        }

        endVisitNode(node, bindingInfo); 
    }

    public void endVisit(MethodInvocation node) 
    {
         String bindingInfo = "";   
         IMethodBinding binding = node.resolveMethodBinding();

     if(binding == null)
     {                    
        System.out.println("method binding = null");
     }
     else
     {
         bindingInfo = binding.toString();
     }

    endVisitNode(node, bindingInfo); 
    }
} 

可能的原因是您不应该直接在Visitor实例中调用该方法。你应该这样做:

unit.accept(visitor);
CompilationUnit的父类ASTNode有一个方法,该方法接受类型为ASTVisitor的访问者


您编写的访问者GenericVisitor确实将Abstract类ASTVisitor子类化,并覆盖您感兴趣的节点类型的实现。因此,我认为更改代码以执行上述形式的调用可以解决您的问题。

ASTParser就是解析器:它构建AST,这是编译的第一步。 实际的编译器所做的不止这些:它运行各种访问者,这些访问者使用附加信息增强了树。其中之一是具有约束力的决议访问者

特别是,请看一下
类中的public void process(CompilationUnitDeclaration unit,int i)方法。

如果绑定为null,我不能完全确定其他解释是否涵盖了您的问题。在我们的代码库中,我们执行以下操作,并且绑定始终存在:

public static ASTNode getASTNodeFromCompilationUnit(ICompilationUnit compUnit) {
    ASTParser parser = ASTParser.newParser(AST.JLS3);
    parser.setResolveBindings(true);
    parser.setSource(compUnit);
    return parser.createAST(/* passing in monitor messes up previous monitor state */ null);
}
所以我能看到的唯一区别是解析绑定的调用顺序,以及我们不在解析器上调用setKind的事实。您是否有可能尝试使用此代码,看看会发生什么情况?

当您使用: parser.setSource(source); 参数“源”的类型是什么

绑定信息来自 Java模型。这意味着 编译单元必须位于 相对于Java模型。这 当源 代码来自任何一个 设置源(ICompilationUnit)或 setSource(IClassFile)。当来源是 由setSource(char[])提供 位置必须被删除 通过调用 setProject(IJavaProject)和 setUnitName(字符串)

这是从
我想也许您只是使用setSource(char[]),而不调用setProject(IJavaProject)和setUnitName(String)

有时,如果引用的源文件中出现错误,那么这些类型的绑定将无法解决。例如,确保使用正确的编码和源代码的Java版本

    ASTParser parser = ASTParser.newParser(AST.JLS3);
    parser.setKind(ASTParser.K_COMPILATION_UNIT);
    parser.setResolveBindings(true);
    parser.setBindingsRecovery(true);
    Hashtable<String, String> options = JavaCore.getDefaultOptions();
    options.put(JavaCore.COMPILER_SOURCE, JavaCore.VERSION_1_6);
    parser.setCompilerOptions(options);
    parser.setEnvironment(classpath, sources, new String[] { "UTF-8", "UTF-8" }, true);
    parser.setSource(fileContents.toCharArray());
    CompilationUnit compilationUnit = (CompilationUnit) parser.createAST(null);
    IProblem[] problems = compilationUnit.getProblems();
    if (problems != null && problems.length > 0) {
        logger.warn("Got {} problems compiling the source file: ", problems.length);
        for (IProblem problem : problems) {
            logger.warn("{}", problem);
        }
    }
    return compilationUnit;
ASTParser=ASTParser.newParser(AST.JLS3);
setKind(ASTParser.K_编译单元);
setResolveBindings(true);
parser.setBindingsRecovery(true);
Hashtable options=JavaCore.getDefaultOptions();
options.put(JavaCore.COMPILER\u源代码,JavaCore.VERSION\u 1\u 6);
设置编译器选项(选项);
setEnvironment(类路径,源,新字符串[]{“UTF-8”,“UTF-8”},true);
setSource(fileContents.toCharArray());
CompilationUnit CompilationUnit=(CompilationUnit)parser.createAST(null);
IProblem[]problems=compilationUnit.getProblems();
if(problems!=null&&problems.length>0){
warn(“编译源文件时遇到了{}个问题:”,problems.length);
对于(i问题:问题){
logger.warn(“{}”,问题);
}
}
返回编译单元;

好的,这是我关于堆栈溢出的第一个答案。紧张的

我和你有同样的问题,既然你这么做了:

parser.setResolveBindings(true);
让我们通过检查以下内容来了解它是否有效:

if (unit.getAST().hasResolvedBindings()) {
    System.out.println("Binding activated.");
}
else {
    Ststem.out.println("Binding is not activated.");
}
我认为结果是“绑定未激活”。这就是为什么你总是得到空指针

然后,我将此语句添加到我的代码中:

parser.setEnvironment(null, null, null, true);

神奇的是,问题解决了!!!我想您也可以尝试一下。

问题在于,您的解析器没有获得构建解析绑定所需的Java模型所需的必要信息

如果解析器的源代码是从
setSource(ICompilationUnit)
setSource(IClassFile)
获取的,则此信息将自动提供给解析器

但是,如果改用
setSource(char[])
,则必须为解析器提供此上下文。这可以通过调用
parser.setProject(IJavaProject)
setEnvironment(String[],String[],String[],String[],boolean)
setUnitName(String)


Source:

也可以使用parser.setEnvironment(…):“设置在没有IJavaProject可用时可以使用的环境。”我正在尝试实现类似的功能,这里的classpath和sources变量是什么?你能举个例子说明它们的值吗?classpath和sources是字符串数组,具有实际的路径,就像你在java-classpath选项中给出的那样。抱歉,我花了这么长时间才回复…似乎setEnvironment只在JDT3.6之后才可用,但Maven最多只有3.3?你是如何安装3.6的?