mirror of
https://github.com/tiennm99/lombok.git
synced 2026-10-11 12:19:00 +00:00
[#1033] steps on the way to issue 1033: You can add cleanup tasks which are deferred (during the javac run) until the end.
This already fixes the exotic-to-the-point-of-nonexistent bug where setter and wither compete to steal the `@param` off of the field’s javadoc. Next are to fix builder and setter/wither competing whilst bringing javadocs to `@Builder`. Then for various other conflicts, we should defer removal of lombok imports and annotations until the end too.
This commit is contained in:
1 parent
20df86149d
commit
ccfab5ebff
11 files changed
+311
-114
No files matched your search
@@ -3,6 +3,7 @@ Lombok Changelog
|
||||
|
||||
### v1.18.5 "Edgy Guinea Pig"
|
||||
* BUGFIX: Since version 1.18.4, the delombok ant task didn't work and errored with a `NoClassDefFoundError`. [Issue #1932](https://github.com/rzwitserloot/lombok/issues/1932)
|
||||
* BUGFIX: Combining both `@Setter` and `@Wither` on the same field, when that field also has javadoc with a `--setter--` section or an `@param` tag, resulted in a race condition where the first handler to get to the field would take that part of the javadoc. This is a step along the way to fixing [Issue #1033](https://github.com/rzwitserloot/lombok/issues/1033)
|
||||
* FEATURE: The `@FieldNameConstants` feature now allows you to write the inner type by hand and add whatever you like to it; lombok will add the constants to this class. See the updated [FieldNameConstants feature](https://projectlombok.org/features/experimental/FieldNameConstants) page.
|
||||
* FEATURE: There is now a `lombok.config` key to configure `@ToString`'s call super behavior; it's just like `@EqualsAndHashCode` which has had it for a while now. [Issue #1918](https://github.com/rzwitserloot/lombok/issues/1918)
|
||||
* ENHANCEMENT: The toString generation of enums now contains the name of the enum constant. [Issue #1916](https://github.com/rzwitserloot/lombok/issues/1916)
|
||||
|
||||
@@ -0,0 +1,64 @@
|
||||
/*
|
||||
* Copyright (C) 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
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
* THE SOFTWARE.
|
||||
*/
|
||||
package lombok.core;
|
||||
|
||||
import java.util.Map;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
|
||||
public class CleanupRegistry {
|
||||
private static final class CleanupKey {
|
||||
private final String key;
|
||||
private final Object target;
|
||||
|
||||
CleanupKey(String key, Object target) {
|
||||
this.key = key;
|
||||
this.target = target;
|
||||
}
|
||||
|
||||
@Override public boolean equals(Object other) {
|
||||
if (other == null) return false;
|
||||
if (other == this) return true;
|
||||
if (!(other instanceof CleanupKey)) return false;
|
||||
CleanupKey o = (CleanupKey) other;
|
||||
if (!key.equals(o.key)) return false;
|
||||
return target == o.target;
|
||||
}
|
||||
|
||||
@Override public int hashCode() {
|
||||
return 109 * System.identityHashCode(target) + key.hashCode();
|
||||
}
|
||||
}
|
||||
|
||||
private final Map<CleanupKey, CleanupTask> tasks = new ConcurrentHashMap<CleanupKey, CleanupTask>();
|
||||
|
||||
public void registerTask(String key, Object target, CleanupTask task) {
|
||||
CleanupKey ck = new CleanupKey(key, target);
|
||||
tasks.putIfAbsent(ck, task);
|
||||
}
|
||||
|
||||
public void run() {
|
||||
for (CleanupTask task : tasks.values()) {
|
||||
task.cleanup();
|
||||
}
|
||||
tasks.clear();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,26 @@
|
||||
/*
|
||||
* Copyright (C) 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
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
* THE SOFTWARE.
|
||||
*/
|
||||
package lombok.core;
|
||||
|
||||
public interface CleanupTask {
|
||||
void cleanup();
|
||||
}
|
||||
@@ -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
|
||||
@@ -37,6 +37,8 @@ import javax.tools.JavaFileObject;
|
||||
|
||||
import com.sun.tools.javac.util.JCDiagnostic;
|
||||
import lombok.core.AST;
|
||||
import lombok.core.CleanupRegistry;
|
||||
import lombok.core.CleanupTask;
|
||||
import lombok.permit.Permit;
|
||||
|
||||
import com.sun.tools.javac.code.Source;
|
||||
@@ -65,6 +67,7 @@ import com.sun.tools.javac.util.Name;
|
||||
* something javac's own AST system does not offer.
|
||||
*/
|
||||
public class JavacAST extends AST<JavacAST, JavacNode, JCTree> {
|
||||
private final CleanupRegistry cleanup;
|
||||
private final JavacElements elements;
|
||||
private final JavacTreeMaker treeMaker;
|
||||
private final Symtab symtab;
|
||||
@@ -80,7 +83,7 @@ public class JavacAST extends AST<JavacAST, JavacNode, JCTree> {
|
||||
* @param context A Context object for interfacing with the compiler.
|
||||
* @param top The compilation unit, which serves as the top level node in the tree to be built.
|
||||
*/
|
||||
public JavacAST(Messager messager, Context context, JCCompilationUnit top) {
|
||||
public JavacAST(Messager messager, Context context, JCCompilationUnit top, CleanupRegistry cleanup) {
|
||||
super(sourceName(top), PackageName.getPackageName(top), new JavacImportList(top), statementTypes());
|
||||
setTop(buildCompilationUnit(top));
|
||||
this.context = context;
|
||||
@@ -90,6 +93,7 @@ public class JavacAST extends AST<JavacAST, JavacNode, JCTree> {
|
||||
this.treeMaker = new JavacTreeMaker(TreeMaker.instance(context));
|
||||
this.symtab = Symtab.instance(context);
|
||||
this.javacTypes = JavacTypes.instance(context);
|
||||
this.cleanup = cleanup;
|
||||
clearChanged();
|
||||
}
|
||||
|
||||
@@ -140,6 +144,10 @@ public class JavacAST extends AST<JavacAST, JavacNode, JCTree> {
|
||||
return Javac.getJavaCompilerVersion();
|
||||
}
|
||||
|
||||
public void cleanupTask(String key, JCTree target, CleanupTask task) {
|
||||
cleanup.registerTask(key, target, task);
|
||||
}
|
||||
|
||||
/** @return A Name object generated for the proper name table belonging to this AST. */
|
||||
public Name toName(String name) {
|
||||
return elements.getName(name);
|
||||
|
||||
@@ -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
|
||||
@@ -36,6 +36,7 @@ import com.sun.tools.javac.util.Context;
|
||||
import com.sun.tools.javac.util.List;
|
||||
|
||||
import lombok.ConfigurationKeys;
|
||||
import lombok.core.CleanupRegistry;
|
||||
import lombok.core.LombokConfiguration;
|
||||
|
||||
public class JavacTransformer {
|
||||
@@ -55,7 +56,7 @@ public class JavacTransformer {
|
||||
return handlers.getPrioritiesRequiringResolutionReset();
|
||||
}
|
||||
|
||||
public void transform(long priority, Context context, java.util.List<JCCompilationUnit> compilationUnitsRaw) {
|
||||
public void transform(long priority, Context context, java.util.List<JCCompilationUnit> compilationUnitsRaw, CleanupRegistry cleanup) {
|
||||
List<JCCompilationUnit> compilationUnits;
|
||||
if (compilationUnitsRaw instanceof List<?>) {
|
||||
compilationUnits = (List<JCCompilationUnit>) compilationUnitsRaw;
|
||||
@@ -70,7 +71,7 @@ public class JavacTransformer {
|
||||
|
||||
for (JCCompilationUnit unit : compilationUnits) {
|
||||
if (!Boolean.TRUE.equals(LombokConfiguration.read(ConfigurationKeys.LOMBOK_DISABLE, JavacAST.getAbsoluteFileLocation(unit)))) {
|
||||
asts.add(new JavacAST(messager, context, unit));
|
||||
asts.add(new JavacAST(messager, context, unit, cleanup));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -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
|
||||
@@ -50,6 +50,7 @@ import javax.tools.JavaFileManager;
|
||||
import javax.tools.JavaFileObject;
|
||||
|
||||
import lombok.Lombok;
|
||||
import lombok.core.CleanupRegistry;
|
||||
import lombok.core.DiagnosticsReceiver;
|
||||
import lombok.javac.JavacTransformer;
|
||||
import lombok.permit.Permit;
|
||||
@@ -288,11 +289,15 @@ public class LombokProcessor extends AbstractProcessor {
|
||||
private final IdentityHashMap<JCCompilationUnit, Long> roots = new IdentityHashMap<JCCompilationUnit, Long>();
|
||||
private long[] priorityLevels;
|
||||
private Set<Long> priorityLevelsRequiringResolutionReset;
|
||||
private CleanupRegistry cleanup = new CleanupRegistry();
|
||||
|
||||
/** {@inheritDoc} */
|
||||
@Override public boolean process(Set<? extends TypeElement> annotations, RoundEnvironment roundEnv) {
|
||||
if (lombokDisabled) return false;
|
||||
if (roundEnv.processingOver()) return false;
|
||||
if (roundEnv.processingOver()) {
|
||||
cleanup.run();
|
||||
return false;
|
||||
}
|
||||
|
||||
// We have: A sorted set of all priority levels: 'priorityLevels'
|
||||
|
||||
@@ -318,7 +323,7 @@ public class LombokProcessor extends AbstractProcessor {
|
||||
if (prioOfCu == null || prioOfCu != prio) continue;
|
||||
cusForThisRound.add(entry.getKey());
|
||||
}
|
||||
transformer.transform(prio, javacProcessingEnv.getContext(), cusForThisRound);
|
||||
transformer.transform(prio, javacProcessingEnv.getContext(), cusForThisRound, cleanup);
|
||||
}
|
||||
|
||||
// Step 3: Push up all CUs to the next level. Set level to null if there is no next level.
|
||||
|
||||
@@ -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
|
||||
@@ -48,6 +48,7 @@ import lombok.core.AST.Kind;
|
||||
import lombok.core.AnnotationValues;
|
||||
import lombok.core.LombokImmutableList;
|
||||
import lombok.core.AnnotationValues.AnnotationValue;
|
||||
import lombok.core.CleanupTask;
|
||||
import lombok.core.TypeResolver;
|
||||
import lombok.core.configuration.NullCheckExceptionType;
|
||||
import lombok.core.configuration.TypeName;
|
||||
@@ -70,8 +71,6 @@ import com.sun.tools.javac.code.Symbol.ClassSymbol;
|
||||
import com.sun.tools.javac.code.Symbol.MethodSymbol;
|
||||
import com.sun.tools.javac.code.Symbol.VarSymbol;
|
||||
import com.sun.tools.javac.code.Type.MethodType;
|
||||
import com.sun.tools.javac.parser.Tokens.Comment;
|
||||
import com.sun.tools.javac.tree.DocCommentTable;
|
||||
import com.sun.tools.javac.tree.JCTree;
|
||||
import com.sun.tools.javac.tree.JCTree.JCAnnotation;
|
||||
import com.sun.tools.javac.tree.JCTree.JCArrayTypeTree;
|
||||
@@ -277,7 +276,7 @@ public class JavacHandlerUtil {
|
||||
*/
|
||||
public static boolean annotationTypeMatches(String type, JavacNode node) {
|
||||
if (node.getKind() != Kind.ANNOTATION) return false;
|
||||
return typeMatches(type, node, ((JCAnnotation)node.get()).annotationType);
|
||||
return typeMatches(type, node, ((JCAnnotation) node.get()).annotationType);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -1165,7 +1164,7 @@ public class JavacHandlerUtil {
|
||||
JavacNode tossMe = typeNode.getNodeFor(def);
|
||||
if (tossMe != null) tossMe.up().removeChild(tossMe);
|
||||
type.defs = addAllButOne(type.defs, idx);
|
||||
ClassSymbolMembersField.remove(type.sym, ((JCMethodDecl)def).sym);
|
||||
ClassSymbolMembersField.remove(type.sym, ((JCMethodDecl) def).sym);
|
||||
break;
|
||||
}
|
||||
}
|
||||
@@ -1812,72 +1811,90 @@ public class JavacHandlerUtil {
|
||||
return javadoc.substring(0, m.start());
|
||||
}
|
||||
|
||||
public static String[] splitJavadocOnSectionIfPresent(String javadoc, String sectionName) {
|
||||
public static String getJavadocSection(String javadoc, String sectionName) {
|
||||
Matcher m = SECTION_FINDER.matcher(javadoc);
|
||||
int getterSectionHeaderStart = -1;
|
||||
int getterSectionStart = -1;
|
||||
int getterSectionEnd = -1;
|
||||
int sectionStart = -1;
|
||||
int sectionEnd = -1;
|
||||
while (m.find()) {
|
||||
if (m.group(1).equalsIgnoreCase(sectionName)) {
|
||||
getterSectionStart = m.end() + 1;
|
||||
getterSectionHeaderStart = m.start();
|
||||
} else if (getterSectionStart != -1) {
|
||||
getterSectionEnd = m.start();
|
||||
sectionStart = m.end() + 1;
|
||||
} else if (sectionStart != -1) {
|
||||
sectionEnd = m.start();
|
||||
}
|
||||
}
|
||||
|
||||
if (getterSectionStart != -1) {
|
||||
if (getterSectionEnd != -1) {
|
||||
return new String[] {javadoc.substring(getterSectionStart, getterSectionEnd), javadoc.substring(0, getterSectionHeaderStart) + javadoc.substring(getterSectionEnd)};
|
||||
} else {
|
||||
return new String[] {javadoc.substring(getterSectionStart), javadoc.substring(0, getterSectionHeaderStart)};
|
||||
}
|
||||
if (sectionStart != -1) {
|
||||
if (sectionEnd != -1) return javadoc.substring(sectionStart, sectionEnd);
|
||||
return javadoc.substring(sectionStart);
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
public static enum CopyJavadoc {
|
||||
VERBATIM,
|
||||
VERBATIM {
|
||||
@Override public String apply(final JCCompilationUnit cu, final JavacNode node) {
|
||||
return Javac.getDocComment(cu, node.get());
|
||||
}
|
||||
},
|
||||
GETTER {
|
||||
@Override public String[] split(String javadoc) {
|
||||
// step 1: Check if there is a 'GETTER' section. If yes, that becomes the new method's javadoc and we strip that from the original.
|
||||
String[] out = splitJavadocOnSectionIfPresent(javadoc, "GETTER");
|
||||
if (out != null) return out;
|
||||
// failing that, create a copy, but strip @return from the original and @param from the copy, as well as other sections.
|
||||
String copy = javadoc;
|
||||
javadoc = stripLinesWithTagFromJavadoc(javadoc, "@returns?\\s+.*");
|
||||
copy = stripLinesWithTagFromJavadoc(copy, "@param(?:eter)?\\s+.*");
|
||||
copy = stripSectionsFromJavadoc(copy);
|
||||
return new String[] {copy, javadoc};
|
||||
@Override public String apply(final JCCompilationUnit cu, final JavacNode node) {
|
||||
final JCTree n = node.get();
|
||||
String javadoc = Javac.getDocComment(cu, n);
|
||||
// step 1: Check if there is a 'GETTER' section. If yes, that becomes the new method's javadoc.
|
||||
String out = getJavadocSection(javadoc, "GETTER");
|
||||
final boolean sectionBased = out != null;
|
||||
if (!sectionBased) {
|
||||
out = stripLinesWithTagFromJavadoc(stripSectionsFromJavadoc(javadoc), "@param(?:eter)?\\s+.*");
|
||||
}
|
||||
node.getAst().cleanupTask("javadocfilter-getter", n, new CleanupTask() {
|
||||
@Override public void cleanup() {
|
||||
String javadoc = Javac.getDocComment(cu, n);
|
||||
if (javadoc == null || javadoc.isEmpty()) return;
|
||||
javadoc = stripSectionsFromJavadoc(javadoc);
|
||||
if (!sectionBased) {
|
||||
javadoc = stripLinesWithTagFromJavadoc(stripSectionsFromJavadoc(javadoc), "@returns?\\s+.*");
|
||||
}
|
||||
Javac.setDocComment(cu, n, javadoc);
|
||||
}
|
||||
});
|
||||
return out;
|
||||
}
|
||||
},
|
||||
SETTER {
|
||||
@Override public String[] split(String javadoc) {
|
||||
return splitForSetters(javadoc, "SETTER");
|
||||
@Override public String apply(final JCCompilationUnit cu, final JavacNode node) {
|
||||
return applySetter(cu, node, "SETTER");
|
||||
}
|
||||
},
|
||||
WITHER {
|
||||
@Override public String[] split(String javadoc) {
|
||||
return splitForSetters(javadoc, "WITHER");
|
||||
@Override public String apply(final JCCompilationUnit cu, final JavacNode node) {
|
||||
return applySetter(cu, node, "WITHER");
|
||||
}
|
||||
};
|
||||
|
||||
private static String[] splitForSetters(String javadoc, String sectionName) {
|
||||
// step 1: Check if there is a 'SETTER' section. If yes, that becomes the new one and we strip that from the original.
|
||||
String[] out = splitJavadocOnSectionIfPresent(javadoc, sectionName);
|
||||
if (out != null) return out;
|
||||
// failing that, create a copy, but strip @param from the original and @return from the copy.
|
||||
String copy = javadoc;
|
||||
javadoc = stripLinesWithTagFromJavadoc(javadoc, "@param(?:eter)?\\s+.*");
|
||||
copy = stripLinesWithTagFromJavadoc(copy, "@returns?\\s+.*");
|
||||
copy = stripSectionsFromJavadoc(copy);
|
||||
return new String[] {copy, javadoc};
|
||||
}
|
||||
public abstract String apply(final JCCompilationUnit cu, final JavacNode node);
|
||||
|
||||
/** Splits the javadoc into the section to be copied (ret[0]) and the section to replace the original with (ret[1]) */
|
||||
public String[] split(String javadoc) {
|
||||
return new String[] {javadoc, javadoc};
|
||||
private static String applySetter(final JCCompilationUnit cu, JavacNode node, String sectionName) {
|
||||
final JCTree n = node.get();
|
||||
String javadoc = Javac.getDocComment(cu, n);
|
||||
// step 1: Check if there is a 'SETTER' section. If yes, that becomes the new method's javadoc.
|
||||
String out = getJavadocSection(javadoc, sectionName);
|
||||
final boolean sectionBased = out != null;
|
||||
if (!sectionBased) {
|
||||
out = stripLinesWithTagFromJavadoc(stripSectionsFromJavadoc(javadoc), "@returns?\\s+.*");
|
||||
}
|
||||
node.getAst().cleanupTask("javadocfilter-setter", n, new CleanupTask() {
|
||||
@Override public void cleanup() {
|
||||
String javadoc = Javac.getDocComment(cu, n);
|
||||
if (javadoc == null || javadoc.isEmpty()) return;
|
||||
javadoc = stripSectionsFromJavadoc(javadoc);
|
||||
if (!sectionBased) {
|
||||
javadoc = stripLinesWithTagFromJavadoc(stripSectionsFromJavadoc(javadoc), "@param(?:eter)?\\s+.*");
|
||||
}
|
||||
Javac.setDocComment(cu, n, javadoc);
|
||||
}
|
||||
});
|
||||
return shouldReturnThis(node) ? addReturnsThisIfNeeded(out) : out;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1894,12 +1911,8 @@ public class JavacHandlerUtil {
|
||||
if (copyMode == null) copyMode = CopyJavadoc.VERBATIM;
|
||||
try {
|
||||
JCCompilationUnit cu = ((JCCompilationUnit) from.top().get());
|
||||
Object dc = Javac.getDocComments(cu);
|
||||
if (dc instanceof Map) {
|
||||
copyJavadoc_jdk6_7(from, to, copyMode, dc);
|
||||
} else if (Javac.instanceOfDocCommentTable(dc)) {
|
||||
CopyJavadoc_8.copyJavadoc(from, to, copyMode, dc);
|
||||
}
|
||||
String newJavadoc = copyMode.apply(cu, from);
|
||||
if (newJavadoc != null) Javac.setDocComment(cu, to, newJavadoc);
|
||||
} catch (Exception ignore) {}
|
||||
}
|
||||
|
||||
@@ -1915,57 +1928,6 @@ public class JavacHandlerUtil {
|
||||
return in + "\n" + line;
|
||||
}
|
||||
|
||||
private static class CopyJavadoc_8 {
|
||||
static void copyJavadoc(JavacNode from, JCTree to, CopyJavadoc copyMode, Object dc) {
|
||||
DocCommentTable dct = (DocCommentTable) dc;
|
||||
Comment javadoc = dct.getComment(from.get());
|
||||
|
||||
if (javadoc != null) {
|
||||
String[] filtered = copyMode.split(javadoc.getText());
|
||||
if (copyMode == CopyJavadoc.SETTER && shouldReturnThis(from)) {
|
||||
filtered[0] = addReturnsThisIfNeeded(filtered[0]);
|
||||
}
|
||||
dct.putComment(to, createJavadocComment(filtered[0], from));
|
||||
dct.putComment(from.get(), createJavadocComment(filtered[1], from));
|
||||
}
|
||||
}
|
||||
|
||||
private static Comment createJavadocComment(final String text, final JavacNode field) {
|
||||
return new Comment() {
|
||||
@Override public String getText() {
|
||||
return text;
|
||||
}
|
||||
|
||||
@Override public int getSourcePos(int index) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
@Override public CommentStyle getStyle() {
|
||||
return CommentStyle.JAVADOC;
|
||||
}
|
||||
|
||||
@Override public boolean isDeprecated() {
|
||||
return text.contains("@deprecated") && field.getKind() == Kind.FIELD && isFieldDeprecated(field);
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
@SuppressWarnings({"unchecked", "all"})
|
||||
private static void copyJavadoc_jdk6_7(JavacNode from, JCTree to, CopyJavadoc copyMode, Object dc) {
|
||||
Map<JCTree, String> docComments = (Map<JCTree, String>) dc;
|
||||
String javadoc = docComments.get(from.get());
|
||||
|
||||
if (javadoc != null) {
|
||||
String[] filtered = copyMode.split(javadoc);
|
||||
if (copyMode == CopyJavadoc.SETTER && shouldReturnThis(from)) {
|
||||
filtered[0] = addReturnsThisIfNeeded(filtered[0]);
|
||||
}
|
||||
docComments.put(to, filtered[0]);
|
||||
docComments.put(from.get(), filtered[1]);
|
||||
}
|
||||
}
|
||||
|
||||
public static boolean isDirectDescendantOfObject(JavacNode typeNode) {
|
||||
if (!(typeNode.get() instanceof JCClassDecl)) throw new IllegalArgumentException("not a type node");
|
||||
JCTree extending = Javac.getExtendsClause((JCClassDecl) typeNode.get());
|
||||
|
||||
@@ -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
|
||||
@@ -28,6 +28,7 @@ import java.lang.reflect.Field;
|
||||
import java.lang.reflect.InvocationTargetException;
|
||||
import java.lang.reflect.Method;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.concurrent.atomic.AtomicInteger;
|
||||
import java.util.regex.Matcher;
|
||||
import java.util.regex.Pattern;
|
||||
@@ -42,17 +43,22 @@ import lombok.javac.JavacTreeMaker.TreeTag;
|
||||
import lombok.javac.JavacTreeMaker.TypeTag;
|
||||
import lombok.permit.Permit;
|
||||
|
||||
import com.sun.tools.javac.code.Flags;
|
||||
import com.sun.tools.javac.code.Source;
|
||||
import com.sun.tools.javac.code.Symtab;
|
||||
import com.sun.tools.javac.code.Type;
|
||||
import com.sun.tools.javac.main.JavaCompiler;
|
||||
import com.sun.tools.javac.parser.Tokens.Comment;
|
||||
import com.sun.tools.javac.tree.DocCommentTable;
|
||||
import com.sun.tools.javac.tree.JCTree;
|
||||
import com.sun.tools.javac.tree.JCTree.JCAnnotation;
|
||||
import com.sun.tools.javac.tree.JCTree.JCClassDecl;
|
||||
import com.sun.tools.javac.tree.JCTree.JCCompilationUnit;
|
||||
import com.sun.tools.javac.tree.JCTree.JCExpression;
|
||||
import com.sun.tools.javac.tree.JCTree.JCFieldAccess;
|
||||
import com.sun.tools.javac.tree.JCTree.JCIdent;
|
||||
import com.sun.tools.javac.tree.JCTree.JCLiteral;
|
||||
import com.sun.tools.javac.tree.JCTree.JCVariableDecl;
|
||||
import com.sun.tools.javac.util.JCDiagnostic.DiagnosticPosition;
|
||||
|
||||
/**
|
||||
@@ -269,6 +275,73 @@ public class Javac {
|
||||
}
|
||||
}
|
||||
|
||||
public static String getDocComment(JCCompilationUnit cu, JCTree node) {
|
||||
Object dc = getDocComments(cu);
|
||||
if (dc instanceof Map) return (String) ((Map<?, ?>) dc).get(node);
|
||||
if (instanceOfDocCommentTable(dc)) return JavadocOps_8.getJavadoc(dc, node);
|
||||
return null;
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
public static void setDocComment(JCCompilationUnit cu, JCTree node, String javadoc) {
|
||||
Object dc = getDocComments(cu);
|
||||
if (dc instanceof Map) {
|
||||
((Map<JCTree, String>) dc).put(node, javadoc);
|
||||
return;
|
||||
}
|
||||
|
||||
if (instanceOfDocCommentTable(dc)) {
|
||||
JavadocOps_8.setJavadoc(dc, node, javadoc);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
private static class JavadocOps_8 {
|
||||
static String getJavadoc(Object dc, JCTree node) {
|
||||
DocCommentTable dct = (DocCommentTable) dc;
|
||||
Comment javadoc = dct.getComment(node);
|
||||
if (javadoc == null) return null;
|
||||
return javadoc.getText();
|
||||
}
|
||||
|
||||
static void setJavadoc(Object dc, JCTree node, String javadoc) {
|
||||
DocCommentTable dct = (DocCommentTable) dc;
|
||||
Comment newCmt = createJavadocComment(javadoc, node);
|
||||
dct.putComment(node, newCmt);
|
||||
}
|
||||
|
||||
private static Comment createJavadocComment(final String text, final JCTree field) {
|
||||
return new Comment() {
|
||||
@Override public String getText() {
|
||||
return text;
|
||||
}
|
||||
|
||||
@Override public int getSourcePos(int index) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
@Override public CommentStyle getStyle() {
|
||||
return CommentStyle.JAVADOC;
|
||||
}
|
||||
|
||||
@Override public boolean isDeprecated() {
|
||||
return text.contains("@deprecated") && field instanceof JCVariableDecl && isFieldDeprecated(field);
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
public static boolean isFieldDeprecated(JCTree field) {
|
||||
if (!(field instanceof JCVariableDecl)) return false;
|
||||
JCVariableDecl fieldNode = (JCVariableDecl) field;
|
||||
if ((fieldNode.mods.flags & Flags.DEPRECATED) != 0) return true;
|
||||
if (fieldNode.mods.annotations != null) for (JCAnnotation ann : fieldNode.mods.annotations) {
|
||||
String at = ann.getAnnotationType().toString();
|
||||
return at.equals("Deprecated") || at.endsWith(".Deprecated");
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public static void initDocComments(JCCompilationUnit cu) {
|
||||
try {
|
||||
JCCOMPILATIONUNIT_DOCCOMMENTS.set(cu, new HashMap<Object, String>());
|
||||
|
||||
@@ -0,0 +1,28 @@
|
||||
class SetterWitherJavadocParamCopy {
|
||||
/**
|
||||
* Some text
|
||||
*/
|
||||
private int fieldName;
|
||||
|
||||
public SetterWitherJavadocParamCopy(int f) {
|
||||
this.fieldName = f;
|
||||
}
|
||||
/**
|
||||
* Some text
|
||||
*
|
||||
* @param fieldName Hello, World1
|
||||
*/
|
||||
@java.lang.SuppressWarnings("all")
|
||||
public void setFieldName(final int fieldName) {
|
||||
this.fieldName = fieldName;
|
||||
}
|
||||
/**
|
||||
* Some text
|
||||
*
|
||||
* @param fieldName Hello, World1
|
||||
*/
|
||||
@java.lang.SuppressWarnings("all")
|
||||
public SetterWitherJavadocParamCopy withFieldName(final int fieldName) {
|
||||
return this.fieldName == fieldName ? this : new SetterWitherJavadocParamCopy(fieldName);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,13 @@
|
||||
class SetterWitherJavadocParamCopy {
|
||||
private @lombok.Setter @lombok.experimental.Wither int fieldName;
|
||||
public SetterWitherJavadocParamCopy(int f) {
|
||||
super();
|
||||
this.fieldName = f;
|
||||
}
|
||||
public @java.lang.SuppressWarnings("all") void setFieldName(final int fieldName) {
|
||||
this.fieldName = fieldName;
|
||||
}
|
||||
public @java.lang.SuppressWarnings("all") SetterWitherJavadocParamCopy withFieldName(final int fieldName) {
|
||||
return ((this.fieldName == fieldName) ? this : new SetterWitherJavadocParamCopy(fieldName));
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,16 @@
|
||||
class SetterWitherJavadocParamCopy {
|
||||
/**
|
||||
* Some text
|
||||
*
|
||||
* @param fieldName Hello, World1
|
||||
* --- GETTER ---
|
||||
* Getter section
|
||||
*
|
||||
* @return Sky is blue1
|
||||
*/
|
||||
@lombok.Setter @lombok.experimental.Wither private int fieldName;
|
||||
|
||||
public SetterWitherJavadocParamCopy(int f) {
|
||||
this.fieldName = f;
|
||||
}
|
||||
}
|
||||
Reference in new issue
Block a user