FWIW, for a related possible future cleanup some modifiers by convention
can be omitted, such as abstract on normal interface methods. The
printModifiers method written annotation processing
http://hg.openjdk.java.net/jdk9/dev/langtools/file/286fc9270404/src/jdk.compiler/share/classes/com/sun/tools/javac/processing/PrintingProcessor.java
tries to output the informative modifiers (in the suggested order).
-Joe
On 9/16/2015 11:20 AM, Martin Buchholz wrote:
Peter, that Java program is awesome, but ...
the original perl seems more readable to me (!)
even if I apply some not-yet-done perl golf to it,
and it seems to me that if we're rewriting in Java we can get the benefits
of Java, i.e. correctness, which you can probably get by tapping into
javac's conversion to AST. This would allow you to get modifiers split
across lines correct, for example.
In practice we want to change the order within e.g. javadoc comments as
well, but we'll leave that to a bolder future code janitor.
On Wed, Sep 16, 2015 at 8:19 AM, Peter Levart <[email protected]>
wrote:
Hi Martin,
On 09/16/2015 02:42 AM, Martin Buchholz wrote:
Hi, Chris and Paul,
I'd like you to do a very boring code review.
This change is entirely machine generated. (the script is more
interesting)http://cr.openjdk.java.net/~martin/webrevs/openjdk9/blessed-modifier-order/blessed-modifier-order.patchhttps://bugs.openjdk.java.net/browse/JDK-8136583
Reviewing the diff would be boring, yes. More interesting is trying to
understand the script.
I re-implemented your script in some other language (called Java ;-) and
compared the results. Nothing can beat concise expressiveness of bash
instantiations of perl template, but Java lambdas and streams are not too
shabby either. Here's a re-implementation in 2 expressions and 1 statement:
import java.io.IOException;
import java.io.UncheckedIOException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.Arrays;
import java.util.List;
import java.util.function.Function;
import java.util.regex.Pattern;
import java.util.stream.Collectors;
import java.util.stream.IntStream;
import java.util.stream.Stream;
import static java.nio.file.StandardCopyOption.*;
import static java.nio.file.StandardOpenOption.*;
public class BlessedModifierOrder {
static final List<String> modifiers = Arrays.asList(
"public", "protected", "private",
"abstract", "static", "final", "transient",
"volatile", "synchronized", "native", "strictfp"
);
static final Function<String, String> editor = IntStream
.range(3, modifiers.size())
.mapToObj(i -> Pattern.compile(
"^([A-Za-z@ ]*)\\b(" +
modifiers.subList(i,
modifiers.size()).stream().collect(Collectors.joining("|")) +
") +(" +
modifiers.subList(0,
i).stream().collect(Collectors.joining("|")) +
")\\b"
))
.map(pattern -> (Function<String, String>) line -> {
String editedLine;
while (!line.equals(editedLine =
pattern.matcher(line).replaceFirst("$1$3 $2"))) {
line = editedLine;
}
return line;
})
.reduce(Function.identity(), (f1, f2) -> f1.andThen(f2));
public static void main(String[] args) {
Stream.of(args)
.map(Paths::get)
.flatMap(dir -> {
try (Stream<Path> files = Files.find(
dir, Integer.MAX_VALUE,
(p, attr) -> attr.isRegularFile() &&
p.toString().endsWith(".java")
)) {
return files.collect(Collectors.toList()).stream();
} catch (IOException e) {
throw new UncheckedIOException(e);
}
})
.forEach(file -> {
try (Stream<String> linesStream = Files.lines(file)) {
List<String> lines = linesStream.map(editor)
.collect(Collectors.toList());
Path newFile =
file.resolveSibling(file.getFileName() + ".new");
Files.write(newFile, lines, WRITE, CREATE,
TRUNCATE_EXISTING);
Files.move(newFile, file, ATOMIC_MOVE,
REPLACE_EXISTING);
} catch (IOException e) {
throw new UncheckedIOException(e);
}
});
}
}
Anyway, the result is exactly the same.
Regards, Peter