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