Skip to content

Commit

Permalink
Add native Parceler support
Browse files Browse the repository at this point in the history
  • Loading branch information
MarcinMoskala committed Jul 21, 2017
1 parent 6e2fb3b commit 088add4
Show file tree
Hide file tree
Showing 23 changed files with 153 additions and 246 deletions.
@@ -1,5 +1,7 @@
package activitystarter;

import com.sun.org.apache.xpath.internal.operations.Bool;

import java.lang.annotation.Retention;
import java.lang.annotation.Target;

Expand All @@ -9,4 +11,5 @@
@Retention(CLASS) @Target(FIELD)
public @interface Arg {
String key() default "";
boolean parceler() default false;
}
Expand Up @@ -4,13 +4,11 @@ import activitystarter.compiler.model.ConverterModel

class ConverterGeneration(val converter: ConverterModel) {

val converterName = converter.className

fun wrap( f: ()->String): String {
return "new $converterName().wrap(${f()})"
return "new ${converter.className}().wrap(${f()})"
}

fun unwrap( f: ()->String): String {
return "new $converterName().unwrap(${f()})"
return "new ${converter.className}().unwrap(${f()})"
}
}
@@ -0,0 +1,12 @@
package activitystarter.compiler.generation

class ParcelerGeneration() {

fun wrap(f: () -> String): String {
return "org.parceler.Parcels.wrap(${f()})"
}

fun unwrap(f: () -> String): String {
return "org.parceler.Parcels.unwrap(${f()})"
}
}
@@ -1,6 +1,7 @@
package activitystarter.compiler.model.param

