Как разобрать переменную статического уровня из файла JAVA? - PullRequest
0 голосов
/ 17 января 2019

Я пытаюсь разобрать значение статической переменной из файла JAVA. Но не смог разобрать переменную.

Я использовал JavaParser для разбора кода и получения значения переменной. Я добился успеха в получении всех других переменных и значений уровня класса, но не смог разобрать статическое поле.

Файл Java выглядит как ...

public class ABC {
    public string variable1 = "Hello How are you?";
    public boolean variable2 = false;
    public static String variable3;
    static{
    variable3 = new String("Want to Fetch this...");
    } 
    //Can't change this file, this is input.
    public static void main(String args[]){
    //....Other Code
    } 
}

Я могу проанализировать значение всех переменных, кроме "variabl3". Код Java-файла выглядит выше, чем Java-код, и мне нужно проанализировать значение «variable3».

Я сделал код ниже для анализа переменной уровня класса ...

import java.util.HashMap;
import java.util.List;

import com.github.javaparser.ast.body.FieldDeclaration;
import com.github.javaparser.ast.body.VariableDeclarator;
import com.github.javaparser.ast.expr.VariableDeclarationExpr;
import com.github.javaparser.ast.visitor.VoidVisitorAdapter;


public class StaticCollector extends 
VoidVisitorAdapter<HashMap<String, String>> {

@Override
public void visit(FieldDeclaration n, HashMap<String, String> arg) {
    // TODO Auto-generated method stub
    List <VariableDeclarator> myVars = n.getVariables();
        for (VariableDeclarator vars: myVars){
            vars.getInitializer().ifPresent(initValue -> System.out.println(initValue.toString()));
            //System.out.println("Variable Name: "+vars.getNameAsString());
            }
}

}

Основной метод ...

public class Test {
public static void main(String[] args) {

    File file = new File("filePath");
    CompilationUnit compilationUnit = null;
    try {
        compilationUnit = JavaParser.parse(file);
    } catch (FileNotFoundException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    }
    HashMap<String, String> collector = new HashMap<String, String>();
    compilationUnit.accept(new StaticCollector(), collector);
} 
}

Как я могу проанализировать значение «variable3», которое является статическим, и значение, назначенное внутри статического блока? В коде может быть другая переменная, но мне нужно найти значение конкретной переменной (в данном случае Variable3). Я делаю что-то не так или мне нужно добавить другой способ, пожалуйста, предложите.

1 Ответ

0 голосов
/ 05 июля 2019

Проверка AST как легко читаемой картинки, например, изображения DOT (GraphViz) с помощью PlantUML , - это огромная помощь в решении этой проблемы. См. этот блог о том, как генерировать DOT, а также другие форматы .

Вот обзор с выделенными узлами "variable3" (я просто искал его в выводе .dot и добавил цвет заливки). Вы увидите, что есть ДВА пятна, где это происходит:

enter image description here

Увеличивая пространство узлов справа, мы видим, что второе поддерево находится под InitializerDeclaration. Далее, это часть AssignExpr, где значением является ObjectCreationExpr:

enter image description here

Итак, я адаптировал вашего посетителя (это внутренний класс, чтобы сделать модуль самодостаточным), и вам нужно переопределить метод visit(InitializerDeclaration n..., чтобы добраться туда, куда вы хотите:

import com.github.javaparser.StaticJavaParser;
import com.github.javaparser.ast.CompilationUnit;
import com.github.javaparser.ast.body.FieldDeclaration;
import com.github.javaparser.ast.body.InitializerDeclaration;
import com.github.javaparser.ast.body.VariableDeclarator;
import com.github.javaparser.ast.stmt.Statement;
import com.github.javaparser.ast.visitor.VoidVisitorAdapter;

import java.io.File;
import java.io.FileNotFoundException;
import java.util.HashMap;
import java.util.List;

public class Test {
    public static void main(String[] args) {

        File file = new File("src/main/java/ABC.java");
        CompilationUnit compilationUnit = null;
        try {
            compilationUnit = StaticJavaParser.parse(file);
        } catch (FileNotFoundException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
        HashMap<String, String> collector = new HashMap<String, String>();
        compilationUnit.accept(new StaticCollector(), collector);
    }

    private static class StaticCollector extends
            VoidVisitorAdapter<HashMap<String, String>> {
        @Override
        public void visit(FieldDeclaration n, HashMap<String, String> arg) {
            List<VariableDeclarator> myVars = n.getVariables();
            for (VariableDeclarator vars: myVars){
                vars.getInitializer().ifPresent(initValue -> System.out.println(initValue.toString()));
                //System.out.println("Variable Name: "+vars.getNameAsString());
            }
        }
        @Override
        public void visit(InitializerDeclaration n, HashMap<String, String> arg) {
            List<Statement> myStatements = n.getBody().getStatements();
            for (Statement s: myStatements) {
                s.ifExpressionStmt(expressionStmt -> expressionStmt.getExpression()
                        .ifAssignExpr(assignExpr -> System.out.println(assignExpr.getValue())));
            }
        }
    }
}

Вот вывод, показывающий дополнительно инициализацию variable3 в статическом блоке:

"Hello How are you?"
false
new String("Want to Fetch this...")
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...