Skip to content

Commit

Permalink
#630 disable parcelable generation if CREATOR field is defined
Browse files Browse the repository at this point in the history
  • Loading branch information
elucash committed Jun 3, 2017
1 parent 3e1a1db commit ea48e68
Show file tree
Hide file tree
Showing 6 changed files with 79 additions and 16 deletions.
@@ -0,0 +1,42 @@
/*
Copyright 2017 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.parcelable;

import android.os.Parcel;
import android.os.Parcelable;
import org.immutables.value.Value;

// Having CREATOR field we suppress parcelable generation
@Value.Immutable
public abstract class CustomParcelable implements Parcelable {
public static final Parcelable.Creator<CustomParcelable> CREATOR = new Parcelable.Creator<CustomParcelable>() {
public CustomParcelable createFromParcel(Parcel in) {
throw new UnsupportedOperationException();
}

public CustomParcelable[] newArray(int size) {
throw new UnsupportedOperationException();
}
};

@Override
public final int describeContents() {
return 0;
}

@Override
public final void writeToParcel(Parcel dest, int flags) {}
}
Expand Up @@ -14,7 +14,7 @@
limitations under the License.
--]
[template public generate Type type]
[if type.parcelable]
[if type.generateParcelable]
[generateCreator type]
[generateParcelableMethods type]
[/if]
Expand All @@ -28,11 +28,11 @@ public static final android.os.Parcelable.ClassLoaderCreator<[type.typeValue.rel
public [type.typeValue.relative] createFromParcel(android.os.Parcel in) {
return createFromParcel(in, this.getClass().getClassLoader());
}

@SuppressWarnings("unchecked") [-- Guess this is needed for generic types casting --]
public [type.typeValue.relative] createFromParcel(android.os.Parcel in, ClassLoader classLoader) {
[generateParcelableBuild type]
}
}

public [type.typeValue.relative]['[]'] newArray(int size) {
return new [type.typeValue.relative]['[size]'];
Expand Down Expand Up @@ -152,4 +152,4 @@ return [type.factoryOf.relative]([for c in type.constructorArguments][if not for
[-- one liner templates are usually inlined by template compiler --]
[template castBuildStagedBuilder Type type String expression][for tb = type.telescopicBuild][if tb](([type.typeBuilderImpl.relative]) [expression])[else][expression][/if][/for][/template]

[template atNullable][if classpath.available 'javax.annotation.Nullable']@javax.annotation.Nullable [/if][/template]
[template atNullable][if classpath.available 'javax.annotation.Nullable']@javax.annotation.Nullable [/if][/template]
Expand Up @@ -45,7 +45,7 @@
final class AccessorAttributesCollector {
private static final String ORDINAL_ORDINAL_ATTRIBUTE_NAME = "ordinal";
private static final String ORDINAL_DOMAIN_ATTRIBUTE_NAME = "domain";
private static final String PARCELABLE_DESCRIBE_CONTENTS_ATTRIBUTE_NAME = "describeContents";
private static final String PARCELABLE_DESCRIBE_CONTENTS_METHOD = "describeContents";

private static final String ORG_ECLIPSE = "org.eclipse";

Expand Down Expand Up @@ -385,7 +385,7 @@ private AttributeNames deriveNames(String accessorName) {
return styles.forAccessorWithRaw(accessorName, accessorName);
}
break;
case PARCELABLE_DESCRIBE_CONTENTS_ATTRIBUTE_NAME:
case PARCELABLE_DESCRIBE_CONTENTS_METHOD:
if (type.isParcelable()) {
return styles.forAccessorWithRaw(accessorName, accessorName);
}
Expand Down
Expand Up @@ -1836,4 +1836,5 @@ && isAnnotatedWith(e, annotation)) {
static final String JACKSON_SERIALIZE = "com.fasterxml.jackson.databind.annotation.JsonSerialize";
static final String JACKSON_ANNOTATIONS_INSIDE = "com.fasterxml.jackson.annotation.JacksonAnnotationsInside";
static final String PARCELABLE_INTERFACE_TYPE = "android.os.Parcelable";
static final String PARCELABLE_CREATOR_FIELD = "CREATOR";
}
Expand Up @@ -512,8 +512,9 @@ public boolean isGenerateWithInterface() {

public boolean isUseCopyMethods() {
return !getSettableAttributes().isEmpty()
&& (isGenerateWithInterface() || (immutableFeatures.copy()
&& !constitution.isImplementationHidden()));
&& (isGenerateWithInterface()
|| (immutableFeatures.copy()
&& !constitution.isImplementationHidden()));
}

public boolean isUseCopyConstructor() {
Expand Down Expand Up @@ -593,7 +594,7 @@ public boolean isUseSingletonOnly() {
&& !isUseConstructor()
&& getWithSettableAfterConstruction().isEmpty();
}

public boolean isUseSingletonOnlyForConstruction() {
return isUseSingleton()
&& !useAttributelessSingleton()
Expand Down Expand Up @@ -915,7 +916,7 @@ public boolean hasAuxiliaryAttributes() {
}
return false;
}

public boolean hasSingleParameterConstructor() {
return isUseConstructor() && getConstructorArguments().size() == 1;
}
Expand Down Expand Up @@ -1285,6 +1286,21 @@ void detectSerialization() {
}
}

private boolean hasCreatorDefined;

void detectParcelableCreator() {
for (VariableElement v : ElementFilter.fieldsIn(element.getEnclosedElements())) {
if (v.getSimpleName().contentEquals(Proto.PARCELABLE_CREATOR_FIELD)) {
hasCreatorDefined = true;
break;
}
}
}

public boolean isGenerateParcelable() {
return isParcelable() && !hasCreatorDefined;
}

public Set<String> getImmutableCopyOfRoutines() {
Set<String> routines = new LinkedHashSet<>();
routines.addAll(constitution.style().immutableCopyOfRoutinesNames());
Expand Down Expand Up @@ -1352,8 +1368,8 @@ public ImmutableList<String> getDocComment() {
if (docComment == null) {
this.docComment = constitution.isImplementationPrimary()
|| constitution.style().getStyles().isImmutableIdentityNaming()
? extractDocComment(element)
: ImmutableList.<String>of();
? extractDocComment(element)
: ImmutableList.<String>of();
}
return docComment;
}
Expand All @@ -1366,7 +1382,8 @@ public Set<String> getNonAttributeAbstractMethodSignatures() {
if (element.getKind().isClass() || element.getKind().isInterface()) {
Set<String> signatures = new LinkedHashSet<>();

List<? extends Element> members = constitution.protoclass().environment()
List<? extends Element> members = constitution.protoclass()
.environment()
.processing()
.getElementUtils()
.getAllMembers(CachingElements.getDelegate((TypeElement) element));
Expand All @@ -1381,7 +1398,8 @@ public Set<String> getNonAttributeAbstractMethodSignatures() {
if (!AccessorAttributesCollector.isEclipseImplementation(m)) {
returnType = AccessorAttributesCollector.asInheritedMemberReturnType(
constitution.protoclass().processing(),
CachingElements.getDelegate((TypeElement) element), m);
CachingElements.getDelegate((TypeElement) element),
m);
}
signatures.add(toSignature(m, returnType));
}
Expand Down Expand Up @@ -1565,15 +1583,16 @@ public GsonTypeTokens getGsonTypeTokens() {
private TypeExtractor getTypeExtractor() {
if (typeExtractor == null) {
this.typeExtractor = new TypeExtractor(
Proto.TYPE_FACTORY, (Parameterizable) element);
Proto.TYPE_FACTORY,
(Parameterizable) element);
}
return typeExtractor;
}

public Reporter report() {
return constitution.protoclass().report();
}

public List<String> getDebugLines() {
return constitution.protoclass().getDebugLines();
}
Expand Down
Expand Up @@ -70,6 +70,7 @@ void compose(ValueType type, Protoclass protoclass) {
}

type.detectSerialization();
type.detectParcelableCreator();
}

checkAttributeNamesIllegalCharacters(type);
Expand Down

0 comments on commit ea48e68

Please sign in to comment.