From b439e4ce771813a12300c3006f9fcc12f25678d7 Mon Sep 17 00:00:00 2001 From: Reinier Zwitserloot Date: Tue, 16 Jul 2019 01:24:18 +0200 Subject: [Fixes #2115] builder fields tracking a property that has a default set is now called `$value` in order to convey that you shouldnt manually mess with it. --- src/core/lombok/javac/handlers/HandleBuilder.java | 24 ++++++++------ .../lombok/javac/handlers/HandleConstructor.java | 2 +- src/core/lombok/javac/handlers/HandleSetter.java | 17 +++++----- .../lombok/javac/handlers/HandleSuperBuilder.java | 19 ++++++----- .../lombok/javac/handlers/JavacHandlerUtil.java | 38 +++++++++++++--------- 5 files changed, 56 insertions(+), 44 deletions(-) (limited to 'src/core/lombok/javac') diff --git a/src/core/lombok/javac/handlers/HandleBuilder.java b/src/core/lombok/javac/handlers/HandleBuilder.java index b339c2ca..35a6dc26 100644 --- a/src/core/lombok/javac/handlers/HandleBuilder.java +++ b/src/core/lombok/javac/handlers/HandleBuilder.java @@ -89,6 +89,7 @@ public class HandleBuilder extends JavacAnnotationHandler { JCExpression type; Name rawName; Name name; + Name builderFieldName; Name nameOfDefaultProvider; Name nameOfSetFlag; SingularData singularData; @@ -174,6 +175,7 @@ public class HandleBuilder extends JavacAnnotationHandler { BuilderFieldData bfd = new BuilderFieldData(); bfd.rawName = fd.name; bfd.name = removePrefixFromField(fieldNode); + bfd.builderFieldName = bfd.name; bfd.annotations = findCopyableAnnotations(fieldNode); bfd.type = fd.vartype; bfd.singularData = getSingularData(fieldNode); @@ -200,6 +202,7 @@ public class HandleBuilder extends JavacAnnotationHandler { if (isDefault != null) { bfd.nameOfDefaultProvider = parent.toName("$default$" + bfd.name); bfd.nameOfSetFlag = parent.toName(bfd.name + "$set"); + bfd.builderFieldName = parent.toName(bfd.name + "$value"); JCMethodDecl md = generateDefaultProvider(bfd.nameOfDefaultProvider, fieldNode, td.typarams); recursiveSetGeneratedBy(md, ast, annotationNode.getContext()); if (md != null) injectMethod(tdParent, md); @@ -360,6 +363,7 @@ public class HandleBuilder extends JavacAnnotationHandler { JCVariableDecl raw = (JCVariableDecl) param.get(); bfd.name = raw.name; + bfd.builderFieldName = bfd.name; bfd.rawName = raw.name; bfd.annotations = findCopyableAnnotations(param); bfd.type = raw.vartype; @@ -628,17 +632,17 @@ public class HandleBuilder extends JavacAnnotationHandler { for (BuilderFieldData bfd : builderFields) { if (bfd.singularData != null && bfd.singularData.getSingularizer() != null) { - bfd.singularData.getSingularizer().appendBuildCode(bfd.singularData, type, source, statements, bfd.name, "this"); + bfd.singularData.getSingularizer().appendBuildCode(bfd.singularData, type, source, statements, bfd.builderFieldName, "this"); } } ListBuffer args = new ListBuffer(); for (BuilderFieldData bfd : builderFields) { if (bfd.nameOfSetFlag != null) { - statements.append(maker.VarDef(maker.Modifiers(0L), bfd.name, cloneType(maker, bfd.type, source, tdParent.getContext()), maker.Select(maker.Ident(type.toName("this")), bfd.name))); - statements.append(maker.If(maker.Unary(CTC_NOT, maker.Ident(bfd.nameOfSetFlag)), maker.Exec(maker.Assign(maker.Ident(bfd.name),maker.Apply(typeParameterNames(maker, ((JCClassDecl) tdParent.get()).typarams), maker.Select(maker.Ident(((JCClassDecl) tdParent.get()).name), bfd.nameOfDefaultProvider), List.nil()))), null)); + statements.append(maker.VarDef(maker.Modifiers(0L), bfd.builderFieldName, cloneType(maker, bfd.type, source, tdParent.getContext()), maker.Select(maker.Ident(type.toName("this")), bfd.builderFieldName))); + statements.append(maker.If(maker.Unary(CTC_NOT, maker.Ident(bfd.nameOfSetFlag)), maker.Exec(maker.Assign(maker.Ident(bfd.builderFieldName), maker.Apply(typeParameterNames(maker, ((JCClassDecl) tdParent.get()).typarams), maker.Select(maker.Ident(((JCClassDecl) tdParent.get()).name), bfd.nameOfDefaultProvider), List.nil()))), null)); } - args.append(maker.Ident(bfd.name)); + args.append(maker.Ident(bfd.builderFieldName)); } if (addCleaning) { @@ -715,13 +719,13 @@ public class HandleBuilder extends JavacAnnotationHandler { JavacNode field = null, setFlag = null; for (JavacNode exists : existing) { Name n = ((JCVariableDecl) exists.get()).name; - if (n.equals(bfd.name)) field = exists; + if (n.equals(bfd.builderFieldName)) field = exists; if (n.equals(bfd.nameOfSetFlag)) setFlag = exists; } JavacTreeMaker maker = builderType.getTreeMaker(); if (field == null) { JCModifiers mods = maker.Modifiers(Flags.PRIVATE); - JCVariableDecl newField = maker.VarDef(mods, bfd.name, cloneType(maker, bfd.type, source, builderType.getContext()), null); + JCVariableDecl newField = maker.VarDef(mods, bfd.builderFieldName, cloneType(maker, bfd.type, source, builderType.getContext()), null); field = injectFieldAndMarkGenerated(builderType, newField); generated.add(newField); } @@ -740,13 +744,13 @@ public class HandleBuilder extends JavacAnnotationHandler { public void makeSetterMethodsForBuilder(JavacNode builderType, BuilderFieldData fieldNode, JavacNode source, boolean fluent, boolean chain, AccessLevel access) { boolean deprecate = isFieldDeprecated(fieldNode.originalFieldNode); if (fieldNode.singularData == null || fieldNode.singularData.getSingularizer() == null) { - makeSimpleSetterMethodForBuilder(builderType, deprecate, fieldNode.createdFields.get(0), fieldNode.nameOfSetFlag, source, fluent, chain, fieldNode.annotations, fieldNode.originalFieldNode, access); + makeSimpleSetterMethodForBuilder(builderType, deprecate, fieldNode.createdFields.get(0), fieldNode.name, fieldNode.nameOfSetFlag, source, fluent, chain, fieldNode.annotations, fieldNode.originalFieldNode, access); } else { fieldNode.singularData.getSingularizer().generateMethods(fieldNode.singularData, deprecate, builderType, source.get(), fluent, chain, access); } } - private void makeSimpleSetterMethodForBuilder(JavacNode builderType, boolean deprecate, JavacNode fieldNode, Name nameOfSetFlag, JavacNode source, boolean fluent, boolean chain, List annosOnParam, JavacNode originalFieldNode, AccessLevel access) { + private void makeSimpleSetterMethodForBuilder(JavacNode builderType, boolean deprecate, JavacNode fieldNode, Name paramName, Name nameOfSetFlag, JavacNode source, boolean fluent, boolean chain, List annosOnParam, JavacNode originalFieldNode, AccessLevel access) { Name fieldName = ((JCVariableDecl) fieldNode.get()).name; for (JavacNode child : builderType.down()) { @@ -756,12 +760,12 @@ public class HandleBuilder extends JavacAnnotationHandler { if (existingName.equals(fieldName) && !isTolerate(fieldNode, methodDecl)) return; } - String setterName = fluent ? fieldNode.getName() : HandlerUtil.buildAccessorName("set", fieldNode.getName()); + String setterName = fluent ? paramName.toString() : HandlerUtil.buildAccessorName("set", paramName.toString()); JavacTreeMaker maker = fieldNode.getTreeMaker(); List methodAnns = JavacHandlerUtil.findCopyableToSetterAnnotations(originalFieldNode); - JCMethodDecl newMethod = HandleSetter.createSetter(toJavacModifier(access), deprecate, fieldNode, maker, setterName, nameOfSetFlag, chain, source, methodAnns, annosOnParam); + JCMethodDecl newMethod = HandleSetter.createSetter(toJavacModifier(access), deprecate, fieldNode, maker, setterName, paramName, nameOfSetFlag, chain, source, methodAnns, annosOnParam); recursiveSetGeneratedBy(newMethod, source.get(), builderType.getContext()); copyJavadoc(originalFieldNode, newMethod, CopyJavadoc.SETTER); diff --git a/src/core/lombok/javac/handlers/HandleConstructor.java b/src/core/lombok/javac/handlers/HandleConstructor.java index e0456782..096963f4 100644 --- a/src/core/lombok/javac/handlers/HandleConstructor.java +++ b/src/core/lombok/javac/handlers/HandleConstructor.java @@ -342,7 +342,7 @@ public class HandleConstructor { JCVariableDecl param = maker.VarDef(maker.Modifiers(flags, copyableAnnotations), fieldName, field.vartype, null); params.append(param); if (hasNonNullAnnotations(fieldNode)) { - JCStatement nullCheck = generateNullCheck(maker, fieldNode, param, source); + JCStatement nullCheck = generateNullCheck(maker, param, source); if (nullCheck != null) nullChecks.append(nullCheck); } JCFieldAccess thisX = maker.Select(maker.Ident(fieldNode.toName("this")), rawName); diff --git a/src/core/lombok/javac/handlers/HandleSetter.java b/src/core/lombok/javac/handlers/HandleSetter.java index 5482cccc..cd8b5d1c 100644 --- a/src/core/lombok/javac/handlers/HandleSetter.java +++ b/src/core/lombok/javac/handlers/HandleSetter.java @@ -203,10 +203,10 @@ public class HandleSetter extends JavacAnnotationHandler { public static JCMethodDecl createSetter(long access, JavacNode field, JavacTreeMaker treeMaker, JavacNode source, List onMethod, List onParam) { String setterName = toSetterName(field); boolean returnThis = shouldReturnThis(field); - return createSetter(access, false, field, treeMaker, setterName, null, returnThis, source, onMethod, onParam); + return createSetter(access, false, field, treeMaker, setterName, null, null, returnThis, source, onMethod, onParam); } - public static JCMethodDecl createSetter(long access, boolean deprecate, JavacNode field, JavacTreeMaker treeMaker, String setterName, Name booleanFieldToSet, boolean shouldReturnThis, JavacNode source, List onMethod, List onParam) { + public static JCMethodDecl createSetter(long access, boolean deprecate, JavacNode field, JavacTreeMaker treeMaker, String setterName, Name paramName, Name booleanFieldToSet, boolean shouldReturnThis, JavacNode source, List onMethod, List onParam) { JCExpression returnType = null; JCReturn returnStatement = null; if (shouldReturnThis) { @@ -214,16 +214,17 @@ public class HandleSetter extends JavacAnnotationHandler { returnStatement = treeMaker.Return(treeMaker.Ident(field.toName("this"))); } - return createSetter(access, deprecate, field, treeMaker, setterName, booleanFieldToSet, returnType, returnStatement, source, onMethod, onParam); + return createSetter(access, deprecate, field, treeMaker, setterName, paramName, booleanFieldToSet, returnType, returnStatement, source, onMethod, onParam); } - public static JCMethodDecl createSetter(long access, boolean deprecate, JavacNode field, JavacTreeMaker treeMaker, String setterName, Name booleanFieldToSet, JCExpression methodType, JCStatement returnStatement, JavacNode source, List onMethod, List onParam) { + public static JCMethodDecl createSetter(long access, boolean deprecate, JavacNode field, JavacTreeMaker treeMaker, String setterName, Name paramName, Name booleanFieldToSet, JCExpression methodType, JCStatement returnStatement, JavacNode source, List onMethod, List onParam) { if (setterName == null) return null; JCVariableDecl fieldDecl = (JCVariableDecl) field.get(); + if (paramName == null) paramName = fieldDecl.name; JCExpression fieldRef = createFieldAccessor(treeMaker, field, FieldAccess.ALWAYS_FIELD); - JCAssign assign = treeMaker.Assign(fieldRef, treeMaker.Ident(fieldDecl.name)); + JCAssign assign = treeMaker.Assign(fieldRef, treeMaker.Ident(paramName)); ListBuffer statements = new ListBuffer(); List copyableAnnotations = findCopyableAnnotations(field); @@ -232,12 +233,12 @@ public class HandleSetter extends JavacAnnotationHandler { List annsOnParam = copyAnnotations(onParam).appendList(copyableAnnotations); long flags = JavacHandlerUtil.addFinalIfNeeded(Flags.PARAMETER, field.getContext()); - JCVariableDecl param = treeMaker.VarDef(treeMaker.Modifiers(flags, annsOnParam), fieldDecl.name, fieldDecl.vartype, null); + JCVariableDecl param = treeMaker.VarDef(treeMaker.Modifiers(flags, annsOnParam), paramName, fieldDecl.vartype, null); if (!hasNonNullAnnotations(field) && !hasNonNullAnnotations(field, onParam)) { statements.append(treeMaker.Exec(assign)); } else { - JCStatement nullCheck = generateNullCheck(treeMaker, field, source); + JCStatement nullCheck = generateNullCheck(treeMaker, fieldDecl.vartype, paramName, source); if (nullCheck != null) statements.append(nullCheck); statements.append(treeMaker.Exec(assign)); } @@ -267,7 +268,7 @@ public class HandleSetter extends JavacAnnotationHandler { } JCMethodDecl decl = recursiveSetGeneratedBy(treeMaker.MethodDef(treeMaker.Modifiers(access, annsOnMethod), methodName, methodType, - methodGenericParams, parameters, throwsClauses, methodBody, annotationMethodDefaultValue), source.get(), field.getContext()); + methodGenericParams, parameters, throwsClauses, methodBody, annotationMethodDefaultValue), source.get(), field.getContext()); copyJavadoc(field, decl, CopyJavadoc.SETTER); return decl; } diff --git a/src/core/lombok/javac/handlers/HandleSuperBuilder.java b/src/core/lombok/javac/handlers/HandleSuperBuilder.java index 9120fa07..a5c492a1 100644 --- a/src/core/lombok/javac/handlers/HandleSuperBuilder.java +++ b/src/core/lombok/javac/handlers/HandleSuperBuilder.java @@ -142,6 +142,7 @@ public class HandleSuperBuilder extends JavacAnnotationHandler { BuilderFieldData bfd = new BuilderFieldData(); bfd.rawName = fd.name; bfd.name = removePrefixFromField(fieldNode); + bfd.builderFieldName = bfd.name; bfd.annotations = findCopyableAnnotations(fieldNode); bfd.type = fd.vartype; bfd.singularData = getSingularData(fieldNode); @@ -166,7 +167,7 @@ public class HandleSuperBuilder extends JavacAnnotationHandler { if (isDefault != null) { bfd.nameOfDefaultProvider = tdParent.toName("$default$" + bfd.name); bfd.nameOfSetFlag = tdParent.toName(bfd.name + "$set"); - bfd.nameOfSetFlag = tdParent.toName(bfd.name + "$set"); + bfd.builderFieldName = tdParent.toName(bfd.name + "$value"); JCMethodDecl md = HandleBuilder.generateDefaultProvider(bfd.nameOfDefaultProvider, fieldNode, td.typarams); recursiveSetGeneratedBy(md, ast, annotationNode.getContext()); if (md != null) injectMethod(tdParent, md); @@ -493,10 +494,10 @@ public class HandleSuperBuilder extends JavacAnnotationHandler { for (BuilderFieldData bfd : builderFields) { JCExpression rhs; if (bfd.singularData != null && bfd.singularData.getSingularizer() != null) { - bfd.singularData.getSingularizer().appendBuildCode(bfd.singularData, bfd.originalFieldNode, bfd.type, statements, bfd.name, "b"); + bfd.singularData.getSingularizer().appendBuildCode(bfd.singularData, bfd.originalFieldNode, bfd.type, statements, bfd.builderFieldName, "b"); rhs = maker.Ident(bfd.singularData.getPluralName()); } else { - rhs = maker.Select(maker.Ident(builderVariableName), bfd.name); + rhs = maker.Select(maker.Ident(builderVariableName), bfd.builderFieldName); } JCFieldAccess fieldInThis = maker.Select(maker.Ident(typeNode.toName("this")), bfd.rawName); @@ -829,13 +830,13 @@ public class HandleSuperBuilder extends JavacAnnotationHandler { JavacNode field = null, setFlag = null; for (JavacNode exists : existing) { Name n = ((JCVariableDecl) exists.get()).name; - if (n.equals(bfd.name)) field = exists; + if (n.equals(bfd.builderFieldName)) field = exists; if (n.equals(bfd.nameOfSetFlag)) setFlag = exists; } JavacTreeMaker maker = builderType.getTreeMaker(); if (field == null) { JCModifiers mods = maker.Modifiers(Flags.PRIVATE); - JCVariableDecl newField = maker.VarDef(mods, bfd.name, cloneType(maker, bfd.type, source, builderType.getContext()), null); + JCVariableDecl newField = maker.VarDef(mods, bfd.builderFieldName, cloneType(maker, bfd.type, source, builderType.getContext()), null); field = injectFieldAndMarkGenerated(builderType, newField); generated.add(newField); } @@ -863,13 +864,13 @@ public class HandleSuperBuilder extends JavacAnnotationHandler { }}; if (fieldNode.singularData == null || fieldNode.singularData.getSingularizer() == null) { - generateSimpleSetterMethodForBuilder(builderType, deprecate, fieldNode.createdFields.get(0), fieldNode.nameOfSetFlag, source, true, returnTypeMaker.make(), returnStatementMaker.make(), fieldNode.annotations, fieldNode.originalFieldNode); + generateSimpleSetterMethodForBuilder(builderType, deprecate, fieldNode.createdFields.get(0), fieldNode.name, fieldNode.nameOfSetFlag, source, true, returnTypeMaker.make(), returnStatementMaker.make(), fieldNode.annotations, fieldNode.originalFieldNode); } else { fieldNode.singularData.getSingularizer().generateMethods(fieldNode.singularData, deprecate, builderType, source.get(), true, returnTypeMaker, returnStatementMaker, AccessLevel.PUBLIC); } } - private void generateSimpleSetterMethodForBuilder(JavacNode builderType, boolean deprecate, JavacNode fieldNode, Name nameOfSetFlag, JavacNode source, boolean fluent, JCExpression returnType, JCStatement returnStatement, List annosOnParam, JavacNode originalFieldNode) { + private void generateSimpleSetterMethodForBuilder(JavacNode builderType, boolean deprecate, JavacNode fieldNode, Name paramName, Name nameOfSetFlag, JavacNode source, boolean fluent, JCExpression returnType, JCStatement returnStatement, List annosOnParam, JavacNode originalFieldNode) { Name fieldName = ((JCVariableDecl) fieldNode.get()).name; for (JavacNode child : builderType.down()) { @@ -879,12 +880,12 @@ public class HandleSuperBuilder extends JavacAnnotationHandler { if (existingName.equals(fieldName) && !isTolerate(fieldNode, methodDecl)) return; } - String setterName = fluent ? fieldNode.getName() : HandlerUtil.buildAccessorName("set", fieldNode.getName()); + String setterName = fluent ? paramName.toString() : HandlerUtil.buildAccessorName("set", paramName.toString()); JavacTreeMaker maker = fieldNode.getTreeMaker(); List methodAnns = JavacHandlerUtil.findCopyableToSetterAnnotations(originalFieldNode); - JCMethodDecl newMethod = HandleSetter.createSetter(Flags.PUBLIC, deprecate, fieldNode, maker, setterName, nameOfSetFlag, returnType, returnStatement, source, methodAnns, annosOnParam); + JCMethodDecl newMethod = HandleSetter.createSetter(Flags.PUBLIC, deprecate, fieldNode, maker, setterName, paramName, nameOfSetFlag, returnType, returnStatement, source, methodAnns, annosOnParam); injectMethod(builderType, newMethod); } diff --git a/src/core/lombok/javac/handlers/JavacHandlerUtil.java b/src/core/lombok/javac/handlers/JavacHandlerUtil.java index 6fa70ff3..76f3c1ad 100644 --- a/src/core/lombok/javac/handlers/JavacHandlerUtil.java +++ b/src/core/lombok/javac/handlers/JavacHandlerUtil.java @@ -1516,34 +1516,40 @@ public class JavacHandlerUtil { * variable name as message. */ public static JCStatement generateNullCheck(JavacTreeMaker maker, JavacNode variable, JavacNode source) { - return generateNullCheck(maker, variable, (JCVariableDecl) variable.get(), source); + return generateNullCheck(maker, (JCVariableDecl) variable.get(), source); } - + /** - * Generates a new statement that checks if the given variable is null, and if so, throws a configured exception with the - * variable name as message. - * - * This is a special case method reserved for use when the provided declaration differs from the - * variable's declaration, i.e. in a constructor or setter where the local parameter is named the same but with the prefix - * stripped as a result of @Accessors.prefix. + * Generates a new statement that checks if the given local is null, and if so, throws a configured exception with the + * local variable name as message. */ - public static JCStatement generateNullCheck(JavacTreeMaker maker, JavacNode variable, JCVariableDecl varDecl, JavacNode source) { + public static JCStatement generateNullCheck(JavacTreeMaker maker, JCExpression typeNode, Name varName, JavacNode source) { NullCheckExceptionType exceptionType = source.getAst().readConfiguration(ConfigurationKeys.NON_NULL_EXCEPTION_TYPE); if (exceptionType == null) exceptionType = NullCheckExceptionType.NULL_POINTER_EXCEPTION; - if (isPrimitive(varDecl.vartype)) return null; - Name fieldName = varDecl.name; - - JCLiteral message = maker.Literal(exceptionType.toExceptionMessage(fieldName.toString())); + if (isPrimitive(typeNode)) return null; + JCLiteral message = maker.Literal(exceptionType.toExceptionMessage(varName.toString())); if (exceptionType == NullCheckExceptionType.ASSERTION) { - return maker.Assert(maker.Binary(CTC_NOT_EQUAL, maker.Ident(fieldName), maker.Literal(CTC_BOT, null)), message); + return maker.Assert(maker.Binary(CTC_NOT_EQUAL, maker.Ident(varName), maker.Literal(CTC_BOT, null)), message); } - JCExpression exType = genTypeRef(variable, exceptionType.getExceptionType()); + JCExpression exType = genTypeRef(source, exceptionType.getExceptionType()); JCExpression exception = maker.NewClass(null, List.nil(), exType, List.of(message), null); JCStatement throwStatement = maker.Throw(exception); JCBlock throwBlock = maker.Block(0, List.of(throwStatement)); - return maker.If(maker.Binary(CTC_EQUAL, maker.Ident(fieldName), maker.Literal(CTC_BOT, null)), throwBlock, null); + return maker.If(maker.Binary(CTC_EQUAL, maker.Ident(varName), maker.Literal(CTC_BOT, null)), throwBlock, null); + } + + /** + * Generates a new statement that checks if the given variable is null, and if so, throws a configured exception with the + * variable name as message. + * + * This is a special case method reserved for use when the provided declaration differs from the + * variable's declaration, i.e. in a constructor or setter where the local parameter is named the same but with the prefix + * stripped as a result of @Accessors.prefix. + */ + public static JCStatement generateNullCheck(JavacTreeMaker maker, JCVariableDecl varDecl, JavacNode source) { + return generateNullCheck(maker, varDecl.vartype, varDecl.name, source); } /** -- cgit From aa80e1baf92f3327383b36466a771e92d8a91b05 Mon Sep 17 00:00:00 2001 From: Roel Spilker Date: Tue, 16 Jul 2019 02:04:11 +0200 Subject: Fixes #1197, add Objects.requireNonNull and Preconditions.checkkNotNull to supported null-check styles --- doc/changelog.markdown | 2 + .../core/configuration/NullCheckExceptionType.java | 38 ++++++++++- .../eclipse/handlers/EclipseHandlerUtil.java | 79 ++++++++++++++-------- .../lombok/eclipse/handlers/HandleNonNull.java | 22 +++++- src/core/lombok/javac/handlers/HandleNonNull.java | 32 ++++++++- .../lombok/javac/handlers/JavacHandlerUtil.java | 6 ++ .../resource/after-delombok/NonNullWithGuava.java | 35 ++++++++++ .../resource/after-delombok/NonNullWithJdk.java | 36 ++++++++++ .../resource/after-ecj/NonNullWithGuava.java | 36 ++++++++++ .../resource/after-ecj/NonNullWithJdk.java | 37 ++++++++++ .../resource/before/NonNullWithGuava.java | 33 +++++++++ test/transform/resource/before/NonNullWithJdk.java | 34 ++++++++++ 12 files changed, 356 insertions(+), 34 deletions(-) create mode 100644 test/transform/resource/after-delombok/NonNullWithGuava.java create mode 100644 test/transform/resource/after-delombok/NonNullWithJdk.java create mode 100644 test/transform/resource/after-ecj/NonNullWithGuava.java create mode 100644 test/transform/resource/after-ecj/NonNullWithJdk.java create mode 100644 test/transform/resource/before/NonNullWithGuava.java create mode 100644 test/transform/resource/before/NonNullWithJdk.java (limited to 'src/core/lombok/javac') diff --git a/doc/changelog.markdown b/doc/changelog.markdown index 0c6bc584..0e489dd3 100644 --- a/doc/changelog.markdown +++ b/doc/changelog.markdown @@ -7,11 +7,13 @@ Lombok Changelog * ENHANCEMENT: `val` is now capable of decoding the type of convoluted expressions (particularly if the right hand side involves lambdas and conditional (ternary) expressions). [Pull Request #2109](https://github.com/rzwitserloot/lombok/pull/2109) and [Pull Request #2138](https://github.com/rzwitserloot/lombok/pull/2138) with thanks to Alexander Bulgakov. * ENHANCEMENT: You can now configure the generated builder class name via the config system, using key `lombok.builder.className`. See the [Builder documentation](https://projectlombok.org/features/Builder) and [SuperBuilder documentation](https://projectlombok.org/features/experimental/SuperBuilder) * ENHANCEMENT: If you mix up eclipse's non-null support, such as `@NonNullByDefault`, with lombok's `@NonNull`, you get a bunch of warnings about dead code that are inappropriate. These warnings are now suppressed, thanks to a contribution from Till Brychcy! [Pull Request #2155](https://github.com/rzwitserloot/lombok/pull/2155) +* ENHANCEMENT: `@NonNull` can now also generate checks using jdk's `Objects.requireNonNull` or Guava's `Preconditions.checkNotNull`. [Issue #1197](https://github.com/rzwitserloot/lombok/issues/1197) * BUGFIX: Delombok would turn something like `List...` in a method parameter to `List...` [Issue #2140](https://github.com/rzwitserloot/lombok/issues/2140) * BUGFIX: Javac would generate the wrong equals and hashCode if a type-use annotation was put on an array type field [Issue #2165](https://github.com/rzwitserloot/lombok/issues/2165) * BUGFIX: Eclipse 2019-06 + JDK-12 compatibility + an `@Singular` builder entry would produce a cascade of error dialogs. [Issue #2169](https://github.com/rzwitserloot/lombok/issues/2169) * IMPROBABLE BREAKING CHANGE: Stricter validation of configuration keys dealing with identifiers and types (`lombok.log.fieldName`, `lombok.fieldNameConstants.innerTypeName`, `lombok.copyableAnnotations`). * IMPROBABLE BREAKING CHANGE: The fields generated inside builders for fields with defaults (with `@Builder` on a class with fields marked `@Default`) now have `$value` as the name; direct manipulation of these fields is not advised because there is an associated `$set` variable that also needs to be taken into account. [Issue #2115](https://github.com/rzwitserloot/lombok/issues/2115) + ### v1.18.8 (May 7th, 2019) * FEATURE: You can now configure `@FieldNameConstants` to `CONSTANT_CASE` the generated constants, using a `lombok.config` option. See the [FieldNameConstants documentation](https://projectlombok.org/features/experimental/FieldNameConstants). [Issue #2092](https://github.com/rzwitserloot/lombok/issues/2092). * FEATURE: You can now suppress generation of the `builder` method when using `@Builder`; usually because you're only interested in the `toBuilder` method. As a convenience we won't emit warnings about missing `@Builder.Default` annotations when you do this. [Issue #2046](https://github.com/rzwitserloot/lombok/issues/2046) diff --git a/src/core/lombok/core/configuration/NullCheckExceptionType.java b/src/core/lombok/core/configuration/NullCheckExceptionType.java index d226c0a8..3c9e325d 100644 --- a/src/core/lombok/core/configuration/NullCheckExceptionType.java +++ b/src/core/lombok/core/configuration/NullCheckExceptionType.java @@ -21,28 +21,64 @@ */ package lombok.core.configuration; +import lombok.core.LombokImmutableList; -@ExampleValueString("[NullPointerException | IllegalArgumentException | Assertion]") +@ExampleValueString("[NullPointerException | IllegalArgumentException | Assertion | JDK | GUAVA]") public enum NullCheckExceptionType { ILLEGAL_ARGUMENT_EXCEPTION { @Override public String getExceptionType() { return "java.lang.IllegalArgumentException"; } + + @Override public LombokImmutableList getMethod() { + return null; + } }, NULL_POINTER_EXCEPTION { @Override public String getExceptionType() { return "java.lang.NullPointerException"; } + + @Override public LombokImmutableList getMethod() { + return null; + } }, ASSERTION { @Override public String getExceptionType() { return null; } + + @Override public LombokImmutableList getMethod() { + return null; + } + }, + JDK { + @Override public String getExceptionType() { + return null; + } + + @Override public LombokImmutableList getMethod() { + return METHOD_JDK; + } + }, + GUAVA { + @Override public String getExceptionType() { + return null; + } + + @Override public LombokImmutableList getMethod() { + return METHOD_GUAVA; + } }; + private static final LombokImmutableList METHOD_JDK = LombokImmutableList.of("java", "util", "Objects", "requireNonNull"); + private static final LombokImmutableList METHOD_GUAVA = LombokImmutableList.of("com", "google", "common", "base", "Preconditions", "checkNotNull"); + public String toExceptionMessage(String fieldName) { return fieldName + " is marked non-null but is null"; } public abstract String getExceptionType(); + + public abstract LombokImmutableList getMethod(); } diff --git a/src/core/lombok/eclipse/handlers/EclipseHandlerUtil.java b/src/core/lombok/eclipse/handlers/EclipseHandlerUtil.java index 37976ae3..11a2b9bd 100644 --- a/src/core/lombok/eclipse/handlers/EclipseHandlerUtil.java +++ b/src/core/lombok/eclipse/handlers/EclipseHandlerUtil.java @@ -38,26 +38,6 @@ import java.util.HashMap; import java.util.List; import java.util.Map; -import lombok.AccessLevel; -import lombok.ConfigurationKeys; -import lombok.Data; -import lombok.Getter; -import lombok.Lombok; -import lombok.core.AST.Kind; -import lombok.core.AnnotationValues; -import lombok.core.AnnotationValues.AnnotationValue; -import lombok.core.TypeResolver; -import lombok.core.configuration.NullCheckExceptionType; -import lombok.core.configuration.TypeName; -import lombok.core.debug.ProblemReporter; -import lombok.core.handlers.HandlerUtil; -import lombok.eclipse.Eclipse; -import lombok.eclipse.EclipseAST; -import lombok.eclipse.EclipseNode; -import lombok.experimental.Accessors; -import lombok.experimental.Tolerate; -import lombok.permit.Permit; - import org.eclipse.jdt.internal.compiler.ast.ASTNode; import org.eclipse.jdt.internal.compiler.ast.AbstractMethodDeclaration; import org.eclipse.jdt.internal.compiler.ast.AbstractVariableDeclaration; @@ -121,6 +101,28 @@ import org.eclipse.jdt.internal.compiler.lookup.TypeConstants; import org.eclipse.jdt.internal.compiler.lookup.TypeIds; import org.eclipse.jdt.internal.compiler.lookup.WildcardBinding; +import lombok.AccessLevel; +import lombok.ConfigurationKeys; +import lombok.Data; +import lombok.Getter; +import lombok.Lombok; +import lombok.core.AST.Kind; +import lombok.core.AnnotationValues; +import lombok.core.AnnotationValues.AnnotationValue; +import lombok.core.LombokImmutableList; +import lombok.core.TypeResolver; +import lombok.core.configuration.NullCheckExceptionType; +import lombok.core.configuration.TypeName; +import lombok.core.debug.ProblemReporter; +import lombok.core.handlers.HandlerUtil; +import lombok.core.handlers.HandlerUtil.FieldAccess; +import lombok.eclipse.Eclipse; +import lombok.eclipse.EclipseAST; +import lombok.eclipse.EclipseNode; +import lombok.experimental.Accessors; +import lombok.experimental.Tolerate; +import lombok.permit.Permit; + /** * Container for static utility methods useful to handlers written for eclipse. */ @@ -1818,8 +1820,6 @@ public class EclipseHandlerUtil { /** * Generates a new statement that checks if the given local variable is null, and if so, throws a specified exception with the * variable name as message. - * - * @param exName The name of the exception to throw; normally {@code java.lang.NullPointerException}. */ public static Statement generateNullCheck(TypeReference type, char[] variable, EclipseNode sourceNode) { NullCheckExceptionType exceptionType = sourceNode.getAst().readConfiguration(ConfigurationKeys.NON_NULL_EXCEPTION_TYPE); @@ -1828,24 +1828,44 @@ public class EclipseHandlerUtil { ASTNode source = sourceNode.get(); int pS = source.sourceStart, pE = source.sourceEnd; - long p = (long)pS << 32 | pE; + long p = (long) pS << 32 | pE; if (isPrimitive(type)) return null; + SingleNameReference varName = new SingleNameReference(variable, p); + setGeneratedBy(varName, source); + + StringLiteral message = new StringLiteral(exceptionType.toExceptionMessage(new String(variable)).toCharArray(), pS, pE, 0); + setGeneratedBy(message, source); + + LombokImmutableList method = exceptionType.getMethod(); + if (method != null) { + + MessageSend invocation = new MessageSend(); + invocation.sourceStart = pS; invocation.sourceEnd = pE; + setGeneratedBy(invocation, source); + + char[][] utilityTypeName = new char[method.size() - 1][]; + for (int i = 0; i < method.size() - 1; i++) { + utilityTypeName[i] = method.get(i).toCharArray(); + } + + invocation.receiver = new QualifiedNameReference(utilityTypeName, new long[method.size()], pS, pE); + setGeneratedBy(invocation.receiver, source); + invocation.selector = method.get(method.size() - 1).toCharArray(); + invocation.arguments = new Expression[] {varName, message}; + return invocation; + } + AllocationExpression exception = new AllocationExpression(); setGeneratedBy(exception, source); - SingleNameReference varName = new SingleNameReference(variable, p); - setGeneratedBy(varName, source); NullLiteral nullLiteral = new NullLiteral(pS, pE); setGeneratedBy(nullLiteral, source); - + int equalOperator = exceptionType == NullCheckExceptionType.ASSERTION ? OperatorIds.NOT_EQUAL : OperatorIds.EQUAL_EQUAL; EqualExpression equalExpression = new EqualExpression(varName, nullLiteral, equalOperator); equalExpression.sourceStart = pS; equalExpression.statementEnd = equalExpression.sourceEnd = pE; setGeneratedBy(equalExpression, source); - - StringLiteral message = new StringLiteral(exceptionType.toExceptionMessage(new String(variable)).toCharArray(), pS, pE, 0); - setGeneratedBy(message, source); if (exceptionType == NullCheckExceptionType.ASSERTION) { Statement assertStatement = new AssertStatement(message, equalExpression, pS); @@ -1865,7 +1885,6 @@ public class EclipseHandlerUtil { ThrowStatement throwStatement = new ThrowStatement(exception, pS, pE); setGeneratedBy(throwStatement, source); - Block throwBlock = new Block(0); throwBlock.statements = new Statement[] {throwStatement}; throwBlock.sourceStart = pS; throwBlock.sourceEnd = pE; diff --git a/src/core/lombok/eclipse/handlers/HandleNonNull.java b/src/core/lombok/eclipse/handlers/HandleNonNull.java index 77c77e1e..c61ce02d 100644 --- a/src/core/lombok/eclipse/handlers/HandleNonNull.java +++ b/src/core/lombok/eclipse/handlers/HandleNonNull.java @@ -33,10 +33,12 @@ import org.eclipse.jdt.internal.compiler.ast.AbstractVariableDeclaration; import org.eclipse.jdt.internal.compiler.ast.Annotation; import org.eclipse.jdt.internal.compiler.ast.Argument; import org.eclipse.jdt.internal.compiler.ast.AssertStatement; +import org.eclipse.jdt.internal.compiler.ast.Assignment; 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.IfStatement; +import org.eclipse.jdt.internal.compiler.ast.MessageSend; import org.eclipse.jdt.internal.compiler.ast.NullLiteral; import org.eclipse.jdt.internal.compiler.ast.OperatorIds; import org.eclipse.jdt.internal.compiler.ast.SingleNameReference; @@ -61,6 +63,9 @@ import lombok.eclipse.EclipseNode; @ProviderFor(EclipseAnnotationHandler.class) @HandlerPriority(value = 512) // 2^9; onParameter=@__(@NonNull) has to run first. public class HandleNonNull extends EclipseAnnotationHandler { + private static final char[] REQUIRE_NON_NULL = "requireNonNull".toCharArray(); + private static final char[] CHECK_NOT_NULL = "checkNotNull".toCharArray(); + public static final HandleNonNull INSTANCE = new HandleNonNull(); public void fix(EclipseNode method) { @@ -193,7 +198,22 @@ public class HandleNonNull extends EclipseAnnotationHandler { public char[] returnVarNameIfNullCheck(Statement stat) { boolean isIf = stat instanceof IfStatement; - if (!isIf && !(stat instanceof AssertStatement)) return null; + boolean isExpression = stat instanceof Expression; + if (!isIf && !(stat instanceof AssertStatement) && !isExpression) return null; + + if (isExpression) { + /* Check if the statements contains a call to checkNotNull or requireNonNull */ + Expression expression = (Expression) stat; + if (expression instanceof Assignment) expression = ((Assignment) expression).expression; + if (!(expression instanceof MessageSend)) return null; + + MessageSend invocation = (MessageSend) expression; + if (!Arrays.equals(invocation.selector, CHECK_NOT_NULL) && !Arrays.equals(invocation.selector, REQUIRE_NON_NULL)) return null; + if (invocation.arguments == null || invocation.arguments.length == 0) return null; + Expression firstArgument = invocation.arguments[0]; + if (!(firstArgument instanceof SingleNameReference)) return null; + return ((SingleNameReference) firstArgument).token; + } if (isIf) { /* Check that the if's statement is a throw statement, possibly in a block. */ diff --git a/src/core/lombok/javac/handlers/HandleNonNull.java b/src/core/lombok/javac/handlers/HandleNonNull.java index 49b987ce..079d5b04 100644 --- a/src/core/lombok/javac/handlers/HandleNonNull.java +++ b/src/core/lombok/javac/handlers/HandleNonNull.java @@ -31,13 +31,17 @@ import org.mangosdk.spi.ProviderFor; import com.sun.tools.javac.tree.JCTree.JCAnnotation; import com.sun.tools.javac.tree.JCTree.JCAssert; +import com.sun.tools.javac.tree.JCTree.JCAssign; import com.sun.tools.javac.tree.JCTree.JCBinary; import com.sun.tools.javac.tree.JCTree.JCBlock; import com.sun.tools.javac.tree.JCTree.JCExpression; +import com.sun.tools.javac.tree.JCTree.JCExpressionStatement; +import com.sun.tools.javac.tree.JCTree.JCFieldAccess; import com.sun.tools.javac.tree.JCTree.JCIdent; 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.JCMethodInvocation; import com.sun.tools.javac.tree.JCTree.JCParens; import com.sun.tools.javac.tree.JCTree.JCStatement; import com.sun.tools.javac.tree.JCTree.JCSynchronized; @@ -45,6 +49,7 @@ import com.sun.tools.javac.tree.JCTree.JCThrow; import com.sun.tools.javac.tree.JCTree.JCTry; import com.sun.tools.javac.tree.JCTree.JCVariableDecl; import com.sun.tools.javac.util.List; +import com.sun.tools.javac.util.Name; import lombok.ConfigurationKeys; import lombok.NonNull; @@ -167,8 +172,31 @@ public class HandleNonNull extends JavacAnnotationHandler { * If it is not of this form, returns null. */ public String returnVarNameIfNullCheck(JCStatement stat) { - boolean isIf = stat instanceof JCIf; - if (!isIf && !(stat instanceof JCAssert)) return null; + boolean isIf = stat instanceof JCIf; + boolean isExpression = stat instanceof JCExpressionStatement; + if (!isIf && !(stat instanceof JCAssert) && !isExpression) return null; + + if (isExpression) { + /* Check if the statements contains a call to checkNotNull or requireNonNull */ + JCExpression expression = ((JCExpressionStatement) stat).expr; + if (expression instanceof JCAssign) expression = ((JCAssign) expression).rhs; + if (!(expression instanceof JCMethodInvocation)) return null; + + JCMethodInvocation invocation = (JCMethodInvocation) expression; + JCExpression method = invocation.meth; + Name name = null; + if (method instanceof JCFieldAccess) { + name = ((JCFieldAccess) method).name; + } else if (method instanceof JCIdent) { + name = ((JCIdent) method).name; + } + if (name == null || (!name.contentEquals("checkNotNull") && !name.contentEquals("requireNonNull"))) return null; + + if (invocation.args.isEmpty()) return null; + JCExpression firstArgument = invocation.args.head; + if (!(firstArgument instanceof JCIdent)) return null; + return ((JCIdent) firstArgument).toString(); + } if (isIf) { /* Check that the if's statement is a throw statement, possibly in a block. */ diff --git a/src/core/lombok/javac/handlers/JavacHandlerUtil.java b/src/core/lombok/javac/handlers/JavacHandlerUtil.java index 76f3c1ad..5f0f39b0 100644 --- a/src/core/lombok/javac/handlers/JavacHandlerUtil.java +++ b/src/core/lombok/javac/handlers/JavacHandlerUtil.java @@ -1529,6 +1529,12 @@ public class JavacHandlerUtil { if (isPrimitive(typeNode)) return null; JCLiteral message = maker.Literal(exceptionType.toExceptionMessage(varName.toString())); + + LombokImmutableList method = exceptionType.getMethod(); + if (method != null) { + return maker.Exec(maker.Apply(List.nil(), chainDots(source, method), List.of(maker.Ident(varName), message))); + } + if (exceptionType == NullCheckExceptionType.ASSERTION) { return maker.Assert(maker.Binary(CTC_NOT_EQUAL, maker.Ident(varName), maker.Literal(CTC_BOT, null)), message); } diff --git a/test/transform/resource/after-delombok/NonNullWithGuava.java b/test/transform/resource/after-delombok/NonNullWithGuava.java new file mode 100644 index 00000000..b3c13d30 --- /dev/null +++ b/test/transform/resource/after-delombok/NonNullWithGuava.java @@ -0,0 +1,35 @@ +import static com.google.common.base.Preconditions.*; +public class NonNullWithGuava { + @lombok.NonNull + private String test; + public void testMethod(@lombok.NonNull String arg) { + com.google.common.base.Preconditions.checkNotNull(arg, "arg is marked non-null but is null"); + System.out.println(arg); + } + public void testMethodWithCheck1(@lombok.NonNull String arg) { + checkNotNull(arg); + } + public void testMethodWithCheckAssign(@lombok.NonNull String arg) { + test = checkNotNull(arg); + } + public void testMethodWithCheck2(@lombok.NonNull String arg) { + com.google.common.base.Preconditions.checkNotNull(arg); + } + public void testMethodWithFakeCheck1(@lombok.NonNull String arg) { + com.google.common.base.Preconditions.checkNotNull(arg, "arg is marked non-null but is null"); + checkNotNull(""); + } + public void testMethodWithFakeCheck2(@lombok.NonNull String arg) { + com.google.common.base.Preconditions.checkNotNull(arg, "arg is marked non-null but is null"); + com.google.common.base.Preconditions.checkNotNull(test); + } + public void testMethodWithFakeCheckAssign(@lombok.NonNull String arg) { + com.google.common.base.Preconditions.checkNotNull(arg, "arg is marked non-null but is null"); + test = checkNotNull(test); + } + @java.lang.SuppressWarnings("all") + public void setTest(@lombok.NonNull final String test) { + com.google.common.base.Preconditions.checkNotNull(test, "test is marked non-null but is null"); + this.test = test; + } +} \ No newline at end of file diff --git a/test/transform/resource/after-delombok/NonNullWithJdk.java b/test/transform/resource/after-delombok/NonNullWithJdk.java new file mode 100644 index 00000000..d7e2958c --- /dev/null +++ b/test/transform/resource/after-delombok/NonNullWithJdk.java @@ -0,0 +1,36 @@ +//version 7: +import static java.util.Objects.*; +public class NonNullWithJdk { + @lombok.NonNull + private String test; + public void testMethod(@lombok.NonNull String arg) { + java.util.Objects.requireNonNull(arg, "arg is marked non-null but is null"); + System.out.println(arg); + } + public void testMethodWithCheck1(@lombok.NonNull String arg) { + requireNonNull(arg); + } + public void testMethodWithCheckAssign(@lombok.NonNull String arg) { + test = requireNonNull(arg); + } + public void testMethodWithCheck2(@lombok.NonNull String arg) { + java.util.Objects.requireNonNull(arg); + } + public void testMethodWithFakeCheck1(@lombok.NonNull String arg) { + java.util.Objects.requireNonNull(arg, "arg is marked non-null but is null"); + requireNonNull(""); + } + public void testMethodWithFakeCheck2(@lombok.NonNull String arg) { + java.util.Objects.requireNonNull(arg, "arg is marked non-null but is null"); + java.util.Objects.requireNonNull(test); + } + public void testMethodWithFakeCheckAssign(@lombok.NonNull String arg) { + java.util.Objects.requireNonNull(arg, "arg is marked non-null but is null"); + test = requireNonNull(test); + } + @java.lang.SuppressWarnings("all") + public void setTest(@lombok.NonNull final String test) { + java.util.Objects.requireNonNull(test, "test is marked non-null but is null"); + this.test = test; + } +} \ No newline at end of file diff --git a/test/transform/resource/after-ecj/NonNullWithGuava.java b/test/transform/resource/after-ecj/NonNullWithGuava.java new file mode 100644 index 00000000..c7f5a7fe --- /dev/null +++ b/test/transform/resource/after-ecj/NonNullWithGuava.java @@ -0,0 +1,36 @@ +import static com.google.common.base.Preconditions.*; +public class NonNullWithGuava { + private @lombok.NonNull @lombok.Setter String test; + public NonNullWithGuava() { + super(); + } + public void testMethod(@lombok.NonNull String arg) { + com.google.common.base.Preconditions.checkNotNull(arg, "arg is marked non-null but is null"); + System.out.println(arg); + } + public void testMethodWithCheck1(@lombok.NonNull String arg) { + checkNotNull(arg); + } + public void testMethodWithCheckAssign(@lombok.NonNull String arg) { + test = checkNotNull(arg); + } + public void testMethodWithCheck2(@lombok.NonNull String arg) { + com.google.common.base.Preconditions.checkNotNull(arg); + } + public void testMethodWithFakeCheck1(@lombok.NonNull String arg) { + com.google.common.base.Preconditions.checkNotNull(arg, "arg is marked non-null but is null"); + checkNotNull(""); + } + public void testMethodWithFakeCheck2(@lombok.NonNull String arg) { + com.google.common.base.Preconditions.checkNotNull(arg, "arg is marked non-null but is null"); + com.google.common.base.Preconditions.checkNotNull(test); + } + public void testMethodWithFakeCheckAssign(@lombok.NonNull String arg) { + com.google.common.base.Preconditions.checkNotNull(arg, "arg is marked non-null but is null"); + test = checkNotNull(test); + } + public @java.lang.SuppressWarnings("all") void setTest(final @lombok.NonNull String test) { + com.google.common.base.Preconditions.checkNotNull(test, "test is marked non-null but is null"); + this.test = test; + } +} diff --git a/test/transform/resource/after-ecj/NonNullWithJdk.java b/test/transform/resource/after-ecj/NonNullWithJdk.java new file mode 100644 index 00000000..7d522260 --- /dev/null +++ b/test/transform/resource/after-ecj/NonNullWithJdk.java @@ -0,0 +1,37 @@ +//version 7: +import static java.util.Objects.*; +public class NonNullWithJdk { + private @lombok.NonNull @lombok.Setter String test; + public NonNullWithJdk() { + super(); + } + public void testMethod(@lombok.NonNull String arg) { + java.util.Objects.requireNonNull(arg, "arg is marked non-null but is null"); + System.out.println(arg); + } + public void testMethodWithCheck1(@lombok.NonNull String arg) { + requireNonNull(arg); + } + public void testMethodWithCheckAssign(@lombok.NonNull String arg) { + test = requireNonNull(arg); + } + public void testMethodWithCheck2(@lombok.NonNull String arg) { + java.util.Objects.requireNonNull(arg); + } + public void testMethodWithFakeCheck1(@lombok.NonNull String arg) { + java.util.Objects.requireNonNull(arg, "arg is marked non-null but is null"); + requireNonNull(""); + } + public void testMethodWithFakeCheck2(@lombok.NonNull String arg) { + java.util.Objects.requireNonNull(arg, "arg is marked non-null but is null"); + java.util.Objects.requireNonNull(test); + } + public void testMethodWithFakeCheckAssign(@lombok.NonNull String arg) { + java.util.Objects.requireNonNull(arg, "arg is marked non-null but is null"); + test = requireNonNull(test); + } + public @java.lang.SuppressWarnings("all") void setTest(final @lombok.NonNull String test) { + java.util.Objects.requireNonNull(test, "test is marked non-null but is null"); + this.test = test; + } +} diff --git a/test/transform/resource/before/NonNullWithGuava.java b/test/transform/resource/before/NonNullWithGuava.java new file mode 100644 index 00000000..dc877daa --- /dev/null +++ b/test/transform/resource/before/NonNullWithGuava.java @@ -0,0 +1,33 @@ +//CONF: lombok.nonNull.exceptionType = Guava +import static com.google.common.base.Preconditions.*; +public class NonNullWithGuava { + @lombok.NonNull @lombok.Setter private String test; + + public void testMethod(@lombok.NonNull String arg) { + System.out.println(arg); + } + + public void testMethodWithCheck1(@lombok.NonNull String arg) { + checkNotNull(arg); + } + + public void testMethodWithCheckAssign(@lombok.NonNull String arg) { + test = checkNotNull(arg); + } + + public void testMethodWithCheck2(@lombok.NonNull String arg) { + com.google.common.base.Preconditions.checkNotNull(arg); + } + + public void testMethodWithFakeCheck1(@lombok.NonNull String arg) { + checkNotNull(""); + } + + public void testMethodWithFakeCheck2(@lombok.NonNull String arg) { + com.google.common.base.Preconditions.checkNotNull(test); + } + + public void testMethodWithFakeCheckAssign(@lombok.NonNull String arg) { + test = checkNotNull(test); + } +} diff --git a/test/transform/resource/before/NonNullWithJdk.java b/test/transform/resource/before/NonNullWithJdk.java new file mode 100644 index 00000000..c8cbf2ee --- /dev/null +++ b/test/transform/resource/before/NonNullWithJdk.java @@ -0,0 +1,34 @@ +//version 7: +//CONF: lombok.nonNull.exceptionType = Jdk +import static java.util.Objects.*; +public class NonNullWithJdk { + @lombok.NonNull @lombok.Setter private String test; + + public void testMethod(@lombok.NonNull String arg) { + System.out.println(arg); + } + + public void testMethodWithCheck1(@lombok.NonNull String arg) { + requireNonNull(arg); + } + + public void testMethodWithCheckAssign(@lombok.NonNull String arg) { + test = requireNonNull(arg); + } + + public void testMethodWithCheck2(@lombok.NonNull String arg) { + java.util.Objects.requireNonNull(arg); + } + + public void testMethodWithFakeCheck1(@lombok.NonNull String arg) { + requireNonNull(""); + } + + public void testMethodWithFakeCheck2(@lombok.NonNull String arg) { + java.util.Objects.requireNonNull(test); + } + + public void testMethodWithFakeCheckAssign(@lombok.NonNull String arg) { + test = requireNonNull(test); + } +} -- cgit