-
Notifications
You must be signed in to change notification settings - Fork 729
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Reflect the annotations declared in constructor params #519
Changes from 3 commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,5 +1,6 @@ | ||
package com.airbnb.epoxy | ||
|
||
import com.squareup.javapoet.CodeBlock | ||
import com.squareup.javapoet.TypeName | ||
import com.squareup.kotlinpoet.ANY | ||
import com.squareup.kotlinpoet.BOOLEAN | ||
|
@@ -13,6 +14,7 @@ import com.squareup.kotlinpoet.LONG | |
import com.squareup.kotlinpoet.SHORT | ||
import com.squareup.kotlinpoet.UNIT | ||
import javax.lang.model.element.Modifier | ||
import kotlin.reflect.jvm.internal.impl.types.KotlinType | ||
|
||
typealias JavaClassName = com.squareup.javapoet.ClassName | ||
typealias JavaTypeName = com.squareup.javapoet.TypeName | ||
|
@@ -102,6 +104,13 @@ private fun JavaClassName.getSimpleNamesInKotlin(): List<String> { | |
return originalNames | ||
} | ||
|
||
// Does not support transferring complex annotations which | ||
// have parameters and values associated with them. | ||
fun JavaAnnotationSpec.toKPoet(): KotlinAnnotationSpec { | ||
val annotationClass = KotlinClassName.bestGuess(type.toString()) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This isn't quite right because it won't capture parameter values in the annotation - so it will only work for basic annotations. If you're interested it would be great to add that full functionality, otherwise can you add a note warning of this partial implementation? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Good catch. Will update the extension to include the parameter values also. I'm interested in also adding tests for the PoetExtensions file. Would it be best for adding tests in the There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. @shaishavgandhi05 great! yes, I think adding tests to There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. After some investigation, this seems like something really hard to do. Parameters are added as |
||
return KotlinAnnotationSpec.builder(annotationClass).build() | ||
} | ||
|
||
fun JavaClassName.setPackage(packageName: String) = | ||
JavaClassName.get(packageName, simpleName(), *simpleNames().drop(1).toTypedArray())!! | ||
|
||
|
@@ -189,6 +198,8 @@ fun JavaParameterSpec.toKPoet(): KotlinParameterSpec { | |
|
||
val nullable = annotations.any { (it.type as? JavaClassName)?.simpleName() == "Nullable" } | ||
|
||
val kotlinAnnotations = annotations.map { it.toKPoet() } | ||
|
||
return KotlinParameterSpec.builder( | ||
paramName, | ||
type.toKPoet(nullable), | ||
|
@@ -197,6 +208,7 @@ fun JavaParameterSpec.toKPoet(): KotlinParameterSpec { | |
if (isLambda(type)) { | ||
addModifiers(KModifier.NOINLINE) | ||
} | ||
addAnnotations(kotlinAnnotations) | ||
}.build() | ||
} | ||
|
||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,79 @@ | ||
package com.airbnb.epoxy | ||
|
||
import android.support.annotation.NonNull | ||
import com.squareup.kotlinpoet.asTypeName | ||
import org.junit.Assert.assertEquals | ||
import org.junit.Assert.assertFalse | ||
import org.junit.Assert.assertTrue | ||
import org.junit.Test | ||
import javax.lang.model.element.Modifier | ||
|
||
class PoetExtensionsTest { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Thanks a lot for the tests! |
||
|
||
@Test fun testAnnotationSpecToKPoet() { | ||
val annotation = EpoxyModelClass::class.java | ||
val type = annotation.asTypeName() | ||
val javaAnnotation = JavaAnnotationSpec.builder(annotation).build() | ||
|
||
val kotlinAnnotation = javaAnnotation.toKPoet() | ||
assertEquals(type, kotlinAnnotation.type) | ||
} | ||
|
||
@Test fun testIsLambdaWithString() { | ||
val stringType = JavaClassName.bestGuess("java.lang.String") | ||
assertFalse(isLambda(stringType)) | ||
} | ||
|
||
@Test fun testIsLambdaWithLambda() { | ||
val lambdaType = JavaClassName.bestGuess("kotlin.Function2") | ||
assertTrue(isLambda(lambdaType)) | ||
} | ||
|
||
@Test fun testJavaParameterSpecToKPoet() { | ||
val name = "android" | ||
val javaParameter = JavaParameterSpec.builder(JavaClassName.bestGuess("java.lang.String"), name, Modifier.PRIVATE) | ||
.addAnnotation(NonNull::class.java) | ||
.build() | ||
val kotlinString = KotlinClassName("kotlin", "String") | ||
|
||
val kotlinParameter = javaParameter.toKPoet() | ||
assertEquals(name, kotlinParameter.name) | ||
assertEquals(kotlinString, kotlinParameter.type) | ||
assertEquals(javaParameter.annotations.size, kotlinParameter.annotations.size) | ||
assertEquals(NonNull::class.java.asTypeName(), kotlinParameter.annotations[0].type) | ||
} | ||
|
||
@Test fun testJavaTypeNameToKPoet() { | ||
val javaType = JavaParametrizedTypeName.get(JavaClassName.bestGuess("java.util.List"), | ||
JavaClassName.bestGuess("java.lang.String")) | ||
|
||
val kotlinType = javaType.toKPoet() | ||
val kotlinList = KotlinClassName("kotlin.collections", "List") | ||
val kotlinString = KotlinClassName("kotlin", "String") | ||
assertEquals(kotlinList, kotlinType.rawType) | ||
assertEquals(kotlinString, kotlinType.typeArguments[0]) | ||
} | ||
|
||
@Test fun testJavaArrayTypeNameToKPoet() { | ||
val javaIntArray = JavaArrayTypeName.of(JavaClassName.INT) | ||
val kotlinIntArray = javaIntArray.toKPoet() | ||
|
||
assertEquals("kotlin.IntArray", kotlinIntArray.toString()) | ||
|
||
val javaFloatArray = JavaArrayTypeName.of(JavaClassName.bestGuess("java.lang.Float")) | ||
val kotlinFloatArray = javaFloatArray.toKPoet() | ||
|
||
assertEquals("kotlin.Array<kotlin.Float>", kotlinFloatArray.toString()) | ||
} | ||
|
||
@Test fun testJavaClassNameToKPoet() { | ||
val javaClassName = JavaClassName.bestGuess("java.lang.Integer") | ||
val kotlinClassName = javaClassName.toKPoet() | ||
|
||
val javaByteName = JavaClassName.BYTE | ||
val kotlinByteName = javaByteName.toKPoet() | ||
|
||
assertEquals("kotlin.Int", kotlinClassName.toString()) | ||
assertEquals("kotlin.Byte", kotlinByteName.toString()) | ||
} | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,22 @@ | ||
package com.airbnb.epoxy.kotlinsample | ||
|
||
import android.support.annotation.DrawableRes | ||
import android.support.annotation.StringRes | ||
import android.view.View | ||
import com.airbnb.epoxy.EpoxyAttribute | ||
import com.airbnb.epoxy.EpoxyHolder | ||
import com.airbnb.epoxy.EpoxyModelClass | ||
import com.airbnb.epoxy.EpoxyModelWithHolder | ||
|
||
@EpoxyModelClass(layout = R.layout.activity_kotlin_sample) | ||
abstract class AnnotationModel(@StringRes val resId: Int): EpoxyModelWithHolder<AnnotationHolder>() { | ||
|
||
@EpoxyAttribute @DrawableRes var drawable: Int? = null | ||
} | ||
|
||
class AnnotationHolder: EpoxyHolder() { | ||
override fun bindView(itemView: View) { | ||
|
||
} | ||
|
||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
maybe this can be nullable, and we would return null if the
JavaAnnotationSpec
has a code block?