mirror of
https://github.com/tiennm99/lombok.git
synced 2026-10-14 02:16:18 +00:00
trying to manually add (parts of) the infrastructure for @Singular @Builder stuff is now flagged as an error.
This commit is contained in:
1 parent
519f95c241
commit
857da88e3e
8 files changed
+165
-24
No files matched your search
@@ -195,7 +195,7 @@ the common tasks and can be called on to run the main aspects of all the sub-scr
|
||||
</ivy:compile>
|
||||
<mkdir dir="build/lombok/META-INF" />
|
||||
<mkdir dir="build/lombok/META-INF/services" />
|
||||
<echo file="build/lombok/META-INF/services/javax.annotation.processing.Processor">lombok.launch.AnnotationProcessorHider.AnnotationProcessor</echo>
|
||||
<echo file="build/lombok/META-INF/services/javax.annotation.processing.Processor">lombok.launch.AnnotationProcessorHider$AnnotationProcessor</echo>
|
||||
</target>
|
||||
|
||||
<target name="dist" description="Builds THE lombok.jar file which contains everything." depends="version, compile">
|
||||
|
||||
@@ -7,7 +7,6 @@ Lombok Changelog
|
||||
* Builder __TODO TODO TODO TODO DO NOT SHIP YET__:
|
||||
|
||||
* features web page
|
||||
* warnings / errors when you attempt to handroll some / all of the methods/fields that @Singular would have generated. We are most likely not going to support it.
|
||||
* The 'I use guava' switch in l.config
|
||||
* Disable auto-singular in l.config
|
||||
* Review if there are nay potentially breaking changes in the pipeline for builder BEFORE moving it out of experimental.
|
||||
|
||||
@@ -1,9 +1,32 @@
|
||||
/*
|
||||
* Copyright (C) 2015 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.eclipse.handlers;
|
||||
|
||||
import static lombok.eclipse.handlers.EclipseHandlerUtil.*;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collections;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
@@ -36,27 +59,6 @@ import lombok.core.SpiLoadUtil;
|
||||
import lombok.core.TypeLibrary;
|
||||
import lombok.eclipse.EclipseNode;
|
||||
|
||||
/*
|
||||
* Copyright (C) 2015 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.
|
||||
*/
|
||||
public class EclipseSingularsRecipes {
|
||||
private static final EclipseSingularsRecipes INSTANCE = new EclipseSingularsRecipes();
|
||||
private final Map<String, EclipseSingularizer> singularizers = new HashMap<String, EclipseSingularizer>();
|
||||
@@ -164,7 +166,51 @@ public class EclipseSingularsRecipes {
|
||||
protected static final long[] NULL_POSS = {0L};
|
||||
public abstract LombokImmutableList<String> getSupportedTypes();
|
||||
|
||||
public abstract java.util.List<EclipseNode> generateFields(SingularData data, EclipseNode builderType);
|
||||
/** Checks if any of the to-be-generated nodes (fields, methods) already exist. If so, errors on these (singulars don't support manually writing some of it, and returns true). */
|
||||
public boolean checkForAlreadyExistingNodesAndGenerateError(EclipseNode builderType, SingularData data) {
|
||||
for (EclipseNode child : builderType.down()) {
|
||||
switch (child.getKind()) {
|
||||
case FIELD: {
|
||||
FieldDeclaration fd = (FieldDeclaration) child.get();
|
||||
char[] name = fd.name;
|
||||
if (name == null) continue;
|
||||
if (getGeneratedBy(fd) != null) continue;
|
||||
for (char[] fieldToBeGenerated : listFieldsToBeGenerated(data)) {
|
||||
if (!Arrays.equals(name, fieldToBeGenerated)) continue;
|
||||
child.addError("Manually adding a field that @Singular @Builder would generate is not supported. If you want to manually manage the builder aspect for this field/parameter, don't use @Singular.");
|
||||
return true;
|
||||
}
|
||||
break;
|
||||
}
|
||||
case METHOD: {
|
||||
AbstractMethodDeclaration method = (AbstractMethodDeclaration) child.get();
|
||||
char[] name = method.selector;
|
||||
if (name == null) continue;
|
||||
if (getGeneratedBy(method) != null) continue;
|
||||
for (char[] methodToBeGenerated : listMethodsToBeGenerated(data)) {
|
||||
if (!Arrays.equals(name, methodToBeGenerated)) continue;
|
||||
child.addError("Manually adding a method that @Singular @Builder would generate is not supported. If you want to manually manage the builder aspect for this field/parameter, don't use @Singular.");
|
||||
return true;
|
||||
}
|
||||
break;
|
||||
}}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
public List<char[]> listFieldsToBeGenerated(SingularData data) {
|
||||
return Collections.singletonList(data.pluralName);
|
||||
}
|
||||
|
||||
public List<char[]> listMethodsToBeGenerated(SingularData data) {
|
||||
char[] p = data.pluralName;
|
||||
char[] s = data.singularName;
|
||||
if (Arrays.equals(p, s)) return Collections.singletonList(p);
|
||||
return Arrays.asList(p, s);
|
||||
}
|
||||
|
||||
public abstract List<EclipseNode> generateFields(SingularData data, EclipseNode builderType);
|
||||
public abstract void generateMethods(SingularData data, EclipseNode builderType, boolean fluent, boolean chain);
|
||||
public abstract void appendBuildCode(SingularData data, EclipseNode builderType, List<Statement> statements, char[] targetVariableName);
|
||||
|
||||
|
||||
@@ -246,6 +246,17 @@ public class HandleBuilder extends EclipseAnnotationHandler<Builder> {
|
||||
builderType = makeBuilderClass(tdParent, builderClassName, typeParams, ast);
|
||||
} else {
|
||||
sanityCheckForMethodGeneratingAnnotationsOnBuilderClass(builderType, annotationNode);
|
||||
/* generate errors for @Singular BFDs that have one already defined node. */ {
|
||||
for (BuilderFieldData bfd : builderFields) {
|
||||
SingularData sd = bfd.singularData;
|
||||
if (sd == null) continue;
|
||||
EclipseSingularizer singularizer = sd.getSingularizer();
|
||||
if (singularizer == null) continue;
|
||||
if (singularizer.checkForAlreadyExistingNodesAndGenerateError(builderType, sd)) {
|
||||
bfd.singularData = null;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for (BuilderFieldData bfd : builderFields) {
|
||||
|
||||
@@ -61,6 +61,26 @@ public class EclipseJavaUtilMapSingularizer extends EclipseJavaUtilSingularizer
|
||||
return LombokImmutableList.of("java.util.Map", "java.util.SortedMap", "java.util.NavigableMap");
|
||||
}
|
||||
|
||||
@Override public List<char[]> listFieldsToBeGenerated(SingularData data) {
|
||||
char[] p = data.getPluralName();
|
||||
int len = p.length;
|
||||
char[] k = new char[len + 4];
|
||||
char[] v = new char[len + 6];
|
||||
System.arraycopy(p, 0, k, 0, len);
|
||||
System.arraycopy(p, 0, v, 0, len);
|
||||
k[len] = '$';
|
||||
k[len + 1] = 'k';
|
||||
k[len + 2] = 'e';
|
||||
k[len + 3] = 'y';
|
||||
v[len] = '$';
|
||||
v[len + 1] = 'v';
|
||||
v[len + 2] = 'a';
|
||||
v[len + 3] = 'l';
|
||||
v[len + 4] = 'u';
|
||||
v[len + 5] = 'e';
|
||||
return Arrays.asList(k, v);
|
||||
}
|
||||
|
||||
@Override public java.util.List<EclipseNode> generateFields(SingularData data, EclipseNode builderType) {
|
||||
char[] keyName = (new String(data.getPluralName()) + "$key").toCharArray();
|
||||
char[] valueName = (new String(data.getPluralName()) + "$value").toCharArray();
|
||||
|
||||
@@ -227,6 +227,18 @@ public class HandleBuilder extends JavacAnnotationHandler<Builder> {
|
||||
builderType = makeBuilderClass(tdParent, builderClassName, typeParams, ast);
|
||||
} else {
|
||||
sanityCheckForMethodGeneratingAnnotationsOnBuilderClass(builderType, annotationNode);
|
||||
/* generate errors for @Singular BFDs that have one already defined node. */ {
|
||||
for (BuilderFieldData bfd : builderFields) {
|
||||
SingularData sd = bfd.singularData;
|
||||
if (sd == null) continue;
|
||||
JavacSingularizer singularizer = sd.getSingularizer();
|
||||
if (singularizer == null) continue;
|
||||
if (singularizer.checkForAlreadyExistingNodesAndGenerateError(builderType, sd)) {
|
||||
bfd.singularData = null;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
for (BuilderFieldData bfd : builderFields) {
|
||||
|
||||
@@ -25,6 +25,8 @@ import static lombok.javac.Javac.*;
|
||||
import static lombok.javac.handlers.JavacHandlerUtil.*;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collections;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
@@ -38,7 +40,9 @@ import com.sun.source.tree.Tree.Kind;
|
||||
import com.sun.tools.javac.code.BoundKind;
|
||||
import com.sun.tools.javac.tree.JCTree;
|
||||
import com.sun.tools.javac.tree.JCTree.JCExpression;
|
||||
import com.sun.tools.javac.tree.JCTree.JCMethodDecl;
|
||||
import com.sun.tools.javac.tree.JCTree.JCStatement;
|
||||
import com.sun.tools.javac.tree.JCTree.JCVariableDecl;
|
||||
import com.sun.tools.javac.tree.JCTree.JCWildcard;
|
||||
import com.sun.tools.javac.util.Context;
|
||||
import com.sun.tools.javac.util.List;
|
||||
@@ -137,6 +141,50 @@ public class JavacSingularsRecipes {
|
||||
public static abstract class JavacSingularizer {
|
||||
public abstract LombokImmutableList<String> getSupportedTypes();
|
||||
|
||||
/** Checks if any of the to-be-generated nodes (fields, methods) already exist. If so, errors on these (singulars don't support manually writing some of it, and returns true). */
|
||||
public boolean checkForAlreadyExistingNodesAndGenerateError(JavacNode builderType, SingularData data) {
|
||||
for (JavacNode child : builderType.down()) {
|
||||
switch (child.getKind()) {
|
||||
case FIELD: {
|
||||
JCVariableDecl field = (JCVariableDecl) child.get();
|
||||
Name name = field.name;
|
||||
if (name == null) break;
|
||||
if (getGeneratedBy(field) != null) continue;
|
||||
for (Name fieldToBeGenerated : listFieldsToBeGenerated(builderType, data)) {
|
||||
if (!fieldToBeGenerated.equals(name)) continue;
|
||||
child.addError("Manually adding a field that @Singular @Builder would generate is not supported. If you want to manually manage the builder aspect for this field/parameter, don't use @Singular.");
|
||||
return true;
|
||||
}
|
||||
break;
|
||||
}
|
||||
case METHOD: {
|
||||
JCMethodDecl method = (JCMethodDecl) child.get();
|
||||
Name name = method.name;
|
||||
if (name == null) break;
|
||||
if (getGeneratedBy(method) != null) continue;
|
||||
for (Name methodToBeGenerated : listMethodsToBeGenerated(builderType, data)) {
|
||||
if (!methodToBeGenerated.equals(name)) continue;
|
||||
child.addError("Manually adding a method that @Singular @Builder would generate is not supported. If you want to manually manage the builder aspect for this field/parameter, don't use @Singular.");
|
||||
return true;
|
||||
}
|
||||
break;
|
||||
}}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
public java.util.List<Name> listFieldsToBeGenerated(JavacNode builderType, SingularData data) {
|
||||
return Collections.singletonList(data.pluralName);
|
||||
}
|
||||
|
||||
public java.util.List<Name> listMethodsToBeGenerated(JavacNode builderType, SingularData data) {
|
||||
Name p = data.pluralName;
|
||||
Name s = data.singularName;
|
||||
if (p.equals(s)) return Collections.singletonList(p);
|
||||
return Arrays.asList(p, s);
|
||||
}
|
||||
|
||||
public abstract java.util.List<JavacNode> generateFields(SingularData data, JavacNode builderType, JCTree source);
|
||||
public abstract void generateMethods(SingularData data, JavacNode builderType, JCTree source, boolean fluent, boolean chain);
|
||||
public abstract void appendBuildCode(SingularData data, JavacNode builderType, JCTree source, ListBuffer<JCStatement> statements, Name targetVariableName);
|
||||
|
||||
@@ -55,6 +55,11 @@ public class JavacJavaUtilMapSingularizer extends JavacJavaUtilSingularizer {
|
||||
return LombokImmutableList.of("java.util.Map", "java.util.SortedMap", "java.util.NavigableMap");
|
||||
}
|
||||
|
||||
@Override public java.util.List<Name> listFieldsToBeGenerated(JavacNode builderType, SingularData data) {
|
||||
String p = data.getPluralName().toString();
|
||||
return Arrays.asList(builderType.toName(p + "$key"), builderType.toName(p + "$value"));
|
||||
}
|
||||
|
||||
@Override public java.util.List<JavacNode> generateFields(SingularData data, JavacNode builderType, JCTree source) {
|
||||
JavacTreeMaker maker = builderType.getTreeMaker();
|
||||
|
||||
|
||||
Reference in new issue
Block a user