使用LexicalPreservingPrinter时新方法体丢失,代码是否存在问题?
JavaParser LexicalPreservingPrinter添加方法丢失方法体问题
问题描述
我希望向现有类中添加新方法,同时保留原有代码的格式。使用com.github.javaparser:javaparser-core:3.25.5版本,但在使用LexicalPreservingPrinter时,新添加的方法没有方法体。参考代码如下:
final CompilationUnit cu = StaticJavaParser.parse(Paths.get("path-of-an-existing-class.java")); LexicalPreservingPrinter.setup(cu); final ClassOrInterfaceDeclaration type = cu.addClass("GeneratedClass"); final MethodDeclaration method = type.addMethod("main", Keyword.PUBLIC, Keyword.STATIC); final BlockStmt block = new BlockStmt(); method.setBody(block); final NameExpr clazz = new NameExpr("System"); final FieldAccessExpr field = new FieldAccessExpr(clazz, "out"); final MethodCallExpr call = new MethodCallExpr(field, "println"); call.addArgument(new StringLiteralExpr("Hello World!")); block.addStatement(call); // 注释掉LexicalPreservingPrinter.setup(...)时,两次打印的"Hello"数量相等 // 启用该代码时,数量不同 System.out.println(StringUtils.countMatches(new DefaultPrettyPrinter().print(cu), "Hello")); System.out.println(StringUtils.countMatches(LexicalPreservingPrinter.print(cu), "Hello"));
问题原因
你的代码存在关键疏漏:LexicalPreservingPrinter.setup(cu)只会初始化解析阶段生成的原有AST节点的词法保留信息,而你手动创建的新节点(比如GeneratedClass类、main方法、方法体等)并没有被纳入词法保留的处理范围。当LexicalPreservingPrinter打印时,无法识别这些新节点的内容,导致新方法的方法体被忽略,两次打印的"Hello"数量出现差异。
解决方法
为每个手动创建的新节点单独调用LexicalPreservingPrinter.setup(),让它们被纳入词法保留机制的处理。修改后的代码如下:
final CompilationUnit cu = StaticJavaParser.parse(Paths.get("path-of-an-existing-class.java")); LexicalPreservingPrinter.setup(cu); final ClassOrInterfaceDeclaration type = cu.addClass("GeneratedClass"); // 为新创建的类启用词法保留 LexicalPreservingPrinter.setup(type); final MethodDeclaration method = type.addMethod("main", Keyword.PUBLIC, Keyword.STATIC); // 为新创建的方法启用词法保留 LexicalPreservingPrinter.setup(method); final BlockStmt block = new BlockStmt(); method.setBody(block); // 为方法体启用词法保留 LexicalPreservingPrinter.setup(block); final NameExpr clazz = new NameExpr("System"); final FieldAccessExpr field = new FieldAccessExpr(clazz, "out"); final MethodCallExpr call = new MethodCallExpr(field, "println"); call.addArgument(new StringLiteralExpr("Hello World!")); block.addStatement(call); System.out.println(StringUtils.countMatches(new DefaultPrettyPrinter().print(cu), "Hello")); System.out.println(StringUtils.countMatches(LexicalPreservingPrinter.print(cu), "Hello"));
这样修改后,LexicalPreservingPrinter就能正确识别并打印新添加的方法体内容,两次输出的"Hello"数量会保持一致。
内容的提问来源于stack exchange,提问作者Shear Plane
相关产品推荐
相关产品推荐

