привязки не разрешаются с обработкой AST в затмении - PullRequest
7 голосов
/ 07 января 2010

Я использую анализатор AST eclipse JDT для обработки некоторого Java-кода и пытаюсь извлечь привязки типов для полей и объявлений методов. Логика для этого внутри моего класса Visitor (см. Ниже). К сожалению, мне не повезло, и ни одна из привязок не разрешается (они постоянно равны нулю). Интересно то, что привязки работают с одним и тем же кодом с помощью плагина eclipse ASTView. Что я делаю не так?

Вот некоторые соответствующие фрагменты кода, которые, мы надеемся, помогут кому-то выяснить, что происходит!

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); 
    }
} 

Ответы [ 7 ]

8 голосов
/ 27 апреля 2011

Когда вы используете: parser.setSource (источник); Какой тип параметра "источник"?

Информация о привязке получена из модель Java. Это означает, что сборник должен быть расположен относительно модели Java. это происходит автоматически, когда источник код приходит либо setSource (ICompilationUnit) или setSource (IClassFile). Когда источник предоставляется setSource (char []), местоположение должно быть установлено явно позвонив setProject (IJavaProject) и setUnitName (String).

Это от http://help.eclipse.org/galileo/index.jsp?topic=/org.eclipse.jdt.doc.isv/reference/api/org/eclipse/jdt/core/dom/ASTParser.html Я думаю, может быть, вы просто используете setSource (char []) без вызова setProject (IJavaProject) и setUnitName (String)

2 голосов
/ 07 января 2010

Вероятная причина в том, что вы не должны вызывать метод в экземпляре Visitor напрямую. Вы должны сделать что-то вроде:

unit.accept(visitor);

Родительский класс CompilationUnit , ASTNode , имеет метод accept , который принимает посетителя типа ASTVisitor .

Посетитель, которого вы написали, GenericVisitor , делает подклассы класса abstarct ASTVisitor и переопределяет реализацию для типов узлов, в которые вы вставили. Поэтому я думаю, что нужно изменить код для выполнения вызов в вышеуказанной форме решит вашу проблему.

1 голос
/ 17 апреля 2017

Проблема в том, что вашему синтаксическому анализатору не была предоставлена ​​необходимая информация для построения его Java-модели, необходимой для разрешения привязок.

Если источник парсера получен из setSource(ICompilationUnit) или setSource(IClassFile), эта информация предоставляется парсеру автоматически.

Однако, если вы вместо этого используете setSource(char[]), вы должны предоставить этот контекст для анализатора. Это можно сделать, позвонив по номеру parser.setProject(IJavaProject) или setEnvironment(String[], String[], String[], boolean) и setUnitName(String)

Источник: http://help.eclipse.org/kepler/topic/org.eclipse.jdt.doc.isv/reference/api/org/eclipse/jdt/core/dom/ASTParser.html#setResolveBindings(boolean)

1 голос
/ 17 октября 2016

Хорошо, это мой первый ответ на переполнение стека. Нервный ...

У меня с вами та же проблема, и с тех пор, как вы это сделали:

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);

Волшебно, проблема исправлена ​​!!! И я полагаю, вы тоже можете попробовать это.

1 голос
/ 07 января 2010

ASTParser - это просто синтаксический анализатор: он создает AST, который является первым шагом в компиляции. Фактический компилятор делает больше, чем просто: он запускает различных посетителей, которые дополняют дерево дополнительной информацией. Одним из них является посетитель с обязательным разрешением.

В частности, взгляните на тело метод public void (метод CompilationUnitDeclaration, int i) в org.eclipse.jdt.internal.compiler.Compiler классе.

0 голосов
/ 19 июня 2012

Иногда, если вы получили ошибки в ссылочных исходных файлах, привязки к этим типам не разрешаются. Например, убедитесь, что вы используете правильную кодировку и версию 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;
0 голосов
/ 15 февраля 2010

Если ваши привязки нулевые, я не совсем уверен, что ваша проблема подпадает под другие объяснения. В нашей кодовой базе мы делаем следующее, и привязки всегда есть:

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 для анализатора. Есть ли шанс, что вы сможете попробовать именно этот код и посмотреть, что произойдет?

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...