我正在开发一个具有以下功能的命令行工具:
public void {marketing} sendEmail() {}。我正在寻找实现第3步的最简单、最有效的方法。在我的项目范围之外,构建一个完整的编译器,如果可能的话,我更愿意利用Java编译器并运行javac。我曾考虑过以下方法,但似乎没有一种是最佳的:
任何投入都是非常感谢的。
发布于 2022-04-01 08:05:40
您可以使用TokenStreamRewriter获得源代码,而无需使用目的节点(或完成许多其他重写任务)。下面是一个应用程序的示例,其中我有条件地向一个LIMIT查询添加了一个顶级的MySQL子句:
/**
001 * Parses the query to see if there's already a top-level limit clause. If none was found, the query is
002 * rewritten to include a limit clause with the given values.
003 *
004 * @param query The query to check and modify.
005 * @param serverVersion The version of MySQL to use for checking.
006 * @param sqlMode The current SQL mode in the server.
007 * @param offset The limit offset to add.
008 * @param count The row count value to add.
009 *
010 * @returns The rewritten query if the original query is error free and contained no top-level LIMIT clause.
011 * Otherwise the original query is returned.
012 */
013 public checkAndApplyLimits(query: string, serverVersion: number, sqlMode: string, offset: number,
014 count: number): [string, boolean] {
015
016 this.applyServerDetails(serverVersion, sqlMode);
017 const tree = this.startParsing(query, false, MySQLParseUnit.Generic);
018 if (!tree || this.errors.length > 0) {
019 return [query, false];
020 }
021
022 const rewriter = new TokenStreamRewriter(this.tokenStream);
023 const expressions = XPath.findAll(tree, "/query/simpleStatement//queryExpression", this.parser);
024 let changed = false;
025 if (expressions.size > 0) {
026 // There can only be one top-level query expression where we can add a LIMIT clause.
027 const candidate: ParseTree = expressions.values().next().value;
028
029 // Check if the candidate comes from a subquery.
030 let run: ParseTree | undefined = candidate;
031 let invalid = false;
032 while (run) {
033 if (run instanceof SubqueryContext) {
034 invalid = true;
035 break;
036 }
037
038 run = run.parent;
039 }
040
041 if (!invalid) {
042 // Top level query expression here. Check if there's already a LIMIT clause before adding one.
043 const context = candidate as QueryExpressionContext;
044 if (!context.limitClause() && context.stop) {
045 // OK, ready to add an own limit clause.
046 rewriter.insertAfter(context.stop, ` LIMIT ${offset}, ${count}`);
047 changed = true;
048 }
049 }
040 }
051
052 return [rewriter.getText(), changed];
053 }这段代码在做什么:
使用这段代码,您可以创建一个临时的java文件进行编译。它可以用于同时执行列表中的两个操作(收集目的并删除它们)。
https://stackoverflow.com/questions/71693775
复制相似问题