aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/core/lombok/bytecode/ClassFileMetaData.java7
-rw-r--r--src/core/lombok/core/LombokInternalAliasing.java35
-rw-r--r--src/core/lombok/core/TypeLibrary.java60
-rw-r--r--src/core/lombok/core/TypeResolver.java81
-rw-r--r--src/core/lombok/eclipse/EclipseImportList.java10
-rwxr-xr-xsrc/core/lombok/eclipse/handlers/EclipseSingularsRecipes.java4
-rw-r--r--src/core/lombok/javac/JavacImportList.java7
-rw-r--r--src/core/lombok/javac/handlers/JavacSingularsRecipes.java4
-rwxr-xr-xsrc/delombok/lombok/delombok/Delombok.java7
-rw-r--r--src/delombok/lombok/delombok/DelombokResult.java13
-rw-r--r--src/delombok/lombok/delombok/PrettyPrinter.java76
-rw-r--r--src/eclipseAgent/lombok/eclipse/agent/PatchVal.java4
-rw-r--r--src/installer/lombok/installer/eclipse/EclipseProductLocation.java8
-rw-r--r--src/stubs/com/sun/tools/javac/parser/Tokens.java2
-rw-r--r--src/utils/lombok/javac/CommentCatcher.java15
-rw-r--r--src/utils/lombok/javac/java8/CommentCollectingParser.java11
-rw-r--r--src/utils/lombok/javac/java8/CommentCollectingScanner.java6
-rw-r--r--src/utils/lombok/javac/java8/CommentCollectingScannerFactory.java8
-rw-r--r--src/utils/lombok/javac/java8/CommentCollectingTokenizer.java25
-rw-r--r--src/utils/lombok/javac/java9/CommentCollectingParser.java10
20 files changed, 253 insertions, 140 deletions
diff --git a/src/core/lombok/bytecode/ClassFileMetaData.java b/src/core/lombok/bytecode/ClassFileMetaData.java
index 826eed83..0510292d 100644
--- a/src/core/lombok/bytecode/ClassFileMetaData.java
+++ b/src/core/lombok/bytecode/ClassFileMetaData.java
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2010-2018 The Project Lombok Authors.
+ * Copyright (C) 2010-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
@@ -43,6 +43,7 @@ public class ClassFileMetaData {
// New in java7: support for methodhandles and invokedynamic
private static final byte METHOD_HANDLE = 15;
private static final byte METHOD_TYPE = 16;
+ private static final byte DYNAMIC = 17;
private static final byte INVOKE_DYNAMIC = 18;
// New in java9: support for modules
private static final byte MODULE = 19;
@@ -96,6 +97,7 @@ public class ClassFileMetaData {
case INTERFACE_METHOD:
case NAME_TYPE:
case INVOKE_DYNAMIC:
+ case DYNAMIC:
position += 4;
break;
case LONG:
@@ -388,6 +390,9 @@ public class ClassFileMetaData {
case METHOD_TYPE:
result.append("MethodType...");
break;
+ case DYNAMIC:
+ result.append("Dynamic...");
+ break;
case INVOKE_DYNAMIC:
result.append("InvokeDynamic...");
break;
diff --git a/src/core/lombok/core/LombokInternalAliasing.java b/src/core/lombok/core/LombokInternalAliasing.java
index 68ced84f..60dea0f2 100644
--- a/src/core/lombok/core/LombokInternalAliasing.java
+++ b/src/core/lombok/core/LombokInternalAliasing.java
@@ -28,8 +28,6 @@ import java.util.HashMap;
import java.util.Map;
public class LombokInternalAliasing {
- /** Maps a package name to a space separated list of packages. If the key package is star-imported, assume all packages in the 'value' part of the MapEntry are too. */
- public static final Map<String, Collection<String>> IMPLIED_EXTRA_STAR_IMPORTS;
public static final Map<String, String> ALIASES;
public static final Map<String, Collection<String>> REVERSE_ALIASES;
@@ -43,36 +41,31 @@ public class LombokInternalAliasing {
}
static {
- Map<String, Collection<String>> m1 = new HashMap<String, Collection<String>>();
- m1.put("lombok.experimental", Collections.singleton("lombok"));
- m1.put("lombok", Collections.singleton("lombok.experimental"));
- IMPLIED_EXTRA_STAR_IMPORTS = Collections.unmodifiableMap(m1);
+ Map<String, String> m1 = new HashMap<String, String>();
+ m1.put("lombok.experimental.Value", "lombok.Value");
+ m1.put("lombok.experimental.Builder", "lombok.Builder");
+ m1.put("lombok.experimental.var", "lombok.var");
+ m1.put("lombok.Delegate", "lombok.experimental.Delegate");
+ m1.put("lombok.experimental.Wither", "lombok.With");
+ ALIASES = Collections.unmodifiableMap(m1);
- Map<String, String> m2 = new HashMap<String, String>();
- m2.put("lombok.experimental.Value", "lombok.Value");
- m2.put("lombok.experimental.Builder", "lombok.Builder");
- m2.put("lombok.experimental.var", "lombok.var");
- m2.put("lombok.Delegate", "lombok.experimental.Delegate");
- m2.put("lombok.experimental.Wither", "lombok.With");
- ALIASES = Collections.unmodifiableMap(m2);
-
- Map<String, Collection<String>> m3 = new HashMap<String, Collection<String>>();
- for (Map.Entry<String, String> e : m2.entrySet()) {
- Collection<String> c = m3.get(e.getValue());
+ Map<String, Collection<String>> m2 = new HashMap<String, Collection<String>>();
+ for (Map.Entry<String, String> e : m1.entrySet()) {
+ Collection<String> c = m2.get(e.getValue());
if (c == null) {
- m3.put(e.getValue(), Collections.singleton(e.getKey()));
+ m2.put(e.getValue(), Collections.singleton(e.getKey()));
} else if (c.size() == 1) {
Collection<String> newC = new ArrayList<String>(2);
newC.addAll(c);
- m3.put(e.getValue(), c);
+ m2.put(e.getValue(), c);
} else {
c.add(e.getKey());
}
}
- for (Map.Entry<String, Collection<String>> e : m3.entrySet()) {
+ for (Map.Entry<String, Collection<String>> e : m2.entrySet()) {
Collection<String> c = e.getValue();
if (c.size() > 1) e.setValue(Collections.unmodifiableList((ArrayList<String>) c));
}
- REVERSE_ALIASES = Collections.unmodifiableMap(m3);
+ REVERSE_ALIASES = Collections.unmodifiableMap(m2);
}
}
diff --git a/src/core/lombok/core/TypeLibrary.java b/src/core/lombok/core/TypeLibrary.java
index 113ce67e..8b9fa4b0 100644
--- a/src/core/lombok/core/TypeLibrary.java
+++ b/src/core/lombok/core/TypeLibrary.java
@@ -21,8 +21,11 @@
*/
package lombok.core;
+import java.util.Arrays;
import java.util.Collection;
+import java.util.Collections;
import java.util.HashMap;
+import java.util.List;
import java.util.Map;
/**
@@ -36,18 +39,18 @@ import java.util.Map;
* <ul><li>foo.Spork</li><li>Spork</li><li>foo.*</li></ul>
*/
public class TypeLibrary {
- private final Map<String, String> unqualifiedToQualifiedMap;
+ private final Map<String, Object> unqualifiedToQualifiedMap; // maps to usually a string, but could be a string array in aliasing cases.
private final String unqualified, qualified;
private boolean locked;
public TypeLibrary() {
- unqualifiedToQualifiedMap = new HashMap<String, String>();
+ unqualifiedToQualifiedMap = new HashMap<String, Object>();
unqualified = null;
qualified = null;
}
public TypeLibrary(TypeLibrary parent) {
- unqualifiedToQualifiedMap = new HashMap<String, String>();
+ unqualifiedToQualifiedMap = new HashMap<String, Object>();
unqualified = null;
qualified = null;
}
@@ -58,7 +61,7 @@ public class TypeLibrary {
private TypeLibrary(String fqnSingleton) {
if (fqnSingleton.indexOf("$") != -1) {
- unqualifiedToQualifiedMap = new HashMap<String, String>();
+ unqualifiedToQualifiedMap = new HashMap<String, Object>();
unqualified = null;
qualified = null;
addType(fqnSingleton);
@@ -93,6 +96,9 @@ public class TypeLibrary {
* @param fullyQualifiedTypeName the FQN type name, such as 'java.lang.String'.
*/
public void addType(String fullyQualifiedTypeName) {
+ Collection<String> oldNames = LombokInternalAliasing.REVERSE_ALIASES.get(fullyQualifiedTypeName);
+ if (oldNames != null) for (String oldName : oldNames) addType(oldName);
+
String dotBased = fullyQualifiedTypeName.replace("$", ".");
if (locked) throw new IllegalStateException("locked");
@@ -102,22 +108,16 @@ public class TypeLibrary {
String unqualified = fullyQualifiedTypeName.substring(idx + 1);
if (unqualifiedToQualifiedMap == null) throw new IllegalStateException("SingleType library");
- unqualifiedToQualifiedMap.put(unqualified.replace("$", "."), dotBased);
- unqualifiedToQualifiedMap.put(unqualified, dotBased);
- unqualifiedToQualifiedMap.put(fullyQualifiedTypeName, dotBased);
- unqualifiedToQualifiedMap.put(dotBased, dotBased);
- Collection<String> oldNames = LombokInternalAliasing.REVERSE_ALIASES.get(fullyQualifiedTypeName);
- if (oldNames != null) for (String oldName : oldNames) {
- unqualifiedToQualifiedMap.put(oldName, dotBased);
- int li = oldName.lastIndexOf('.');
- if (li != -1) unqualifiedToQualifiedMap.put(oldName.substring(li + 1), dotBased);
- }
+ put(unqualified.replace("$", "."), dotBased);
+ put(unqualified, dotBased);
+ put(fullyQualifiedTypeName, dotBased);
+ put(dotBased, dotBased);
int idx2 = fullyQualifiedTypeName.indexOf('$', idx + 1);
while (idx2 != -1) {
String unq = fullyQualifiedTypeName.substring(idx2 + 1);
- unqualifiedToQualifiedMap.put(unq.replace("$", "."), dotBased);
- unqualifiedToQualifiedMap.put(unq, dotBased);
+ put(unq.replace("$", "."), dotBased);
+ put(unq, dotBased);
idx2 = fullyQualifiedTypeName.indexOf('$', idx2 + 1);
}
}
@@ -126,13 +126,33 @@ public class TypeLibrary {
* Translates an unqualified name such as 'String' to 'java.lang.String', _if_ you added 'java.lang.String' to the library via the {@code addType} method.
* Also returns the input if it is equal to a fully qualified name added to this type library.
*
- * Returns null if it does not match any type in this type library.
+ * Returns an empty collection if it does not match any type in this type library.
*/
- public String toQualified(String typeReference) {
+ public List<String> toQualifieds(String typeReference) {
if (unqualifiedToQualifiedMap == null) {
- if (typeReference.equals(unqualified) || typeReference.equals(qualified)) return qualified;
+ if (typeReference.equals(unqualified) || typeReference.equals(qualified)) return Collections.singletonList(qualified);
return null;
}
- return unqualifiedToQualifiedMap.get(typeReference);
+
+ Object v = unqualifiedToQualifiedMap.get(typeReference);
+ if (v == null) return Collections.emptyList();
+ if (v instanceof String) return Collections.singletonList((String) v);
+ return Arrays.asList((String[]) v);
+ }
+
+ private void put(String k, String v) {
+ Object old = unqualifiedToQualifiedMap.put(k, v);
+ if (old == null) return;
+ String[] nv;
+ if (old instanceof String) {
+ if (old.equals(v)) return;
+ nv = new String[] {(String) old, v};
+ } else {
+ String[] s = (String[]) old;
+ nv = new String[s.length + 1];
+ System.arraycopy(s, 0, nv, 0, s.length);
+ nv[s.length] = v;
+ }
+ unqualifiedToQualifiedMap.put(k, nv);
}
}
diff --git a/src/core/lombok/core/TypeResolver.java b/src/core/lombok/core/TypeResolver.java
index 06c91138..2c36d1fc 100644
--- a/src/core/lombok/core/TypeResolver.java
+++ b/src/core/lombok/core/TypeResolver.java
@@ -21,6 +21,8 @@
*/
package lombok.core;
+import java.util.List;
+
import lombok.core.AST.Kind;
/**
@@ -44,13 +46,12 @@ public class TypeResolver {
}
public String typeRefToFullyQualifiedName(LombokNode<?, ?, ?> context, TypeLibrary library, String typeRef) {
- typeRef = LombokInternalAliasing.processAliases(typeRef);
// When asking if 'Foo' could possibly be referring to 'bar.Baz', the answer is obviously no.
- String qualified = library.toQualified(typeRef);
- if (qualified == null) return null;
+ List<String> qualifieds = library.toQualifieds(typeRef);
+ if (qualifieds == null || qualifieds.isEmpty()) return null;
// When asking if 'lombok.Getter' could possibly be referring to 'lombok.Getter', the answer is obviously yes.
- if (typeRef.equals(qualified)) return typeRef;
+ if (qualifieds.contains(typeRef)) return LombokInternalAliasing.processAliases(typeRef);
// When asking if 'Getter' could possibly be referring to 'lombok.Getter' if 'import lombok.Getter;' is in the source file, the answer is yes.
int firstDot = typeRef.indexOf('.');
@@ -58,50 +59,58 @@ public class TypeResolver {
String firstTypeRef = typeRef.substring(0, firstDot);
String fromExplicitImport = imports.getFullyQualifiedNameForSimpleName(firstTypeRef);
if (fromExplicitImport != null) {
+ String fqn = fromExplicitImport + typeRef.substring(firstDot);
+ if (qualifieds.contains(fqn)) return LombokInternalAliasing.processAliases(fqn);
// ... and if 'import foobar.Getter;' is in the source file, the answer is no.
- return (fromExplicitImport + typeRef.substring(firstDot)).equals(qualified) ? qualified : null;
+ return null;
}
// When asking if 'Getter' could possibly be referring to 'lombok.Getter' and 'import lombok.*; / package lombok;' isn't in the source file. the answer is no.
- String pkgName = qualified.substring(0, qualified.length() - typeRef.length() - 1);
- if (!imports.hasStarImport(pkgName)) return null;
-
- // Now the hard part: Given that there is a star import, 'Getter' most likely refers to 'lombok.Getter', but type shadowing may occur in which case it doesn't.
- LombokNode<?, ?, ?> n = context;
-
- mainLoop:
- while (n != null) {
- if (n.getKind() == Kind.TYPE && firstTypeRef.equals(n.getName())) {
- // Our own class or one of our outer classes is named 'typeRef' so that's what 'typeRef' is referring to, not one of our type library classes.
- return null;
- }
+ for (String qualified : qualifieds) {
+ String pkgName = qualified.substring(0, qualified.length() - typeRef.length() - 1);
+ if (!imports.hasStarImport(pkgName)) continue;
- if (n.getKind() == Kind.STATEMENT || n.getKind() == Kind.LOCAL) {
- LombokNode<?, ?, ?> newN = n.directUp();
- if (newN == null) break mainLoop;
+ // Now the hard part: Given that there is a star import, 'Getter' most likely refers to 'lombok.Getter', but type shadowing may occur in which case it doesn't.
+ LombokNode<?, ?, ?> n = context;
+
+ mainLoop:
+ while (n != null) {
+ if (n.getKind() == Kind.TYPE && firstTypeRef.equals(n.getName())) {
+ // Our own class or one of our outer classes is named 'typeRef' so that's what 'typeRef' is referring to, not one of our type library classes.
+ return null;
+ }
- if (newN.getKind() == Kind.STATEMENT || newN.getKind() == Kind.INITIALIZER || newN.getKind() == Kind.METHOD) {
- for (LombokNode<?, ?, ?> child : newN.down()) {
- // We found a method local with the same name above our code. That's the one 'typeRef' is referring to, not
- // anything in the type library we're trying to find, so, no matches.
- if (child.getKind() == Kind.TYPE && firstTypeRef.equals(child.getName())) return null;
- if (child == n) break;
+ if (n.getKind() == Kind.STATEMENT || n.getKind() == Kind.LOCAL) {
+ LombokNode<?, ?, ?> newN = n.directUp();
+ if (newN == null) break mainLoop;
+
+ if (newN.getKind() == Kind.STATEMENT || newN.getKind() == Kind.INITIALIZER || newN.getKind() == Kind.METHOD) {
+ for (LombokNode<?, ?, ?> child : newN.down()) {
+ // We found a method local with the same name above our code. That's the one 'typeRef' is referring to, not
+ // anything in the type library we're trying to find, so, no matches.
+ if (child.getKind() == Kind.TYPE && firstTypeRef.equals(child.getName())) return null;
+ if (child == n) break;
+ }
}
+ n = newN;
+ continue mainLoop;
}
- n = newN;
- continue mainLoop;
- }
-
- if (n.getKind() == Kind.TYPE || n.getKind() == Kind.COMPILATION_UNIT) {
- for (LombokNode<?, ?, ?> child : n.down()) {
- // Inner class that's visible to us has 'typeRef' as name, so that's the one being referred to, not one of our type library classes.
- if (child.getKind() == Kind.TYPE && firstTypeRef.equals(child.getName())) return null;
+
+ if (n.getKind() == Kind.TYPE || n.getKind() == Kind.COMPILATION_UNIT) {
+ for (LombokNode<?, ?, ?> child : n.down()) {
+ // Inner class that's visible to us has 'typeRef' as name, so that's the one being referred to, not one of our type library classes.
+ if (child.getKind() == Kind.TYPE && firstTypeRef.equals(child.getName())) return null;
+ }
}
+
+ n = n.directUp();
}
- n = n.directUp();
+ // If no shadowing thing has been found, the star import 'wins', so, return that.
+ return LombokInternalAliasing.processAliases(qualified);
}
- return qualified;
+ // No star import matches either.
+ return null;
}
}
diff --git a/src/core/lombok/eclipse/EclipseImportList.java b/src/core/lombok/eclipse/EclipseImportList.java
index 47167ec6..6d60f5aa 100644
--- a/src/core/lombok/eclipse/EclipseImportList.java
+++ b/src/core/lombok/eclipse/EclipseImportList.java
@@ -27,7 +27,6 @@ import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.List;
-import java.util.Map;
import lombok.core.ImportList;
import lombok.core.LombokInternalAliasing;
@@ -65,19 +64,10 @@ public class EclipseImportList implements ImportList {
if (isEqual(packageName, pkg)) return true;
if ("java.lang".equals(packageName)) return true;
- if (pkg != null && pkg.tokens != null && pkg.tokens.length == 0) {
- for (Map.Entry<String, Collection<String>> e : LombokInternalAliasing.IMPLIED_EXTRA_STAR_IMPORTS.entrySet()) {
- if (isEqual(e.getKey(), pkg) && e.getValue().contains(packageName)) return true;
- }
- }
-
if (imports != null) for (ImportReference imp : imports) {
if ((imp.bits & ASTNode.OnDemand) == 0) continue;
if (imp.isStatic()) continue;
if (isEqual(packageName, imp)) return true;
- for (Map.Entry<String, Collection<String>> e : LombokInternalAliasing.IMPLIED_EXTRA_STAR_IMPORTS.entrySet()) {
- if (isEqual(e.getKey(), imp) && e.getValue().contains(packageName)) return true;
- }
}
return false;
diff --git a/src/core/lombok/eclipse/handlers/EclipseSingularsRecipes.java b/src/core/lombok/eclipse/handlers/EclipseSingularsRecipes.java
index 0f463ae2..ce5a1b4c 100755
--- a/src/core/lombok/eclipse/handlers/EclipseSingularsRecipes.java
+++ b/src/core/lombok/eclipse/handlers/EclipseSingularsRecipes.java
@@ -109,7 +109,9 @@ public class EclipseSingularsRecipes {
}
public String toQualified(String typeReference) {
- return singularizableTypes.toQualified(typeReference);
+ List<String> q = singularizableTypes.toQualifieds(typeReference);
+ if (q.isEmpty()) return null;
+ return q.get(0);
}
public EclipseSingularizer getSingularizer(String fqn) {
diff --git a/src/core/lombok/javac/JavacImportList.java b/src/core/lombok/javac/JavacImportList.java
index 468d8c7b..8de61afc 100644
--- a/src/core/lombok/javac/JavacImportList.java
+++ b/src/core/lombok/javac/JavacImportList.java
@@ -60,11 +60,6 @@ public class JavacImportList implements ImportList {
if (pkgStr != null && pkgStr.equals(packageName)) return true;
if ("java.lang".equals(packageName)) return true;
- if (pkgStr != null) {
- Collection<String> extra = LombokInternalAliasing.IMPLIED_EXTRA_STAR_IMPORTS.get(pkgStr);
- if (extra != null && extra.contains(packageName)) return true;
- }
-
for (JCTree def : defs) {
if (!(def instanceof JCImport)) continue;
if (((JCImport) def).staticImport) continue;
@@ -74,8 +69,6 @@ public class JavacImportList implements ImportList {
if (!"*".equals(simpleName)) continue;
String starImport = ((JCFieldAccess) qual).selected.toString();
if (packageName.equals(starImport)) return true;
- Collection<String> extra = LombokInternalAliasing.IMPLIED_EXTRA_STAR_IMPORTS.get(starImport);
- if (extra != null && extra.contains(packageName)) return true;
}
return false;
diff --git a/src/core/lombok/javac/handlers/JavacSingularsRecipes.java b/src/core/lombok/javac/handlers/JavacSingularsRecipes.java
index 10e6f9b4..87081dde 100644
--- a/src/core/lombok/javac/handlers/JavacSingularsRecipes.java
+++ b/src/core/lombok/javac/handlers/JavacSingularsRecipes.java
@@ -101,7 +101,9 @@ public class JavacSingularsRecipes {
}
public String toQualified(String typeReference) {
- return singularizableTypes.toQualified(typeReference);
+ java.util.List<String> q = singularizableTypes.toQualifieds(typeReference);
+ if (q.isEmpty()) return null;
+ return q.get(0);
}
public JavacSingularizer getSingularizer(String fqn, JavacNode node) {
diff --git a/src/delombok/lombok/delombok/Delombok.java b/src/delombok/lombok/delombok/Delombok.java
index 76b2715a..7318a8ce 100755
--- a/src/delombok/lombok/delombok/Delombok.java
+++ b/src/delombok/lombok/delombok/Delombok.java
@@ -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;
diff --git a/src/delombok/lombok/delombok/DelombokResult.java b/src/delombok/lombok/delombok/DelombokResult.java
index 8985b257..bc19c74d 100644
--- a/src/delombok/lombok/delombok/DelombokResult.java
+++ b/src/delombok/lombok/delombok/DelombokResult.java
@@ -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 {
diff --git a/src/delombok/lombok/delombok/PrettyPrinter.java b/src/delombok/lombok/delombok/PrettyPrinter.java
index 1532319f..fc5eaec2 100644
--- a/src/delombok/lombok/delombok/PrettyPrinter.java
+++ b/src/delombok/lombok/delombok/PrettyPrinter.java
@@ -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;
@@ -488,6 +491,19 @@ public class PrettyPrinter extends JCTree.Visitor {
}
@Override public void visitImport(JCImport tree) {
+ if (tree.qualid instanceof JCFieldAccess) {
+ JCFieldAccess fa = ((JCFieldAccess) tree.qualid);
+ if (fa.name.length() == 1 && fa.name.contentEquals("*")) {
+ if (fa.selected instanceof JCFieldAccess) {
+ JCFieldAccess lombokExperimental = (JCFieldAccess) fa.selected;
+ if (lombokExperimental.name.contentEquals("experimental") && lombokExperimental.selected instanceof JCIdent && ((JCIdent) lombokExperimental.selected).name.contentEquals("lombok")) {
+ // do not ever print lombok.experimental.*.
+ return;
+ }
+ }
+ }
+ }
+
aPrint("import ");
if (tree.staticImport) print("static ");
print(tree.qualid);
@@ -727,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) {
@@ -1266,6 +1312,11 @@ public class PrettyPrinter extends JCTree.Visitor {
print(";");
needsNewLine = true;
needsAlign = true;
+ } else if (tree.stats.head.getClass().getSimpleName().equals("JCYield")) {
+ print((JCExpression) readObject(tree.stats.head, "value", null));
+ print(";");
+ needsNewLine = true;
+ needsAlign = true;
} else {
print(tree.stats.head);
if (tree.stats.head instanceof JCBlock) needsNewLine = false;
@@ -1295,7 +1346,10 @@ public class PrettyPrinter extends JCTree.Visitor {
print(")");
}
println(" {");
+ boolean ruleStyle = isCaseRuleStyle(tree.cases.head);
+ if (ruleStyle) indent++;
print(tree.cases, "");
+ if (ruleStyle) indent--;
aPrintln("}", tree);
}
@@ -1311,10 +1365,20 @@ public class PrettyPrinter extends JCTree.Visitor {
}
println(" {");
List<JCCase> cases = readObject(tree, "cases", null);
+ boolean ruleStyle = isCaseRuleStyle(cases.head);
+ if (ruleStyle) indent++;
print(cases, "");
+ if (ruleStyle) indent--;
aPrint("}");
}
+ void printYieldExpression(JCTree tree) {
+ aPrint("yield ");
+ JCExpression value = readObject(tree, "value", null);
+ print(value);
+ println(";", tree);
+ }
+
@Override public void visitTry(JCTry tree) {
aPrint("try ");
List<?> resources = readObject(tree, "resources", List.nil());
@@ -1535,11 +1599,19 @@ public class PrettyPrinter extends JCTree.Visitor {
// Starting with JDK9, this is inside the import list, but we've already printed it. Just ignore it.
} else if ("JCSwitchExpression".equals(simpleName)) { // Introduced as preview feature in JDK12
printSwitchExpression(tree);
+ } else if ("JCYield".equals(simpleName)) { // Introduced as preview feature in JDK13, part of switch expressions.
+ printYieldExpression(tree);
} else {
throw new AssertionError("Unhandled tree type: " + tree.getClass() + ": " + tree);
}
}
+ private boolean isCaseRuleStyle(JCCase tree) {
+ if (tree == null) return false;
+ Enum<?> caseKind = readObject(tree, "caseKind", null); // JDK 12+
+ return caseKind != null && caseKind.name().equalsIgnoreCase("RULE");
+ }
+
private boolean jcAnnotatedTypeInit = false;
private Class<?> jcAnnotatedTypeClass = null;
diff --git a/src/eclipseAgent/lombok/eclipse/agent/PatchVal.java b/src/eclipseAgent/lombok/eclipse/agent/PatchVal.java
index 5c31e87a..056852c8 100644
--- a/src/eclipseAgent/lombok/eclipse/agent/PatchVal.java
+++ b/src/eclipseAgent/lombok/eclipse/agent/PatchVal.java
@@ -24,7 +24,6 @@ package lombok.eclipse.agent;
import lombok.permit.Permit;
import org.eclipse.jdt.core.compiler.CategorizedProblem;
import org.eclipse.jdt.internal.compiler.CompilationResult;
-import org.eclipse.jdt.internal.compiler.DefaultErrorHandlingPolicies;
import org.eclipse.jdt.internal.compiler.ast.ASTNode;
import org.eclipse.jdt.internal.compiler.ast.AbstractMethodDeclaration;
import org.eclipse.jdt.internal.compiler.ast.Annotation;
@@ -54,7 +53,6 @@ import org.eclipse.jdt.internal.compiler.lookup.TypeBinding;
import org.eclipse.jdt.internal.compiler.lookup.TypeConstants;
import org.eclipse.jdt.internal.compiler.lookup.TypeIds;
import org.eclipse.jdt.internal.compiler.problem.AbortCompilation;
-import org.eclipse.jdt.internal.compiler.problem.ProblemReporter;
import java.lang.reflect.Field;
@@ -455,7 +453,7 @@ public class PatchVal {
}
}
- private static Field getField(Class clazz, String name) {
+ private static Field getField(Class<?> clazz, String name) {
try {
return Permit.getField(clazz, name);
} catch (NoSuchFieldException e) {
diff --git a/src/installer/lombok/installer/eclipse/EclipseProductLocation.java b/src/installer/lombok/installer/eclipse/EclipseProductLocation.java
index aa97a3e5..73f98a35 100644
--- a/src/installer/lombok/installer/eclipse/EclipseProductLocation.java
+++ b/src/installer/lombok/installer/eclipse/EclipseProductLocation.java
@@ -294,10 +294,12 @@ public final class EclipseProductLocation extends IdeLocation {
try {
lombokJar.delete();
} catch (Throwable ignore) { /* Nothing we can do about that. */ }
- if (!readSucceeded) throw new InstallException(
- "I can't read my own jar file. I think you've found a bug in this installer!\nI suggest you restart it " +
+ if (!readSucceeded) {
+ throw new InstallException(
+ "I can't read my own jar file (trying: " + ourJar.toString() + "). I think you've found a bug in this installer!\nI suggest you restart it " +
"and use the 'what do I do' link, to manually install lombok. Also, tell us about this at:\n" +
- "http://groups.google.com/group/project-lombok - Thanks!", e);
+ "http://groups.google.com/group/project-lombok - Thanks!\n\n[DEBUG INFO] " + e.getClass() + ": " + e.getMessage() + "\nBase: " + OsUtils.class.getResource("OsUtils.class"), e);
+ }
throw new InstallException("I can't write to your " + descriptor.getProductName() + " directory at " + name + generateWriteErrorMessage(), e);
}
}
diff --git a/src/stubs/com/sun/tools/javac/parser/Tokens.java b/src/stubs/com/sun/tools/javac/parser/Tokens.java
index 6e0aa479..f86bcefa 100644
--- a/src/stubs/com/sun/tools/javac/parser/Tokens.java
+++ b/src/stubs/com/sun/tools/javac/parser/Tokens.java
@@ -2,7 +2,7 @@ package com.sun.tools.javac.parser;
public class Tokens {
public static class Token {
-
+ public int pos;
}
public interface Comment {
diff --git a/src/utils/lombok/javac/CommentCatcher.java b/src/utils/lombok/javac/CommentCatcher.java
index f8b73b0a..90266c26 100644
--- a/src/utils/lombok/javac/CommentCatcher.java
+++ b/src/utils/lombok/javac/CommentCatcher.java
@@ -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) {
diff --git a/src/utils/lombok/javac/java8/CommentCollectingParser.java b/src/utils/lombok/javac/java8/CommentCollectingParser.java
index b49312cb..c1dc2f7e 100644
--- a/src/utils/lombok/javac/java8/CommentCollectingParser.java
+++ b/src/utils/lombok/javac/java8/CommentCollectingParser.java
@@ -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;
}
diff --git a/src/utils/lombok/javac/java8/CommentCollectingScanner.java b/src/utils/lombok/javac/java8/CommentCollectingScanner.java
index b59a9390..5a0647cc 100644
--- a/src/utils/lombok/javac/java8/CommentCollectingScanner.java
+++ b/src/utils/lombok/javac/java8/CommentCollectingScanner.java
@@ -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();
+ }
} \ No newline at end of file
diff --git a/src/utils/lombok/javac/java8/CommentCollectingScannerFactory.java b/src/utils/lombok/javac/java8/CommentCollectingScannerFactory.java
index fa79ff67..cb0d2e12 100644
--- a/src/utils/lombok/javac/java8/CommentCollectingScannerFactory.java
+++ b/src/utils/lombok/javac/java8/CommentCollectingScannerFactory.java
@@ -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));
}
}
diff --git a/src/utils/lombok/javac/java8/CommentCollectingTokenizer.java b/src/utils/lombok/javac/java8/CommentCollectingTokenizer.java
index 1834fb00..08477e61 100644
--- a/src/utils/lombok/javac/java8/CommentCollectingTokenizer.java
+++ b/src/utils/lombok/javac/java8/CommentCollectingTokenizer.java
@@ -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);
diff --git a/src/utils/lombok/javac/java9/CommentCollectingParser.java b/src/utils/lombok/javac/java9/CommentCollectingParser.java
index 307be405..034b6705 100644
--- a/src/utils/lombok/javac/java9/CommentCollectingParser.java
+++ b/src/utils/lombok/javac/java9/CommentCollectingParser.java
@@ -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;
}