diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 3c37929..223712a 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -31,7 +31,7 @@ jobs: java-version: 8 - name: Setup Gradle - uses: gradle/gradle-build-action@v2 + uses: gradle/gradle-build-action@v2.4.2 - name: Run local tests run: ./gradlew :kace-compiler:test diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml new file mode 100755 index 0000000..442c0ff --- /dev/null +++ b/.github/workflows/release.yml @@ -0,0 +1,18 @@ +--- +name: "Tagged Release" + +on: + push: + tags: + - "v*" + +jobs: + tagged-release: + name: "Tagged Release" + runs-on: "ubuntu-latest" + + steps: + - uses: "marvinpinto/action-automatic-releases@v1.2.1" + with: + repo_token: "${{ secrets.GITHUB_TOKEN }}" + prerelease: false \ No newline at end of file diff --git a/README.md b/README.md index f2ebfea..4367d12 100644 --- a/README.md +++ b/README.md @@ -67,11 +67,12 @@ kace { The Kace currently supports the above four most commonly used types. Other types supported by kotlin-android-extensions such as android.app.Fragment, android.app.Dialog, kotlinx.android.extensions.LayoutContainer are deprecated or rarely used, currently not supported by the Kace ## Version compatible -| Kace | Kotlin | AGP | Gradle | -|--------------|---------------|-------|--------| -| 1.7.0-1.0.4 | 1.7.0 | 4.2.0 | 6.7.1 | -| 1.8.0-1.0.4 | 1.8.0~1.8.10 | 4.2.0 | 6.8.3 | -| 1.8.20-1.0.4 | 1.8.20 | 4.2.0 | 6.8.3 | +| Kace | Kotlin | AGP | Gradle | +|--------------|--------------|-------|--------| +| 1.7.0-1.0.4 | 1.7.0 | 4.2.0 | 6.7.1 | +| 1.8.0-1.0.4 | 1.8.0~1.8.10 | 4.2.0 | 6.8.3 | +| 1.8.20-1.1.0 | 1.8.20 | 4.2.0 | 6.8.3 | +| 1.9.0-1.1.0 | 1.9.0 | 4.2.2 | 6.8.3 | Since the goal of the Kace is to help developers easily upgrade to Kotlin 1.8, the minimum supported version of Kotlin is relatively high diff --git a/README_zh.md b/README_zh.md index bcb044c..bdf42cf 100644 --- a/README_zh.md +++ b/README_zh.md @@ -67,11 +67,12 @@ kace { Kace 目前支持了以上四种最常用的类型,其他 kotlin-android-extensions 支持的类型如 android.app.Fragment, android.app.Dialog, kotlinx.android.extensions.LayoutContainer 等,由于被废弃或者使用较少,Kace 目前没有做支持 ## 版本兼容 -| Kace | Kotlin | AGP | Gradle | -|----------------------|--------|-------|--------| -| 1.7.0-1.0.4 | 1.7.0 | 4.2.0 | 6.7.1 | -| 1.8.0-1.0.4 | 1.8.0~1.8.10 | 4.2.0 | 6.8.3 | -| 1.8.20-1.0.4 | 1.8.20 | 4.2.0 | 6.8.3 | +| Kace | Kotlin | AGP | Gradle | +|--------------|--------------|-------|--------| +| 1.7.0-1.0.4 | 1.7.0 | 4.2.0 | 6.7.1 | +| 1.8.0-1.0.4 | 1.8.0~1.8.10 | 4.2.0 | 6.8.3 | +| 1.8.20-1.1.0 | 1.8.20 | 4.2.0 | 6.8.3 | +| 1.9.0-1.1.0 | 1.9.0 | 4.2.2 | 6.8.3 | 由于 Kace 的目标是帮助开发者更方便地迁移到 Kotlin 1.8,因此 Kotlin 最低支持版本比较高 diff --git a/build.gradle.kts b/build.gradle.kts index 046948c..940d60c 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -1,15 +1,16 @@ // Top-level build file where you can add configuration options common to all sub-projects/modules. plugins { - id("com.android.application") version "4.2.0" apply false - id("com.android.library") version "4.2.0" apply false - id("org.jetbrains.kotlin.android") version "1.8.20" apply false + id("com.android.application") version "4.2.2" apply false + id("com.android.library") version "4.2.2" apply false + id("org.jetbrains.kotlin.android") version "1.9.0" apply false id("com.vanniktech.maven.publish") version "0.18.0" apply false id("com.github.gmazzo.buildconfig") version "2.1.0" apply false } allprojects { repositories { - maven { setUrl("https://mirrors.tencent.com/nexus/repository/maven-public/") } + mavenCentral() + google() maven { setUrl("https://oss.sonatype.org/content/repositories/snapshots/") } } diff --git a/gradle.properties b/gradle.properties index bd4ca1c..8cf924d 100644 --- a/gradle.properties +++ b/gradle.properties @@ -23,7 +23,7 @@ kotlin.code.style=official android.nonTransitiveRClass=true KOTLIN_PLUGIN_ID=com.kanyun.kace -VERSION_NAME=1.8.20-1.1.0 +VERSION_NAME=1.9.0-1.2.0-SNAPSHOT GROUP=com.kanyun.kace diff --git a/kace-compiler/build.gradle.kts b/kace-compiler/build.gradle.kts index a99aabb..7539c06 100644 --- a/kace-compiler/build.gradle.kts +++ b/kace-compiler/build.gradle.kts @@ -35,12 +35,11 @@ dependencies { testImplementation(kotlin("test-junit")) testImplementation("org.jetbrains.kotlin:kotlin-compiler-embeddable") - testImplementation("com.bennyhuo.kotlin:kotlin-compile-testing-extensions:1.8.0.1") + testImplementation("com.bennyhuo.kotlin:kotlin-compile-testing-extensions:1.8.20-1.1.0") } val compileKotlin: KotlinCompile by tasks compileKotlin.kotlinOptions.freeCompilerArgs += listOf( - "-Xjvm-default=enable", "-opt-in=kotlin.RequiresOptIn", "-Xcontext-receivers" ) diff --git a/kace-compiler/src/main/java/com/kanyun/kace/compiler/KaceIrTransformer.kt b/kace-compiler/src/main/java/com/kanyun/kace/compiler/KaceIrTransformer.kt index 8a4fb07..d75177f 100644 --- a/kace-compiler/src/main/java/com/kanyun/kace/compiler/KaceIrTransformer.kt +++ b/kace-compiler/src/main/java/com/kanyun/kace/compiler/KaceIrTransformer.kt @@ -25,6 +25,7 @@ import com.kanyun.kace.compiler.utils.irThis import com.kanyun.kace.compiler.utils.isAndroidExtensions import com.kanyun.kace.compiler.utils.symbolOfAndroidExtensionImpl import com.kanyun.kace.compiler.utils.typeOfAndroidExtensionsBase +import com.kanyun.kace.compiler.utils.typeOfJavaClass import com.kanyun.kace.compiler.utils.typeOfView import org.jetbrains.kotlin.backend.common.extensions.IrPluginContext import org.jetbrains.kotlin.backend.common.lower.DeclarationIrBuilder @@ -85,6 +86,7 @@ class KaceIrTransformer(private val context: IrPluginContext) : IrElementTransfo addValueParameter("owner", context.typeOfAndroidExtensionsBase()) addValueParameter("id", context.symbols.int.defaultType) + addValueParameter("viewClass", context.typeOfJavaClass()) body = IrBlockBodyBuilder( context, diff --git a/kace-compiler/src/main/java/com/kanyun/kace/compiler/utils/Consts.kt b/kace-compiler/src/main/java/com/kanyun/kace/compiler/utils/Consts.kt index 8e0bbac..0412980 100644 --- a/kace-compiler/src/main/java/com/kanyun/kace/compiler/utils/Consts.kt +++ b/kace-compiler/src/main/java/com/kanyun/kace/compiler/utils/Consts.kt @@ -34,6 +34,8 @@ val ANDROID_VIEW_CLASS_ID = classId("android.view", "View") val ANDROID_ACTIVITY_CLASS_ID = classId("android.app", "Activity") val ANDROIDX_FRAGMENT_CLASS_ID = classId("androidx.fragment.app", "Fragment") +val JAVA_CLASS_CLASS_ID = classId("java.lang", "Class") + val IMPLICIT_ANDROID_EXTENSIONS_CLASS_IDS = setOf( ANDROID_ACTIVITY_CLASS_ID, ANDROIDX_FRAGMENT_CLASS_ID, diff --git a/kace-compiler/src/main/java/com/kanyun/kace/compiler/utils/Ir.kt b/kace-compiler/src/main/java/com/kanyun/kace/compiler/utils/Ir.kt index 53a1d6d..1a495fb 100644 --- a/kace-compiler/src/main/java/com/kanyun/kace/compiler/utils/Ir.kt +++ b/kace-compiler/src/main/java/com/kanyun/kace/compiler/utils/Ir.kt @@ -21,6 +21,7 @@ import org.jetbrains.kotlin.ir.declarations.IrClass import org.jetbrains.kotlin.ir.declarations.IrFunction import org.jetbrains.kotlin.ir.declarations.IrSimpleFunction import org.jetbrains.kotlin.ir.types.classFqName +import org.jetbrains.kotlin.ir.types.classifierOrNull import org.jetbrains.kotlin.ir.types.defaultType import org.jetbrains.kotlin.ir.util.functions @@ -32,10 +33,11 @@ fun IrClass.findViewByIdCached(pluginContext: IrPluginContext): IrSimpleFunction fun IrFunction.isFindViewByIdCached(pluginContext: IrPluginContext): Boolean { return name.identifier == FIND_VIEW_BY_ID_CACHED_NAME && - valueParameters.size == 2 && - valueParameters[0].type == - pluginContext.referenceClass(ANDROID_EXTENSIONS_BASE_CLASS_ID)?.defaultType && - valueParameters[1].type == pluginContext.symbols.int.defaultType + valueParameters.size == 3 && + valueParameters[0].type == pluginContext.typeOfAndroidExtensionsBase() && + valueParameters[1].type == pluginContext.symbols.int.defaultType && + // java.lang.Class -> java.lang.Class + valueParameters[2].type.classifierOrNull?.defaultType == pluginContext.typeOfJavaClass() } fun IrClass.isAndroidExtensions(): Boolean { @@ -47,5 +49,7 @@ fun IrPluginContext.typeOfAndroidExtensionsBase() = fun IrPluginContext.typeOfView() = referenceClass(ANDROID_VIEW_CLASS_ID)!!.defaultType +fun IrPluginContext.typeOfJavaClass() = referenceClass(JAVA_CLASS_CLASS_ID)!!.defaultType + fun IrPluginContext.symbolOfAndroidExtensionImpl() = referenceClass(ANDROID_EXTENSIONS_IMPL_CLASS_ID)!! diff --git a/kace-compiler/src/test/java/com/kanyun/kace/compiler/KaceTest.kt b/kace-compiler/src/test/java/com/kanyun/kace/compiler/KaceTest.kt index 05e03f9..33a007f 100644 --- a/kace-compiler/src/test/java/com/kanyun/kace/compiler/KaceTest.kt +++ b/kace-compiler/src/test/java/com/kanyun/kace/compiler/KaceTest.kt @@ -18,10 +18,11 @@ package com.kanyun.kace.compiler import com.bennyhuo.kotlin.compiletesting.extensions.module.KotlinModule import com.bennyhuo.kotlin.compiletesting.extensions.module.checkResult -import com.bennyhuo.kotlin.compiletesting.extensions.source.FileBasedModuleInfoLoader +import com.bennyhuo.kotlin.compiletesting.extensions.source.TextBasedModuleInfoLoader import com.kanyun.kace.compiler.options.Options import org.jetbrains.kotlin.compiler.plugin.ExperimentalCompilerApi import org.junit.Test +import java.io.File class KaceTest { @@ -37,7 +38,9 @@ class KaceTest { @OptIn(ExperimentalCompilerApi::class) private fun testBase(fileName: String, useK2: Boolean) { - val loader = FileBasedModuleInfoLoader("testData/$fileName") + val source = File("testData/source.txt").readText() + val expect = File("testData/$fileName").readText() + val loader = TextBasedModuleInfoLoader("$source\n$expect") val sourceModuleInfos = loader.loadSourceModuleInfos() Options.isEnabled.set(true) diff --git a/kace-compiler/testData/K1.txt b/kace-compiler/testData/K1.txt index 44cf613..1be30e7 100644 --- a/kace-compiler/testData/K1.txt +++ b/kace-compiler/testData/K1.txt @@ -1,139 +1,3 @@ -// SOURCE -// FILE: Activity.java -package android.app; - -public class Activity { - -} -// FILE: BaseActivity.java -package android.app; - -import android.app.Activity; - -public class BaseActivity extends Activity { - -} -// FILE: BaseKotlinActivity.kt -package android.app - -import android.app.Activity - -open class BaseKotlinActivity : Activity() { - -} -// FILE: Base2Activity.java -package android.app; - -import android.app.Activity; - -public class Base2Activity extends BaseKotlinActivity { - -} -// FILE: View.java -package android.view; - -public class View { - public String value; - public View(String value) { - this.value = value; - } - - public String toString() { - return value; - } -} -// FILE: AndroidExtensionsBase.java -package com.kanyun.kace; - -import android.view.View; - -public interface AndroidExtensionsBase { - - T findViewByIdCached(AndroidExtensionsBase owner, int id); - -} -// FILE: common.kt -package com.kanyun.kace - -import android.view.View - -interface AndroidExtensions: AndroidExtensionsBase { - override fun findViewByIdCached(owner: AndroidExtensionsBase, id: Int): T? = error("Never called!") -} -class AndroidExtensionsImpl: AndroidExtensions { - - private val map = HashMap() - - init { - List(10) { - map[it] = View("$it") - } - } - - override fun findViewByIdCached(owner: AndroidExtensionsBase, id: Int): T? { - println(owner::class) - return map[id] as T? - } -} - -// FILE: Main.kt [MainKt#main] -import com.kanyun.kace.AndroidExtensions -import com.kanyun.kace.AndroidExtensionsBase -import com.kanyun.kace.AndroidExtensionsImpl -import android.view.View -import android.app.Activity -import android.app.BaseActivity -import android.app.Base2Activity - -class MainActivity : AndroidExtensions by AndroidExtensionsImpl() { - -} - -class SecondActivity : AndroidExtensions { - -} - -class ThirdActivity : AndroidExtensions { - - override fun findViewByIdCached(owner: AndroidExtensionsBase, id: Int): T? { - println(owner::class) - return View("Third!!") as T? - } -} - -open class FourthActivity : Activity() { - -} - - -class FifthActivity : BaseActivity() { - -} - -class SixthActivity : Base2Activity() { - -} - -fun main() { - val main = MainActivity() - println(main.findViewByIdCached(main, 0)) - - val second = SecondActivity() - println(second.findViewByIdCached(second, 1)) - - val third = ThirdActivity() - println(third.findViewByIdCached(third, 2)) - - val fouth = FourthActivity() - println(fouth.findViewByIdCached(fouth, 3)) - - val fifth = FifthActivity() - println(fifth.findViewByIdCached(fifth, 4)) - - val sixth = SixthActivity() - println(sixth.findViewByIdCached(sixth, 7)) -} - // EXPECT // FILE: compiles.log OK @@ -153,46 +17,46 @@ class SixthActivity // FILE: Main.kt.ir class MainActivity : AndroidExtensions { private val $$delegate_0: AndroidExtensionsImpl = AndroidExtensionsImpl() - override fun findViewByIdCached(owner: AndroidExtensionsBase, id: Int): T? { - return .$$delegate_0.findViewByIdCached(owner, id) + override fun findViewByIdCached(owner: AndroidExtensionsBase, id: Int, viewClass: Class): T? { + return .$$delegate_0.findViewByIdCached(owner, id, viewClass) } } class SecondActivity : AndroidExtensions { private var $$androidExtensionsImpl: AndroidExtensionsImpl = AndroidExtensionsImpl() - override fun findViewByIdCached(owner: AndroidExtensionsBase, id: Int): T? { - return .$$androidExtensionsImpl.findViewByIdCached(owner, id) + override fun findViewByIdCached(owner: AndroidExtensionsBase, id: Int, viewClass: Class): T? { + return .$$androidExtensionsImpl.findViewByIdCached(owner, id, viewClass) } } class ThirdActivity : AndroidExtensions { - override fun findViewByIdCached(owner: AndroidExtensionsBase, id: Int): T? { + override fun findViewByIdCached(owner: AndroidExtensionsBase, id: Int, viewClass: Class): T? { println(<>) return View("Third!!") } } open class FourthActivity : Activity, AndroidExtensions { private var $$androidExtensionsImpl: AndroidExtensionsImpl = AndroidExtensionsImpl() - override fun findViewByIdCached(owner: AndroidExtensionsBase, id: Int): T? { - return .$$androidExtensionsImpl.findViewByIdCached(owner, id) + override fun findViewByIdCached(owner: AndroidExtensionsBase, id: Int, viewClass: Class): T? { + return .$$androidExtensionsImpl.findViewByIdCached(owner, id, viewClass) } } class FifthActivity : BaseActivity, AndroidExtensions { private var $$androidExtensionsImpl: AndroidExtensionsImpl = AndroidExtensionsImpl() - override fun findViewByIdCached(owner: AndroidExtensionsBase, id: Int): T? { - return .$$androidExtensionsImpl.findViewByIdCached(owner, id) + override fun findViewByIdCached(owner: AndroidExtensionsBase, id: Int, viewClass: Class): T? { + return .$$androidExtensionsImpl.findViewByIdCached(owner, id, viewClass) } } -class SixthActivity : Base2Activity +class SixthActivity : Base2Activity fun main() { val main = MainActivity() - println(main.findViewByIdCached(main, 0)) + println(main.findViewByIdCached(main, 0, View::class.java)) val second = SecondActivity() - println(second.findViewByIdCached(second, 1)) + println(second.findViewByIdCached(second, 1, View::class.java)) val third = ThirdActivity() - println(third.findViewByIdCached(third, 2)) + println(third.findViewByIdCached(third, 2, View::class.java)) val fouth = FourthActivity() - println(fouth.findViewByIdCached(fouth, 3)) + println(fouth.findViewByIdCached(fouth, 3, View::class.java)) val fifth = FifthActivity() - println(fifth.findViewByIdCached(fifth, 4)) + println(fifth.findViewByIdCached(fifth, 4, View::class.java)) val sixth = SixthActivity() - println(sixth.findViewByIdCached(sixth, 7)) + println(sixth.findViewByIdCached(sixth, 7, View::class.java)) } diff --git a/kace-compiler/testData/K2.txt b/kace-compiler/testData/K2.txt index 96286f4..354a38c 100644 --- a/kace-compiler/testData/K2.txt +++ b/kace-compiler/testData/K2.txt @@ -1,139 +1,3 @@ -// SOURCE -// FILE: Activity.java -package android.app; - -public class Activity { - -} -// FILE: BaseActivity.java -package android.app; - -import android.app.Activity; - -public class BaseActivity extends Activity { - -} -// FILE: BaseKotlinActivity.kt -package android.app - -import android.app.Activity - -open class BaseKotlinActivity : Activity() { - -} -// FILE: Base2Activity.java -package android.app; - -import android.app.Activity; - -public class Base2Activity extends BaseKotlinActivity { - -} -// FILE: View.java -package android.view; - -public class View { - public String value; - public View(String value) { - this.value = value; - } - - public String toString() { - return value; - } -} -// FILE: AndroidExtensionsBase.java -package com.kanyun.kace; - -import android.view.View; - -public interface AndroidExtensionsBase { - - T findViewByIdCached(AndroidExtensionsBase owner, int id); - -} -// FILE: common.kt -package com.kanyun.kace - -import android.view.View - -interface AndroidExtensions: AndroidExtensionsBase { - override fun findViewByIdCached(owner: AndroidExtensionsBase, id: Int): T? = error("Never called!") -} -class AndroidExtensionsImpl: AndroidExtensions { - - private val map = HashMap() - - init { - List(10) { - map[it] = View("$it") - } - } - - override fun findViewByIdCached(owner: AndroidExtensionsBase, id: Int): T? { - println(owner::class) - return map[id] as T? - } -} - -// FILE: Main.kt [MainKt#main] -import com.kanyun.kace.AndroidExtensions -import com.kanyun.kace.AndroidExtensionsBase -import com.kanyun.kace.AndroidExtensionsImpl -import android.view.View -import android.app.Activity -import android.app.BaseActivity -import android.app.Base2Activity - -class MainActivity : AndroidExtensions by AndroidExtensionsImpl() { - -} - -class SecondActivity : AndroidExtensions { - -} - -class ThirdActivity : AndroidExtensions { - - override fun findViewByIdCached(owner: AndroidExtensionsBase, id: Int): T? { - println(owner::class) - return View("Third!!") as T? - } -} - -open class FourthActivity : Activity() { - -} - - -class FifthActivity : BaseActivity() { - -} - -class SixthActivity : Base2Activity() { - -} - -fun main() { - val main = MainActivity() - println(main.findViewByIdCached(main, 0)) - - val second = SecondActivity() - println(second.findViewByIdCached(second, 1)) - - val third = ThirdActivity() - println(third.findViewByIdCached(third, 2)) - - val fouth = FourthActivity() - println(fouth.findViewByIdCached(fouth, 3)) - - val fifth = FifthActivity() - println(fifth.findViewByIdCached(fifth, 4)) - - val sixth = SixthActivity() - println(sixth.findViewByIdCached(sixth, 7)) -} - // EXPECT // MODULE: default-module // FILE: compiles.log @@ -153,47 +17,47 @@ class SixthActivity 7 // FILE: Main.kt.ir class MainActivity : AndroidExtensions { - override fun findViewByIdCached(owner: AndroidExtensionsBase, id: Int): T? { - return .$$delegate_0.findViewByIdCached(owner, id) + override fun findViewByIdCached(owner: AndroidExtensionsBase, id: Int, viewClass: Class): T? { + return .$$delegate_0.findViewByIdCached(owner, id, viewClass) } private val $$delegate_0: AndroidExtensionsImpl = AndroidExtensionsImpl() } class SecondActivity : AndroidExtensions { private var $$androidExtensionsImpl: AndroidExtensionsImpl = AndroidExtensionsImpl() - override fun findViewByIdCached(owner: AndroidExtensionsBase, id: Int): T? { - return .$$androidExtensionsImpl.findViewByIdCached(owner, id) + override fun findViewByIdCached(owner: AndroidExtensionsBase, id: Int, viewClass: Class): T? { + return .$$androidExtensionsImpl.findViewByIdCached(owner, id, viewClass) } } class ThirdActivity : AndroidExtensions { - override fun findViewByIdCached(owner: AndroidExtensionsBase, id: Int): T? { + override fun findViewByIdCached(owner: AndroidExtensionsBase, id: Int, viewClass: Class): T? { println(<>) return View("Third!!") } } open class FourthActivity : Activity, AndroidExtensions { private var $$androidExtensionsImpl: AndroidExtensionsImpl = AndroidExtensionsImpl() - override fun findViewByIdCached(owner: AndroidExtensionsBase, id: Int): T? { - return .$$androidExtensionsImpl.findViewByIdCached(owner, id) + override fun findViewByIdCached(owner: AndroidExtensionsBase, id: Int, viewClass: Class): T? { + return .$$androidExtensionsImpl.findViewByIdCached(owner, id, viewClass) } } class FifthActivity : BaseActivity, AndroidExtensions { private var $$androidExtensionsImpl: AndroidExtensionsImpl = AndroidExtensionsImpl() - override fun findViewByIdCached(owner: AndroidExtensionsBase, id: Int): T? { - return .$$androidExtensionsImpl.findViewByIdCached(owner, id) + override fun findViewByIdCached(owner: AndroidExtensionsBase, id: Int, viewClass: Class): T? { + return .$$androidExtensionsImpl.findViewByIdCached(owner, id, viewClass) } } -class SixthActivity : Base2Activity +class SixthActivity : Base2Activity fun main() { val main = MainActivity() - println(main.findViewByIdCached(main, 0)) + println(main.findViewByIdCached(main, 0, View::class.java)) val second = SecondActivity() - println(second.findViewByIdCached(second, 1)) + println(second.findViewByIdCached(second, 1, View::class.java)) val third = ThirdActivity() - println(third.findViewByIdCached(third, 2)) + println(third.findViewByIdCached(third, 2, View::class.java)) val fouth = FourthActivity() - println(fouth.findViewByIdCached(fouth, 3)) + println(fouth.findViewByIdCached(fouth, 3, View::class.java)) val fifth = FifthActivity() - println(fifth.findViewByIdCached(fifth, 4)) + println(fifth.findViewByIdCached(fifth, 4, View::class.java)) val sixth = SixthActivity() - println(sixth.findViewByIdCached(sixth, 7)) + println(sixth.findViewByIdCached(sixth, 7, View::class.java)) } diff --git a/kace-compiler/testData/source.txt b/kace-compiler/testData/source.txt new file mode 100644 index 0000000..f918f29 --- /dev/null +++ b/kace-compiler/testData/source.txt @@ -0,0 +1,139 @@ +// SOURCE +// FILE: Activity.java +package android.app; + +public class Activity { + +} +// FILE: BaseActivity.java +package android.app; + +import android.app.Activity; + +public class BaseActivity extends Activity { + +} +// FILE: BaseKotlinActivity.kt +package android.app + +import android.app.Activity + +open class BaseKotlinActivity : Activity() { + +} +// FILE: Base2Activity.java +package android.app; + +import android.app.Activity; + +public class Base2Activity extends BaseKotlinActivity { + +} +// FILE: View.java +package android.view; + +public class View { + public String value; + public View(String value) { + this.value = value; + } + + public String toString() { + return value; + } +} +// FILE: AndroidExtensionsBase.java +package com.kanyun.kace; + +import android.view.View; + +public interface AndroidExtensionsBase { + + T findViewByIdCached(AndroidExtensionsBase owner, int id, Class viewClass); + +} +// FILE: common.kt +package com.kanyun.kace + +import android.view.View + +interface AndroidExtensions : AndroidExtensionsBase { + + override fun findViewByIdCached(owner: AndroidExtensionsBase, id: Int, viewClass: Class): T? = + error("Never called.") + +} + +class AndroidExtensionsImpl: AndroidExtensions { + + private val map = HashMap() + + init { + List(10) { + map[it] = View("$it") + } + } + + override fun findViewByIdCached(owner: AndroidExtensionsBase, id: Int, viewClass: Class): T? { + println(owner::class) + return map[id] as T? + } +} + +// FILE: Main.kt [MainKt#main] +import com.kanyun.kace.AndroidExtensions +import com.kanyun.kace.AndroidExtensionsBase +import com.kanyun.kace.AndroidExtensionsImpl +import android.view.View +import android.app.Activity +import android.app.BaseActivity +import android.app.Base2Activity + +class MainActivity : AndroidExtensions by AndroidExtensionsImpl() { + +} + +class SecondActivity : AndroidExtensions { + +} + +class ThirdActivity : AndroidExtensions { + + override fun findViewByIdCached(owner: AndroidExtensionsBase, id: Int, viewClass: Class): T? { + println(owner::class) + return View("Third!!") as T? + } +} + +open class FourthActivity : Activity() { + +} + + +class FifthActivity : BaseActivity() { + +} + +class SixthActivity : Base2Activity() { + +} + +fun main() { + val main = MainActivity() + println(main.findViewByIdCached(main, 0, View::class.java)) + + val second = SecondActivity() + println(second.findViewByIdCached(second, 1, View::class.java)) + + val third = ThirdActivity() + println(third.findViewByIdCached(third, 2, View::class.java)) + + val fouth = FourthActivity() + println(fouth.findViewByIdCached(fouth, 3, View::class.java)) + + val fifth = FifthActivity() + println(fifth.findViewByIdCached(fifth, 4, View::class.java)) + + val sixth = SixthActivity() + println(sixth.findViewByIdCached(sixth, 7, View::class.java)) +} diff --git a/kace-gradle-plugin/build.gradle.kts b/kace-gradle-plugin/build.gradle.kts index 7b616fe..26490a5 100644 --- a/kace-gradle-plugin/build.gradle.kts +++ b/kace-gradle-plugin/build.gradle.kts @@ -25,7 +25,7 @@ dependencies { implementation(kotlin("gradle-plugin")) implementation(kotlin("stdlib-jdk8")) - compileOnly("com.android.tools.build:gradle:4.2.0") + compileOnly("com.android.tools.build:gradle:4.2.2") compileOnly("org.jetbrains.kotlin:kotlin-gradle-plugin:1.7.0") implementation("org.jetbrains.kotlin:kotlin-compiler-embeddable") } diff --git a/kace-gradle-plugin/src/main/java/com/kanyun/kace/gradle/KaceGenerateAction.kt b/kace-gradle-plugin/src/main/java/com/kanyun/kace/gradle/KaceGenerateAction.kt index 4be545b..3bc68cd 100644 --- a/kace-gradle-plugin/src/main/java/com/kanyun/kace/gradle/KaceGenerateAction.kt +++ b/kace-gradle-plugin/src/main/java/com/kanyun/kace/gradle/KaceGenerateAction.kt @@ -71,7 +71,7 @@ abstract class KaceGenerateAction : WorkAction { layoutNodeItems.forEach { item -> writer.appendLine("private inline val AndroidExtensionsBase.${item.viewId}") - writer.appendLine(" get() = findViewByIdCached<${item.viewNameWithPackage}>(this, R.id.${item.viewId})") + writer.appendLine(" get() = findViewByIdCached(this, R.id.${item.viewId}, ${item.viewNameWithPackage}::class.java)") writer.appendLine("internal inline val Activity.${item.viewId}") writer.appendLine(" get() = (this as AndroidExtensionsBase).${item.viewId}") writer.appendLine("internal inline val Fragment.${item.viewId}") @@ -93,12 +93,13 @@ abstract class KaceGenerateAction : WorkAction { writer.appendLine("package ${item.targetFilePackageName}.view") writer.newLine() writer.appendLine("import android.view.View") + writer.appendLine("import com.kanyun.kace.KaceViewUtils") writer.appendLine("import $namespace.R") writer.newLine() layoutNodeItems.forEach { item -> writer.appendLine("internal inline val View.${item.viewId}") - writer.appendLine(" get() = findViewById<${item.viewNameWithPackage}>(R.id.${item.viewId})") + writer.appendLine(" get() = KaceViewUtils.findViewById(this, R.id.${item.viewId}, ${item.viewNameWithPackage}::class.java)") writer.newLine() } } diff --git a/kace-runtime/src/main/java/com/kanyun/kace/AndroidExtensions.kt b/kace-runtime/src/main/java/com/kanyun/kace/AndroidExtensions.kt index 1ef8121..a722531 100644 --- a/kace-runtime/src/main/java/com/kanyun/kace/AndroidExtensions.kt +++ b/kace-runtime/src/main/java/com/kanyun/kace/AndroidExtensions.kt @@ -20,6 +20,6 @@ import android.view.View interface AndroidExtensions : AndroidExtensionsBase { - override fun findViewByIdCached(owner: AndroidExtensionsBase, id: Int): T = + override fun findViewByIdCached(owner: AndroidExtensionsBase, id: Int, viewClass: Class): T? = error("Never called.") } diff --git a/kace-runtime/src/main/java/com/kanyun/kace/AndroidExtensionsBase.java b/kace-runtime/src/main/java/com/kanyun/kace/AndroidExtensionsBase.java index b510fa9..635910a 100644 --- a/kace-runtime/src/main/java/com/kanyun/kace/AndroidExtensionsBase.java +++ b/kace-runtime/src/main/java/com/kanyun/kace/AndroidExtensionsBase.java @@ -23,6 +23,6 @@ public interface AndroidExtensionsBase { /** * It is necessary to write this in Java, because we want a platform type here as the return type. */ - T findViewByIdCached(AndroidExtensionsBase owner, int id); + T findViewByIdCached(AndroidExtensionsBase owner, int id, Class viewClass); } \ No newline at end of file diff --git a/kace-runtime/src/main/java/com/kanyun/kace/AndroidExtensionsImpl.kt b/kace-runtime/src/main/java/com/kanyun/kace/AndroidExtensionsImpl.kt index 93fa9a6..56f760f 100644 --- a/kace-runtime/src/main/java/com/kanyun/kace/AndroidExtensionsImpl.kt +++ b/kace-runtime/src/main/java/com/kanyun/kace/AndroidExtensionsImpl.kt @@ -36,7 +36,7 @@ class AndroidExtensionsImpl : AndroidExtensions { } } - override fun findViewByIdCached(owner: AndroidExtensionsBase, id: Int): T { + override fun findViewByIdCached(owner: AndroidExtensionsBase, id: Int, viewClass: Class): T { initComponent(owner) initCachedHashMap() return cached?.getOrPut(id) { component!!.findViewById(id) } as T diff --git a/kace-runtime/src/main/java/com/kanyun/kace/KaceViewUtils.java b/kace-runtime/src/main/java/com/kanyun/kace/KaceViewUtils.java new file mode 100644 index 0000000..96998a0 --- /dev/null +++ b/kace-runtime/src/main/java/com/kanyun/kace/KaceViewUtils.java @@ -0,0 +1,14 @@ +package com.kanyun.kace; + +import android.view.View; + +/** + * Created by benny at 2023/8/17 15:28. + */ +public class KaceViewUtils { + + public static T findViewById(View view, int id, Class viewClass) { + return view.findViewById(id); + } + +} diff --git a/kace-sample/app/src/main/java/com/kanyun/kace/sample/demo/GenericView.kt b/kace-sample/app/src/main/java/com/kanyun/kace/sample/demo/GenericView.kt new file mode 100644 index 0000000..052bb1d --- /dev/null +++ b/kace-sample/app/src/main/java/com/kanyun/kace/sample/demo/GenericView.kt @@ -0,0 +1,13 @@ +package com.kanyun.kace.sample.demo + +import android.content.Context +import android.util.AttributeSet +import android.view.View + +/** + * Created by benny at 2023/8/17 15:37. + */ +class GenericView +@JvmOverloads constructor( + context: Context?, attrs: AttributeSet? = null, defStyleAttr: Int = 0 +) : View(context, attrs, defStyleAttr) \ No newline at end of file diff --git a/kace-sample/app/src/main/java/com/kanyun/kace/sample/demo/MainActivity.kt b/kace-sample/app/src/main/java/com/kanyun/kace/sample/demo/MainActivity.kt index 04ee02b..768e73a 100644 --- a/kace-sample/app/src/main/java/com/kanyun/kace/sample/demo/MainActivity.kt +++ b/kace-sample/app/src/main/java/com/kanyun/kace/sample/demo/MainActivity.kt @@ -17,6 +17,7 @@ package com.kanyun.kace.sample.demo import android.content.Intent +import android.graphics.Color import android.os.Bundle import android.util.Log import android.widget.Toast @@ -40,6 +41,8 @@ class MainActivity : AppCompatActivity(){ } button1.text2?.text = "test text" + + genericView.setBackgroundColor(Color.YELLOW) } override fun onDestroy() { diff --git a/kace-sample/app/src/main/res/layout/activity_main.xml b/kace-sample/app/src/main/res/layout/activity_main.xml index 60f0028..f6e2287 100644 --- a/kace-sample/app/src/main/res/layout/activity_main.xml +++ b/kace-sample/app/src/main/res/layout/activity_main.xml @@ -43,4 +43,10 @@ android:layout_width="match_parent" android:layout_height="100dp" /> + + \ No newline at end of file diff --git a/kace-sample/build.gradle.kts b/kace-sample/build.gradle.kts index 71ff01a..75e1a34 100644 --- a/kace-sample/build.gradle.kts +++ b/kace-sample/build.gradle.kts @@ -2,7 +2,7 @@ plugins { id("com.android.application") apply false id("com.android.library") apply false - id("org.jetbrains.kotlin.android") version "1.8.20" apply false + id("org.jetbrains.kotlin.android") version "1.9.0" apply false id("com.kanyun.kace") version "0.0.0-SNAPSHOT" apply false } diff --git a/kace-sample/gradle.properties b/kace-sample/gradle.properties index 3fac72c..981c599 100644 --- a/kace-sample/gradle.properties +++ b/kace-sample/gradle.properties @@ -28,4 +28,4 @@ kotlin_version = 1.7.0 kotlin_coroutine_version = 1.6.3 testAgp=false -agpVersion=4.2.0 \ No newline at end of file +agpVersion=4.2.2 \ No newline at end of file diff --git a/settings.gradle b/settings.gradle index f4d5495..067a9ec 100644 --- a/settings.gradle +++ b/settings.gradle @@ -1,6 +1,7 @@ pluginManagement { repositories { - maven { url 'https://mirrors.tencent.com/nexus/repository/maven-public/' } + mavenCentral() + google() gradlePluginPortal() } } diff --git a/test_agp.sh b/test_agp.sh index 2699483..2480378 100755 --- a/test_agp.sh +++ b/test_agp.sh @@ -17,7 +17,7 @@ function testUnderAGPVersion() { cd kace-sample setGradleVersion 6.8.3 -testUnderAGPVersion 4.2.0 +testUnderAGPVersion 4.2.2 setGradleVersion 7.3.3 testUnderAGPVersion 7.2.0