OpenRewrite - Refaster 模板配方不可发现且不可用

问题描述 投票:0回答:1

据了解,OpenRewrite 主要有 3 种创建配方的方法:Declarative、Refaster 和 Imperative。这是关于 Refaster 方法的。

我创建了以下 Refaster 模板类来进行简单的代码更改 - 确保除法发生在乘法之后。 (只是一个测试 OpenRewrite 功能的示例)

package com.self.openrewrite_lib.refaster;

import com.google.errorprone.refaster.annotation.AfterTemplate;
import com.google.errorprone.refaster.annotation.BeforeTemplate;
import org.openrewrite.java.template.RecipeDescriptor;

@RecipeDescriptor(name = "Multiply then divide formatter", description = "Ensures that divisions occur after multiplication for accuracy.")
public class MultiplyThenDivide {
    @BeforeTemplate
    public double divideThenMultiply(double original, double divisor, double multiplier) {
        return original / divisor * multiplier;
    }
    @AfterTemplate
    public double multiplyThenDivide(double original, double divisor, double multiplier) {
        return original * multiplier / divisor;
    }
}

在终端中运行

mvn compile
后,会在
target/generated-sources/annotations/com/self/openrewrite_lib/refaster
目录中生成Recipe类。

package com.self.openrewrite_lib.refaster;

import org.jspecify.annotations.NullMarked;
import org.openrewrite.ExecutionContext;
import org.openrewrite.Preconditions;
import org.openrewrite.Recipe;
import org.openrewrite.TreeVisitor;
import org.openrewrite.java.JavaParser;
import org.openrewrite.java.JavaTemplate;
import org.openrewrite.java.JavaVisitor;
import org.openrewrite.java.search.*;
import org.openrewrite.java.template.Primitive;
import org.openrewrite.java.template.function.*;
import org.openrewrite.java.template.internal.AbstractRefasterJavaVisitor;
import org.openrewrite.java.tree.*;

import javax.annotation.Generated;
import java.util.*;

import static org.openrewrite.java.template.internal.AbstractRefasterJavaVisitor.EmbeddingOption.*;

/**

* OpenRewrite recipe created for Refaster template {@code MultiplyThenDivide}.
  */
  @SuppressWarnings("all")
  @NullMarked
  @Generated("org.openrewrite.java.template.processor.RefasterTemplateProcessor")
  public class MultiplyThenDivideRecipe extends Recipe {

  /**

  * Instantiates a new instance.
    */
    public MultiplyThenDivideRecipe() {}

  @Override
  public String getDisplayName() {
  return "Multiply then divide formatter";
  }

  @Override
  public String getDescription() {
  return "Ensures that divisions occur after multiplication for accuracy.";
  }

  @Override
  public TreeVisitor\<?, ExecutionContext\> getVisitor() {
  return new AbstractRefasterJavaVisitor() {
  final JavaTemplate divideThenMultiply = JavaTemplate
  .builder("#{original:any(double)} / #{divisor:any(double)} * #{multiplier:any(double)}")
  .build();
  final JavaTemplate multiplyThenDivide = JavaTemplate
  .builder("#{original:any(double)} * #{multiplier:any(double)} / #{divisor:any(double)}")
  .build();

           @Override
           public J visitBinary(J.Binary elem, ExecutionContext ctx) {
               JavaTemplate.Matcher matcher;
               if ((matcher = divideThenMultiply.matcher(getCursor())).find()) {
                   return embed(
                           multiplyThenDivide.apply(getCursor(), elem.getCoordinates().replace(), matcher.parameter(0), matcher.parameter(2), matcher.parameter(1)),
                           getCursor(),
                           ctx,
                           SHORTEN_NAMES
                   );
               }
               return super.visitBinary(elem, ctx);
           }
      
       };

  }
  }

在编写 OpenRewrite 测试用例时可以使用上面的内容,但是当尝试通过

mvn rewrite:run
命令在我自己的代码上运行配方时,或者尝试通过
mvn rewrite:discover
命令发现配方时,找不到新生成的配方.

测试用例使用(通过):

package com.self.openrewrite_lib;

import com.self.openrewrite_lib.refaster.MultiplyThenDivideRecipe;
import org.junit.jupiter.api.Test;
import org.openrewrite.test.RewriteTest;

class OpenRewriteTests implements RewriteTest {

    @Test
    void multiplyThenDivideRecipe() {
        rewriteRun(spec -> spec.recipe(new MultiplyThenDivideRecipe()),
                //language=java
                org.openrewrite.java.Assertions.java(
                        """
                        class TestExample {
                            public double calculate(double a, double b, double c) {
                                return a / b * c;
                            }
                        }
                        """,
                        """
                        class TestExample {
                            public double calculate(double a, double b, double c) {
                                return a * c / b;
                            }
                        }
                        """
                ));
    }

}

运行

mvn rewrite:discover
Failed to execute goal org.openrewrite.maven:rewrite-maven-plugin:5.42.2:discover (default-cli) on project openrewrite-lib: Could not find recipe 'com.self.openrewrite_lib.refaster.MultiplyThenDivideRecipe' among available recipes -> [Help 1]

