aboutsummaryrefslogtreecommitdiff
path: root/src/core/lombok
diff options
context:
space:
mode:
Diffstat (limited to 'src/core/lombok')
-rw-r--r--src/core/lombok/eclipse/handlers/EclipseHandlerUtil.java151
-rwxr-xr-xsrc/core/lombok/eclipse/handlers/HandleBuilder.java43
-rwxr-xr-xsrc/core/lombok/eclipse/handlers/HandleConstructor.java2
-rwxr-xr-xsrc/core/lombok/eclipse/handlers/HandleSuperBuilder.java61
-rw-r--r--src/core/lombok/javac/handlers/HandleBuilder.java59
-rw-r--r--src/core/lombok/javac/handlers/HandleSuperBuilder.java49
-rw-r--r--src/core/lombok/javac/handlers/JavacHandlerUtil.java37
7 files changed, 282 insertions, 120 deletions
diff --git a/src/core/lombok/eclipse/handlers/EclipseHandlerUtil.java b/src/core/lombok/eclipse/handlers/EclipseHandlerUtil.java
index 0955dba6..1c988d31 100644
--- a/src/core/lombok/eclipse/handlers/EclipseHandlerUtil.java
+++ b/src/core/lombok/eclipse/handlers/EclipseHandlerUtil.java
@@ -505,7 +505,13 @@ public class EclipseHandlerUtil {
} catch (Exception ignore) {}
}
- public static TypeReference namePlusTypeParamsToTypeReference(char[] typeName, TypeParameter[] params, long p) {
+ public static TypeReference namePlusTypeParamsToTypeReference(EclipseNode type, TypeParameter[] params, long p) {
+ TypeDeclaration td = (TypeDeclaration) type.get();
+ boolean instance = (td.modifiers & ClassFileConstants.AccStatic) == 0;
+ return namePlusTypeParamsToTypeReference(type.up(), td.name, instance, params, p);
+ }
+
+ public static TypeReference namePlusTypeParamsToTypeReference(EclipseNode parentType, char[] typeName, boolean instance, TypeParameter[] params, long p) {
if (params != null && params.length > 0) {
TypeReference[] refs = new TypeReference[params.length];
int idx = 0;
@@ -513,10 +519,10 @@ public class EclipseHandlerUtil {
TypeReference typeRef = new SingleTypeReference(param.name, p);
refs[idx++] = typeRef;
}
- return new ParameterizedSingleTypeReference(typeName, refs, 0, p);
+ return generateParameterizedTypeReference(parentType, typeName, instance, refs, p);
}
- return new SingleTypeReference(typeName, p);
+ return generateTypeReference(parentType, typeName, instance, p);
}
public static TypeReference[] copyTypes(TypeReference[] refs) {
@@ -851,15 +857,150 @@ public class EclipseHandlerUtil {
if (source != null) setGeneratedBy(typeRef, source);
refs[idx++] = typeRef;
}
- result = new ParameterizedSingleTypeReference(typeDecl.name, refs, 0, p);
+ result = generateParameterizedTypeReference(type, refs, p);
} else {
- result = new SingleTypeReference(((TypeDeclaration)type.get()).name, p);
+ result = generateTypeReference(type, p);
}
}
if (result != null && source != null) setGeneratedBy(result, source);
return result;
}
+ public static TypeReference generateParameterizedTypeReference(EclipseNode type, TypeReference[] typeParams, long p) {
+ TypeDeclaration td = (TypeDeclaration) type.get();
+ char[][] tn = getQualifiedInnerName(type.up(), td.name);
+ if (tn.length == 1) return new ParameterizedSingleTypeReference(tn[0], typeParams, 0, p);
+ int tnLen = tn.length;
+ long[] ps = new long[tnLen];
+ for (int i = 0; i < tnLen; i++) ps[i] = p;
+ TypeReference[][] rr = new TypeReference[tnLen][];
+ rr[tnLen - 1] = typeParams;
+ boolean instance = (td.modifiers & ClassFileConstants.AccStatic) == 0;
+ if (instance) fillOuterTypeParams(rr, tnLen - 2, type.up(), p);
+ return new ParameterizedQualifiedTypeReference(tn, rr, 0, ps);
+ }
+
+ public static TypeReference generateParameterizedTypeReference(EclipseNode parent, char[] name, boolean instance, TypeReference[] typeParams, long p) {
+ char[][] tn = getQualifiedInnerName(parent, name);
+ if (tn.length == 1) return new ParameterizedSingleTypeReference(tn[0], typeParams, 0, p);
+ int tnLen = tn.length;
+ long[] ps = new long[tnLen];
+ for (int i = 0; i < tnLen; i++) ps[i] = p;
+ TypeReference[][] rr = new TypeReference[tnLen][];
+ rr[tnLen - 1] = typeParams;
+ if (instance) fillOuterTypeParams(rr, tnLen - 2, parent, p);
+ return new ParameterizedQualifiedTypeReference(tn, rr, 0, ps);
+ }
+
+ /**
+ * This class will add type params to fully qualified chain of type references for inner types, such as {@code GrandParent.Parent.Child}; this is needed only as long as the chain does not involve static.
+ *
+ * @return {@code true} if at least one parameterization is actually added, {@code false} otherwise.
+ */
+ private static boolean fillOuterTypeParams(TypeReference[][] rr, int idx, EclipseNode node, long p) {
+ if (idx < 0 || node == null || !(node.get() instanceof TypeDeclaration)) return false;
+ boolean filled = false;
+ TypeDeclaration td = (TypeDeclaration) node.get();
+ TypeParameter[] tps = td.typeParameters;
+ if (tps != null && tps.length > 0) {
+ TypeReference[] trs = new TypeReference[tps.length];
+ for (int i = 0; i < tps.length; i++) {
+ trs[i] = new SingleTypeReference(tps[i].name, p);
+ }
+ rr[idx] = trs;
+ filled = true;
+ }
+ if ((td.modifiers & ClassFileConstants.AccStatic) != 0) return filled; // Once we hit a static class, no further typeparams needed.
+ boolean f2 = fillOuterTypeParams(rr, idx - 1, node.up(), p);
+ return f2 || filled;
+ }
+
+ public static NameReference generateNameReference(EclipseNode type, long p) {
+ char[][] tn = getQualifiedInnerName(type.up(), ((TypeDeclaration) type.get()).name);
+ if (tn.length == 1) return new SingleNameReference(tn[0], p);
+ int tnLen = tn.length;
+ long[] ps = new long[tnLen];
+ for (int i = 0; i < tnLen; i++) ps[i] = p;
+ int ss = (int) (p >> 32);
+ int se = (int) p;
+ return new QualifiedNameReference(tn, ps, ss, se);
+ }
+
+ public static NameReference generateNameReference(EclipseNode parent, char[] name, long p) {
+ char[][] tn = getQualifiedInnerName(parent, name);
+ if (tn.length == 1) return new SingleNameReference(tn[0], p);
+ int tnLen = tn.length;
+ long[] ps = new long[tnLen];
+ for (int i = 0; i < tnLen; i++) ps[i] = p;
+ int ss = (int) (p >> 32);
+ int se = (int) p;
+ return new QualifiedNameReference(tn, ps, ss, se);
+ }
+
+ public static TypeReference generateTypeReference(EclipseNode type, long p) {
+ TypeDeclaration td = (TypeDeclaration) type.get();
+ char[][] tn = getQualifiedInnerName(type.up(), td.name);
+ if (tn.length == 1) return new SingleTypeReference(tn[0], p);
+ int tnLen = tn.length;
+ long[] ps = new long[tnLen];
+ for (int i = 0; i < tnLen; i++) ps[i] = p;
+
+ boolean instance = (td.modifiers & ClassFileConstants.AccStatic) == 0 && type.up() != null && type.up().get() instanceof TypeDeclaration;
+ if (instance) {
+ TypeReference[][] trs = new TypeReference[tn.length][];
+ boolean filled = fillOuterTypeParams(trs, trs.length - 2, type.up(), p);
+ if (filled) return new ParameterizedQualifiedTypeReference(tn, trs, 0, ps);
+ }
+
+ return new QualifiedTypeReference(tn, ps);
+ }
+
+ public static TypeReference generateTypeReference(EclipseNode parent, char[] name, boolean instance, long p) {
+ char[][] tn = getQualifiedInnerName(parent, name);
+ if (tn.length == 1) return new SingleTypeReference(tn[0], p);
+ int tnLen = tn.length;
+ long[] ps = new long[tnLen];
+ for (int i = 0; i < tnLen; i++) ps[i] = p;
+
+ if (instance && parent != null && parent.get() instanceof TypeDeclaration) {
+ TypeReference[][] trs = new TypeReference[tn.length][];
+ if (fillOuterTypeParams(trs, tn.length - 2, parent, p)) return new ParameterizedQualifiedTypeReference(tn, trs, 0, ps);
+ }
+
+ return new QualifiedTypeReference(tn, ps);
+ }
+
+ /**
+ * Generate a chain of names for the enclosing classes.
+ *
+ * Given for example {@code class Outer { class Inner {} }} this would generate {@code char[][] { "Outer", "Inner" }}.
+ * For method local and top level types, this generates a size-1 char[][] where the only char[] element is {@code name} itself.
+ */
+ private static char[][] getQualifiedInnerName(EclipseNode parent, char[] name) {
+ int count = 0;
+
+ EclipseNode n = parent;
+ while (n != null && n.getKind() == Kind.TYPE && n.get() instanceof TypeDeclaration) {
+ TypeDeclaration td = (TypeDeclaration) n.get();
+ if (td.name == null || td.name.length == 0) break;
+ count++;
+ n = n.up();
+ }
+
+ if (count == 0) return new char[][] { name };
+ char[][] res = new char[count + 1][];
+ res[count] = name;
+
+ n = parent;
+ while (n != null && n.getKind() == Kind.TYPE && n.get() instanceof TypeDeclaration) {
+ TypeDeclaration td = (TypeDeclaration) n.get();
+ res[--count] = td.name;
+ n = n.up();
+ }
+
+ return res;
+ }
+
public static TypeReference makeType(TypeBinding binding, ASTNode pos, boolean allowCompound) {
if (binding.getClass() == EclipseReflectiveMembers.INTERSECTION_BINDING) {
Object[] arr = (Object[]) EclipseReflectiveMembers.reflect(EclipseReflectiveMembers.INTERSECTION_BINDING_TYPES, binding);
diff --git a/src/core/lombok/eclipse/handlers/HandleBuilder.java b/src/core/lombok/eclipse/handlers/HandleBuilder.java
index 70978e23..6cc5bd57 100755
--- a/src/core/lombok/eclipse/handlers/HandleBuilder.java
+++ b/src/core/lombok/eclipse/handlers/HandleBuilder.java
@@ -55,6 +55,7 @@ import org.eclipse.jdt.internal.compiler.ast.NullLiteral;
import org.eclipse.jdt.internal.compiler.ast.OperatorIds;
import org.eclipse.jdt.internal.compiler.ast.ParameterizedQualifiedTypeReference;
import org.eclipse.jdt.internal.compiler.ast.ParameterizedSingleTypeReference;
+import org.eclipse.jdt.internal.compiler.ast.QualifiedAllocationExpression;
import org.eclipse.jdt.internal.compiler.ast.QualifiedThisReference;
import org.eclipse.jdt.internal.compiler.ast.QualifiedTypeReference;
import org.eclipse.jdt.internal.compiler.ast.ReturnStatement;
@@ -274,7 +275,7 @@ public class HandleBuilder extends EclipseAnnotationHandler<Builder> {
handleConstructor.generateConstructor(tdParent, AccessLevel.PACKAGE, allFields, false, null, SkipIfConstructorExists.I_AM_BUILDER,
Collections.<Annotation>emptyList(), annotationNode);
- returnType = namePlusTypeParamsToTypeReference(td.name, td.typeParameters, p);
+ returnType = namePlusTypeParamsToTypeReference(tdParent, td.typeParameters, p);
typeParams = td.typeParameters;
thrownExceptions = null;
nameOfStaticBuilderMethod = null;
@@ -289,7 +290,7 @@ public class HandleBuilder extends EclipseAnnotationHandler<Builder> {
tdParent = parent.up();
TypeDeclaration td = (TypeDeclaration) tdParent.get();
- returnType = namePlusTypeParamsToTypeReference(td.name, td.typeParameters, p);
+ returnType = namePlusTypeParamsToTypeReference(tdParent, td.typeParameters, p);
typeParams = td.typeParameters;
thrownExceptions = cd.thrownExceptions;
nameOfStaticBuilderMethod = null;
@@ -539,7 +540,7 @@ public class HandleBuilder extends EclipseAnnotationHandler<Builder> {
tps[i].name = typeArgsForToBuilder.get(i);
}
}
- MethodDeclaration md = generateToBuilderMethod(cfv, toBuilderMethodName, builderClassName, tdParent, tps, builderFields, fluent, ast, accessForOuters, builderInstance.setterPrefix());
+ MethodDeclaration md = generateToBuilderMethod(cfv, isStatic, toBuilderMethodName, builderClassName, tdParent, tps, builderFields, fluent, ast, accessForOuters, builderInstance.setterPrefix());
if (md != null) injectMethod(tdParent, md);
}
@@ -552,7 +553,7 @@ public class HandleBuilder extends EclipseAnnotationHandler<Builder> {
}
private static final char[] BUILDER_TEMP_VAR = {'b', 'u', 'i', 'l', 'd', 'e', 'r'};
- private MethodDeclaration generateToBuilderMethod(CheckerFrameworkVersion cfv, String methodName, String builderClassName, EclipseNode type, TypeParameter[] typeParams, List<BuilderFieldData> builderFields, boolean fluent, ASTNode source, AccessLevel access, String prefix) {
+ private MethodDeclaration generateToBuilderMethod(CheckerFrameworkVersion cfv, boolean isStatic, String methodName, String builderClassName, EclipseNode type, TypeParameter[] typeParams, List<BuilderFieldData> builderFields, boolean fluent, ASTNode source, AccessLevel access, String prefix) {
int pS = source.sourceStart, pE = source.sourceEnd;
long p = (long) pS << 32 | pE;
@@ -560,9 +561,9 @@ public class HandleBuilder extends EclipseAnnotationHandler<Builder> {
out.selector = methodName.toCharArray();
out.modifiers = toEclipseModifier(access);
out.bits |= ECLIPSE_DO_NOT_TOUCH_FLAG;
- out.returnType = namePlusTypeParamsToTypeReference(builderClassName.toCharArray(), typeParams, p);
+ out.returnType = namePlusTypeParamsToTypeReference(type, builderClassName.toCharArray(), !isStatic, typeParams, p);
AllocationExpression invoke = new AllocationExpression();
- invoke.type = namePlusTypeParamsToTypeReference(builderClassName.toCharArray(), typeParams, p);
+ invoke.type = namePlusTypeParamsToTypeReference(type, builderClassName.toCharArray(), !isStatic, typeParams, p);
Expression receiver = invoke;
List<Statement> statements = null;
@@ -593,7 +594,7 @@ public class HandleBuilder extends EclipseAnnotationHandler<Builder> {
obtainExpr.typeArguments[j] = new SingleTypeReference(typeParams[j].name, 0);
}
}
- obtainExpr.receiver = new SingleNameReference(type.getName().toCharArray(), 0);
+ obtainExpr.receiver = generateNameReference(type, 0);
} else {
obtainExpr.receiver = new ThisReference(0, 0);
}
@@ -623,7 +624,7 @@ public class HandleBuilder extends EclipseAnnotationHandler<Builder> {
LocalDeclaration b = new LocalDeclaration(BUILDER_TEMP_VAR, pS, pE);
out.statements[0] = b;
b.modifiers |= Modifier.FINAL;
- b.type = namePlusTypeParamsToTypeReference(builderClassName.toCharArray(), typeParams, p);
+ b.type = namePlusTypeParamsToTypeReference(type, builderClassName.toCharArray(), !isStatic, typeParams, p);
b.type.sourceStart = pS; b.type.sourceEnd = pE;
b.initialization = receiver;
out.statements[out.statements.length - 1] = new ReturnStatement(new SingleNameReference(BUILDER_TEMP_VAR, p), pS, pE);
@@ -684,7 +685,7 @@ public class HandleBuilder extends EclipseAnnotationHandler<Builder> {
}
ann.memberValue = arr;
}
- Argument arg = new Argument(new char[] { 't', 'h', 'i', 's' }, 0, new SingleTypeReference(type.getName().toCharArray(), source.sourceStart), Modifier.FINAL);
+ Argument arg = new Argument(new char[] { 't', 'h', 'i', 's' }, 0, generateTypeReference(type, source.sourceStart), Modifier.FINAL);
arg.annotations = new Annotation[] {ann};
return new Argument[] {arg};
}
@@ -751,7 +752,7 @@ public class HandleBuilder extends EclipseAnnotationHandler<Builder> {
if (isStatic) {
invoke.receiver = new SingleNameReference(type.up().getName().toCharArray(), 0);
} else {
- invoke.receiver = new QualifiedThisReference(new SingleTypeReference(type.up().getName().toCharArray(), 0) , 0, 0);
+ invoke.receiver = new QualifiedThisReference(generateTypeReference(type.up(), 0) , 0, 0);
}
invoke.typeArguments = typeParameterNames(((TypeDeclaration) type.get()).typeParameters);
@@ -801,17 +802,31 @@ public class HandleBuilder extends EclipseAnnotationHandler<Builder> {
public MethodDeclaration generateBuilderMethod(CheckerFrameworkVersion cfv, boolean isStatic, String builderMethodName, String builderClassName, EclipseNode type, TypeParameter[] typeParams, ASTNode source, AccessLevel access) {
int pS = source.sourceStart, pE = source.sourceEnd;
long p = (long) pS << 32 | pE;
+ char[] builderClassName_ = builderClassName.toCharArray();
MethodDeclaration out = new MethodDeclaration(((CompilationUnitDeclaration) type.top().get()).compilationResult);
out.selector = builderMethodName.toCharArray();
out.modifiers = toEclipseModifier(access);
if (isStatic) out.modifiers |= ClassFileConstants.AccStatic;
out.bits |= ECLIPSE_DO_NOT_TOUCH_FLAG;
- out.returnType = namePlusTypeParamsToTypeReference(builderClassName.toCharArray(), typeParams, p);
+ out.returnType = namePlusTypeParamsToTypeReference(type, builderClassName_, !isStatic, typeParams, p);
out.typeParameters = copyTypeParams(typeParams, source);
AllocationExpression invoke = new AllocationExpression();
- invoke.type = namePlusTypeParamsToTypeReference(builderClassName.toCharArray(), typeParams, p);
- out.statements = new Statement[] {new ReturnStatement(invoke, pS, pE)};
+ if (isStatic) {
+ invoke.type = namePlusTypeParamsToTypeReference(type, builderClassName_, false, typeParams, p);
+ out.statements = new Statement[] {new ReturnStatement(invoke, pS, pE)};
+ } else {
+ // return this.new Builder();
+ QualifiedAllocationExpression qualifiedInvoke = new QualifiedAllocationExpression();
+ qualifiedInvoke.enclosingInstance = new ThisReference(pS, pE);
+ if (typeParams == null || typeParams.length == 0) {
+ qualifiedInvoke.type = new SingleTypeReference(builderClassName_, p);
+ } else {
+ qualifiedInvoke.type = namePlusTypeParamsToTypeReference(null, builderClassName_, false, typeParams, p);
+ }
+
+ out.statements = new Statement[] {new ReturnStatement(qualifiedInvoke, pS, pE)};
+ }
Annotation uniqueAnn = cfv.generateUnique() ? generateNamedAnnotation(source, CheckerFrameworkVersion.NAME__UNIQUE) : null;
Annotation sefAnn = cfv.generateSideEffectFree() ? generateNamedAnnotation(source, CheckerFrameworkVersion.NAME__SIDE_EFFECT_FREE) : null;
if (uniqueAnn != null && sefAnn != null) {
@@ -904,7 +919,7 @@ public class HandleBuilder extends EclipseAnnotationHandler<Builder> {
Argument[] arr = setter.arguments == null ? new Argument[0] : setter.arguments;
Argument[] newArr = new Argument[arr.length + 1];
System.arraycopy(arr, 0, newArr, 1, arr.length);
- newArr[0] = new Argument(new char[] { 't', 'h', 'i', 's' }, 0, new SingleTypeReference(builderType.getName().toCharArray(), 0), Modifier.FINAL);
+ newArr[0] = new Argument(new char[] { 't', 'h', 'i', 's' }, 0, generateTypeReference(builderType, 0), Modifier.FINAL);
char[][] nameNotCalled = fromQualifiedName(CheckerFrameworkVersion.NAME__NOT_CALLED);
SingleMemberAnnotation ann = new SingleMemberAnnotation(new QualifiedTypeReference(nameNotCalled, poss(
source, nameNotCalled.length)), source.sourceStart);
diff --git a/src/core/lombok/eclipse/handlers/HandleConstructor.java b/src/core/lombok/eclipse/handlers/HandleConstructor.java
index 8f981c1a..7cb2036b 100755
--- a/src/core/lombok/eclipse/handlers/HandleConstructor.java
+++ b/src/core/lombok/eclipse/handlers/HandleConstructor.java
@@ -530,7 +530,7 @@ public class HandleConstructor {
constructor.modifiers = toEclipseModifier(level) | ClassFileConstants.AccStatic;
TypeDeclaration typeDecl = (TypeDeclaration) type.get();
- constructor.returnType = EclipseHandlerUtil.namePlusTypeParamsToTypeReference(typeDecl.name, typeDecl.typeParameters, p);
+ constructor.returnType = EclipseHandlerUtil.namePlusTypeParamsToTypeReference(type, typeDecl.typeParameters, p);
constructor.annotations = null;
constructor.selector = name.toCharArray();
constructor.thrownExceptions = null;
diff --git a/src/core/lombok/eclipse/handlers/HandleSuperBuilder.java b/src/core/lombok/eclipse/handlers/HandleSuperBuilder.java
index 8f0ef338..fbd4ce24 100755
--- a/src/core/lombok/eclipse/handlers/HandleSuperBuilder.java
+++ b/src/core/lombok/eclipse/handlers/HandleSuperBuilder.java
@@ -217,7 +217,7 @@ public class HandleSuperBuilder extends EclipseAnnotationHandler<SuperBuilder> {
String builderImplClassName = builderClassName + "Impl";
typeParams = td.typeParameters != null ? td.typeParameters : new TypeParameter[0];
- returnType = namePlusTypeParamsToTypeReference(td.name, typeParams, p);
+ returnType = namePlusTypeParamsToTypeReference(tdParent, typeParams, p);
// <C, B> are the generics for our builder.
String classGenericName = "C";
@@ -438,7 +438,7 @@ public class HandleSuperBuilder extends EclipseAnnotationHandler<SuperBuilder> {
o = new TypeParameter();
o.name = builderGenericName.toCharArray();
TypeReference[] typerefs = appendBuilderTypeReferences(typeParams, classGenericName, builderGenericName);
- o.type = new ParameterizedSingleTypeReference(builderClass.toCharArray(), typerefs, 0, 0);
+ o.type = generateParameterizedTypeReference(tdParent, builderClass.toCharArray(), false, typerefs, 0);
builder.typeParameters[builder.typeParameters.length - 1] = o;
builder.superclass = copyType(superclassBuilderClass, source);
@@ -469,8 +469,8 @@ public class HandleSuperBuilder extends EclipseAnnotationHandler<SuperBuilder> {
// 2. The return type for the build() method (named "C" in the abstract builder), which is the annotated class.
// 3. The return type for all setter methods (named "B" in the abstract builder), which is this builder class.
typeArgs[typeArgs.length - 2] = cloneSelfType(tdParent, source);
- typeArgs[typeArgs.length - 1] = createTypeReferenceWithTypeParameters(builderImplClass, typeParams);
- builder.superclass = new ParameterizedSingleTypeReference(builderAbstractClass.toCharArray(), typeArgs, 0, 0);
+ typeArgs[typeArgs.length - 1] = createTypeReferenceWithTypeParameters(tdParent, builderImplClass, typeParams);
+ builder.superclass = generateParameterizedTypeReference(tdParent, builderAbstractClass.toCharArray(), false, typeArgs, 0);
}
builder.createDefaultConstructor(false, true);
@@ -523,7 +523,7 @@ public class HandleSuperBuilder extends EclipseAnnotationHandler<SuperBuilder> {
constructor.bodyEnd = constructor.declarationSourceEnd = constructor.sourceEnd = source.sourceEnd;
TypeReference[] wildcards = new TypeReference[] {new Wildcard(Wildcard.UNBOUND), new Wildcard(Wildcard.UNBOUND)};
- TypeReference builderType = new ParameterizedSingleTypeReference(builderClassName.toCharArray(), mergeToTypeReferences(typeParams, wildcards), 0, p);
+ TypeReference builderType = generateParameterizedTypeReference(typeNode, builderClassName.toCharArray(), false, mergeToTypeReferences(typeParams, wildcards), p);
constructor.arguments = new Argument[] {new Argument(BUILDER_VARIABLE_NAME, p, builderType, Modifier.FINAL)};
List<Statement> statements = new ArrayList<Statement>();
@@ -554,7 +554,7 @@ public class HandleSuperBuilder extends EclipseAnnotationHandler<SuperBuilder> {
MessageSend defaultMethodCall = new MessageSend();
defaultMethodCall.sourceStart = source.sourceStart;
defaultMethodCall.sourceEnd = source.sourceEnd;
- defaultMethodCall.receiver = new SingleNameReference(((TypeDeclaration) typeNode.get()).name, 0L);
+ defaultMethodCall.receiver = generateNameReference(typeNode, 0L);
defaultMethodCall.selector = fieldNode.nameOfDefaultProvider;
defaultMethodCall.typeArguments = typeParameterNames(((TypeDeclaration) typeNode.get()).typeParameters);
@@ -591,10 +591,10 @@ public class HandleSuperBuilder extends EclipseAnnotationHandler<SuperBuilder> {
if (typeParams != null && typeParams.length > 0) out.typeParameters = copyTypeParams(typeParams, source);
TypeReference[] wildcards = new TypeReference[] {new Wildcard(Wildcard.UNBOUND), new Wildcard(Wildcard.UNBOUND) };
- out.returnType = new ParameterizedSingleTypeReference(builderClassName.toCharArray(), mergeToTypeReferences(typeParams, wildcards), 0, p);
+ out.returnType = generateParameterizedTypeReference(type, builderClassName.toCharArray(), false, mergeToTypeReferences(typeParams, wildcards), p);
AllocationExpression invoke = new AllocationExpression();
- invoke.type = namePlusTypeParamsToTypeReference(builderImplClassName.toCharArray(), typeParams, p);
+ invoke.type = namePlusTypeParamsToTypeReference(type, builderImplClassName.toCharArray(), false, typeParams, p);
out.statements = new Statement[] {new ReturnStatement(invoke, pS, pE)};
if (cfv.generateUnique()) out.annotations = new Annotation[] {generateNamedAnnotation(source, CheckerFrameworkVersion.NAME__UNIQUE)};
@@ -606,8 +606,8 @@ public class HandleSuperBuilder extends EclipseAnnotationHandler<SuperBuilder> {
/**
* Generates a <code>toBuilder()</code> method in the annotated class that looks like this:
* <pre>
- * public ParentBuilder&lt;?, ?&gt; toBuilder() {
- * return new <i>Foobar</i>BuilderImpl().$fillValuesFrom(this);
+ * public <i>Foobar</i>.<i>Foobar</i>Builder&lt;?, ?&gt; toBuilder() {
+ * return new <i.Foobar</i>.<i>Foobar</i>BuilderImpl().$fillValuesFrom(this);
* }
* </pre>
*/
@@ -621,10 +621,10 @@ public class HandleSuperBuilder extends EclipseAnnotationHandler<SuperBuilder> {
out.bits |= ECLIPSE_DO_NOT_TOUCH_FLAG;
TypeReference[] wildcards = new TypeReference[] {new Wildcard(Wildcard.UNBOUND), new Wildcard(Wildcard.UNBOUND) };
- out.returnType = new ParameterizedSingleTypeReference(builderClassName.toCharArray(), mergeToTypeReferences(typeParams, wildcards), 0, p);
+ out.returnType = generateParameterizedTypeReference(type, builderClassName.toCharArray(), false, mergeToTypeReferences(typeParams, wildcards), p);
AllocationExpression newClass = new AllocationExpression();
- newClass.type = namePlusTypeParamsToTypeReference(builderImplClassName.toCharArray(), typeParams, p);
+ newClass.type = namePlusTypeParamsToTypeReference(type, builderImplClassName.toCharArray(), false, typeParams, p);
MessageSend invokeFillMethod = new MessageSend();
invokeFillMethod.receiver = newClass;
invokeFillMethod.selector = FILL_VALUES_METHOD_NAME;
@@ -643,7 +643,7 @@ public class HandleSuperBuilder extends EclipseAnnotationHandler<SuperBuilder> {
* <pre>
* protected B $fillValuesFrom(final C instance) {
* super.$fillValuesFrom(instance);
- * FoobarBuilderImpl.$fillValuesFromInstanceIntoBuilder(instance, this);
+ * Foobar.FoobarBuilderImpl.$fillValuesFromInstanceIntoBuilder(instance, this);
* return self();
* }
* </pre>
@@ -672,7 +672,7 @@ public class HandleSuperBuilder extends EclipseAnnotationHandler<SuperBuilder> {
// Call the builder implemention's helper method that actually fills the values from the instance.
MessageSend callStaticFillValuesMethod = new MessageSend();
- callStaticFillValuesMethod.receiver = new SingleNameReference(builderClassName.toCharArray(), 0);
+ callStaticFillValuesMethod.receiver = generateNameReference(tdParent, builderClassName.toCharArray(), 0);
callStaticFillValuesMethod.selector = FILL_VALUES_STATIC_METHOD_NAME;
callStaticFillValuesMethod.arguments = new Expression[] {new SingleNameReference(INSTANCE_VARIABLE_NAME, 0), new ThisReference(0, 0)};
body.add(callStaticFillValuesMethod);
@@ -707,16 +707,25 @@ public class HandleSuperBuilder extends EclipseAnnotationHandler<SuperBuilder> {
out.returnType = TypeReference.baseTypeReference(TypeIds.T_void, 0);
TypeReference[] wildcards = new TypeReference[] {new Wildcard(Wildcard.UNBOUND), new Wildcard(Wildcard.UNBOUND)};
- TypeReference builderType = new ParameterizedSingleTypeReference(builderClassName.toCharArray(), mergeToTypeReferences(typeParams, wildcards), 0, 0);
+ TypeReference builderType = generateParameterizedTypeReference(tdParent, builderClassName.toCharArray(), false, mergeToTypeReferences(typeParams, wildcards), 0);
Argument builderArgument = new Argument(BUILDER_VARIABLE_NAME, 0, builderType, Modifier.FINAL);
- TypeReference parentArgument = createTypeReferenceWithTypeParameters(tdParent.getName(), typeParams);
+ TypeReference[] typerefs = null;
+ if (typeParams.length > 0) {
+ typerefs = new TypeReference[typeParams.length];
+ for (int i = 0; i < typeParams.length; i++) typerefs[i] = new SingleTypeReference(typeParams[i].name, 0);
+ }
+
+ long p = source.sourceStart;
+ p = (p << 32) | source.sourceEnd;
+
+ TypeReference parentArgument = typerefs == null ? generateTypeReference(tdParent, p) : generateParameterizedTypeReference(tdParent, typerefs, p);
out.arguments = new Argument[] {new Argument(INSTANCE_VARIABLE_NAME, 0, parentArgument, Modifier.FINAL), builderArgument};
-
+
// Add type params if there are any.
if (typeParams.length > 0) out.typeParameters = copyTypeParams(typeParams, source);
-
+
List<Statement> body = new ArrayList<Statement>();
-
+
// Call the builder's setter methods to fill the values from the instance.
for (BuilderFieldData bfd : builderFields) {
MessageSend exec = createSetterCallWithInstanceValue(bfd, tdParent, source);
@@ -727,7 +736,7 @@ public class HandleSuperBuilder extends EclipseAnnotationHandler<SuperBuilder> {
return out;
}
-
+
private MessageSend createSetterCallWithInstanceValue(BuilderFieldData bfd, EclipseNode type, ASTNode source) {
char[] setterName = bfd.name;
MessageSend ms = new MessageSend();
@@ -745,7 +754,7 @@ public class HandleSuperBuilder extends EclipseAnnotationHandler<SuperBuilder> {
boolean obtainIsStatic = bfd.obtainVia.isStatic();
for (int i = 0; i < tgt.length; i++) {
MessageSend obtainExpr = new MessageSend();
- obtainExpr.receiver = obtainIsStatic ? new SingleNameReference(type.getName().toCharArray(), 0) : new SingleNameReference(INSTANCE_VARIABLE_NAME, 0);
+ obtainExpr.receiver = obtainIsStatic ? generateNameReference(type, 0) : new SingleNameReference(INSTANCE_VARIABLE_NAME, 0);
obtainExpr.selector = obtainName.toCharArray();
if (obtainIsStatic) obtainExpr.arguments = new Expression[] {new SingleNameReference(INSTANCE_VARIABLE_NAME, 0)};
tgt[i] = obtainExpr;
@@ -796,7 +805,7 @@ public class HandleSuperBuilder extends EclipseAnnotationHandler<SuperBuilder> {
else if (rrAnn != null) out.annotations = new Annotation[] {overrideAnn, rrAnn};
else if (sefAnn != null) out.annotations = new Annotation[] {overrideAnn, sefAnn};
else out.annotations = new Annotation[] {overrideAnn};
- out.returnType = namePlusTypeParamsToTypeReference(builderImplType.getName().toCharArray(), typeParams, p);
+ out.returnType = namePlusTypeParamsToTypeReference(builderImplType, typeParams, p);
out.statements = new Statement[] {new ReturnStatement(new ThisReference(0, 0), 0, 0)};
return out;
}
@@ -959,7 +968,7 @@ public class HandleSuperBuilder extends EclipseAnnotationHandler<SuperBuilder> {
Argument[] arr = setter.arguments == null ? new Argument[0] : setter.arguments;
Argument[] newArr = new Argument[arr.length + 1];
System.arraycopy(arr, 0, newArr, 1, arr.length);
- newArr[0] = new Argument(new char[] { 't', 'h', 'i', 's' }, 0, new SingleTypeReference(builderType.getName().toCharArray(), 0), Modifier.FINAL);
+ newArr[0] = new Argument(new char[] { 't', 'h', 'i', 's' }, 0, generateTypeReference(builderType, 0), Modifier.FINAL);
char[][] nameNotCalled = fromQualifiedName(CheckerFrameworkVersion.NAME__NOT_CALLED);
SingleMemberAnnotation ann = new SingleMemberAnnotation(new QualifiedTypeReference(nameNotCalled, poss(source, nameNotCalled.length)), source.sourceStart);
ann.memberValue = new StringLiteral(setterName.toCharArray(), 0, 0, 0);
@@ -1067,15 +1076,15 @@ public class HandleSuperBuilder extends EclipseAnnotationHandler<SuperBuilder> {
return typeArgs;
}
- private static SingleTypeReference createTypeReferenceWithTypeParameters(String referenceName, TypeParameter[] typeParams) {
+ private static TypeReference createTypeReferenceWithTypeParameters(EclipseNode parent, String referenceName, TypeParameter[] typeParams) {
if (typeParams.length > 0) {
TypeReference[] typerefs = new TypeReference[typeParams.length];
for (int i = 0; i < typeParams.length; i++) {
typerefs[i] = new SingleTypeReference(typeParams[i].name, 0);
}
- return new ParameterizedSingleTypeReference(referenceName.toCharArray(), typerefs, 0, 0);
+ return generateParameterizedTypeReference(parent, referenceName.toCharArray(), false, typerefs, 0);
} else {
- return new SingleTypeReference(referenceName.toCharArray(), 0);
+ return generateTypeReference(parent, referenceName.toCharArray(), false, 0);
}
}
diff --git a/src/core/lombok/javac/handlers/HandleBuilder.java b/src/core/lombok/javac/handlers/HandleBuilder.java
index 349b1382..00741249 100644
--- a/src/core/lombok/javac/handlers/HandleBuilder.java
+++ b/src/core/lombok/javac/handlers/HandleBuilder.java
@@ -21,6 +21,12 @@
*/
package lombok.javac.handlers;
+import static lombok.core.handlers.HandlerUtil.*;
+import static lombok.javac.Javac.*;
+import static lombok.javac.JavacTreeMaker.TypeTag.typeTag;
+import static lombok.javac.handlers.JavacHandlerUtil.*;
+import static lombok.javac.handlers.JavacHandlerUtil.isFieldDeprecated;
+
import java.util.ArrayList;
import javax.lang.model.element.Modifier;
@@ -40,6 +46,7 @@ import com.sun.tools.javac.tree.JCTree.JCIf;
import com.sun.tools.javac.tree.JCTree.JCLiteral;
import com.sun.tools.javac.tree.JCTree.JCMethodDecl;
import com.sun.tools.javac.tree.JCTree.JCModifiers;
+import com.sun.tools.javac.tree.JCTree.JCNewClass;
import com.sun.tools.javac.tree.JCTree.JCPrimitiveTypeTree;
import com.sun.tools.javac.tree.JCTree.JCStatement;
import com.sun.tools.javac.tree.JCTree.JCTypeApply;
@@ -60,6 +67,7 @@ import lombok.core.AnnotationValues;
import lombok.core.HandlerPriority;
import lombok.core.configuration.CheckerFrameworkVersion;
import lombok.core.handlers.HandlerUtil;
+import lombok.core.handlers.HandlerUtil.FieldAccess;
import lombok.core.handlers.InclusionExclusionUtils.Included;
import lombok.experimental.NonFinal;
import lombok.javac.Javac;
@@ -67,12 +75,10 @@ import lombok.javac.JavacAnnotationHandler;
import lombok.javac.JavacNode;
import lombok.javac.JavacTreeMaker;
import lombok.javac.handlers.HandleConstructor.SkipIfConstructorExists;
+import lombok.javac.handlers.JavacHandlerUtil.CopyJavadoc;
+import lombok.javac.handlers.JavacHandlerUtil.MemberExistsResult;
import lombok.javac.handlers.JavacSingularsRecipes.JavacSingularizer;
import lombok.javac.handlers.JavacSingularsRecipes.SingularData;
-import static lombok.core.handlers.HandlerUtil.*;
-import static lombok.javac.handlers.JavacHandlerUtil.*;
-import static lombok.javac.Javac.*;
-import static lombok.javac.JavacTreeMaker.TypeTag.*;
@ProviderFor(JavacAnnotationHandler.class)
@HandlerPriority(-1024) //-2^10; to ensure we've picked up @FieldDefault's changes (-2048) but @Value hasn't removed itself yet (-512), so that we can error on presence of it on the builder classes.
@@ -216,7 +222,7 @@ public class HandleBuilder extends JavacAnnotationHandler<Builder> {
handleConstructor.generateConstructor(tdParent, AccessLevel.PACKAGE, List.<JCAnnotation>nil(), allFields.toList(), false, null, SkipIfConstructorExists.I_AM_BUILDER, annotationNode);
- returnType = namePlusTypeParamsToTypeReference(tdParent.getTreeMaker(), td.name, td.typarams);
+ returnType = namePlusTypeParamsToTypeReference(tdParent.getTreeMaker(), tdParent, td.typarams);
typeParams = td.typarams;
thrownExceptions = List.nil();
nameOfBuilderMethod = null;
@@ -231,7 +237,7 @@ public class HandleBuilder extends JavacAnnotationHandler<Builder> {
tdParent = parent.up();
JCClassDecl td = (JCClassDecl) tdParent.get();
- returnType = namePlusTypeParamsToTypeReference(tdParent.getTreeMaker(), td.name, td.typarams);
+ returnType = namePlusTypeParamsToTypeReference(tdParent.getTreeMaker(), tdParent, td.typarams);
typeParams = td.typarams;
thrownExceptions = jmd.thrown;
nameOfBuilderMethod = null;
@@ -487,7 +493,7 @@ public class HandleBuilder extends JavacAnnotationHandler<Builder> {
}
tps = lb.toList();
}
- JCMethodDecl md = generateToBuilderMethod(cfv, toBuilderMethodName, builderClassName, tdParent, tps, builderFields, fluent, ast, accessForOuters, builderInstance.setterPrefix());
+ JCMethodDecl md = generateToBuilderMethod(cfv, toBuilderMethodName, builderClassName, tdParent, isStatic, tps, builderFields, fluent, ast, accessForOuters, builderInstance.setterPrefix());
if (md != null) {
recursiveSetGeneratedBy(md, ast, annotationNode.getContext());
injectMethod(tdParent, md);
@@ -536,7 +542,7 @@ public class HandleBuilder extends JavacAnnotationHandler<Builder> {
}
private static final String BUILDER_TEMP_VAR = "builder";
- private JCMethodDecl generateToBuilderMethod(CheckerFrameworkVersion cfv, String toBuilderMethodName, String builderClassName, JavacNode type, List<JCTypeParameter> typeParams, java.util.List<BuilderFieldData> builderFields, boolean fluent, JCAnnotation ast, AccessLevel access, String prefix) {
+ private JCMethodDecl generateToBuilderMethod(CheckerFrameworkVersion cfv, String toBuilderMethodName, String builderClassName, JavacNode type, boolean isStatic, List<JCTypeParameter> typeParams, java.util.List<BuilderFieldData> builderFields, boolean fluent, JCAnnotation ast, AccessLevel access, String prefix) {
// return new ThingieBuilder<A, B>().setA(this.a).setB(this.b);
JavacTreeMaker maker = type.getTreeMaker();
@@ -545,7 +551,7 @@ public class HandleBuilder extends JavacAnnotationHandler<Builder> {
typeArgs.append(maker.Ident(typeParam.name));
}
- JCExpression call = maker.NewClass(null, List.<JCExpression>nil(), namePlusTypeParamsToTypeReference(maker, type.toName(builderClassName), typeParams), List.<JCExpression>nil(), null);
+ JCExpression call = maker.NewClass(null, List.<JCExpression>nil(), namePlusTypeParamsToTypeReference(maker, type, type.toName(builderClassName), !isStatic, typeParams), List.<JCExpression>nil(), null);
JCExpression invoke = call;
ListBuffer<JCStatement> statements = new ListBuffer<JCStatement>();
for (BuilderFieldData bfd : builderFields) {
@@ -584,7 +590,7 @@ public class HandleBuilder extends JavacAnnotationHandler<Builder> {
}
}
if (!statements.isEmpty()) {
- JCExpression tempVarType = namePlusTypeParamsToTypeReference(maker, type.toName(builderClassName), typeParams);
+ JCExpression tempVarType = namePlusTypeParamsToTypeReference(maker, type, type.toName(builderClassName), !isStatic, typeParams);
statements.prepend(maker.VarDef(maker.Modifiers(Flags.FINAL), type.toName(BUILDER_TEMP_VAR), tempVarType, invoke));
statements.append(maker.Return(maker.Ident(type.toName(BUILDER_TEMP_VAR))));
} else {
@@ -592,7 +598,7 @@ public class HandleBuilder extends JavacAnnotationHandler<Builder> {
}
JCBlock body = maker.Block(0, statements.toList());
List<JCAnnotation> annsOnMethod = cfv.generateUnique() ? List.of(maker.Annotation(genTypeRef(type, CheckerFrameworkVersion.NAME__UNIQUE), List.<JCExpression>nil())) : List.<JCAnnotation>nil();
- return maker.MethodDef(maker.Modifiers(toJavacModifier(access), annsOnMethod), type.toName(toBuilderMethodName), namePlusTypeParamsToTypeReference(maker, type.toName(builderClassName), typeParams), List.<JCTypeParameter>nil(), List.<JCVariableDecl>nil(), List.<JCExpression>nil(), body, null);
+ return maker.MethodDef(maker.Modifiers(toJavacModifier(access), annsOnMethod), type.toName(toBuilderMethodName), namePlusTypeParamsToTypeReference(maker, type, type.toName(builderClassName), !isStatic, typeParams), List.<JCTypeParameter>nil(), List.<JCVariableDecl>nil(), List.<JCExpression>nil(), body, null);
}
private JCMethodDecl generateCleanMethod(java.util.List<BuilderFieldData> builderFields, JavacNode type, JCTree source) {
@@ -610,18 +616,6 @@ public class HandleBuilder extends JavacAnnotationHandler<Builder> {
JCMethodDecl method = maker.MethodDef(maker.Modifiers(toJavacModifier(AccessLevel.PRIVATE)), type.toName("$lombokClean"), maker.Type(Javac.createVoidType(type.getSymbolTable(), CTC_VOID)), List.<JCTypeParameter>nil(), List.<JCVariableDecl>nil(), List.<JCExpression>nil(), body, null);
recursiveSetGeneratedBy(method, source, type.getContext());
return method;
- /*
- * if (shouldReturnThis) {
- methodType = cloneSelfType(field);
- }
-
- if (methodType == null) {
- //WARNING: Do not use field.getSymbolTable().voidType - that field has gone through non-backwards compatible API changes within javac1.6.
- methodType = treeMaker.Type(Javac.createVoidType(treeMaker, CTC_VOID));
- shouldReturnThis = false;
- }
-
- */
}
static List<JCVariableDecl> generateBuildArgs(CheckerFrameworkVersion cfv, JavacNode type, java.util.List<BuilderFieldData> builderFields) {
@@ -643,10 +637,10 @@ public class HandleBuilder extends JavacAnnotationHandler<Builder> {
}
JCAnnotation recvAnno = maker.Annotation(genTypeRef(type, CheckerFrameworkVersion.NAME__CALLED), List.of(arg));
JCClassDecl builderTypeNode = (JCClassDecl) type.get();
- JCVariableDecl recv = maker.VarDef(maker.Modifiers(0L, List.<JCAnnotation>of(recvAnno)), type.toName("this"), maker.Ident(builderTypeNode.name), null);
+ JCVariableDecl recv = maker.VarDef(maker.Modifiers(0L, List.<JCAnnotation>of(recvAnno)), type.toName("this"), namePlusTypeParamsToTypeReference(maker, type, builderTypeNode.typarams), null);
return List.of(recv);
}
-
+
private JCMethodDecl generateBuildMethod(CheckerFrameworkVersion cfv, JavacNode tdParent, boolean isStatic, String buildName, Name builderName, JCExpression returnType, java.util.List<BuilderFieldData> builderFields, JavacNode type, List<JCExpression> thrownExceptions, JCTree source, boolean addCleaning, AccessLevel access) {
JavacTreeMaker maker = type.getTreeMaker();
@@ -725,7 +719,14 @@ public class HandleBuilder extends JavacAnnotationHandler<Builder> {
typeArgs.append(maker.Ident(typeParam.name));
}
- JCExpression call = maker.NewClass(null, List.<JCExpression>nil(), namePlusTypeParamsToTypeReference(maker, type.toName(builderClassName), typeParams), List.<JCExpression>nil(), null);
+ JCExpression call;
+ if (isStatic) {
+ call = maker.NewClass(null, List.<JCExpression>nil(), namePlusTypeParamsToTypeReference(maker, type, type.toName(builderClassName), false, typeParams), List.<JCExpression>nil(), null);
+ } else {
+ call = maker.NewClass(null, List.<JCExpression>nil(), namePlusTypeParamsToTypeReference(maker, null, type.toName(builderClassName), false, typeParams), List.<JCExpression>nil(), null);
+ ((JCNewClass) call).encl = maker.Ident(type.toName("this"));
+
+ }
JCStatement statement = maker.Return(call);
JCBlock body = maker.Block(0, List.<JCStatement>of(statement));
@@ -738,7 +739,7 @@ public class HandleBuilder extends JavacAnnotationHandler<Builder> {
else if (annUnique != null) annsOnMethod = List.of(annUnique);
else if (annSef != null) annsOnMethod = List.of(annSef);
else annsOnMethod = List.nil();
- return maker.MethodDef(maker.Modifiers(modifiers, annsOnMethod), type.toName(builderMethodName), namePlusTypeParamsToTypeReference(maker, type.toName(builderClassName), typeParams), copyTypeParams(source, typeParams), List.<JCVariableDecl>nil(), List.<JCExpression>nil(), body, null);
+ return maker.MethodDef(maker.Modifiers(modifiers, annsOnMethod), type.toName(builderMethodName), namePlusTypeParamsToTypeReference(maker, type, type.toName(builderClassName), !isStatic, typeParams), copyTypeParams(source, typeParams), List.<JCVariableDecl>nil(), List.<JCExpression>nil(), body, null);
}
public void generateBuilderFields(JavacNode builderType, java.util.List<BuilderFieldData> builderFields, JCTree source) {
@@ -785,7 +786,6 @@ public class HandleBuilder extends JavacAnnotationHandler<Builder> {
if (fieldNode.singularData == null || fieldNode.singularData.getSingularizer() == null) {
makePrefixedSetterMethodForBuilder(cfv, builderType, deprecate, fieldNode.createdFields.get(0), fieldNode.name, fieldNode.nameOfSetFlag, source, fluent, chain, fieldNode.annotations, fieldNode.originalFieldNode, access, prefix);
} else {
- // TODO prefixed version
fieldNode.singularData.getSingularizer().generateMethods(cfv, fieldNode.singularData, deprecate, builderType, source.get(), fluent, chain, access);
}
}
@@ -809,7 +809,8 @@ public class HandleBuilder extends JavacAnnotationHandler<Builder> {
if (cfv.generateCalledMethods()) {
JCAnnotation ncAnno = maker.Annotation(genTypeRef(source, CheckerFrameworkVersion.NAME__NOT_CALLED), List.<JCExpression>of(maker.Literal(newMethod.getName().toString())));
JCClassDecl builderTypeNode = (JCClassDecl) builderType.get();
- JCVariableDecl recv = maker.VarDef(maker.Modifiers(0L, List.<JCAnnotation>of(ncAnno)), builderType.toName("this"), maker.Ident(builderTypeNode.name), null);
+ JCExpression selfType = namePlusTypeParamsToTypeReference(maker, builderType, builderTypeNode.typarams);
+ JCVariableDecl recv = maker.VarDef(maker.Modifiers(0L, List.<JCAnnotation>of(ncAnno)), builderType.toName("this"), selfType, null);
newMethod.params = List.of(recv, newMethod.params.get(0));
}
recursiveSetGeneratedBy(newMethod, source.get(), builderType.getContext());
diff --git a/src/core/lombok/javac/handlers/HandleSuperBuilder.java b/src/core/lombok/javac/handlers/HandleSuperBuilder.java
index 83dc23d1..d37b3049 100644
--- a/src/core/lombok/javac/handlers/HandleSuperBuilder.java
+++ b/src/core/lombok/javac/handlers/HandleSuperBuilder.java
@@ -408,18 +408,15 @@ public class HandleSuperBuilder extends JavacAnnotationHandler<SuperBuilder> {
allTypeParams.addAll(copyTypeParams(source, typeParams));
// Add builder-specific type params required for inheritable builders.
// 1. The return type for the build() method, named "C", which extends the annotated class.
- JCExpression annotatedClass = maker.Ident(tdParent.toName(tdParent.getName()));
- if (typeParams.nonEmpty()) {
- // Add type params of the annotated class.
- annotatedClass = maker.TypeApply(annotatedClass, getTypeParamExpressions(typeParams, maker).toList());
- }
+ JCExpression annotatedClass = namePlusTypeParamsToTypeReference(maker, tdParent, typeParams);
+
allTypeParams.add(maker.TypeParameter(tdParent.toName(classGenericName), List.<JCExpression>of(annotatedClass)));
// 2. The return type for all setter methods, named "B", which extends this builder class.
Name builderClassName = tdParent.toName(builderClass);
ListBuffer<JCExpression> typeParamsForBuilder = getTypeParamExpressions(typeParams, maker);
typeParamsForBuilder.add(maker.Ident(tdParent.toName(classGenericName)));
typeParamsForBuilder.add(maker.Ident(tdParent.toName(builderGenericName)));
- JCTypeApply typeApply = maker.TypeApply(maker.Ident(builderClassName), typeParamsForBuilder.toList());
+ JCTypeApply typeApply = maker.TypeApply(namePlusTypeParamsToTypeReference(maker, tdParent, builderClassName, false, List.<JCTypeParameter>nil()), typeParamsForBuilder.toList());
allTypeParams.add(maker.TypeParameter(tdParent.toName(builderGenericName), List.<JCExpression>of(typeApply)));
JCExpression extending = null;
@@ -445,22 +442,16 @@ public class HandleSuperBuilder extends JavacAnnotationHandler<SuperBuilder> {
JCModifiers mods = maker.Modifiers(Flags.STATIC | Flags.PRIVATE | Flags.FINAL);
// Extend the abstract builder.
- JCExpression extending = maker.Ident(tdParent.toName(builderAbstractClass));
+ JCExpression extending = namePlusTypeParamsToTypeReference(maker, tdParent, tdParent.toName(builderAbstractClass), false, List.<JCTypeParameter>nil());
// Add any type params of the annotated class.
ListBuffer<JCTypeParameter> allTypeParams = new ListBuffer<JCTypeParameter>();
allTypeParams.addAll(copyTypeParams(source, typeParams));
// Add builder-specific type params required for inheritable builders.
// 1. The return type for the build() method (named "C" in the abstract builder), which is the annotated class.
- JCExpression annotatedClass = maker.Ident(tdParent.toName(tdParent.getName()));
- if (typeParams.nonEmpty()) {
- // Add type params of the annotated class.
- annotatedClass = maker.TypeApply(annotatedClass, getTypeParamExpressions(typeParams, maker).toList());
- }
+ JCExpression annotatedClass = namePlusTypeParamsToTypeReference(maker, tdParent, typeParams);
// 2. The return type for all setter methods (named "B" in the abstract builder), which is this builder class.
- JCExpression builderImplClassExpression = maker.Ident(tdParent.toName(builderImplClass));
- if (typeParams.nonEmpty()) {
- builderImplClassExpression = maker.TypeApply(builderImplClassExpression, getTypeParamExpressions(typeParams, maker).toList());
- }
+ JCExpression builderImplClassExpression = namePlusTypeParamsToTypeReference(maker, tdParent, tdParent.toName(builderImplClass), false, typeParams);
+
ListBuffer<JCExpression> typeParamsForBuilder = getTypeParamExpressions(typeParams, maker);
typeParamsForBuilder.add(annotatedClass);
typeParamsForBuilder.add(builderImplClassExpression);
@@ -509,7 +500,8 @@ public class HandleSuperBuilder extends JavacAnnotationHandler<SuperBuilder> {
if (bfd.nameOfSetFlag != null) {
JCFieldAccess setField = maker.Select(maker.Ident(builderVariableName), bfd.nameOfSetFlag);
fieldInThis = maker.Select(maker.Ident(typeNode.toName("this")), bfd.rawName);
- JCAssign assignDefault = maker.Assign(fieldInThis, maker.Apply(typeParameterNames(maker, ((JCClassDecl) typeNode.get()).typarams), maker.Select(maker.Ident(((JCClassDecl) typeNode.get()).name), bfd.nameOfDefaultProvider), List.<JCExpression>nil()));
+ JCExpression parentTypeRef = namePlusTypeParamsToTypeReference(maker, typeNode, List.<JCTypeParameter>nil());
+ JCAssign assignDefault = maker.Assign(fieldInThis, maker.Apply(typeParameterNames(maker, ((JCClassDecl) typeNode.get()).typarams), maker.Select(parentTypeRef, bfd.nameOfDefaultProvider), List.<JCExpression>nil()));
statements.append(maker.If(setField, assign, maker.Exec(assignDefault)));
} else {
statements.append(assign);
@@ -535,7 +527,7 @@ public class HandleSuperBuilder extends JavacAnnotationHandler<SuperBuilder> {
typeParamsForBuilderParameter.add(wildcard);
wildcard = maker.Wildcard(maker.TypeBoundKind(BoundKind.UNBOUND), null);
typeParamsForBuilderParameter.add(wildcard);
- JCTypeApply paramType = maker.TypeApply(maker.Ident(builderClassname), typeParamsForBuilderParameter.toList());
+ JCTypeApply paramType = maker.TypeApply(namePlusTypeParamsToTypeReference(maker, typeNode, builderClassname, false, List.<JCTypeParameter>nil()), typeParamsForBuilderParameter.toList());
JCVariableDecl param = maker.VarDef(maker.Modifiers(flags), builderVariableName, paramType, null);
params.append(param);
@@ -560,7 +552,7 @@ public class HandleSuperBuilder extends JavacAnnotationHandler<SuperBuilder> {
ListBuffer<JCExpression> typeArgs = new ListBuffer<JCExpression>();
for (JCTypeParameter typeParam : typeParams) typeArgs.append(maker.Ident(typeParam.name));
- JCExpression call = maker.NewClass(null, List.<JCExpression>nil(), namePlusTypeParamsToTypeReference(maker, type.toName(builderImplClassName), typeParams), List.<JCExpression>nil(), null);
+ JCExpression call = maker.NewClass(null, List.<JCExpression>nil(), namePlusTypeParamsToTypeReference(maker, type, type.toName(builderImplClassName), false, typeParams), List.<JCExpression>nil(), null);
JCStatement statement = maker.Return(call);
JCBlock body = maker.Block(0, List.<JCStatement>of(statement));
@@ -574,7 +566,7 @@ public class HandleSuperBuilder extends JavacAnnotationHandler<SuperBuilder> {
JCWildcard wildcard = maker.Wildcard(maker.TypeBoundKind(BoundKind.UNBOUND), null);
typeParameterNames.add(wildcard);
typeParameterNames.add(wildcard);
- JCTypeApply returnType = maker.TypeApply(maker.Ident(type.toName(builderClassName)), typeParameterNames.toList());
+ JCTypeApply returnType = maker.TypeApply(namePlusTypeParamsToTypeReference(maker, type, type.toName(builderClassName), false, List.<JCTypeParameter>nil()), typeParameterNames.toList());
List<JCAnnotation> annsOnMethod = cfv.generateUnique() ? List.of(maker.Annotation(genTypeRef(type, CheckerFrameworkVersion.NAME__SIDE_EFFECT_FREE), List.<JCExpression>nil())) : List.<JCAnnotation>nil();
return maker.MethodDef(maker.Modifiers(modifiers, annsOnMethod), type.toName(builderMethodName), returnType, copyTypeParams(source, typeParams), List.<JCVariableDecl>nil(), List.<JCExpression>nil(), body, null);
@@ -594,7 +586,7 @@ public class HandleSuperBuilder extends JavacAnnotationHandler<SuperBuilder> {
ListBuffer<JCExpression> typeArgs = new ListBuffer<JCExpression>();
for (JCTypeParameter typeParam : typeParams) typeArgs.append(maker.Ident(typeParam.name));
- JCExpression newClass = maker.NewClass(null, List.<JCExpression>nil(), namePlusTypeParamsToTypeReference(maker, type.toName(builderImplClassName), typeParams), List.<JCExpression>nil(), null);
+ JCExpression newClass = maker.NewClass(null, List.<JCExpression>nil(), namePlusTypeParamsToTypeReference(maker, type, type.toName(builderImplClassName), false, typeParams), List.<JCExpression>nil(), null);
List<JCExpression> methodArgs = List.<JCExpression>of(maker.Ident(type.toName("this")));
JCMethodInvocation invokeFillMethod = maker.Apply(List.<JCExpression>nil(), maker.Select(newClass, type.toName(FILL_VALUES_METHOD_NAME)), methodArgs);
JCStatement statement = maker.Return(invokeFillMethod);
@@ -609,7 +601,7 @@ public class HandleSuperBuilder extends JavacAnnotationHandler<SuperBuilder> {
JCWildcard wildcard = maker.Wildcard(maker.TypeBoundKind(BoundKind.UNBOUND), null);
typeParameterNames.add(wildcard);
typeParameterNames.add(wildcard);
- JCTypeApply returnType = maker.TypeApply(maker.Ident(type.toName(builderClassName)), typeParameterNames.toList());
+ JCTypeApply returnType = maker.TypeApply(namePlusTypeParamsToTypeReference(maker, type, type.toName(builderClassName), false, List.<JCTypeParameter>nil()), typeParameterNames.toList());
List<JCAnnotation> annsOnMethod = cfv.generateUnique() ? List.of(maker.Annotation(genTypeRef(type, CheckerFrameworkVersion.NAME__SIDE_EFFECT_FREE), List.<JCExpression>nil())) : List.<JCAnnotation>nil();
return maker.MethodDef(maker.Modifiers(modifiers, annsOnMethod), type.toName(TO_BUILDER_METHOD_NAME), returnType, List.<JCTypeParameter>nil(), List.<JCVariableDecl>nil(), List.<JCExpression>nil(), body, null);
@@ -651,8 +643,9 @@ public class HandleSuperBuilder extends JavacAnnotationHandler<SuperBuilder> {
}
// Call the builder implemention's helper method that actually fills the values from the instance.
+ JCExpression ref = namePlusTypeParamsToTypeReference(maker, type, type.toName(builderImplClassName), false, List.<JCTypeParameter>nil());
JCMethodInvocation callStaticFillValuesMethod = maker.Apply(List.<JCExpression>nil(),
- maker.Select(maker.Ident(type.toName(builderImplClassName)), type.toName(STATIC_FILL_VALUES_METHOD_NAME)),
+ maker.Select(ref, type.toName(STATIC_FILL_VALUES_METHOD_NAME)),
List.<JCExpression>of(maker.Ident(type.toName(INSTANCE_VARIABLE_NAME)), maker.Ident(type.toName("this"))));
body.append(maker.Exec(callStaticFillValuesMethod));
@@ -692,7 +685,7 @@ public class HandleSuperBuilder extends JavacAnnotationHandler<SuperBuilder> {
typeParamsForBuilderParameter.add(wildcard);
wildcard = maker.Wildcard(maker.TypeBoundKind(BoundKind.UNBOUND), null);
typeParamsForBuilderParameter.add(wildcard);
- JCTypeApply builderType = maker.TypeApply(maker.Ident(type.toName(builderClassname)), typeParamsForBuilderParameter.toList());
+ JCTypeApply builderType = maker.TypeApply(namePlusTypeParamsToTypeReference(maker, type, type.toName(builderClassname), false, List.<JCTypeParameter>nil()), typeParamsForBuilderParameter.toList());
JCVariableDecl paramBuilder = maker.VarDef(maker.Modifiers(Flags.LocalVarFlags), type.toName(BUILDER_VARIABLE_NAME), builderType, null);
ListBuffer<JCStatement> body = new ListBuffer<JCStatement>();
@@ -717,7 +710,8 @@ public class HandleSuperBuilder extends JavacAnnotationHandler<SuperBuilder> {
} else {
if (bfd.obtainVia.isStatic()) {
for (int i = 0; i < tgt.length; i++) {
- JCExpression c = maker.Select(maker.Ident(type.toName(type.getName())), type.toName(bfd.obtainVia.method()));
+ JCExpression typeRef = namePlusTypeParamsToTypeReference(maker, type, List.<JCTypeParameter>nil());
+ JCExpression c = maker.Select(typeRef, type.toName(bfd.obtainVia.method()));
tgt[i] = maker.Apply(List.<JCExpression>nil(), c, List.<JCExpression>of(maker.Ident(type.toName(INSTANCE_VARIABLE_NAME))));
}
} else {
@@ -772,7 +766,7 @@ public class HandleSuperBuilder extends JavacAnnotationHandler<SuperBuilder> {
JCModifiers modifiers = maker.Modifiers(Flags.PROTECTED, annsOnMethod);
Name name = builderImplType.toName(SELF_METHOD);
- JCExpression returnType = namePlusTypeParamsToTypeReference(maker, builderImplType.toName(builderImplType.getName()), typeParams);
+ JCExpression returnType = namePlusTypeParamsToTypeReference(maker, builderImplType.up(), builderImplType.toName(builderImplType.getName()), false, typeParams);
JCStatement statement = maker.Return(maker.Ident(builderImplType.toName("this")));
JCBlock body = maker.Block(0, List.<JCStatement>of(statement));
@@ -908,7 +902,8 @@ public class HandleSuperBuilder extends JavacAnnotationHandler<SuperBuilder> {
if (cfv.generateCalledMethods()) {
JCAnnotation ncAnno = maker.Annotation(genTypeRef(source, CheckerFrameworkVersion.NAME__NOT_CALLED), List.<JCExpression>of(maker.Literal(newMethod.getName().toString())));
JCClassDecl builderTypeNode = (JCClassDecl) builderType.get();
- JCVariableDecl recv = maker.VarDef(maker.Modifiers(0L, List.<JCAnnotation>of(ncAnno)), builderType.toName("this"), maker.Ident(builderTypeNode.name), null);
+ JCExpression selfType = namePlusTypeParamsToTypeReference(maker, builderType, builderTypeNode.typarams);
+ JCVariableDecl recv = maker.VarDef(maker.Modifiers(0L, List.<JCAnnotation>of(ncAnno)), builderType.toName("this"), selfType, null);
newMethod.params = List.of(recv, newMethod.params.get(0));
}
if (cfv.generateReturnsReceiver()) {
diff --git a/src/core/lombok/javac/handlers/JavacHandlerUtil.java b/src/core/lombok/javac/handlers/JavacHandlerUtil.java
index d12a980f..885d8ffb 100644
--- a/src/core/lombok/javac/handlers/JavacHandlerUtil.java
+++ b/src/core/lombok/javac/handlers/JavacHandlerUtil.java
@@ -622,20 +622,7 @@ public class JavacHandlerUtil {
JavacNode typeNode = childOfType;
JavacTreeMaker maker = childOfType.getTreeMaker();
while (typeNode != null && typeNode.getKind() != Kind.TYPE) typeNode = typeNode.up();
- if (typeNode != null && typeNode.get() instanceof JCClassDecl) {
- JCClassDecl type = (JCClassDecl) typeNode.get();
- ListBuffer<JCExpression> typeArgs = new ListBuffer<JCExpression>();
- if (!type.typarams.isEmpty()) {
- for (JCTypeParameter tp : type.typarams) {
- typeArgs.append(maker.Ident(tp.name));
- }
- return maker.TypeApply(maker.Ident(type.name), typeArgs.toList());
- } else {
- return maker.Ident(type.name);
- }
- } else {
- return null;
- }
+ return JavacHandlerUtil.namePlusTypeParamsToTypeReference(maker, typeNode, ((JCClassDecl) typeNode.get()).typarams);
}
public static boolean isBoolean(JavacNode field) {
@@ -1722,11 +1709,25 @@ public class JavacHandlerUtil {
return JCAnnotatedTypeReflect.getUnderlyingType(from);
}
- public static JCExpression namePlusTypeParamsToTypeReference(JavacTreeMaker maker, Name typeName, List<JCTypeParameter> params) {
- if (params.isEmpty()) {
- return maker.Ident(typeName);
+ public static JCExpression namePlusTypeParamsToTypeReference(JavacTreeMaker maker, JavacNode type, List<JCTypeParameter> params) {
+ JCClassDecl td = (JCClassDecl) type.get();
+ boolean instance = (td.mods.flags & Flags.STATIC) == 0;
+ return namePlusTypeParamsToTypeReference(maker, type.up(), td.name, instance, params);
+ }
+
+ public static JCExpression namePlusTypeParamsToTypeReference(JavacTreeMaker maker, JavacNode parentType, Name typeName, boolean instance, List<JCTypeParameter> params) {
+ JCExpression r = null;
+
+ if (parentType != null && parentType.getKind() == Kind.TYPE) {
+ JCClassDecl td = (JCClassDecl) parentType.get();
+ boolean outerInstance = instance && ((td.mods.flags & Flags.STATIC) == 0);
+ List<JCTypeParameter> outerParams = instance ? td.typarams : List.<JCTypeParameter>nil();
+ r = namePlusTypeParamsToTypeReference(maker, parentType.up(), td.name, outerInstance, outerParams);
}
- return maker.TypeApply(maker.Ident(typeName), typeParameterNames(maker, params));
+
+ r = r == null ? maker.Ident(typeName) : maker.Select(r, typeName);
+ if (!params.isEmpty()) r = maker.TypeApply(r, typeParameterNames(maker, params));
+ return r;
}
public static List<JCExpression> typeParameterNames(JavacTreeMaker maker, List<JCTypeParameter> params) {