[jdk13] Added support for printing text blocks (triple quoted strings) in text block form

This commit is contained in:
Reinier Zwitserloot committed 2019-09-25 01:19:55 +02:00
1 parent 230cd66765
commit 69011b90d8
12 files changed
+146 -37

No files matched your search

+4 -3
View File
@@ -1,5 +1,5 @@
/*
* Copyright (C) 2009-2018 The Project Lombok Authors.
* Copyright (C) 2009-2019 The Project Lombok Authors.
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
@@ -700,11 +700,12 @@ public class Delombok {
String[] argv = argsList.toArray(new String[0]);
args.init("javac", argv);
options.put("diags.legacy", "TRUE");
options.put("allowStringFolding", "FALSE");
} else {
if (modulepath != null && !modulepath.isEmpty()) throw new IllegalStateException("DELOMBOK: Option --module-path requires usage of JDK9 or higher.");
}
CommentCatcher catcher = CommentCatcher.create(context);
CommentCatcher catcher = CommentCatcher.create(context, Javac.getJavaCompilerVersion() >= 13);
JavaCompiler compiler = catcher.getCompiler();
List<JCCompilationUnit> roots = new ArrayList<JCCompilationUnit>();
@@ -769,7 +770,7 @@ public class Delombok {
FormatPreferences fps = new FormatPreferences(formatPrefs);
for (JCCompilationUnit unit : roots) {
DelombokResult result = new DelombokResult(catcher.getComments(unit), unit, force || options.isChanged(unit), fps);
DelombokResult result = new DelombokResult(catcher.getComments(unit), catcher.getTextBlockStarts(unit), unit, force || options.isChanged(unit), fps);
if (onlyChanged && !result.isChanged() && !options.isChanged(unit)) {
if (verbose) feedback.printf("File: %s [%s]\n", unit.sourcefile.getName(), "unchanged (skipped)");
continue;
@@ -1,5 +1,5 @@
/*
* Copyright (C) 2009-2013 The Project Lombok Authors.
* Copyright (C) 2009-2019 The Project Lombok Authors.
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
@@ -34,12 +34,14 @@ import com.sun.tools.javac.tree.JCTree.JCCompilationUnit;
public class DelombokResult {
private final List<CommentInfo> comments;
private final List<Integer> textBlockStarts;
private final JCCompilationUnit compilationUnit;
private final boolean changed;
private final FormatPreferences formatPreferences;
public DelombokResult(List<CommentInfo> comments, JCCompilationUnit compilationUnit, boolean changed, FormatPreferences formatPreferences) {
public DelombokResult(List<CommentInfo> comments, List<Integer> textBlockStarts, JCCompilationUnit compilationUnit, boolean changed, FormatPreferences formatPreferences) {
this.comments = comments;
this.textBlockStarts = textBlockStarts;
this.compilationUnit = compilationUnit;
this.changed = changed;
this.formatPreferences = formatPreferences;
@@ -61,12 +63,15 @@ public class DelombokResult {
}
com.sun.tools.javac.util.List<CommentInfo> comments_;
int[] textBlockStarts_;
if (comments instanceof com.sun.tools.javac.util.List) comments_ = (com.sun.tools.javac.util.List<CommentInfo>) comments;
else comments_ = com.sun.tools.javac.util.List.from(comments.toArray(new CommentInfo[0]));
textBlockStarts_ = new int[textBlockStarts.size()];
int idx = 0;
for (int tbs : textBlockStarts) textBlockStarts_[idx++] = tbs;
FormatPreferences preferences = new FormatPreferenceScanner().scan(formatPreferences, getContent());
//compilationUnit.accept(new PrettyCommentsPrinter(out, compilationUnit, comments_, preferences));
compilationUnit.accept(new PrettyPrinter(out, compilationUnit, comments_, preferences));
compilationUnit.accept(new PrettyPrinter(out, compilationUnit, comments_, textBlockStarts_, preferences));
}
private CharSequence getContent() throws IOException {
@@ -31,6 +31,7 @@ import java.io.Writer;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.Arrays;
import java.util.HashMap;
import java.util.Map;
@@ -153,6 +154,7 @@ public class PrettyPrinter extends JCTree.Visitor {
private final Writer out;
private final JCCompilationUnit compilationUnit;
private List<CommentInfo> comments;
private final int[] textBlockStarts;
private final FormatPreferences formatPreferences;
private final Map<JCTree, String> docComments;
@@ -160,9 +162,10 @@ public class PrettyPrinter extends JCTree.Visitor {
private int indent = 0;
@SuppressWarnings({"unchecked", "rawtypes"})
public PrettyPrinter(Writer out, JCCompilationUnit cu, List<CommentInfo> comments, FormatPreferences preferences) {
public PrettyPrinter(Writer out, JCCompilationUnit cu, List<CommentInfo> comments, int[] textBlockStarts, FormatPreferences preferences) {
this.out = out;
this.comments = comments;
this.textBlockStarts = textBlockStarts;
this.compilationUnit = cu;
this.formatPreferences = preferences;
@@ -740,7 +743,37 @@ public class PrettyPrinter extends JCTree.Visitor {
}
else if (CTC_BOOLEAN.equals(typeTag)) print(((Number)tree.value).intValue() == 1 ? "true" : "false");
else if (CTC_BOT.equals(typeTag)) print("null");
else print("\"" + quoteChars(tree.value.toString()) + "\"");
else {
if (Arrays.binarySearch(textBlockStarts, tree.pos) < 0) {
print("\"" + quoteChars(tree.value.toString()) + "\"");
} else {
printTextBlock(tree.value.toString());
}
}
}
private void printTextBlock(String s) {
println("\"\"\"");
needsAlign = true;
indent++;
StringBuilder sb = new StringBuilder();
boolean lineStart = true;
for (int i = 0; i < s.length(); i++) {
char c = s.charAt(i);
if (c != ' ' && c != '\t') lineStart = false;
if (c == '\n') {
println(sb);
sb.setLength(0);
needsAlign = true;
lineStart = true;
continue;
}
if (c == '\t' && lineStart) sb.append("\t");
else sb.append(quoteChar(s.charAt(i)));
}
print(sb);
print("\"\"\"");
indent--;
}
@Override public void visitMethodDef(JCMethodDecl tree) {
@@ -2,7 +2,7 @@ package com.sun.tools.javac.parser;
public class Tokens {
public static class Token {
public int pos;
}
public interface Comment {
+11 -4
View File
@@ -1,5 +1,5 @@
/*
* Copyright (C) 2011-2014 The Project Lombok Authors.
* Copyright (C) 2011-2019 The Project Lombok Authors.
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
@@ -35,9 +35,10 @@ import com.sun.tools.javac.util.Context;
public class CommentCatcher {
private final JavaCompiler compiler;
public static final FieldAugment<JCCompilationUnit, List<CommentInfo>> JCCompilationUnit_comments = FieldAugment.augment(JCCompilationUnit.class, List.class, "lombok$comments");
public static final FieldAugment<JCCompilationUnit, List<Integer>> JCCompilationUnit_textBlockStarts = FieldAugment.augment(JCCompilationUnit.class, List.class, "lombok$textBlockStarts");
public static CommentCatcher create(Context context) {
registerCommentsCollectingScannerFactory(context);
public static CommentCatcher create(Context context, boolean findTextBlocks) {
registerCommentsCollectingScannerFactory(context, findTextBlocks);
JavaCompiler compiler = new JavaCompiler(context);
setInCompiler(compiler, context);
@@ -69,7 +70,12 @@ public class CommentCatcher {
return list == null ? Collections.<CommentInfo>emptyList() : list;
}
private static void registerCommentsCollectingScannerFactory(Context context) {
public List<Integer> getTextBlockStarts(JCCompilationUnit ast) {
List<Integer> list = JCCompilationUnit_textBlockStarts.get(ast);
return list == null ? Collections.<Integer>emptyList() : list;
}
private static void registerCommentsCollectingScannerFactory(Context context, boolean findTextBlocks) {
try {
Class<?> scannerFactory;
int javaCompilerVersion = Javac.getJavaCompilerVersion();
@@ -79,6 +85,7 @@ public class CommentCatcher {
scannerFactory = Class.forName("lombok.javac.java7.CommentCollectingScannerFactory");
} else {
scannerFactory = Class.forName("lombok.javac.java8.CommentCollectingScannerFactory");
if (findTextBlocks) Permit.getField(scannerFactory, "findTextBlocks").set(null, true);
}
Permit.getMethod(scannerFactory, "preRegister", Context.class).invoke(null, context);
} catch (InvocationTargetException e) {
@@ -1,5 +1,5 @@
/*
* Copyright (C) 2013-2014 The Project Lombok Authors.
* Copyright (C) 2013-2019 The Project Lombok Authors.
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
@@ -22,10 +22,7 @@
package lombok.javac.java8;
import static lombok.javac.CommentCatcher.JCCompilationUnit_comments;
import java.util.List;
import lombok.javac.CommentInfo;
import static lombok.javac.CommentCatcher.JCCompilationUnit_textBlockStarts;
import com.sun.tools.javac.parser.JavacParser;
import com.sun.tools.javac.parser.Lexer;
@@ -44,8 +41,8 @@ class CommentCollectingParser extends JavacParser {
public JCCompilationUnit parseCompilationUnit() {
JCCompilationUnit result = super.parseCompilationUnit();
if (lexer instanceof CommentCollectingScanner) {
List<CommentInfo> comments = ((CommentCollectingScanner)lexer).getComments();
JCCompilationUnit_comments.set(result, comments);
JCCompilationUnit_comments.set(result, ((CommentCollectingScanner) lexer).getComments());
JCCompilationUnit_textBlockStarts.set(result, ((CommentCollectingScanner) lexer).getTextBlockStarts());
}
return result;
}
@@ -1,5 +1,5 @@
/*
* Copyright (C) 2013 The Project Lombok Authors.
* Copyright (C) 2013-2019 The Project Lombok Authors.
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
@@ -39,4 +39,8 @@ public class CommentCollectingScanner extends Scanner {
public List<CommentInfo> getComments() {
return tokenizer.getComments();
}
public List<Integer> getTextBlockStarts() {
return tokenizer.getTextBlockStarts();
}
}
@@ -1,5 +1,5 @@
/*
* Copyright (C) 2011-2013 The Project Lombok Authors.
* Copyright (C) 2011-2019 The Project Lombok Authors.
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
@@ -28,7 +28,7 @@ import com.sun.tools.javac.parser.ScannerFactory;
import com.sun.tools.javac.util.Context;
public class CommentCollectingScannerFactory extends ScannerFactory {
public static boolean findTextBlocks;
@SuppressWarnings("all")
public static void preRegister(final Context context) {
if (context.get(scannerFactoryKey) == null) {
@@ -76,7 +76,7 @@ public class CommentCollectingScannerFactory extends ScannerFactory {
public Scanner newScanner(CharSequence input, boolean keepDocComments) {
if (input instanceof CharBuffer) {
CharBuffer buf = (CharBuffer) input;
return new CommentCollectingScanner(this, new CommentCollectingTokenizer(this, buf));
return new CommentCollectingScanner(this, new CommentCollectingTokenizer(this, buf, findTextBlocks));
}
char[] array = input.toString().toCharArray();
return newScanner(array, array.length, keepDocComments);
@@ -84,6 +84,6 @@ public class CommentCollectingScannerFactory extends ScannerFactory {
@Override
public Scanner newScanner(char[] input, int inputLength, boolean keepDocComments) {
return new CommentCollectingScanner(this, new CommentCollectingTokenizer(this, input, inputLength));
return new CommentCollectingScanner(this, new CommentCollectingTokenizer(this, input, inputLength, findTextBlocks));
}
}
@@ -1,5 +1,5 @@
/*
* Copyright (C) 2013 The Project Lombok Authors.
* Copyright (C) 2013-2019 The Project Lombok Authors.
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
@@ -39,19 +39,30 @@ import com.sun.tools.javac.util.ListBuffer;
class CommentCollectingTokenizer extends JavaTokenizer {
private int prevEndPosition = 0;
private final ListBuffer<CommentInfo> comments = new ListBuffer<CommentInfo>();
private final ListBuffer<Integer> textBlockStarts;
private int endComment = 0;
CommentCollectingTokenizer(ScannerFactory fac, char[] buf, int inputLength) {
CommentCollectingTokenizer(ScannerFactory fac, char[] buf, int inputLength, boolean findTextBlocks) {
super(fac, new PositionUnicodeReader(fac, buf, inputLength));
textBlockStarts = findTextBlocks ? new ListBuffer<Integer>() : null;
}
CommentCollectingTokenizer(ScannerFactory fac, CharBuffer buf) {
CommentCollectingTokenizer(ScannerFactory fac, CharBuffer buf, boolean findTextBlocks) {
super(fac, new PositionUnicodeReader(fac, buf));
textBlockStarts = findTextBlocks ? new ListBuffer<Integer>() : null;
}
int pos() {
return ((PositionUnicodeReader) reader).pos();
}
@Override public Token readToken() {
Token token = super.readToken();
prevEndPosition = ((PositionUnicodeReader)reader).pos();
prevEndPosition = pos();
if (textBlockStarts != null && (prevEndPosition - token.pos > 5) && token.getClass().getSimpleName().equals("StringToken")) {
char[] start = reader.getRawCharacters(token.pos, token.pos + 3);
if (start[0] == '"' && start[1] == '"' && start[2] == '"') textBlockStarts.add(token.pos);
}
return token;
}
@@ -113,6 +124,10 @@ class CommentCollectingTokenizer extends JavaTokenizer {
return comments.toList();
}
public List<Integer> getTextBlockStarts() {
return textBlockStarts == null ? List.<Integer>nil() : textBlockStarts.toList();
}
static class PositionUnicodeReader extends UnicodeReader {
protected PositionUnicodeReader(ScannerFactory sf, char[] input, int inputLength) {
super(sf, input, inputLength);
@@ -1,5 +1,5 @@
/*
* Copyright (C) 2013-2017 The Project Lombok Authors.
* Copyright (C) 2013-2019 The Project Lombok Authors.
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
@@ -22,10 +22,8 @@
package lombok.javac.java9;
import static lombok.javac.CommentCatcher.JCCompilationUnit_comments;
import static lombok.javac.CommentCatcher.JCCompilationUnit_textBlockStarts;
import java.util.List;
import lombok.javac.CommentInfo;
import lombok.javac.java8.CommentCollectingScanner;
import com.sun.tools.javac.parser.JavacParser;
@@ -45,8 +43,8 @@ class CommentCollectingParser extends JavacParser {
public JCCompilationUnit parseCompilationUnit() {
JCCompilationUnit result = super.parseCompilationUnit();
if (lexer instanceof CommentCollectingScanner) {
List<CommentInfo> comments = ((CommentCollectingScanner)lexer).getComments();
JCCompilationUnit_comments.set(result, comments);
JCCompilationUnit_comments.set(result, ((CommentCollectingScanner) lexer).getComments());
JCCompilationUnit_textBlockStarts.set(result, ((CommentCollectingScanner) lexer).getTextBlockStarts());
}
return result;
}
@@ -0,0 +1,25 @@
public class TextBlocks {
private String example = """
This should not be indented.
line 2
line 3
""";
private String ex2 = """
This should be though.
""";
private String ex3 = "This is a simple\nstring";
private String ex4 = """
""";
private String bizarroDent = """
foo
bar""" + "hey" + """
weird!""";
private String stringFolding = "hmmm" + """
line1
line2""";
}
@@ -0,0 +1,24 @@
// version 13:
public class TextBlocks {
private String example = """
This should not be indented.\nline 2
line 3
""";
private String ex2 = """
This should be though.
""";
private String ex3 = "This is a simple\nstring";
private String ex4 = """
""";
private String bizarroDent = """
foo\n bar""" + "hey" + """
weird!""";
private String stringFolding = "hmmm" + """
line1
line2""";
}