日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程语言 > java >内容正文

java

JavaParser生成,分析和修改Java代码

發布時間:2023/12/3 java 46 豆豆
生活随笔 收集整理的這篇文章主要介紹了 JavaParser生成,分析和修改Java代码 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

作為開發人員,我們經常鄙視手動進行重復工作的人員。

我們認為, 他們應該實現這一目標 。

盡管如此,我們還是進行與編碼有關的所有活動。 當然,我們使用的高級IDE可以為我們執行一些重構,但這基本上就是結束了。 我們不品嘗我們自己的藥。

讓我們改變它。 讓我們看看如何將代碼編寫為:

  • 生成我們必須編寫的無聊的重復性Java代碼
  • 分析我們的代碼以回答有關它的一些問題
  • 做一些代碼處理和重構

好消息是,我們將使用一組庫來實現所有這些功能:JavaParser和它的弟弟JavaSymbolSolver。

入門

好吧,這很簡單:只需將JavaSymbolSolver添加到您的依賴項中即可。

什么是JavaSymbolSolver? 它是JavaParser的補充庫,為它提供了一些相當強大的功能,這些功能對于回答關于代碼的更復雜的問題是必需的。

JavaSymbolSolver依賴于JavaParser,因此您只需要添加JavaSymbolSolver,Maven或Gradle也會為您提供JavaParser。

我假設您知道如何使用Maven或Gradle。 如果您不喜歡,請停止閱讀并開始學習!

使用javaparser生成代碼

在某些情況下,您可能需要生成Java代碼。 例如,您可能想基于一些外部數據生成代碼,例如數據庫架構或REST API。

您可能還需要將其他語言翻譯成Java。 例如,我設計了用于生活的DSL,而當用戶只能看到我為他們構建的DSL時,我經常在后臺生成Java并將其編譯。

有時候,您只想生成樣板代碼,就像我以前在使用JavaEE和所有這些層(誰能記住編寫EJB的過程很無聊?)時使用dp一樣。

無論生成代碼的原因是什么,都可以使用JavaParser。 JavaParser不會提出問題,它只是在幫助您。

讓我們看看如何生成一個具有兩個字段的類,一個構造函數和兩個getter。 沒什么特別先進的,但是它應該使您了解使用JavaParser進行代碼生成的含義。

CompilationUnit cu = new CompilationUnit();cu.setPackageDeclaration("jpexample.model");ClassOrInterfaceDeclaration book = cu.addClass("Book"); book.addField("String", "title"); book.addField("Person", "author");book.addConstructor(Modifier.PUBLIC).addParameter("String", "title").addParameter("Person", "author").setBody(new BlockStmt().addStatement(new ExpressionStmt(new AssignExpr(new FieldAccessExpr(new ThisExpr(), "title"),new NameExpr("title"),AssignExpr.Operator.ASSIGN))).addStatement(new ExpressionStmt(new AssignExpr(new FieldAccessExpr(new ThisExpr(), "author"),new NameExpr("author"),AssignExpr.Operator.ASSIGN))));book.addMethod("getTitle", Modifier.PUBLIC).setBody(new BlockStmt().addStatement(new ReturnStmt(new NameExpr("title"))));book.addMethod("getAuthor", Modifier.PUBLIC).setBody(new BlockStmt().addStatement(new ReturnStmt(new NameExpr("author"))));System.out.println(cu.toString());

最后一條指令將打印出您的代碼,并且可以立即進行編譯。 您可能希望將代碼保存到文件中而不是打印它,但是您明白了。

使用javaparser分析代碼

您可能會詢問有關代碼的許多不同問題,以及許多不同的分析方式。

首先,讓我們解析項目的所有源文件:

// Parse all source files SourceRoot sourceRoot = new SourceRoot(myProjectSourceDir.toPath()); sourceRoot.setParserConfiguration(parserConfiguration); List<ParseResult> parseResults = sourceRoot.tryToParse("");// Now get all compilation unitsList allCus = parseResults.stream() .filter(ParseResult::isSuccessful) .map(r -> r.getResult().get()) .collect(Collectors.toList());

我們還創建一個方法來獲取所有編譯單元中特定類型的所有節點:

public static List getNodes(List cus, Class nodeClass) {List res = new LinkedList();cus.forEach(cu -> res.addAll(cu.findAll(nodeClass)));return res; }

然后讓我們開始提問,例如:

