openrewrite / rewrite

Automated mass refactoring of source code.
https://docs.openrewrite.org
Apache License 2.0
2.03k stars 300 forks source link

Question: How to include and visit in the AST the flat files of a JAVA project #1787

Closed ferblaca closed 2 years ago

ferblaca commented 2 years ago

Hi! I don't know if this can actually be done, but I would need to find out if OpenRewrite is able to include flat files in the AST and therefore be able to traverse and/or manipulate them.

My use case is as follows: Find out if there is a file with a specific name (x.e: file.marker) and based on that perform some action like adding a maven property to the pom.xml of the project.

For a project structure:

module2
├── pom.xml
└── src
    ├── main
    │   ├── java
    │   │   └── com
    │   │       └── example
    │   │           └── openrewrite
    │   │               └── test
    │   │                   └── module
    │   │                       └── Module2Application.java
    │   ├── markers
    │   │   └── file.marker
    │   └── resources
    │       └── application.properties
    └── test

And according to the following recipe I have tried to traverse the AST looking for the SourceFile file.marker:

    @Override
    protected List<SourceFile> visit(final List<SourceFile> before, final ExecutionContext ctx) {
        final AtomicBoolean amigaWsApiFirstClientMarkerFound = new AtomicBoolean(false);
        ListUtils.map(before, (integer, sourceFile) -> {
            new TreeVisitor<Tree, ExecutionContext>() {
                @Nullable
                @Override
                public Tree visit(@Nullable final Tree tree, final ExecutionContext executionContext) {
                    if (tree instanceof SourceFile) {
                        final SourceFile sourceFile = (SourceFile) tree;
                        System.out.println("############ sourceFile: " + sourceFile.getSourcePath());
                        if (sourceFile.getSourcePath().endsWith(markerFileName)) {
                            amigaWsApiFirstClientMarkerFound.set(true);
                        }
                    }
                    return tree;
                }
            }.visit(before, ctx);
            return sourceFile;
        });

        // If marker is found
        if (amigaWsApiFirstClientMarkerFound.get()) {
            // add maven property
            this.doNext(new ChangePropertyValue(mavenPropertyName, "to fill!", true));
        }

        return super.visit(before, ctx);
    }

But the only results I get are the following:

[INFO] Using active recipe(s) [com.yourorg.DetectMarkerRecipe]
[INFO] Using active styles(s) []
[INFO] Validating active recipes...
[INFO] Parsing Java main files...
[INFO] Parsing Java test files...
[INFO] Running recipe(s)...
############ sourceFile: modules/module2/pom.xml
############ sourceFile: modules/module2/src/main/java/com/example/openrewrite/test/module2/Module2Application.java
############ sourceFile: modules/module2/src/main/resources/application.properties
############ sourceFile: modules/module2/pom.xml
############ sourceFile: modules/module2/src/main/java/com/example/openrewrite/test/module2/Module2Application.java
############ sourceFile: modules/module2/src/main/resources/application.properties
############ sourceFile: modules/module2/pom.xml
############ sourceFile: modules/module2/src/main/java/com/example/openrewrite/test/module2/Module2Application.java
############ sourceFile: modules/module2/src/main/resources/application.properties

Is it possible to do this?

I am using version 7.22.0

Sorry to add a question here, but I added it before on StackOverflow without success.

pway99 commented 2 years ago

Hi @ferblaca, Have a look at the new Quark which was introduced in rewrite 7.23.0 and released yesterday. Now the build plugins will add a Quark having a Path and Markers to the source set for each file not supported by any other parser.

tkvangorder commented 2 years ago

Additionally, there is now a visitSourceFile on the TreeVisitor that can use to see if the file path is present.

ferblaca commented 2 years ago

Hi @pway99 and @tkvangorder !!

I have upgraded to Open Rewrite version 7.23.0 and modified the previous recipe by using visitSourceFile in TreeVisitor, and also to take into account the new source type Quark. However, I still can't browse files with *.marker extension.

The recipe can be found here:

        ListUtils.map(before, (integer, sourceFile) -> {
            new TreeVisitor<Tree, ExecutionContext>() {
                @Override
                public @Nullable Tree visitSourceFile(SourceFile sourceFile, ExecutionContext executionContext) {
                    if (OpenRewriteUtils.isQuarkSource(sourceFile)) {
                        Quark quark = (Quark) sourceFile;
                        System.out.println("############ Quark found: " + quark.getSourcePath());
                    }

                    if (sourceFile.getSourcePath().endsWith(markerFileName)) {
                        amigaWsApiFirstClientMarkerFound.set(true);
                    }
                    return sourceFile;
                }
            }.visit(before, ctx);
            return sourceFile;
        });

I have also created a test where you can see that I am not able to browse the AST using the visitSourceFile.

When executing the recipe in the final project I am not able to get the *.marker files either.

ferblaca commented 2 years ago

Hi @tkvangorder @pway99 !

The problem was that I hadn't updated the maven plug-in version to 4.24.0 and because the file.marker file was empty...

Does the file need to have any content in order to be processed in AST?

pway99 commented 2 years ago

Hi @ferblaca

Does the file need to have any content in order to be processed in AST?

Yes, although that was an oversight. I have updated both plugins to allow empty files to parsed as quarks.

https://github.com/openrewrite/rewrite-maven-plugin/pull/362 https://github.com/openrewrite/rewrite-gradle-plugin/pull/114