Skip to content

Commit

Permalink
Added Recipe for removing Empty XML tags (#3613)
Browse files Browse the repository at this point in the history
* Added Recipe for removing Empty XML tags

Added the recipe to check for and remove empty tags with no children.
Added a test for this recipe.

* added recipe

Added recipe to remove empty and self-closing tags in xml tree.

* Restored ExecutionContextParameterName.java

I changed this file really early by mistake, and forgot to remove this change from origin main.

* Restored build.gradle.kts in rewrite-xml

* added missing curly brace

* Delete Unit)

* Add Gradle license headers

* Revert unintended changes

* Remove `isSelfClosing` and inline `isEmptyTag` & visitor

* Verify empty parents are already removed

* Reuse existing RemoveContentVisitor

* Inline `RemoveEmptyTagsVisitor`, as we already have `RemoveContentVisitor`

* Remove excess cast

* Apply suggestions from code review

---------

Co-authored-by: Tim te Beek <[email protected]>
  • Loading branch information
TheMarvelFan and timtebeek authored Dec 1, 2023
1 parent 777a0f3 commit e587cd8
Show file tree
Hide file tree
Showing 4 changed files with 206 additions and 1 deletion.
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ public Xml visitTag(Xml.Tag tag, P p) {
List<Content> contents = new ArrayList<>(t.getContent());
contents.remove(content);

if (removeEmptyAncestors && contents.isEmpty()) {
if (removeEmptyAncestors && contents.isEmpty() && t.getAttributes().isEmpty()) {
if (getCursor().getParentOrThrow().getValue() instanceof Xml.Document) {
return t.withContent(null).withClosing(null);
} else {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
/*
* Copyright 2023 the original author or authors.
* <p>
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
* <p>
* https://www.apache.org/licenses/LICENSE-2.0
* <p>
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.openrewrite.xml;

import org.openrewrite.Recipe;
import org.openrewrite.ExecutionContext;
import org.openrewrite.TreeVisitor;
import org.openrewrite.xml.tree.Xml;

public class RemoveEmptyXmlTags extends Recipe {
@Override
public String getDisplayName() {
return "Remove empty XML Tag";
}

@Override
public String getDescription() {
return "Removes XML tags that do not have attributes or children, including self closing tags.";
}

@Override
public TreeVisitor<?, ExecutionContext> getVisitor() {
return new XmlIsoVisitor<ExecutionContext>() {
@Override
public Xml.Tag visitTag(Xml.Tag tag, ExecutionContext ctx) {
Xml.Tag t = super.visitTag(tag, ctx);
if (t != null && (t.getContent() == null || t.getContent().isEmpty()) && t.getAttributes().isEmpty()) {
doAfterVisit(new RemoveContentVisitor<>(t, true));
}
return t;
}
};
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,102 @@
/*
* Copyright 2023 the original author or authors.
* <p>
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
* <p>
* https://www.apache.org/licenses/LICENSE-2.0
* <p>
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.openrewrite.xml;

import org.junit.jupiter.api.Test;
import org.openrewrite.test.RewriteTest;

import static org.openrewrite.xml.Assertions.xml;

class RemoveEmptyXmlTagsTest implements RewriteTest {
@Test
void removeEmptyPluginRepositories() {
rewriteRun(
spec -> spec.recipe(new RemoveEmptyXmlTags()),
xml(
"""
<project>
<modelVersion>4.0.0</modelVersion>
<groupId>com.example</groupId>
<artifactId>sample-app</artifactId>
<version>1.0-SNAPSHOT</version>
<pluginRepositories>
</pluginRepositories>
</project>
""",
"""
<project>
<modelVersion>4.0.0</modelVersion>
<groupId>com.example</groupId>
<artifactId>sample-app</artifactId>
<version>1.0-SNAPSHOT</version>
</project>
"""
)
);
}

@Test
void removeNestedEmptyTags() {
rewriteRun(
spec -> spec.recipe(new RemoveEmptyXmlTags()),
xml(
"""
<project>
<modelVersion>4.0.0</modelVersion>
<groupId>com.example</groupId>
<artifactId>sample-app</artifactId>
<version>1.0-SNAPSHOT</version>
<build>
<pluginManagement>
<plugins>
<plugin/>
</plugins>
</pluginManagement>
</build>
</project>
""",
"""
<project>
<modelVersion>4.0.0</modelVersion>
<groupId>com.example</groupId>
<artifactId>sample-app</artifactId>
<version>1.0-SNAPSHOT</version>
</project>
"""
)
);
}

@Test
void retainWhenThereAttributes() {
rewriteRun(
spec -> spec.recipe(new RemoveEmptyXmlTags()),
xml(
"""
<project>
<modelVersion>4.0.0</modelVersion>
<groupId>com.example</groupId>
<artifactId>sample-app</artifactId>
<version>1.0-SNAPSHOT</version>
<build attr="true">
</build>
<dependencies attr="false" />
</project>
"""
)
);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -102,4 +102,60 @@ void fileMatcherEmpty() {
)
);
}

@Test
void removeEmptyParentTag() {
rewriteRun(
spec -> spec.recipe(new RemoveXmlTag("//project/build/pluginManagement/plugins/plugin", null)),
xml(
"""
<project>
<modelVersion>4.0.0</modelVersion>
<groupId>com.example</groupId>
<artifactId>sample-app</artifactId>
<version>1.0-SNAPSHOT</version>
<build>
<pluginManagement>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.8.1</version>
</plugin>
</plugins>
</pluginManagement>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<configuration>
<release>11</release>
</configuration>
</plugin>
</plugins>
</build>
</project>
""",
"""
<project>
<modelVersion>4.0.0</modelVersion>
<groupId>com.example</groupId>
<artifactId>sample-app</artifactId>
<version>1.0-SNAPSHOT</version>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<configuration>
<release>11</release>
</configuration>
</plugin>
</plugins>
</build>
</project>
"""
)
);
}
}

0 comments on commit e587cd8

Please sign in to comment.