有多少種方法采用3個以上的參數?

long n = getNodes(allCus, MethodDeclaration.class) .stream() .filter(m -> m.getParameters().size() > 3).count();System.out.println("N of methods with 3+ params: " + n);

大多數方法中的三個頂級類別是什么?

getNodes(allCus, ClassOrInterfaceDeclaration.class) .stream() .filter(c -> !c.isInterface()) .sorted(Comparator.comparingInt(o -> -1 * o.getMethods().size())) .limit(3) .forEach(c -> System.out.println(c.getNameAsString() + ": " + c.getMethods().size() + " methods"));

好的,您知道了。 現在去檢查您的代碼。 您沒有什么可隱藏的,對嗎?

使用javaparser轉換代碼

假設您是某個庫的滿意用戶。 幾年前,您已將其添加到依賴項中,并從此以后就愉快地使用它。 時間已經過去,您已經在整個項目中越來越多地使用它。

有一天,該有用庫的新版本出現了,您決定要更新依賴項。 現在,他們在新庫中刪除了您正在使用的方法之一。 確保已棄用它,并將其命名為oldMethod (可能告訴您一些信息……)。

現在oldMethod已被newMethod取代。 newMethod具有3個參數:前兩個參數與oldMethod相同,只是將它們取反,第三個參數是布爾值,應將其設置為true以獲得與oldMethod相同的行為。

您有對oldMethod的數百個調用…是否要一個一個地更改它們? 好吧,也許,如果您按小時收費。 或者,您可以只使用JavaParser代替。

首先,讓我們在某個文件(即JavaParser parlanse中的CompilationUnit)中找到對舊方法的所有調用:

myCompilationUnit.findAll(ethodCallExpr.class).stream().filter(m -> m.resolveInvokedMethod() .getQualifiedSignature() .equals("foo.MyClass.oldMethod(java.lang.String, int)")) .forEach(m -> m.replace(replaceCallsToOldMethod(m)));

然后,讓我們將舊調用轉換為新調用:

public MethodCallExpr replaceCallsToOldMethod(MethodCallExpr methodCall) { MethodCallExpr newMethodCall = new MethodCallExpr(methodCall.getScope().get(), "newMethod"); newMethodCall.addArgument(methodCall.getArgument(1)); newMethodCall.addArgument(methodCall.getArgument(0)); newMethodCall.addArgument(new BooleanLiteralExpr(true)); return newMethodCall; }

太酷了,現在我們只需要獲取修改后的CompilationUnit的代碼并將其保存到Java文件即可。

newMethod使用壽命長 !

在哪里可以找到有關javaparser的更多信息

我們還沒有看到JavaParser的眾多功能:

  • JavaParser可以處理注釋,弄清楚它們所引用的元素
  • JavaParser可以進行詞法保留或漂亮的打印 :您的選擇
  • 它可以找出一個方法調用指向哪個方法聲明,某個類具有哪個祖先,以及更多地歸功于與JavaSymbolSolver的集成。
  • 它可以將AST導出為JSON,XML,YAML,甚至可以使用Graphviz生成圖表!

您在哪里可以了解所有這些東西?

這里有一些資源:

  • 我們寫了一本關于JavaParser和JavaSymbolSolver的書,可免費獲得。 它被命名為JavaParser:Visited
  • Matozoid偉大的博客 :他是JavaParser的光榮維護者,這是不可阻擋的力量,每隔一個星期就會推出新版本。 誰更了解JavaParser?
  • 我關于語言工程的拙劣博客 。 我是JavaSymbolSolver的維護者,我嘗試作為JavaParser中的第二命令來提供幫助。 遙遠的第二個&#55357;&#56898;
  • 該項目的網站 :目前內容還不是很豐富,但是我們正在努力
  • 煩惱頻道 :您有問題嗎? 在那兒問他們

摘要

幾乎沒有情況可以學習如何使用一種工具來完成三件不同的事情。 通過學習如何使用JavaParser,您可以分析,生成和修改Java代碼。

好吧,感覺就像圣誕節,不是嗎?

翻譯自: https://www.javacodegeeks.com/2017/12/javaparser-generate-analyze-modify-java-code.html

創作挑戰賽新人創作獎勵來咯,堅持創作打卡瓜分現金大獎

總結

以上是生活随笔為你收集整理的JavaParser生成,分析和修改Java代码的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。