[英]How to get final package name?
I have the code 我有代码
private static class MyVisitor extends VoidVisitorAdapter<Object> {
@Override
public void visit(MethodCallExpr exp, Object arg) {
System.out.println("Scope: " + exp.getScope());
System.out.println("Method: " + exp.getName());
if(exp.getArgs() != null)
for(Expression e : exp.getArgs()) {
System.out.println("\tArgument: " + e.toString());
}
System.out.println();
}
}
And 和
CompilationUnit cu = JavaParser.parse(new File("Test.java"));
for(TypeDeclaration type : cu.getTypes()) {
for(BodyDeclaration dec : type.getMembers()) {
if(dec instanceof MethodDeclaration) {
MethodDeclaration mdec = (MethodDeclaration) dec;
BlockStmt block = mdec.getBody();
for(Statement stmt : block.getStmts()) {
MyVisitor visitor = new MyVisitor();
s.accept(visitor, null);
}
}
}
}
I have two problems: 我有两个问题:
if(stmt instanceof MethodCallExp)
but got error. 我试图通过这种方式检查它们是不兼容的类型: if(stmt instanceof MethodCallExp)
但是出错了。 I entered the code I use now. 我输入了我现在使用的代码。 Is that the one way to perform check? 这是执行检查的一种方法吗? System.out.println("Scope: " + exp.getScope());
will be displayed the object/package/package+class name. 将显示对象/包/包+类名。 But how to get its type? 但是如何获得它的类型? For example for the code System.out.println("Hello world");
例如代码System.out.println("Hello world");
Should be outputted 应该输出 Type: java.io.PrintStream 键入:java.io.PrintStream
Class.forName("java.lang.System").getField("out").getType();
In your code example above you pass your visitor to every statement within the method body. 在上面的代码示例中,您将访问者传递给方法体内的每个语句。 If you create the visitor outside of the loop, it will be able to remember information seen in previous statements. 如果您在循环之外创建访问者,它将能够记住在先前语句中看到的信息。 This way, you might add a field to your visitor to store the variable declarations: 这样,您可以向访问者添加一个字段来存储变量声明: final HashMap varNameToType = new HashMap();
You can store the variable declarations like below. 您可以存储如下所示的变量声明。 When you get to a method call, you can use the scope to try and get the type via the map. 当您进行方法调用时,您可以使用范围尝试通过地图获取类型。 If the map doesn't contain the Type, you may need to use Reflection, since the variable may be part of the JDK classes. 如果映射不包含Type,则可能需要使用Reflection,因为该变量可能是JDK类的一部分。 I'm not suggesting that this covers all cases. 我并不是说这涵盖了所有情况。 Eg when you access a field of your parent class, you wouldn't have any information about that field at your position in the code - you may need to look at different compilation units for that. 例如,当您访问父类的字段时,您将无法在代码中的位置获得有关该字段的任何信息 - 您可能需要查看不同的编译单元。 @Override
public void visit(
final VariableDeclarationExpr n,
final Object arg) {
final Type varType = n.getType();
n.getVars().forEach(vd ->
varNameToType.put(vd.getId().getName(),varType)
);
}
If you don't need to stick on JavaParser
maybe you could solve it in the way the Android lint tools do it. 如果您不需要坚持JavaParser
也许您可以通过Android lint工具的方式来解决它。 EcjParserTest.java . EcjParserTest.java 。 It uses Lombok
under the hood. 它使用Lombok
引擎盖。
At line 380
it compares in the test an output similar to the one you want to have [ExpressionStatement], type: void, resolved method: println java.io.PrintStream
. 在第380
行,它在测试中比较了一个类似于你想要的输出[ExpressionStatement], type: void, resolved method: println java.io.PrintStream
。
I had no deeper look, but it looks as a promising starting point 我没有更深入的了解,但它看起来是一个很有希望的起点
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.