From 2a15bc3f3becaebe9043813d21dc48440c7c30be Mon Sep 17 00:00:00 2001 From: Anthony Restaino Date: Wed, 28 Jun 2017 10:26:41 -0400 Subject: [PATCH 1/6] Updating readme badges, adding javadoc badge --- README.md | 15 ++------------- 1 file changed, 2 insertions(+), 13 deletions(-) diff --git a/README.md b/README.md index cf40d19f..4db38cf4 100644 --- a/README.md +++ b/README.md @@ -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) | - -| 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) | +[![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) + ## Why Build Stag? From b761ef1f4af3ca16ba943e7a9b9a6b066b9cd7d2 Mon Sep 17 00:00:00 2001 From: Mathias Griffe Date: Tue, 27 Jun 2017 15:53:15 -0400 Subject: [PATCH 2/6] CI-487: publish stag artifacts and doc to MavenCentral --- .travis.yml | 2 +- CHANGELOG.md | 4 ++ README.md | 8 +-- build.gradle | 4 +- fastlane/Fastfile | 36 +++++++++- fastlane/README.md | 40 ++++++++++- stag-library-compiler/build.gradle | 70 +++++++++++++++---- .../vimeo/stag/processor/utils/TypeUtils.java | 12 ++-- stag-library/build.gradle | 70 +++++++++++++++---- .../src/main/java/com/vimeo/stag/UseStag.java | 4 +- 10 files changed, 202 insertions(+), 48 deletions(-) diff --git a/.travis.yml b/.travis.yml index 9017920b..ecd68547 100644 --- a/.travis.yml +++ b/.travis.yml @@ -20,7 +20,7 @@ script: - rvm install 2.2 - rvm use 2.2 - bundle install -- FASTLANE_SKIP_UPDATE_CHECK=1 bundle exec fastlane test +- FASTLANE_SKIP_UPDATE_CHECK=1 bundle exec fastlane shipit - ./gradlew jacocoTestReport --stacktrace after_success: - bash <(curl -s https://codecov.io/bash) diff --git a/CHANGELOG.md b/CHANGELOG.md index 3aa56c3b..4b162b84 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,6 +1,10 @@ Change Log ========== +Version 2.3.1 *(2017-06-27)* +---------------------------- +- Stag is now being deployed to Maven Central. + Version 2.3.0 *(2017-06-22)* ---------------------------- - Stag now throws an exception if you try to reuse a `Stag.Factory` instance between multiple gson instances. diff --git a/README.md b/README.md index dc551a91..cf40d19f 100644 --- a/README.md +++ b/README.md @@ -49,8 +49,8 @@ buildscript { apply plugin: 'net.ltgt.apt' dependencies { - compile 'com.vimeo.stag:stag-library:2.3.0' - apt 'com.vimeo.stag:stag-library-compiler:2.3.0' + compile 'com.vimeo.stag:stag-library:2.3.1' + apt 'com.vimeo.stag:stag-library-compiler:2.3.1' } // Optional annotation processor arguments (see below) @@ -67,8 +67,8 @@ apt { ```groovy dependencies { - compile 'com.vimeo.stag:stag-library:2.3.0' - annotationProcessor 'com.vimeo.stag:stag-library-compiler:2.3.0' + compile 'com.vimeo.stag:stag-library:2.3.1' + annotationProcessor 'com.vimeo.stag:stag-library-compiler:2.3.1' } android { diff --git a/build.gradle b/build.gradle index 5639bd57..8109963a 100644 --- a/build.gradle +++ b/build.gradle @@ -15,7 +15,7 @@ buildscript { } dependencies { classpath 'com.android.tools.build:gradle:2.3.3' - classpath 'com.jfrog.bintray.gradle:gradle-bintray-plugin:1.7' + classpath 'com.jfrog.bintray.gradle:gradle-bintray-plugin:1.7.3' classpath 'com.dicedmelon.gradle:jacoco-android:0.1.1' classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version" } @@ -38,5 +38,5 @@ allprojects { subprojects { group = 'com.vimeo.stag' - version = '2.3.0' + version = '2.3.1' } diff --git a/fastlane/Fastfile b/fastlane/Fastfile index a9f83772..e7deeabb 100644 --- a/fastlane/Fastfile +++ b/fastlane/Fastfile @@ -28,12 +28,42 @@ platform :android do end end + desc "main entrypoint for CI" + lane :shipit do + if is_ci + # If the build was triggered by a Pull Request + if ENV['TRAVIS_PULL_REQUEST'] && ENV['TRAVIS_PULL_REQUEST'] != 'false' + test + else + # This build was triggered by a branch update + branch = git_branch + # If the branch is master, this means new updates were merged into master + # Then publish the artifacts to bintray + if branch == 'master' + publish_artifacts( + snapshot: false + ) + + # TODO: publish Snapshots with snapshot = true + end + end + end + end + + desc "publish artifacts to bintray. Use the 'snapshot' option (boolean) to publish a Snapshot instead of a release (not implemented yet)" + lane :publish_artifacts do |options| + # Upload to bintray + gradle( + task: "stag-library:bintrayUpload stag-library-compiler:bintrayUpload", + properties: { + "snapshot" => options[:snapshot] + } + ) + end + desc "test" lane :test do - # gotta do some setup before running gradle - sh 'touch ../local.properties' - # run the tests, but dont puke everywhere until the report is printed. junit_report_path_array = [ "stag-library/build/test-results/test/*.xml", diff --git a/fastlane/README.md b/fastlane/README.md index 51e5c38d..a79be552 100644 --- a/fastlane/README.md +++ b/fastlane/README.md @@ -1,11 +1,45 @@ fastlane documentation ================ # Installation + +Make sure you have the latest version of the Xcode command line tools installed: + ``` -sudo gem install fastlane +xcode-select --install ``` + +## Choose your installation method: + + + + + + + + + + + + + + +
Homebrew +Installer Script +Rubygems +
macOSmacOSmacOS or Linux with Ruby 2.0.0 or above
brew cask install fastlaneDownload the zip file. Then double click on the install script (or run it in a terminal window).sudo gem install fastlane -NV
+ # Available Actions ## Android +### android shipit +``` +fastlane android shipit +``` +main entrypoint for CI +### android publish_artifacts +``` +fastlane android publish_artifacts +``` +publish artifacts to bintray. Use the 'snapshot' option (boolean) to publish a Snapshot instead of a release (not implemented yet) ### android test ``` fastlane android test @@ -15,5 +49,5 @@ test ---- This README.md is auto-generated and will be re-generated every time [fastlane](https://fastlane.tools) is run. -More information about fastlane can be found on [https://fastlane.tools](https://fastlane.tools). -The documentation of fastlane can be found on [GitHub](https://github.com/fastlane/fastlane/tree/master/fastlane). +More information about fastlane can be found on [fastlane.tools](https://fastlane.tools). +The documentation of fastlane can be found on [docs.fastlane.tools](https://docs.fastlane.tools). diff --git a/stag-library-compiler/build.gradle b/stag-library-compiler/build.gradle index a61f2aec..e35c952f 100644 --- a/stag-library-compiler/build.gradle +++ b/stag-library-compiler/build.gradle @@ -47,6 +47,8 @@ task sourcesJar(type: Jar, dependsOn: classes) { from sourceSets.main.allSource } +tasks.withType(Javadoc).all { enabled = true } + task javadocJar(type: Jar, dependsOn: javadoc) { classifier = 'javadoc' from javadoc.destinationDir @@ -56,35 +58,67 @@ artifacts { archives sourcesJar, javadocJar } +// Create the pom configuration +// All the fields below are required by Maven Central +def pomConfig = { + licenses { + license { + name "MIT License" + url "http://www.opensource.org/licenses/mit-license.php" + distribution "repo" + } + } + developers { + developer { + id "vimeo" + name "Vimeo Mobile" + email "mobileops@vimeo.com" + organisation "Vimeo" + organisationUrl "https://github.com/vimeo" + } + } + + scm { + connection "scm:git:git://github.com/vimeo/stag-java.git" + developerConnection "scm:git:ssh://github.com:vimeo/stag-java.git" + url "https://github.com/vimeo/stag-java" + } +} + +// Create the publication with the pom configuration: // Requires apply plugin: maven-publish publishing { publications { - mavenJava(MavenPublication) { - // We don't have any complex artifacts, so let's just - // reference the fact that we rely on plugin java + MyPublication(MavenPublication) { from components.java + artifact sourcesJar + artifact javadocJar groupId project.group artifactId 'stag-library-compiler' version project.version - - artifact sourcesJar - artifact javadocJar + pom.withXml { + def root = asNode() + root.appendNode('description', 'Stag improves Gson performance by automatically generating reflection-less TypeAdapters for your model objects.') + root.appendNode('name', 'stag-library-compiler') + root.appendNode('url', 'https://github.com/vimeo/stag-java') + root.children().last() + pomConfig + } } } } -// Only execute the bintray task if this is the actual stag-library-compilers project (not an include) +// Only execute the bintray task if this is the actual networking project (not an include) allprojects { afterEvaluate { project -> def bintrayProject = project.plugins.hasPlugin('com.jfrog.bintray') if (bintrayProject) { bintray { - Properties properties = new Properties() - properties.load(project.rootProject.file('local.properties').newDataInputStream()) - user = properties.getProperty('bintray.user') - key = properties.getProperty('bintray.apikey') - publications = ['mavenJava'] + user = System.getenv('BINTRAY_USER') + // api key + key = System.getenv('BINTRAY_API_KEY') + publications = ['MyPublication'] dryRun = false // Whether to run this as dry-run, without deploying + override = false pkg { repo = 'maven' name = 'stag-library-compiler' @@ -98,9 +132,19 @@ allprojects { version { name = project.version vcsTag = project.version + gpg { + sign = true + passphrase = System.getenv('BINTRAY_GPG_PASSWORD') + } + mavenCentralSync { + sync = true //Optional (true by default). Determines whether to sync the version to Maven Central. + user = System.getenv('SONATYPE_TOKEN_USER') //OSS user token + password = System.getenv('SONATYPE_TOKEN_PASSWORD') //OSS user password + close = '1' //Optional property. By default the staging repository is closed and artifacts are released to Maven Central. You can optionally turn this behaviour off (by puting 0 as value) and release the version manually. + } } } } } } -} \ No newline at end of file +} diff --git a/stag-library-compiler/src/main/java/com/vimeo/stag/processor/utils/TypeUtils.java b/stag-library-compiler/src/main/java/com/vimeo/stag/processor/utils/TypeUtils.java index d3d0a6d9..9ca8f2c7 100644 --- a/stag-library-compiler/src/main/java/com/vimeo/stag/processor/utils/TypeUtils.java +++ b/stag-library-compiler/src/main/java/com/vimeo/stag/processor/utils/TypeUtils.java @@ -301,22 +301,20 @@ public static boolean isEnum(@Nullable TypeElement element) { * Retrieves a Map of the inherited concrete member variables of an Element. This takes all the * member variables that were inherited from the generic parent class and evaluates what their concrete * type will be based on the concrete inherited type. For instance, take the following code example: - *
-     * {@code
-     * Factory {
+     * 

+     * {@literal Factory} {
      *
-     *  @literal @UseStag
+     *  {@literal @UseStag}
      *   public T data;
      *
      * }
      *
-     * VideoFactory extends Factory
+ *
* In this example, VideoFactory has a public member variable T that is of type Video. * Since the Factory class has the UseStag annotation, we cannot just generate * parsing code for the Factory class, since it is generic and we need concrete types. diff --git a/stag-library/build.gradle b/stag-library/build.gradle index c50b1d18..7f1e8d01 100644 --- a/stag-library/build.gradle +++ b/stag-library/build.gradle @@ -27,6 +27,8 @@ dependencies { testCompile 'junit:junit:4.12' } +tasks.withType(Javadoc).all { enabled = true } + // custom tasks for creating source/javadoc jars task sourcesJar(type: Jar, dependsOn: classes) { classifier = 'sources' @@ -42,35 +44,67 @@ artifacts { archives sourcesJar, javadocJar } +// Create the pom configuration +// All the fields below are required by Maven Central +def pomConfig = { + licenses { + license { + name "MIT License" + url "http://www.opensource.org/licenses/mit-license.php" + distribution "repo" + } + } + developers { + developer { + id "vimeo" + name "Vimeo Mobile" + email "mobileops@vimeo.com" + organisation "Vimeo" + organisationUrl "https://github.com/vimeo" + } + } + + scm { + connection "scm:git:git://github.com/vimeo/stag-java.git" + developerConnection "scm:git:ssh://github.com:vimeo/stag-java.git" + url "https://github.com/vimeo/stag-java" + } +} + +// Create the publication with the pom configuration: // Requires apply plugin: maven-publish publishing { publications { - mavenJava(MavenPublication) { - // We don't have any complex artifacts, so let's just - // reference the fact that we rely on the java plugin + MyPublication(MavenPublication) { from components.java + artifact sourcesJar + artifact javadocJar groupId project.group artifactId 'stag-library' version project.version - - artifact sourcesJar - artifact javadocJar + pom.withXml { + def root = asNode() + root.appendNode('description', 'Stag improves Gson performance by automatically generating reflection-less TypeAdapters for your model objects.') + root.appendNode('name', 'stag-library') + root.appendNode('url', 'https://github.com/vimeo/stag-java') + root.children().last() + pomConfig + } } } } -// Only execute the bintray task if this is the actual stag-library project (not an include) +// Only execute the bintray task if this is the actual networking project (not an include) allprojects { afterEvaluate { project -> def bintrayProject = project.plugins.hasPlugin('com.jfrog.bintray') if (bintrayProject) { bintray { - Properties properties = new Properties() - properties.load(project.rootProject.file('local.properties').newDataInputStream()) - user = properties.getProperty('bintray.user') - key = properties.getProperty('bintray.apikey') - publications = ['mavenJava'] + user = System.getenv('BINTRAY_USER') + // api key + key = System.getenv('BINTRAY_API_KEY') + publications = ['MyPublication'] dryRun = false // Whether to run this as dry-run, without deploying + override = false pkg { repo = 'maven' name = 'stag-library' @@ -84,9 +118,19 @@ allprojects { version { name = project.version vcsTag = project.version + gpg { + sign = true + passphrase = System.getenv('BINTRAY_GPG_PASSWORD') + } + mavenCentralSync { + sync = true //Optional (true by default). Determines whether to sync the version to Maven Central. + user = System.getenv('SONATYPE_TOKEN_USER') //OSS user token + password = System.getenv('SONATYPE_TOKEN_PASSWORD') //OSS user password + close = '1' //Optional property. By default the staging repository is closed and artifacts are released to Maven Central. You can optionally turn this behaviour off (by puting 0 as value) and release the version manually. + } } } } } } -} \ No newline at end of file +} diff --git a/stag-library/src/main/java/com/vimeo/stag/UseStag.java b/stag-library/src/main/java/com/vimeo/stag/UseStag.java index 28a605c8..f3ff9acd 100644 --- a/stag-library/src/main/java/com/vimeo/stag/UseStag.java +++ b/stag-library/src/main/java/com/vimeo/stag/UseStag.java @@ -33,10 +33,10 @@ /** * Use this annotation to tell Stag that all the member variables * of the class should be processed. - *

+ *

* If the class is annotated, Stag will generate a TypeAdapter for * that class. Stag does not generate TypeAdapters for abstract classes. - *

+ *

*/ @Target({ElementType.TYPE}) public @interface UseStag { From 7a4471e4579f4ddbd0e463bbf37c82a83b2d2093 Mon Sep 17 00:00:00 2001 From: Anthony Restaino Date: Wed, 12 Jul 2017 11:46:28 -0400 Subject: [PATCH 3/6] Fix bug where private parameterized fields could not be found The issue was using direct type comparison rather than the Types.isSameType for comparison --- sample-model/build.gradle | 5 ++-- .../sample_model/ExternalModelGeneric1.java | 30 +++++++++++++++++-- .../generators/model/AnnotatedClass.java | 14 ++++----- .../processor/generators/model/ClassInfo.java | 2 +- .../model/accessor/MethodFieldAccessor.java | 11 ++++--- .../vimeo/stag/processor/utils/TypeUtils.java | 12 ++++++++ 6 files changed, 55 insertions(+), 19 deletions(-) diff --git a/sample-model/build.gradle b/sample-model/build.gradle index 6213cd49..5c048982 100644 --- a/sample-model/build.gradle +++ b/sample-model/build.gradle @@ -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' ] } } diff --git a/sample-model/src/main/java/com/vimeo/sample_model/ExternalModelGeneric1.java b/sample-model/src/main/java/com/vimeo/sample_model/ExternalModelGeneric1.java index 2e3ef8df..7cbabeaa 100644 --- a/sample-model/src/main/java/com/vimeo/sample_model/ExternalModelGeneric1.java +++ b/sample-model/src/main/java/com/vimeo/sample_model/ExternalModelGeneric1.java @@ -9,11 +9,35 @@ public class ExternalModelGeneric1 { @SerializedName("field2") - public String mField2; + private String mField2; @SerializedName("genericField") - public T mGenericField; + private T mGenericField; @SerializedName("unknownType") - public ValueCallback mUnknownType; + private ValueCallback 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 getUnknownType() { + return mUnknownType; + } + + public void setUnknownType(ValueCallback unknownType) { + mUnknownType = unknownType; + } } \ No newline at end of file diff --git a/stag-library-compiler/src/main/java/com/vimeo/stag/processor/generators/model/AnnotatedClass.java b/stag-library-compiler/src/main/java/com/vimeo/stag/processor/generators/model/AnnotatedClass.java index 581ef122..b5b7bf94 100644 --- a/stag-library-compiler/src/main/java/com/vimeo/stag/processor/generators/model/AnnotatedClass.java +++ b/stag-library-compiler/src/main/java/com/vimeo/stag/processor/generators/model/AnnotatedClass.java @@ -108,8 +108,8 @@ public static Set annotatedClassToTypeMirror(@NotNull Collection inheritedMemberVariables = TypeUtils.getConcreteMembers(inheritedType, - genericInheritedType.getElement(), - genericInheritedType.getMemberVariables()); + genericInheritedType.getElement(), + genericInheritedType.getMemberVariables()); for (Map.Entry entry : inheritedMemberVariables.entrySet()) { addMemberVariable(entry.getKey(), entry.getValue(), variableNames); @@ -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); } @@ -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); @@ -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); diff --git a/stag-library-compiler/src/main/java/com/vimeo/stag/processor/generators/model/ClassInfo.java b/stag-library-compiler/src/main/java/com/vimeo/stag/processor/generators/model/ClassInfo.java index 9790451b..674782e9 100644 --- a/stag-library-compiler/src/main/java/com/vimeo/stag/processor/generators/model/ClassInfo.java +++ b/stag-library-compiler/src/main/java/com/vimeo/stag/processor/generators/model/ClassInfo.java @@ -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); } diff --git a/stag-library-compiler/src/main/java/com/vimeo/stag/processor/generators/model/accessor/MethodFieldAccessor.java b/stag-library-compiler/src/main/java/com/vimeo/stag/processor/generators/model/accessor/MethodFieldAccessor.java index 3ec59ec9..51395da3 100644 --- a/stag-library-compiler/src/main/java/com/vimeo/stag/processor/generators/model/accessor/MethodFieldAccessor.java +++ b/stag-library-compiler/src/main/java/com/vimeo/stag/processor/generators/model/accessor/MethodFieldAccessor.java @@ -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; @@ -59,8 +60,6 @@ private static List getSiblingMethods(@NotNull VariableElemen List methodElements = new ArrayList<>(); List 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); @@ -73,7 +72,7 @@ private static List 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)) { @@ -81,7 +80,7 @@ private static String findSetterMethodName(@NotNull VariableElement variableElem 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"); @@ -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))) { diff --git a/stag-library-compiler/src/main/java/com/vimeo/stag/processor/utils/TypeUtils.java b/stag-library-compiler/src/main/java/com/vimeo/stag/processor/utils/TypeUtils.java index 9ca8f2c7..d7ef3fb2 100644 --- a/stag-library-compiler/src/main/java/com/vimeo/stag/processor/utils/TypeUtils.java +++ b/stag-library-compiler/src/main/java/com/vimeo/stag/processor/utils/TypeUtils.java @@ -164,6 +164,18 @@ public static List 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(@Nullable TypeMirror typeMirror1, @Nullable 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 From a44d9bb8134546f1752362d5cae223d460c234c7 Mon Sep 17 00:00:00 2001 From: Anthony Restaino Date: Wed, 12 Jul 2017 15:19:54 -0400 Subject: [PATCH 4/6] Adding unit test for new TypeUtils method --- .../vimeo/stag/processor/utils/TypeUtils.java | 2 +- .../stag/processor/TypeUtilsUnitTest.java | 28 ++++++++++++++----- .../java/com/vimeo/stag/processor/Utils.java | 24 ++++++++++++++-- 3 files changed, 44 insertions(+), 10 deletions(-) diff --git a/stag-library-compiler/src/main/java/com/vimeo/stag/processor/utils/TypeUtils.java b/stag-library-compiler/src/main/java/com/vimeo/stag/processor/utils/TypeUtils.java index d7ef3fb2..60adde43 100644 --- a/stag-library-compiler/src/main/java/com/vimeo/stag/processor/utils/TypeUtils.java +++ b/stag-library-compiler/src/main/java/com/vimeo/stag/processor/utils/TypeUtils.java @@ -172,7 +172,7 @@ public static List getTypeArguments(@Nullable TypeMirror t * @param typeMirror2 the second type to compare. * @return true if they are equal, false otherwise. */ - public static boolean areEqual(@Nullable TypeMirror typeMirror1, @Nullable TypeMirror typeMirror2) { + public static boolean areEqual(@NotNull TypeMirror typeMirror1, @NotNull TypeMirror typeMirror2) { return getUtils().isSameType(typeMirror1, typeMirror2); } diff --git a/stag-library-compiler/src/test/java/com/vimeo/stag/processor/TypeUtilsUnitTest.java b/stag-library-compiler/src/test/java/com/vimeo/stag/processor/TypeUtilsUnitTest.java index a20457b3..ee054ea4 100644 --- a/stag-library-compiler/src/test/java/com/vimeo/stag/processor/TypeUtilsUnitTest.java +++ b/stag-library-compiler/src/test/java/com/vimeo/stag/processor/TypeUtilsUnitTest.java @@ -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 = ")) { @@ -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())); } } } @@ -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 { diff --git a/stag-library-compiler/src/test/java/com/vimeo/stag/processor/Utils.java b/stag-library-compiler/src/test/java/com/vimeo/stag/processor/Utils.java index c2c28669..b1be1839 100644 --- a/stag-library-compiler/src/test/java/com/vimeo/stag/processor/Utils.java +++ b/stag-library-compiler/src/test/java/com/vimeo/stag/processor/Utils.java @@ -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; @@ -83,6 +84,25 @@ public static void testZeroArgumentConstructorFinalClass(Class 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()); @@ -108,13 +128,13 @@ public static TypeMirror getTypeMirrorFromObject(@NotNull Object object) { @NotNull public static TypeMirror getGenericVersionOfClass(@NotNull Class clazz) { List 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); } } From 6433bf4cfc78f26c8aa366396fbd86001c172db4 Mon Sep 17 00:00:00 2001 From: Anthony Restaino Date: Thu, 13 Jul 2017 10:52:26 -0400 Subject: [PATCH 5/6] Adding optional blurb about removing model list --- README.md | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/README.md b/README.md index 4db38cf4..1fa5341d 100644 --- a/README.md +++ b/README.md @@ -134,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. From 2929c4c0aa57828bd697a78e30fa57ed73a6d432 Mon Sep 17 00:00:00 2001 From: Anthony Restaino Date: Fri, 14 Jul 2017 10:27:28 -0400 Subject: [PATCH 6/6] Bumping version to 2.3.2 bugfix version --- CHANGELOG.md | 5 +++++ README.md | 8 ++++---- build.gradle | 2 +- 3 files changed, 10 insertions(+), 5 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 4b162b84..791371d9 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -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. diff --git a/README.md b/README.md index cf40d19f..707006db 100644 --- a/README.md +++ b/README.md @@ -49,8 +49,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) @@ -67,8 +67,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 { diff --git a/build.gradle b/build.gradle index 8109963a..77187314 100644 --- a/build.gradle +++ b/build.gradle @@ -38,5 +38,5 @@ allprojects { subprojects { group = 'com.vimeo.stag' - version = '2.3.1' + version = '2.3.2' }