Skip to content

Commit

Permalink
#879 corrections wrt type annotations
Browse files Browse the repository at this point in the history
  • Loading branch information
elucash committed Dec 17, 2018
1 parent de4d25d commit 27799da
Show file tree
Hide file tree
Showing 5 changed files with 74 additions and 8 deletions.
9 changes: 9 additions & 0 deletions value-fixture/src/nonimmutables/NoNilType.java
@@ -0,0 +1,9 @@
package nonimmutables;

import java.lang.annotation.ElementType;
import java.lang.annotation.Target;

// Type annotation to check for sloppy typechecks which can take
// type mirror's toString which can include printed type annotation.
@Target(ElementType.TYPE_USE)
public @interface NoNilType {}
@@ -0,0 +1,29 @@
/*
Copyright 2018 Immutables Authors and Contributors
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
package org.immutables.fixture;

import nonimmutables.NoNilType;
import org.immutables.value.Value.Immutable;

@Immutable
public interface WithThisCheckForNoNilString {
@NoNilType
String a(); // with method should not generate `== this.a`
// check because of the type annotation. Should be equals
// ErrorProne

String b();
}
15 changes: 14 additions & 1 deletion value-fixture/test/org/immutables/fixture/ValuesTest.java
Expand Up @@ -211,7 +211,7 @@ public void auxiliary() {
check(includesAuxiliary.hashCode()).is(excludesAuxiliary.hashCode());
check(includesAuxiliary).asString().not().contains("auxiliary");
}

@Test
public void auxiliaryOnForcedSingleton() {
check(ImmutableAuxDefaultOnForcedSingleton.of().withAux(66).aux()).is(66);
Expand Down Expand Up @@ -555,4 +555,17 @@ public void redactedMaskJdkOnlyOpt() {

check(m).hasToString("RedactedMaskJdkOnlyOpt{code=????}");
}

@Test
public void withStringEqualsRegardlessOfTypeAnnotation() {
ImmutableWithThisCheckForNoNilString o = ImmutableWithThisCheckForNoNilString.builder()
.a("a")
.b("b")
.build();
// with should use equals short-circuit check to return this, not reference equality
// so we create "new String"
check(o.withA(new String("a"))).same(o);
check(o.withB(new String("b"))).same(o);
check(o.withA("other")).not().same(o);
}
}
Expand Up @@ -3323,6 +3323,9 @@ public final [type.typeImmutable.relative] [v.names.with]([unwrappedOptionalType
*/
[suppressCovariantCastForOptional v]
[deprecation v]
//E: [v.elementType]
//W: [v.wrappedElementType]
//U: [v.unwrappedElementType]
public final [type.typeImmutable.relative] [v.names.with]([v.rawType][if not v.jdkSpecializedOptional]<[v.consumedElementType]>[/if] optional) {
[immutableImplementationType v] value = [valueFromValue v 'optional'];
[if v.jdkOptional]
Expand Down Expand Up @@ -3379,6 +3382,9 @@ public final [type.typeImmutable.relative] [v.names.with]([v.atNullability][if v
* @return A modified copy of the {@code this} object
*/
[deprecation v]
//E: [v.elementType]
//W: [v.wrappedElementType]
//U: [v.unwrappedElementType]
public final [type.typeImmutable.relative] [v.names.with]([v.atNullability][v.type] value) {
[if v.float]
if (Float.floatToIntBits(this.[v.name]) == Float.floatToIntBits(value)) return this;
Expand Down
Expand Up @@ -15,6 +15,7 @@
*/
package org.immutables.value.processor.meta;

import com.google.common.base.Ascii;
import com.google.common.base.Joiner;
import com.google.common.base.MoreObjects;
import com.google.common.base.Optional;
Expand Down Expand Up @@ -165,8 +166,10 @@ public boolean isSimpleLiteralType() {

public boolean hasSimpleScalarElementType() {
ensureTypeIntrospected();

String type = getWrappedElementType();
return type.equals(String.class.getName())
return isStringType()
|| String.class.getName().equals(type)
|| isPrimitiveWrappedType(type)
|| hasEnumContainedElementType()
|| isEnumType()
Expand Down Expand Up @@ -591,7 +594,7 @@ public boolean hasVirtualImpl() {

public String getUnwrappedElementType() {
return isContainerType() && nullElements.ban()
? unwrapType(containmentTypeName())
? unwrapType(firstTypeParameter())
: getElementType();
}

Expand All @@ -602,11 +605,16 @@ public String getUnwrappedValueElementType() {
}

public String getWrappedElementType() {
return wrapType(containmentTypeName());
if (returnType.getKind().isPrimitive()) {
return wrapType(Ascii.toLowerCase(returnType.getKind().name()));
}
return wrapType(hasContainedElementType()
? firstTypeParameter()
: returnTypeName);
}

private String containmentTypeName() {
return (isArrayType() || isContainerType()) ? firstTypeParameter() : returnTypeName;
private boolean hasContainedElementType() {
return isArrayType() || isContainerType();
}

public String getRawType() {
Expand All @@ -615,7 +623,8 @@ public String getRawType() {

public String getConsumedElementType() {
return (isUnwrappedElementPrimitiveType()
|| String.class.getName().equals(containmentTypeName())
|| isStringType()
|| (hasContainedElementType() && firstTypeParameter().equals(String.class.getName()))
|| hasEnumFirstTypeParameter())
? getWrappedElementType()
: "? extends " + getWrappedElementType();
Expand Down Expand Up @@ -656,7 +665,7 @@ public String secondTypeParameter() {
}

public String getElementType() {
return containmentTypeName();
return hasContainedElementType() ? firstTypeParameter() : returnTypeName;
}

@Nullable
Expand Down

0 comments on commit 27799da

Please sign in to comment.