Skip to content

Commit

Permalink
GROOVY-7503: Builder with Initializer strategy and no properties resu…
Browse files Browse the repository at this point in the history
…lts in ClassFormatError (side effect: closes apache#60)
  • Loading branch information
paulk-asert committed Jul 16, 2015
1 parent 653690c commit 2e5288c
Show file tree
Hide file tree
Showing 3 changed files with 35 additions and 6 deletions.
3 changes: 3 additions & 0 deletions gradle/pomconfigurer.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -564,6 +564,9 @@ project.ext.pomConfigureClosureWithoutTweaks = {
contributor {
name 'Nick Grealy'
}
contributor {
name 'Marcin Grzejszczak'
}
}
mailingLists {
mailingList {
Expand Down
13 changes: 9 additions & 4 deletions src/main/groovy/transform/builder/InitializerStrategy.java
Original file line number Diff line number Diff line change
Expand Up @@ -112,9 +112,6 @@
* to call your constructor. Any parameters to your constructor become the properties expected by the initializer.
* If you use such a builder on a constructor as well as on the class or on more than one constructor, then it is up to you
* to define unique values for 'builderClassName' and 'builderMethodName' for each annotation.
*
* @author Paul King
* @author Marcin Grzejszczak
*/
public class InitializerStrategy extends BuilderASTTransformation.AbstractBuilderStrategy {

Expand Down Expand Up @@ -149,6 +146,10 @@ private void createBuilderForAnnotatedClass(BuilderASTTransformation transform,
if (!getIncludeExclude(transform, anno, buildee, excludes, includes)) return;
List<FieldNode> fields = getInstancePropertyFields(buildee);
List<FieldNode> filteredFields = filterFields(fields, includes, excludes);
if (filteredFields.isEmpty()) {
transform.addError("Error during " + BuilderASTTransformation.MY_TYPE_NAME +
" processing: at least one property is required for this strategy", anno);
}
ClassNode builder = createInnerHelperClass(buildee, getBuilderClassName(buildee, anno), filteredFields.size());
addFields(buildee, filteredFields, builder);

Expand All @@ -157,7 +158,7 @@ private void createBuilderForAnnotatedClass(BuilderASTTransformation transform,
}

private void createBuilderForAnnotatedMethod(BuilderASTTransformation transform, MethodNode mNode, AnnotationNode anno, boolean useSetters) {
if (transform.getMemberValue(anno, "includes") != null || transform.getMemberValue(anno, "includes") != null) {
if (transform.getMemberValue(anno, "includes") != null || transform.getMemberValue(anno, "excludes") != null) {
transform.addError("Error during " + BuilderASTTransformation.MY_TYPE_NAME +
" processing: includes/excludes only allowed on classes", anno);
}
Expand All @@ -172,6 +173,10 @@ private void createBuilderForAnnotatedMethod(BuilderASTTransformation transform,
}
ClassNode buildee = mNode.getDeclaringClass();
Parameter[] parameters = mNode.getParameters();
if (parameters.length == 0) {
transform.addError("Error during " + BuilderASTTransformation.MY_TYPE_NAME +
" processing: at least one parameter is required for this strategy", anno);
}
ClassNode builder = createInnerHelperClass(buildee, getBuilderClassName(buildee, anno), parameters.length);
List<FieldNode> convertedFields = convertParamsToFields(builder, parameters);

Expand Down
25 changes: 23 additions & 2 deletions src/test/org/codehaus/groovy/transform/BuilderTransformTest.groovy
Original file line number Diff line number Diff line change
Expand Up @@ -21,8 +21,7 @@ package org.codehaus.groovy.transform
import gls.CompilableTestSupport

/**
* @author Marcin Grzejszczak
* @author Paul King
* Tests for {@code @Builder} transform.
*/
class BuilderTransformTest extends CompilableTestSupport {

Expand Down Expand Up @@ -569,4 +568,26 @@ class BuilderTransformTest extends CompilableTestSupport {
'''
}

void testInitializerStrategyEmptyCases_GROOVY7503() {
def message = shouldNotCompile '''
import groovy.transform.builder.*
@Builder(builderStrategy=InitializerStrategy) class Foo { }
'''
assert message.contains('at least one property is required for this strategy')
message = shouldNotCompile '''
import groovy.transform.builder.*
@Builder(builderStrategy=InitializerStrategy, excludes='bar') class Foo { String bar }
'''
assert message.contains('at least one property is required for this strategy')
message = shouldNotCompile '''
import groovy.transform.builder.*
class Foo {
@Builder(builderStrategy=InitializerStrategy)
Foo() {
}
}
'''
assert message.contains('at least one parameter is required for this strategy')
}

}

0 comments on commit 2e5288c

Please sign in to comment.