Skip to content
This repository has been archived by the owner on Aug 26, 2021. It is now read-only.

Commit

Permalink
Merge pull request #124 from vimeo/develop
Browse files Browse the repository at this point in the history
Release 2.3.2
  • Loading branch information
anthonycr authored Jul 14, 2017
2 parents 4bb93ae + a877aa9 commit 8527b99
Show file tree
Hide file tree
Showing 11 changed files with 115 additions and 45 deletions.
5 changes: 5 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,11 @@
Change Log
==========

Version 2.3.2 *(2017-07-14)*
----------------------------
- Fixed a bug where stag was unable to find setters/getters for parameterized private fields.
- Found solution for model list file being included in build (refer to README).

Version 2.3.1 *(2017-06-27)*
----------------------------
- Stag is now being deployed to Maven Central.
Expand Down
27 changes: 11 additions & 16 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,19 +2,8 @@

Stag improves Gson performance by automatically generating reflection-less TypeAdapters for your model objects.

| Branch | Build Status |
|--------|--------------|
| master | [![Build Status](https://travis-ci.org/vimeo/stag-java.svg?branch=master)](https://travis-ci.org/vimeo/stag-java) |
| dev | [![Build Status](https://travis-ci.org/vimeo/stag-java.svg?branch=dev)](https://travis-ci.org/vimeo/stag-java) |
[![Build Status](https://travis-ci.org/vimeo/stag-java.svg?branch=master)](https://travis-ci.org/vimeo/stag-java) [![codecov](https://codecov.io/gh/vimeo/stag-java/branch/dev/graph/badge.svg)](https://codecov.io/gh/vimeo/stag-java) [![Download](https://api.bintray.com/packages/vimeo/maven/stag-library/images/download.svg)](https://bintray.com/vimeo/maven/stag-library/_latestVersion) [![Javadocs](https://www.javadoc.io/badge/com.vimeo.stag/stag-library.svg)](https://www.javadoc.io/doc/com.vimeo.stag/stag-library)

| Test Coverage |
|---------------|
| [![codecov](https://codecov.io/gh/vimeo/stag-java/branch/dev/graph/badge.svg)](https://codecov.io/gh/vimeo/stag-java) |

| Artifact | Latest Version |
|----------|----------------|
| stag-library | [![Download](https://api.bintray.com/packages/vimeo/maven/stag-library/images/download.svg)](https://bintray.com/vimeo/maven/stag-library/_latestVersion) |
| stag-library-compiler | [![Download](https://api.bintray.com/packages/vimeo/maven/stag-library-compiler/images/download.svg)](https://bintray.com/vimeo/maven/stag-library-compiler/_latestVersion) |

## Why Build Stag?

Expand Down Expand Up @@ -49,8 +38,8 @@ buildscript {
apply plugin: 'net.ltgt.apt'
dependencies {
compile 'com.vimeo.stag:stag-library:2.3.1'
apt 'com.vimeo.stag:stag-library-compiler:2.3.1'
compile 'com.vimeo.stag:stag-library:2.3.2'
apt 'com.vimeo.stag:stag-library-compiler:2.3.2'
}
// Optional annotation processor arguments (see below)
Expand All @@ -67,8 +56,8 @@ apt {

```groovy
dependencies {
compile 'com.vimeo.stag:stag-library:2.3.1'
annotationProcessor 'com.vimeo.stag:stag-library-compiler:2.3.1'
compile 'com.vimeo.stag:stag-library:2.3.2'
annotationProcessor 'com.vimeo.stag:stag-library-compiler:2.3.2'
}
android {
Expand Down Expand Up @@ -145,6 +134,12 @@ Last but not the least, Stag is almost in parity with GSON.
6. Register the `Stag.Factory` with Gson when you create your Gson instance: `Gson gson = new GsonBuilder().registerTypeAdapterFactory(new Stag.Factory()).create();`
7. Make sure that you are not reusing the `Stag.Factory` instance between Gson instances. The factory is stateful and must be recreated when creating a new Gson instance. If you try to reuse the instance, an `UnsupportedOperationException` will be thrown.
8. You're done!
9. [Optional] By default, stag will drop a file called `StagTypeAdapterFactory.list` into your build folder which contains the plaintext names of all your models. It is used by the compiler to generate the adapters. It's a very small file and will compress down to a few bytes in size, but if you don't want it in your compiled apk, you can exclude it using the following code (if you supply a custom package name as a compiler argument, use that in place of `com/vimeo/stag/generated/` below):
```groovy
packagingOptions {
exclude 'com/vimeo/stag/generated/StagTypeAdapterFactory.list'
}
```

See the [example below](#example) or the [sample app](sample) to get more info on how to use Stag.

Expand Down
2 changes: 1 addition & 1 deletion build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -38,5 +38,5 @@ allprojects {

subprojects {
group = 'com.vimeo.stag'
version = '2.3.1'
version = '2.3.2'
}
5 changes: 3 additions & 2 deletions sample-model/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -21,8 +21,9 @@ android {
javaCompileOptions {
annotationProcessorOptions {
arguments = [
stagGeneratedPackageName: 'com.vimeo.sample_model.stag.generated',
stagDebug : 'true'
stagGeneratedPackageName : 'com.vimeo.sample_model.stag.generated',
stagDebug : 'true',
stagAssumeHungarianNotation: 'true'
]
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,11 +9,35 @@
public class ExternalModelGeneric1<T> {

@SerializedName("field2")
public String mField2;
private String mField2;

@SerializedName("genericField")
public T mGenericField;
private T mGenericField;

@SerializedName("unknownType")
public ValueCallback<T> mUnknownType;
private ValueCallback<T> mUnknownType;

public String getField2() {
return mField2;
}

public void setField2(String field2) {
mField2 = field2;
}

public T getGenericField() {
return mGenericField;
}

public void setGenericField(T genericField) {
mGenericField = genericField;
}

public ValueCallback<T> getUnknownType() {
return mUnknownType;
}

public void setUnknownType(ValueCallback<T> unknownType) {
mUnknownType = unknownType;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -108,8 +108,8 @@ public static Set<TypeMirror> annotatedClassToTypeMirror(@NotNull Collection<Ann
AnnotatedClass genericInheritedType = mSupportedTypesModel.addToKnownInheritedType(inheritedType, fieldOption);

LinkedHashMap<FieldAccessor, TypeMirror> inheritedMemberVariables = TypeUtils.getConcreteMembers(inheritedType,
genericInheritedType.getElement(),
genericInheritedType.getMemberVariables());
genericInheritedType.getElement(),
genericInheritedType.getMemberVariables());

for (Map.Entry<FieldAccessor, TypeMirror> entry : inheritedMemberVariables.entrySet()) {
addMemberVariable(entry.getKey(), entry.getValue(), variableNames);
Expand All @@ -132,7 +132,7 @@ private void addMemberVariable(@NotNull FieldAccessor element, @NotNull TypeMirr
if (null != previousElement) {
mMemberVariables.remove(previousElement);
MessagerUtils.logInfo("Ignoring inherited Member variable with the same variable name in class" +
element.toString() + ", with variable name " + previousElement.asType().toString());
element.toString() + ", with variable name " + previousElement.asType().toString());
}
mMemberVariables.put(element, typeMirror);
}
Expand All @@ -142,9 +142,9 @@ private static boolean checkPrivateFinalModifiers(@NotNull VariableElement varia

if (modifiers.contains(Modifier.FINAL)) {
MessagerUtils.reportError("Unable to access field \"" +
variableElement.getSimpleName().toString() + "\" in class " +
variableElement.getEnclosingElement().asType() +
", field must not be final.", variableElement);
variableElement.getSimpleName().toString() + "\" in class " +
variableElement.getEnclosingElement().asType() +
", field must not be final.", variableElement);
}

return modifiers.contains(Modifier.FINAL) || modifiers.contains(Modifier.PRIVATE);
Expand All @@ -165,7 +165,7 @@ private void addToSupportedTypes(@NotNull VariableElement element, @NotNull Fiel
try {
addMemberVariable(new MethodFieldAccessor(element, mNamingNotation), element.asType(), variableNames);
} catch (UnsupportedOperationException exception) {
MessagerUtils.reportError("Unable to find getter/setter for private/final field", element);
MessagerUtils.reportError(exception.getMessage(), element);
}
} else {
addMemberVariable(new DirectFieldAccessor(element), element.asType(), variableNames);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -124,7 +124,7 @@ public boolean equals(Object o) {
ClassInfo classInfo = (ClassInfo) o;

return mClassName.equals(classInfo.mClassName) && mPackageName.equals(classInfo.mPackageName) &&
mTypeName.equals(classInfo.mTypeName) && mType.equals(classInfo.mType);
mTypeName.equals(classInfo.mTypeName) && TypeUtils.areEqual(mType, classInfo.mType);

}

Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package com.vimeo.stag.processor.generators.model.accessor;

import com.vimeo.stag.processor.utils.MessagerUtils;
import com.vimeo.stag.processor.utils.TypeUtils;

import org.jetbrains.annotations.NotNull;

Expand Down Expand Up @@ -59,8 +60,6 @@ private static List<ExecutableElement> getSiblingMethods(@NotNull VariableElemen
List<ExecutableElement> methodElements = new ArrayList<>();
List<? extends Element> otherElements = variableElement.getEnclosingElement().getEnclosedElements();

MessagerUtils.logInfo("Looking for setter and getter");

for (Element element : otherElements) {
if (element.getKind() == ElementKind.METHOD && element instanceof ExecutableElement) {
methodElements.add((ExecutableElement) element);
Expand All @@ -73,15 +72,15 @@ private static List<ExecutableElement> getSiblingMethods(@NotNull VariableElemen
@NotNull
private static String findSetterMethodName(@NotNull VariableElement variableElement,
@NotNull Notation namingNotation) throws UnsupportedOperationException {
MessagerUtils.logInfo("Looking for setter and getter");
MessagerUtils.logInfo("Looking for setter");

for (ExecutableElement method : getSiblingMethods(variableElement)) {

List<? extends VariableElement> parameters = method.getParameters();

if (method.getReturnType().getKind() == TypeKind.VOID &&
parameters.size() == 1 &&
parameters.get(0).asType().equals(variableElement.asType()) &&
TypeUtils.areEqual(parameters.get(0).asType(), variableElement.asType()) &&
method.getSimpleName().toString().equals("set" + getVariableNameAsMethodName(variableElement, namingNotation))) {
MessagerUtils.logInfo("Found setter");

Expand All @@ -96,11 +95,11 @@ private static String findSetterMethodName(@NotNull VariableElement variableElem
@NotNull
private static String findGetterMethodName(@NotNull VariableElement variableElement,
@NotNull Notation namingNotation) throws UnsupportedOperationException {
MessagerUtils.logInfo("Looking for setter and getter");
MessagerUtils.logInfo("Looking for getter");

for (ExecutableElement method : getSiblingMethods(variableElement)) {

if (method.getReturnType().equals(variableElement.asType()) &&
if (TypeUtils.areEqual(method.getReturnType(), variableElement.asType()) &&
method.getParameters().isEmpty() &&
method.getSimpleName().toString().equals("get" + getVariableNameAsMethodName(variableElement, namingNotation))) {

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -164,6 +164,18 @@ public static List<? extends TypeMirror> getTypeArguments(@Nullable TypeMirror t
return type instanceof DeclaredType ? ((DeclaredType) type).getTypeArguments() : null;
}

/**
* TypeMirrors should not be compared directly, but should use
* {@link Types} in order to compare them.
*
* @param typeMirror1 the first type to compare.
* @param typeMirror2 the second type to compare.
* @return true if they are equal, false otherwise.
*/
public static boolean areEqual(@NotNull TypeMirror typeMirror1, @NotNull TypeMirror typeMirror2) {
return getUtils().isSameType(typeMirror1, typeMirror2);
}

/**
* Determines whether or not the Element is a concrete type.
* If the element is a generic type or contains generic type
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -143,7 +143,7 @@ public void getConcreteMembers_isCorrect() throws Exception {
assertTrue(entry.getValue()
.toString()
.equals(types.getDeclaredType(Utils.getElementFromClass(ArrayList.class),
stringType).toString()));
stringType).toString()));

} else if (entry.getKey().createGetterCode().contentEquals("testMap = ")) {

Expand All @@ -162,15 +162,15 @@ public void getConcreteMembers_isCorrect() throws Exception {
TypeMirror listString = types.getDeclaredType(Utils.getElementFromClass(List.class), stringType);

assertTrue(entry.getValue()
.toString()
.equals(types.getDeclaredType(Utils.getElementFromClass(HashMap.class), stringType, listString)
.toString()));
.toString()
.equals(types.getDeclaredType(Utils.getElementFromClass(HashMap.class), stringType, listString)
.toString()));
} else if (entry.getKey().createGetterCode().contentEquals("testListMap = ")) {
TypeMirror mapStringString = types.getDeclaredType(Utils.getElementFromClass(Map.class), stringType, stringType);
assertTrue(entry.getValue()
.toString()
.equals(types.getDeclaredType(Utils.getElementFromClass(ArrayList.class), mapStringString)
.toString()));
.toString()
.equals(types.getDeclaredType(Utils.getElementFromClass(ArrayList.class), mapStringString)
.toString()));
}
}
}
Expand All @@ -189,6 +189,20 @@ public void isEnum_isCorrect() throws Exception {
assertFalse(TypeUtils.isEnum(Utils.getElementFromClass(String.class)));
}

@Test
public void areEqual_isCorrect() {
assertTrue(TypeUtils.areEqual(Utils.getTypeMirrorFromClass(Object.class), Utils.getTypeMirrorFromClass(Object.class)));
assertTrue(TypeUtils.areEqual(Utils.getTypeMirrorFromClass(String.class), Utils.getTypeMirrorFromClass(String.class)));
assertTrue(TypeUtils.areEqual(Utils.getTypeMirrorFromClass(List.class), Utils.getTypeMirrorFromClass(List.class)));

assertFalse(TypeUtils.areEqual(Utils.getTypeMirrorFromClass(Object.class), Utils.getTypeMirrorFromClass(String.class)));
assertFalse(TypeUtils.areEqual(Utils.getTypeMirrorFromClass(String.class), Utils.getTypeMirrorFromClass(List.class)));
assertFalse(TypeUtils.areEqual(Utils.getTypeMirrorFromClass(List.class), Utils.getTypeMirrorFromClass(ArrayList.class)));

assertTrue(TypeUtils.areEqual(Utils.getParameterizedClass(List.class, String.class), Utils.getParameterizedClass(List.class, String.class)));
assertFalse(TypeUtils.areEqual(Utils.getParameterizedClass(List.class, String.class), Utils.getParameterizedClass(List.class, Integer.class)));
}

@Test
public void isParameterizedType_isCorrect() throws Exception {

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@

import javax.lang.model.element.TypeElement;
import javax.lang.model.element.TypeParameterElement;
import javax.lang.model.type.DeclaredType;
import javax.lang.model.type.TypeMirror;
import javax.lang.model.util.Elements;
import javax.lang.model.util.Types;
Expand Down Expand Up @@ -83,6 +84,25 @@ public static <T> void testZeroArgumentConstructorFinalClass(Class<T> clazz) thr
assertTrue(exceptionThrown);
}

/**
* Gets the parameterized class with the given parameters.
*
* @param clazz the class to parameterize.
* @param parameters the parameters to use.
* @return the declared type mirror with the correct type parameters.
*/
@NotNull
public static DeclaredType getParameterizedClass(@NotNull Class clazz, @NotNull Class... parameters) {
TypeElement rootType = safeElements().getTypeElement(clazz.getName());
TypeMirror[] params = new TypeMirror[parameters.length];

for (int n = 0; n < parameters.length; n++) {
params[n] = safeElements().getTypeElement(parameters[n].getName()).asType();
}

return safeTypes().getDeclaredType(rootType, params);
}

@Nullable
public static TypeElement getElementFromClass(@NotNull Class clazz) {
return safeElements().getTypeElement(clazz.getName());
Expand All @@ -108,13 +128,13 @@ public static TypeMirror getTypeMirrorFromObject(@NotNull Object object) {
@NotNull
public static TypeMirror getGenericVersionOfClass(@NotNull Class clazz) {
List<? extends TypeParameterElement> params =
safeElements().getTypeElement(clazz.getName()).getTypeParameters();
safeElements().getTypeElement(clazz.getName()).getTypeParameters();
TypeMirror[] genericTypes = new TypeMirror[params.size()];
for (int n = 0; n < genericTypes.length; n++) {
genericTypes[n] = params.get(n).asType();
}
return safeTypes().getDeclaredType(safeElements().getTypeElement(DummyGenericClass.class.getName()),
genericTypes);
genericTypes);
}

}

0 comments on commit 8527b99

Please sign in to comment.