You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

OpenRewrite:如何用JavaTemplate将单条语句替换为多条语句?

解决OpenRewrite替换单条语句为多条语句的问题

问题根源

直接用oldMockStatement.getCoordinates().replace()替换单条语句为多条时,若未正确配置JavaTemplate,OpenRewrite会将模板内容当作单个语法节点处理,导致多条语句解析失败,出现类似Templategiven(...)的语法错误,同时触发"替换单条语句为多条无效"的报错。

正确实现方法

核心是让JavaTemplate明确识别模板内容为多条语句序列,并使用正确的坐标进行替换。

方法1:单模板直接替换(推荐)

通过statements(true)声明模板为多条语句,同时清理模板格式避免多余缩进:

// 定义多条语句模板,用trimIndent()移除多余缩进
String NEW_MOCK_STATEMENTS = """
        given(methodToMock1).willReturn(expectedResponse1);
        given(methodToMock2).willReturn(expectedResponse2);
        """.trimIndent();

// 构建模板时明确指定为语句序列
JavaTemplate javaTemplate = JavaTemplate.builder(NEW_MOCK_STATEMENTS)
        .statements(true) // 关键:告知模板这是多条语句
        .build();

// 替换原单条语句为多条新语句
methodDeclarationWhereApplyingChanges = methodDeclarationWhereApplyingChanges.withBody(
        javaTemplate.apply(
                getCursor(), // 直接使用当前cursor,无需新建
                oldMockStatement.getCoordinates().replace()
        )
);

方法2:分步替换(兼容复杂场景)

如果单模板替换仍有问题,可拆分为"替换原语句为第一条新语句" + "插入第二条新语句"两步:

// 第一步:替换原语句为第一条新mock语句
JavaTemplate firstMockTemplate = JavaTemplate.builder("given(methodToMock1).willReturn(expectedResponse1);").build();
methodDeclarationWhereApplyingChanges = firstMockTemplate.apply(
        getCursor(),
        oldMockStatement.getCoordinates().replace()
);

// 第二步:在第一条新语句后插入第二条mock语句
// 先获取刚插入的第一条语句(可通过语法树查询定位)
Statement firstNewMock = methodDeclarationWhereApplyingChanges.getBody().getStatements()
        .stream()
        .filter(s -> s instanceof ExpressionStmt)
        .map(s -> (ExpressionStmt) s)
        .filter(e -> e.getExpression().toString().startsWith("given(methodToMock1)"))
        .findFirst()
        .orElseThrow(() -> new IllegalArgumentException("First mock statement not found"));

JavaTemplate secondMockTemplate = JavaTemplate.builder("given(methodToMock2).willReturn(expectedResponse2);").build();
methodDeclarationWhereApplyingChanges = secondMockTemplate.apply(
        getCursor(),
        firstNewMock.getCoordinates().insertAfter()
);

关键注意事项

  • 模板内容必须是合法的Java语句,每条语句结尾要有分号。
  • 使用trimIndent()清理模板的多余缩进,避免生成格式混乱的代码。
  • 当替换单条语句为多条时,必须通过statements(true)声明模板类型,否则OpenRewrite会将整个模板内容当作单个表达式解析,导致语法错误。

内容的提问来源于stack exchange,提问作者Sergio García

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.24 16:42:44