Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .github/CODEOWNERS
Original file line number Diff line number Diff line change
@@ -1 +1,2 @@
.github/ @VKCOM/vk-sec
* @VKCOM/Android
4 changes: 2 additions & 2 deletions .github/workflows/publish_plugins.yml
Original file line number Diff line number Diff line change
Expand Up @@ -22,13 +22,13 @@ jobs:
- name: Grant Permission to Execute Gradle
run: chmod +x gradlew
- name: Grant Permission to scripts
run: chmod +x ./scripts/publish_plugins_remote.sh
run: chmod +x ./scripts/publish_plugins_remote

- name: Release build
run: ./gradlew build

- name: Publish to MavenCentral
run: ./scripts/publish_plugins_remote.sh
run: ./scripts/publish_plugins_remote
env:
REMOTE_REPO_PUBLIC_URL: ${{ secrets.REMOTE_REPO_PUBLIC_URL }}
ORG_GRADLE_PROJECT_mavenCentralUsername: ${{ secrets.REMOTE_REPO_PUBLIC_USER }}
Expand Down
4 changes: 2 additions & 2 deletions .github/workflows/publish_rules.yml
Original file line number Diff line number Diff line change
Expand Up @@ -20,13 +20,13 @@ jobs:
- name: Grant Permission to Execute Gradle
run: chmod +x gradlew
- name: Grant Permission to scripts
run: chmod +x ./scripts/publish_rules_remote.sh
run: chmod +x ./scripts/publish_rules_remote

- name: Release build
run: ./gradlew build