运行

mvn rewrite:run
Failed to execute goal org.openrewrite.maven:rewrite-maven-plugin:5.42.2:run (default-cli) on project openrewrite-lib: Execution default-cli of goal org.openrewrite.maven:rewrite-maven-plugin:5.42.2:run failed: Recipe(s) not found: com.self.openrewrite_lib.refaster.MultiplyThenDivideRecipe

任何指导将不胜感激。谢谢。

用于参考的教程/文档:https://docs.openrewrite.org/authoring-recipes/refaster-recipes

pom.xml:

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>3.3.4</version>
        <relativePath/> <!-- lookup parent from repository -->
    </parent>
    <groupId>com.self</groupId>
    <artifactId>openrewrite-lib</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    <name>openrewrite-lib</name>
    <description>Demo project for Spring Boot</description>
    <url/>
    <licenses>
        <license/>
    </licenses>
    <developers>
        <developer/>
    </developers>
    <scm>
        <connection/>
        <developerConnection/>
        <tag/>
        <url/>
    </scm>
    <properties>
        <maven.compiler.source>1.8</maven.compiler.source>
        <maven.compiler.target>1.8</maven.compiler.target>
        <java.version>17</java.version>
    </properties>

    <dependencyManagement>
        <dependencies>
            <dependency>
                <groupId>org.openrewrite.recipe</groupId>
                <artifactId>rewrite-recipe-bom</artifactId>
                <version>2.21.1</version>
                <type>pom</type>
                <scope>import</scope>
            </dependency>
        </dependencies>
    </dependencyManagement>

    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter</artifactId>
        </dependency>

        <dependency>
            <groupId>org.openrewrite</groupId>
            <artifactId>rewrite-java</artifactId>
            <scope>compile</scope>
        </dependency>
        <dependency>
            <groupId>org.openrewrite</groupId>
            <artifactId>rewrite-java-17</artifactId>
            <scope>runtime</scope>
        </dependency>

        <dependency>
            <groupId>org.openrewrite</groupId>
            <artifactId>rewrite-yaml</artifactId>
            <scope>compile</scope>
        </dependency>

        <dependency>
            <groupId>org.openrewrite</groupId>
            <artifactId>rewrite-templating</artifactId>
        </dependency>
        <dependency>
            <groupId>com.google.errorprone</groupId>
            <artifactId>error_prone_core</artifactId>
            <version>2.34.0</version>
            <scope>provided</scope>
            <exclusions>
                <exclusion>
                    <groupId>com.google.auto.service</groupId>
                    <artifactId>auto-service-annotations</artifactId>
                </exclusion>
            </exclusions>
        </dependency>

        <dependency>
            <groupId>javax.annotation</groupId>
            <artifactId>javax.annotation-api</artifactId>
            <version>1.3.2</version>
        </dependency>

        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <version>1.18.34</version>
            <optional>true</optional>
        </dependency>

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>

        <dependency>
            <groupId>org.openrewrite</groupId>
            <artifactId>rewrite-test</artifactId>
            <scope>test</scope>
        </dependency>
    </dependencies>

    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
            </plugin>
            <plugin>
                <artifactId>maven-surefire-plugin</artifactId>
                <version>3.0.0-M9</version>
            </plugin>
            <!-- lombok is optional, but recommended for authoring recipes -->
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-compiler-plugin</artifactId>
                <version>3.13.0</version>
                <configuration>
                    <source>17</source>
                    <target>17</target>
                    <compilerArgs>
                        <arg>-parameters</arg>
                    </compilerArgs>
                    <annotationProcessorPaths>
                        <path>
                            <groupId>org.projectlombok</groupId>
                            <artifactId>lombok</artifactId>
                            <version>1.18.34</version>
                        </path>
                        <path>
                            <groupId>org.openrewrite</groupId>
                            <artifactId>rewrite-templating</artifactId>
                            <version>1.16.1</version>
                        </path>
                    </annotationProcessorPaths>
                </configuration>
            </plugin>
            <plugin>
                <groupId>org.openrewrite.maven</groupId>
                <artifactId>rewrite-maven-plugin</artifactId>
                <version>5.42.2</version>
                <configuration>
                    <activeRecipes>
                        <recipe>com.self.openrewrite_lib.refaster.MultiplyThenDivideRecipe</recipe>
                    </activeRecipes>
                </configuration>
            </plugin>
        </plugins>
    </build>
</project>
java maven openrewrite
1个回答
0
投票

您是否将该

target/generated-sources/annotations/
文件夹标记为生成的源根目录?如果文件存在但找不到该类,听起来您的 IDE 尚未识别该文件。

对于参考实现,您还可以查看我们的重写配方启动器: https://github.com/moderneinc/rewrite-recipe-starter/blob/main/pom.xml#L150-L154

希望有帮助!

© www.soinside.com 2019 - 2024. All rights reserved.