import activitystarter.compiler.generation.ConverterGeneration
import activitystarter.compiler.generation.ParcelerGeneration
import activitystarter.compiler.model.ConverterModel
import activitystarter.compiler.utils.camelCaseToUppercaseUnderscore
import com.squareup.javapoet.TypeName
Expand All @@ -11,20 +12,22 @@ class ArgumentModel(
val paramType: ParamType,
val typeName: TypeName,
val saveParamType: ParamType,
val saveTypeName: TypeName,
val isOptional: Boolean,
val accessor: FieldAccessor,
private val converter: ConverterModel?
private val converter: ConverterModel?,
val parceler: Boolean
) {
val fieldName: String by lazy { camelCaseToUppercaseUnderscore(name) + "_KEY" }

fun addUnwrapper(body: () -> String): String {
converter ?: return body()
return ConverterGeneration(converter).unwrap(body)
fun addUnwrapper(body: () -> String) = when {
parceler -> ParcelerGeneration().unwrap(body)
converter != null -> ConverterGeneration(converter).unwrap(body)
else -> body()
}

fun addWrapper(body: () -> String): String {
converter ?: return body()
return ConverterGeneration(converter).wrap(body)
fun addWrapper(body: () -> String) = when {
parceler -> ParcelerGeneration().wrap(body)
converter != null -> ConverterGeneration(converter).wrap(body)
else -> body()
}
}
Expand Up @@ -4,6 +4,7 @@ import activitystarter.Arg
import activitystarter.Optional
import activitystarter.compiler.error.Errors
import activitystarter.compiler.error.error
import activitystarter.compiler.model.ConverterModel
import activitystarter.compiler.model.ProjectConfig
import activitystarter.compiler.model.classbinding.KnownClassType
import activitystarter.compiler.model.param.ArgumentModel
Expand All @@ -28,20 +29,29 @@ class ArgumentFactory(val enclosingElement: TypeElement, val config: ProjectConf
return null
}
val name: String = element.simpleName.toString()
val keyFromAnnotation = element.getAnnotation(Arg::class.java)?.key
val annotation = element.getAnnotation(Arg::class.java)
val keyFromAnnotation = annotation?.key
val isParceler = annotation?.parceler ?: false
val defaultKey = "$packageName.${name}StarterKey"
val key: String = if (keyFromAnnotation.isNullOrBlank()) defaultKey else keyFromAnnotation!!
val typeName: TypeName = TypeName.get(elementType)
val isOptional: Boolean = element.getAnnotation(Optional::class.java) != null
val accessor: FieldAccessor = FieldAccessor(element)
val converter = config.converterFor(elementType)
val saveParamType = converter?.toParamType ?: paramType
if(saveParamType == ParamType.ObjectSubtype) {

val converter: ConverterModel?
val saveParamType: ParamType?
if (isParceler) {
converter = null
saveParamType = ParamType.ParcelableSubtype
} else {
converter = config.converterFor(elementType)
saveParamType = converter?.toParamType ?: paramType
}
if (saveParamType == ParamType.ObjectSubtype) {
showProcessingError(element, Errors.notSupportedType)
return null
}
val saveTypeName = converter?.typeTo?.let { TypeName.get(it) } ?: typeName
return ArgumentModel(name, key, paramType, typeName, saveParamType, saveTypeName, isOptional, accessor, converter)
return ArgumentModel(name, key, paramType, typeName, saveParamType, isOptional, accessor, converter, isParceler)
}

private fun getFieldError(element: Element, knownClassType: KnownClassType, paramTypeNullable: ParamType?) = when {
Expand All @@ -57,13 +67,13 @@ class ArgumentFactory(val enclosingElement: TypeElement, val config: ProjectConf
error(enclosingElement, "@%s %s $text (%s)", Arg::class.java.simpleName, enclosingElement.qualifiedName, element.simpleName)
}

class ProcessingError(override val message: String): Throwable(message)
class ProcessingError(override val message: String) : Throwable(message)

fun processElement(element: Element) {
fun throwError(message: String): Nothing
= throw ProcessingError("Error in element $element: $message")
fun processElement(element: Element) {
fun throwError(message: String): Nothing
= throw ProcessingError("Error in element $element: $message")

val enclosingElement = element.enclosingElement ?: throwError("Lack of enclosing element")
}
val enclosingElement = element.enclosingElement ?: throwError("Lack of enclosing element")
}

}
Expand Up @@ -8,14 +8,12 @@ import javax.lang.model.type.TypeMirror

class ConverterFaktory {

fun create(converters: List<TypeMirror>): List<ConverterModel> {
return converters.mapNotNull { c ->
val typeElement = c.toTypeElement() ?: return@mapNotNull null
val declaredParentInterface = typeElement.interfaces?.get(0) as? DeclaredType
val genericTypes = declaredParentInterface?.typeArguments ?: return@mapNotNull null
val fromClass = genericTypes[0]!!
val toClass = genericTypes[1]!!
ConverterModel(c.toString(), fromClass, toClass)
}
fun create(converters: List<TypeMirror>): List<ConverterModel> = converters.mapNotNull { c ->
val typeElement = c.toTypeElement() ?: return@mapNotNull null
val declaredParentInterface = typeElement.interfaces?.get(0) as? DeclaredType
val genericTypes = declaredParentInterface?.typeArguments ?: return@mapNotNull null
val fromClass = genericTypes[0]!!
val toClass = genericTypes[1]!!
ConverterModel(c.toString(), fromClass, toClass)
}
}
1 change: 0 additions & 1 deletion activitystarter-parceler-arg-converter/.gitignore

This file was deleted.

28 changes: 0 additions & 28 deletions activitystarter-parceler-arg-converter/build.gradle

This file was deleted.

25 changes: 0 additions & 25 deletions activitystarter-parceler-arg-converter/proguard-rules.pro

This file was deleted.

This file was deleted.

This file was deleted.

This file was deleted.

This file was deleted.

1 change: 0 additions & 1 deletion activitystarter/build.gradle
Expand Up @@ -46,7 +46,6 @@ dependencies {
testCompile files(getRuntimeJar())
testCompile files(Jvm.current().getToolsJar())
testCompile project(':activitystarter-compiler')
testCompile project(':activitystarter-parceler-arg-converter')
testCompile deps.kotlin
testCompile deps.kotlin_junit
testCompile deps.parceler
Expand Down
Expand Up @@ -13,6 +13,6 @@ class ActivityWithConvertersTest: GenerationTest() {

@Test
fun toParcelableConversionTest() {
filePrecessingComparator("withConverters/ActivityWithObjectToParcelableConverter")
filePrecessingComparator("parceler/Simple")
}
}
91 changes: 91 additions & 0 deletions generationExamples/parceler/Simple
@@ -0,0 +1,91 @@
********com.example.activitystarter.MainActivity********
package com.example.activitystarter;
import android.app.Activity;
import activitystarter.Arg;
import org.parceler.Parcel;

public class MainActivity extends Activity {

@Arg(parceler = true) StudentParcel studentParceler;

@Parcel
public static class StudentParcel {

private int id;
private String name;
private char grade;

public StudentParcel() {
}

public StudentParcel(int id, String name, char grade) {
this.id = id;
this.name = name;
this.grade = grade;
}

public int getId() {
return id;
}

public void setId(int id) {
this.id = id;
}

public String getName() {
return name;
}

public void setName(String name) {
this.name = name;
}

public char getGrade() {
return grade;
}

public void setGrade(char grade) {
this.grade = grade;
}
}
}
********com.example.activitystarter.MainActivityStarter********
package com.example.activitystarter;

import android.content.Context;
import android.content.Intent;
import android.os.Bundle;
import java.lang.String;

public final class MainActivityStarter {
private static final String STUDENT_PARCELER_KEY = "com.example.activitystarter.studentParcelerStarterKey";

public static void fill(MainActivity activity, Bundle savedInstanceState) {
Intent intent = activity.getIntent();
if(savedInstanceState != null && savedInstanceState.containsKey(STUDENT_PARCELER_KEY)) {
activity.studentParceler = (MainActivity.StudentParcel) org.parceler.Parcels.unwrap(savedInstanceState.getParcelable(STUDENT_PARCELER_KEY));
} else if(intent.hasExtra(STUDENT_PARCELER_KEY))
activity.studentParceler = (MainActivity.StudentParcel) org.parceler.Parcels.unwrap(intent.getParcelableExtra(STUDENT_PARCELER_KEY));
}

public static void save(MainActivity activity, Bundle bundle) {
bundle.putParcelable(STUDENT_PARCELER_KEY, org.parceler.Parcels.wrap(activity.studentParceler));
}

public static Intent getIntent(Context context, MainActivity.StudentParcel studentParceler) {
Intent intent = new Intent(context, MainActivity.class);
intent.putExtra(STUDENT_PARCELER_KEY, org.parceler.Parcels.wrap(studentParceler));
return intent;
}

public static void start(Context context, MainActivity.StudentParcel studentParceler) {
Intent intent = getIntent(context, studentParceler);
context.startActivity(intent);
}

public static void startWithFlags(Context context, MainActivity.StudentParcel studentParceler, int flags) {
Intent intent = getIntent(context, studentParceler);
intent.addFlags(flags);
context.startActivity(intent);
}
}

0 comments on commit 088add4

Please sign in to comment.