-
Notifications
You must be signed in to change notification settings - Fork 9
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Perform additional validation & fail earlier for incorrect arguments #87
base: develop
Are you sure you want to change the base?
Perform additional validation & fail earlier for incorrect arguments #87
Conversation
MethodSpec and ParameterSpec already had this.
Thanks for your interest in palantir/javapoet, @Marcono1234! Before we can accept your pull request, you need to sign our contributor license agreement - just visit https://cla.palantir.com/ and follow the instructions. Once you sign, I'll automatically update this pull request. |
Generate changelog in
|
checkState(enclosingClassName == null || enclosingClassName.packageName.equals(packageName), | ||
"enclosing class is in wrong package"); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think this is impossible with the public API currently, but I added this check nonetheless to be safe.
protected final List<AnnotationSpec> concatAnnotations(List<AnnotationSpec> annotations) { | ||
final List<AnnotationSpec> concatAnnotations(List<AnnotationSpec> annotations) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Changed this because if I understand it correctly TypeName
cannot be subclassed by users, so it makes no sense that they see this method if they cannot use it anyway.
static ArrayTypeName get(ArrayType mirror, Map<TypeParameterElement, TypeVariableName> typeVariables) { | ||
checkNotNull(mirror, "mirror == null"); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
For all these get(... mirror, Map typeVariables)
methods in the ...TypeName
classes I wasn't completely sure if typeVariables
can be null
either. So for now I did not add a null check.
// Compact constructor. | ||
// Canonical record constructor. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This just writes the canonical constructor, whether it is also "compact" depends on whether MethodSpec.compactConstructorBuilder()
was used.
throw new UnsupportedOperationException(kind + " can't have record constructor"); | ||
} | ||
checkState(this.kind == Kind.RECORD, "%s can't have record constructor", this.kind); | ||
checkState(this.recordConstructor == null, "record constructor already set to %s", this.recordConstructor); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This "record constructor already set" is probably consistent with most other builder methods, which don't allow overwriting values:
TypeSpec.Builder#superclass
MethodSpec.Builder#defaultValue
FieldSpec.Builder#initializer
(but there are some exceptions)
@@ -786,19 +810,23 @@ public Builder addEnumConstant(String name) { | |||
} | |||
|
|||
public Builder addEnumConstant(String name, TypeSpec typeSpec) { | |||
checkNotNull(name, "name == null"); | |||
checkNotNull(typeSpec, "typeSpec == null"); | |||
checkState(kind == Kind.ENUM, "only enums can have enum constants"); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Side note: This "only enums can have enum constants" is currently also checked in build()
(with message "%s is not enum" there)
checkArgument(methodSpec.defaultValue() == null || kind == Kind.ANNOTATION, | ||
"method with default value is only allowed for annotation type"); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Side note: This defaultValue()
check already exists in build()
as well
a = ParameterSpec.builder(int.class, "i").addModifiers(Modifier.STATIC).build(); | ||
b = ParameterSpec.builder(int.class, "i").addModifiers(Modifier.STATIC).build(); | ||
a = ParameterSpec.builder(int.class, "i").addModifiers(Modifier.FINAL).build(); | ||
b = ParameterSpec.builder(int.class, "i").addModifiers(Modifier.FINAL).build(); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This includes the fix from #85 (comment), where it was previously not delegating the call, and this addModifiers
overload did not validate the modifiers.
Currently still waiting for an answer to my questions regarding the CLA, see #84 (comment). |
Before this PR
null
This would probably often have lead to delayed
NullPointerException
s, or might have even caused different behavior in casenull
had internally a special meaning.Sometimes
IllegalArgumentException
was thrown fornull
; in two casesUnsupportedOperationException
was thrown instead ofIllegalStateException
.build()
, and not already when calling builder methodsNote: I only changed a few cases; maybe would be worth to investigate this more in depth in the future. But this applies mainly to immutable state of a builder, e.g. a
TypeSpec.Builder
forclass
will keep that kind and it cannot be changed toenum
. For other validation is probably fine and better to do this inbuild()
.After this PR
NullPointerException
is thrown for unexpectednull
IllegalStateException
is thrown when methods are called on wrong type, e.g. adding record constructor to regular classaddModifier(Iterable)
overloads, see Fix incompletetoBuilder
implementations and add tests #85 (comment)Possible downsides?
I hope these changes do not accidentally disallow arguments which should be allowed.