RFR: 8136583: Core libraries should use blessed modifier order
Peter Levart
peter.levart at gmail.com
Wed Sep 16 15:19:14 UTC 2015
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.patch
> https://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
More information about the core-libs-dev
mailing list