Skip to content

Commit

Permalink
Update to latest kotlin/ksp/xprocessing (#1261)
Browse files Browse the repository at this point in the history
* Fix xprocessing api changes

* fix resource bug

* Return to loop instead of entire function

* formatting

* catch regex formatting issues

* ksp updates in progress

* project compiles with all versions updated

* Tests pass

* fix PagedDataModelCacheTest

* all checks pass

* reenable sample
  • Loading branch information
elihart authored Jul 6, 2022
1 parent 8b3dd9c commit 55c3b2e
Show file tree
Hide file tree
Showing 29 changed files with 860 additions and 111 deletions.
24 changes: 12 additions & 12 deletions blessedDeps.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ rootProject.ext.JAVA_SOURCE_VERSION = JavaVersion.VERSION_1_8
rootProject.ext.JAVA_TARGET_VERSION = JavaVersion.VERSION_1_8

rootProject.ext.TARGET_SDK_VERSION = 30
rootProject.ext.COMPILE_SDK_VERSION = 30
rootProject.ext.COMPILE_SDK_VERSION = 32
rootProject.ext.MIN_SDK_VERSION = 14
rootProject.ext.COMPOSE_MIN_SDK_VERSION = 21

Expand All @@ -29,7 +29,7 @@ rootProject.ext.ANDROIDX_MATERIAL = "1.3.0"
rootProject.ext.ANDROIDX_PAGING = "2.0.0"
rootProject.ext.ANDROIDX_PAGING3 = "3.0.0"
rootProject.ext.ANDROIDX_RECYCLERVIEW = "1.2.0"
rootProject.ext.ANDROIDX_ROOM = "2.2.5"
rootProject.ext.ANDROIDX_ROOM = "2.4.2"
rootProject.ext.ANDROIDX_RUNTIME = "2.3.1"
rootProject.ext.ANDROIDX_VERSIONED_PARCELABLE = "1.1.1"
rootProject.ext.ANDROID_ARCH_TESTING = "2.1.0"
Expand All @@ -42,21 +42,21 @@ rootProject.ext.GLIDE_VERSION = "4.12.0"
rootProject.ext.GOOGLE_TESTING_COMPILE_VERSION = "0.19"
rootProject.ext.INCAP_VERSION = "0.3"
rootProject.ext.JUNIT_VERSION = "4.13.1"
rootProject.ext.KOTLIN_COROUTINES_TEST_VERSION = "1.4.1"
rootProject.ext.KOTLIN_COROUTINES_VERSION = "1.3.9"
rootProject.ext.KOTLINX_METADATA = "0.3.0"
rootProject.ext.KOTLIN_COROUTINES_VERSION = "1.6.3"
rootProject.ext.KOTLINX_METADATA = "0.5.0"
rootProject.ext.LOTTIE_VERSION = "2.8.0"
rootProject.ext.MOCKITO_VERSION = "3.7.7"
rootProject.ext.PARIS_VERSION = "2.0.1"
rootProject.ext.ROBOLECTRIC_VERSION = "4.5.1"
rootProject.ext.SQUARE_JAVAPOET_VERSION = "1.13.0"
rootProject.ext.SQUARE_KOTLINPOET_VERSION = "1.10.2"
rootProject.ext.COMPOSE_VERSION = "1.0.4"
rootProject.ext.COMPOSE_ACTIVITY_VERSION = "1.3.1"
rootProject.ext.SQUARE_KOTLINPOET_VERSION = "1.12.0"
rootProject.ext.COMPOSE_COMPILER_VERSION = "1.2.0"
rootProject.ext.COMPOSE_VERSION = "1.2.0-rc03"
rootProject.ext.COMPOSE_ACTIVITY_VERSION = "1.5.0"
rootProject.ext.KOTLINX_LIFECYCLE_RUNTIME_VERSION = "2.3.0"
rootProject.ext.KSP_VERSION = "1.5.31-1.0.0"
rootProject.ext.XPROCESSING_VERSION = "2.4.0-beta01"
rootProject.ext.KOTLIN_TESTING_COMPILE_VERSION = '1.4.5'
rootProject.ext.KSP_VERSION = "1.7.0-1.0.6"
rootProject.ext.XPROCESSING_VERSION = "2.5.0-alpha02"
rootProject.ext.KOTLIN_TESTING_COMPILE_VERSION = '1.4.9'

rootProject.ext.deps = [
activityCompose : "androidx.activity:activity-compose:$COMPOSE_ACTIVITY_VERSION",
Expand Down Expand Up @@ -90,7 +90,7 @@ rootProject.ext.deps = [
incapRuntime : "net.ltgt.gradle.incap:incap:$INCAP_VERSION",
junit : "junit:junit:$JUNIT_VERSION",
kotlinCoroutines : "org.jetbrains.kotlinx:kotlinx-coroutines-core:$KOTLIN_COROUTINES_VERSION",
kotlinCoroutinesTest : "org.jetbrains.kotlinx:kotlinx-coroutines-test:$KOTLIN_COROUTINES_TEST_VERSION",
kotlinCoroutinesTest : "org.jetbrains.kotlinx:kotlinx-coroutines-test:$KOTLIN_COROUTINES_VERSION",
kotlinxMetadata : "org.jetbrains.kotlinx:kotlinx-metadata-jvm:$KOTLINX_METADATA",
lottie : "com.airbnb.android:lottie:$LOTTIE_VERSION",
mockito : "org.mockito:mockito-core:$MOCKITO_VERSION",
Expand Down
28 changes: 22 additions & 6 deletions build.gradle
Original file line number Diff line number Diff line change
@@ -1,15 +1,14 @@
// Top-level build file where you can add configuration options common to all sub-projects/modules.
buildscript {

ext.KOTLIN_VERSION = "1.5.31"
ext.ANDROID_PLUGIN_VERSION = '7.0.3'
ext.KSP_VERSION = '1.5.31-1.0.0'
ext.KOTLIN_VERSION = "1.7.0"
ext.ANDROID_PLUGIN_VERSION = '7.2.1'
ext.KSP_VERSION = '1.7.0-1.0.6'

repositories {
google()
mavenCentral()
gradlePluginPortal()
jcenter()
}
dependencies {
classpath "com.android.tools.build:gradle:$ANDROID_PLUGIN_VERSION"
Expand All @@ -18,7 +17,7 @@ buildscript {
// ./gradlew clean uploadArchives --no-daemon --no-parallel
classpath 'com.vanniktech:gradle-maven-publish-plugin:0.14.2'
// Dokka is needed on classpath for vanniktech publish plugin
classpath "org.jetbrains.dokka:dokka-gradle-plugin:1.4.30"
classpath "org.jetbrains.dokka:dokka-gradle-plugin:1.5.31"
}
}

Expand All @@ -32,7 +31,6 @@ allprojects {
repositories {
google()
mavenCentral()
jcenter()
}

// Prevent javadoc task complaining about errors with kotlin files
Expand All @@ -50,6 +48,24 @@ subprojects { project ->
if (project.tasks.findByName('check')) {
check.dependsOn('ktlint')
}

if (project.extensions.findByType(com.android.build.gradle.LibraryExtension.class) != null) {
project.android.libraryVariants.all { variant ->
def outputFolder = new File("build/generated/ksp/${variant.name}/kotlin")
variant.addJavaSourceFoldersToModel(outputFolder)
android.sourceSets.getAt(variant.name).java {
srcDir(outputFolder)
}
}
} else if (project.extensions.findByType(com.android.build.gradle.AbstractAppExtension.class) != null) {
project.android.applicationVariants.all { variant ->
def outputFolder = new File("build/generated/ksp/${variant.name}/kotlin")
variant.addJavaSourceFoldersToModel(outputFolder)
android.sourceSets.getAt(variant.name).java {
srcDir(outputFolder)
}
}
}
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -245,9 +245,9 @@ class EpoxyVisibilityTracker {
// without recursively searching through the view children.
if (groupChildHolder.itemView is RecyclerView) {
if (detachEvent) {
processChildRecyclerViewDetached(groupChildHolder.itemView)
processChildRecyclerViewDetached(groupChildHolder.itemView as RecyclerView)
} else {
processChildRecyclerViewAttached(groupChildHolder.itemView)
processChildRecyclerViewAttached(groupChildHolder.itemView as RecyclerView)
}
}
processChild(
Expand Down
2 changes: 1 addition & 1 deletion epoxy-compose/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ android {
compose true
}
composeOptions {
kotlinCompilerExtensionVersion COMPOSE_VERSION
kotlinCompilerExtensionVersion COMPOSE_COMPILER_VERSION
}
}

Expand Down
2 changes: 1 addition & 1 deletion epoxy-composeinterop-maverickssample/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ android {
compose true
}
composeOptions {
kotlinCompilerExtensionVersion COMPOSE_VERSION
kotlinCompilerExtensionVersion COMPOSE_COMPILER_VERSION
}
packagingOptions {
exclude "**/attach_hotspot_windows.dll"
Expand Down
2 changes: 1 addition & 1 deletion epoxy-composesample/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ android {
compose true
}
composeOptions {
kotlinCompilerExtensionVersion COMPOSE_VERSION
kotlinCompilerExtensionVersion COMPOSE_COMPILER_VERSION
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,9 @@ class ModelsWithCustomTypes {
@EpoxyModelClass
abstract static class ModelWithCustomType extends BaseModelWithCustomType<ImageView> {

public ModelWithCustomType() {
}

@Override
protected int getDefaultLayout() {
return 0;
Expand All @@ -25,6 +28,9 @@ protected int getDefaultLayout() {

abstract static class BaseModelWithCustomType<U extends View> extends EpoxyModel<TextView> {

public BaseModelWithCustomType() {
}

public void testMethod(U param) {

}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,10 +10,10 @@ import kotlinx.coroutines.ExperimentalCoroutinesApi
import kotlinx.coroutines.ObsoleteCoroutinesApi
import kotlinx.coroutines.async
import kotlinx.coroutines.delay
import kotlinx.coroutines.flow.collect
import kotlinx.coroutines.flow.collectLatest
import kotlinx.coroutines.runBlocking
import kotlinx.coroutines.test.TestCoroutineDispatcher
import kotlinx.coroutines.test.runBlockingTest
import kotlinx.coroutines.test.advanceTimeBy
import kotlinx.coroutines.test.runTest
import org.hamcrest.CoreMatchers
import org.hamcrest.MatcherAssert
import org.junit.Assert.assertEquals
Expand All @@ -28,10 +28,6 @@ import kotlin.coroutines.CoroutineContext
@RunWith(RobolectricTestRunner::class)
@LooperMode(LooperMode.Mode.LEGACY)
class PagedDataModelCacheTest {
/**
* test dispatcher used for controlling paging source
* */
private val testDispatcher = TestCoroutineDispatcher()

/**
* Simple mode builder for [DummyItem]
Expand Down Expand Up @@ -77,16 +73,16 @@ class PagedDataModelCacheTest {
}

@Test
fun partialLoad() = runBlockingTest {
fun partialLoad() = runTest {
val items = createDummyItems(INITIAL_LOAD_SIZE + PAGE_SIZE)
val pager = createPager(testDispatcher, items)
val pager = createPager(this.coroutineContext, items)
val deferred = async {
pager.flow.collect {
pager.flow.collectLatest {
pagedDataModelCache.submitData(it)
}
}
// advance in time to create first page of data
testDispatcher.advanceTimeBy(DEFAULT_DELAY)
advanceTimeBy(DEFAULT_DELAY)

// wait for pagedDataModelCache submits data
delay(2000)
Expand All @@ -97,7 +93,7 @@ class PagedDataModelCacheTest {
assertModelDummyItems(items.subList(0, INITIAL_LOAD_SIZE))
MatcherAssert.assertThat(rebuildCounter, CoreMatchers.`is`(0))
// advance in time to create second page of data
testDispatcher.advanceTimeBy(DEFAULT_DELAY)
advanceTimeBy(DEFAULT_DELAY)
delay(2000)
assertModelDummyItems(items)
assertAndResetRebuildModels()
Expand Down

This file was deleted.

This file was deleted.

Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ package com.airbnb.epoxy.processor
import androidx.annotation.LayoutRes
import androidx.room.compiler.processing.XElement
import androidx.room.compiler.processing.XFiler
import androidx.room.compiler.processing.XMethodElement
import androidx.room.compiler.processing.XProcessingEnv
import androidx.room.compiler.processing.XTypeElement
import androidx.room.compiler.processing.addOriginatingElement
Expand Down Expand Up @@ -834,7 +835,11 @@ class GeneratedModelWriter(
// EpoxyModel implementation which calls normal "bind". Doing that would force a full
// bind!!! So we mustn't do that. So, we only call the super diff binding if we think
// it's a custom implementation.
if (modelImplementsBindWithDiff(classInfo.superClassElement, build(), environment)) {
if (modelImplementsBindWithDiff(
classInfo.superClassElement,
memoizer.baseBindWithDiffMethod
)
) {
addStatement(
"super.bind(\$L, \$L)",
boundObjectParam.name,
Expand Down Expand Up @@ -2097,24 +2102,16 @@ class GeneratedModelWriter(

fun modelImplementsBindWithDiff(
clazz: XTypeElement,
bindWithDiffMethod: MethodSpec,
environment: XProcessingEnv
baseBindWithDiffMethod: XMethodElement
): Boolean {
val methodOnClass = Utils.getMethodOnClass(
clazz,
bindWithDiffMethod,
environment
) ?: return false

if (methodOnClass.isAbstract()) {
return false
return clazz.getAllMethods().any {
it.name == baseBindWithDiffMethod.name &&
!it.isAbstract() &&
it.overrides(
other = baseBindWithDiffMethod,
owner = clazz
)
}

val enclosingElement = methodOnClass.enclosingElement as XTypeElement

// As long as the implementation is not on the base EpoxyModel we consider it a custom
// implementation
return enclosingElement.qualifiedName != Utils.UNTYPED_EPOXY_MODEL_TYPE
}
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ package com.airbnb.epoxy.processor

import androidx.room.compiler.processing.XArrayType
import androidx.room.compiler.processing.XElement
import androidx.room.compiler.processing.XMethodElement
import androidx.room.compiler.processing.XProcessingEnv
import androidx.room.compiler.processing.XType
import androidx.room.compiler.processing.XTypeElement
Expand Down Expand Up @@ -110,6 +111,17 @@ class Memoizer(
environment.requireType(ClassNames.ANDROID_VIEW)
}

val baseBindWithDiffMethod: XMethodElement by lazy {
epoxyModelClassElementUntyped.getDeclaredMethods()
.firstOrNull {
it.name == "bind" &&
it.parameters.size == 2 &&
// Second parameter in bind function is an epoxy model.
it.parameters[1].type.typeElement?.name == "EpoxyModel"
}
?: error("Unable to find bind function in epoxy model")
}

private val methodsReturningClassType = mutableMapOf<String, Set<MethodInfo>>()

fun getMethodsReturningClassType(classType: XType, memoizer: Memoizer): Set<MethodInfo> {
Expand Down Expand Up @@ -222,8 +234,8 @@ class Memoizer(

// Any type is allowed, so View wil work
return typeParam.isObjectOrAny() ||
// If there is no bound then a View will work
typeParam.extendsBound() == null ||
// If there is no type bound then a View will work
typeParam.extendsBound()?.typeElement?.type == null ||
// if the bound is Any, then that is fine too.
// For some reason this case is different in KSP and needs to be checked for.
typeParam.extendsBound()?.typeElement?.type?.isObjectOrAny() == true ||
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -75,7 +75,7 @@ class ModelViewInfo(
// Only include the interface if the view has one of the interface methods annotated with a prop annotation
val interfaceMethods = interfaceElement.getDeclaredMethods()
methodsOnView.any { viewMethod ->
viewMethod.hasAnyOf(*ModelViewProcessor.modelPropAnnotationsArray) &&
viewMethod.hasAnyAnnotation(*ModelViewProcessor.modelPropAnnotationsArray) &&
interfaceMethods.any { interfaceMethod ->
// To keep this simple we only compare name and ignore parameters, should be close enough
viewMethod.name == interfaceMethod.name
Expand Down Expand Up @@ -174,7 +174,7 @@ class ModelViewInfo(
return modelViewConfig.getNameForView(viewElement)
}

logger.logError(viewElement, "UnabletypeNameWorkaround to get layout resource for view %s", viewElement.name)
logger.logError(viewElement, "Unable to get layout resource for view %s", viewElement.name)
return ResourceValue(0)
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -241,7 +241,7 @@ class ModelViewProcessor @JvmOverloads constructor(
info.viewElement.findOverload(
prop,
1
)?.hasAnyOf(*modelPropAnnotationsArray) == true
)?.hasAnyAnnotation(*modelPropAnnotationsArray) == true
) {
return@mapNotNull null
}
Expand Down
Loading

0 comments on commit 55c3b2e

Please sign in to comment.