Skip to content

Commit f9d0a37

Browse files
committed
Patched an issue with formatting empty elements
1 parent 9e68b29 commit f9d0a37

File tree

1 file changed

+30
-9
lines changed
  • plugins/codemodder-plugin-maven/src/main/java/io/codemodder/plugins/maven/operator

1 file changed

+30
-9
lines changed

plugins/codemodder-plugin-maven/src/main/java/io/codemodder/plugins/maven/operator/FormatCommand.java

Lines changed: 30 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99
import java.net.URISyntaxException;
1010
import java.nio.charset.Charset;
1111
import java.util.*;
12+
import java.util.function.UnaryOperator;
1213
import java.util.regex.Pattern;
1314
import java.util.stream.Collectors;
1415
import java.util.stream.Stream;
@@ -137,22 +138,22 @@ private BitSet elementBitSet(byte[] doc) throws XMLStreamException {
137138
* A Slight variation on writeAsUnicode from stax which writes as a regex string so we could
138139
* rewrite its output
139140
*/
140-
private String writeAsRegex(StartElement element) {
141+
private String writeAsRegex(final StartElement element, final List<Attribute> orderedAttributes) {
141142
StringWriter writer = new StringWriter();
142143

143144
writer.write("<");
144145
writer.write(Pattern.quote(element.getName().getLocalPart()));
145146

146-
Iterator<?> attrIter = element.getAttributes();
147-
while (attrIter.hasNext()) {
148-
Attribute attr = (Attribute) attrIter.next();
149-
147+
for (var attr : orderedAttributes) {
150148
writer.write("\\s+");
151149

152150
writer.write(Pattern.quote(attr.getName().getLocalPart()));
153-
writer.write("=[\\\"\']");
151+
writer.write("\\s*");
152+
writer.write("=");
153+
writer.write("\\s*");
154+
writer.write("[\\\"']");
154155
writer.write(Pattern.quote(attr.getValue()));
155-
writer.write("[\\\"\']");
156+
writer.write("[\\\"']");
156157
}
157158
writer.write("\\s*\\/>");
158159

@@ -335,7 +336,25 @@ private void parseXmlAndCharset(POMDocument pomFile) throws XMLStreamException,
335336
new IntRange(
336337
realElementStart, realElementStart + 1 + trimmedOriginalContent.length());
337338

338-
String contentRe = writeAsRegex(getLastStartElement(prevEvents));
339+
var element = getLastStartElement(prevEvents);
340+
341+
// order the attributes by the original ordering
342+
// attributes names are unique, we can just order them by the index of the name
343+
344+
// Remove attribute contents, just in case some they contain the name of an attribute
345+
// TODO should we trim the element name beforehand?
346+
String contentRemoved = untrimmedOriginalContent.replaceAll("[\\\"'].*[\\\"']", "");
347+
348+
var it = element.getAttributes();
349+
var orderedAttributes =
350+
Stream.iterate(it, Iterator::hasNext, UnaryOperator.identity())
351+
.map(Iterator::next)
352+
.map(a -> new Pair<>(a, contentRemoved.indexOf(a.getName().getLocalPart())))
353+
.sorted(Comparator.comparing(p -> p.getSecond()))
354+
.map(p -> p.getFirst())
355+
.collect(Collectors.toList());
356+
357+
String contentRe = writeAsRegex(element, orderedAttributes);
339358

340359
Regex modifiedContentRE = new Regex(contentRe);
341360

@@ -397,7 +416,7 @@ private StartElement getLastStartElement(List<XMLEvent> prevEvents) {
397416
* <p>this is important so we can mix and match offsets and apply formatting accordingly
398417
*
399418
* @param xmlDocumentString Rendered POM Document Contents (string-formatted)
400-
* @return map of (index, matchData object) reverse ordered
419+
* @return map of (index, matchData object) reve/rse ordered
401420
*/
402421
private LinkedHashMap<Integer, MatchData> findSingleElementMatchesFrom(String xmlDocumentString) {
403422
Sequence<MatchResult> allFoundMatchesSequence =
@@ -494,6 +513,8 @@ private byte[] serializePomFile(POMDocument pom) throws XMLStreamException {
494513
// Let's find out the original empty elements from the original pom and store into a stack
495514
List<MatchData> elementsToReplace = getElementsToReplace(originalElementMap, pom);
496515

516+
// DOM parsers don't guarantee attribute ordering, extract the original ordering for the regex
517+
497518
// Lets to the replacements backwards on the existing, current pom
498519
Map<Integer, MatchData> emptyElements = getEmptyElements(targetElementMap, xmlRepresentation);
499520

0 commit comments

Comments
 (0)