- name: Publish to MavenCentral
run: ./scripts/publish_rules_remote.sh
run: ./scripts/publish_rules_remote
env:
REMOTE_REPO_PUBLIC_URL: ${{ secrets.REMOTE_REPO_PUBLIC_URL }}
ORG_GRADLE_PROJECT_mavenCentralUsername: ${{ secrets.REMOTE_REPO_PUBLIC_USER }}
Expand Down
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -9,3 +9,4 @@ build/
.cxx
local.properties
/idea-plugin/compose-test-tag/.idea/
scripts/etc/*
20 changes: 9 additions & 11 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ The repository contains utilities for Jetpack Compose, including Kotlin compiler
| 0.7 | 2.1.0 |
| 0.7.1 | 2.2.0 |
| 0.7.2 | 2.2.21 |
| 0.8.0 | 2.3.20 |

Currently, the following compiler plugins are available:
- Functions skippability checker: Determines [function skippability](https://github.com/androidx/androidx/blob/androidx-main/compose/compiler/design/compiler-metrics.md#functions-that-are-restartable-but-not-skippable) based on checking function parameters stability.
Expand All @@ -28,7 +29,7 @@ How to use?
1. Apply Gradle plugin
```kotlin
plugins {
id("com.vk.vkompose") version "0.7.2"
id("com.vk.vkompose") version "0.8.0"
}
```

Expand Down Expand Up @@ -98,13 +99,13 @@ TestTagDrawConfig.isEnabled = true
Besides these plugins are published separately. So if you want to use only one, you can do.
```kotlin
plugins {
id("com.vk.recompose-highlighter") version "0.7.2"
id("com.vk.recompose-logger") version "0.7.2"
id("com.vk.compose-test-tag-applier") version "0.7.2"
id("com.vk.compose-test-tag-cleaner") version "0.7.2"
id("com.vk.compose-test-tag-drawer") version "0.7.2"
id("com.vk.compose-source-information-cleaner") version "0.7.2"
id("com.vk.composable-skippability-checker") version "0.7.2"
id("com.vk.recompose-highlighter") version "0.8.0"
id("com.vk.recompose-logger") version "0.8.0"
id("com.vk.compose-test-tag-applier") version "0.8.0"
id("com.vk.compose-test-tag-cleaner") version "0.8.0"
id("com.vk.compose-test-tag-drawer") version "0.8.0"
id("com.vk.compose-source-information-cleaner") version "0.8.0"
id("com.vk.composable-skippability-checker") version "0.8.0"
}

recomposeHighlighter {
Expand Down Expand Up @@ -209,6 +210,3 @@ vkompose:
#### Strong skipping problems suppression since 0.6
In the compiler plugin, detector rules and plugin functions, ideas can be suppressed by either of the suppressions: NonSkippableComposable or ParamsComparedByRef.
The NonSkippableComposable suppression will be removed in the future. For now, if strong skip is enabled, the idea plugin will mark NonSkippableComposable as unused and you can easily switch to ParamsComparedByRef

### Known issues
- Idea plugin cannot draw a test tag marker for functions from other libraries if they have a default Modifier value and Modifier is not explicitly passes as an argument. For more see [KTIJ-27688](https://youtrack.jetbrains.com/issue/KTIJ-27688/Quick-documentation-shows-COMPILEDCODE-instead-of-the-real-default-value-for-compiled-code-with-sources)
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ plugins {
}

android {
compileSdk = 33
compileSdk = 34

defaultConfig {
minSdk = 21
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,32 +12,40 @@ org.bouncycastle:bcprov-jdk18on:1.80=kotlinBouncyCastleConfiguration
org.bouncycastle:bcutil-jdk18on:1.80=kotlinBouncyCastleConfiguration
org.checkerframework:checker-qual:3.43.0=swiftExportClasspathResolvable
org.jetbrains.intellij.deps:trove4j:1.0.20200330=dependencySources
org.jetbrains.kotlin:abi-tools-api:2.2.21=kotlinInternalAbiValidation
org.jetbrains.kotlin:abi-tools:2.2.21=kotlinInternalAbiValidation
org.jetbrains.kotlin:kotlin-build-tools-api:2.2.21=kotlinBuildToolsApiClasspath
org.jetbrains.kotlin:kotlin-build-tools-impl:2.2.21=kotlinBuildToolsApiClasspath
org.jetbrains.kotlin:abi-tools-api:2.3.20=kotlinInternalAbiValidation
org.jetbrains.kotlin:abi-tools:2.3.20=kotlinInternalAbiValidation
org.jetbrains.kotlin:kotlin-build-tools-api:2.3.20=kotlinBuildToolsApiClasspath,kotlinCompilerClasspath
org.jetbrains.kotlin:kotlin-build-tools-compat:2.3.20=kotlinBuildToolsApiClasspath,kotlinCompilerClasspath
org.jetbrains.kotlin:kotlin-build-tools-cri-impl:2.3.20=kotlinBuildToolsApiClasspath,kotlinCompilerClasspath
org.jetbrains.kotlin:kotlin-build-tools-impl:2.3.20=kotlinBuildToolsApiClasspath,kotlinCompilerClasspath
org.jetbrains.kotlin:kotlin-compiler-embeddable:2.0.0=dependencySources
org.jetbrains.kotlin:kotlin-compiler-embeddable:2.2.21=compileClasspath,compileOnlyDependenciesMetadata,kotlinBuildToolsApiClasspath,kotlinCompilerClasspath,kotlinInternalAbiValidation,kotlinKlibCommonizerClasspath,swiftExportClasspathResolvable
org.jetbrains.kotlin:kotlin-compiler-runner:2.2.21=kotlinBuildToolsApiClasspath
org.jetbrains.kotlin:kotlin-daemon-client:2.2.21=kotlinBuildToolsApiClasspath
org.jetbrains.kotlin:kotlin-compiler-embeddable:2.2.21=compileOnlyDependenciesMetadata,swiftExportClasspathResolvable
org.jetbrains.kotlin:kotlin-compiler-embeddable:2.3.20=compileClasspath,kotlinBuildToolsApiClasspath,kotlinCompilerClasspath,kotlinKlibCommonizerClasspath
org.jetbrains.kotlin:kotlin-compiler-runner:2.3.20=kotlinBuildToolsApiClasspath,kotlinCompilerClasspath
org.jetbrains.kotlin:kotlin-daemon-client:2.3.20=kotlinBuildToolsApiClasspath,kotlinCompilerClasspath
org.jetbrains.kotlin:kotlin-daemon-embeddable:2.0.0=dependencySources
org.jetbrains.kotlin:kotlin-daemon-embeddable:2.2.21=kotlinBuildToolsApiClasspath,kotlinCompilerClasspath,kotlinInternalAbiValidation,kotlinKlibCommonizerClasspath,swiftExportClasspathResolvable
org.jetbrains.kotlin:kotlin-klib-commonizer-embeddable:2.2.21=kotlinKlibCommonizerClasspath
org.jetbrains.kotlin:kotlin-metadata-jvm:2.2.21=kotlinInternalAbiValidation
org.jetbrains.kotlin:kotlin-daemon-embeddable:2.2.21=swiftExportClasspathResolvable
org.jetbrains.kotlin:kotlin-daemon-embeddable:2.3.20=kotlinBuildToolsApiClasspath,kotlinCompilerClasspath,kotlinKlibCommonizerClasspath
org.jetbrains.kotlin:kotlin-klib-abi-reader:2.3.20=kotlinInternalAbiValidation
org.jetbrains.kotlin:kotlin-klib-commonizer-embeddable:2.3.20=kotlinKlibCommonizerClasspath
org.jetbrains.kotlin:kotlin-metadata-jvm:2.3.20=kotlinInternalAbiValidation
org.jetbrains.kotlin:kotlin-native-prebuilt:2.0.20=kotlinNativeBundleConfiguration
org.jetbrains.kotlin:kotlin-reflect:1.6.10=dependencySources,kotlinBuildToolsApiClasspath,kotlinCompilerClasspath,kotlinInternalAbiValidation,kotlinKlibCommonizerClasspath,swiftExportClasspathResolvable
org.jetbrains.kotlin:kotlin-reflect:1.6.10=dependencySources,kotlinBuildToolsApiClasspath,kotlinCompilerClasspath,kotlinKlibCommonizerClasspath,swiftExportClasspathResolvable
org.jetbrains.kotlin:kotlin-script-runtime:2.0.0=dependencySources
org.jetbrains.kotlin:kotlin-script-runtime:2.2.21=kotlinBuildToolsApiClasspath,kotlinCompilerClasspath,kotlinCompilerPluginClasspathMain,kotlinCompilerPluginClasspathTest,kotlinInternalAbiValidation,kotlinKlibCommonizerClasspath,swiftExportClasspathResolvable
org.jetbrains.kotlin:kotlin-scripting-common:2.2.21=kotlinBuildToolsApiClasspath,kotlinCompilerPluginClasspathMain,kotlinCompilerPluginClasspathTest
org.jetbrains.kotlin:kotlin-scripting-compiler-embeddable:2.2.21=kotlinBuildToolsApiClasspath,kotlinCompilerPluginClasspathMain,kotlinCompilerPluginClasspathTest
org.jetbrains.kotlin:kotlin-scripting-compiler-impl-embeddable:2.2.21=kotlinBuildToolsApiClasspath,kotlinCompilerPluginClasspathMain,kotlinCompilerPluginClasspathTest
org.jetbrains.kotlin:kotlin-scripting-jvm:2.2.21=kotlinBuildToolsApiClasspath,kotlinCompilerPluginClasspathMain,kotlinCompilerPluginClasspathTest
org.jetbrains.kotlin:kotlin-script-runtime:2.2.21=swiftExportClasspathResolvable
org.jetbrains.kotlin:kotlin-script-runtime:2.3.20=kotlinBuildToolsApiClasspath,kotlinCompilerClasspath,kotlinCompilerPluginClasspathMain,kotlinCompilerPluginClasspathTest,kotlinKlibCommonizerClasspath
org.jetbrains.kotlin:kotlin-scripting-common:2.3.20=kotlinCompilerPluginClasspathMain,kotlinCompilerPluginClasspathTest
org.jetbrains.kotlin:kotlin-scripting-compiler-embeddable:2.3.20=kotlinCompilerPluginClasspathMain,kotlinCompilerPluginClasspathTest
org.jetbrains.kotlin:kotlin-scripting-compiler-impl-embeddable:2.3.20=kotlinCompilerPluginClasspathMain,kotlinCompilerPluginClasspathTest
org.jetbrains.kotlin:kotlin-scripting-jvm:2.3.20=kotlinCompilerPluginClasspathMain,kotlinCompilerPluginClasspathTest
org.jetbrains.kotlin:kotlin-stdlib:2.0.0=dependencySources,testDependencySources
org.jetbrains.kotlin:kotlin-stdlib:2.2.21=apiDependenciesMetadata,compileClasspath,implementationDependenciesMetadata,kotlinBuildToolsApiClasspath,kotlinCompilerClasspath,kotlinCompilerPluginClasspathMain,kotlinCompilerPluginClasspathTest,kotlinInternalAbiValidation,kotlinKlibCommonizerClasspath,runtimeClasspath,swiftExportClasspathResolvable,testCompileClasspath,testImplementationDependenciesMetadata,testRuntimeClasspath
org.jetbrains.kotlin:kotlin-stdlib:2.2.21=apiDependenciesMetadata,swiftExportClasspathResolvable
org.jetbrains.kotlin:kotlin-stdlib:2.3.20=compileClasspath,kotlinBuildToolsApiClasspath,kotlinCompilerClasspath,kotlinCompilerPluginClasspathMain,kotlinCompilerPluginClasspathTest,kotlinInternalAbiValidation,kotlinKlibCommonizerClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
org.jetbrains.kotlin:kotlin-tooling-core:2.3.20=kotlinBuildToolsApiClasspath,kotlinCompilerClasspath
org.jetbrains.kotlin:swift-export-embeddable:2.2.21=swiftExportClasspathResolvable
org.jetbrains.kotlinx:kotlinx-coroutines-core-jvm:1.8.0=kotlinBuildToolsApiClasspath,kotlinCompilerClasspath,kotlinInternalAbiValidation,kotlinKlibCommonizerClasspath,swiftExportClasspathResolvable
org.jetbrains.kotlinx:kotlinx-coroutines-core-jvm:1.8.0=kotlinBuildToolsApiClasspath,kotlinCompilerClasspath,kotlinKlibCommonizerClasspath,swiftExportClasspathResolvable
org.jetbrains.kotlinx:kotlinx-serialization-bom:1.7.3=swiftExportClasspathResolvable
org.jetbrains.kotlinx:kotlinx-serialization-core-jvm:1.7.3=swiftExportClasspathResolvable
org.jetbrains.kotlinx:kotlinx-serialization-core:1.7.3=swiftExportClasspathResolvable
org.jetbrains:annotations:13.0=compileClasspath,kotlinBuildToolsApiClasspath,kotlinCompilerClasspath,kotlinCompilerPluginClasspathMain,kotlinCompilerPluginClasspathTest,kotlinInternalAbiValidation,kotlinKlibCommonizerClasspath,runtimeClasspath,swiftExportClasspathResolvable,testCompileClasspath,testRuntimeClasspath
empty=annotationProcessor,intransitiveDependenciesMetadata,kotlinCompilerPluginClasspath,kotlinNativeCompilerPluginClasspath,kotlinScriptDef,kotlinScriptDefExtensions,runtimeOnlyDependenciesMetadata,testAnnotationProcessor,testApiDependenciesMetadata,testCompileOnlyDependenciesMetadata,testIntransitiveDependenciesMetadata,testKotlinScriptDef,testKotlinScriptDefExtensions,testRuntimeOnlyDependenciesMetadata
empty=annotationProcessor,implementationDependenciesMetadata,intransitiveDependenciesMetadata,kotlinCompilerPluginClasspath,kotlinNativeCompilerPluginClasspath,kotlinScriptDef,kotlinScriptDefExtensions,runtimeOnlyDependenciesMetadata,testAnnotationProcessor,testApiDependenciesMetadata,testCompileOnlyDependenciesMetadata,testImplementationDependenciesMetadata,testIntransitiveDependenciesMetadata,testKotlinScriptDef,testKotlinScriptDefExtensions,testRuntimeOnlyDependenciesMetadata
Original file line number Diff line number Diff line change
@@ -0,0 +1,151 @@
/*
* Copyright 2019 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

package androidx.compose.compiler.plugins.kotlin.vk

import org.jetbrains.kotlin.ir.declarations.IrAnnotationContainer
import org.jetbrains.kotlin.ir.expressions.IrConstructorCall
import org.jetbrains.kotlin.ir.symbols.UnsafeDuringIrConstructionAPI
import org.jetbrains.kotlin.ir.types.IrType
import org.jetbrains.kotlin.ir.util.constructedClass
import org.jetbrains.kotlin.ir.util.hasAnnotation
import org.jetbrains.kotlin.ir.util.hasEqualFqName
import org.jetbrains.kotlin.name.CallableId
import org.jetbrains.kotlin.name.ClassId
import org.jetbrains.kotlin.name.FqName
import org.jetbrains.kotlin.name.Name

private const val root = "androidx.compose.runtime"
private const val internalRoot = "$root.internal"
private val rootFqName = FqName(root)
private val internalRootFqName = FqName(internalRoot)
private val toolingFqName = FqName("$root.tooling")

object ComposeClassIds {
private fun classIdFor(cname: String) =
ClassId(rootFqName, Name.identifier(cname))

internal fun internalClassIdFor(cname: String) =
ClassId(internalRootFqName, Name.identifier(cname))

internal fun toolingClassIdFor(cname: String) =
ClassId(toolingFqName, Name.identifier(cname))

val Composable = classIdFor("Composable")
val ComposableInferredTarget = classIdFor("ComposableInferredTarget")
val ComposableLambda = internalClassIdFor("ComposableLambda")
val ComposableOpenTarget = classIdFor("ComposableOpenTarget")
val ComposableTarget = classIdFor("ComposableTarget")
val ComposableTargetMarker = classIdFor("ComposableTargetMarker")
val ComposeVersion = classIdFor("ComposeVersion")
val Composer = classIdFor("Composer")
val DisallowComposableCalls = classIdFor("DisallowComposableCalls")
val FunctionKeyMetaClass = internalClassIdFor("FunctionKeyMetaClass")
val FunctionKeyMeta = internalClassIdFor("FunctionKeyMeta")
val LiveLiteralFileInfo = internalClassIdFor("LiveLiteralFileInfo")
val LiveLiteralInfo = internalClassIdFor("LiveLiteralInfo")
val NoLiveLiterals = classIdFor("NoLiveLiterals")
val ReadOnlyComposable = classIdFor("ReadOnlyComposable")
val State = classIdFor("State")
val StabilityInferred = internalClassIdFor("StabilityInferred")
val SourceInformation = toolingClassIdFor("SourceInformation")
}

object ComposeCallableIds {
private fun topLevelCallableId(name: String) =
CallableId(rootFqName, Name.identifier(name))

internal fun internalTopLevelCallableId(name: String) =
CallableId(internalRootFqName, Name.identifier(name))

val cache = topLevelCallableId("cache")
val key = topLevelCallableId("key")
val composableLambda = internalTopLevelCallableId("composableLambda")
val composableLambdaInstance =
internalTopLevelCallableId("composableLambdaInstance")
val composableLambdaN = internalTopLevelCallableId("composableLambdaN")
val composableLambdaNInstance =
internalTopLevelCallableId("composableLambdaNInstance")
val currentComposer = topLevelCallableId("currentComposer")
val isLiveLiteralsEnabled =
internalTopLevelCallableId("isLiveLiteralsEnabled")
val isTraceInProgress =
topLevelCallableId(ComposeNames.IsTraceInProgress)
val liveLiteral = internalTopLevelCallableId("liveLiteral")
val remember = topLevelCallableId("remember")
val sourceInformation =
topLevelCallableId(ComposeNames.SourceInformation)
val sourceInformationMarkerEnd =
topLevelCallableId(ComposeNames.SourceInformationMarkerEnd)
val sourceInformationMarkerStart =
topLevelCallableId(ComposeNames.SourceInformationMarkerStart)
val traceEventEnd = topLevelCallableId(ComposeNames.TraceEventEnd)
val traceEventStart = topLevelCallableId(ComposeNames.TraceEventStart)
val updateChangedFlags = topLevelCallableId(ComposeNames.UpdateChangedFlags)
val rememberComposableLambda =
internalTopLevelCallableId(ComposeNames.RememberComposableLambda)
val rememberComposableLambdaN =
internalTopLevelCallableId(ComposeNames.RememberComposableLambdaN)
}

object ComposeFqNames {
internal fun fqNameFor(cname: String) = FqName("$root.$cname")
private fun internalFqNameFor(cname: String) = FqName("$internalRoot.$cname")
private fun composablesFqNameFor(cname: String) = fqNameFor("ComposablesKt.$cname")

val InternalPackage = internalRootFqName
val Composable = ComposeClassIds.Composable.asSingleFqName()
val ComposableTarget = ComposeClassIds.ComposableTarget.asSingleFqName()
val ComposableTargetMarker = fqNameFor("ComposableTargetMarker")
val ComposableTargetMarkerDescription = "description"
val ComposableTargetMarkerDescriptionName = Name.identifier(ComposableTargetMarkerDescription)
val ComposableTargetApplierArgument = Name.identifier("applier")
val ComposableOpenTarget = ComposeClassIds.ComposableOpenTarget.asSingleFqName()
val ComposableOpenTargetIndexArgument = Name.identifier("index")
val ComposableInferredTarget = ComposeClassIds.ComposableInferredTarget.asSingleFqName()
val ComposableInferredTargetSchemeArgument = Name.identifier("scheme")
val CurrentComposerIntrinsic = fqNameFor("<get-currentComposer>")
val getCurrentComposerFullName = composablesFqNameFor("<get-currentComposer>")
val DisallowComposableCalls = ComposeClassIds.DisallowComposableCalls.asSingleFqName()
val ReadOnlyComposable = ComposeClassIds.ReadOnlyComposable.asSingleFqName()
val ExplicitGroupsComposable = fqNameFor("ExplicitGroupsComposable")
val NonRestartableComposable = fqNameFor("NonRestartableComposable")
val NonSkippableComposable = fqNameFor("NonSkippableComposable")
val DontMemoize = fqNameFor("DontMemoize")
val composableLambdaType = ComposeClassIds.ComposableLambda.asSingleFqName()
val composableLambda = ComposeCallableIds.composableLambda.asSingleFqName()
val rememberComposableLambda = ComposeCallableIds.rememberComposableLambda.asSingleFqName()
val composableLambdaFullName =
internalFqNameFor("ComposableLambdaKt.composableLambda")
val remember = ComposeCallableIds.remember.asSingleFqName()
val cache = ComposeCallableIds.cache.asSingleFqName()
val key = ComposeCallableIds.key.asSingleFqName()
val StableMarker = fqNameFor("StableMarker")
val Stable = fqNameFor("Stable")
val Immutable = fqNameFor("Immutable")
val Composer = ComposeClassIds.Composer.asSingleFqName()
val StabilityInferred = ComposeClassIds.StabilityInferred.asSingleFqName()
}

fun IrType.hasComposableAnnotation(): Boolean =
hasAnnotation(ComposeFqNames.Composable)

fun IrAnnotationContainer.hasComposableAnnotation(): Boolean =
hasAnnotation(ComposeFqNames.Composable)

@UnsafeDuringIrConstructionAPI
fun IrConstructorCall.isComposableAnnotation() =
symbol.owner.constructedClass.hasEqualFqName(ComposeFqNames.Composable)
Loading
Loading