From 3f00e7c90548cc00fca75ad1975a2ecc05521871 Mon Sep 17 00:00:00 2001 From: Roel Spilker Date: Thu, 11 Nov 2010 05:55:15 +0100 Subject: @Getter(lazy=true) now also works in Eclipse --- src/core/lombok/eclipse/handlers/HandleGetter.java | 246 ++++++++++++++++++++- .../after-delombok/GetterLazyEahcToString.java | 16 +- .../resource/after-delombok/GetterLazyInvalid.java | 9 +- .../resource/after-delombok/GetterLazyNative.java | 19 +- test/transform/resource/after-ecj/GetterLazy.java | 27 +++ .../resource/after-ecj/GetterLazyEahcToString.java | 53 +++++ .../resource/after-ecj/GetterLazyInvalid.java | 40 ++++ .../resource/after-ecj/GetterLazyNative.java | 158 +++++++++++++ .../resource/before/GetterLazyEahcToString.java | 2 + .../resource/before/GetterLazyInvalid.java | 11 +- .../resource/before/GetterLazyNative.java | 3 + .../GetterLazyInvalid.java.messages | 2 +- .../messages-ecj/GetterLazyInvalid.java.messages | 6 + 13 files changed, 570 insertions(+), 22 deletions(-) create mode 100644 test/transform/resource/after-ecj/GetterLazy.java create mode 100644 test/transform/resource/after-ecj/GetterLazyEahcToString.java create mode 100644 test/transform/resource/after-ecj/GetterLazyInvalid.java create mode 100644 test/transform/resource/after-ecj/GetterLazyNative.java create mode 100644 test/transform/resource/messages-ecj/GetterLazyInvalid.java.messages diff --git a/src/core/lombok/eclipse/handlers/HandleGetter.java b/src/core/lombok/eclipse/handlers/HandleGetter.java index e5ddbc3f..56d0ba6c 100644 --- a/src/core/lombok/eclipse/handlers/HandleGetter.java +++ b/src/core/lombok/eclipse/handlers/HandleGetter.java @@ -25,6 +25,9 @@ import static lombok.eclipse.Eclipse.*; import static lombok.eclipse.handlers.EclipseHandlerUtil.*; import java.util.Collection; +import java.util.Collections; +import java.util.HashMap; +import java.util.Map; import lombok.AccessLevel; import lombok.Getter; @@ -34,14 +37,30 @@ import lombok.core.handlers.TransformationsUtil; import lombok.eclipse.Eclipse; import lombok.eclipse.EclipseAnnotationHandler; import lombok.eclipse.EclipseNode; +import lombok.eclipse.handlers.EclipseHandlerUtil.FieldAccess; import org.eclipse.jdt.internal.compiler.ast.ASTNode; +import org.eclipse.jdt.internal.compiler.ast.AllocationExpression; import org.eclipse.jdt.internal.compiler.ast.Annotation; +import org.eclipse.jdt.internal.compiler.ast.ArrayTypeReference; +import org.eclipse.jdt.internal.compiler.ast.Assignment; +import org.eclipse.jdt.internal.compiler.ast.BinaryExpression; +import org.eclipse.jdt.internal.compiler.ast.Block; +import org.eclipse.jdt.internal.compiler.ast.EqualExpression; import org.eclipse.jdt.internal.compiler.ast.Expression; import org.eclipse.jdt.internal.compiler.ast.FieldDeclaration; +import org.eclipse.jdt.internal.compiler.ast.IfStatement; +import org.eclipse.jdt.internal.compiler.ast.LocalDeclaration; +import org.eclipse.jdt.internal.compiler.ast.MessageSend; import org.eclipse.jdt.internal.compiler.ast.MethodDeclaration; +import org.eclipse.jdt.internal.compiler.ast.NullLiteral; +import org.eclipse.jdt.internal.compiler.ast.ParameterizedQualifiedTypeReference; +import org.eclipse.jdt.internal.compiler.ast.QualifiedTypeReference; import org.eclipse.jdt.internal.compiler.ast.ReturnStatement; +import org.eclipse.jdt.internal.compiler.ast.SingleNameReference; +import org.eclipse.jdt.internal.compiler.ast.SingleTypeReference; import org.eclipse.jdt.internal.compiler.ast.Statement; +import org.eclipse.jdt.internal.compiler.ast.SynchronizedStatement; import org.eclipse.jdt.internal.compiler.ast.TypeDeclaration; import org.eclipse.jdt.internal.compiler.ast.TypeReference; import org.eclipse.jdt.internal.compiler.classfmt.ClassFileConstants; @@ -123,7 +142,7 @@ public class HandleGetter implements EclipseAnnotationHandler { boolean lazy = annotationInstance.lazy(); if (level == AccessLevel.NONE) { if (lazy) { - annotationNode.addWarning("'lazy' requires AccessLevel.PRIVATE or higher."); + annotationNode.addWarning("'lazy' does not work with AccessLevel.NONE."); } return true; } @@ -158,7 +177,7 @@ public class HandleGetter implements EclipseAnnotationHandler { FieldDeclaration field = (FieldDeclaration) fieldNode.get(); if (lazy) { - if ((field.modifiers & (ClassFileConstants.AccPrivate | ClassFileConstants.AccFinal)) != 0) { + if ((field.modifiers & ClassFileConstants.AccPrivate) == 0 || (field.modifiers & ClassFileConstants.AccFinal) == 0) { errorNode.addError("'lazy' requires the field to be private and final."); return true; } @@ -193,7 +212,7 @@ public class HandleGetter implements EclipseAnnotationHandler { } } - MethodDeclaration method = generateGetter((TypeDeclaration) fieldNode.up().get(), fieldNode, getterName, modifier, source); + MethodDeclaration method = generateGetter((TypeDeclaration) fieldNode.up().get(), fieldNode, getterName, modifier, source, lazy); Annotation[] copiedAnnotations = copyAnnotations(source, findAnnotations(field, TransformationsUtil.NON_NULL_PATTERN), findAnnotations(field, TransformationsUtil.NULLABLE_PATTERN), onMethod); if (copiedAnnotations.length != 0) { method.annotations = copiedAnnotations; @@ -204,12 +223,22 @@ public class HandleGetter implements EclipseAnnotationHandler { return true; } - private MethodDeclaration generateGetter(TypeDeclaration parent, EclipseNode fieldNode, String name, int modifier, ASTNode source) { - FieldDeclaration field = (FieldDeclaration) fieldNode.get(); + private MethodDeclaration generateGetter(TypeDeclaration parent, EclipseNode fieldNode, String name, int modifier, ASTNode source, boolean lazy) { + + // Remember the type; lazy will change it; + TypeReference returnType = copyType(((FieldDeclaration) fieldNode.get()).type, source); + + Statement[] statements; + if (lazy) { + statements = createLazyGetterBody(source, fieldNode); + } else { + statements = createSimpleGetterBody(source, fieldNode); + } + MethodDeclaration method = new MethodDeclaration(parent.compilationResult); Eclipse.setGeneratedBy(method, source); method.modifiers = modifier; - method.returnType = copyType(field.type, source); + method.returnType = returnType; method.annotations = null; method.arguments = null; method.selector = name.toCharArray(); @@ -217,12 +246,209 @@ public class HandleGetter implements EclipseAnnotationHandler { method.thrownExceptions = null; method.typeParameters = null; method.bits |= ECLIPSE_DO_NOT_TOUCH_FLAG; - Expression fieldRef = createFieldAccessor(fieldNode, FieldAccess.ALWAYS_FIELD, source); - Statement returnStatement = new ReturnStatement(fieldRef, field.sourceStart, field.sourceEnd); - Eclipse.setGeneratedBy(returnStatement, source); method.bodyStart = method.declarationSourceStart = method.sourceStart = source.sourceStart; method.bodyEnd = method.declarationSourceEnd = method.sourceEnd = source.sourceEnd; - method.statements = new Statement[] { returnStatement }; + method.statements = statements; return method; } + + private Statement[] createSimpleGetterBody(ASTNode source, EclipseNode fieldNode) { + FieldDeclaration field = (FieldDeclaration) fieldNode.get(); + Expression fieldRef = createFieldAccessor(fieldNode, FieldAccess.ALWAYS_FIELD, source); + Statement returnStatement = new ReturnStatement(fieldRef, field.sourceStart, field.sourceEnd); + Eclipse.setGeneratedBy(returnStatement, source); + return new Statement[] {returnStatement}; + } + + private static final char[][] AR = fromQualifiedName("java.util.concurrent.atomic.AtomicReference"); + private static final TypeReference[][] AR_PARAMS = new TypeReference[5][]; + + private static final java.util.Map TYPE_MAP; + static { + Map m = new HashMap(); + m.put("int", fromQualifiedName("java.lang.Integer")); + m.put("double", fromQualifiedName("java.lang.Double")); + m.put("float", fromQualifiedName("java.lang.Float")); + m.put("short", fromQualifiedName("java.lang.Short")); + m.put("byte", fromQualifiedName("java.lang.Byte")); + m.put("long", fromQualifiedName("java.lang.Long")); + m.put("boolean", fromQualifiedName("java.lang.Boolean")); + m.put("char", fromQualifiedName("java.lang.Character")); + TYPE_MAP = Collections.unmodifiableMap(m); + } + + private static char[] valueName = "value".toCharArray(); + + private Statement[] createLazyGetterBody(ASTNode source, EclipseNode fieldNode) { + /* + java.util.concurrent.atomic.AtomicReference value = this.fieldName.get(); + if (value == null) { + synchronized (this.fieldName) { + value = this.fieldName.get(); + if (value == null) { + value = new java.util.concurrent.atomic.AtomicReference(new ValueType()); + this.fieldName.set(value); + } + } + } + return value.get(); + */ + + FieldDeclaration field = (FieldDeclaration) fieldNode.get(); + int pS = source.sourceStart, pE = source.sourceEnd; + long p = (long)pS << 32 | pE; + + TypeReference componentType = copyType(field.type, source); + if (field.type instanceof SingleTypeReference && !(field.type instanceof ArrayTypeReference)) { + char[][] newType = TYPE_MAP.get(new String(((SingleTypeReference)field.type).token)); + if (newType != null) { + componentType = new QualifiedTypeReference(newType, poss(source, 3)); + Eclipse.setGeneratedBy(componentType, source); + } + } + + Statement[] statements = new Statement[3]; + + /* java.util.concurrent.atomic.AtomicReference value = this.fieldName.get(); */ { + LocalDeclaration valueDecl = new LocalDeclaration(valueName, pS, pE); + Eclipse.setGeneratedBy(valueDecl, source); + TypeReference[][] typeParams = AR_PARAMS.clone(); + typeParams[4] = new TypeReference[] {copyType(componentType, source)}; + valueDecl.type = new ParameterizedQualifiedTypeReference(AR, typeParams, 0, poss(source, 5)); + valueDecl.type.sourceStart = pS; valueDecl.type.sourceEnd = pE; + Eclipse.setGeneratedBy(valueDecl.type, source); + + MessageSend getter = new MessageSend(); + Eclipse.setGeneratedBy(getter, source); + getter.sourceStart = pS; getter.sourceEnd = pE; + getter.selector = new char[] {'g', 'e', 't'}; + getter.receiver = EclipseHandlerUtil.createFieldAccessor(fieldNode, FieldAccess.ALWAYS_FIELD, source); + + valueDecl.initialization = getter; + Eclipse.setGeneratedBy(valueDecl.initialization, source); + statements[0] = valueDecl; + } + + /* + if (value == null) { + synchronized (this.fieldName) { + value = this.fieldName.get(); + if (value == null) { + value = new java.util.concurrent.atomic.AtomicReference(new ValueType()); + this.fieldName.set(value); + } + } + } + */ { + EqualExpression cond = new EqualExpression( + new SingleNameReference(valueName, p), new NullLiteral(pS, pE), + BinaryExpression.EQUAL_EQUAL); + Eclipse.setGeneratedBy(cond.left, source); + Eclipse.setGeneratedBy(cond.right, source); + Eclipse.setGeneratedBy(cond, source); + Block then = new Block(0); + Eclipse.setGeneratedBy(then, source); + Expression lock = EclipseHandlerUtil.createFieldAccessor(fieldNode, FieldAccess.ALWAYS_FIELD, source); + Block inner = new Block(0); + Eclipse.setGeneratedBy(inner, source); + inner.statements = new Statement[2]; + /* value = this.fieldName.get(); */ { + MessageSend getter = new MessageSend(); + Eclipse.setGeneratedBy(getter, source); + getter.sourceStart = pS; getter.sourceEnd = pE; + getter.selector = new char[] {'g', 'e', 't'}; + getter.receiver = EclipseHandlerUtil.createFieldAccessor(fieldNode, FieldAccess.ALWAYS_FIELD, source); + Assignment assign = new Assignment(new SingleNameReference(valueName, p), getter, pE); + Eclipse.setGeneratedBy(assign, source); + Eclipse.setGeneratedBy(assign.lhs, source); + inner.statements[0] = assign; + } + /* if (value == null) */ { + EqualExpression innerCond = new EqualExpression( + new SingleNameReference(valueName, p), new NullLiteral(pS, pE), + BinaryExpression.EQUAL_EQUAL); + Eclipse.setGeneratedBy(innerCond.left, source); + Eclipse.setGeneratedBy(innerCond.right, source); + Eclipse.setGeneratedBy(innerCond, source); + Block innerThen = new Block(0); + Eclipse.setGeneratedBy(innerThen, source); + innerThen.statements = new Statement[2]; + /*value = new java.util.concurrent.atomic.AtomicReference(new ValueType()); */ { + AllocationExpression create = new AllocationExpression(); + Eclipse.setGeneratedBy(create, source); + create.sourceStart = pS; create.sourceEnd = pE; + TypeReference[][] typeParams = AR_PARAMS.clone(); + typeParams[4] = new TypeReference[] {copyType(componentType, source)}; + create.type = new ParameterizedQualifiedTypeReference(AR, typeParams, 0, poss(source, 5)); + create.type.sourceStart = pS; create.type.sourceEnd = pE; + Eclipse.setGeneratedBy(create.type, source); + create.arguments = new Expression[] {field.initialization}; + Assignment innerAssign = new Assignment(new SingleNameReference(valueName, p), create, pE); + Eclipse.setGeneratedBy(innerAssign, source); + Eclipse.setGeneratedBy(innerAssign.lhs, source); + innerThen.statements[0] = innerAssign; + } + + /*this.fieldName.set(value);*/ { + MessageSend setter = new MessageSend(); + Eclipse.setGeneratedBy(setter, source); + setter.sourceStart = pS; setter.sourceEnd = pE; + setter.receiver = EclipseHandlerUtil.createFieldAccessor(fieldNode, FieldAccess.ALWAYS_FIELD, source); + setter.selector = new char[] { 's', 'e', 't' }; + setter.arguments = new Expression[] { + new SingleNameReference(valueName, p)}; + Eclipse.setGeneratedBy(setter.arguments[0], source); + innerThen.statements[1] = setter; + } + + IfStatement innerIf = new IfStatement(innerCond, innerThen, pS, pE); + Eclipse.setGeneratedBy(innerIf, source); + inner.statements[1] = innerIf; + } + + SynchronizedStatement sync = new SynchronizedStatement(lock, inner, pS, pE); + Eclipse.setGeneratedBy(sync, source); + then.statements = new Statement[] {sync}; + + IfStatement ifStatement = new IfStatement(cond, then, pS, pE); + Eclipse.setGeneratedBy(ifStatement, source); + statements[1] = ifStatement; + } + + /* return value.get(); */ { + MessageSend getter = new MessageSend(); + Eclipse.setGeneratedBy(getter, source); + getter.sourceStart = pS; getter.sourceEnd = pE; + getter.selector = new char[] {'g', 'e', 't'}; + getter.receiver = new SingleNameReference(valueName, p); + Eclipse.setGeneratedBy(getter.receiver, source); + + statements[2] = new ReturnStatement(getter, pS, pE); + Eclipse.setGeneratedBy(statements[2], source); + } + + + // update the field type and init last + + /* private final java.util.concurrent.atomic.AtomicReference fieldName = new java.util.concurrent.atomic.AtomicReference>(); */ { + + LocalDeclaration first = (LocalDeclaration) statements[0]; + TypeReference innerType = copyType(first.type, source); + + TypeReference[][] typeParams = AR_PARAMS.clone(); + typeParams[4] = new TypeReference[] {copyType(innerType, source)}; + TypeReference type = new ParameterizedQualifiedTypeReference(AR, typeParams, 0, poss(source, 5)); + // Some magic here + type.sourceStart = -1; type.sourceEnd = -2; + Eclipse.setGeneratedBy(type, source); + + field.type = type; + AllocationExpression init = new AllocationExpression(); + // Some magic here + init.sourceStart = field.initialization.sourceStart; init.sourceEnd = field.initialization.sourceEnd; + init.type = copyType(type, source); + field.initialization = init; + } + return statements; + } } diff --git a/test/transform/resource/after-delombok/GetterLazyEahcToString.java b/test/transform/resource/after-delombok/GetterLazyEahcToString.java index 7d37e46b..f085722d 100644 --- a/test/transform/resource/after-delombok/GetterLazyEahcToString.java +++ b/test/transform/resource/after-delombok/GetterLazyEahcToString.java @@ -1,5 +1,8 @@ class GetterLazyEahcToString { + private final java.util.concurrent.atomic.AtomicReference> value = new java.util.concurrent.atomic.AtomicReference>(); + private final String value2 = ""; + @java.lang.Override @java.lang.SuppressWarnings("all") public boolean equals(final java.lang.Object o) { @@ -8,25 +11,31 @@ class GetterLazyEahcToString { final GetterLazyEahcToString other = (GetterLazyEahcToString)o; if (!other.canEqual(this)) return false; if (this.getValue() == null ? other.getValue() != null : !this.getValue().equals(other.getValue())) return false; + if (this.value2 == null ? other.value2 != null : !this.value2.equals(other.value2)) return false; return true; } + @java.lang.SuppressWarnings("all") public boolean canEqual(final java.lang.Object other) { return other instanceof GetterLazyEahcToString; } + @java.lang.Override @java.lang.SuppressWarnings("all") public int hashCode() { final int PRIME = 31; int result = 1; result = result * PRIME + (this.getValue() == null ? 0 : this.getValue().hashCode()); + result = result * PRIME + (this.value2 == null ? 0 : this.value2.hashCode()); return result; } + @java.lang.Override @java.lang.SuppressWarnings("all") public java.lang.String toString() { - return "GetterLazyEahcToString(value=" + this.getValue() + ")"; + return "GetterLazyEahcToString(value=" + this.getValue() + ", value2=" + this.value2 + ")"; } + @java.lang.SuppressWarnings("all") public String getValue() { java.util.concurrent.atomic.AtomicReference value = this.value.get(); @@ -41,4 +50,9 @@ class GetterLazyEahcToString { } return value.get(); } + + @java.lang.SuppressWarnings("all") + public String getValue2() { + return this.value2; + } } \ No newline at end of file diff --git a/test/transform/resource/after-delombok/GetterLazyInvalid.java b/test/transform/resource/after-delombok/GetterLazyInvalid.java index 78cb7c2d..25963921 100644 --- a/test/transform/resource/after-delombok/GetterLazyInvalid.java +++ b/test/transform/resource/after-delombok/GetterLazyInvalid.java @@ -8,15 +8,18 @@ class GetterLazyInvalidNotPrivateFinal { String fieldName = ""; } class GetterLazyInvalidNone { - String fieldName = ""; + private final String fieldName = ""; } class GetterLazyInvalidClass { - String fieldName = ""; + private final String fieldName = ""; @java.lang.SuppressWarnings("all") public String getFieldName() { return this.fieldName; } } class GetterLazyInvalidNoInit { - String fieldName; + private final String fieldName; + GetterLazyInvalidNoInit() { + this.fieldName = "foo"; + } } \ No newline at end of file diff --git a/test/transform/resource/after-delombok/GetterLazyNative.java b/test/transform/resource/after-delombok/GetterLazyNative.java index ffa0824b..650d0496 100644 --- a/test/transform/resource/after-delombok/GetterLazyNative.java +++ b/test/transform/resource/after-delombok/GetterLazyNative.java @@ -1,5 +1,4 @@ class GetterLazyNative { - private final java.util.concurrent.atomic.AtomicReference> booleanField = new java.util.concurrent.atomic.AtomicReference>(); private final java.util.concurrent.atomic.AtomicReference> byteField = new java.util.concurrent.atomic.AtomicReference>(); private final java.util.concurrent.atomic.AtomicReference> shortField = new java.util.concurrent.atomic.AtomicReference>(); @@ -8,7 +7,7 @@ class GetterLazyNative { private final java.util.concurrent.atomic.AtomicReference> floatField = new java.util.concurrent.atomic.AtomicReference>(); private final java.util.concurrent.atomic.AtomicReference> doubleField = new java.util.concurrent.atomic.AtomicReference>(); private final java.util.concurrent.atomic.AtomicReference> charField = new java.util.concurrent.atomic.AtomicReference>(); - + private final java.util.concurrent.atomic.AtomicReference> intArrayField = new java.util.concurrent.atomic.AtomicReference>(); @java.lang.SuppressWarnings("all") public boolean getBooleanField() { java.util.concurrent.atomic.AtomicReference value = this.booleanField.get(); @@ -121,4 +120,18 @@ class GetterLazyNative { } return value.get(); } -} + @java.lang.SuppressWarnings("all") + public int[] getIntArrayField() { + java.util.concurrent.atomic.AtomicReference value = this.intArrayField.get(); + if (value == null) { + synchronized (this.intArrayField) { + value = this.intArrayField.get(); + if (value == null) { + value = new java.util.concurrent.atomic.AtomicReference(new int[]{1}); + this.intArrayField.set(value); + } + } + } + return value.get(); + } +} \ No newline at end of file diff --git a/test/transform/resource/after-ecj/GetterLazy.java b/test/transform/resource/after-ecj/GetterLazy.java new file mode 100644 index 00000000..669a9a81 --- /dev/null +++ b/test/transform/resource/after-ecj/GetterLazy.java @@ -0,0 +1,27 @@ +class GetterLazy { + static class ValueType { + ValueType() { + super(); + } + } + private final @lombok.Getter(lazy = true) java.util.concurrent.atomic.AtomicReference> fieldName = new java.util.concurrent.atomic.AtomicReference>(); + public @java.lang.SuppressWarnings("all") ValueType getFieldName() { + java.util.concurrent.atomic.AtomicReference value = this.fieldName.get(); + if ((value == null)) + { + synchronized (this.fieldName) + { + value = this.fieldName.get(); + if ((value == null)) + { + value = new java.util.concurrent.atomic.AtomicReference(new ValueType()); + this.fieldName.set(value); + } + } + } + return value.get(); + } + GetterLazy() { + super(); + } +} diff --git a/test/transform/resource/after-ecj/GetterLazyEahcToString.java b/test/transform/resource/after-ecj/GetterLazyEahcToString.java new file mode 100644 index 00000000..6261ce38 --- /dev/null +++ b/test/transform/resource/after-ecj/GetterLazyEahcToString.java @@ -0,0 +1,53 @@ +@lombok.EqualsAndHashCode(doNotUseGetters = true) @lombok.ToString(doNotUseGetters = true) class GetterLazyEahcToString { + private final @lombok.Getter(lazy = true) java.util.concurrent.atomic.AtomicReference> value = new java.util.concurrent.atomic.AtomicReference>(); + private final @lombok.Getter String value2 = ""; + public @java.lang.SuppressWarnings("all") String getValue() { + java.util.concurrent.atomic.AtomicReference value = this.value.get(); + if ((value == null)) + { + synchronized (this.value) + { + value = this.value.get(); + if ((value == null)) + { + value = new java.util.concurrent.atomic.AtomicReference(""); + this.value.set(value); + } + } + } + return value.get(); + } + public @java.lang.SuppressWarnings("all") String getValue2() { + return this.value2; + } + public @java.lang.Override @java.lang.SuppressWarnings("all") boolean equals(final java.lang.Object o) { + if ((o == this)) + return true; + if ((! (o instanceof GetterLazyEahcToString))) + return false; + final GetterLazyEahcToString other = (GetterLazyEahcToString) o; + if ((! other.canEqual(this))) + return false; + if (((this.getValue() == null) ? (other.getValue() != null) : (! this.getValue().equals(other.getValue())))) + return false; + if (((this.value2 == null) ? (other.value2 != null) : (! this.value2.equals(other.value2)))) + return false; + return true; + } + public @java.lang.SuppressWarnings("all") boolean canEqual(final java.lang.Object other) { + return (other instanceof GetterLazyEahcToString); + } + public @java.lang.Override @java.lang.SuppressWarnings("all") int hashCode() { + final int PRIME = 31; + int result = 1; + result = ((result * PRIME) + ((this.getValue() == null) ? 0 : this.getValue().hashCode())); + result = ((result * PRIME) + ((this.value2 == null) ? 0 : this.value2.hashCode())); + return result; + } + public @java.lang.Override @java.lang.SuppressWarnings("all") java.lang.String toString() { + return (((("GetterLazyEahcToString(value=" + this.getValue()) + ", value2=") + this.value2) + ")"); + } + GetterLazyEahcToString() { + super(); + } +} \ No newline at end of file diff --git a/test/transform/resource/after-ecj/GetterLazyInvalid.java b/test/transform/resource/after-ecj/GetterLazyInvalid.java new file mode 100644 index 00000000..eaa22d71 --- /dev/null +++ b/test/transform/resource/after-ecj/GetterLazyInvalid.java @@ -0,0 +1,40 @@ +class GetterLazyInvalidNotFinal { + private @lombok.Getter(lazy = true) String fieldName = ""; + GetterLazyInvalidNotFinal() { + super(); + } +} +class GetterLazyInvalidNotPrivate { + final @lombok.Getter(lazy = true) String fieldName = ""; + GetterLazyInvalidNotPrivate() { + super(); + } +} +class GetterLazyInvalidNotPrivateFinal { + @lombok.Getter(lazy = true) String fieldName = ""; + GetterLazyInvalidNotPrivateFinal() { + super(); + } +} +class GetterLazyInvalidNone { + private final @lombok.Getter(lazy = true,value = lombok.AccessLevel.NONE) String fieldName = ""; + GetterLazyInvalidNone() { + super(); + } +} +@lombok.Getter(lazy = true) class GetterLazyInvalidClass { + private final String fieldName = ""; + public @java.lang.SuppressWarnings("all") String getFieldName() { + return this.fieldName; + } + GetterLazyInvalidClass() { + super(); + } +} +class GetterLazyInvalidNoInit { + private final @lombok.Getter(lazy = true) String fieldName; + GetterLazyInvalidNoInit() { + super(); + this.fieldName = "foo"; + } +} \ No newline at end of file diff --git a/test/transform/resource/after-ecj/GetterLazyNative.java b/test/transform/resource/after-ecj/GetterLazyNative.java new file mode 100644 index 00000000..6c90a101 --- /dev/null +++ b/test/transform/resource/after-ecj/GetterLazyNative.java @@ -0,0 +1,158 @@ +class GetterLazyNative { + private final @lombok.Getter(lazy = true) java.util.concurrent.atomic.AtomicReference> booleanField = new java.util.concurrent.atomic.AtomicReference>(); + private final @lombok.Getter(lazy = true) java.util.concurrent.atomic.AtomicReference> byteField = new java.util.concurrent.atomic.AtomicReference>(); + private final @lombok.Getter(lazy = true) java.util.concurrent.atomic.AtomicReference> shortField = new java.util.concurrent.atomic.AtomicReference>(); + private final @lombok.Getter(lazy = true) java.util.concurrent.atomic.AtomicReference> intField = new java.util.concurrent.atomic.AtomicReference>(); + private final @lombok.Getter(lazy = true) java.util.concurrent.atomic.AtomicReference> longField = new java.util.concurrent.atomic.AtomicReference>(); + private final @lombok.Getter(lazy = true) java.util.concurrent.atomic.AtomicReference> floatField = new java.util.concurrent.atomic.AtomicReference>(); + private final @lombok.Getter(lazy = true) java.util.concurrent.atomic.AtomicReference> doubleField = new java.util.concurrent.atomic.AtomicReference>(); + private final @lombok.Getter(lazy = true) java.util.concurrent.atomic.AtomicReference> charField = new java.util.concurrent.atomic.AtomicReference>(); + private final @lombok.Getter(lazy = true) java.util.concurrent.atomic.AtomicReference> intArrayField = new java.util.concurrent.atomic.AtomicReference>(); + public @java.lang.SuppressWarnings("all") boolean isBooleanField() { + java.util.concurrent.atomic.AtomicReference value = this.booleanField.get(); + if ((value == null)) + { + synchronized (this.booleanField) + { + value = this.booleanField.get(); + if ((value == null)) + { + value = new java.util.concurrent.atomic.AtomicReference(true); + this.booleanField.set(value); + } + } + } + return value.get(); + } + public @java.lang.SuppressWarnings("all") byte getByteField() { + java.util.concurrent.atomic.AtomicReference value = this.byteField.get(); + if ((value == null)) + { + synchronized (this.byteField) + { + value = this.byteField.get(); + if ((value == null)) + { + value = new java.util.concurrent.atomic.AtomicReference(1); + this.byteField.set(value); + } + } + } + return value.get(); + } + public @java.lang.SuppressWarnings("all") short getShortField() { + java.util.concurrent.atomic.AtomicReference value = this.shortField.get(); + if ((value == null)) + { + synchronized (this.shortField) + { + value = this.shortField.get(); + if ((value == null)) + { + value = new java.util.concurrent.atomic.AtomicReference(1); + this.shortField.set(value); + } + } + } + return value.get(); + } + public @java.lang.SuppressWarnings("all") int getIntField() { + java.util.concurrent.atomic.AtomicReference value = this.intField.get(); + if ((value == null)) + { + synchronized (this.intField) + { + value = this.intField.get(); + if ((value == null)) + { + value = new java.util.concurrent.atomic.AtomicReference(1); + this.intField.set(value); + } + } + } + return value.get(); + } + public @java.lang.SuppressWarnings("all") long getLongField() { + java.util.concurrent.atomic.AtomicReference value = this.longField.get(); + if ((value == null)) + { + synchronized (this.longField) + { + value = this.longField.get(); + if ((value == null)) + { + value = new java.util.concurrent.atomic.AtomicReference(1); + this.longField.set(value); + } + } + } + return value.get(); + } + public @java.lang.SuppressWarnings("all") float getFloatField() { + java.util.concurrent.atomic.AtomicReference value = this.floatField.get(); + if ((value == null)) + { + synchronized (this.floatField) + { + value = this.floatField.get(); + if ((value == null)) + { + value = new java.util.concurrent.atomic.AtomicReference(1.0f); + this.floatField.set(value); + } + } + } + return value.get(); + } + public @java.lang.SuppressWarnings("all") double getDoubleField() { + java.util.concurrent.atomic.AtomicReference value = this.doubleField.get(); + if ((value == null)) + { + synchronized (this.doubleField) + { + value = this.doubleField.get(); + if ((value == null)) + { + value = new java.util.concurrent.atomic.AtomicReference(1.0); + this.doubleField.set(value); + } + } + } + return value.get(); + } + public @java.lang.SuppressWarnings("all") char getCharField() { + java.util.concurrent.atomic.AtomicReference value = this.charField.get(); + if ((value == null)) + { + synchronized (this.charField) + { + value = this.charField.get(); + if ((value == null)) + { + value = new java.util.concurrent.atomic.AtomicReference('1'); + this.charField.set(value); + } + } + } + return value.get(); + } + public @java.lang.SuppressWarnings("all") int[] getIntArrayField() { + java.util.concurrent.atomic.AtomicReference value = this.intArrayField.get(); + if ((value == null)) + { + synchronized (this.intArrayField) + { + value = this.intArrayField.get(); + if ((value == null)) + { + value = new java.util.concurrent.atomic.AtomicReference(new int[]{1}); + this.intArrayField.set(value); + } + } + } + return value.get(); + } + GetterLazyNative() { + super(); + } +} \ No newline at end of file diff --git a/test/transform/resource/before/GetterLazyEahcToString.java b/test/transform/resource/before/GetterLazyEahcToString.java index 60509257..642f8deb 100644 --- a/test/transform/resource/before/GetterLazyEahcToString.java +++ b/test/transform/resource/before/GetterLazyEahcToString.java @@ -3,4 +3,6 @@ class GetterLazyEahcToString { @lombok.Getter(lazy=true) private final String value = ""; + @lombok.Getter + private final String value2 = ""; } diff --git a/test/transform/resource/before/GetterLazyInvalid.java b/test/transform/resource/before/GetterLazyInvalid.java index ead12443..cc9f9501 100644 --- a/test/transform/resource/before/GetterLazyInvalid.java +++ b/test/transform/resource/before/GetterLazyInvalid.java @@ -12,13 +12,16 @@ class GetterLazyInvalidNotPrivateFinal { } class GetterLazyInvalidNone { @lombok.Getter(lazy=true, value=lombok.AccessLevel.NONE) - String fieldName = ""; + private final String fieldName = ""; } @lombok.Getter(lazy = true) class GetterLazyInvalidClass { - String fieldName = ""; + private final String fieldName = ""; } class GetterLazyInvalidNoInit { @lombok.Getter(lazy = true) - String fieldName; -} + private final String fieldName; + GetterLazyInvalidNoInit() { + this.fieldName = "foo"; + } +} \ No newline at end of file diff --git a/test/transform/resource/before/GetterLazyNative.java b/test/transform/resource/before/GetterLazyNative.java index bd14cbd7..9b290bc7 100644 --- a/test/transform/resource/before/GetterLazyNative.java +++ b/test/transform/resource/before/GetterLazyNative.java @@ -22,4 +22,7 @@ class GetterLazyNative { @lombok.Getter(lazy=true) private final char charField = '1'; + + @lombok.Getter(lazy=true) + private final int[] intArrayField = new int[] {1}; } diff --git a/test/transform/resource/messages-delombok/GetterLazyInvalid.java.messages b/test/transform/resource/messages-delombok/GetterLazyInvalid.java.messages index b53b8550..4f7e3df8 100644 --- a/test/transform/resource/messages-delombok/GetterLazyInvalid.java.messages +++ b/test/transform/resource/messages-delombok/GetterLazyInvalid.java.messages @@ -3,4 +3,4 @@ 10:9 ERROR 'lazy' requires the field to be private and final. 14:9 WARNING 'lazy' does not work with AccessLevel.NONE. 17:1 ERROR 'lazy' is not supported for @Getter on a type. -22:9 ERROR 'lazy' requires the field to be private and final. \ No newline at end of file +22:9 ERROR 'lazy' requires field initialization. \ No newline at end of file diff --git a/test/transform/resource/messages-ecj/GetterLazyInvalid.java.messages b/test/transform/resource/messages-ecj/GetterLazyInvalid.java.messages new file mode 100644 index 00000000..25641930 --- /dev/null +++ b/test/transform/resource/messages-ecj/GetterLazyInvalid.java.messages @@ -0,0 +1,6 @@ +2 error 'lazy' requires the field to be private and final. +6 error 'lazy' requires the field to be private and final. +10 error 'lazy' requires the field to be private and final. +14 warning 'lazy' does not work with AccessLevel.NONE. +17 error 'lazy' is not supported for @Getter on a type. +22 error 'lazy' requires field initialization. -- cgit