From fb16d627d81fed993a7afb2ce201dfae3368b307 Mon Sep 17 00:00:00 2001 From: James Barr Date: Tue, 4 Oct 2022 00:07:32 -0700 Subject: [PATCH 01/56] Prepare for release 0.4.0-alpha01 --- gradle.properties | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gradle.properties b/gradle.properties index 5cfb5e00..813b53c1 100644 --- a/gradle.properties +++ b/gradle.properties @@ -14,7 +14,7 @@ # limitations under the License. # GROUP=com.uber.motif -VERSION_NAME=0.3.9-SNAPSHOT +VERSION_NAME=0.4.0-alpha01 POM_DESCRIPTION=Simple DI API for Android / Java. POM_URL=https://github.com/uber/motif/ POM_SCM_URL=https://github.com/uber/motif/ From 83d39bfbee1fab6b4565f47ac4d1ff4f3ad2cb24 Mon Sep 17 00:00:00 2001 From: James Barr Date: Tue, 11 Oct 2022 16:30:01 -0700 Subject: [PATCH 02/56] Prepare next development version --- gradle.properties | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/gradle.properties b/gradle.properties index 813b53c1..6f946dc5 100644 --- a/gradle.properties +++ b/gradle.properties @@ -14,7 +14,7 @@ # limitations under the License. # GROUP=com.uber.motif -VERSION_NAME=0.4.0-alpha01 +VERSION_NAME=0.4.0-alpha02-SNAPSHOT POM_DESCRIPTION=Simple DI API for Android / Java. POM_URL=https://github.com/uber/motif/ POM_SCM_URL=https://github.com/uber/motif/ @@ -33,4 +33,4 @@ android.useAndroidX=true android.enableJetifier=true # https://github.com/Kotlin/dokka/issues/1405 -org.gradle.jvmargs=-XX:MaxMetaspaceSize=1g \ No newline at end of file +org.gradle.jvmargs=-XX:MaxMetaspaceSize=1g From cace4bd61497076d5a1921284b3478c1fc933307 Mon Sep 17 00:00:00 2001 From: James Barr Date: Tue, 11 Oct 2022 16:31:06 -0700 Subject: [PATCH 03/56] Add Java KSP sample lib --- build.gradle | 2 + samples/sample-kotlin-ksp/build.gradle | 5 +-- samples/sample-lib-ksp/build.gradle | 39 +++++++++++++++++++ .../src/main/AndroidManifest.xml | 2 + .../com/example/sample_lib_ksp/Greeter.java | 13 +++++++ .../com/example/sample_lib_ksp/JavaScope.java | 26 +++++++++++++ settings.gradle | 1 + 7 files changed, 84 insertions(+), 4 deletions(-) create mode 100644 samples/sample-lib-ksp/build.gradle create mode 100644 samples/sample-lib-ksp/src/main/AndroidManifest.xml create mode 100644 samples/sample-lib-ksp/src/main/java/com/example/sample_lib_ksp/Greeter.java create mode 100644 samples/sample-lib-ksp/src/main/java/com/example/sample_lib_ksp/JavaScope.java diff --git a/build.gradle b/build.gradle index 955d67ff..ce0bc58b 100644 --- a/build.gradle +++ b/build.gradle @@ -39,6 +39,8 @@ subprojects { useTarget(deps.autoCommon) } else if (requested.group == "org.jetbrains.kotlinx" && requested.name == "kotlinx-metadata") { useTarget(deps.kotlinxMetadata) + } else if (requested.group == "com.google.devtools.ksp") { + useVersion(deps.versions.ksp) } } } diff --git a/samples/sample-kotlin-ksp/build.gradle b/samples/sample-kotlin-ksp/build.gradle index 8740fd20..fd8cdecf 100644 --- a/samples/sample-kotlin-ksp/build.gradle +++ b/samples/sample-kotlin-ksp/build.gradle @@ -1,8 +1,8 @@ plugins { id 'com.google.devtools.ksp' id 'com.android.application' + id 'org.jetbrains.kotlin.android' } -apply plugin: 'kotlin-android' android { compileSdkVersion deps.build.compileSdkVersion @@ -43,6 +43,3 @@ dependencies { implementation project(':lib') implementation deps.kotlin.stdlib } -repositories { - mavenCentral() -} diff --git a/samples/sample-lib-ksp/build.gradle b/samples/sample-lib-ksp/build.gradle new file mode 100644 index 00000000..7ddadf73 --- /dev/null +++ b/samples/sample-lib-ksp/build.gradle @@ -0,0 +1,39 @@ +plugins { + id 'com.google.devtools.ksp' + id 'com.android.library' + id 'org.jetbrains.kotlin.android' +} + +android { + namespace 'com.example.sample_lib_ksp' + compileSdkVersion deps.build.compileSdkVersion + + defaultConfig { + minSdkVersion deps.build.minSdkVersion + targetSdkVersion deps.build.targetSdkVersion + } + + // No need for lint. This is just a tutorial. + lintOptions { + abortOnError false + quiet true + } + + sourceSets { + libraryVariants.all { variant -> + main.java.srcDirs += ["build/generated/ksp/${variant.name}/kotlin"] + } + } + + compileOptions { + sourceCompatibility JavaVersion.VERSION_1_8 + targetCompatibility JavaVersion.VERSION_1_8 + } +} + +dependencies { + ksp project(':compiler-ksp') + + implementation project(':lib') + implementation deps.kotlin.stdlib +} diff --git a/samples/sample-lib-ksp/src/main/AndroidManifest.xml b/samples/sample-lib-ksp/src/main/AndroidManifest.xml new file mode 100644 index 00000000..1d26c87a --- /dev/null +++ b/samples/sample-lib-ksp/src/main/AndroidManifest.xml @@ -0,0 +1,2 @@ + + \ No newline at end of file diff --git a/samples/sample-lib-ksp/src/main/java/com/example/sample_lib_ksp/Greeter.java b/samples/sample-lib-ksp/src/main/java/com/example/sample_lib_ksp/Greeter.java new file mode 100644 index 00000000..0b4cd70d --- /dev/null +++ b/samples/sample-lib-ksp/src/main/java/com/example/sample_lib_ksp/Greeter.java @@ -0,0 +1,13 @@ +package com.example.sample_lib_ksp; + +class Greeter { + private final String name; + + public Greeter(String name) { + this.name = name; + } + + String greet() { + return "Hello " + name + "!"; + } +} diff --git a/samples/sample-lib-ksp/src/main/java/com/example/sample_lib_ksp/JavaScope.java b/samples/sample-lib-ksp/src/main/java/com/example/sample_lib_ksp/JavaScope.java new file mode 100644 index 00000000..f7c99744 --- /dev/null +++ b/samples/sample-lib-ksp/src/main/java/com/example/sample_lib_ksp/JavaScope.java @@ -0,0 +1,26 @@ +package com.example.sample_lib_ksp; + +import javax.inject.Named; + +import motif.Scope; + +@Scope +public interface JavaScope { + String greeter(); + + @motif.Objects + class Objects { + + @Named("name") + String name() { + return "World"; + } + + Greeter greeter(@Named("name") String name) { + return new Greeter(name); + } + } + + interface Dependencies { + } +} diff --git a/settings.gradle b/settings.gradle index 609e3b29..ee6526e1 100644 --- a/settings.gradle +++ b/settings.gradle @@ -54,3 +54,4 @@ include 'xprocessing-testing' project(':compiler-ast').projectDir = file('compiler/ast') project(':compiler-ksp').projectDir = file('compiler/ksp') project(':intellij-ast').projectDir = file('intellij/ast') +include ':samples:sample-lib-ksp' From a453155569962065c3e5fadfbd998567ff744682 Mon Sep 17 00:00:00 2001 From: James Barr Date: Tue, 11 Oct 2022 17:44:03 -0700 Subject: [PATCH 04/56] Run spotless --- .../com/example/sample_lib_ksp/Greeter.java | 15 +++++++++++++++ .../com/example/sample_lib_ksp/JavaScope.java | 19 ++++++++++++++++--- 2 files changed, 31 insertions(+), 3 deletions(-) diff --git a/samples/sample-lib-ksp/src/main/java/com/example/sample_lib_ksp/Greeter.java b/samples/sample-lib-ksp/src/main/java/com/example/sample_lib_ksp/Greeter.java index 0b4cd70d..f6272834 100644 --- a/samples/sample-lib-ksp/src/main/java/com/example/sample_lib_ksp/Greeter.java +++ b/samples/sample-lib-ksp/src/main/java/com/example/sample_lib_ksp/Greeter.java @@ -1,3 +1,18 @@ +/* + * Copyright (c) 2022 Uber Technologies, Inc. + * + * 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 com.example.sample_lib_ksp; class Greeter { diff --git a/samples/sample-lib-ksp/src/main/java/com/example/sample_lib_ksp/JavaScope.java b/samples/sample-lib-ksp/src/main/java/com/example/sample_lib_ksp/JavaScope.java index f7c99744..4031e0ff 100644 --- a/samples/sample-lib-ksp/src/main/java/com/example/sample_lib_ksp/JavaScope.java +++ b/samples/sample-lib-ksp/src/main/java/com/example/sample_lib_ksp/JavaScope.java @@ -1,7 +1,21 @@ +/* + * Copyright (c) 2022 Uber Technologies, Inc. + * + * 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 com.example.sample_lib_ksp; import javax.inject.Named; - import motif.Scope; @Scope @@ -21,6 +35,5 @@ Greeter greeter(@Named("name") String name) { } } - interface Dependencies { - } + interface Dependencies {} } From 1a2e7afab5ba6a6f6a81ee4cbf4d7ad7c76f0df6 Mon Sep 17 00:00:00 2001 From: James Barr Date: Tue, 11 Oct 2022 19:33:39 -0700 Subject: [PATCH 05/56] Exclude failing sample project --- .github/workflows/ci.yml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index d8326214..459ed25f 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -24,11 +24,11 @@ jobs: # Gradle configuration install deps run: ./gradlew help - name: Build Project - run: ./gradlew spotlessCheck build --stacktrace + run: ./gradlew spotlessCheck build --stacktrace -x :samples:sample-lib-ksp:build - name : Testing - run: ./gradlew test --stacktrace + run: ./gradlew test --stacktrace -x :samples:sample-lib-ksp:test - name: Final Checks - run: ./gradlew check --stacktrace + run: ./gradlew check --stacktrace -x :samples:sample-lib-ksp:check - name: Upload Snapshot run: ./gradlew publish --no-daemon --no-parallel -PmavenCentralUsername="${{ secrets.SonatypeUsername }}" -PmavenCentralPassword="${{ secrets.SonatypePassword }}" if: success() && github.ref == 'refs/heads/master' && github.event_name != 'pull_request' && matrix.java_version == '11' From 4dec441539417e9fdd191c3ccb29eb9414492153 Mon Sep 17 00:00:00 2001 From: James Barr Date: Mon, 14 Nov 2022 11:58:59 -0800 Subject: [PATCH 06/56] Update to Kotlin 1.7.20 & KSP 1.0.8 --- gradle/dependencies.gradle | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/gradle/dependencies.gradle b/gradle/dependencies.gradle index a17e3851..9d350b4a 100644 --- a/gradle/dependencies.gradle +++ b/gradle/dependencies.gradle @@ -15,8 +15,8 @@ */ def versions = [ - kotlin: '1.7.10', - ksp: '1.7.10-1.0.6', + kotlin: '1.7.20', + ksp: '1.7.20-1.0.8', ktlint: '0.41.0', ktfmt: '0.23', dagger: '2.24', From 71565991d562871d710ba3477b66ef2f6341ae94 Mon Sep 17 00:00:00 2001 From: James Barr Date: Fri, 18 Nov 2022 19:06:26 -0800 Subject: [PATCH 07/56] Fix KSP sample lib --- .github/workflows/ci.yml | 6 +++--- samples/sample-lib-ksp/build.gradle | 6 ++++++ 2 files changed, 9 insertions(+), 3 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 459ed25f..d8326214 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -24,11 +24,11 @@ jobs: # Gradle configuration install deps run: ./gradlew help - name: Build Project - run: ./gradlew spotlessCheck build --stacktrace -x :samples:sample-lib-ksp:build + run: ./gradlew spotlessCheck build --stacktrace - name : Testing - run: ./gradlew test --stacktrace -x :samples:sample-lib-ksp:test + run: ./gradlew test --stacktrace - name: Final Checks - run: ./gradlew check --stacktrace -x :samples:sample-lib-ksp:check + run: ./gradlew check --stacktrace - name: Upload Snapshot run: ./gradlew publish --no-daemon --no-parallel -PmavenCentralUsername="${{ secrets.SonatypeUsername }}" -PmavenCentralPassword="${{ secrets.SonatypePassword }}" if: success() && github.ref == 'refs/heads/master' && github.event_name != 'pull_request' && matrix.java_version == '11' diff --git a/samples/sample-lib-ksp/build.gradle b/samples/sample-lib-ksp/build.gradle index 7ddadf73..8d5b1cb9 100644 --- a/samples/sample-lib-ksp/build.gradle +++ b/samples/sample-lib-ksp/build.gradle @@ -29,6 +29,12 @@ android { sourceCompatibility JavaVersion.VERSION_1_8 targetCompatibility JavaVersion.VERSION_1_8 } + + androidComponents { + beforeVariants(selector().withBuildType("debug")) { variantBuilder -> + variantBuilder.enabled = false + } + } } dependencies { From b0f116b890db9dcea81f185002e5adac4a62f9ac Mon Sep 17 00:00:00 2001 From: James Barr Date: Tue, 29 Nov 2022 10:56:55 -0800 Subject: [PATCH 08/56] Remove error rethrower --- .../google/devtools/ksp/KspErrorThrower.kt | 22 ---------- .../motif/compiler/ksp/MessageWatcher.kt | 43 ------------------- .../ksp/MotifSymbolProcessorProvider.kt | 3 +- 3 files changed, 1 insertion(+), 67 deletions(-) delete mode 100644 compiler/ksp/src/main/kotlin/com/google/devtools/ksp/KspErrorThrower.kt delete mode 100644 compiler/ksp/src/main/kotlin/motif/compiler/ksp/MessageWatcher.kt diff --git a/compiler/ksp/src/main/kotlin/com/google/devtools/ksp/KspErrorThrower.kt b/compiler/ksp/src/main/kotlin/com/google/devtools/ksp/KspErrorThrower.kt deleted file mode 100644 index f48e735a..00000000 --- a/compiler/ksp/src/main/kotlin/com/google/devtools/ksp/KspErrorThrower.kt +++ /dev/null @@ -1,22 +0,0 @@ -/* - * Copyright (c) 2022 Uber Technologies, Inc. - * - * 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 com.google.devtools.ksp - -internal object KspErrorThrower { - internal fun rethrowKspError(msg: String) { - throw IllegalStateException(msg) - } -} diff --git a/compiler/ksp/src/main/kotlin/motif/compiler/ksp/MessageWatcher.kt b/compiler/ksp/src/main/kotlin/motif/compiler/ksp/MessageWatcher.kt deleted file mode 100644 index 7e05dd80..00000000 --- a/compiler/ksp/src/main/kotlin/motif/compiler/ksp/MessageWatcher.kt +++ /dev/null @@ -1,43 +0,0 @@ -/* - * Copyright (c) 2022 Uber Technologies, Inc. - * - * 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 motif.compiler.ksp - -import androidx.room.compiler.processing.XAnnotation -import androidx.room.compiler.processing.XAnnotationValue -import androidx.room.compiler.processing.XElement -import androidx.room.compiler.processing.XMessager -import com.google.devtools.ksp.KspErrorThrower -import javax.tools.Diagnostic - -/** - * A message watcher that re-throws exceptions from the KSP devtools package to work around an issue - * where exceptions are swallowed. - * - * https://github.com/google/ksp/issues/974 - */ -internal class MessageWatcher : XMessager() { - override fun onPrintMessage( - kind: Diagnostic.Kind, - msg: String, - element: XElement?, - annotation: XAnnotation?, - annotationValue: XAnnotationValue? - ) { - if (kind == Diagnostic.Kind.ERROR) { - KspErrorThrower.rethrowKspError("\n$msg") - } - } -} diff --git a/compiler/ksp/src/main/kotlin/motif/compiler/ksp/MotifSymbolProcessorProvider.kt b/compiler/ksp/src/main/kotlin/motif/compiler/ksp/MotifSymbolProcessorProvider.kt index bae006a2..2aae4b7a 100644 --- a/compiler/ksp/src/main/kotlin/motif/compiler/ksp/MotifSymbolProcessorProvider.kt +++ b/compiler/ksp/src/main/kotlin/motif/compiler/ksp/MotifSymbolProcessorProvider.kt @@ -41,7 +41,6 @@ class MotifSymbolProcessorProvider( config: XProcessingEnvConfig ) : KspBasicAnnotationProcessor(environment, config) { - override fun processingSteps() = - listOf(MotifProcessingStep(graphSetter = { graph = it }, messageWatcher = MessageWatcher())) + override fun processingSteps() = listOf(MotifProcessingStep(graphSetter = { graph = it })) } } From e22bf2d1ddeea38a06f36f75ea7c972a1f592d41 Mon Sep 17 00:00:00 2001 From: James Barr Date: Tue, 31 Jan 2023 15:16:46 -0800 Subject: [PATCH 09/56] XProcessing to v2.5.0 & KotlinPoet to v1.12.0 --- gradle/dependencies.gradle | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/gradle/dependencies.gradle b/gradle/dependencies.gradle index 9d350b4a..36aa2989 100644 --- a/gradle/dependencies.gradle +++ b/gradle/dependencies.gradle @@ -23,9 +23,9 @@ def versions = [ butterknife: '10.1.0', glide: '4.9.0', gjf: '1.7', - kotlinpoet: '1.10.2', + kotlinpoet: '1.12.0', room: '2.1.0', - roomCompilerProcessing: '2.5.0-alpha03', + roomCompilerProcessing: '2.5.0', dokka: '1.4.32', "gradleIntellijPlugin": [ ide: '2020.1' From 87a712400fc5852a64920677c32c768ba47a6c51 Mon Sep 17 00:00:00 2001 From: James Barr Date: Tue, 31 Jan 2023 22:53:04 -0800 Subject: [PATCH 10/56] Revert "XProcessing to v2.5.0 & KotlinPoet to v1.12.0" This reverts commit e22bf2d1ddeea38a06f36f75ea7c972a1f592d41. --- gradle/dependencies.gradle | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/gradle/dependencies.gradle b/gradle/dependencies.gradle index 36aa2989..9d350b4a 100644 --- a/gradle/dependencies.gradle +++ b/gradle/dependencies.gradle @@ -23,9 +23,9 @@ def versions = [ butterknife: '10.1.0', glide: '4.9.0', gjf: '1.7', - kotlinpoet: '1.12.0', + kotlinpoet: '1.10.2', room: '2.1.0', - roomCompilerProcessing: '2.5.0', + roomCompilerProcessing: '2.5.0-alpha03', dokka: '1.4.32', "gradleIntellijPlugin": [ ide: '2020.1' From 03ab638af1246266d4b83db00b6d7b358161f971 Mon Sep 17 00:00:00 2001 From: James Barr Date: Wed, 1 Feb 2023 11:12:38 -0800 Subject: [PATCH 11/56] Bump KotlinPoet & JavaPoet --- compiler/src/main/kotlin/motif/compiler/ScopeImpl.kt | 11 +++++++++++ gradle/dependencies.gradle | 4 ++-- 2 files changed, 13 insertions(+), 2 deletions(-) diff --git a/compiler/src/main/kotlin/motif/compiler/ScopeImpl.kt b/compiler/src/main/kotlin/motif/compiler/ScopeImpl.kt index 854ee459..a09e9142 100644 --- a/compiler/src/main/kotlin/motif/compiler/ScopeImpl.kt +++ b/compiler/src/main/kotlin/motif/compiler/ScopeImpl.kt @@ -18,6 +18,7 @@ package motif.compiler import androidx.room.compiler.processing.XProcessingEnv import androidx.room.compiler.processing.XType import androidx.room.compiler.processing.compat.XConverters.getProcessingEnv +import androidx.room.compiler.processing.compat.XConverters.toJavac import androidx.room.compiler.processing.compat.XConverters.toKS import com.squareup.javapoet.ParameterizedTypeName import com.squareup.javapoet.WildcardTypeName @@ -424,6 +425,16 @@ class TypeName private constructor(private val mirror: XType) { .typeArguments .map { WildcardTypeName.subtypeOf(Object::class.java) } .toTypedArray()) + } else if (mirror.typeArguments.isNotEmpty() && + "<" in jTypeName.toString() && + "$" in jTypeName.toString()) { + // Work around issue where JavaPoet returns a TypeName with a '$' for a Kotlin inner class + ParameterizedTypeName.get( + com.squareup.javapoet.ClassName.get(mirror.typeElement?.toJavac()), + *mirror + .typeArguments + .map { it.typeName } + .toTypedArray()) } else { jTypeName } diff --git a/gradle/dependencies.gradle b/gradle/dependencies.gradle index 9d350b4a..41495596 100644 --- a/gradle/dependencies.gradle +++ b/gradle/dependencies.gradle @@ -23,7 +23,7 @@ def versions = [ butterknife: '10.1.0', glide: '4.9.0', gjf: '1.7', - kotlinpoet: '1.10.2', + kotlinpoet: '1.12.0', room: '2.1.0', roomCompilerProcessing: '2.5.0-alpha03', dokka: '1.4.32', @@ -79,7 +79,7 @@ ext.deps = [ ], dagger: "com.google.dagger:dagger:${versions.dagger}", daggerCompiler: "com.google.dagger:dagger-compiler:${versions.dagger}", - javapoet: 'com.squareup:javapoet:1.11.1', + javapoet: 'com.squareup:javapoet:1.13.0', kotlinpoet: "com.squareup:kotlinpoet:${versions.kotlinpoet}", kotlinpoetInteropMetadata: "com.squareup:kotlinpoet-metadata:${versions.kotlinpoet}", kotlinxMetadata : 'org.jetbrains.kotlinx:kotlinx-metadata-jvm:0.5.0', From 51737d9cf743301ff0ace1b09c52741ca92aa4a4 Mon Sep 17 00:00:00 2001 From: James Barr Date: Wed, 1 Feb 2023 12:08:35 -0800 Subject: [PATCH 12/56] Run spotless --- compiler/src/main/kotlin/motif/compiler/ScopeImpl.kt | 11 ++++------- 1 file changed, 4 insertions(+), 7 deletions(-) diff --git a/compiler/src/main/kotlin/motif/compiler/ScopeImpl.kt b/compiler/src/main/kotlin/motif/compiler/ScopeImpl.kt index a09e9142..855a5ca5 100644 --- a/compiler/src/main/kotlin/motif/compiler/ScopeImpl.kt +++ b/compiler/src/main/kotlin/motif/compiler/ScopeImpl.kt @@ -428,13 +428,10 @@ class TypeName private constructor(private val mirror: XType) { } else if (mirror.typeArguments.isNotEmpty() && "<" in jTypeName.toString() && "$" in jTypeName.toString()) { - // Work around issue where JavaPoet returns a TypeName with a '$' for a Kotlin inner class - ParameterizedTypeName.get( - com.squareup.javapoet.ClassName.get(mirror.typeElement?.toJavac()), - *mirror - .typeArguments - .map { it.typeName } - .toTypedArray()) + // Work around issue where JavaPoet returns a TypeName with a '$' for a Kotlin inner class + ParameterizedTypeName.get( + com.squareup.javapoet.ClassName.get(mirror.typeElement?.toJavac()), + *mirror.typeArguments.map { it.typeName }.toTypedArray()) } else { jTypeName } From bd9f8988801a65df78ede5e3f6e23bff8ad1a18b Mon Sep 17 00:00:00 2001 From: James Barr Date: Wed, 1 Feb 2023 15:24:26 -0800 Subject: [PATCH 13/56] Prepare for release 0.4.0-alpha02 --- gradle.properties | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gradle.properties b/gradle.properties index 6f946dc5..7419d2cb 100644 --- a/gradle.properties +++ b/gradle.properties @@ -14,7 +14,7 @@ # limitations under the License. # GROUP=com.uber.motif -VERSION_NAME=0.4.0-alpha02-SNAPSHOT +VERSION_NAME=0.4.0-alpha02 POM_DESCRIPTION=Simple DI API for Android / Java. POM_URL=https://github.com/uber/motif/ POM_SCM_URL=https://github.com/uber/motif/ From 7afe009375f584d2641da7f372ff40fe381da9d2 Mon Sep 17 00:00:00 2001 From: James Barr Date: Wed, 1 Feb 2023 15:30:42 -0800 Subject: [PATCH 14/56] Prepare next development version --- gradle.properties | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gradle.properties b/gradle.properties index 7419d2cb..06084deb 100644 --- a/gradle.properties +++ b/gradle.properties @@ -14,7 +14,7 @@ # limitations under the License. # GROUP=com.uber.motif -VERSION_NAME=0.4.0-alpha02 +VERSION_NAME=0.4.0-alpha03-SNAPSHOT POM_DESCRIPTION=Simple DI API for Android / Java. POM_URL=https://github.com/uber/motif/ POM_SCM_URL=https://github.com/uber/motif/ From 3c4115249c7af317dba78df55276d188ddae79e1 Mon Sep 17 00:00:00 2001 From: James Barr Date: Thu, 20 Jul 2023 21:00:37 -0700 Subject: [PATCH 15/56] Bump XProcessing, Kotlin, & kotlinx-metadata-jvm --- gradle/dependencies.gradle | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/gradle/dependencies.gradle b/gradle/dependencies.gradle index 41495596..2f8661c6 100644 --- a/gradle/dependencies.gradle +++ b/gradle/dependencies.gradle @@ -15,8 +15,8 @@ */ def versions = [ - kotlin: '1.7.20', - ksp: '1.7.20-1.0.8', + kotlin: '1.8.20', + ksp: '1.8.20-1.0.11', ktlint: '0.41.0', ktfmt: '0.23', dagger: '2.24', @@ -25,7 +25,7 @@ def versions = [ gjf: '1.7', kotlinpoet: '1.12.0', room: '2.1.0', - roomCompilerProcessing: '2.5.0-alpha03', + roomCompilerProcessing: '2.6.0-alpha02', dokka: '1.4.32', "gradleIntellijPlugin": [ ide: '2020.1' @@ -38,7 +38,7 @@ ext.deps = [ buildToolsVersion: '30.0.3', compileSdkVersion: 31, ci: 'true' == System.getenv('CI'), - minSdkVersion: 14, + minSdkVersion: 21, targetSdkVersion: 30, gradlePlugins: [ @@ -82,7 +82,7 @@ ext.deps = [ javapoet: 'com.squareup:javapoet:1.13.0', kotlinpoet: "com.squareup:kotlinpoet:${versions.kotlinpoet}", kotlinpoetInteropMetadata: "com.squareup:kotlinpoet-metadata:${versions.kotlinpoet}", - kotlinxMetadata : 'org.jetbrains.kotlinx:kotlinx-metadata-jvm:0.5.0', + kotlinxMetadata : 'org.jetbrains.kotlinx:kotlinx-metadata-jvm:0.6.2', autoCommon: 'com.google.auto:auto-common:1.1.2', autoService: "com.google.auto.service:auto-service:1.0", commonsCodec: 'commons-codec:commons-codec:1.13', From 00c141bfc740a6f4f29383f825186d9d37fe75b1 Mon Sep 17 00:00:00 2001 From: James Barr Date: Thu, 20 Jul 2023 21:01:32 -0700 Subject: [PATCH 16/56] Prepare for release 0.4.0-alpha03 --- CHANGELOG.md | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index cc13e777..cda00ea1 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,12 @@ +# 0.4.0-alpha03 +* Update XProcessing version + +# 0.4.0-alpha02 +* Upgrade JavaPoet, KotlinPoet, & XProcessing + +# 0.4.0-alpha01 +* Initial support for KSP + # 0.3.8 * Throw CannotResolveType error when compiler cannot resolve it. From 8e4e5f087c81605532fb49e0b937b3db21e04643 Mon Sep 17 00:00:00 2001 From: James Barr Date: Thu, 20 Jul 2023 21:06:48 -0700 Subject: [PATCH 17/56] Prepare next development version --- gradle.properties | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gradle.properties b/gradle.properties index 06084deb..35b32224 100644 --- a/gradle.properties +++ b/gradle.properties @@ -14,7 +14,7 @@ # limitations under the License. # GROUP=com.uber.motif -VERSION_NAME=0.4.0-alpha03-SNAPSHOT +VERSION_NAME=0.4.0-alpha04-SNAPSHOT POM_DESCRIPTION=Simple DI API for Android / Java. POM_URL=https://github.com/uber/motif/ POM_SCM_URL=https://github.com/uber/motif/ From 31049d79a1c6c40a45e6012d14037b5f4602c201 Mon Sep 17 00:00:00 2001 From: James Barr Date: Fri, 21 Jul 2023 01:31:53 -0700 Subject: [PATCH 18/56] Prepare for release 0.4.0-alpha04 --- gradle.properties | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gradle.properties b/gradle.properties index 35b32224..e1d34e75 100644 --- a/gradle.properties +++ b/gradle.properties @@ -14,7 +14,7 @@ # limitations under the License. # GROUP=com.uber.motif -VERSION_NAME=0.4.0-alpha04-SNAPSHOT +VERSION_NAME=0.4.0-alpha04 POM_DESCRIPTION=Simple DI API for Android / Java. POM_URL=https://github.com/uber/motif/ POM_SCM_URL=https://github.com/uber/motif/ From 7c88008c6b2bb3a7ea4b75d77484c4fd6e76e0dd Mon Sep 17 00:00:00 2001 From: James Barr Date: Sun, 23 Jul 2023 21:38:46 -0700 Subject: [PATCH 19/56] Fix Room version for sample --- build.gradle | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/build.gradle b/build.gradle index ce0bc58b..a0ec1818 100644 --- a/build.gradle +++ b/build.gradle @@ -41,6 +41,10 @@ subprojects { useTarget(deps.kotlinxMetadata) } else if (requested.group == "com.google.devtools.ksp") { useVersion(deps.versions.ksp) + } else if (requested.group == "androidx.room") { + if (requested.name != "room-compiler-processing" && requested.name != "room-compiler-processing-testing") { + useVersion(deps.versions.room) + } } } } From 60e9476c2551092600437b27d64268925bb92bae Mon Sep 17 00:00:00 2001 From: James Barr Date: Sun, 23 Jul 2023 21:39:06 -0700 Subject: [PATCH 20/56] Update Dagger version --- gradle/dependencies.gradle | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gradle/dependencies.gradle b/gradle/dependencies.gradle index 2f8661c6..3ce9b033 100644 --- a/gradle/dependencies.gradle +++ b/gradle/dependencies.gradle @@ -19,7 +19,7 @@ def versions = [ ksp: '1.8.20-1.0.11', ktlint: '0.41.0', ktfmt: '0.23', - dagger: '2.24', + dagger: '2.47', butterknife: '10.1.0', glide: '4.9.0', gjf: '1.7', From c2ea4d2358df0aa5ea1670d704fca1411b79b18c Mon Sep 17 00:00:00 2001 From: James Barr Date: Sun, 23 Jul 2023 21:59:30 -0700 Subject: [PATCH 21/56] Update CHANGELOG --- CHANGELOG.md | 3 +++ 1 file changed, 3 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index cda00ea1..1ae3123d 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,6 @@ +# 0.4.0-alpha04 +* Update Dagger version + # 0.4.0-alpha03 * Update XProcessing version From f3de1ab440df38fa7ac4b6aeb43cf77d20d2c933 Mon Sep 17 00:00:00 2001 From: James Barr Date: Tue, 19 Sep 2023 18:58:10 -0400 Subject: [PATCH 22/56] Set JVM version to 1.8 --- lib/build.gradle | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/lib/build.gradle b/lib/build.gradle index d8569938..016a1b67 100644 --- a/lib/build.gradle +++ b/lib/build.gradle @@ -1,7 +1,7 @@ apply plugin: 'java-library' -sourceCompatibility = 1.7 -targetCompatibility = 1.7 +sourceCompatibility = 1.8 +targetCompatibility = 1.8 dependencies { // Dagger is part of the API since we generate code which depends on Dagger's API in the consuming gradle module. From 4c9b1af5459dbc288a42de5830d1064f5d881d09 Mon Sep 17 00:00:00 2001 From: James Barr Date: Wed, 20 Sep 2023 10:49:13 -0400 Subject: [PATCH 23/56] Prepare for release 0.4.0-alpha05 --- CHANGELOG.md | 3 +++ gradle.properties | 2 +- 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 1ae3123d..fbb8c3c5 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,6 @@ +# 0.4.0-alpha05 +* Set JvmVersion to 1.8 + # 0.4.0-alpha04 * Update Dagger version diff --git a/gradle.properties b/gradle.properties index e1d34e75..bb0bc47d 100644 --- a/gradle.properties +++ b/gradle.properties @@ -14,7 +14,7 @@ # limitations under the License. # GROUP=com.uber.motif -VERSION_NAME=0.4.0-alpha04 +VERSION_NAME=0.4.0-alpha05 POM_DESCRIPTION=Simple DI API for Android / Java. POM_URL=https://github.com/uber/motif/ POM_SCM_URL=https://github.com/uber/motif/ From 184f671170a8de438d3c1db8feead10b64d3a8d5 Mon Sep 17 00:00:00 2001 From: James Barr Date: Wed, 20 Sep 2023 10:55:02 -0400 Subject: [PATCH 24/56] Prepare next development version --- gradle.properties | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gradle.properties b/gradle.properties index bb0bc47d..e418fcc8 100644 --- a/gradle.properties +++ b/gradle.properties @@ -14,7 +14,7 @@ # limitations under the License. # GROUP=com.uber.motif -VERSION_NAME=0.4.0-alpha05 +VERSION_NAME=0.4.0-alpha06-SNAPSHOT POM_DESCRIPTION=Simple DI API for Android / Java. POM_URL=https://github.com/uber/motif/ POM_SCM_URL=https://github.com/uber/motif/ From 97f1bf7c9415e27bc843cc976902ca1c18c0bed9 Mon Sep 17 00:00:00 2001 From: daviss Date: Thu, 5 Oct 2023 10:26:10 -0700 Subject: [PATCH 25/56] support intellij 2023.2 (232) targets 2023.2 and make the associated gradle version, plugin, java version change. note that things are very broken at this commit - we will need to fix tests and other stuff in the coming commits --- gradle/dependencies.gradle | 2 +- gradle/wrapper/gradle-wrapper.properties | 2 +- intellij/ast/build.gradle | 20 +++++++------------ intellij/build.gradle | 8 +++++++- .../src/main/resources/META-INF/plugin.xml | 6 +++--- tests/build.gradle | 1 - 6 files changed, 19 insertions(+), 20 deletions(-) diff --git a/gradle/dependencies.gradle b/gradle/dependencies.gradle index 3ce9b033..c2b0f3ce 100644 --- a/gradle/dependencies.gradle +++ b/gradle/dependencies.gradle @@ -28,7 +28,7 @@ def versions = [ roomCompilerProcessing: '2.6.0-alpha02', dokka: '1.4.32', "gradleIntellijPlugin": [ - ide: '2020.1' + ide: '2023.2' ], ] diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties index 7665b0fa..070cb702 100644 --- a/gradle/wrapper/gradle-wrapper.properties +++ b/gradle/wrapper/gradle-wrapper.properties @@ -1,5 +1,5 @@ distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-6.9-all.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-7.6-bin.zip zipStoreBase=GRADLE_USER_HOME zipStorePath=wrapper/dists diff --git a/intellij/ast/build.gradle b/intellij/ast/build.gradle index 1d840a3a..348011d7 100644 --- a/intellij/ast/build.gradle +++ b/intellij/ast/build.gradle @@ -1,5 +1,5 @@ plugins { - id "org.jetbrains.intellij" version "1.0" + id "org.jetbrains.intellij" version "1.15.0" id 'org.jetbrains.kotlin.jvm' id 'org.jetbrains.dokka' } @@ -11,6 +11,12 @@ intellij { updateSinceUntilBuild = false } +java { + toolchain { + languageVersion.set(JavaLanguageVersion.of(17)) + } +} + dependencies { implementation project(':lib') implementation project(':ast') @@ -24,18 +30,6 @@ dependencies { testImplementation project(':intellij:testing') } -compileKotlin { - kotlinOptions { - jvmTarget = "1.8" - } -} - -compileTestKotlin { - kotlinOptions { - jvmTarget = "1.8" - } -} - tasks { buildSearchableOptions { enabled = false diff --git a/intellij/build.gradle b/intellij/build.gradle index 89f998d5..34be84e9 100644 --- a/intellij/build.gradle +++ b/intellij/build.gradle @@ -1,5 +1,5 @@ plugins { - id "org.jetbrains.intellij" version "1.0" + id "org.jetbrains.intellij" version "1.15.0" id 'org.jetbrains.kotlin.jvm' id 'org.jetbrains.dokka' } @@ -11,6 +11,12 @@ intellij { updateSinceUntilBuild = false } +java { + toolchain { + languageVersion.set(JavaLanguageVersion.of(17)) + } +} + group 'com.uber.motif' version '0.0.5' // Plugin version diff --git a/intellij/src/main/resources/META-INF/plugin.xml b/intellij/src/main/resources/META-INF/plugin.xml index 27b5c055..da829338 100644 --- a/intellij/src/main/resources/META-INF/plugin.xml +++ b/intellij/src/main/resources/META-INF/plugin.xml @@ -1,6 +1,6 @@ com.uber.motif - Motif Plugin + Motif 0.0.5 Uber @@ -15,10 +15,10 @@ ]]> - + + Release 0.0.5: Add logging extension point + IntelliJ 2023.2 compatibility.
Release 0.0.4: Update plugin email address.
Release 0.0.3: Minor fixes.
Release 0.0.2: Minor fixes.
diff --git a/tests/build.gradle b/tests/build.gradle index a50a9011..0b5a6326 100644 --- a/tests/build.gradle +++ b/tests/build.gradle @@ -1,5 +1,4 @@ plugins { - id 'net.ltgt.apt-idea' version '0.21' id 'com.google.devtools.ksp' } From 2019b6545774ca531e35105a9aaf896b64492550 Mon Sep 17 00:00:00 2001 From: daviss Date: Thu, 5 Oct 2023 11:02:23 -0700 Subject: [PATCH 26/56] prefer LightJavaCodeInsightFixtureTestCase LightCodeInsightFixtureTestCase was deprecated - we needed to update how we set up the ProjectDescriptor as well. Per IDEA-225960, internalJdk will be increasingly deprecated - IDEA seems to updated the internal disposal logic so our static initialization no longer works - they have created fake jdk for test usage - but there seems to be some slight behavior change (e.g. no fully qualified name) that we should probably update separately --- .../ast/intellij/IntelliJAnnotationTest.kt | 16 +++++-------- .../motif/ast/intellij/IntelliJClassTest.kt | 18 ++++++-------- .../motif/ast/intellij/IntelliJKotlinTest.kt | 16 +++++-------- .../test/kotlin/motif/intellij/TestHarness.kt | 15 +++++------- .../motif/intellij/testing/InternalJdk.kt | 24 ------------------- 5 files changed, 25 insertions(+), 64 deletions(-) delete mode 100644 intellij/testing/src/main/kotlin/motif/intellij/testing/InternalJdk.kt diff --git a/intellij/ast/src/test/kotlin/motif/ast/intellij/IntelliJAnnotationTest.kt b/intellij/ast/src/test/kotlin/motif/ast/intellij/IntelliJAnnotationTest.kt index 1ec2a3e3..4609a646 100644 --- a/intellij/ast/src/test/kotlin/motif/ast/intellij/IntelliJAnnotationTest.kt +++ b/intellij/ast/src/test/kotlin/motif/ast/intellij/IntelliJAnnotationTest.kt @@ -15,28 +15,24 @@ */ package motif.ast.intellij -import com.intellij.pom.java.LanguageLevel +import com.intellij.openapi.projectRoots.impl.JavaAwareProjectJdkTableImpl import com.intellij.psi.PsiElementFactory -import com.intellij.testFramework.LightProjectDescriptor -import com.intellij.testFramework.fixtures.LightCodeInsightFixtureTestCase -import motif.intellij.testing.InternalJdk +import com.intellij.testFramework.fixtures.DefaultLightProjectDescriptor +import com.intellij.testFramework.fixtures.LightJavaCodeInsightFixtureTestCase import org.assertj.core.api.Assertions.assertThat import org.intellij.lang.annotations.Language -class IntelliJAnnotationTest : LightCodeInsightFixtureTestCase() { +class IntelliJAnnotationTest : LightJavaCodeInsightFixtureTestCase() { lateinit var psiElementFactory: PsiElementFactory override fun setUp() { super.setUp() - psiElementFactory = PsiElementFactory.SERVICE.getInstance(project) } - override fun getProjectDescriptor(): LightProjectDescriptor { - return object : ProjectDescriptor(LanguageLevel.HIGHEST) { - override fun getSdk() = InternalJdk.instance - } + override fun getProjectDescriptor() = DefaultLightProjectDescriptor { + JavaAwareProjectJdkTableImpl.getInstanceEx().internalJdk } override fun getTestDataPath(): String { diff --git a/intellij/ast/src/test/kotlin/motif/ast/intellij/IntelliJClassTest.kt b/intellij/ast/src/test/kotlin/motif/ast/intellij/IntelliJClassTest.kt index 4ef652eb..cdf467b9 100644 --- a/intellij/ast/src/test/kotlin/motif/ast/intellij/IntelliJClassTest.kt +++ b/intellij/ast/src/test/kotlin/motif/ast/intellij/IntelliJClassTest.kt @@ -15,29 +15,25 @@ */ package motif.ast.intellij -import com.intellij.pom.java.LanguageLevel +import com.intellij.openapi.projectRoots.impl.JavaAwareProjectJdkTableImpl import com.intellij.psi.PsiElementFactory -import com.intellij.testFramework.LightProjectDescriptor -import com.intellij.testFramework.fixtures.LightCodeInsightFixtureTestCase -import motif.intellij.testing.InternalJdk +import com.intellij.testFramework.fixtures.DefaultLightProjectDescriptor +import com.intellij.testFramework.fixtures.LightJavaCodeInsightFixtureTestCase import org.assertj.core.api.Assertions.assertThat import org.intellij.lang.annotations.Language import org.junit.Test -class IntelliJClassTest : LightCodeInsightFixtureTestCase() { +class IntelliJClassTest : LightJavaCodeInsightFixtureTestCase() { lateinit var psiElementFactory: PsiElementFactory override fun setUp() { super.setUp() - - psiElementFactory = PsiElementFactory.SERVICE.getInstance(project) + psiElementFactory = PsiElementFactory.getInstance(project) } - override fun getProjectDescriptor(): LightProjectDescriptor { - return object : ProjectDescriptor(LanguageLevel.HIGHEST) { - override fun getSdk() = InternalJdk.instance - } + override fun getProjectDescriptor() = DefaultLightProjectDescriptor { + JavaAwareProjectJdkTableImpl.getInstanceEx().internalJdk } override fun getTestDataPath(): String { diff --git a/intellij/ast/src/test/kotlin/motif/ast/intellij/IntelliJKotlinTest.kt b/intellij/ast/src/test/kotlin/motif/ast/intellij/IntelliJKotlinTest.kt index 896b71a7..18f37900 100644 --- a/intellij/ast/src/test/kotlin/motif/ast/intellij/IntelliJKotlinTest.kt +++ b/intellij/ast/src/test/kotlin/motif/ast/intellij/IntelliJKotlinTest.kt @@ -15,30 +15,26 @@ */ package motif.ast.intellij -import com.intellij.pom.java.LanguageLevel +import com.intellij.openapi.projectRoots.impl.JavaAwareProjectJdkTableImpl import com.intellij.psi.PsiElementFactory -import com.intellij.testFramework.LightProjectDescriptor -import com.intellij.testFramework.fixtures.LightCodeInsightFixtureTestCase -import motif.intellij.testing.InternalJdk +import com.intellij.testFramework.fixtures.DefaultLightProjectDescriptor +import com.intellij.testFramework.fixtures.LightJavaCodeInsightFixtureTestCase import org.assertj.core.api.Assertions.assertThat import org.jetbrains.kotlin.psi.KtFile import org.jetbrains.uast.UClass import org.jetbrains.uast.toUElementOfType -class IntelliJKotlinTest : LightCodeInsightFixtureTestCase() { +class IntelliJKotlinTest : LightJavaCodeInsightFixtureTestCase() { lateinit var psiElementFactory: PsiElementFactory override fun setUp() { super.setUp() - psiElementFactory = PsiElementFactory.SERVICE.getInstance(project) } - override fun getProjectDescriptor(): LightProjectDescriptor { - return object : ProjectDescriptor(LanguageLevel.HIGHEST) { - override fun getSdk() = InternalJdk.instance - } + override fun getProjectDescriptor() = DefaultLightProjectDescriptor { + JavaAwareProjectJdkTableImpl.getInstanceEx().internalJdk } override fun getTestDataPath(): String { diff --git a/intellij/src/test/kotlin/motif/intellij/TestHarness.kt b/intellij/src/test/kotlin/motif/intellij/TestHarness.kt index 36ef5134..52dbacdd 100644 --- a/intellij/src/test/kotlin/motif/intellij/TestHarness.kt +++ b/intellij/src/test/kotlin/motif/intellij/TestHarness.kt @@ -17,11 +17,11 @@ package motif.intellij import com.google.common.truth.Truth.assertThat import com.google.common.truth.Truth.assertWithMessage -import com.intellij.pom.java.LanguageLevel -import com.intellij.testFramework.LightProjectDescriptor +import com.intellij.openapi.projectRoots.impl.JavaAwareProjectJdkTableImpl import com.intellij.testFramework.Parameterized import com.intellij.testFramework.PsiTestUtil -import com.intellij.testFramework.fixtures.LightCodeInsightFixtureTestCase +import com.intellij.testFramework.fixtures.DefaultLightProjectDescriptor +import com.intellij.testFramework.fixtures.LightJavaCodeInsightFixtureTestCase import java.io.File import javax.annotation.Nullable import javax.inject.Inject @@ -30,7 +30,6 @@ import motif.Scope import motif.core.ResolvedGraph import motif.errormessage.ErrorMessage import motif.intellij.testing.IntelliJRule -import motif.intellij.testing.InternalJdk import motif.viewmodel.TestRenderer import org.junit.After import org.junit.Before @@ -39,16 +38,14 @@ import org.junit.Test import org.junit.runner.RunWith @RunWith(Parameterized::class) -class TestHarness : LightCodeInsightFixtureTestCase() { +class TestHarness : LightJavaCodeInsightFixtureTestCase() { @get:Rule val rule = IntelliJRule() @org.junit.runners.Parameterized.Parameter(0) lateinit var testDir: File - override fun getProjectDescriptor(): LightProjectDescriptor { - return object : ProjectDescriptor(LanguageLevel.HIGHEST) { - override fun getSdk() = InternalJdk.instance - } + override fun getProjectDescriptor() = DefaultLightProjectDescriptor { + JavaAwareProjectJdkTableImpl.getInstanceEx().internalJdk } @Before diff --git a/intellij/testing/src/main/kotlin/motif/intellij/testing/InternalJdk.kt b/intellij/testing/src/main/kotlin/motif/intellij/testing/InternalJdk.kt deleted file mode 100644 index 0f1c4598..00000000 --- a/intellij/testing/src/main/kotlin/motif/intellij/testing/InternalJdk.kt +++ /dev/null @@ -1,24 +0,0 @@ -/* - * Copyright (c) 2018-2019 Uber Technologies, Inc. - * - * 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 motif.intellij.testing - -import com.intellij.openapi.projectRoots.Sdk -import com.intellij.openapi.projectRoots.impl.JavaAwareProjectJdkTableImpl - -object InternalJdk { - - val instance: Sdk by lazy { JavaAwareProjectJdkTableImpl.getInstanceEx().internalJdk } -} From 8a7a2dfc7a62921d46974695a746ab4044464d08 Mon Sep 17 00:00:00 2001 From: daviss Date: Thu, 5 Oct 2023 11:07:54 -0700 Subject: [PATCH 27/56] update HierarchyBrowserBase children HierarchyBrowserBase updated its createTrees generic variance and removed some method - this commit changes the children to follow --- .../motif/intellij/hierarchy/ErrorHierarchyBrowser.kt | 6 +----- .../motif/intellij/hierarchy/ScopeHierarchyBrowser.kt | 6 +----- .../intellij/hierarchy/ScopePropertyHierarchyBrowser.kt | 6 +----- .../motif/intellij/hierarchy/UsageHierarchyBrowser.kt | 6 +----- 4 files changed, 4 insertions(+), 20 deletions(-) diff --git a/intellij/src/main/kotlin/motif/intellij/hierarchy/ErrorHierarchyBrowser.kt b/intellij/src/main/kotlin/motif/intellij/hierarchy/ErrorHierarchyBrowser.kt index 8722c30b..20082b9b 100644 --- a/intellij/src/main/kotlin/motif/intellij/hierarchy/ErrorHierarchyBrowser.kt +++ b/intellij/src/main/kotlin/motif/intellij/hierarchy/ErrorHierarchyBrowser.kt @@ -92,7 +92,7 @@ class ErrorHierarchyBrowser( return null } - override fun createTrees(trees: MutableMap) { + override fun createTrees(trees: MutableMap) { trees[ERROR_HIERARCHY_TYPE] = createTree(true) } @@ -129,10 +129,6 @@ class ErrorHierarchyBrowser( return null } - override fun getBrowserDataKey(): String { - return DATA_KEY.name - } - override fun doRefresh(currentBuilderOnly: Boolean) { MotifProjectComponent.getInstance(project).refreshGraph() } diff --git a/intellij/src/main/kotlin/motif/intellij/hierarchy/ScopeHierarchyBrowser.kt b/intellij/src/main/kotlin/motif/intellij/hierarchy/ScopeHierarchyBrowser.kt index 5d4cfc98..83f437e6 100644 --- a/intellij/src/main/kotlin/motif/intellij/hierarchy/ScopeHierarchyBrowser.kt +++ b/intellij/src/main/kotlin/motif/intellij/hierarchy/ScopeHierarchyBrowser.kt @@ -116,7 +116,7 @@ class ScopeHierarchyBrowser( return null } - override fun createTrees(trees: MutableMap) { + override fun createTrees(trees: MutableMap) { trees[TYPE_HIERARCHY_TYPE] = createTree(true) } @@ -164,10 +164,6 @@ class ScopeHierarchyBrowser( return null } - override fun getBrowserDataKey(): String { - return DATA_KEY.name - } - override fun configureTree(tree: Tree) { super.configureTree(tree) tree.addTreeSelectionListener { diff --git a/intellij/src/main/kotlin/motif/intellij/hierarchy/ScopePropertyHierarchyBrowser.kt b/intellij/src/main/kotlin/motif/intellij/hierarchy/ScopePropertyHierarchyBrowser.kt index 3f287506..c7551437 100644 --- a/intellij/src/main/kotlin/motif/intellij/hierarchy/ScopePropertyHierarchyBrowser.kt +++ b/intellij/src/main/kotlin/motif/intellij/hierarchy/ScopePropertyHierarchyBrowser.kt @@ -113,7 +113,7 @@ class ScopePropertyHierarchyBrowser( return LABEL_GO_NEXT_SCOPE } - override fun createTrees(trees: MutableMap) { + override fun createTrees(trees: MutableMap) { trees[PROPERTY_HIERARCHY_TYPE] = createTree(true) } @@ -186,10 +186,6 @@ class ScopePropertyHierarchyBrowser( return null } - override fun getBrowserDataKey(): String { - return DATA_KEY.name - } - override fun onGraphUpdated(graph: ResolvedGraph) { this.graph = graph super.doRefresh(true) diff --git a/intellij/src/main/kotlin/motif/intellij/hierarchy/UsageHierarchyBrowser.kt b/intellij/src/main/kotlin/motif/intellij/hierarchy/UsageHierarchyBrowser.kt index 823b8993..6c1dc2f9 100644 --- a/intellij/src/main/kotlin/motif/intellij/hierarchy/UsageHierarchyBrowser.kt +++ b/intellij/src/main/kotlin/motif/intellij/hierarchy/UsageHierarchyBrowser.kt @@ -87,7 +87,7 @@ class UsageHierarchyBrowser( return null } - override fun createTrees(trees: MutableMap) { + override fun createTrees(trees: MutableMap) { trees[USAGE_HIERARCHY_TYPE] = createTree(true) } @@ -108,10 +108,6 @@ class UsageHierarchyBrowser( return null } - override fun getBrowserDataKey(): String { - return DATA_KEY.name - } - override fun onGraphUpdated(graph: ResolvedGraph) { this.graph = graph super.doRefresh(true) From 65ef280525629c5b01865d02d91e2e30fba71ab9 Mon Sep 17 00:00:00 2001 From: daviss Date: Thu, 5 Oct 2023 12:14:01 -0700 Subject: [PATCH 28/56] stop using project component project component has been deprecated - in this commit, we migrate to MotifProjectService and AnalyticsProjectService --- .../AttachMotifProjectServiceActivity.kt | 26 +++++++++++++ ...ectComponent.kt => MotifProjectService.kt} | 37 ++++++++++--------- .../actions/MotifAncestorGraphAction.kt | 15 ++++---- .../intellij/actions/MotifGraphAction.kt | 14 ++++--- .../intellij/actions/MotifUsageAction.kt | 18 +++++---- ...omponent.kt => AnalyticsProjectService.kt} | 12 +++--- .../hierarchy/ErrorHierarchyBrowser.kt | 6 +-- .../hierarchy/ScopeHierarchyBrowser.kt | 10 ++--- .../ScopePropertyHierarchyBrowser.kt | 4 +- .../hierarchy/UsageHierarchyBrowser.kt | 4 +- .../ScopeHierarchyLineMarkerProvider.kt | 17 +++++---- .../ScopeNavigationLineMarkerProvider.kt | 9 +++-- .../motif/intellij/ui/MotifErrorPanel.kt | 4 +- .../motif/intellij/ui/MotifScopePanel.kt | 4 +- .../motif/intellij/ui/MotifUsagePanel.kt | 4 +- .../src/main/resources/META-INF/plugin.xml | 13 ++----- 16 files changed, 114 insertions(+), 83 deletions(-) create mode 100644 intellij/src/main/kotlin/motif/intellij/AttachMotifProjectServiceActivity.kt rename intellij/src/main/kotlin/motif/intellij/{MotifProjectComponent.kt => MotifProjectService.kt} (89%) rename intellij/src/main/kotlin/motif/intellij/analytics/{AnalyticsProjectComponent.kt => AnalyticsProjectService.kt} (82%) diff --git a/intellij/src/main/kotlin/motif/intellij/AttachMotifProjectServiceActivity.kt b/intellij/src/main/kotlin/motif/intellij/AttachMotifProjectServiceActivity.kt new file mode 100644 index 00000000..71699f9d --- /dev/null +++ b/intellij/src/main/kotlin/motif/intellij/AttachMotifProjectServiceActivity.kt @@ -0,0 +1,26 @@ +/* + * Copyright (c) 2023 Uber Technologies, Inc. + * + * 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 motif.intellij + +import com.intellij.openapi.components.service +import com.intellij.openapi.project.Project +import com.intellij.openapi.startup.ProjectActivity + +class AttachMotifProjectServiceActivity : ProjectActivity { + override suspend fun execute(project: Project) { + project.service().attach() + } +} diff --git a/intellij/src/main/kotlin/motif/intellij/MotifProjectComponent.kt b/intellij/src/main/kotlin/motif/intellij/MotifProjectService.kt similarity index 89% rename from intellij/src/main/kotlin/motif/intellij/MotifProjectComponent.kt rename to intellij/src/main/kotlin/motif/intellij/MotifProjectService.kt index df11f638..9b40cc6c 100644 --- a/intellij/src/main/kotlin/motif/intellij/MotifProjectComponent.kt +++ b/intellij/src/main/kotlin/motif/intellij/MotifProjectService.kt @@ -19,10 +19,11 @@ import com.intellij.codeInsight.daemon.LineMarkerProviders import com.intellij.ide.plugins.PluginManager import com.intellij.lang.Language import com.intellij.lang.java.JavaLanguage +import com.intellij.openapi.Disposable import com.intellij.openapi.actionSystem.ActionManager import com.intellij.openapi.actionSystem.AnAction import com.intellij.openapi.application.ApplicationManager -import com.intellij.openapi.components.ProjectComponent +import com.intellij.openapi.components.Service import com.intellij.openapi.progress.ProgressIndicator import com.intellij.openapi.progress.ProgressManager import com.intellij.openapi.progress.Task @@ -36,15 +37,17 @@ import com.intellij.psi.PsiClass import com.intellij.psi.PsiElement import com.intellij.ui.content.Content import com.intellij.ui.content.ContentFactory +import javax.swing.Icon import motif.core.ResolvedGraph -import motif.intellij.analytics.AnalyticsProjectComponent +import motif.intellij.analytics.AnalyticsProjectService import motif.intellij.analytics.MotifAnalyticsActions import motif.intellij.ui.MotifErrorPanel import motif.intellij.ui.MotifScopePanel import motif.intellij.ui.MotifUsagePanel import org.jetbrains.kotlin.idea.KotlinLanguage -class MotifProjectComponent(val project: Project) : ProjectComponent { +@Service(Service.Level.PROJECT) +class MotifProjectService(val project: Project) : Disposable { companion object { const val TOOL_WINDOW_ID: String = "Motif" @@ -61,10 +64,6 @@ class MotifProjectComponent(val project: Project) : ProjectComponent { "Error computing Motif graph. If error persists after you rebuild your project and restart IDE, please make sure to report the issue." private val MOTIF_ACTION_IDS = listOf("motif_usage", "motif_graph", "motif_ancestor_graph") - - fun getInstance(project: Project): MotifProjectComponent { - return project.getComponent(MotifProjectComponent::class.java) - } } private val graphFactory: GraphFactory by lazy { GraphFactory(project) } @@ -79,19 +78,22 @@ class MotifProjectComponent(val project: Project) : ProjectComponent { private var isRefreshing: Boolean = false private var pendingAction: (() -> Unit)? = null - override fun projectOpened() { + fun attach() { DumbService.getInstance(project).runWhenSmart { ApplicationManager.getApplication().runReadAction { // Initialize plugin with empty graph to avoid IDE startup slowdown val emptyGraph: ResolvedGraph = ResolvedGraph.create(emptyList()) onGraphUpdated(emptyGraph) - AnalyticsProjectComponent.getInstance(project) + project + .getService(AnalyticsProjectService::class.java) .logEvent(MotifAnalyticsActions.PROJECT_OPENED) } } } + override fun dispose() {} + fun refreshGraph() { if (isRefreshing) { return @@ -111,12 +113,13 @@ class MotifProjectComponent(val project: Project) : ProjectComponent { if (updatedGraph.errors.isNotEmpty()) MotifAnalyticsActions.GRAPH_UPDATE_ERROR else MotifAnalyticsActions.GRAPH_UPDATE_SUCCESS - AnalyticsProjectComponent.getInstance(project).logEvent(eventName) + project.getService(AnalyticsProjectService::class.java).logEvent(eventName) } catch (t: Throwable) { val emptyGraph: ResolvedGraph = ResolvedGraph.create(emptyList()) onGraphUpdated(emptyGraph) - AnalyticsProjectComponent.getInstance(project) + project + .getService(AnalyticsProjectService::class.java) .logEvent(MotifAnalyticsActions.GRAPH_COMPUTATION_ERROR) PluginManager.getLogger().error(LABEL_GRAPH_COMPUTATION_ERROR, t) } finally { @@ -166,7 +169,7 @@ class MotifProjectComponent(val project: Project) : ProjectComponent { if (toolWindowManager.getToolWindow(TOOL_WINDOW_ID) == null) { val toolWindow: ToolWindow = toolWindowManager.registerToolWindow(TOOL_WINDOW_ID, true, ToolWindowAnchor.RIGHT) - toolWindow.setIcon(IconLoader.getIcon("/icons/icon.svg")) + toolWindow.setIcon(IconLoader.getIcon("/icons/icon.svg", Icon::class.java)) toolWindow.title = TOOL_WINDOW_TITLE scopePanel = MotifScopePanel(project, graph) @@ -211,16 +214,14 @@ class MotifProjectComponent(val project: Project) : ProjectComponent { } private fun createScopeContent(toolWindow: ToolWindow): Content { - val content = - ContentFactory.SERVICE.getInstance().createContent(scopePanel, TAB_NAME_SCOPES, true) + val content = ContentFactory.getInstance().createContent(scopePanel, TAB_NAME_SCOPES, true) content.isCloseable = false toolWindow.contentManager.addContent(content) return content } private fun createErrorContent(toolWindow: ToolWindow): Content { - val content = - ContentFactory.SERVICE.getInstance().createContent(errorPanel, TAB_NAME_ERRORS, true) + val content = ContentFactory.getInstance().createContent(errorPanel, TAB_NAME_ERRORS, true) content.isCloseable = false toolWindow.contentManager.addContent(content) return content @@ -228,7 +229,7 @@ class MotifProjectComponent(val project: Project) : ProjectComponent { private fun createUsageContent(toolWindow: ToolWindow): Content { val content: Content = - ContentFactory.SERVICE.getInstance().createContent(usagePanel, TAB_NAME_USAGE, true) + ContentFactory.getInstance().createContent(usagePanel, TAB_NAME_USAGE, true) content.description = TAB_NAME_USAGE content.isCloseable = true toolWindow.contentManager.addContent(content) @@ -237,7 +238,7 @@ class MotifProjectComponent(val project: Project) : ProjectComponent { private fun createAncestorContent(toolWindow: ToolWindow): Content { val content: Content = - ContentFactory.SERVICE.getInstance().createContent(ancestorPanel, TAB_NAME_ANCESTOR, true) + ContentFactory.getInstance().createContent(ancestorPanel, TAB_NAME_ANCESTOR, true) content.description = TAB_NAME_ANCESTOR content.isCloseable = true toolWindow.contentManager.addContent(content) diff --git a/intellij/src/main/kotlin/motif/intellij/actions/MotifAncestorGraphAction.kt b/intellij/src/main/kotlin/motif/intellij/actions/MotifAncestorGraphAction.kt index 8c1e618b..b0aa009b 100644 --- a/intellij/src/main/kotlin/motif/intellij/actions/MotifAncestorGraphAction.kt +++ b/intellij/src/main/kotlin/motif/intellij/actions/MotifAncestorGraphAction.kt @@ -23,18 +23,18 @@ import com.intellij.openapi.wm.ToolWindowManager import com.intellij.psi.PsiClass import com.intellij.psi.PsiElement import motif.core.ResolvedGraph -import motif.intellij.MotifProjectComponent -import motif.intellij.MotifProjectComponent.Companion.TOOL_WINDOW_ID +import motif.intellij.MotifProjectService +import motif.intellij.MotifProjectService.Companion.TOOL_WINDOW_ID import motif.intellij.ScopeHierarchyUtils.Companion.getParentScopes import motif.intellij.ScopeHierarchyUtils.Companion.isInitializedGraph import motif.intellij.ScopeHierarchyUtils.Companion.isMotifScopeClass -import motif.intellij.analytics.AnalyticsProjectComponent +import motif.intellij.analytics.AnalyticsProjectService import motif.intellij.analytics.MotifAnalyticsActions /* * {@AnAction} used to trigger displaying a particular scope ancestors hierarchy. */ -class MotifAncestorGraphAction : AnAction(), MotifProjectComponent.Listener { +class MotifAncestorGraphAction : AnAction(), MotifProjectService.Listener { private var graph: ResolvedGraph? = null @@ -48,17 +48,18 @@ class MotifAncestorGraphAction : AnAction(), MotifProjectComponent.Listener { val graph = graph ?: return if (!isInitializedGraph(graph)) { - MotifProjectComponent.getInstance(project).refreshGraph { actionPerformed(event) } + project.getService(MotifProjectService::class.java).refreshGraph { actionPerformed(event) } return } val toolWindow: ToolWindow = ToolWindowManager.getInstance(project).getToolWindow(TOOL_WINDOW_ID) ?: return toolWindow.activate { - MotifProjectComponent.getInstance(project).onSelectedAncestorScope(element) + project.getService(MotifProjectService::class.java).onSelectedAncestorScope(element) } - AnalyticsProjectComponent.getInstance(project) + project + .getService(AnalyticsProjectService::class.java) .logEvent(MotifAnalyticsActions.ANCESTOR_MENU_CLICK) } diff --git a/intellij/src/main/kotlin/motif/intellij/actions/MotifGraphAction.kt b/intellij/src/main/kotlin/motif/intellij/actions/MotifGraphAction.kt index ae4e892b..0fbbde2b 100644 --- a/intellij/src/main/kotlin/motif/intellij/actions/MotifGraphAction.kt +++ b/intellij/src/main/kotlin/motif/intellij/actions/MotifGraphAction.kt @@ -20,16 +20,16 @@ import com.intellij.openapi.actionSystem.AnActionEvent import com.intellij.openapi.wm.ToolWindow import com.intellij.openapi.wm.ToolWindowManager import motif.core.ResolvedGraph -import motif.intellij.MotifProjectComponent -import motif.intellij.MotifProjectComponent.Companion.TOOL_WINDOW_ID +import motif.intellij.MotifProjectService +import motif.intellij.MotifProjectService.Companion.TOOL_WINDOW_ID import motif.intellij.ScopeHierarchyUtils.Companion.isInitializedGraph -import motif.intellij.analytics.AnalyticsProjectComponent +import motif.intellij.analytics.AnalyticsProjectService import motif.intellij.analytics.MotifAnalyticsActions /* * {@AnAction} used to trigger displaying entire scope hierarchy. */ -class MotifGraphAction : AnAction(), MotifProjectComponent.Listener { +class MotifGraphAction : AnAction(), MotifProjectService.Listener { private var graph: ResolvedGraph? = null @@ -42,7 +42,7 @@ class MotifGraphAction : AnAction(), MotifProjectComponent.Listener { val graph = graph ?: return if (!isInitializedGraph(graph)) { - MotifProjectComponent.getInstance(project).refreshGraph { actionPerformed(event) } + project.getService(MotifProjectService::class.java).refreshGraph { actionPerformed(event) } return } @@ -50,7 +50,9 @@ class MotifGraphAction : AnAction(), MotifProjectComponent.Listener { ToolWindowManager.getInstance(project).getToolWindow(TOOL_WINDOW_ID) ?: return toolWindow.activate {} - AnalyticsProjectComponent.getInstance(project).logEvent(MotifAnalyticsActions.GRAPH_MENU_CLICK) + project + .getService(AnalyticsProjectService::class.java) + .logEvent(MotifAnalyticsActions.GRAPH_MENU_CLICK) } override fun update(e: AnActionEvent) { diff --git a/intellij/src/main/kotlin/motif/intellij/actions/MotifUsageAction.kt b/intellij/src/main/kotlin/motif/intellij/actions/MotifUsageAction.kt index 6a87669b..e5c85263 100644 --- a/intellij/src/main/kotlin/motif/intellij/actions/MotifUsageAction.kt +++ b/intellij/src/main/kotlin/motif/intellij/actions/MotifUsageAction.kt @@ -23,17 +23,17 @@ import com.intellij.openapi.wm.ToolWindowManager import com.intellij.psi.PsiClass import com.intellij.psi.PsiElement import motif.core.ResolvedGraph -import motif.intellij.MotifProjectComponent -import motif.intellij.MotifProjectComponent.Companion.TOOL_WINDOW_ID +import motif.intellij.MotifProjectService +import motif.intellij.MotifProjectService.Companion.TOOL_WINDOW_ID import motif.intellij.ScopeHierarchyUtils import motif.intellij.ScopeHierarchyUtils.Companion.getUsageCount -import motif.intellij.analytics.AnalyticsProjectComponent +import motif.intellij.analytics.AnalyticsProjectService import motif.intellij.analytics.MotifAnalyticsActions /* * {@AnAction} used to trigger navigation to a particular scope in the scope hierarchy window. */ -class MotifUsageAction : AnAction(), MotifProjectComponent.Listener { +class MotifUsageAction : AnAction(), MotifProjectService.Listener { private var graph: ResolvedGraph? = null @@ -47,15 +47,19 @@ class MotifUsageAction : AnAction(), MotifProjectComponent.Listener { val graph = graph ?: return if (!ScopeHierarchyUtils.isInitializedGraph(graph)) { - MotifProjectComponent.getInstance(project).refreshGraph { actionPerformed(event) } + project.getService(MotifProjectService::class.java).refreshGraph { actionPerformed(event) } return } val toolWindow: ToolWindow = ToolWindowManager.getInstance(project).getToolWindow(TOOL_WINDOW_ID) ?: return - toolWindow.activate { MotifProjectComponent.getInstance(project).onSelectedClass(element) } + toolWindow.activate { + project.getService(MotifProjectService::class.java).onSelectedClass(element) + } - AnalyticsProjectComponent.getInstance(project).logEvent(MotifAnalyticsActions.USAGE_MENU_CLICK) + project + .getService(AnalyticsProjectService::class.java) + .logEvent(MotifAnalyticsActions.USAGE_MENU_CLICK) } override fun update(e: AnActionEvent) { diff --git a/intellij/src/main/kotlin/motif/intellij/analytics/AnalyticsProjectComponent.kt b/intellij/src/main/kotlin/motif/intellij/analytics/AnalyticsProjectService.kt similarity index 82% rename from intellij/src/main/kotlin/motif/intellij/analytics/AnalyticsProjectComponent.kt rename to intellij/src/main/kotlin/motif/intellij/analytics/AnalyticsProjectService.kt index 9034531a..62aba5f5 100644 --- a/intellij/src/main/kotlin/motif/intellij/analytics/AnalyticsProjectComponent.kt +++ b/intellij/src/main/kotlin/motif/intellij/analytics/AnalyticsProjectService.kt @@ -15,23 +15,23 @@ */ package motif.intellij.analytics -import com.intellij.openapi.components.ProjectComponent +import com.intellij.openapi.Disposable +import com.intellij.openapi.components.Service import com.intellij.openapi.extensions.ExtensionPointName import com.intellij.openapi.project.Project import java.util.UUID -class AnalyticsProjectComponent(val project: Project) : ProjectComponent { +@Service(Service.Level.PROJECT) +class AnalyticsProjectService(val project: Project) : Disposable { companion object { private val LOGGER_EXTENSION_POINT_NAME: ExtensionPointName = ExtensionPointName.create("com.uber.motif.motifAnalyticsLogger") private val SESSION_ID = UUID.randomUUID() - - fun getInstance(project: Project): AnalyticsProjectComponent { - return project.getComponent(AnalyticsProjectComponent::class.java) - } } + override fun dispose() {} + fun logEvent(action: String) { val metadata: Map = mapOf("SessionId" to SESSION_ID.toString(), "ActionName" to action) diff --git a/intellij/src/main/kotlin/motif/intellij/hierarchy/ErrorHierarchyBrowser.kt b/intellij/src/main/kotlin/motif/intellij/hierarchy/ErrorHierarchyBrowser.kt index 20082b9b..9a3ffd17 100644 --- a/intellij/src/main/kotlin/motif/intellij/hierarchy/ErrorHierarchyBrowser.kt +++ b/intellij/src/main/kotlin/motif/intellij/hierarchy/ErrorHierarchyBrowser.kt @@ -33,7 +33,7 @@ import javax.swing.JTree import javax.swing.tree.DefaultMutableTreeNode import motif.core.ResolvedGraph import motif.errormessage.ErrorMessage -import motif.intellij.MotifProjectComponent +import motif.intellij.MotifProjectService import motif.intellij.ScopeHierarchyUtils.Companion.isRootElement import motif.intellij.hierarchy.ScopeHierarchyBrowser.Companion.LABEL_GO_NEXT_SCOPE import motif.intellij.hierarchy.ScopeHierarchyBrowser.Companion.LABEL_GO_PREVIOUS_SCOPE @@ -49,7 +49,7 @@ class ErrorHierarchyBrowser( initialGraph: ResolvedGraph, private val rootElement: PsiElement, private val selectionListener: Listener? -) : HierarchyBrowserBase(project, rootElement), MotifProjectComponent.Listener { +) : HierarchyBrowserBase(project, rootElement), MotifProjectService.Listener { private var graph: ResolvedGraph = initialGraph @@ -130,7 +130,7 @@ class ErrorHierarchyBrowser( } override fun doRefresh(currentBuilderOnly: Boolean) { - MotifProjectComponent.getInstance(project).refreshGraph() + project.getService(MotifProjectService::class.java).refreshGraph() } override fun onGraphUpdated(graph: ResolvedGraph) { diff --git a/intellij/src/main/kotlin/motif/intellij/hierarchy/ScopeHierarchyBrowser.kt b/intellij/src/main/kotlin/motif/intellij/hierarchy/ScopeHierarchyBrowser.kt index 83f437e6..95bc83d8 100644 --- a/intellij/src/main/kotlin/motif/intellij/hierarchy/ScopeHierarchyBrowser.kt +++ b/intellij/src/main/kotlin/motif/intellij/hierarchy/ScopeHierarchyBrowser.kt @@ -42,10 +42,10 @@ import motif.ast.IrType import motif.ast.intellij.IntelliJClass import motif.ast.intellij.IntelliJType import motif.core.ResolvedGraph -import motif.intellij.MotifProjectComponent +import motif.intellij.MotifProjectService import motif.intellij.ScopeHierarchyUtils import motif.intellij.ScopeHierarchyUtils.Companion.isMotifScopeClass -import motif.intellij.analytics.AnalyticsProjectComponent +import motif.intellij.analytics.AnalyticsProjectService import motif.intellij.analytics.MotifAnalyticsActions import motif.intellij.hierarchy.descriptor.ScopeHierarchyRootDescriptor import motif.intellij.hierarchy.descriptor.ScopeHierarchyScopeAncestorDescriptor @@ -60,7 +60,7 @@ class ScopeHierarchyBrowser( initialGraph: ResolvedGraph, private val rootElement: PsiElement, private val selectionListener: Listener? -) : HierarchyBrowserBase(project, rootElement), MotifProjectComponent.Listener { +) : HierarchyBrowserBase(project, rootElement), MotifProjectService.Listener { companion object { const val LABEL_GO_PREVIOUS_SCOPE: String = "Go to previous Scope." @@ -189,12 +189,12 @@ class ScopeHierarchyBrowser( else -> {} } - MotifProjectComponent.getInstance(project).refreshGraph() + project.getService(MotifProjectService::class.java).refreshGraph() val action: String = if (status == Status.INITIALIZING) MotifAnalyticsActions.GRAPH_INIT else MotifAnalyticsActions.GRAPH_UPDATE - AnalyticsProjectComponent.getInstance(project).logEvent(action) + project.getService(AnalyticsProjectService::class.java).logEvent(action) } /* diff --git a/intellij/src/main/kotlin/motif/intellij/hierarchy/ScopePropertyHierarchyBrowser.kt b/intellij/src/main/kotlin/motif/intellij/hierarchy/ScopePropertyHierarchyBrowser.kt index c7551437..2847fda1 100644 --- a/intellij/src/main/kotlin/motif/intellij/hierarchy/ScopePropertyHierarchyBrowser.kt +++ b/intellij/src/main/kotlin/motif/intellij/hierarchy/ScopePropertyHierarchyBrowser.kt @@ -41,7 +41,7 @@ import motif.ast.IrType import motif.ast.intellij.IntelliJClass import motif.ast.intellij.IntelliJType import motif.core.ResolvedGraph -import motif.intellij.MotifProjectComponent +import motif.intellij.MotifProjectService import motif.intellij.ScopeHierarchyUtils.Companion.isMotifScopeClass import motif.intellij.hierarchy.ScopeHierarchyBrowser.Companion.LABEL_GO_NEXT_SCOPE import motif.intellij.hierarchy.ScopeHierarchyBrowser.Companion.LABEL_GO_PREVIOUS_SCOPE @@ -61,7 +61,7 @@ class ScopePropertyHierarchyBrowser( initialGraph: ResolvedGraph, private val rootElement: PsiElement, private val hierarchyType: PropertyHierarchyType -) : HierarchyBrowserBase(project, rootElement), MotifProjectComponent.Listener { +) : HierarchyBrowserBase(project, rootElement), MotifProjectService.Listener { private var graph: ResolvedGraph = initialGraph diff --git a/intellij/src/main/kotlin/motif/intellij/hierarchy/UsageHierarchyBrowser.kt b/intellij/src/main/kotlin/motif/intellij/hierarchy/UsageHierarchyBrowser.kt index 6c1dc2f9..f537618e 100644 --- a/intellij/src/main/kotlin/motif/intellij/hierarchy/UsageHierarchyBrowser.kt +++ b/intellij/src/main/kotlin/motif/intellij/hierarchy/UsageHierarchyBrowser.kt @@ -30,7 +30,7 @@ import java.text.MessageFormat import javax.swing.JPanel import javax.swing.JTree import motif.core.ResolvedGraph -import motif.intellij.MotifProjectComponent +import motif.intellij.MotifProjectService import motif.intellij.hierarchy.ScopeHierarchyBrowser.Companion.LABEL_GO_NEXT_SCOPE import motif.intellij.hierarchy.ScopeHierarchyBrowser.Companion.LABEL_GO_PREVIOUS_SCOPE import motif.intellij.hierarchy.descriptor.ScopeHierarchyUsageSectionDescriptor @@ -42,7 +42,7 @@ class UsageHierarchyBrowser( project: Project, initialGraph: ResolvedGraph, private val rootElement: PsiElement -) : HierarchyBrowserBase(project, rootElement), MotifProjectComponent.Listener { +) : HierarchyBrowserBase(project, rootElement), MotifProjectService.Listener { private var graph: ResolvedGraph = initialGraph diff --git a/intellij/src/main/kotlin/motif/intellij/provider/ScopeHierarchyLineMarkerProvider.kt b/intellij/src/main/kotlin/motif/intellij/provider/ScopeHierarchyLineMarkerProvider.kt index 0480ee0f..5663298f 100644 --- a/intellij/src/main/kotlin/motif/intellij/provider/ScopeHierarchyLineMarkerProvider.kt +++ b/intellij/src/main/kotlin/motif/intellij/provider/ScopeHierarchyLineMarkerProvider.kt @@ -32,17 +32,17 @@ import com.intellij.psi.impl.source.PsiClassReferenceType import com.intellij.util.ConstantFunction import java.awt.event.MouseEvent import motif.core.ResolvedGraph -import motif.intellij.MotifProjectComponent -import motif.intellij.MotifProjectComponent.Companion.TOOL_WINDOW_ID +import motif.intellij.MotifProjectService +import motif.intellij.MotifProjectService.Companion.TOOL_WINDOW_ID import motif.intellij.ScopeHierarchyUtils.Companion.getParentScopes import motif.intellij.ScopeHierarchyUtils.Companion.isMotifScopeClass -import motif.intellij.analytics.AnalyticsProjectComponent +import motif.intellij.analytics.AnalyticsProjectService import motif.intellij.analytics.MotifAnalyticsActions /* * {@LineMarkerProvider} used to display icon in gutter to navigate to motif scope ancestors hierarchy. */ -class ScopeHierarchyLineMarkerProvider : LineMarkerProvider, MotifProjectComponent.Listener { +class ScopeHierarchyLineMarkerProvider : LineMarkerProvider, MotifProjectService.Listener { companion object { const val LABEL_ANCESTORS_SCOPE: String = "View Scope Ancestors." @@ -83,18 +83,21 @@ class ScopeHierarchyLineMarkerProvider : LineMarkerProvider, MotifProjectCompone ToolWindowManager.getInstance(project).getToolWindow(TOOL_WINDOW_ID) ?: return if (element is PsiClass) { toolWindow.activate { - MotifProjectComponent.getInstance(project).onSelectedAncestorScope(element) + project.getService(MotifProjectService::class.java).onSelectedAncestorScope(element) } } else if (element is PsiMethod) { if (element.returnType is PsiClassReferenceType) { val returnElementClass: PsiClass = (element.returnType as PsiClassReferenceType).resolve() ?: return toolWindow.activate { - MotifProjectComponent.getInstance(project).onSelectedAncestorScope(returnElementClass) + project + .getService(MotifProjectService::class.java) + .onSelectedAncestorScope(returnElementClass) } } } - AnalyticsProjectComponent.getInstance(project) + project + .getService(AnalyticsProjectService::class.java) .logEvent(MotifAnalyticsActions.ANCESTOR_GUTTER_CLICK) } } diff --git a/intellij/src/main/kotlin/motif/intellij/provider/ScopeNavigationLineMarkerProvider.kt b/intellij/src/main/kotlin/motif/intellij/provider/ScopeNavigationLineMarkerProvider.kt index cf3afa47..8219066a 100644 --- a/intellij/src/main/kotlin/motif/intellij/provider/ScopeNavigationLineMarkerProvider.kt +++ b/intellij/src/main/kotlin/motif/intellij/provider/ScopeNavigationLineMarkerProvider.kt @@ -40,11 +40,11 @@ import java.awt.event.MouseEvent import motif.ast.intellij.IntelliJClass import motif.core.ResolvedGraph import motif.core.ScopeEdge -import motif.intellij.MotifProjectComponent +import motif.intellij.MotifProjectService import motif.intellij.ScopeHierarchyUtils.Companion.getParentScopes import motif.intellij.ScopeHierarchyUtils.Companion.isMotifChildScopeMethod import motif.intellij.ScopeHierarchyUtils.Companion.isMotifScopeClass -import motif.intellij.analytics.AnalyticsProjectComponent +import motif.intellij.analytics.AnalyticsProjectService import motif.intellij.analytics.MotifAnalyticsActions import motif.intellij.toPsiClass import motif.intellij.toPsiMethod @@ -52,7 +52,7 @@ import motif.intellij.toPsiMethod /* * {@LineMarkerProvider} used to display navigation icons in gutter to navigate to parent/children of Motif scopes. */ -class ScopeNavigationLineMarkerProvider : LineMarkerProvider, MotifProjectComponent.Listener { +class ScopeNavigationLineMarkerProvider : LineMarkerProvider, MotifProjectService.Listener { companion object { const val LABEL_NAVIGATE_PARENT_SCOPE: String = "Navigate to parent Scope." @@ -157,7 +157,8 @@ class ScopeNavigationLineMarkerProvider : LineMarkerProvider, MotifProjectCompon } } } - AnalyticsProjectComponent.getInstance(project) + project + .getService(AnalyticsProjectService::class.java) .logEvent(MotifAnalyticsActions.NAVIGATION_GUTTER_CLICK) } diff --git a/intellij/src/main/kotlin/motif/intellij/ui/MotifErrorPanel.kt b/intellij/src/main/kotlin/motif/intellij/ui/MotifErrorPanel.kt index b1d57be9..dfcffe51 100644 --- a/intellij/src/main/kotlin/motif/intellij/ui/MotifErrorPanel.kt +++ b/intellij/src/main/kotlin/motif/intellij/ui/MotifErrorPanel.kt @@ -23,13 +23,13 @@ import javax.swing.JSplitPane import javax.swing.JTextArea import motif.core.ResolvedGraph import motif.errormessage.ErrorMessage -import motif.intellij.MotifProjectComponent +import motif.intellij.MotifProjectService import motif.intellij.ScopeHierarchyUtils import motif.intellij.hierarchy.ErrorHierarchyBrowser import motif.models.MotifError class MotifErrorPanel(project: Project, graph: ResolvedGraph) : - JPanel(), MotifProjectComponent.Listener, ErrorHierarchyBrowser.Listener { + JPanel(), MotifProjectService.Listener, ErrorHierarchyBrowser.Listener { private val splitPane: JSplitPane private val errorBrowser: ErrorHierarchyBrowser diff --git a/intellij/src/main/kotlin/motif/intellij/ui/MotifScopePanel.kt b/intellij/src/main/kotlin/motif/intellij/ui/MotifScopePanel.kt index 572a3b19..ddc50319 100644 --- a/intellij/src/main/kotlin/motif/intellij/ui/MotifScopePanel.kt +++ b/intellij/src/main/kotlin/motif/intellij/ui/MotifScopePanel.kt @@ -24,7 +24,7 @@ import javax.swing.JPanel import javax.swing.JSplitPane import javax.swing.JSplitPane.RIGHT import motif.core.ResolvedGraph -import motif.intellij.MotifProjectComponent +import motif.intellij.MotifProjectService import motif.intellij.ScopeHierarchyUtils import motif.intellij.hierarchy.ScopeHierarchyBrowser import motif.intellij.hierarchy.ScopePropertyHierarchyBrowser @@ -32,7 +32,7 @@ import motif.intellij.hierarchy.ScopePropertyHierarchyBrowser.PropertyHierarchyT import motif.models.Scope class MotifScopePanel(val project: Project, initialGraph: ResolvedGraph) : - JPanel(), ScopeHierarchyBrowser.Listener, MotifProjectComponent.Listener { + JPanel(), ScopeHierarchyBrowser.Listener, MotifProjectService.Listener { private var graph: ResolvedGraph = initialGraph diff --git a/intellij/src/main/kotlin/motif/intellij/ui/MotifUsagePanel.kt b/intellij/src/main/kotlin/motif/intellij/ui/MotifUsagePanel.kt index b4f85c08..1804cb4f 100644 --- a/intellij/src/main/kotlin/motif/intellij/ui/MotifUsagePanel.kt +++ b/intellij/src/main/kotlin/motif/intellij/ui/MotifUsagePanel.kt @@ -21,12 +21,12 @@ import com.intellij.psi.PsiElement import java.awt.BorderLayout import javax.swing.JPanel import motif.core.ResolvedGraph -import motif.intellij.MotifProjectComponent +import motif.intellij.MotifProjectService import motif.intellij.ScopeHierarchyUtils import motif.intellij.hierarchy.UsageHierarchyBrowser class MotifUsagePanel(project: Project, graph: ResolvedGraph) : - JPanel(), MotifProjectComponent.Listener { + JPanel(), MotifProjectService.Listener { private val usageBrowser: UsageHierarchyBrowser diff --git a/intellij/src/main/resources/META-INF/plugin.xml b/intellij/src/main/resources/META-INF/plugin.xml index da829338..81e9066f 100644 --- a/intellij/src/main/resources/META-INF/plugin.xml +++ b/intellij/src/main/resources/META-INF/plugin.xml @@ -30,16 +30,9 @@ org.jetbrains.kotlin com.intellij.modules.lang - - - motif.intellij.MotifProjectComponent - - - motif.intellij.analytics.AnalyticsProjectComponent - - + + + Date: Thu, 5 Oct 2023 16:22:10 -0700 Subject: [PATCH 29/56] fix test harness For some reason, our old way of adding libraries to the test environment stopped working and we need to use a different way. Also, the test rule need to be updated since the test environment now is more properly "faked" and the old rule hangs forever --- .../test/kotlin/motif/intellij/TestHarness.kt | 17 +++++++++++++---- .../motif/intellij/testing/IntelliJRule.kt | 17 ----------------- 2 files changed, 13 insertions(+), 21 deletions(-) diff --git a/intellij/src/test/kotlin/motif/intellij/TestHarness.kt b/intellij/src/test/kotlin/motif/intellij/TestHarness.kt index 52dbacdd..c6f88c91 100644 --- a/intellij/src/test/kotlin/motif/intellij/TestHarness.kt +++ b/intellij/src/test/kotlin/motif/intellij/TestHarness.kt @@ -23,6 +23,7 @@ import com.intellij.testFramework.PsiTestUtil import com.intellij.testFramework.fixtures.DefaultLightProjectDescriptor import com.intellij.testFramework.fixtures.LightJavaCodeInsightFixtureTestCase import java.io.File +import java.net.URI import javax.annotation.Nullable import javax.inject.Inject import kotlin.reflect.KClass @@ -63,10 +64,18 @@ class TestHarness : LightJavaCodeInsightFixtureTestCase() { } private fun addLibrary(clazz: KClass<*>) { - val path = clazz.java.protectionDomain.codeSource.location.path - val file = File(path) - val libName = file.name - PsiTestUtil.addLibrary(myFixture.projectDisposable, module, libName, file.parent, libName) + val fileUri = + clazz + .java + .getResource(clazz.simpleName + ".class") + ?.toString() + ?.let { Regex("file:.*[.]jar").find(it)?.value } + ?.let { URI.create(it) } + if (fileUri != null) { + val file = File(fileUri) + val libName = file.name + PsiTestUtil.addLibrary(myFixture.projectDisposable, module, libName, file.parent, libName) + } } @Test diff --git a/intellij/testing/src/main/kotlin/motif/intellij/testing/IntelliJRule.kt b/intellij/testing/src/main/kotlin/motif/intellij/testing/IntelliJRule.kt index 1d882feb..b50a56d3 100644 --- a/intellij/testing/src/main/kotlin/motif/intellij/testing/IntelliJRule.kt +++ b/intellij/testing/src/main/kotlin/motif/intellij/testing/IntelliJRule.kt @@ -15,9 +15,7 @@ */ package motif.intellij.testing -import com.intellij.openapi.application.ApplicationManager import com.intellij.testFramework.TestApplicationManager -import java.util.concurrent.CountDownLatch import org.junit.rules.TestRule import org.junit.runner.Description import org.junit.runners.model.Statement @@ -29,21 +27,6 @@ class IntelliJRule : TestRule { override fun evaluate() { TestApplicationManager.getInstance() - var e: Throwable? = null - val latch = CountDownLatch(1) - ApplicationManager.getApplication().invokeLater { - ApplicationManager.getApplication().runReadAction { - try { - base.evaluate() - } catch (throwable: Throwable) { - e = throwable - } finally { - latch.countDown() - } - } - } - latch.await() - e?.let { throw it } } } } From 111b7d36e9e8c3bda76843947d94fc4a5ef50864 Mon Sep 17 00:00:00 2001 From: daviss Date: Thu, 12 Oct 2023 10:03:50 -0700 Subject: [PATCH 30/56] remove "project" keyword from class Since that was leftover from ProjectComponent --- ...Activity.kt => AttachMotifServiceActivity.kt} | 4 ++-- .../{MotifProjectService.kt => MotifService.kt} | 10 +++++----- .../intellij/actions/MotifAncestorGraphAction.kt | 14 +++++++------- .../motif/intellij/actions/MotifGraphAction.kt | 12 ++++++------ .../motif/intellij/actions/MotifUsageAction.kt | 16 +++++++--------- ...ticsProjectService.kt => AnalyticsService.kt} | 2 +- .../intellij/hierarchy/ErrorHierarchyBrowser.kt | 6 +++--- .../intellij/hierarchy/ScopeHierarchyBrowser.kt | 10 +++++----- .../hierarchy/ScopePropertyHierarchyBrowser.kt | 4 ++-- .../intellij/hierarchy/UsageHierarchyBrowser.kt | 4 ++-- .../provider/ScopeHierarchyLineMarkerProvider.kt | 16 +++++++--------- .../ScopeNavigationLineMarkerProvider.kt | 8 ++++---- .../kotlin/motif/intellij/ui/MotifErrorPanel.kt | 4 ++-- .../kotlin/motif/intellij/ui/MotifScopePanel.kt | 4 ++-- .../kotlin/motif/intellij/ui/MotifUsagePanel.kt | 5 ++--- intellij/src/main/resources/META-INF/plugin.xml | 2 +- 16 files changed, 58 insertions(+), 63 deletions(-) rename intellij/src/main/kotlin/motif/intellij/{AttachMotifProjectServiceActivity.kt => AttachMotifServiceActivity.kt} (88%) rename intellij/src/main/kotlin/motif/intellij/{MotifProjectService.kt => MotifService.kt} (96%) rename intellij/src/main/kotlin/motif/intellij/analytics/{AnalyticsProjectService.kt => AnalyticsService.kt} (95%) diff --git a/intellij/src/main/kotlin/motif/intellij/AttachMotifProjectServiceActivity.kt b/intellij/src/main/kotlin/motif/intellij/AttachMotifServiceActivity.kt similarity index 88% rename from intellij/src/main/kotlin/motif/intellij/AttachMotifProjectServiceActivity.kt rename to intellij/src/main/kotlin/motif/intellij/AttachMotifServiceActivity.kt index 71699f9d..86f8d7ed 100644 --- a/intellij/src/main/kotlin/motif/intellij/AttachMotifProjectServiceActivity.kt +++ b/intellij/src/main/kotlin/motif/intellij/AttachMotifServiceActivity.kt @@ -19,8 +19,8 @@ import com.intellij.openapi.components.service import com.intellij.openapi.project.Project import com.intellij.openapi.startup.ProjectActivity -class AttachMotifProjectServiceActivity : ProjectActivity { +class AttachMotifServiceActivity : ProjectActivity { override suspend fun execute(project: Project) { - project.service().attach() + project.service().attach() } } diff --git a/intellij/src/main/kotlin/motif/intellij/MotifProjectService.kt b/intellij/src/main/kotlin/motif/intellij/MotifService.kt similarity index 96% rename from intellij/src/main/kotlin/motif/intellij/MotifProjectService.kt rename to intellij/src/main/kotlin/motif/intellij/MotifService.kt index 9b40cc6c..cfb1adf7 100644 --- a/intellij/src/main/kotlin/motif/intellij/MotifProjectService.kt +++ b/intellij/src/main/kotlin/motif/intellij/MotifService.kt @@ -39,7 +39,7 @@ import com.intellij.ui.content.Content import com.intellij.ui.content.ContentFactory import javax.swing.Icon import motif.core.ResolvedGraph -import motif.intellij.analytics.AnalyticsProjectService +import motif.intellij.analytics.AnalyticsService import motif.intellij.analytics.MotifAnalyticsActions import motif.intellij.ui.MotifErrorPanel import motif.intellij.ui.MotifScopePanel @@ -47,7 +47,7 @@ import motif.intellij.ui.MotifUsagePanel import org.jetbrains.kotlin.idea.KotlinLanguage @Service(Service.Level.PROJECT) -class MotifProjectService(val project: Project) : Disposable { +class MotifService(val project: Project) : Disposable { companion object { const val TOOL_WINDOW_ID: String = "Motif" @@ -86,7 +86,7 @@ class MotifProjectService(val project: Project) : Disposable { onGraphUpdated(emptyGraph) project - .getService(AnalyticsProjectService::class.java) + .getService(AnalyticsService::class.java) .logEvent(MotifAnalyticsActions.PROJECT_OPENED) } } @@ -113,13 +113,13 @@ class MotifProjectService(val project: Project) : Disposable { if (updatedGraph.errors.isNotEmpty()) MotifAnalyticsActions.GRAPH_UPDATE_ERROR else MotifAnalyticsActions.GRAPH_UPDATE_SUCCESS - project.getService(AnalyticsProjectService::class.java).logEvent(eventName) + project.getService(AnalyticsService::class.java).logEvent(eventName) } catch (t: Throwable) { val emptyGraph: ResolvedGraph = ResolvedGraph.create(emptyList()) onGraphUpdated(emptyGraph) project - .getService(AnalyticsProjectService::class.java) + .getService(AnalyticsService::class.java) .logEvent(MotifAnalyticsActions.GRAPH_COMPUTATION_ERROR) PluginManager.getLogger().error(LABEL_GRAPH_COMPUTATION_ERROR, t) } finally { diff --git a/intellij/src/main/kotlin/motif/intellij/actions/MotifAncestorGraphAction.kt b/intellij/src/main/kotlin/motif/intellij/actions/MotifAncestorGraphAction.kt index b0aa009b..744c9a9b 100644 --- a/intellij/src/main/kotlin/motif/intellij/actions/MotifAncestorGraphAction.kt +++ b/intellij/src/main/kotlin/motif/intellij/actions/MotifAncestorGraphAction.kt @@ -23,18 +23,18 @@ import com.intellij.openapi.wm.ToolWindowManager import com.intellij.psi.PsiClass import com.intellij.psi.PsiElement import motif.core.ResolvedGraph -import motif.intellij.MotifProjectService -import motif.intellij.MotifProjectService.Companion.TOOL_WINDOW_ID +import motif.intellij.MotifService +import motif.intellij.MotifService.Companion.TOOL_WINDOW_ID import motif.intellij.ScopeHierarchyUtils.Companion.getParentScopes import motif.intellij.ScopeHierarchyUtils.Companion.isInitializedGraph import motif.intellij.ScopeHierarchyUtils.Companion.isMotifScopeClass -import motif.intellij.analytics.AnalyticsProjectService +import motif.intellij.analytics.AnalyticsService import motif.intellij.analytics.MotifAnalyticsActions /* * {@AnAction} used to trigger displaying a particular scope ancestors hierarchy. */ -class MotifAncestorGraphAction : AnAction(), MotifProjectService.Listener { +class MotifAncestorGraphAction : AnAction(), MotifService.Listener { private var graph: ResolvedGraph? = null @@ -48,18 +48,18 @@ class MotifAncestorGraphAction : AnAction(), MotifProjectService.Listener { val graph = graph ?: return if (!isInitializedGraph(graph)) { - project.getService(MotifProjectService::class.java).refreshGraph { actionPerformed(event) } + project.getService(MotifService::class.java).refreshGraph { actionPerformed(event) } return } val toolWindow: ToolWindow = ToolWindowManager.getInstance(project).getToolWindow(TOOL_WINDOW_ID) ?: return toolWindow.activate { - project.getService(MotifProjectService::class.java).onSelectedAncestorScope(element) + project.getService(MotifService::class.java).onSelectedAncestorScope(element) } project - .getService(AnalyticsProjectService::class.java) + .getService(AnalyticsService::class.java) .logEvent(MotifAnalyticsActions.ANCESTOR_MENU_CLICK) } diff --git a/intellij/src/main/kotlin/motif/intellij/actions/MotifGraphAction.kt b/intellij/src/main/kotlin/motif/intellij/actions/MotifGraphAction.kt index 0fbbde2b..9f33ac99 100644 --- a/intellij/src/main/kotlin/motif/intellij/actions/MotifGraphAction.kt +++ b/intellij/src/main/kotlin/motif/intellij/actions/MotifGraphAction.kt @@ -20,16 +20,16 @@ import com.intellij.openapi.actionSystem.AnActionEvent import com.intellij.openapi.wm.ToolWindow import com.intellij.openapi.wm.ToolWindowManager import motif.core.ResolvedGraph -import motif.intellij.MotifProjectService -import motif.intellij.MotifProjectService.Companion.TOOL_WINDOW_ID +import motif.intellij.MotifService +import motif.intellij.MotifService.Companion.TOOL_WINDOW_ID import motif.intellij.ScopeHierarchyUtils.Companion.isInitializedGraph -import motif.intellij.analytics.AnalyticsProjectService +import motif.intellij.analytics.AnalyticsService import motif.intellij.analytics.MotifAnalyticsActions /* * {@AnAction} used to trigger displaying entire scope hierarchy. */ -class MotifGraphAction : AnAction(), MotifProjectService.Listener { +class MotifGraphAction : AnAction(), MotifService.Listener { private var graph: ResolvedGraph? = null @@ -42,7 +42,7 @@ class MotifGraphAction : AnAction(), MotifProjectService.Listener { val graph = graph ?: return if (!isInitializedGraph(graph)) { - project.getService(MotifProjectService::class.java).refreshGraph { actionPerformed(event) } + project.getService(MotifService::class.java).refreshGraph { actionPerformed(event) } return } @@ -51,7 +51,7 @@ class MotifGraphAction : AnAction(), MotifProjectService.Listener { toolWindow.activate {} project - .getService(AnalyticsProjectService::class.java) + .getService(AnalyticsService::class.java) .logEvent(MotifAnalyticsActions.GRAPH_MENU_CLICK) } diff --git a/intellij/src/main/kotlin/motif/intellij/actions/MotifUsageAction.kt b/intellij/src/main/kotlin/motif/intellij/actions/MotifUsageAction.kt index e5c85263..35392a60 100644 --- a/intellij/src/main/kotlin/motif/intellij/actions/MotifUsageAction.kt +++ b/intellij/src/main/kotlin/motif/intellij/actions/MotifUsageAction.kt @@ -23,17 +23,17 @@ import com.intellij.openapi.wm.ToolWindowManager import com.intellij.psi.PsiClass import com.intellij.psi.PsiElement import motif.core.ResolvedGraph -import motif.intellij.MotifProjectService -import motif.intellij.MotifProjectService.Companion.TOOL_WINDOW_ID +import motif.intellij.MotifService +import motif.intellij.MotifService.Companion.TOOL_WINDOW_ID import motif.intellij.ScopeHierarchyUtils import motif.intellij.ScopeHierarchyUtils.Companion.getUsageCount -import motif.intellij.analytics.AnalyticsProjectService +import motif.intellij.analytics.AnalyticsService import motif.intellij.analytics.MotifAnalyticsActions /* * {@AnAction} used to trigger navigation to a particular scope in the scope hierarchy window. */ -class MotifUsageAction : AnAction(), MotifProjectService.Listener { +class MotifUsageAction : AnAction(), MotifService.Listener { private var graph: ResolvedGraph? = null @@ -47,18 +47,16 @@ class MotifUsageAction : AnAction(), MotifProjectService.Listener { val graph = graph ?: return if (!ScopeHierarchyUtils.isInitializedGraph(graph)) { - project.getService(MotifProjectService::class.java).refreshGraph { actionPerformed(event) } + project.getService(MotifService::class.java).refreshGraph { actionPerformed(event) } return } val toolWindow: ToolWindow = ToolWindowManager.getInstance(project).getToolWindow(TOOL_WINDOW_ID) ?: return - toolWindow.activate { - project.getService(MotifProjectService::class.java).onSelectedClass(element) - } + toolWindow.activate { project.getService(MotifService::class.java).onSelectedClass(element) } project - .getService(AnalyticsProjectService::class.java) + .getService(AnalyticsService::class.java) .logEvent(MotifAnalyticsActions.USAGE_MENU_CLICK) } diff --git a/intellij/src/main/kotlin/motif/intellij/analytics/AnalyticsProjectService.kt b/intellij/src/main/kotlin/motif/intellij/analytics/AnalyticsService.kt similarity index 95% rename from intellij/src/main/kotlin/motif/intellij/analytics/AnalyticsProjectService.kt rename to intellij/src/main/kotlin/motif/intellij/analytics/AnalyticsService.kt index 62aba5f5..9b0848d3 100644 --- a/intellij/src/main/kotlin/motif/intellij/analytics/AnalyticsProjectService.kt +++ b/intellij/src/main/kotlin/motif/intellij/analytics/AnalyticsService.kt @@ -22,7 +22,7 @@ import com.intellij.openapi.project.Project import java.util.UUID @Service(Service.Level.PROJECT) -class AnalyticsProjectService(val project: Project) : Disposable { +class AnalyticsService(val project: Project) : Disposable { companion object { private val LOGGER_EXTENSION_POINT_NAME: ExtensionPointName = diff --git a/intellij/src/main/kotlin/motif/intellij/hierarchy/ErrorHierarchyBrowser.kt b/intellij/src/main/kotlin/motif/intellij/hierarchy/ErrorHierarchyBrowser.kt index 9a3ffd17..9fbf3ee3 100644 --- a/intellij/src/main/kotlin/motif/intellij/hierarchy/ErrorHierarchyBrowser.kt +++ b/intellij/src/main/kotlin/motif/intellij/hierarchy/ErrorHierarchyBrowser.kt @@ -33,7 +33,7 @@ import javax.swing.JTree import javax.swing.tree.DefaultMutableTreeNode import motif.core.ResolvedGraph import motif.errormessage.ErrorMessage -import motif.intellij.MotifProjectService +import motif.intellij.MotifService import motif.intellij.ScopeHierarchyUtils.Companion.isRootElement import motif.intellij.hierarchy.ScopeHierarchyBrowser.Companion.LABEL_GO_NEXT_SCOPE import motif.intellij.hierarchy.ScopeHierarchyBrowser.Companion.LABEL_GO_PREVIOUS_SCOPE @@ -49,7 +49,7 @@ class ErrorHierarchyBrowser( initialGraph: ResolvedGraph, private val rootElement: PsiElement, private val selectionListener: Listener? -) : HierarchyBrowserBase(project, rootElement), MotifProjectService.Listener { +) : HierarchyBrowserBase(project, rootElement), MotifService.Listener { private var graph: ResolvedGraph = initialGraph @@ -130,7 +130,7 @@ class ErrorHierarchyBrowser( } override fun doRefresh(currentBuilderOnly: Boolean) { - project.getService(MotifProjectService::class.java).refreshGraph() + project.getService(MotifService::class.java).refreshGraph() } override fun onGraphUpdated(graph: ResolvedGraph) { diff --git a/intellij/src/main/kotlin/motif/intellij/hierarchy/ScopeHierarchyBrowser.kt b/intellij/src/main/kotlin/motif/intellij/hierarchy/ScopeHierarchyBrowser.kt index 95bc83d8..6001f3fa 100644 --- a/intellij/src/main/kotlin/motif/intellij/hierarchy/ScopeHierarchyBrowser.kt +++ b/intellij/src/main/kotlin/motif/intellij/hierarchy/ScopeHierarchyBrowser.kt @@ -42,10 +42,10 @@ import motif.ast.IrType import motif.ast.intellij.IntelliJClass import motif.ast.intellij.IntelliJType import motif.core.ResolvedGraph -import motif.intellij.MotifProjectService +import motif.intellij.MotifService import motif.intellij.ScopeHierarchyUtils import motif.intellij.ScopeHierarchyUtils.Companion.isMotifScopeClass -import motif.intellij.analytics.AnalyticsProjectService +import motif.intellij.analytics.AnalyticsService import motif.intellij.analytics.MotifAnalyticsActions import motif.intellij.hierarchy.descriptor.ScopeHierarchyRootDescriptor import motif.intellij.hierarchy.descriptor.ScopeHierarchyScopeAncestorDescriptor @@ -60,7 +60,7 @@ class ScopeHierarchyBrowser( initialGraph: ResolvedGraph, private val rootElement: PsiElement, private val selectionListener: Listener? -) : HierarchyBrowserBase(project, rootElement), MotifProjectService.Listener { +) : HierarchyBrowserBase(project, rootElement), MotifService.Listener { companion object { const val LABEL_GO_PREVIOUS_SCOPE: String = "Go to previous Scope." @@ -189,12 +189,12 @@ class ScopeHierarchyBrowser( else -> {} } - project.getService(MotifProjectService::class.java).refreshGraph() + project.getService(MotifService::class.java).refreshGraph() val action: String = if (status == Status.INITIALIZING) MotifAnalyticsActions.GRAPH_INIT else MotifAnalyticsActions.GRAPH_UPDATE - project.getService(AnalyticsProjectService::class.java).logEvent(action) + project.getService(AnalyticsService::class.java).logEvent(action) } /* diff --git a/intellij/src/main/kotlin/motif/intellij/hierarchy/ScopePropertyHierarchyBrowser.kt b/intellij/src/main/kotlin/motif/intellij/hierarchy/ScopePropertyHierarchyBrowser.kt index 2847fda1..ae0b7159 100644 --- a/intellij/src/main/kotlin/motif/intellij/hierarchy/ScopePropertyHierarchyBrowser.kt +++ b/intellij/src/main/kotlin/motif/intellij/hierarchy/ScopePropertyHierarchyBrowser.kt @@ -41,7 +41,7 @@ import motif.ast.IrType import motif.ast.intellij.IntelliJClass import motif.ast.intellij.IntelliJType import motif.core.ResolvedGraph -import motif.intellij.MotifProjectService +import motif.intellij.MotifService import motif.intellij.ScopeHierarchyUtils.Companion.isMotifScopeClass import motif.intellij.hierarchy.ScopeHierarchyBrowser.Companion.LABEL_GO_NEXT_SCOPE import motif.intellij.hierarchy.ScopeHierarchyBrowser.Companion.LABEL_GO_PREVIOUS_SCOPE @@ -61,7 +61,7 @@ class ScopePropertyHierarchyBrowser( initialGraph: ResolvedGraph, private val rootElement: PsiElement, private val hierarchyType: PropertyHierarchyType -) : HierarchyBrowserBase(project, rootElement), MotifProjectService.Listener { +) : HierarchyBrowserBase(project, rootElement), MotifService.Listener { private var graph: ResolvedGraph = initialGraph diff --git a/intellij/src/main/kotlin/motif/intellij/hierarchy/UsageHierarchyBrowser.kt b/intellij/src/main/kotlin/motif/intellij/hierarchy/UsageHierarchyBrowser.kt index f537618e..3237ebf8 100644 --- a/intellij/src/main/kotlin/motif/intellij/hierarchy/UsageHierarchyBrowser.kt +++ b/intellij/src/main/kotlin/motif/intellij/hierarchy/UsageHierarchyBrowser.kt @@ -30,7 +30,7 @@ import java.text.MessageFormat import javax.swing.JPanel import javax.swing.JTree import motif.core.ResolvedGraph -import motif.intellij.MotifProjectService +import motif.intellij.MotifService import motif.intellij.hierarchy.ScopeHierarchyBrowser.Companion.LABEL_GO_NEXT_SCOPE import motif.intellij.hierarchy.ScopeHierarchyBrowser.Companion.LABEL_GO_PREVIOUS_SCOPE import motif.intellij.hierarchy.descriptor.ScopeHierarchyUsageSectionDescriptor @@ -42,7 +42,7 @@ class UsageHierarchyBrowser( project: Project, initialGraph: ResolvedGraph, private val rootElement: PsiElement -) : HierarchyBrowserBase(project, rootElement), MotifProjectService.Listener { +) : HierarchyBrowserBase(project, rootElement), MotifService.Listener { private var graph: ResolvedGraph = initialGraph diff --git a/intellij/src/main/kotlin/motif/intellij/provider/ScopeHierarchyLineMarkerProvider.kt b/intellij/src/main/kotlin/motif/intellij/provider/ScopeHierarchyLineMarkerProvider.kt index 5663298f..a54e0e1b 100644 --- a/intellij/src/main/kotlin/motif/intellij/provider/ScopeHierarchyLineMarkerProvider.kt +++ b/intellij/src/main/kotlin/motif/intellij/provider/ScopeHierarchyLineMarkerProvider.kt @@ -32,17 +32,17 @@ import com.intellij.psi.impl.source.PsiClassReferenceType import com.intellij.util.ConstantFunction import java.awt.event.MouseEvent import motif.core.ResolvedGraph -import motif.intellij.MotifProjectService -import motif.intellij.MotifProjectService.Companion.TOOL_WINDOW_ID +import motif.intellij.MotifService +import motif.intellij.MotifService.Companion.TOOL_WINDOW_ID import motif.intellij.ScopeHierarchyUtils.Companion.getParentScopes import motif.intellij.ScopeHierarchyUtils.Companion.isMotifScopeClass -import motif.intellij.analytics.AnalyticsProjectService +import motif.intellij.analytics.AnalyticsService import motif.intellij.analytics.MotifAnalyticsActions /* * {@LineMarkerProvider} used to display icon in gutter to navigate to motif scope ancestors hierarchy. */ -class ScopeHierarchyLineMarkerProvider : LineMarkerProvider, MotifProjectService.Listener { +class ScopeHierarchyLineMarkerProvider : LineMarkerProvider, MotifService.Listener { companion object { const val LABEL_ANCESTORS_SCOPE: String = "View Scope Ancestors." @@ -83,21 +83,19 @@ class ScopeHierarchyLineMarkerProvider : LineMarkerProvider, MotifProjectService ToolWindowManager.getInstance(project).getToolWindow(TOOL_WINDOW_ID) ?: return if (element is PsiClass) { toolWindow.activate { - project.getService(MotifProjectService::class.java).onSelectedAncestorScope(element) + project.getService(MotifService::class.java).onSelectedAncestorScope(element) } } else if (element is PsiMethod) { if (element.returnType is PsiClassReferenceType) { val returnElementClass: PsiClass = (element.returnType as PsiClassReferenceType).resolve() ?: return toolWindow.activate { - project - .getService(MotifProjectService::class.java) - .onSelectedAncestorScope(returnElementClass) + project.getService(MotifService::class.java).onSelectedAncestorScope(returnElementClass) } } } project - .getService(AnalyticsProjectService::class.java) + .getService(AnalyticsService::class.java) .logEvent(MotifAnalyticsActions.ANCESTOR_GUTTER_CLICK) } } diff --git a/intellij/src/main/kotlin/motif/intellij/provider/ScopeNavigationLineMarkerProvider.kt b/intellij/src/main/kotlin/motif/intellij/provider/ScopeNavigationLineMarkerProvider.kt index 8219066a..b1883155 100644 --- a/intellij/src/main/kotlin/motif/intellij/provider/ScopeNavigationLineMarkerProvider.kt +++ b/intellij/src/main/kotlin/motif/intellij/provider/ScopeNavigationLineMarkerProvider.kt @@ -40,11 +40,11 @@ import java.awt.event.MouseEvent import motif.ast.intellij.IntelliJClass import motif.core.ResolvedGraph import motif.core.ScopeEdge -import motif.intellij.MotifProjectService +import motif.intellij.MotifService import motif.intellij.ScopeHierarchyUtils.Companion.getParentScopes import motif.intellij.ScopeHierarchyUtils.Companion.isMotifChildScopeMethod import motif.intellij.ScopeHierarchyUtils.Companion.isMotifScopeClass -import motif.intellij.analytics.AnalyticsProjectService +import motif.intellij.analytics.AnalyticsService import motif.intellij.analytics.MotifAnalyticsActions import motif.intellij.toPsiClass import motif.intellij.toPsiMethod @@ -52,7 +52,7 @@ import motif.intellij.toPsiMethod /* * {@LineMarkerProvider} used to display navigation icons in gutter to navigate to parent/children of Motif scopes. */ -class ScopeNavigationLineMarkerProvider : LineMarkerProvider, MotifProjectService.Listener { +class ScopeNavigationLineMarkerProvider : LineMarkerProvider, MotifService.Listener { companion object { const val LABEL_NAVIGATE_PARENT_SCOPE: String = "Navigate to parent Scope." @@ -158,7 +158,7 @@ class ScopeNavigationLineMarkerProvider : LineMarkerProvider, MotifProjectServic } } project - .getService(AnalyticsProjectService::class.java) + .getService(AnalyticsService::class.java) .logEvent(MotifAnalyticsActions.NAVIGATION_GUTTER_CLICK) } diff --git a/intellij/src/main/kotlin/motif/intellij/ui/MotifErrorPanel.kt b/intellij/src/main/kotlin/motif/intellij/ui/MotifErrorPanel.kt index dfcffe51..58770d64 100644 --- a/intellij/src/main/kotlin/motif/intellij/ui/MotifErrorPanel.kt +++ b/intellij/src/main/kotlin/motif/intellij/ui/MotifErrorPanel.kt @@ -23,13 +23,13 @@ import javax.swing.JSplitPane import javax.swing.JTextArea import motif.core.ResolvedGraph import motif.errormessage.ErrorMessage -import motif.intellij.MotifProjectService +import motif.intellij.MotifService import motif.intellij.ScopeHierarchyUtils import motif.intellij.hierarchy.ErrorHierarchyBrowser import motif.models.MotifError class MotifErrorPanel(project: Project, graph: ResolvedGraph) : - JPanel(), MotifProjectService.Listener, ErrorHierarchyBrowser.Listener { + JPanel(), MotifService.Listener, ErrorHierarchyBrowser.Listener { private val splitPane: JSplitPane private val errorBrowser: ErrorHierarchyBrowser diff --git a/intellij/src/main/kotlin/motif/intellij/ui/MotifScopePanel.kt b/intellij/src/main/kotlin/motif/intellij/ui/MotifScopePanel.kt index ddc50319..ff443477 100644 --- a/intellij/src/main/kotlin/motif/intellij/ui/MotifScopePanel.kt +++ b/intellij/src/main/kotlin/motif/intellij/ui/MotifScopePanel.kt @@ -24,7 +24,7 @@ import javax.swing.JPanel import javax.swing.JSplitPane import javax.swing.JSplitPane.RIGHT import motif.core.ResolvedGraph -import motif.intellij.MotifProjectService +import motif.intellij.MotifService import motif.intellij.ScopeHierarchyUtils import motif.intellij.hierarchy.ScopeHierarchyBrowser import motif.intellij.hierarchy.ScopePropertyHierarchyBrowser @@ -32,7 +32,7 @@ import motif.intellij.hierarchy.ScopePropertyHierarchyBrowser.PropertyHierarchyT import motif.models.Scope class MotifScopePanel(val project: Project, initialGraph: ResolvedGraph) : - JPanel(), ScopeHierarchyBrowser.Listener, MotifProjectService.Listener { + JPanel(), ScopeHierarchyBrowser.Listener, MotifService.Listener { private var graph: ResolvedGraph = initialGraph diff --git a/intellij/src/main/kotlin/motif/intellij/ui/MotifUsagePanel.kt b/intellij/src/main/kotlin/motif/intellij/ui/MotifUsagePanel.kt index 1804cb4f..5c312f51 100644 --- a/intellij/src/main/kotlin/motif/intellij/ui/MotifUsagePanel.kt +++ b/intellij/src/main/kotlin/motif/intellij/ui/MotifUsagePanel.kt @@ -21,12 +21,11 @@ import com.intellij.psi.PsiElement import java.awt.BorderLayout import javax.swing.JPanel import motif.core.ResolvedGraph -import motif.intellij.MotifProjectService +import motif.intellij.MotifService import motif.intellij.ScopeHierarchyUtils import motif.intellij.hierarchy.UsageHierarchyBrowser -class MotifUsagePanel(project: Project, graph: ResolvedGraph) : - JPanel(), MotifProjectService.Listener { +class MotifUsagePanel(project: Project, graph: ResolvedGraph) : JPanel(), MotifService.Listener { private val usageBrowser: UsageHierarchyBrowser diff --git a/intellij/src/main/resources/META-INF/plugin.xml b/intellij/src/main/resources/META-INF/plugin.xml index 81e9066f..e49bd34a 100644 --- a/intellij/src/main/resources/META-INF/plugin.xml +++ b/intellij/src/main/resources/META-INF/plugin.xml @@ -31,7 +31,7 @@ com.intellij.modules.lang - + From dfbe85696405bfd5f12fd616facd8b2c414f467f Mon Sep 17 00:00:00 2001 From: daviss Date: Thu, 12 Oct 2023 10:57:11 -0700 Subject: [PATCH 31/56] fix various stuff found during plugin test * prefer Uber Motif to make plugin easier to identify * fix null pointer exception for icon load --- intellij/src/main/kotlin/motif/intellij/MotifService.kt | 3 +-- intellij/src/main/resources/META-INF/plugin.xml | 2 +- 2 files changed, 2 insertions(+), 3 deletions(-) diff --git a/intellij/src/main/kotlin/motif/intellij/MotifService.kt b/intellij/src/main/kotlin/motif/intellij/MotifService.kt index cfb1adf7..cea7ec95 100644 --- a/intellij/src/main/kotlin/motif/intellij/MotifService.kt +++ b/intellij/src/main/kotlin/motif/intellij/MotifService.kt @@ -37,7 +37,6 @@ import com.intellij.psi.PsiClass import com.intellij.psi.PsiElement import com.intellij.ui.content.Content import com.intellij.ui.content.ContentFactory -import javax.swing.Icon import motif.core.ResolvedGraph import motif.intellij.analytics.AnalyticsService import motif.intellij.analytics.MotifAnalyticsActions @@ -169,7 +168,7 @@ class MotifService(val project: Project) : Disposable { if (toolWindowManager.getToolWindow(TOOL_WINDOW_ID) == null) { val toolWindow: ToolWindow = toolWindowManager.registerToolWindow(TOOL_WINDOW_ID, true, ToolWindowAnchor.RIGHT) - toolWindow.setIcon(IconLoader.getIcon("/icons/icon.svg", Icon::class.java)) + toolWindow.setIcon(IconLoader.getIcon("/icons/icon.svg", this::class.java)) toolWindow.title = TOOL_WINDOW_TITLE scopePanel = MotifScopePanel(project, graph) diff --git a/intellij/src/main/resources/META-INF/plugin.xml b/intellij/src/main/resources/META-INF/plugin.xml index e49bd34a..f1b5da87 100644 --- a/intellij/src/main/resources/META-INF/plugin.xml +++ b/intellij/src/main/resources/META-INF/plugin.xml @@ -1,6 +1,6 @@ com.uber.motif - Motif + Uber Motif 0.0.5 Uber From c3e6f51d5646f98692c36795a0463fe341352335 Mon Sep 17 00:00:00 2001 From: daviss Date: Tue, 17 Oct 2023 15:33:39 -0700 Subject: [PATCH 32/56] remove rule that skips test We did a partial removal in an earlier commit and unintentionally made the TestHarness skip its tests. This commit removes the rule altogether and fixes the setUp/tearDown calls by removing the annotation (annotation not needed), see https://github.com/JetBrains/intellij-community/blob/master/platform/testFramework/src/com/intellij/testFramework/UsefulTestCase.java#L91 --- intellij/ast/build.gradle | 1 - intellij/build.gradle | 1 - .../test/kotlin/motif/intellij/TestHarness.kt | 13 -------- intellij/testing/build.gradle | 21 ------------ .../motif/intellij/testing/IntelliJRule.kt | 33 ------------------- settings.gradle | 1 - 6 files changed, 70 deletions(-) delete mode 100644 intellij/testing/build.gradle delete mode 100644 intellij/testing/src/main/kotlin/motif/intellij/testing/IntelliJRule.kt diff --git a/intellij/ast/build.gradle b/intellij/ast/build.gradle index 348011d7..2ff5f97d 100644 --- a/intellij/ast/build.gradle +++ b/intellij/ast/build.gradle @@ -27,7 +27,6 @@ dependencies { testImplementation deps.test.junit testImplementation deps.test.assertj testImplementation deps.test.truth - testImplementation project(':intellij:testing') } tasks { diff --git a/intellij/build.gradle b/intellij/build.gradle index 34be84e9..94215cac 100644 --- a/intellij/build.gradle +++ b/intellij/build.gradle @@ -28,7 +28,6 @@ dependencies { implementation deps.kotlin.reflection testImplementation deps.test.truth - testImplementation project(':intellij:testing') testImplementation project(':viewmodel') } diff --git a/intellij/src/test/kotlin/motif/intellij/TestHarness.kt b/intellij/src/test/kotlin/motif/intellij/TestHarness.kt index c6f88c91..2e0ba1aa 100644 --- a/intellij/src/test/kotlin/motif/intellij/TestHarness.kt +++ b/intellij/src/test/kotlin/motif/intellij/TestHarness.kt @@ -30,39 +30,26 @@ import kotlin.reflect.KClass import motif.Scope import motif.core.ResolvedGraph import motif.errormessage.ErrorMessage -import motif.intellij.testing.IntelliJRule import motif.viewmodel.TestRenderer -import org.junit.After -import org.junit.Before -import org.junit.Rule import org.junit.Test import org.junit.runner.RunWith @RunWith(Parameterized::class) class TestHarness : LightJavaCodeInsightFixtureTestCase() { - @get:Rule val rule = IntelliJRule() - @org.junit.runners.Parameterized.Parameter(0) lateinit var testDir: File override fun getProjectDescriptor() = DefaultLightProjectDescriptor { JavaAwareProjectJdkTableImpl.getInstanceEx().internalJdk } - @Before public override fun setUp() { super.setUp() - addLibrary(Inject::class) addLibrary(Scope::class) addLibrary(Nullable::class) } - @After - public override fun tearDown() { - super.tearDown() - } - private fun addLibrary(clazz: KClass<*>) { val fileUri = clazz diff --git a/intellij/testing/build.gradle b/intellij/testing/build.gradle deleted file mode 100644 index a1df613e..00000000 --- a/intellij/testing/build.gradle +++ /dev/null @@ -1,21 +0,0 @@ -plugins { - id "org.jetbrains.intellij" - id 'org.jetbrains.kotlin.jvm' -} - -intellij { - version = deps.versions.gradleIntellijPlugin.ide - plugins = [ 'java', 'Kotlin' ] - pluginName = 'Motif Plugin' - updateSinceUntilBuild = false -} - -dependencies { - implementation deps.test.truth -} - -tasks { - buildSearchableOptions { - enabled = false - } -} diff --git a/intellij/testing/src/main/kotlin/motif/intellij/testing/IntelliJRule.kt b/intellij/testing/src/main/kotlin/motif/intellij/testing/IntelliJRule.kt deleted file mode 100644 index b50a56d3..00000000 --- a/intellij/testing/src/main/kotlin/motif/intellij/testing/IntelliJRule.kt +++ /dev/null @@ -1,33 +0,0 @@ -/* - * Copyright (c) 2018-2019 Uber Technologies, Inc. - * - * 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 motif.intellij.testing - -import com.intellij.testFramework.TestApplicationManager -import org.junit.rules.TestRule -import org.junit.runner.Description -import org.junit.runners.model.Statement - -class IntelliJRule : TestRule { - - override fun apply(base: Statement, description: Description): Statement { - return object : Statement() { - - override fun evaluate() { - TestApplicationManager.getInstance() - } - } - } -} diff --git a/settings.gradle b/settings.gradle index ee6526e1..99f710c5 100644 --- a/settings.gradle +++ b/settings.gradle @@ -40,7 +40,6 @@ include 'samples:sample-kotlin-ksp' include 'samples:dagger-comparison' include 'intellij' include 'intellij-ast' -include 'intellij:testing' include 'core' include 'errormessage' include 'models' From 8327d8ba33778f013905735552c8119fb56a380b Mon Sep 17 00:00:00 2001 From: daviss Date: Fri, 20 Oct 2023 17:01:25 -0700 Subject: [PATCH 33/56] clean up build script 1. setting the jvm target in a more succinct way 2. avoid noisy build due to spotless depending on its own output https://github.com/diffplug/spotless/issues/870#issuecomment-851726260 --- build.gradle | 8 ++++---- intellij/ast/build.gradle | 6 ++---- intellij/build.gradle | 6 ++---- 3 files changed, 8 insertions(+), 12 deletions(-) diff --git a/build.gradle b/build.gradle index a0ec1818..a63c4f3d 100644 --- a/build.gradle +++ b/build.gradle @@ -74,13 +74,13 @@ subprojects { apply plugin: 'com.diffplug.spotless' spotless { format 'misc', { - target '**/*.md', '**/.gitignore' + target '*.md', '.gitignore' trimTrailingWhitespace() endWithNewline() } kotlin { - target "**/*.kt" + target "src/**/*.kt" ktlint(deps.versions.ktlint).userData(['indent_size': '2', 'continuation_indent_size': '2']) ktfmt(deps.versions.ktfmt) licenseHeaderFile rootProject.file('config/spotless/copyright.kt') @@ -88,7 +88,7 @@ subprojects { endWithNewline() } java { - target "**/*.java" + target "src/**/*.java" googleJavaFormat(deps.versions.gjf) licenseHeaderFile rootProject.file('config/spotless/copyright.java') removeUnusedImports() @@ -96,7 +96,7 @@ subprojects { endWithNewline() } groovyGradle { - target '**/*.gradle' + target '*.gradle' trimTrailingWhitespace() endWithNewline() } diff --git a/intellij/ast/build.gradle b/intellij/ast/build.gradle index 2ff5f97d..6ffafded 100644 --- a/intellij/ast/build.gradle +++ b/intellij/ast/build.gradle @@ -11,10 +11,8 @@ intellij { updateSinceUntilBuild = false } -java { - toolchain { - languageVersion.set(JavaLanguageVersion.of(17)) - } +kotlin { + jvmToolchain(17) } dependencies { diff --git a/intellij/build.gradle b/intellij/build.gradle index 94215cac..a9b28868 100644 --- a/intellij/build.gradle +++ b/intellij/build.gradle @@ -11,10 +11,8 @@ intellij { updateSinceUntilBuild = false } -java { - toolchain { - languageVersion.set(JavaLanguageVersion.of(17)) - } +kotlin { + jvmToolchain(17) } group 'com.uber.motif' From dc43c4ad557d6d976403ccd01588b5659dc7c85a Mon Sep 17 00:00:00 2001 From: daviss Date: Fri, 20 Oct 2023 16:27:06 -0700 Subject: [PATCH 34/56] bump gradle version to match This commit is to keep the build somewhat in line with RIBs and other uber open source projects --- ast/build.gradle | 4 +++- compiler/ast/build.gradle | 5 +++-- compiler/build.gradle | 4 +++- compiler/ksp/build.gradle | 4 +++- core/build.gradle | 4 +++- errormessage/build.gradle | 5 +++-- gradle/dependencies.gradle | 4 ++-- gradle/wrapper/gradle-wrapper.properties | 2 +- models/build.gradle | 5 +++-- samples/sample-kotlin-ksp/build.gradle | 8 ++++++-- samples/sample-kotlin/build.gradle | 8 ++++++-- samples/sample-lib-ksp/build.gradle | 8 ++++++-- tests/build.gradle | 4 +++- tests/compiler/build.gradle | 4 +++- viewmodel/build.gradle | 4 +++- xprocessing-testing/build.gradle | 2 +- xprocessing/build.gradle | 2 +- 17 files changed, 53 insertions(+), 24 deletions(-) diff --git a/ast/build.gradle b/ast/build.gradle index 800c2361..500b41b9 100644 --- a/ast/build.gradle +++ b/ast/build.gradle @@ -5,7 +5,9 @@ plugins { apply plugin: 'kotlin-kapt' -sourceCompatibility = 1.8 +kotlin { + jvmToolchain(11) +} dependencies { implementation deps.kotlin.stdlib diff --git a/compiler/ast/build.gradle b/compiler/ast/build.gradle index df0669ad..f3da3e79 100644 --- a/compiler/ast/build.gradle +++ b/compiler/ast/build.gradle @@ -5,8 +5,9 @@ plugins { apply plugin: 'kotlin-kapt' -sourceCompatibility = 1.8 - +kotlin { + jvmToolchain(11) +} dependencies { implementation deps.kotlin.stdlib diff --git a/compiler/build.gradle b/compiler/build.gradle index 768ca945..55242027 100644 --- a/compiler/build.gradle +++ b/compiler/build.gradle @@ -3,7 +3,9 @@ plugins { id 'org.jetbrains.dokka' } -sourceCompatibility = 1.8 +kotlin { + jvmToolchain(11) +} dependencies { implementation deps.kotlin.stdlib diff --git a/compiler/ksp/build.gradle b/compiler/ksp/build.gradle index 660d1c69..c058e0ab 100644 --- a/compiler/ksp/build.gradle +++ b/compiler/ksp/build.gradle @@ -2,7 +2,9 @@ plugins { id 'org.jetbrains.kotlin.jvm' } -sourceCompatibility = 1.8 +kotlin { + jvmToolchain(11) +} dependencies { implementation deps.kotlin.stdlib diff --git a/core/build.gradle b/core/build.gradle index c1eba4b3..427d7511 100644 --- a/core/build.gradle +++ b/core/build.gradle @@ -3,7 +3,9 @@ plugins { id 'org.jetbrains.dokka' } -sourceCompatibility = 1.8 +kotlin { + jvmToolchain(11) +} dependencies { api project(':models') diff --git a/errormessage/build.gradle b/errormessage/build.gradle index eda0a098..303e39e4 100644 --- a/errormessage/build.gradle +++ b/errormessage/build.gradle @@ -3,8 +3,9 @@ plugins { id 'org.jetbrains.dokka' } -sourceCompatibility = 1.8 - +kotlin { + jvmToolchain(11) +} dependencies { implementation deps.kotlin.stdlib diff --git a/gradle/dependencies.gradle b/gradle/dependencies.gradle index c2b0f3ce..08290f26 100644 --- a/gradle/dependencies.gradle +++ b/gradle/dependencies.gradle @@ -42,13 +42,13 @@ ext.deps = [ targetSdkVersion: 30, gradlePlugins: [ - android: 'com.android.tools.build:gradle:4.2.0', + android: 'com.android.tools.build:gradle:7.4.2', kotlin: "org.jetbrains.kotlin:kotlin-gradle-plugin:${versions.kotlin}", ksp: "com.google.devtools.ksp:com.google.devtools.ksp.gradle.plugin:${versions.ksp}", dokka: "org.jetbrains.dokka:dokka-gradle-plugin:${versions.dokka}", mavenPublish: 'com.vanniktech:gradle-maven-publish-plugin:0.18.0', spotless: "com.diffplug.spotless:spotless-plugin-gradle:5.11.0", - shadow: "com.github.jengelman.gradle.plugins:shadow:6.1.0", + shadow: "com.github.johnrengelman:shadow:8.1.0", ] ], "kotlin": [ diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties index 070cb702..1f017e4e 100644 --- a/gradle/wrapper/gradle-wrapper.properties +++ b/gradle/wrapper/gradle-wrapper.properties @@ -1,5 +1,5 @@ distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-7.6-bin.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-8.1.1-all.zip zipStoreBase=GRADLE_USER_HOME zipStorePath=wrapper/dists diff --git a/models/build.gradle b/models/build.gradle index 7ec1c7b1..5c803e05 100644 --- a/models/build.gradle +++ b/models/build.gradle @@ -5,8 +5,9 @@ plugins { apply plugin: 'kotlin-kapt' -sourceCompatibility = 1.8 - +kotlin { + jvmToolchain(11) +} dependencies { api project(':ast') diff --git a/samples/sample-kotlin-ksp/build.gradle b/samples/sample-kotlin-ksp/build.gradle index fd8cdecf..fef42637 100644 --- a/samples/sample-kotlin-ksp/build.gradle +++ b/samples/sample-kotlin-ksp/build.gradle @@ -4,6 +4,10 @@ plugins { id 'org.jetbrains.kotlin.android' } +kotlin { + jvmToolchain(11) +} + android { compileSdkVersion deps.build.compileSdkVersion buildToolsVersion deps.build.buildToolsVersion @@ -26,8 +30,8 @@ android { } compileOptions { - sourceCompatibility JavaVersion.VERSION_1_8 - targetCompatibility JavaVersion.VERSION_1_8 + sourceCompatibility JavaVersion.VERSION_11 + targetCompatibility JavaVersion.VERSION_11 } variantFilter { variant -> diff --git a/samples/sample-kotlin/build.gradle b/samples/sample-kotlin/build.gradle index d3a8bca6..7eb7dbe5 100644 --- a/samples/sample-kotlin/build.gradle +++ b/samples/sample-kotlin/build.gradle @@ -4,6 +4,10 @@ plugins { apply plugin: 'kotlin-android' apply plugin: 'kotlin-kapt' +kotlin { + jvmToolchain(11) +} + android { compileSdkVersion deps.build.compileSdkVersion buildToolsVersion deps.build.buildToolsVersion @@ -25,8 +29,8 @@ android { } compileOptions { - sourceCompatibility JavaVersion.VERSION_1_8 - targetCompatibility JavaVersion.VERSION_1_8 + sourceCompatibility JavaVersion.VERSION_11 + targetCompatibility JavaVersion.VERSION_11 } variantFilter { variant -> diff --git a/samples/sample-lib-ksp/build.gradle b/samples/sample-lib-ksp/build.gradle index 8d5b1cb9..6975623f 100644 --- a/samples/sample-lib-ksp/build.gradle +++ b/samples/sample-lib-ksp/build.gradle @@ -4,6 +4,10 @@ plugins { id 'org.jetbrains.kotlin.android' } +kotlin { + jvmToolchain(11) +} + android { namespace 'com.example.sample_lib_ksp' compileSdkVersion deps.build.compileSdkVersion @@ -26,8 +30,8 @@ android { } compileOptions { - sourceCompatibility JavaVersion.VERSION_1_8 - targetCompatibility JavaVersion.VERSION_1_8 + sourceCompatibility JavaVersion.VERSION_11 + targetCompatibility JavaVersion.VERSION_11 } androidComponents { diff --git a/tests/build.gradle b/tests/build.gradle index 0b5a6326..d136e573 100644 --- a/tests/build.gradle +++ b/tests/build.gradle @@ -6,7 +6,9 @@ apply plugin: 'java-library' apply plugin: 'kotlin' apply plugin: 'kotlin-kapt' -sourceCompatibility = 1.8 +kotlin { + jvmToolchain(11) +} kotlin { sourceSets { diff --git a/tests/compiler/build.gradle b/tests/compiler/build.gradle index 7e1404fb..640c8f4e 100644 --- a/tests/compiler/build.gradle +++ b/tests/compiler/build.gradle @@ -2,7 +2,9 @@ plugins { id 'org.jetbrains.kotlin.jvm' } -sourceCompatibility = 1.8 +kotlin { + jvmToolchain(11) +} dependencies { implementation deps.autoCommon diff --git a/viewmodel/build.gradle b/viewmodel/build.gradle index 386cacda..af186cc9 100644 --- a/viewmodel/build.gradle +++ b/viewmodel/build.gradle @@ -3,7 +3,9 @@ plugins { id 'org.jetbrains.dokka' } -sourceCompatibility = 1.8 +kotlin { + jvmToolchain(11) +} dependencies { api project(':core') diff --git a/xprocessing-testing/build.gradle b/xprocessing-testing/build.gradle index 2985bfd5..499c4622 100644 --- a/xprocessing-testing/build.gradle +++ b/xprocessing-testing/build.gradle @@ -21,7 +21,7 @@ shadowJar { dependencies { include dependency(deps.test.roomCompilerProcessingTesting) } - classifier = '' + archiveClassifier = '' configurations = [shadedConfig] mergeServiceFiles() relocate 'androidx.room.compiler.processing', 'motif.compiler.processing' diff --git a/xprocessing/build.gradle b/xprocessing/build.gradle index 2e4e8383..f3c6b18e 100644 --- a/xprocessing/build.gradle +++ b/xprocessing/build.gradle @@ -21,7 +21,7 @@ shadowJar { dependencies { include dependency(deps.roomCompilerProcessing) } - classifier = '' + archiveClassifier = '' configurations = [shadedConfig] mergeServiceFiles() relocate 'androidx.room.compiler.processing', 'motif.compiler.processing' From 93c4d872f94f92d9096f7cbc5ee2388a4c87bc8b Mon Sep 17 00:00:00 2001 From: daviss Date: Fri, 20 Oct 2023 17:27:49 -0700 Subject: [PATCH 35/56] avoid apply plugin Thie commit prefers the slightly newer style of gradle plugin specification --- ast/build.gradle | 6 ++---- compiler/ast/build.gradle | 6 ++---- compiler/build.gradle | 3 +-- compiler/ksp/build.gradle | 3 +-- core/build.gradle | 3 +-- errormessage/build.gradle | 3 +-- intellij/ast/build.gradle | 3 +-- intellij/build.gradle | 3 +-- lib/build.gradle | 7 ++++--- models/build.gradle | 6 ++---- samples/sample-kotlin/build.gradle | 4 ++-- tests/build.gradle | 7 +++---- viewmodel/build.gradle | 3 +-- xprocessing-testing/build.gradle | 3 +-- xprocessing/build.gradle | 3 +-- 15 files changed, 24 insertions(+), 39 deletions(-) diff --git a/ast/build.gradle b/ast/build.gradle index 500b41b9..d9b77331 100644 --- a/ast/build.gradle +++ b/ast/build.gradle @@ -1,10 +1,10 @@ plugins { id 'org.jetbrains.kotlin.jvm' id 'org.jetbrains.dokka' + id 'kotlin-kapt' + id 'com.vanniktech.maven.publish' } -apply plugin: 'kotlin-kapt' - kotlin { jvmToolchain(11) } @@ -16,5 +16,3 @@ dependencies { testImplementation deps.test.junit testImplementation deps.test.truth } - -apply plugin: 'com.vanniktech.maven.publish' diff --git a/compiler/ast/build.gradle b/compiler/ast/build.gradle index f3da3e79..72594665 100644 --- a/compiler/ast/build.gradle +++ b/compiler/ast/build.gradle @@ -1,10 +1,10 @@ plugins { id 'org.jetbrains.kotlin.jvm' id 'org.jetbrains.dokka' + id 'kotlin-kapt' + id 'com.vanniktech.maven.publish' } -apply plugin: 'kotlin-kapt' - kotlin { jvmToolchain(11) } @@ -23,5 +23,3 @@ dependencies { testImplementation deps.test.compileTesting testImplementation deps.test.roomCompilerProcessingTesting } - -apply plugin: 'com.vanniktech.maven.publish' diff --git a/compiler/build.gradle b/compiler/build.gradle index 55242027..9898e8ce 100644 --- a/compiler/build.gradle +++ b/compiler/build.gradle @@ -1,6 +1,7 @@ plugins { id 'org.jetbrains.kotlin.jvm' id 'org.jetbrains.dokka' + id 'com.vanniktech.maven.publish' } kotlin { @@ -37,5 +38,3 @@ dependencies { test { inputs.files(file("$rootDir/tests/src")) } - -apply plugin: 'com.vanniktech.maven.publish' diff --git a/compiler/ksp/build.gradle b/compiler/ksp/build.gradle index c058e0ab..50c907d7 100644 --- a/compiler/ksp/build.gradle +++ b/compiler/ksp/build.gradle @@ -1,5 +1,6 @@ plugins { id 'org.jetbrains.kotlin.jvm' + id 'com.vanniktech.maven.publish' } kotlin { @@ -29,5 +30,3 @@ dependencies { testImplementation deps.test.compileTesting testImplementation deps.test.compileTestingKotlin } - -apply plugin: 'com.vanniktech.maven.publish' diff --git a/core/build.gradle b/core/build.gradle index 427d7511..54698cdb 100644 --- a/core/build.gradle +++ b/core/build.gradle @@ -1,6 +1,7 @@ plugins { id 'org.jetbrains.kotlin.jvm' id 'org.jetbrains.dokka' + id 'com.vanniktech.maven.publish' } kotlin { @@ -12,5 +13,3 @@ dependencies { implementation deps.kotlin.stdlib } - -apply plugin: 'com.vanniktech.maven.publish' diff --git a/errormessage/build.gradle b/errormessage/build.gradle index 303e39e4..15eefe39 100644 --- a/errormessage/build.gradle +++ b/errormessage/build.gradle @@ -1,6 +1,7 @@ plugins { id 'org.jetbrains.kotlin.jvm' id 'org.jetbrains.dokka' + id 'com.vanniktech.maven.publish' } kotlin { @@ -11,5 +12,3 @@ dependencies { implementation deps.kotlin.stdlib implementation project(':core') } - -apply plugin: 'com.vanniktech.maven.publish' diff --git a/intellij/ast/build.gradle b/intellij/ast/build.gradle index 6ffafded..be8451fe 100644 --- a/intellij/ast/build.gradle +++ b/intellij/ast/build.gradle @@ -2,6 +2,7 @@ plugins { id "org.jetbrains.intellij" version "1.15.0" id 'org.jetbrains.kotlin.jvm' id 'org.jetbrains.dokka' + id 'com.vanniktech.maven.publish' } intellij { @@ -32,5 +33,3 @@ tasks { enabled = false } } - -apply plugin: 'com.vanniktech.maven.publish' diff --git a/intellij/build.gradle b/intellij/build.gradle index a9b28868..8f347d89 100644 --- a/intellij/build.gradle +++ b/intellij/build.gradle @@ -2,6 +2,7 @@ plugins { id "org.jetbrains.intellij" version "1.15.0" id 'org.jetbrains.kotlin.jvm' id 'org.jetbrains.dokka' + id 'com.vanniktech.maven.publish' } intellij { @@ -42,5 +43,3 @@ tasks { enabled = false } } - -apply plugin: 'com.vanniktech.maven.publish' diff --git a/lib/build.gradle b/lib/build.gradle index 016a1b67..e5b5bc47 100644 --- a/lib/build.gradle +++ b/lib/build.gradle @@ -1,4 +1,7 @@ -apply plugin: 'java-library' +plugins { + id 'java-library' + id 'com.vanniktech.maven.publish' +} sourceCompatibility = 1.8 targetCompatibility = 1.8 @@ -7,5 +10,3 @@ dependencies { // Dagger is part of the API since we generate code which depends on Dagger's API in the consuming gradle module. api deps.dagger } - -apply plugin: 'com.vanniktech.maven.publish' diff --git a/models/build.gradle b/models/build.gradle index 5c803e05..4f244380 100644 --- a/models/build.gradle +++ b/models/build.gradle @@ -1,10 +1,10 @@ plugins { id 'org.jetbrains.kotlin.jvm' id 'org.jetbrains.dokka' + id 'kotlin-kapt' + id 'com.vanniktech.maven.publish' } -apply plugin: 'kotlin-kapt' - kotlin { jvmToolchain(11) } @@ -20,5 +20,3 @@ dependencies { testImplementation deps.test.truth testImplementation deps.test.compileTesting } - -apply plugin: 'com.vanniktech.maven.publish' diff --git a/samples/sample-kotlin/build.gradle b/samples/sample-kotlin/build.gradle index 7eb7dbe5..bedc5f63 100644 --- a/samples/sample-kotlin/build.gradle +++ b/samples/sample-kotlin/build.gradle @@ -1,8 +1,8 @@ plugins { id 'com.android.application' + id 'kotlin-android' + id 'kotlin-kapt' } -apply plugin: 'kotlin-android' -apply plugin: 'kotlin-kapt' kotlin { jvmToolchain(11) diff --git a/tests/build.gradle b/tests/build.gradle index d136e573..840b3db7 100644 --- a/tests/build.gradle +++ b/tests/build.gradle @@ -1,11 +1,10 @@ plugins { id 'com.google.devtools.ksp' + id 'java-library' + id 'kotlin' + id 'kotlin-kapt' } -apply plugin: 'java-library' -apply plugin: 'kotlin' -apply plugin: 'kotlin-kapt' - kotlin { jvmToolchain(11) } diff --git a/viewmodel/build.gradle b/viewmodel/build.gradle index af186cc9..96283119 100644 --- a/viewmodel/build.gradle +++ b/viewmodel/build.gradle @@ -1,6 +1,7 @@ plugins { id 'org.jetbrains.kotlin.jvm' id 'org.jetbrains.dokka' + id 'com.vanniktech.maven.publish' } kotlin { @@ -14,5 +15,3 @@ dependencies { implementation deps.kotlin.stdlib } - -apply plugin: 'com.vanniktech.maven.publish' diff --git a/xprocessing-testing/build.gradle b/xprocessing-testing/build.gradle index 499c4622..75c06fb6 100644 --- a/xprocessing-testing/build.gradle +++ b/xprocessing-testing/build.gradle @@ -1,6 +1,7 @@ plugins { id 'java' id 'com.github.johnrengelman.shadow' + id 'com.vanniktech.maven.publish' } java { @@ -43,5 +44,3 @@ artifacts { runtimeOnly shadowJar archives shadowJar } - -apply plugin: "com.vanniktech.maven.publish" diff --git a/xprocessing/build.gradle b/xprocessing/build.gradle index f3c6b18e..41eb88c7 100644 --- a/xprocessing/build.gradle +++ b/xprocessing/build.gradle @@ -1,6 +1,7 @@ plugins { id 'java' id 'com.github.johnrengelman.shadow' + id 'com.vanniktech.maven.publish' } java { @@ -43,5 +44,3 @@ artifacts { runtimeOnly shadowJar archives shadowJar } - -apply plugin: "com.vanniktech.maven.publish" From ab27a1d6e191a29ca7c31b8dc38a04e0a313e94c Mon Sep 17 00:00:00 2001 From: daviss Date: Fri, 27 Oct 2023 11:11:35 -0700 Subject: [PATCH 36/56] pass in resolved type info This avoids the infinite poetry in https://github.com/uber/motif/issues/255 --- .../main/kotlin/motif/compiler/XFunSpec.kt | 28 +++------ .../testcases/KT006_reference_self/Child.kt | 24 ++++++++ .../testcases/KT006_reference_self/Foo.kt | 22 +++++++ .../testcases/KT006_reference_self/GRAPH.txt | 57 +++++++++++++++++++ .../testcases/KT006_reference_self/Scope.kt | 31 ++++++++++ .../testcases/KT006_reference_self/Test.java | 26 +++++++++ 6 files changed, 168 insertions(+), 20 deletions(-) create mode 100644 tests/src/main/java/testcases/KT006_reference_self/Child.kt create mode 100644 tests/src/main/java/testcases/KT006_reference_self/Foo.kt create mode 100644 tests/src/main/java/testcases/KT006_reference_self/GRAPH.txt create mode 100644 tests/src/main/java/testcases/KT006_reference_self/Scope.kt create mode 100644 tests/src/main/java/testcases/KT006_reference_self/Test.java diff --git a/compiler/src/main/kotlin/motif/compiler/XFunSpec.kt b/compiler/src/main/kotlin/motif/compiler/XFunSpec.kt index 22547fca..8ce264d5 100644 --- a/compiler/src/main/kotlin/motif/compiler/XFunSpec.kt +++ b/compiler/src/main/kotlin/motif/compiler/XFunSpec.kt @@ -23,13 +23,10 @@ import com.squareup.kotlinpoet.AnnotationSpec import com.squareup.kotlinpoet.FunSpec import com.squareup.kotlinpoet.KModifier import com.squareup.kotlinpoet.ParameterSpec -import com.squareup.kotlinpoet.javapoet.KotlinPoetJavaPoetPreview -import com.squareup.kotlinpoet.javapoet.toKTypeName import com.uber.xprocessing.ext.modifiers import javax.lang.model.element.Modifier import motif.compiler.KotlinTypeWorkaround.javaToKotlinType -@OptIn(KotlinPoetJavaPoetPreview::class) object XFunSpec { /** Copied from [FunSpec.overriding] and modified to leverage [javaToKotlinType]& XProcessing. */ fun overriding( @@ -50,23 +47,13 @@ object XFunSpec { env.requireType(method.returnType.typeName) } - val builder = overriding(methodElement) - builder.returns(javaToKotlinType(returnType)) - - var i = 0 - val size = builder.parameters.size - val resolvedParameterTypes = method.parameterTypes - while (i < size) { - val parameter = builder.parameters[i] - val type = javaToKotlinType(resolvedParameterTypes[i]) - builder.parameters[i] = parameter.toBuilder(parameter.name, type).build() - i++ - } - - return builder + return overriding(methodElement, method.parameterTypes).returns(javaToKotlinType(returnType)) } - private fun overriding(method: XMethodElement): FunSpec.Builder { + private fun overriding( + method: XMethodElement, + resolvedParameterTypes: List + ): FunSpec.Builder { var modifiers: Set = method.modifiers.toMutableSet() require( Modifier.PRIVATE !in modifiers && @@ -90,9 +77,10 @@ object XFunSpec { .forEach { funBuilder.addTypeVariable(it) } */ - method.parameters.forEach { + method.parameters.forEachIndexed { index, parameter -> funBuilder.addParameter( - ParameterSpec.builder(it.name, it.type.typeName.toKTypeName()).build()) + ParameterSpec.builder(parameter.name, javaToKotlinType(resolvedParameterTypes[index])) + .build()) } if (method.isVarArgs()) { funBuilder.parameters[funBuilder.parameters.lastIndex] = diff --git a/tests/src/main/java/testcases/KT006_reference_self/Child.kt b/tests/src/main/java/testcases/KT006_reference_self/Child.kt new file mode 100644 index 00000000..0ccfeed6 --- /dev/null +++ b/tests/src/main/java/testcases/KT006_reference_self/Child.kt @@ -0,0 +1,24 @@ +/* + * Copyright (c) 2023 Uber Technologies, Inc. + * + * 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 testcases.KT006_reference_self + +@motif.Scope +interface Child { + + @motif.Objects + abstract class Objects : ObjectComponent + +} \ No newline at end of file diff --git a/tests/src/main/java/testcases/KT006_reference_self/Foo.kt b/tests/src/main/java/testcases/KT006_reference_self/Foo.kt new file mode 100644 index 00000000..b68ef420 --- /dev/null +++ b/tests/src/main/java/testcases/KT006_reference_self/Foo.kt @@ -0,0 +1,22 @@ +/* + * Copyright (c) 2023 Uber Technologies, Inc. + * + * 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 testcases.KT006_reference_self + +interface Foo +class Bar : Foo +interface ObjectComponent> { + fun generic(someFoo: T): Foo +} \ No newline at end of file diff --git a/tests/src/main/java/testcases/KT006_reference_self/GRAPH.txt b/tests/src/main/java/testcases/KT006_reference_self/GRAPH.txt new file mode 100644 index 00000000..33bc45a4 --- /dev/null +++ b/tests/src/main/java/testcases/KT006_reference_self/GRAPH.txt @@ -0,0 +1,57 @@ +######################################################################## +# # +# This file is auto-generated by running the Motif compiler tests and # +# serves a as validation of graph correctness. IntelliJ plugin tests # +# also rely on this file to ensure that the plugin graph understanding # +# is equivalent to the compiler's. # +# # +# - Do not edit manually. # +# - Commit changes to source control. # +# - Since this file is autogenerated, code review changes carefully to # +# ensure correctness. # +# # +######################################################################## + + ------- +| Scope | + ------- + + ==== Required ==== + + ==== Provides ==== + + ---- Bar | Objects.bar ---- + [ Required ] + [ Consumed By ] + * Child | Objects.generic(someFoo) + + ---- Scope | implicit ---- + [ Required ] + [ Consumed By ] + + ------- + | Child | + ------- + + ==== Required ==== + + ---- Bar ---- + [ Provided By ] + * Scope | Objects.bar + [ Consumed By ] + * Child | Objects.generic(someFoo) + + ==== Provides ==== + + ---- Child | implicit ---- + [ Required ] + [ Consumed By ] + + ---- Foo | Objects.generic ---- + [ Required ] + Bar + [ Provided By ] + * Scope | Objects.bar + [ Consumed By ] + + diff --git a/tests/src/main/java/testcases/KT006_reference_self/Scope.kt b/tests/src/main/java/testcases/KT006_reference_self/Scope.kt new file mode 100644 index 00000000..6138d23c --- /dev/null +++ b/tests/src/main/java/testcases/KT006_reference_self/Scope.kt @@ -0,0 +1,31 @@ +/* + * Copyright (c) 2023 Uber Technologies, Inc. + * + * 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 testcases.KT006_reference_self + +import motif.Expose + +@motif.Scope +interface Scope { + + fun child(): Child + + @motif.Objects + abstract class Objects { + + @Expose + fun bar(): Bar = Bar() + } +} \ No newline at end of file diff --git a/tests/src/main/java/testcases/KT006_reference_self/Test.java b/tests/src/main/java/testcases/KT006_reference_self/Test.java new file mode 100644 index 00000000..21ed2131 --- /dev/null +++ b/tests/src/main/java/testcases/KT006_reference_self/Test.java @@ -0,0 +1,26 @@ +/* + * Copyright (c) 2023 Uber Technologies, Inc. + * + * 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 testcases.KT006_reference_self; + +import static com.google.common.truth.Truth.assertThat; + +public class Test { + + public static void run() { + Scope scope = new ScopeImpl(); + assertThat(scope.child()).isNotNull(); + } +} From 6a7863d06605d61588bd27e3611b1f37cc9351ce Mon Sep 17 00:00:00 2001 From: daviss Date: Fri, 3 Nov 2023 12:22:05 -0700 Subject: [PATCH 37/56] remove unused kapt plugin directive These modules don't seem to use kapt in the gradle. More importantly, having those lines prevented dokka from completing due to gradle complaining about task dependencies when trying to publish the change to local maven --- ast/build.gradle | 1 - compiler/ast/build.gradle | 1 - models/build.gradle | 1 - 3 files changed, 3 deletions(-) diff --git a/ast/build.gradle b/ast/build.gradle index d9b77331..8814d457 100644 --- a/ast/build.gradle +++ b/ast/build.gradle @@ -1,7 +1,6 @@ plugins { id 'org.jetbrains.kotlin.jvm' id 'org.jetbrains.dokka' - id 'kotlin-kapt' id 'com.vanniktech.maven.publish' } diff --git a/compiler/ast/build.gradle b/compiler/ast/build.gradle index 72594665..2000d89a 100644 --- a/compiler/ast/build.gradle +++ b/compiler/ast/build.gradle @@ -1,7 +1,6 @@ plugins { id 'org.jetbrains.kotlin.jvm' id 'org.jetbrains.dokka' - id 'kotlin-kapt' id 'com.vanniktech.maven.publish' } diff --git a/models/build.gradle b/models/build.gradle index 4f244380..9bc86355 100644 --- a/models/build.gradle +++ b/models/build.gradle @@ -1,7 +1,6 @@ plugins { id 'org.jetbrains.kotlin.jvm' id 'org.jetbrains.dokka' - id 'kotlin-kapt' id 'com.vanniktech.maven.publish' } From dfb9036ba9f5366bdecfa40ae02f62d4b4ba1c58 Mon Sep 17 00:00:00 2001 From: daviss Date: Thu, 2 Nov 2023 14:47:28 -0700 Subject: [PATCH 38/56] check for explicit dependencies While determining whether to create a no-arg convenience constructor, we check for both explicit (creatable) dependencies in addition to unsatisfied sinks to avoid generating incompatible code --- .../kotlin/motif/compiler/ScopeImplFactory.kt | 3 +- .../GRAPH.txt | 27 +++++++++++++++ .../KT007_scope_factory_dependencies/Scope.kt | 26 ++++++++++++++ .../Test.java | 34 +++++++++++++++++++ .../config.pro | 10 ++++++ 5 files changed, 99 insertions(+), 1 deletion(-) create mode 100644 tests/src/main/java/testcases/KT007_scope_factory_dependencies/GRAPH.txt create mode 100644 tests/src/main/java/testcases/KT007_scope_factory_dependencies/Scope.kt create mode 100644 tests/src/main/java/testcases/KT007_scope_factory_dependencies/Test.java create mode 100644 tests/src/main/java/testcases/KT007_scope_factory_dependencies/config.pro diff --git a/compiler/src/main/kotlin/motif/compiler/ScopeImplFactory.kt b/compiler/src/main/kotlin/motif/compiler/ScopeImplFactory.kt index 12b71b9c..c730e70c 100644 --- a/compiler/src/main/kotlin/motif/compiler/ScopeImplFactory.kt +++ b/compiler/src/main/kotlin/motif/compiler/ScopeImplFactory.kt @@ -109,7 +109,8 @@ private constructor(private val env: XProcessingEnv, private val graph: Resolved } private fun alternateConstructor(): AlternateConstructor? { - if (getDependencyMethodData(scope).isNotEmpty()) { + if (getDependencyMethodData(scope).isNotEmpty() || + !scope.dependencies?.methods.isNullOrEmpty()) { return null } return AlternateConstructor(scope.dependenciesClassName) diff --git a/tests/src/main/java/testcases/KT007_scope_factory_dependencies/GRAPH.txt b/tests/src/main/java/testcases/KT007_scope_factory_dependencies/GRAPH.txt new file mode 100644 index 00000000..550c4318 --- /dev/null +++ b/tests/src/main/java/testcases/KT007_scope_factory_dependencies/GRAPH.txt @@ -0,0 +1,27 @@ +######################################################################## +# # +# This file is auto-generated by running the Motif compiler tests and # +# serves a as validation of graph correctness. IntelliJ plugin tests # +# also rely on this file to ensure that the plugin graph understanding # +# is equivalent to the compiler's. # +# # +# - Do not edit manually. # +# - Commit changes to source control. # +# - Since this file is autogenerated, code review changes carefully to # +# ensure correctness. # +# # +######################################################################## + + ------- +| Scope | + ------- + + ==== Required ==== + + ==== Provides ==== + + ---- Scope | implicit ---- + [ Required ] + [ Consumed By ] + + diff --git a/tests/src/main/java/testcases/KT007_scope_factory_dependencies/Scope.kt b/tests/src/main/java/testcases/KT007_scope_factory_dependencies/Scope.kt new file mode 100644 index 00000000..f0304f89 --- /dev/null +++ b/tests/src/main/java/testcases/KT007_scope_factory_dependencies/Scope.kt @@ -0,0 +1,26 @@ +/* + * Copyright (c) 2023 Uber Technologies, Inc. + * + * 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 testcases.KT007_scope_factory_dependencies + +import motif.Creatable + +@motif.Scope +interface Scope : Creatable { + // note the absence of string() accessor (e.g. sink) in this scope + interface Dependencies { + fun string(): String + } +} \ No newline at end of file diff --git a/tests/src/main/java/testcases/KT007_scope_factory_dependencies/Test.java b/tests/src/main/java/testcases/KT007_scope_factory_dependencies/Test.java new file mode 100644 index 00000000..ba3c02bf --- /dev/null +++ b/tests/src/main/java/testcases/KT007_scope_factory_dependencies/Test.java @@ -0,0 +1,34 @@ +/* + * Copyright (c) 2023 Uber Technologies, Inc. + * + * 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 testcases.KT007_scope_factory_dependencies; + +import motif.ScopeFactory; +import org.jetbrains.annotations.NotNull; + +public class Test { + + public static void run() { + ScopeFactory.create( + Scope.class, new Scope.Dependencies() { + @NotNull + @Override + public String string() { + return "s"; + } + } + ); + } +} diff --git a/tests/src/main/java/testcases/KT007_scope_factory_dependencies/config.pro b/tests/src/main/java/testcases/KT007_scope_factory_dependencies/config.pro new file mode 100644 index 00000000..8d56db15 --- /dev/null +++ b/tests/src/main/java/testcases/KT007_scope_factory_dependencies/config.pro @@ -0,0 +1,10 @@ +-libraryjars /jmods/java.base.jmod(!**.jar;!module-info.class) +-dontshrink +-keep class **Test { + public static void run(); +} + +-keepnames @motif.Scope interface * +-keepnames @motif.ScopeImpl class * { + (...); +} \ No newline at end of file From c39a4ab41d662bf5463bfe212eca78fc9ddda136 Mon Sep 17 00:00:00 2001 From: daviss Date: Wed, 6 Mar 2024 11:43:58 -0800 Subject: [PATCH 39/56] update dokka to support new kotlin --- ast/build.gradle | 1 - build.gradle | 9 +++++++++ compiler/ast/build.gradle | 1 - compiler/build.gradle | 1 - core/build.gradle | 1 - errormessage/build.gradle | 1 - gradle/dependencies.gradle | 4 ++-- intellij/ast/build.gradle | 1 - intellij/build.gradle | 1 - models/build.gradle | 1 - viewmodel/build.gradle | 1 - 11 files changed, 11 insertions(+), 11 deletions(-) diff --git a/ast/build.gradle b/ast/build.gradle index 8814d457..545b5298 100644 --- a/ast/build.gradle +++ b/ast/build.gradle @@ -1,6 +1,5 @@ plugins { id 'org.jetbrains.kotlin.jvm' - id 'org.jetbrains.dokka' id 'com.vanniktech.maven.publish' } diff --git a/build.gradle b/build.gradle index a63c4f3d..130a8b63 100644 --- a/build.gradle +++ b/build.gradle @@ -1,3 +1,5 @@ +import org.jetbrains.dokka.gradle.DokkaTaskPartial + // https://github.com/gradle/gradle/issues/4848 gradle.startParameter.configureOnDemand = false @@ -102,4 +104,11 @@ subprojects { } } } + + apply plugin: 'org.jetbrains.dokka' + tasks.withType(DokkaTaskPartial).configureEach { + outputDirectory.set(new File(buildDir, "docs/partial")) + moduleName.set(project.property("POM_ARTIFACT_ID").toString()) + moduleVersion.set(project.property("VERSION_NAME").toString()) + } } diff --git a/compiler/ast/build.gradle b/compiler/ast/build.gradle index 2000d89a..0c3fa969 100644 --- a/compiler/ast/build.gradle +++ b/compiler/ast/build.gradle @@ -1,6 +1,5 @@ plugins { id 'org.jetbrains.kotlin.jvm' - id 'org.jetbrains.dokka' id 'com.vanniktech.maven.publish' } diff --git a/compiler/build.gradle b/compiler/build.gradle index 9898e8ce..0fc9e26f 100644 --- a/compiler/build.gradle +++ b/compiler/build.gradle @@ -1,6 +1,5 @@ plugins { id 'org.jetbrains.kotlin.jvm' - id 'org.jetbrains.dokka' id 'com.vanniktech.maven.publish' } diff --git a/core/build.gradle b/core/build.gradle index 54698cdb..db139530 100644 --- a/core/build.gradle +++ b/core/build.gradle @@ -1,6 +1,5 @@ plugins { id 'org.jetbrains.kotlin.jvm' - id 'org.jetbrains.dokka' id 'com.vanniktech.maven.publish' } diff --git a/errormessage/build.gradle b/errormessage/build.gradle index 15eefe39..2ea5385a 100644 --- a/errormessage/build.gradle +++ b/errormessage/build.gradle @@ -1,6 +1,5 @@ plugins { id 'org.jetbrains.kotlin.jvm' - id 'org.jetbrains.dokka' id 'com.vanniktech.maven.publish' } diff --git a/gradle/dependencies.gradle b/gradle/dependencies.gradle index 08290f26..ba434d4f 100644 --- a/gradle/dependencies.gradle +++ b/gradle/dependencies.gradle @@ -26,7 +26,7 @@ def versions = [ kotlinpoet: '1.12.0', room: '2.1.0', roomCompilerProcessing: '2.6.0-alpha02', - dokka: '1.4.32', + dokka: '1.9.10', "gradleIntellijPlugin": [ ide: '2023.2' ], @@ -46,7 +46,7 @@ ext.deps = [ kotlin: "org.jetbrains.kotlin:kotlin-gradle-plugin:${versions.kotlin}", ksp: "com.google.devtools.ksp:com.google.devtools.ksp.gradle.plugin:${versions.ksp}", dokka: "org.jetbrains.dokka:dokka-gradle-plugin:${versions.dokka}", - mavenPublish: 'com.vanniktech:gradle-maven-publish-plugin:0.18.0', + mavenPublish: 'com.vanniktech:gradle-maven-publish-plugin:0.27.0', spotless: "com.diffplug.spotless:spotless-plugin-gradle:5.11.0", shadow: "com.github.johnrengelman:shadow:8.1.0", ] diff --git a/intellij/ast/build.gradle b/intellij/ast/build.gradle index be8451fe..e68379ca 100644 --- a/intellij/ast/build.gradle +++ b/intellij/ast/build.gradle @@ -1,7 +1,6 @@ plugins { id "org.jetbrains.intellij" version "1.15.0" id 'org.jetbrains.kotlin.jvm' - id 'org.jetbrains.dokka' id 'com.vanniktech.maven.publish' } diff --git a/intellij/build.gradle b/intellij/build.gradle index 8f347d89..244a0e5c 100644 --- a/intellij/build.gradle +++ b/intellij/build.gradle @@ -1,7 +1,6 @@ plugins { id "org.jetbrains.intellij" version "1.15.0" id 'org.jetbrains.kotlin.jvm' - id 'org.jetbrains.dokka' id 'com.vanniktech.maven.publish' } diff --git a/models/build.gradle b/models/build.gradle index 9bc86355..98718cc7 100644 --- a/models/build.gradle +++ b/models/build.gradle @@ -1,6 +1,5 @@ plugins { id 'org.jetbrains.kotlin.jvm' - id 'org.jetbrains.dokka' id 'com.vanniktech.maven.publish' } diff --git a/viewmodel/build.gradle b/viewmodel/build.gradle index 96283119..3cb2f4d8 100644 --- a/viewmodel/build.gradle +++ b/viewmodel/build.gradle @@ -1,6 +1,5 @@ plugins { id 'org.jetbrains.kotlin.jvm' - id 'org.jetbrains.dokka' id 'com.vanniktech.maven.publish' } From e3edd84b4ffab9b8454bb7b03d412af5e884e2a2 Mon Sep 17 00:00:00 2001 From: daviss Date: Wed, 13 Dec 2023 16:03:50 -0800 Subject: [PATCH 40/56] Clean various compile warnings The most important ones being the changes in IntelliJType.kt; the old ones are marked for removal. --- .../test/kotlin/motif/ast/SimpleNameTest.kt | 2 +- .../com/uber/xprocessing/ext/XOverrides.kt | 6 +- .../kotlin/com/uber/xprocessing/ext/XType.kt | 2 +- .../src/main/kotlin/motif/compiler/Names.kt | 33 +-- .../src/test/java/motif/compiler/NamesTest.kt | 2 +- .../test/java/motif/compiler/TestHarness.kt | 18 +- .../ScopeExtendsScopeMethodHandler.kt | 2 +- .../kotlin/motif/ast/intellij/IntelliJType.kt | 20 +- .../motif/intellij/ScopeHierarchyUtils.kt | 265 +++++++++--------- .../actions/MotifAncestorGraphAction.kt | 6 +- .../intellij/actions/MotifGraphAction.kt | 2 +- .../intellij/actions/MotifUsageAction.kt | 2 +- .../analytics/MotifAnalyticsActions.kt | 26 +- .../hierarchy/ErrorHierarchyBrowser.kt | 2 +- .../hierarchy/ScopeHierarchyBrowser.kt | 2 +- .../hierarchy/ScopeHierarchyTreeStructure.kt | 14 +- .../ScopePropertyHierarchyBrowser.kt | 2 +- .../ScopeHierarchyDependencyDescriptor.kt | 2 +- .../ScopeHierarchyScopeDescriptor.kt | 2 +- .../ScopeHierarchySinkDetailsDescriptor.kt | 2 +- .../ScopeHierarchySourceDescriptor.kt | 2 +- .../ScopeHierarchySourceDetailsDescriptor.kt | 2 +- ...erarchySourcesAndSinksSectionDescriptor.kt | 2 +- .../ScopeHierarchySourcesSectionDescriptor.kt | 2 +- .../ScopeHierarchyUsageSectionDescriptor.kt | 4 +- ...opeHierarchyUsageSinksSectionDescriptor.kt | 4 +- ...eHierarchyUsageSourcesSectionDescriptor.kt | 4 +- .../ScopeHierarchyLineMarkerProvider.kt | 4 +- .../ScopeNavigationLineMarkerProvider.kt | 6 +- .../E057_scope_extends_scope/ERROR.txt | 2 +- .../ERROR.txt | 2 +- 31 files changed, 214 insertions(+), 232 deletions(-) diff --git a/ast/src/test/kotlin/motif/ast/SimpleNameTest.kt b/ast/src/test/kotlin/motif/ast/SimpleNameTest.kt index 8345554b..61efab06 100644 --- a/ast/src/test/kotlin/motif/ast/SimpleNameTest.kt +++ b/ast/src/test/kotlin/motif/ast/SimpleNameTest.kt @@ -38,7 +38,7 @@ class SimpleNameTest(private val qualifiedName: String, private val expectedSimp @JvmStatic @Parameterized.Parameters(name = "{0}") fun data(): Collection> { - return tests.map { (key, value) -> arrayOf(key, value) } + return tests.map { (key, value) -> arrayOf(key, value) } } } diff --git a/compiler/ast/src/main/kotlin/com/uber/xprocessing/ext/XOverrides.kt b/compiler/ast/src/main/kotlin/com/uber/xprocessing/ext/XOverrides.kt index 799da720..38be1a3f 100644 --- a/compiler/ast/src/main/kotlin/com/uber/xprocessing/ext/XOverrides.kt +++ b/compiler/ast/src/main/kotlin/com/uber/xprocessing/ext/XOverrides.kt @@ -105,8 +105,7 @@ object XOverrides { // one that declares the same method, and check that we haven't reached mA. We compare // the enclosing elements rather than the methods themselves for the reason described // at the start of the method. - var inherited: XMethodElement? = null - (inherited != null && overridden.enclosingElement != inherited.enclosingElement) + false } else if (overriddenType?.isInterface() == true) { // ...overrides from C another method mI declared in interface I. We've already checked // the conditions (assuming that the only alternative to mI being abstract or default is @@ -121,8 +120,7 @@ object XOverrides { // to `overriddenType` (or the several paths if there are several) and apply similar logic // to methodFromSuperclasses above. if (overrider.isAbstract()) { - var inherited: XMethodElement? = null - (inherited != null && overridden.enclosingElement != inherited.enclosingElement) + false } else { true } diff --git a/compiler/ast/src/main/kotlin/com/uber/xprocessing/ext/XType.kt b/compiler/ast/src/main/kotlin/com/uber/xprocessing/ext/XType.kt index 261291b9..d35c2bd4 100644 --- a/compiler/ast/src/main/kotlin/com/uber/xprocessing/ext/XType.kt +++ b/compiler/ast/src/main/kotlin/com/uber/xprocessing/ext/XType.kt @@ -304,7 +304,7 @@ fun XType.isDeclaredType(): Boolean { } fun XType.isEnum(): Boolean { - return typeElement?.let { it.isEnum() } ?: false + return typeElement?.isEnum() ?: false } fun XType.isPrimitive(): Boolean { diff --git a/compiler/src/main/kotlin/motif/compiler/Names.kt b/compiler/src/main/kotlin/motif/compiler/Names.kt index 49fac078..70f3bcd6 100644 --- a/compiler/src/main/kotlin/motif/compiler/Names.kt +++ b/compiler/src/main/kotlin/motif/compiler/Names.kt @@ -46,27 +46,24 @@ private class UniqueNameSet(blacklist: Iterable) { } } -class Names { +object Names { - companion object { - - @JvmStatic - fun safeName(typeMirror: XType, annotation: XAnnotation?): String { - var name = XNameVisitor.visit(typeMirror) - val annotationString = annotationString(annotation) - name = "$annotationString$name".decapitalize() - if (name in KEYWORDS) { - name += "_" - } - return name + @JvmStatic + fun safeName(typeMirror: XType, annotation: XAnnotation?): String { + var name = XNameVisitor.visit(typeMirror) + val annotationString = annotationString(annotation) + name = "$annotationString$name".decapitalize() + if (name in KEYWORDS) { + name += "_" } + return name + } - private fun annotationString(annotation: XAnnotation?): String { - return if (annotation?.qualifiedName == "javax.inject.Named") { - annotation.getAnnotationValue("value").value.toString() - } else { - annotation?.type?.typeElement?.name.orEmpty() - } + private fun annotationString(annotation: XAnnotation?): String { + return if (annotation?.qualifiedName == "javax.inject.Named") { + annotation.getAnnotationValue("value").value.toString() + } else { + annotation?.type?.typeElement?.name.orEmpty() } } } diff --git a/compiler/src/test/java/motif/compiler/NamesTest.kt b/compiler/src/test/java/motif/compiler/NamesTest.kt index 448f1b3b..5969a992 100644 --- a/compiler/src/test/java/motif/compiler/NamesTest.kt +++ b/compiler/src/test/java/motif/compiler/NamesTest.kt @@ -24,7 +24,7 @@ import com.google.common.collect.Sets.cartesianProduct import com.google.common.truth.Truth.assertThat import com.squareup.javapoet.ClassName import javax.inject.Qualifier -import motif.compiler.Names.Companion.safeName +import motif.compiler.Names.safeName import org.junit.Test import org.junit.runner.RunWith import org.junit.runners.Parameterized diff --git a/compiler/src/test/java/motif/compiler/TestHarness.kt b/compiler/src/test/java/motif/compiler/TestHarness.kt index 0eabbeee..cab63526 100644 --- a/compiler/src/test/java/motif/compiler/TestHarness.kt +++ b/compiler/src/test/java/motif/compiler/TestHarness.kt @@ -90,7 +90,7 @@ class TestHarness( // We don't generate Java from KSP proc == ProcessorType.KSP && mode == OutputMode.JAVA } - .filterNot { (proc, mode, dir, name) -> + .filterNot { (proc, _, _, name) -> // Can't run KSP on Java sources until fixed: https://github.com/google/ksp/issues/1086 proc == ProcessorType.KSP && "$name"[0] in setOf('T', 'E') } @@ -98,7 +98,6 @@ class TestHarness( testFilter(proc as ProcessorType, mode as OutputMode, dir as File, name as String) } .map { it.toTypedArray() as Array } - .toList() } private fun isTestDir(file: File): Boolean { @@ -119,7 +118,7 @@ class TestHarness( ProcessorType.AP -> annotationProcessor?.graph ProcessorType.KSP -> symbolProcessorProvider?.graph } - ?: throw IllegalStateException("No graph found during processing") + checkNotNull(graph) { "No graph found during processing" } if (isErrorTest) { runErrorTest(result, graph) @@ -139,7 +138,7 @@ class TestHarness( if (externalClassesDirs.isEmpty()) { URLClassLoader(arrayOf(proguardedClasses.toURI().toURL()), javaClass.classLoader) - } else {} + } val testClass = classLoader.loadClass(testClassName) if (testClass.getAnnotation(Ignore::class.java) == null) { @@ -173,7 +172,7 @@ class TestHarness( symbolProcessorProvider: SymbolProcessorProvider?, classpath: List = emptyList() ): TestCompilationResult { - val processorOptions = mapOf("motif.mode" to outputMode.name.toLowerCase()) + val processorOptions = mapOf("motif.mode" to outputMode.name.lowercase()) val sources = getFiles(sourcesDir).asSources() val annotationProcessors = annotationProcessor?.let { listOf(it, ComponentProcessor()) } ?: emptyList() @@ -359,12 +358,7 @@ class TestHarness( internal fun File.listFilesRecursively() = walkTopDown().filter { it.isFile }.toList() -private fun TestCompilationResult.success() = success - private fun TestCompilationResult.messages(): String { - return diagnostics[Diagnostic.Kind.ERROR] - .orEmpty() - .flatMap { it.msg.lines() } - .map { " $it" } - .joinToString(separator = "\n") + return diagnostics[Diagnostic.Kind.ERROR].orEmpty().flatMap { it.msg.lines() }.joinToString( + separator = "\n") { " $it" } } diff --git a/errormessage/src/main/kotlin/motif/errormessage/ScopeExtendsScopeMethodHandler.kt b/errormessage/src/main/kotlin/motif/errormessage/ScopeExtendsScopeMethodHandler.kt index 830820f0..2e8aa513 100644 --- a/errormessage/src/main/kotlin/motif/errormessage/ScopeExtendsScopeMethodHandler.kt +++ b/errormessage/src/main/kotlin/motif/errormessage/ScopeExtendsScopeMethodHandler.kt @@ -24,7 +24,7 @@ class ScopeExtendsScopeMethodHandler(private val error: ScopeExtendsScope) : Err override fun StringBuilder.handle() { appendLine( """ - Scopes can't extend other Scopes: + Scope can't extend other Scopes: ${error.scope.qualifiedName} """.trimIndent()) diff --git a/intellij/ast/src/main/kotlin/motif/ast/intellij/IntelliJType.kt b/intellij/ast/src/main/kotlin/motif/ast/intellij/IntelliJType.kt index 42304caf..110f602a 100644 --- a/intellij/ast/src/main/kotlin/motif/ast/intellij/IntelliJType.kt +++ b/intellij/ast/src/main/kotlin/motif/ast/intellij/IntelliJType.kt @@ -19,10 +19,10 @@ import com.intellij.openapi.project.Project import com.intellij.psi.GenericsUtil import com.intellij.psi.PsiClassType import com.intellij.psi.PsiType +import com.intellij.psi.PsiTypes import com.intellij.psi.util.TypeConversionUtil import kotlin.jvm.javaClass import kotlin.let -import kotlin.text.contains import motif.ast.IrClass import motif.ast.IrType @@ -32,18 +32,18 @@ class IntelliJType(private val project: Project, val psiType: PsiType) : IrType GenericsUtil.getVariableTypeByExpressionType(psiType).getCanonicalText(false) } - override val isVoid: Boolean by lazy { psiType == PsiType.VOID } + override val isVoid: Boolean by lazy { psiType == PsiTypes.voidType() } override val isPrimitive: Boolean by lazy { when (psiType) { - PsiType.BOOLEAN, - PsiType.BYTE, - PsiType.SHORT, - PsiType.INT, - PsiType.LONG, - PsiType.CHAR, - PsiType.FLOAT, - PsiType.DOUBLE -> true + PsiTypes.booleanType(), + PsiTypes.byteType(), + PsiTypes.shortType(), + PsiTypes.intType(), + PsiTypes.longType(), + PsiTypes.charType(), + PsiTypes.floatType(), + PsiTypes.doubleType() -> true else -> false } } diff --git a/intellij/src/main/kotlin/motif/intellij/ScopeHierarchyUtils.kt b/intellij/src/main/kotlin/motif/intellij/ScopeHierarchyUtils.kt index 23300d0f..d46a6170 100644 --- a/intellij/src/main/kotlin/motif/intellij/ScopeHierarchyUtils.kt +++ b/intellij/src/main/kotlin/motif/intellij/ScopeHierarchyUtils.kt @@ -37,172 +37,167 @@ import motif.models.ScopeSource import motif.models.Sink import motif.models.Source -class ScopeHierarchyUtils { +object ScopeHierarchyUtils { - companion object { - - object ScopeComparator : Comparator { - override fun compare(o1: Scope, o2: Scope): Int { - return o1.simpleName.compareTo(o2.simpleName) - } + object ScopeComparator : Comparator { + override fun compare(o1: Scope, o2: Scope): Int { + return o1.simpleName.compareTo(o2.simpleName) } + } - object ScopeEdgeParentComparator : Comparator { - override fun compare(o1: ScopeEdge, o2: ScopeEdge): Int { - return o1.parent.simpleName.compareTo(o2.parent.simpleName) - } + object ScopeEdgeParentComparator : Comparator { + override fun compare(o1: ScopeEdge, o2: ScopeEdge): Int { + return o1.parent.simpleName.compareTo(o2.parent.simpleName) } + } - object ScopeEdgeChildComparator : Comparator { - override fun compare(o1: ScopeEdge, o2: ScopeEdge): Int { - return o1.child.simpleName.compareTo(o2.child.simpleName) - } + object ScopeEdgeChildComparator : Comparator { + override fun compare(o1: ScopeEdge, o2: ScopeEdge): Int { + return o1.child.simpleName.compareTo(o2.child.simpleName) } + } - object SourceComparator : Comparator { - override fun compare(o1: Source, o2: Source): Int { - if (o1.isExposed != o2.isExposed) return o1.isExposed.compareTo(o2.isExposed) * -1 - return o1.type.simpleName.compareTo(o2.type.simpleName) - } + object SourceComparator : Comparator { + override fun compare(o1: Source, o2: Source): Int { + if (o1.isExposed != o2.isExposed) return o1.isExposed.compareTo(o2.isExposed) * -1 + return o1.type.simpleName.compareTo(o2.type.simpleName) } + } - object SinkComparator : Comparator { - override fun compare(o1: Sink, o2: Sink): Int { - return o1.type.simpleName.compareTo(o2.type.simpleName) - } + object SinkComparator : Comparator { + override fun compare(o1: Sink, o2: Sink): Int { + return o1.type.simpleName.compareTo(o2.type.simpleName) } + } - object MethodComparator : Comparator { - override fun compare(o1: Dependencies.Method, o2: Dependencies.Method): Int { - return o1.method.name.compareTo(o2.method.name) - } + object MethodComparator : Comparator { + override fun compare(o1: Dependencies.Method, o2: Dependencies.Method): Int { + return o1.method.name.compareTo(o2.method.name) } + } - fun buildRootElement(project: Project): PsiClass { - return JavaPsiFacade.getInstance(project) - .findClass(Object::class.java.name, GlobalSearchScope.allScope(project))!! - } + fun buildRootElement(project: Project): PsiClass { + return JavaPsiFacade.getInstance(project) + .findClass(Object::class.java.name, GlobalSearchScope.allScope(project))!! + } - fun isRootElement(element: PsiElement?): Boolean { - return element is PsiClass && element.qualifiedName == Object::class.java.name - } + fun isRootElement(element: PsiElement?): Boolean { + return element is PsiClass && element.qualifiedName == Object::class.java.name + } - fun isInitializedGraph(graph: ResolvedGraph): Boolean { - return graph.roots.isNotEmpty() - } + fun isInitializedGraph(graph: ResolvedGraph): Boolean { + return graph.roots.isNotEmpty() + } - fun isMotifScopeClass(element: PsiClass?): Boolean { - return element?.hasAnnotation(motif.Scope::class.java.name) ?: false - } + fun isMotifScopeClass(element: PsiClass?): Boolean { + return element?.hasAnnotation(motif.Scope::class.java.name) ?: false + } - fun isMotifChildScopeMethod(element: PsiElement?): Boolean { - if (element is PsiMethod) { - val classElement = PsiTreeUtil.getParentOfType(element, PsiClass::class.java) - if (isMotifScopeClass(classElement) && element.returnType is PsiClassReferenceType) { - val returnElementClass: PsiClass? = - (element.returnType as PsiClassReferenceType).resolve() - if (isMotifScopeClass(returnElementClass)) { - return true - } + fun isMotifChildScopeMethod(element: PsiElement?): Boolean { + if (element is PsiMethod) { + val classElement = PsiTreeUtil.getParentOfType(element, PsiClass::class.java) + if (isMotifScopeClass(classElement) && element.returnType is PsiClassReferenceType) { + val returnElementClass: PsiClass? = (element.returnType as PsiClassReferenceType).resolve() + if (isMotifScopeClass(returnElementClass)) { + return true } } - return false } + return false + } - fun getParentScopes( - project: Project, - graph: ResolvedGraph, - element: PsiClass - ): Array? { - val scopeType: PsiType = PsiElementFactory.SERVICE.getInstance(project).createType(element) - val type: IrType = IntelliJType(project, scopeType) - val scope: Scope? = graph.getScope(type) - return if (scope != null) - Iterables.toArray(graph.getParentEdges(scope), ScopeEdge::class.java) - else null - } + fun getParentScopes( + project: Project, + graph: ResolvedGraph, + element: PsiClass + ): Array? { + val scopeType: PsiType = PsiElementFactory.SERVICE.getInstance(project).createType(element) + val type: IrType = IntelliJType(project, scopeType) + val scope: Scope? = graph.getScope(type) + return if (scope != null) Iterables.toArray(graph.getParentEdges(scope), ScopeEdge::class.java) + else null + } - /* - * Returns the list of sources for given scope to display in the UI - */ - fun getVisibleSources(graph: ResolvedGraph, scope: Scope): List { - return graph.getSources(scope).filter { it !is ChildParameterSource && it !is ScopeSource } - } + /* + * Returns the list of sources for given scope to display in the UI + */ + fun getVisibleSources(graph: ResolvedGraph, scope: Scope): List { + return graph.getSources(scope).filter { it !is ChildParameterSource && it !is ScopeSource } + } - /* - * Returns the number of usage for the given class. - */ - fun getUsageCount( - project: Project, - graph: ResolvedGraph, - clazz: PsiClass, - includeSources: Boolean = true, - includeSinks: Boolean = true - ): Int { - var count = 0 - val elementType: PsiType = PsiElementFactory.SERVICE.getInstance(project).createType(clazz) - val type: IrType = IntelliJType(project, elementType) - if (includeSources) { - graph.getSources(type).forEach { _ -> count++ } - } - if (includeSinks) { - graph.getSinks(type).forEach { _ -> count++ } - } - return count - } + /* + * Returns the number of usage for the given class. + */ + fun getUsageCount( + project: Project, + graph: ResolvedGraph, + clazz: PsiClass, + includeSources: Boolean = true, + includeSinks: Boolean = true + ): Int { + var count = 0 + val elementType: PsiType = PsiElementFactory.SERVICE.getInstance(project).createType(clazz) + val type: IrType = IntelliJType(project, elementType) + if (includeSources) { + graph.getSources(type).forEach { _ -> count++ } + } + if (includeSinks) { + graph.getSinks(type).forEach { _ -> count++ } + } + return count + } - fun getUsageString(count: Int): String { - return when (count) { - 0 -> "No usage" - 1 -> "1 usage" - else -> "$count usages" - } + fun getUsageString(count: Int): String { + return when (count) { + 0 -> "No usage" + 1 -> "1 usage" + else -> "$count usages" } + } - fun getObjectString(count: Int): String { - return when (count) { - 0 -> "No object" - 1 -> "1 object" - else -> "$count objects" - } + fun getObjectString(count: Int): String { + return when (count) { + 0 -> "No object" + 1 -> "1 object" + else -> "$count objects" } + } - fun formatQualifiedName(qualifiedName: String): String { - val index: Int = qualifiedName.lastIndexOf(".") - return if (index > 0) qualifiedName.substring(0, index) else qualifiedName - } + fun formatQualifiedName(qualifiedName: String): String { + val index: Int = qualifiedName.lastIndexOf(".") + return if (index > 0) qualifiedName.substring(0, index) else qualifiedName + } - fun formatMultilineText(text: String): String { - return "" + text.replace("\n", "
") + "" - } + fun formatMultilineText(text: String): String { + return "" + text.replace("\n", "
") + "" + } - /* - * Returns all the paths, starting from root scopes, leading to the provided scope. - */ - fun getMotifScopePaths(scope: Scope, graph: ResolvedGraph): ArrayList> { - val list: ArrayList = ArrayList() - val all: ArrayList> = ArrayList() - all.add(list) - getMotifScopePathsRecursive(scope, graph, list, all) - return all - } + /* + * Returns all the paths, starting from root scopes, leading to the provided scope. + */ + fun getMotifScopePaths(scope: Scope, graph: ResolvedGraph): ArrayList> { + val list: ArrayList = ArrayList() + val all: ArrayList> = ArrayList() + all.add(list) + getMotifScopePathsRecursive(scope, graph, list, all) + return all + } - private fun getMotifScopePathsRecursive( - scope: Scope, - graph: ResolvedGraph, - list: ArrayList, - all: ArrayList> - ) { - list.add(scope) - val parentEdgesIterator: Iterator = graph.getParentEdges(scope).iterator() - if (parentEdgesIterator.hasNext()) { - getMotifScopePathsRecursive(parentEdgesIterator.next().parent, graph, list, all) - } - for (edge: ScopeEdge in parentEdgesIterator) { - val newList: ArrayList = ArrayList() - all.add(newList) - getMotifScopePathsRecursive(edge.parent, graph, newList, all) - } + private fun getMotifScopePathsRecursive( + scope: Scope, + graph: ResolvedGraph, + list: ArrayList, + all: ArrayList> + ) { + list.add(scope) + val parentEdgesIterator: Iterator = graph.getParentEdges(scope).iterator() + if (parentEdgesIterator.hasNext()) { + getMotifScopePathsRecursive(parentEdgesIterator.next().parent, graph, list, all) + } + for (edge: ScopeEdge in parentEdgesIterator) { + val newList: ArrayList = ArrayList() + all.add(newList) + getMotifScopePathsRecursive(edge.parent, graph, newList, all) } } } diff --git a/intellij/src/main/kotlin/motif/intellij/actions/MotifAncestorGraphAction.kt b/intellij/src/main/kotlin/motif/intellij/actions/MotifAncestorGraphAction.kt index 744c9a9b..ef770747 100644 --- a/intellij/src/main/kotlin/motif/intellij/actions/MotifAncestorGraphAction.kt +++ b/intellij/src/main/kotlin/motif/intellij/actions/MotifAncestorGraphAction.kt @@ -25,9 +25,9 @@ import com.intellij.psi.PsiElement import motif.core.ResolvedGraph import motif.intellij.MotifService import motif.intellij.MotifService.Companion.TOOL_WINDOW_ID -import motif.intellij.ScopeHierarchyUtils.Companion.getParentScopes -import motif.intellij.ScopeHierarchyUtils.Companion.isInitializedGraph -import motif.intellij.ScopeHierarchyUtils.Companion.isMotifScopeClass +import motif.intellij.ScopeHierarchyUtils.getParentScopes +import motif.intellij.ScopeHierarchyUtils.isInitializedGraph +import motif.intellij.ScopeHierarchyUtils.isMotifScopeClass import motif.intellij.analytics.AnalyticsService import motif.intellij.analytics.MotifAnalyticsActions diff --git a/intellij/src/main/kotlin/motif/intellij/actions/MotifGraphAction.kt b/intellij/src/main/kotlin/motif/intellij/actions/MotifGraphAction.kt index 9f33ac99..9f989dff 100644 --- a/intellij/src/main/kotlin/motif/intellij/actions/MotifGraphAction.kt +++ b/intellij/src/main/kotlin/motif/intellij/actions/MotifGraphAction.kt @@ -22,7 +22,7 @@ import com.intellij.openapi.wm.ToolWindowManager import motif.core.ResolvedGraph import motif.intellij.MotifService import motif.intellij.MotifService.Companion.TOOL_WINDOW_ID -import motif.intellij.ScopeHierarchyUtils.Companion.isInitializedGraph +import motif.intellij.ScopeHierarchyUtils.isInitializedGraph import motif.intellij.analytics.AnalyticsService import motif.intellij.analytics.MotifAnalyticsActions diff --git a/intellij/src/main/kotlin/motif/intellij/actions/MotifUsageAction.kt b/intellij/src/main/kotlin/motif/intellij/actions/MotifUsageAction.kt index 35392a60..63deed0a 100644 --- a/intellij/src/main/kotlin/motif/intellij/actions/MotifUsageAction.kt +++ b/intellij/src/main/kotlin/motif/intellij/actions/MotifUsageAction.kt @@ -26,7 +26,7 @@ import motif.core.ResolvedGraph import motif.intellij.MotifService import motif.intellij.MotifService.Companion.TOOL_WINDOW_ID import motif.intellij.ScopeHierarchyUtils -import motif.intellij.ScopeHierarchyUtils.Companion.getUsageCount +import motif.intellij.ScopeHierarchyUtils.getUsageCount import motif.intellij.analytics.AnalyticsService import motif.intellij.analytics.MotifAnalyticsActions diff --git a/intellij/src/main/kotlin/motif/intellij/analytics/MotifAnalyticsActions.kt b/intellij/src/main/kotlin/motif/intellij/analytics/MotifAnalyticsActions.kt index 0a309f4e..3a22ca02 100644 --- a/intellij/src/main/kotlin/motif/intellij/analytics/MotifAnalyticsActions.kt +++ b/intellij/src/main/kotlin/motif/intellij/analytics/MotifAnalyticsActions.kt @@ -15,21 +15,19 @@ */ package motif.intellij.analytics -abstract class MotifAnalyticsActions { +object MotifAnalyticsActions { - companion object { - const val PROJECT_OPENED = "projectOpened" + const val PROJECT_OPENED = "projectOpened" - const val GRAPH_INIT = "graphInit" - const val GRAPH_UPDATE = "graphUpdate" - const val GRAPH_UPDATE_SUCCESS = "graphUpdateSuccess" - const val GRAPH_UPDATE_ERROR = "graphUpdateError" - const val GRAPH_COMPUTATION_ERROR = "graphComputationError" + const val GRAPH_INIT = "graphInit" + const val GRAPH_UPDATE = "graphUpdate" + const val GRAPH_UPDATE_SUCCESS = "graphUpdateSuccess" + const val GRAPH_UPDATE_ERROR = "graphUpdateError" + const val GRAPH_COMPUTATION_ERROR = "graphComputationError" - const val GRAPH_MENU_CLICK = "graphMenuClick" - const val ANCESTOR_MENU_CLICK = "ancestorMenuClick" - const val USAGE_MENU_CLICK = "usageMenuClick" - const val ANCESTOR_GUTTER_CLICK = "ancestorGutterClick" - const val NAVIGATION_GUTTER_CLICK = "navigationGutterClick" - } + const val GRAPH_MENU_CLICK = "graphMenuClick" + const val ANCESTOR_MENU_CLICK = "ancestorMenuClick" + const val USAGE_MENU_CLICK = "usageMenuClick" + const val ANCESTOR_GUTTER_CLICK = "ancestorGutterClick" + const val NAVIGATION_GUTTER_CLICK = "navigationGutterClick" } diff --git a/intellij/src/main/kotlin/motif/intellij/hierarchy/ErrorHierarchyBrowser.kt b/intellij/src/main/kotlin/motif/intellij/hierarchy/ErrorHierarchyBrowser.kt index 9fbf3ee3..04b8c238 100644 --- a/intellij/src/main/kotlin/motif/intellij/hierarchy/ErrorHierarchyBrowser.kt +++ b/intellij/src/main/kotlin/motif/intellij/hierarchy/ErrorHierarchyBrowser.kt @@ -34,7 +34,7 @@ import javax.swing.tree.DefaultMutableTreeNode import motif.core.ResolvedGraph import motif.errormessage.ErrorMessage import motif.intellij.MotifService -import motif.intellij.ScopeHierarchyUtils.Companion.isRootElement +import motif.intellij.ScopeHierarchyUtils.isRootElement import motif.intellij.hierarchy.ScopeHierarchyBrowser.Companion.LABEL_GO_NEXT_SCOPE import motif.intellij.hierarchy.ScopeHierarchyBrowser.Companion.LABEL_GO_PREVIOUS_SCOPE import motif.intellij.hierarchy.descriptor.ScopeHierarchyErrorDescriptor diff --git a/intellij/src/main/kotlin/motif/intellij/hierarchy/ScopeHierarchyBrowser.kt b/intellij/src/main/kotlin/motif/intellij/hierarchy/ScopeHierarchyBrowser.kt index 6001f3fa..43df929f 100644 --- a/intellij/src/main/kotlin/motif/intellij/hierarchy/ScopeHierarchyBrowser.kt +++ b/intellij/src/main/kotlin/motif/intellij/hierarchy/ScopeHierarchyBrowser.kt @@ -44,7 +44,7 @@ import motif.ast.intellij.IntelliJType import motif.core.ResolvedGraph import motif.intellij.MotifService import motif.intellij.ScopeHierarchyUtils -import motif.intellij.ScopeHierarchyUtils.Companion.isMotifScopeClass +import motif.intellij.ScopeHierarchyUtils.isMotifScopeClass import motif.intellij.analytics.AnalyticsService import motif.intellij.analytics.MotifAnalyticsActions import motif.intellij.hierarchy.descriptor.ScopeHierarchyRootDescriptor diff --git a/intellij/src/main/kotlin/motif/intellij/hierarchy/ScopeHierarchyTreeStructure.kt b/intellij/src/main/kotlin/motif/intellij/hierarchy/ScopeHierarchyTreeStructure.kt index 0cf7cb9a..9611d361 100644 --- a/intellij/src/main/kotlin/motif/intellij/hierarchy/ScopeHierarchyTreeStructure.kt +++ b/intellij/src/main/kotlin/motif/intellij/hierarchy/ScopeHierarchyTreeStructure.kt @@ -27,13 +27,13 @@ import motif.ast.intellij.IntelliJType import motif.core.ResolvedGraph import motif.errormessage.ErrorMessage import motif.intellij.ScopeHierarchyUtils -import motif.intellij.ScopeHierarchyUtils.Companion.MethodComparator -import motif.intellij.ScopeHierarchyUtils.Companion.ScopeComparator -import motif.intellij.ScopeHierarchyUtils.Companion.ScopeEdgeChildComparator -import motif.intellij.ScopeHierarchyUtils.Companion.ScopeEdgeParentComparator -import motif.intellij.ScopeHierarchyUtils.Companion.SinkComparator -import motif.intellij.ScopeHierarchyUtils.Companion.SourceComparator -import motif.intellij.ScopeHierarchyUtils.Companion.getVisibleSources +import motif.intellij.ScopeHierarchyUtils.MethodComparator +import motif.intellij.ScopeHierarchyUtils.ScopeComparator +import motif.intellij.ScopeHierarchyUtils.ScopeEdgeChildComparator +import motif.intellij.ScopeHierarchyUtils.ScopeEdgeParentComparator +import motif.intellij.ScopeHierarchyUtils.SinkComparator +import motif.intellij.ScopeHierarchyUtils.SourceComparator +import motif.intellij.ScopeHierarchyUtils.getVisibleSources import motif.intellij.hierarchy.descriptor.ScopeHierarchyDependenciesSectionDescriptor import motif.intellij.hierarchy.descriptor.ScopeHierarchyDependencyDescriptor import motif.intellij.hierarchy.descriptor.ScopeHierarchyErrorDescriptor diff --git a/intellij/src/main/kotlin/motif/intellij/hierarchy/ScopePropertyHierarchyBrowser.kt b/intellij/src/main/kotlin/motif/intellij/hierarchy/ScopePropertyHierarchyBrowser.kt index ae0b7159..ca7115b5 100644 --- a/intellij/src/main/kotlin/motif/intellij/hierarchy/ScopePropertyHierarchyBrowser.kt +++ b/intellij/src/main/kotlin/motif/intellij/hierarchy/ScopePropertyHierarchyBrowser.kt @@ -42,7 +42,7 @@ import motif.ast.intellij.IntelliJClass import motif.ast.intellij.IntelliJType import motif.core.ResolvedGraph import motif.intellij.MotifService -import motif.intellij.ScopeHierarchyUtils.Companion.isMotifScopeClass +import motif.intellij.ScopeHierarchyUtils.isMotifScopeClass import motif.intellij.hierarchy.ScopeHierarchyBrowser.Companion.LABEL_GO_NEXT_SCOPE import motif.intellij.hierarchy.ScopeHierarchyBrowser.Companion.LABEL_GO_PREVIOUS_SCOPE import motif.intellij.hierarchy.descriptor.ScopeHierarchyDependenciesSectionDescriptor diff --git a/intellij/src/main/kotlin/motif/intellij/hierarchy/descriptor/ScopeHierarchyDependencyDescriptor.kt b/intellij/src/main/kotlin/motif/intellij/hierarchy/descriptor/ScopeHierarchyDependencyDescriptor.kt index 11e722cf..882caad6 100644 --- a/intellij/src/main/kotlin/motif/intellij/hierarchy/descriptor/ScopeHierarchyDependencyDescriptor.kt +++ b/intellij/src/main/kotlin/motif/intellij/hierarchy/descriptor/ScopeHierarchyDependencyDescriptor.kt @@ -20,7 +20,7 @@ import com.intellij.openapi.project.Project import com.intellij.openapi.roots.ui.util.CompositeAppearance import com.intellij.psi.PsiElement import motif.core.ResolvedGraph -import motif.intellij.ScopeHierarchyUtils.Companion.formatQualifiedName +import motif.intellij.ScopeHierarchyUtils.formatQualifiedName import motif.models.Dependencies open class ScopeHierarchyDependencyDescriptor( diff --git a/intellij/src/main/kotlin/motif/intellij/hierarchy/descriptor/ScopeHierarchyScopeDescriptor.kt b/intellij/src/main/kotlin/motif/intellij/hierarchy/descriptor/ScopeHierarchyScopeDescriptor.kt index 8b0e8feb..52a143be 100644 --- a/intellij/src/main/kotlin/motif/intellij/hierarchy/descriptor/ScopeHierarchyScopeDescriptor.kt +++ b/intellij/src/main/kotlin/motif/intellij/hierarchy/descriptor/ScopeHierarchyScopeDescriptor.kt @@ -24,7 +24,7 @@ import com.intellij.psi.PsiClass import com.intellij.psi.PsiElement import javax.swing.Icon import motif.core.ResolvedGraph -import motif.intellij.ScopeHierarchyUtils.Companion.formatQualifiedName +import motif.intellij.ScopeHierarchyUtils.formatQualifiedName import motif.models.ErrorScope import motif.models.Scope diff --git a/intellij/src/main/kotlin/motif/intellij/hierarchy/descriptor/ScopeHierarchySinkDetailsDescriptor.kt b/intellij/src/main/kotlin/motif/intellij/hierarchy/descriptor/ScopeHierarchySinkDetailsDescriptor.kt index a057303a..4c4a9443 100644 --- a/intellij/src/main/kotlin/motif/intellij/hierarchy/descriptor/ScopeHierarchySinkDetailsDescriptor.kt +++ b/intellij/src/main/kotlin/motif/intellij/hierarchy/descriptor/ScopeHierarchySinkDetailsDescriptor.kt @@ -21,7 +21,7 @@ import com.intellij.openapi.roots.ui.util.CompositeAppearance import com.intellij.psi.PsiElement import javax.swing.Icon import motif.core.ResolvedGraph -import motif.intellij.ScopeHierarchyUtils.Companion.formatQualifiedName +import motif.intellij.ScopeHierarchyUtils.formatQualifiedName import motif.models.Sink open class ScopeHierarchySinkDetailsDescriptor( diff --git a/intellij/src/main/kotlin/motif/intellij/hierarchy/descriptor/ScopeHierarchySourceDescriptor.kt b/intellij/src/main/kotlin/motif/intellij/hierarchy/descriptor/ScopeHierarchySourceDescriptor.kt index a51f9694..2180c16c 100644 --- a/intellij/src/main/kotlin/motif/intellij/hierarchy/descriptor/ScopeHierarchySourceDescriptor.kt +++ b/intellij/src/main/kotlin/motif/intellij/hierarchy/descriptor/ScopeHierarchySourceDescriptor.kt @@ -27,7 +27,7 @@ import javax.swing.Icon import motif.ast.intellij.IntelliJClass import motif.ast.intellij.IntelliJMethod import motif.core.ResolvedGraph -import motif.intellij.ScopeHierarchyUtils.Companion.formatQualifiedName +import motif.intellij.ScopeHierarchyUtils.formatQualifiedName import motif.models.ChildParameterSource import motif.models.FactoryMethodSource import motif.models.ScopeSource diff --git a/intellij/src/main/kotlin/motif/intellij/hierarchy/descriptor/ScopeHierarchySourceDetailsDescriptor.kt b/intellij/src/main/kotlin/motif/intellij/hierarchy/descriptor/ScopeHierarchySourceDetailsDescriptor.kt index eace0ee1..16089c4f 100644 --- a/intellij/src/main/kotlin/motif/intellij/hierarchy/descriptor/ScopeHierarchySourceDetailsDescriptor.kt +++ b/intellij/src/main/kotlin/motif/intellij/hierarchy/descriptor/ScopeHierarchySourceDetailsDescriptor.kt @@ -21,7 +21,7 @@ import com.intellij.openapi.roots.ui.util.CompositeAppearance import com.intellij.psi.PsiElement import javax.swing.Icon import motif.core.ResolvedGraph -import motif.intellij.ScopeHierarchyUtils.Companion.formatQualifiedName +import motif.intellij.ScopeHierarchyUtils.formatQualifiedName import motif.models.Source open class ScopeHierarchySourceDetailsDescriptor( diff --git a/intellij/src/main/kotlin/motif/intellij/hierarchy/descriptor/ScopeHierarchySourcesAndSinksSectionDescriptor.kt b/intellij/src/main/kotlin/motif/intellij/hierarchy/descriptor/ScopeHierarchySourcesAndSinksSectionDescriptor.kt index 74bb0367..7436256f 100644 --- a/intellij/src/main/kotlin/motif/intellij/hierarchy/descriptor/ScopeHierarchySourcesAndSinksSectionDescriptor.kt +++ b/intellij/src/main/kotlin/motif/intellij/hierarchy/descriptor/ScopeHierarchySourcesAndSinksSectionDescriptor.kt @@ -22,7 +22,7 @@ import com.intellij.openapi.roots.ui.util.CompositeAppearance import com.intellij.psi.PsiElement import java.awt.Font.BOLD import motif.core.ResolvedGraph -import motif.intellij.ScopeHierarchyUtils.Companion.formatQualifiedName +import motif.intellij.ScopeHierarchyUtils.formatQualifiedName import motif.models.Scope open class ScopeHierarchySourcesAndSinksSectionDescriptor( diff --git a/intellij/src/main/kotlin/motif/intellij/hierarchy/descriptor/ScopeHierarchySourcesSectionDescriptor.kt b/intellij/src/main/kotlin/motif/intellij/hierarchy/descriptor/ScopeHierarchySourcesSectionDescriptor.kt index c1b37233..6739e427 100644 --- a/intellij/src/main/kotlin/motif/intellij/hierarchy/descriptor/ScopeHierarchySourcesSectionDescriptor.kt +++ b/intellij/src/main/kotlin/motif/intellij/hierarchy/descriptor/ScopeHierarchySourcesSectionDescriptor.kt @@ -22,7 +22,7 @@ import com.intellij.psi.PsiElement import javax.swing.Icon import motif.core.ResolvedGraph import motif.intellij.ScopeHierarchyUtils -import motif.intellij.ScopeHierarchyUtils.Companion.getVisibleSources +import motif.intellij.ScopeHierarchyUtils.getVisibleSources import motif.models.Scope open class ScopeHierarchySourcesSectionDescriptor( diff --git a/intellij/src/main/kotlin/motif/intellij/hierarchy/descriptor/ScopeHierarchyUsageSectionDescriptor.kt b/intellij/src/main/kotlin/motif/intellij/hierarchy/descriptor/ScopeHierarchyUsageSectionDescriptor.kt index 3144ac54..7b215dac 100644 --- a/intellij/src/main/kotlin/motif/intellij/hierarchy/descriptor/ScopeHierarchyUsageSectionDescriptor.kt +++ b/intellij/src/main/kotlin/motif/intellij/hierarchy/descriptor/ScopeHierarchyUsageSectionDescriptor.kt @@ -20,8 +20,8 @@ import com.intellij.openapi.project.Project import com.intellij.openapi.roots.ui.util.CompositeAppearance import com.intellij.psi.PsiClass import motif.core.ResolvedGraph -import motif.intellij.ScopeHierarchyUtils.Companion.getUsageCount -import motif.intellij.ScopeHierarchyUtils.Companion.getUsageString +import motif.intellij.ScopeHierarchyUtils.getUsageCount +import motif.intellij.ScopeHierarchyUtils.getUsageString open class ScopeHierarchyUsageSectionDescriptor( private val nonNullproject: Project, diff --git a/intellij/src/main/kotlin/motif/intellij/hierarchy/descriptor/ScopeHierarchyUsageSinksSectionDescriptor.kt b/intellij/src/main/kotlin/motif/intellij/hierarchy/descriptor/ScopeHierarchyUsageSinksSectionDescriptor.kt index a1c47e20..d55130ef 100644 --- a/intellij/src/main/kotlin/motif/intellij/hierarchy/descriptor/ScopeHierarchyUsageSinksSectionDescriptor.kt +++ b/intellij/src/main/kotlin/motif/intellij/hierarchy/descriptor/ScopeHierarchyUsageSinksSectionDescriptor.kt @@ -22,8 +22,8 @@ import com.intellij.psi.PsiClass import com.intellij.psi.PsiElement import javax.swing.Icon import motif.core.ResolvedGraph -import motif.intellij.ScopeHierarchyUtils.Companion.getUsageCount -import motif.intellij.ScopeHierarchyUtils.Companion.getUsageString +import motif.intellij.ScopeHierarchyUtils.getUsageCount +import motif.intellij.ScopeHierarchyUtils.getUsageString open class ScopeHierarchyUsageSinksSectionDescriptor( private val nonNullProject: Project, diff --git a/intellij/src/main/kotlin/motif/intellij/hierarchy/descriptor/ScopeHierarchyUsageSourcesSectionDescriptor.kt b/intellij/src/main/kotlin/motif/intellij/hierarchy/descriptor/ScopeHierarchyUsageSourcesSectionDescriptor.kt index 80b6d4f0..46222828 100644 --- a/intellij/src/main/kotlin/motif/intellij/hierarchy/descriptor/ScopeHierarchyUsageSourcesSectionDescriptor.kt +++ b/intellij/src/main/kotlin/motif/intellij/hierarchy/descriptor/ScopeHierarchyUsageSourcesSectionDescriptor.kt @@ -22,8 +22,8 @@ import com.intellij.psi.PsiClass import com.intellij.psi.PsiElement import javax.swing.Icon import motif.core.ResolvedGraph -import motif.intellij.ScopeHierarchyUtils.Companion.getUsageCount -import motif.intellij.ScopeHierarchyUtils.Companion.getUsageString +import motif.intellij.ScopeHierarchyUtils.getUsageCount +import motif.intellij.ScopeHierarchyUtils.getUsageString open class ScopeHierarchyUsageSourcesSectionDescriptor( private val nonNullProject: Project, diff --git a/intellij/src/main/kotlin/motif/intellij/provider/ScopeHierarchyLineMarkerProvider.kt b/intellij/src/main/kotlin/motif/intellij/provider/ScopeHierarchyLineMarkerProvider.kt index a54e0e1b..212c2a83 100644 --- a/intellij/src/main/kotlin/motif/intellij/provider/ScopeHierarchyLineMarkerProvider.kt +++ b/intellij/src/main/kotlin/motif/intellij/provider/ScopeHierarchyLineMarkerProvider.kt @@ -34,8 +34,8 @@ import java.awt.event.MouseEvent import motif.core.ResolvedGraph import motif.intellij.MotifService import motif.intellij.MotifService.Companion.TOOL_WINDOW_ID -import motif.intellij.ScopeHierarchyUtils.Companion.getParentScopes -import motif.intellij.ScopeHierarchyUtils.Companion.isMotifScopeClass +import motif.intellij.ScopeHierarchyUtils.getParentScopes +import motif.intellij.ScopeHierarchyUtils.isMotifScopeClass import motif.intellij.analytics.AnalyticsService import motif.intellij.analytics.MotifAnalyticsActions diff --git a/intellij/src/main/kotlin/motif/intellij/provider/ScopeNavigationLineMarkerProvider.kt b/intellij/src/main/kotlin/motif/intellij/provider/ScopeNavigationLineMarkerProvider.kt index b1883155..b50984d7 100644 --- a/intellij/src/main/kotlin/motif/intellij/provider/ScopeNavigationLineMarkerProvider.kt +++ b/intellij/src/main/kotlin/motif/intellij/provider/ScopeNavigationLineMarkerProvider.kt @@ -41,9 +41,9 @@ import motif.ast.intellij.IntelliJClass import motif.core.ResolvedGraph import motif.core.ScopeEdge import motif.intellij.MotifService -import motif.intellij.ScopeHierarchyUtils.Companion.getParentScopes -import motif.intellij.ScopeHierarchyUtils.Companion.isMotifChildScopeMethod -import motif.intellij.ScopeHierarchyUtils.Companion.isMotifScopeClass +import motif.intellij.ScopeHierarchyUtils.getParentScopes +import motif.intellij.ScopeHierarchyUtils.isMotifChildScopeMethod +import motif.intellij.ScopeHierarchyUtils.isMotifScopeClass import motif.intellij.analytics.AnalyticsService import motif.intellij.analytics.MotifAnalyticsActions import motif.intellij.toPsiClass diff --git a/tests/src/main/java/testcases/E057_scope_extends_scope/ERROR.txt b/tests/src/main/java/testcases/E057_scope_extends_scope/ERROR.txt index dda5980a..00045c19 100644 --- a/tests/src/main/java/testcases/E057_scope_extends_scope/ERROR.txt +++ b/tests/src/main/java/testcases/E057_scope_extends_scope/ERROR.txt @@ -17,7 +17,7 @@ [SCOPE EXTENDS SCOPE] - Scopes can't extend other Scopes: + Scope can't extend other Scopes: testcases.E057_scope_extends_scope.FooScope diff --git a/tests/src/main/java/testcases/E058_scope_extends_scope_intermediate_class/ERROR.txt b/tests/src/main/java/testcases/E058_scope_extends_scope_intermediate_class/ERROR.txt index b53093fc..a0e75e1c 100644 --- a/tests/src/main/java/testcases/E058_scope_extends_scope_intermediate_class/ERROR.txt +++ b/tests/src/main/java/testcases/E058_scope_extends_scope_intermediate_class/ERROR.txt @@ -17,7 +17,7 @@ [SCOPE EXTENDS SCOPE] - Scopes can't extend other Scopes: + Scope can't extend other Scopes: testcases.E058_scope_extends_scope_intermediate_class.FooScope From b57ab9b81a216eac704da8b888a80129e99e7056 Mon Sep 17 00:00:00 2001 From: daviss Date: Fri, 22 Mar 2024 14:43:54 -0700 Subject: [PATCH 41/56] unify tests/samples structure This commit follows the naming pattern we use for the compiler/compiler-ast module nesting. Note that these tests/samples modules are not published so these namings are purely for consistency reason and ease of identification. --- build.gradle | 10 ++++++---- samples/sample/build.gradle | 3 +-- settings.gradle | 29 ++++++++++++++++++----------- tests/build.gradle | 2 +- 4 files changed, 26 insertions(+), 18 deletions(-) diff --git a/build.gradle b/build.gradle index 130a8b63..6e7d9eda 100644 --- a/build.gradle +++ b/build.gradle @@ -106,9 +106,11 @@ subprojects { } apply plugin: 'org.jetbrains.dokka' - tasks.withType(DokkaTaskPartial).configureEach { - outputDirectory.set(new File(buildDir, "docs/partial")) - moduleName.set(project.property("POM_ARTIFACT_ID").toString()) - moduleVersion.set(project.property("VERSION_NAME").toString()) + if (!project.name.contains("samples") && !project.name.contains("tests")) { + tasks.withType(DokkaTaskPartial).configureEach { + outputDirectory.set(new File(buildDir, "docs/partial")) + moduleName.set(project.property("POM_ARTIFACT_ID").toString()) + moduleVersion.set(project.property("VERSION_NAME").toString()) + } } } diff --git a/samples/sample/build.gradle b/samples/sample/build.gradle index 2c9c197e..27ef9c76 100644 --- a/samples/sample/build.gradle +++ b/samples/sample/build.gradle @@ -38,7 +38,7 @@ dependencies { annotationProcessor deps.butterknifeCompiler annotationProcessor deps.glideCompiler annotationProcessor project(':compiler') - implementation project(':samples:sample-lib') + implementation project(':samples-sample-lib') implementation project(':lib') implementation deps.glide implementation deps.stetho @@ -47,5 +47,4 @@ dependencies { testImplementation deps.test.junit testImplementation deps.test.truth - } diff --git a/settings.gradle b/settings.gradle index 99f710c5..64db481b 100644 --- a/settings.gradle +++ b/settings.gradle @@ -29,23 +29,24 @@ pluginManagement { } rootProject.name = 'motif' -include 'lib' +include 'ast' include 'compiler' include 'compiler-ast' include 'compiler-ksp' -include 'samples:sample' -include 'samples:sample-lib' -include 'samples:sample-kotlin' -include 'samples:sample-kotlin-ksp' -include 'samples:dagger-comparison' -include 'intellij' -include 'intellij-ast' include 'core' include 'errormessage' +include 'intellij' +include 'intellij-ast' +include 'lib' include 'models' -include 'ast' +include 'samples-dagger-comparison' +include 'samples-sample' +include 'samples-sample-kotlin' +include 'samples-sample-kotlin-ksp' +include 'samples-sample-lib' +include 'samples-sample-lib-ksp' include 'tests' -include 'tests:compiler' +include 'tests-compiler' include 'viewmodel' include 'xprocessing' include 'xprocessing-testing' @@ -53,4 +54,10 @@ include 'xprocessing-testing' project(':compiler-ast').projectDir = file('compiler/ast') project(':compiler-ksp').projectDir = file('compiler/ksp') project(':intellij-ast').projectDir = file('intellij/ast') -include ':samples:sample-lib-ksp' +project(':samples-dagger-comparison').projectDir = file('samples/dagger-comparison') +project(':samples-sample').projectDir = file('samples/sample') +project(':samples-sample-kotlin').projectDir = file('samples/sample-kotlin') +project(':samples-sample-kotlin-ksp').projectDir = file('samples/sample-kotlin-ksp') +project(':samples-sample-lib').projectDir = file('samples/sample-lib') +project(':samples-sample-lib-ksp').projectDir = file('samples/sample-lib-ksp') +project(':tests-compiler').projectDir = file('tests/compiler') diff --git a/tests/build.gradle b/tests/build.gradle index 840b3db7..e08ce43c 100644 --- a/tests/build.gradle +++ b/tests/build.gradle @@ -17,7 +17,7 @@ kotlin { } dependencies { - kapt project(':tests:compiler') + kapt project(':tests-compiler') kapt deps.daggerCompiler implementation project(':core') implementation project(':lib') From 3d4dc3d4aeab05200871b930d2977737b8569cec Mon Sep 17 00:00:00 2001 From: James Barr Date: Tue, 11 Feb 2025 11:53:44 -0800 Subject: [PATCH 42/56] Migrate off deprecated case conversion methods --- compiler/src/main/kotlin/motif/compiler/CodeGenerator.kt | 2 +- .../src/main/kotlin/motif/compiler/MotifProcessingStep.kt | 2 +- intellij/ast/src/main/kotlin/motif/ast/intellij/IrUtil.kt | 4 +--- 3 files changed, 3 insertions(+), 5 deletions(-) diff --git a/compiler/src/main/kotlin/motif/compiler/CodeGenerator.kt b/compiler/src/main/kotlin/motif/compiler/CodeGenerator.kt index 522afd55..07b025e6 100644 --- a/compiler/src/main/kotlin/motif/compiler/CodeGenerator.kt +++ b/compiler/src/main/kotlin/motif/compiler/CodeGenerator.kt @@ -29,7 +29,7 @@ object CodeGenerator { } else if (mode == OutputMode.KOTLIN) { if (env.backend == XProcessingEnv.Backend.JAVAC && kaptKotlinGeneratedDir == null) { throw IllegalStateException( - "-A$OPTION_MODE=${OutputMode.KOTLIN.name.toLowerCase()} " + + "-A$OPTION_MODE=${OutputMode.KOTLIN.name.lowercase()} " + "requires -A$OPTION_KAPT_KOTLIN_GENERATED to be set.") } generateKotlin(env, graph, kaptKotlinGeneratedDir) diff --git a/compiler/src/main/kotlin/motif/compiler/MotifProcessingStep.kt b/compiler/src/main/kotlin/motif/compiler/MotifProcessingStep.kt index 37724906..85466b5b 100644 --- a/compiler/src/main/kotlin/motif/compiler/MotifProcessingStep.kt +++ b/compiler/src/main/kotlin/motif/compiler/MotifProcessingStep.kt @@ -83,7 +83,7 @@ class MotifProcessingStep( val mode: OutputMode? = try { - OutputMode.valueOf(env.options[OPTION_MODE]?.toUpperCase() ?: "") + OutputMode.valueOf(env.options[OPTION_MODE]?.uppercase() ?: "") } catch (ignore: IllegalArgumentException) { if (env.backend == XProcessingEnv.Backend.KSP) OutputMode.KOTLIN else null } diff --git a/intellij/ast/src/main/kotlin/motif/ast/intellij/IrUtil.kt b/intellij/ast/src/main/kotlin/motif/ast/intellij/IrUtil.kt index d9d8971d..2673ec94 100644 --- a/intellij/ast/src/main/kotlin/motif/ast/intellij/IrUtil.kt +++ b/intellij/ast/src/main/kotlin/motif/ast/intellij/IrUtil.kt @@ -19,11 +19,9 @@ import com.intellij.openapi.project.Project import com.intellij.psi.PsiAnnotationOwner import com.intellij.psi.PsiModifier import com.intellij.psi.PsiModifierListOwner -import java.util.Locale import kotlin.collections.filter import kotlin.collections.map import kotlin.collections.toSet -import kotlin.text.toUpperCase import motif.ast.IrAnnotation import motif.ast.IrModifier @@ -32,7 +30,7 @@ interface IrUtil { fun PsiModifierListOwner.irModifiers(): Set { return PsiModifier.MODIFIERS .filter { hasModifierProperty(it) } - .map { IrModifier.valueOf(it.toUpperCase(Locale.getDefault())) } + .map { IrModifier.valueOf(it.uppercase()) } .toSet() } From 39a75a65ad5463a896105f35198bcaaca1be1ee7 Mon Sep 17 00:00:00 2001 From: James Barr Date: Tue, 11 Feb 2025 11:55:59 -0800 Subject: [PATCH 43/56] Centralize source compat java version --- ast/build.gradle | 4 ---- build.gradle | 25 +++++++++++++++++++++++++ compiler/ast/build.gradle | 4 ---- compiler/build.gradle | 4 ---- compiler/ksp/build.gradle | 4 ---- core/build.gradle | 4 ---- errormessage/build.gradle | 4 ---- models/build.gradle | 4 ---- samples/dagger-comparison/build.gradle | 5 ----- samples/sample-kotlin-ksp/build.gradle | 5 ----- samples/sample-kotlin/build.gradle | 5 ----- samples/sample-lib-ksp/build.gradle | 5 ----- samples/sample-lib/build.gradle | 5 ----- samples/sample/build.gradle | 5 ----- tests/build.gradle | 4 ---- tests/compiler/build.gradle | 4 ---- viewmodel/build.gradle | 4 ---- 17 files changed, 25 insertions(+), 70 deletions(-) diff --git a/ast/build.gradle b/ast/build.gradle index 545b5298..b1f92cb5 100644 --- a/ast/build.gradle +++ b/ast/build.gradle @@ -3,10 +3,6 @@ plugins { id 'com.vanniktech.maven.publish' } -kotlin { - jvmToolchain(11) -} - dependencies { implementation deps.kotlin.stdlib implementation deps.dagger diff --git a/build.gradle b/build.gradle index 6e7d9eda..23559940 100644 --- a/build.gradle +++ b/build.gradle @@ -64,12 +64,37 @@ subprojects { } boolean isKotlinLibrary = project.plugins.hasPlugin("org.jetbrains.kotlin.jvm") || project.plugins.hasPlugin("org.jetbrains.kotlin.android") if (isKotlinLibrary) { + java { + toolchain.languageVersion.set(JavaLanguageVersion.of(11)) + } + kotlin { + jvmToolchain(11) + } it.tasks.withType(org.jetbrains.kotlin.gradle.tasks.KotlinCompile).configureEach { kotlinOptions { freeCompilerArgs += extraKotlincArgs } } } + + boolean isAndroidLibraryOrApp = project.plugins.hasPlugin("org.jetbrains.kotlin.android") + if (isAndroidLibraryOrApp) { + android { + compileOptions { + sourceCompatibility JavaVersion.VERSION_1_8 + targetCompatibility JavaVersion.VERSION_1_8 + } + + } + } + + if (isKotlinLibrary && isAndroidLibraryOrApp) { + android { + kotlinOptions { + jvmTarget = "1.8" + } + } + } } if (project.path != ":tests") { diff --git a/compiler/ast/build.gradle b/compiler/ast/build.gradle index 0c3fa969..dcf40949 100644 --- a/compiler/ast/build.gradle +++ b/compiler/ast/build.gradle @@ -3,10 +3,6 @@ plugins { id 'com.vanniktech.maven.publish' } -kotlin { - jvmToolchain(11) -} - dependencies { implementation deps.kotlin.stdlib implementation deps.autoCommon diff --git a/compiler/build.gradle b/compiler/build.gradle index 0fc9e26f..fb845b28 100644 --- a/compiler/build.gradle +++ b/compiler/build.gradle @@ -3,10 +3,6 @@ plugins { id 'com.vanniktech.maven.publish' } -kotlin { - jvmToolchain(11) -} - dependencies { implementation deps.kotlin.stdlib implementation deps.kotlin.reflection diff --git a/compiler/ksp/build.gradle b/compiler/ksp/build.gradle index 50c907d7..a4e54977 100644 --- a/compiler/ksp/build.gradle +++ b/compiler/ksp/build.gradle @@ -3,10 +3,6 @@ plugins { id 'com.vanniktech.maven.publish' } -kotlin { - jvmToolchain(11) -} - dependencies { implementation deps.kotlin.stdlib implementation deps.kotlin.reflection diff --git a/core/build.gradle b/core/build.gradle index db139530..275159a5 100644 --- a/core/build.gradle +++ b/core/build.gradle @@ -3,10 +3,6 @@ plugins { id 'com.vanniktech.maven.publish' } -kotlin { - jvmToolchain(11) -} - dependencies { api project(':models') diff --git a/errormessage/build.gradle b/errormessage/build.gradle index 2ea5385a..7a5b3d61 100644 --- a/errormessage/build.gradle +++ b/errormessage/build.gradle @@ -3,10 +3,6 @@ plugins { id 'com.vanniktech.maven.publish' } -kotlin { - jvmToolchain(11) -} - dependencies { implementation deps.kotlin.stdlib implementation project(':core') diff --git a/models/build.gradle b/models/build.gradle index 98718cc7..e1d865c0 100644 --- a/models/build.gradle +++ b/models/build.gradle @@ -3,10 +3,6 @@ plugins { id 'com.vanniktech.maven.publish' } -kotlin { - jvmToolchain(11) -} - dependencies { api project(':ast') diff --git a/samples/dagger-comparison/build.gradle b/samples/dagger-comparison/build.gradle index 619cc488..f23c0be2 100644 --- a/samples/dagger-comparison/build.gradle +++ b/samples/dagger-comparison/build.gradle @@ -21,11 +21,6 @@ android { abortOnError false quiet true } - - compileOptions { - sourceCompatibility JavaVersion.VERSION_1_8 - targetCompatibility JavaVersion.VERSION_1_8 - } } dependencies { diff --git a/samples/sample-kotlin-ksp/build.gradle b/samples/sample-kotlin-ksp/build.gradle index fef42637..db4e8854 100644 --- a/samples/sample-kotlin-ksp/build.gradle +++ b/samples/sample-kotlin-ksp/build.gradle @@ -29,11 +29,6 @@ android { } } - compileOptions { - sourceCompatibility JavaVersion.VERSION_11 - targetCompatibility JavaVersion.VERSION_11 - } - variantFilter { variant -> if (variant.buildType.name == 'release') { variant.setIgnore(true) diff --git a/samples/sample-kotlin/build.gradle b/samples/sample-kotlin/build.gradle index bedc5f63..b41a8aa6 100644 --- a/samples/sample-kotlin/build.gradle +++ b/samples/sample-kotlin/build.gradle @@ -28,11 +28,6 @@ android { quiet true } - compileOptions { - sourceCompatibility JavaVersion.VERSION_11 - targetCompatibility JavaVersion.VERSION_11 - } - variantFilter { variant -> if (variant.buildType.name == 'release') { variant.setIgnore(true) diff --git a/samples/sample-lib-ksp/build.gradle b/samples/sample-lib-ksp/build.gradle index 6975623f..c790276b 100644 --- a/samples/sample-lib-ksp/build.gradle +++ b/samples/sample-lib-ksp/build.gradle @@ -29,11 +29,6 @@ android { } } - compileOptions { - sourceCompatibility JavaVersion.VERSION_11 - targetCompatibility JavaVersion.VERSION_11 - } - androidComponents { beforeVariants(selector().withBuildType("debug")) { variantBuilder -> variantBuilder.enabled = false diff --git a/samples/sample-lib/build.gradle b/samples/sample-lib/build.gradle index 35e2d1ad..926ca2cc 100644 --- a/samples/sample-lib/build.gradle +++ b/samples/sample-lib/build.gradle @@ -21,11 +21,6 @@ android { abortOnError false quiet true } - - compileOptions { - sourceCompatibility JavaVersion.VERSION_1_8 - targetCompatibility JavaVersion.VERSION_1_8 - } } dependencies { diff --git a/samples/sample/build.gradle b/samples/sample/build.gradle index 27ef9c76..bcaf1e78 100644 --- a/samples/sample/build.gradle +++ b/samples/sample/build.gradle @@ -22,11 +22,6 @@ android { quiet true } - compileOptions { - sourceCompatibility JavaVersion.VERSION_1_8 - targetCompatibility JavaVersion.VERSION_1_8 - } - variantFilter { variant -> if (variant.buildType.name == 'release') { variant.setIgnore(true) diff --git a/tests/build.gradle b/tests/build.gradle index e08ce43c..b3c6cea4 100644 --- a/tests/build.gradle +++ b/tests/build.gradle @@ -5,10 +5,6 @@ plugins { id 'kotlin-kapt' } -kotlin { - jvmToolchain(11) -} - kotlin { sourceSets { main.kotlin.srcDirs += 'build/generated/ksp/main/kotlin' diff --git a/tests/compiler/build.gradle b/tests/compiler/build.gradle index 640c8f4e..4767775e 100644 --- a/tests/compiler/build.gradle +++ b/tests/compiler/build.gradle @@ -2,10 +2,6 @@ plugins { id 'org.jetbrains.kotlin.jvm' } -kotlin { - jvmToolchain(11) -} - dependencies { implementation deps.autoCommon implementation deps.kotlin.stdlib diff --git a/viewmodel/build.gradle b/viewmodel/build.gradle index 3cb2f4d8..1738742e 100644 --- a/viewmodel/build.gradle +++ b/viewmodel/build.gradle @@ -3,10 +3,6 @@ plugins { id 'com.vanniktech.maven.publish' } -kotlin { - jvmToolchain(11) -} - dependencies { api project(':core') api project(':models') From 4955c2f5a4cb84ab2f0dd935f3a305077b0b3f1a Mon Sep 17 00:00:00 2001 From: James Barr Date: Tue, 11 Feb 2025 11:56:55 -0800 Subject: [PATCH 44/56] Add Kotlinpoet optin --- .../kotlin/motif/compiler/JavaCodeGenerator.kt | 2 ++ .../src/main/kotlin/motif/compiler/XFunSpec.kt | 2 ++ kls_database.db | Bin 0 -> 61440 bytes 3 files changed, 4 insertions(+) create mode 100644 kls_database.db diff --git a/compiler/src/main/kotlin/motif/compiler/JavaCodeGenerator.kt b/compiler/src/main/kotlin/motif/compiler/JavaCodeGenerator.kt index 72d5eaf6..10830de6 100644 --- a/compiler/src/main/kotlin/motif/compiler/JavaCodeGenerator.kt +++ b/compiler/src/main/kotlin/motif/compiler/JavaCodeGenerator.kt @@ -24,6 +24,7 @@ import com.squareup.javapoet.JavaFile import com.squareup.javapoet.MethodSpec import com.squareup.javapoet.ParameterSpec import com.squareup.javapoet.TypeSpec +import com.squareup.kotlinpoet.javapoet.KotlinPoetJavaPoetPreview import com.uber.xprocessing.ext.isKotlinSource import com.uber.xprocessing.ext.withRawTypeFix import javax.lang.model.element.Modifier @@ -126,6 +127,7 @@ object JavaCodeGenerator { .build() } + @OptIn(KotlinPoetJavaPoetPreview::class) private fun ChildDependenciesImpl.spec(): TypeSpec { val isKotlinDepInterface = env.findTypeElement(childDependenciesClassName.j).isKotlinSource(env) return TypeSpec.anonymousClassBuilder("") diff --git a/compiler/src/main/kotlin/motif/compiler/XFunSpec.kt b/compiler/src/main/kotlin/motif/compiler/XFunSpec.kt index 8ce264d5..7768c0fe 100644 --- a/compiler/src/main/kotlin/motif/compiler/XFunSpec.kt +++ b/compiler/src/main/kotlin/motif/compiler/XFunSpec.kt @@ -23,12 +23,14 @@ import com.squareup.kotlinpoet.AnnotationSpec import com.squareup.kotlinpoet.FunSpec import com.squareup.kotlinpoet.KModifier import com.squareup.kotlinpoet.ParameterSpec +import com.squareup.kotlinpoet.javapoet.KotlinPoetJavaPoetPreview import com.uber.xprocessing.ext.modifiers import javax.lang.model.element.Modifier import motif.compiler.KotlinTypeWorkaround.javaToKotlinType object XFunSpec { /** Copied from [FunSpec.overriding] and modified to leverage [javaToKotlinType]& XProcessing. */ + @OptIn(KotlinPoetJavaPoetPreview::class) fun overriding( executableElement: XExecutableElement, enclosing: XType, diff --git a/kls_database.db b/kls_database.db new file mode 100644 index 0000000000000000000000000000000000000000..17f2914772b88ff39873092402df49514eb674f3 GIT binary patch literal 61440 zcmeI5Ym6M%mEU__91e%Wu`OvOTe3BjC0Vl6-SvLRmL-a&B$^T>QIfT?y{2zf-5U0= zr+d^7KJ?ro6JQZ+J}edqjO-)H2M77EK!9WsFOUyTg2YHRPJnnf>tK-}4x9&+Y#zog z93b!Ct?KUS>gnlWlcF?S)Ib_Ghf{UWJ@?#m&+~s@e(AYdN3O-q)~4vJnWc}FW@buH zuC0|yr3L<9<^TTIJRj8m{jZt+hY5c!lq&ImTHzNK4*&bo>V?(&k9>3GFY~eZDmYMZ zpx{8kfr0}C2MP`p94I(YaG>D8&EY`eE-c=8^5jfX>xiH(pX%1?(aT}0w$(Xa7wz_o zqI2%J2+zqAjZW+GH9NRj^@dKUUozzIwIxzfWX{O=f_VX_dC}*k6I(FcO%)(Xl<`O^}-9!oj7)Sz~)ES z0woeLbG;y2?OL<3_SDH|Sh;KwUYtE}=Od5Iyq?aX{YD*!`D|Oh(Upx*j{J2lNA<`* zKGYDK@=>0AI9Z%oyt7=MNsguO{4%TvL|gVJH~RP4+*?Qg^;)^mpISPvzJMv;d}j53 zmiVvuDmYMZpx{8kfr0}C2MP`p94I(YaG>Bo!GVGU1qc4rabSLCt~4{hvii46^Q#w2 ztN(fRpRZnA{nbBp(<~-baG>Bo!GVGU1qTWa6dWixP;j8&K*5260|f^@Iu3klZqA<> zU-&S4bbjvS(&Wk#2)}!2{Ns1c&Y81=f7&iYsdc%qT`K zI8bn);6TBFf&&Ey3Jw$;C^%4Xpx{8kfr0}C2R?WX9Gaak9bB0C3p0QHR|D1Le{l8p z)gY^@|7-PUt3O@+qt*Yg`s39bs!KUj7T{kcQSOXm*$_Tv9tY##XG!hc+NasIdF zel{m&|MBd?%!$%(e(=-{zcIQ0o`uqtQ>E&wZTd2*8-ZxGs+IMYi0ZN$s+OI0b+Z|D z>#|)os;Ym3KP!5b#+6F@jjm|P?pF1Dvs14%wwkh2-Vhgr`cTy?x>3=pp5~gG<#>7= z2cGV0wkx&BaHL@vy6x*h;Dn*=d*Qful(TnKXnjc@zZ){&nVL+|h+55Bbg9y6HaDy4 zTe;VA(<*PZnsk@6YmN1)QE@6-S=6`A3C*Y)Qgc1ivLns$EYq-jUBohuLOqOhBd|m) zY~Rs@v+Mid(9ru*`j35Tp>%a&YWfwM*PG4tx~xR>2!k*VOw05=JBWPU8UHfgGW4=^4tIQ# zH7MW697MO%tg3Hn6*ije;d38?mGLVW9iM6`tc7jv2-xjBL-)UDwh*M+=4@ zRl-p*Qo25I7j%7YYPy=O^~yQ18Mb7*Q|*6%u$F`@vuYW_u%pm4bl)=kSd&T~G|kat zSBHm|AHZ=A95#yDp-_W+cyvZo9JC+<;w;+NP+N+l^Wr%T`%58qJRA z&_UH!+;gk3?}pNeWGJLCjlfjPE=|{W{n!f}%Z;I#?FaLAeUaj&n^JxB=b-w;)Km|N z>4wn^Ho|K5$0)T`85v$ABU=|xS*{lh}@}z_M-Wc$%;2{+Q>}1y`!z_B){Q zksF~=F}M=f8d1<)N9VO$re;@7b`5*qmco!;poOOC3D0#+-3%fNd5p|hYPKVV>&05s zd#ap1m9p;K?d7hQDKs@->f$Um zPc;^`Ix`fZ(!)qIYOAV8VXQ~e^bDZ|F>^2@R>QM=n;CdsAVM8o5&G5K!w3ftr^Frp z1jOAvHF4_Tx>Tt(He}eT=Kg{v^<6s>s7_b2G{bfS1UNEuVVHX0I-#%Io{|qQ_Z%cC zX*E9%In(Qbp&cb#t!9hEsv)cC$Fu3@v%`wOKPttNWhxF>f4Kb1ch*`HmI`(e{IosI&ya@XnEiQZl^}v(atT zkjeDBg;`Z)cbk!JYoUfwf@vas-;1$WJY9<%FE(6H3fq%tVf9Q|J(F_i^DA)ZwW&Fz z4oVEc@VsorEgEbuHe2Vby&t6Jl<1T(1?!kmcEzq*raCrFX`;tN4o=;dy3HR#=sG*w zkDR~=Tt6K53Pg}sq{QBH7-GLLHL*h?m?_2VyWuJYf&8WRU^Q^19-40KIA}vX72sx>xi@g^3!ob!L z{_vA!y{A8t$^tZSU{q2))KDP9!m%R|rOK_5w8Bo!GVGU1qTWa6dWixP;j8&K*526 z0|f^P4t(ew2=MEZllk2DrjbRfYMo~5a+PpSbvv9hE_6cP!mk*{NGK%xp^60k1Kk*{~ZNKwN`t<6Y%N~a|n zZFTWryG%W^pb*$GW0Qh>3Me&0r()O_rW;a$Z&(q9JiXtRRJTehb!svytLn^7?SiDl zgO9vO6Cu+sCXsFE=~2$aP|R;Y#46b4Kq<{a9GS^B19P5PT<*^h;#GK1UlWoMqZ$62E)FZ z7w8=dwJkQcXg8{6f0j|Iz2dA|qa$0JGOCFV|Ez?UwxqMIvuQcuSyrNbZSN70C&~RX*_c}zV}{o_z3U%yXqK0%jM&bPI7x)q zCe*QOs!2o-H0gO}sCq;qFLr$Cn0duC*fvAejN3Jda}{b5m#%$iUw3`YXGB^pkYH7} z>=;6Zs;XMoV>2g0gQ3S&D$)^ecn%~dHd&bJ361el$IE};;N>GVPc{UTC!Xhn?WQnS-L@65&rl?JF1e0 zU$a#gozzOA=r%16FPk(|WFOVz$tORDh}-#zkL)gN#j!n-J@0C4Hw2j@8pFGzs?*4H=?RFHa?mu_&}fpPA(6s(2Lm~6 za~tkwNe@*eE#_yTak5U>Lt3t>A@fij*Ng<#{ES(s#9gp4` ze!=Utu53T4_;~7GcHv%S^}Q|JQnmO!#ohC0Q%j2;)T~B7Ir16ic<*)TosMf&;om=@fJkCC3qI(@5HK4rBWL5uf-p1Wn%w%!J1^ zv#b7E)x&NuF#6f!#MCthHq%tCI_!c_Q|*;lPM$zL*gcu(6UC#789|v*>16I;f=V`hiVKwA7QaHkDeY}v%IOE8n|0c z4#H*&DdsHg`+><_Ux%mW)Qj9ZKQC28D?G>9g5;)WbGB1x6;n+{!~|?34rzNbJms9? zOW|12{%7GT6DrXBz=^f=RN+|fZL;)H#o0H%21hPVq-@*t!T9n-OnZ$X4V~5{M>iwO zFljK1&CrbKF3-Eg^%`EKa#G9NF8Ppq+<2X_C+nl!*nu4dL|PDSP!MP}(@aiGrX2w# zKwoBlHMUx;M}8UJ{dvZlBH9zvh8S9!Zn&Ibp^Kqs+6GO)c*dTN$)7Xy>djEpgH{tC zo~^wp8uZhQh(Y(Y>7-AhDQS+xzQ#DlHa60y(<#Yu6j-i9hp$K2z>Pqsz@w$zSlE0f zc!aMq^d!`&-GT7E{VEK3Ya(Ge0Z@nmA-ET|>G%kp$IetOqk-zNBYKe+zTQQmGTLJI z5UHRUJRNxuh-$vV=p&~1h(($kT}E`Mnm#iX`0CQ}P2Y(P&JJA~7QwijIAoWq;<2Y4 zlUX?E^2-c3MU28>XPb2OdoGbTygFg%>@^}LHrA|dJL3i%G?(Uwe*4UHoTkZ?=^2`- z3tiGUNr{ndNZ%Cf!BEq!+|UCDvn?*js1340#_4VS_pz6dz|UU$LIZK&YZf*_Y=ahp zTCoG4ZrDgTIDJkSj30hm-3)pY%R?lko!NbreBnhHGL^III*S@N54^99EJg=^=8>BK&+We`dQ`{2=v9;1mOi4sEbI(eO! z9u9hiHr@U-FP>(&H?Dm+w3@?cn396HYbby^aFFjng+7tNd`#{FN}<_`TH@kha}5Sg zO3$<8bJspHunHRR5I()lejtblLWgTbb_8-sAnd%d8yPu8<>(M;Pc=(_?r%Rgoy^-< z*Ad4FP5zkw(u_pl>I68zvcO)7^V?0dFLPb9xZI?#9S{jbeq^EFI>qQyL___6v1r#< zXg;lwx#iH=S>N4z)+aN5AVAj7~`i>){Y5(8_-)M7Ij*<(cax5k(fPc!BehOAH41PqqI z3OtRhi54PdaGU94Dsr0S6sp?Ma_m%-g%j-Rm22PCAv($nI3#t~1c`(*B`}1gIR^fr z2AooE+`&1rolZf()0^8>&TPnXeDllGEw={rQ3&!0s)QK3ja_96orD(Aeu9^FUW;y% zp|W;00AmzLlGRr$-Q&}-K4kM^F9YFVfqx`PvIL&gY5aEC)?j$$SdeP)ZDScbsXy#n zPciHi`Xq8`J@-Je(8x`KL*T@w#hI@5IewU)-_qMBXPrD{#6|C^`7ju~d5poQFqO0b zY!?lq8S@n-suP`XIaa`^3PLL$$tcyanMbwf8&5LeWbBlj0@JKOmzZV%JJ=$`_QX8) z@#q0vU}uTEWr&Tmu1sat)vP#u1}C#mAlr-AF5CE38cYW40%G<#9CB@&qKeJq`sAPvpWxXCVg?r{KwYUMhPJ_zTc3d=11j-;f;l_>BXwKKU(hbCqCs2Bw&E7^qt7x;iC_Z+UEIloz51qYAY*@>2#(Wm3S9n zIcj4_Fo>8iglD6gflQ*LKsr|bkR6Pgq1L5GT^hi@*k;rzyd@9+2nh^hfWmOifH6ZC zYoP$F({w$1mr>bAD7SVwtSjA{M!GMz7MPhzrJt2!O&A!?V+jThLY}eK=f3&Xec<6Z5Xj;963?`q#X=R(ZunNKJ8L94IZ3!M;s6#T|Ed|Dz+V7*lYBFRjq4%_M&@j(!Qer+gL`%!@JE?X zHmQU_D&%i8VZt=#2G~9pMzr)XurTUO5ZEHZ6^0LnBuk&8BNVM@r?-?GXiPVElbnRf zX$hQ_t;(Q?ub~?;I0(oHs#tPkj-7kouA~TT$gq5Olete36$QYRgr05qmLA(wKw!^% zM1dWNaczO*wl^L5@!NIApTbx5eM|*h2pe!ypcsk8le(dFh@2fRteF?U)JUwU&}H7t zxpbaEr>ONHz9}Ng!QxO5@eGOk3A}Y&)sRpHxs~yg286P6PU%t-gab3Pw86TM97vO7 zJ{FW3Mp$-Kl~DCYYL&EFz>IO)+3&l!P`#luy=vx3c)P~rrwF^+0q(I$ygy{xK9wf; z6|SnZ0OD77^nC1VAbIPxn9Tq{SS#D`eFj`S$LLciSrX)A;%q_#gxdf#bnHOjQ2El8 zWMtxe6n=Yj;sr84@Ehw4JjEurbVIkuV{;&b(FWr^mffWg(ojB3lwb2r6#=S|ZdDp( z;5S{2cg}S$%VE3dWPHUG|K1X<%bA5B+e5WlJ=;Z{+DS?7l(IcWo>*Tpy|I!kN06{r zo^-6)v}d);^wgXWS&7&4X3QS^n5tSXSG$(X1x$S@KiZ@{ZV+E}Jo5K}MX;aRu?P%G z&N=FeEMd8MQ5(qkF7;d(QCT^{l7NakuAK@@CY%LoN)B=w}dc+!78Y<2hc* zZCe#(d5NebmA8#fx)FvBndIlb1ufNyv`lm>w?`R5^}|b0>25=h$#Y}tsQ`n5+QTNp zspOo%OhQXiV5$-E8G4Xi+D~`icNW5?_hAOfu|enrOvZk;GqdoNmz8G72!WWEPgqm> zXwVqcbD#7#kphFvtc*#@n-WCQ(dU()m6<0=>6;Ka#hF1p3l;(~fq=wekowmu$Qc+0 zl#r;)t>pH&gWyjZp2+1(-u?yl&lG1y%$cP?UP(Pu0|XK@HO5dv!EX%2s++gewkg<7 z+~h`A{{N?y|9|et_mAAQk{tfy!!IrWr94kj3Fs86NS1x*%IDO28T-| zxrE|EE$l%?_x>{M_nz#Z$VPaZXZ`3K1%qF21Dhc+5 zZs(HNu)Z=m2Rv@7x!u|en_cP! zzAlwFWru__f%}aMo0OXpN2!8mP2CqL&G?G0;R=`PWFOC!kQtTBU^ffG^!Tk~-$Bu7 zFBX&BpD4`hQ`faNgBrEWSV`-;`lPZhX>Ax3`Wz5`fMHKn8Ua(ftLQ9pfX}6lN#~vo zSC>K#*M{}qff%ZHq%!naqTsHlSK{Ls+Yc!A*OaRR2se-t=1P}dY|`~qrkac?wI5JU z>YDBm;MPg8C~pmegfhp_?30~#M5yTN(5s-nAE!*LM4@3%js=FH_-(un@>EjIm{^V|hGRgz&;V@0m=pG{4()fFNXmpEK& zgRMvo7}HQEGcicO?Dk&F($R}~zL+SS@5$ET2OzqsTbPNj1hU`5zO+c++cKmL5F^Eq z#Cla~nJzjEZFRB0ZsN<5Zj11f36S7><_HF2k{w}rL*PU*e+{xR@`~|?1EAg4aX6$} zAiLyfsPbJ|jbXWcj+lH@^~-35a*HgXNg*d&2p5xPQc{QHFa;GD5n%PchdoE>v&t7! zXsJ`BKlF}r?j5Nxo5?H$-;mWZL~#0X?ByITrTP|9OI;XoH|k?Z-V2AEHbCm!*yB>C zYjH;c5qS|#DAngRDcPS%W+3~CsrR5dD|Wrdp;xP)9%^_xz|(77C1a6>plX#{8&oNL zK!=zKuTf?uexE&BtUox-4kaZhymM*_m0qoP);m4p38y3!Th;8lx}AseF>0Hra*@)a zYsQh1jGAvpL?7aik_@TQp&_E|39Nu#DgJv9^T^c142fl~6kpj@St&m5Igti#vmhDC zg&^EpLe&>RPJ+6$W5%p489&nd{ZjnFlj$-(@-AeJgmtE~8Z*mT3At)t5}j)HgY*)% za_>h3aI18HaKDPl#cNc8Q{51e!8WNguxJs%nOA+_2K7wlnCHxQEz5}(#ZiIbn=I-NqQ`H5f+K~|1;+HP~t!Z_Lz zIC_=;e|zb_l~%uWlTbVul<>g;K^mh-7H~FdMmF?uC3iq z#JB5$&OK$yo=)h_yn63-ZO{*!?U_FnRN6%(UV@BzWPA0T}ULA>2T3Y=HGoWc?iL}J~Q*9nM~@-lsC504%$RdR1fUr4Ae)uG1OMh_HwOQtI7A_3}BSv;H2G<@~8{cBkah#%2MX#q`IvaA{l)45oQYFWO%K;?&W z3=ig_K9p-9;G}dvmZ;9=TSATEgGM!O3D3Nto&<5p_^mBLs>Cy$i=L>P$ZrWl2nhhk{@(H*E#GtK^it>GcNX7Y{LFzT7p~0z&fNR-`hR=o{Ta9P?g#7sCw4+R%9YLi zr@d7{KpHYt@&87yx;0(+N}_sN&hAgbgUj>@2i+(dKII=tR0quUMf7g!;i6a_G}%;_ z%c{Y@cNQK^RJ+WH{mEe3=u#uaQ{d(@9xu4s(5H7k0s!C?q}<1$4tsu?Nqu2zLo(0dDY#2TcBUx zwS)SwU*VyOZzwFTy(!W%c9vvEl<%1YpwX)%9ZI*@rm1D7ikARhdS!BD{yy6fN`LZWHx-lTg*z`Mi(-H+%Kytu>!^ySCm) zo65%t-01`~+gmKL)DByhc9Fi4fR=kpZJ|rdqYqxyCMvYq?Wk(LRCB+U0Kj`y zzqLfJhqF3xlv8tUhi&jw0<7=V#an1<<#nKw0P9kivE~mad(qP60qX- zYg9tjdp_L)Jm6xpbv|Y5XOov9_vHSRQiTtfrPtOHQ0cB5-=Ac*vh3x9iGr?sVSmy{ z(67@Bx^cSbk0wCcUHSUHrIboFaBsFFJ>>)_yz8uVz3F?u4`*J^z==`@Kac>Xw_kOC z&nHd^J(?)&y?q*#>^sX3CBXCT*PtXs4vXsj31EKv^_be|HfkL!UHFF*aR2rzPd8{z z8A|7WE&(p^%1irGU8&e7J4$AWV>p5gCbthJU@Y!eqbt4Tq`&T3@)VSY`*Vk>$Uv(h>MypMp=`IyJ=ai6j_rS%%k9fR z*lhM_R{8&>Bo!GVGU1qTWa6dWix zP;em6fn+WD7AF7nk@iW*DD6(9ayco2iBaW3PT+(BlbegVp~kg5E=>ZoS%d)20CevF z(W&lj9sn|APvh)^f0ET#e?C!2Y_Co2O6^S}ZDHr#K57eBYtZN}VsKOi;72A9A^>v% z{*&Hi>TtJ;8@N$y^^qfbgsN9$)MmYipHCDd+s&fZ>r?Bh3x7a80aG@#fi41D20Shw z6cp}L1DuOHL*ft^&YjeH!_=-Nz_;DR_1CJ>iZxK@xl4#5A?{QRLF>1p+`}MItA|w(>SV&@ZF^!r^`lvnv7eqy)OBkkeONmn tWCrgVk2IogO&jS++v^qMkVYO(xDM^gt5ff{4<$n^8lAKel|R)Q{C}M6Z?*sc literal 0 HcmV?d00001 From e4eba1012a5daa6975aca1e34d4301be7e28209c Mon Sep 17 00:00:00 2001 From: James Barr Date: Tue, 11 Feb 2025 12:00:21 -0800 Subject: [PATCH 45/56] Keep motif runtime lib at 1.8 --- lib/build.gradle | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/lib/build.gradle b/lib/build.gradle index e5b5bc47..a918dabf 100644 --- a/lib/build.gradle +++ b/lib/build.gradle @@ -6,6 +6,10 @@ plugins { sourceCompatibility = 1.8 targetCompatibility = 1.8 +java { + toolchain.languageVersion.set(JavaLanguageVersion.of(8)) +} + dependencies { // Dagger is part of the API since we generate code which depends on Dagger's API in the consuming gradle module. api deps.dagger From 503040cae92076ad667c6f472086eb1aab4be9f9 Mon Sep 17 00:00:00 2001 From: James Barr Date: Tue, 11 Feb 2025 12:53:58 -0800 Subject: [PATCH 46/56] Update Kotlin & related dependencies to 2.1.0 --- gradle/dependencies.gradle | 25 +++++++++++++------------ 1 file changed, 13 insertions(+), 12 deletions(-) diff --git a/gradle/dependencies.gradle b/gradle/dependencies.gradle index ba434d4f..1092923c 100644 --- a/gradle/dependencies.gradle +++ b/gradle/dependencies.gradle @@ -15,18 +15,18 @@ */ def versions = [ - kotlin: '1.8.20', - ksp: '1.8.20-1.0.11', - ktlint: '0.41.0', - ktfmt: '0.23', + kotlin: '2.1.0', + ksp: '2.1.0-1.0.28', + ktlint: '1.5.0', + ktfmt: '0.54', dagger: '2.47', butterknife: '10.1.0', glide: '4.9.0', - gjf: '1.7', + gjf: '1.8', kotlinpoet: '1.12.0', room: '2.1.0', - roomCompilerProcessing: '2.6.0-alpha02', - dokka: '1.9.10', + roomCompilerProcessing: '2.7.0-alpha13', + dokka: '2.0.0', "gradleIntellijPlugin": [ ide: '2023.2' ], @@ -35,26 +35,27 @@ def versions = [ ext.deps = [ "versions": versions, "build": [ - buildToolsVersion: '30.0.3', - compileSdkVersion: 31, + buildToolsVersion: '33.0.0', + compileSdkVersion: 33, ci: 'true' == System.getenv('CI'), minSdkVersion: 21, targetSdkVersion: 30, gradlePlugins: [ android: 'com.android.tools.build:gradle:7.4.2', + intellij: 'org.jetbrains.intellij:org.jetbrains.intellij.gradle.plugin:1.15.0', kotlin: "org.jetbrains.kotlin:kotlin-gradle-plugin:${versions.kotlin}", ksp: "com.google.devtools.ksp:com.google.devtools.ksp.gradle.plugin:${versions.ksp}", dokka: "org.jetbrains.dokka:dokka-gradle-plugin:${versions.dokka}", mavenPublish: 'com.vanniktech:gradle-maven-publish-plugin:0.27.0', - spotless: "com.diffplug.spotless:spotless-plugin-gradle:5.11.0", + spotless: "com.diffplug.spotless:spotless-plugin-gradle:7.0.2", shadow: "com.github.johnrengelman:shadow:8.1.0", ] ], "kotlin": [ kapt: "org.jetbrains.kotlin:kotlin-annotation-processing-embeddable:${versions.kotlin}", reflection: "org.jetbrains.kotlin:kotlin-reflect:${versions.kotlin}", - stdlib: "org.jetbrains.kotlin:kotlin-stdlib:${versions.kotlin}" + stdlib: "org.jetbrains.kotlin:kotlin-stdlib:${versions.kotlin}", ], "rx": [ android: 'io.reactivex.rxjava2:rxandroid:2.1.1', @@ -82,7 +83,7 @@ ext.deps = [ javapoet: 'com.squareup:javapoet:1.13.0', kotlinpoet: "com.squareup:kotlinpoet:${versions.kotlinpoet}", kotlinpoetInteropMetadata: "com.squareup:kotlinpoet-metadata:${versions.kotlinpoet}", - kotlinxMetadata : 'org.jetbrains.kotlinx:kotlinx-metadata-jvm:0.6.2', + kotlinxMetadata : 'org.jetbrains.kotlinx:kotlinx-metadata-jvm:0.9.0', autoCommon: 'com.google.auto:auto-common:1.1.2', autoService: "com.google.auto.service:auto-service:1.0", commonsCodec: 'commons-codec:commons-codec:1.13', From df1af3d101b0a2120a30260f575e4f12730de9a2 Mon Sep 17 00:00:00 2001 From: James Barr Date: Tue, 11 Feb 2025 12:55:39 -0800 Subject: [PATCH 47/56] Fixup gradle build files --- build.gradle | 1 + intellij/ast/build.gradle | 2 +- intellij/build.gradle | 2 +- 3 files changed, 3 insertions(+), 2 deletions(-) diff --git a/build.gradle b/build.gradle index 23559940..c6faf24c 100644 --- a/build.gradle +++ b/build.gradle @@ -13,6 +13,7 @@ buildscript { } dependencies { classpath deps.build.gradlePlugins.android + classpath deps.build.gradlePlugins.intellij classpath deps.build.gradlePlugins.kotlin classpath deps.build.gradlePlugins.ksp classpath deps.build.gradlePlugins.dokka diff --git a/intellij/ast/build.gradle b/intellij/ast/build.gradle index e68379ca..98255d4c 100644 --- a/intellij/ast/build.gradle +++ b/intellij/ast/build.gradle @@ -1,5 +1,5 @@ plugins { - id "org.jetbrains.intellij" version "1.15.0" + id "org.jetbrains.intellij" id 'org.jetbrains.kotlin.jvm' id 'com.vanniktech.maven.publish' } diff --git a/intellij/build.gradle b/intellij/build.gradle index 244a0e5c..b3f5c29c 100644 --- a/intellij/build.gradle +++ b/intellij/build.gradle @@ -1,5 +1,5 @@ plugins { - id "org.jetbrains.intellij" version "1.15.0" + id "org.jetbrains.intellij" id 'org.jetbrains.kotlin.jvm' id 'com.vanniktech.maven.publish' } From 4a35a55248f2577c1c9ed830b959f183aca3161f Mon Sep 17 00:00:00 2001 From: James Barr Date: Tue, 11 Feb 2025 14:15:23 -0800 Subject: [PATCH 48/56] Fix spotless config --- build.gradle | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/build.gradle b/build.gradle index c6faf24c..f1486618 100644 --- a/build.gradle +++ b/build.gradle @@ -109,7 +109,10 @@ subprojects { } kotlin { target "src/**/*.kt" - ktlint(deps.versions.ktlint).userData(['indent_size': '2', 'continuation_indent_size': '2']) + ktlint(deps.versions.ktlint).editorConfigOverride([ + "indent_size": "2", + "continuation_indent_size": "4" + ]) ktfmt(deps.versions.ktfmt) licenseHeaderFile rootProject.file('config/spotless/copyright.kt') trimTrailingWhitespace() From 8c576ec8afc6687cf97fb2162c5467a2c3b3f7ff Mon Sep 17 00:00:00 2001 From: James Barr Date: Tue, 11 Feb 2025 15:17:54 -0800 Subject: [PATCH 49/56] Suppress function name lint check --- build.gradle | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/build.gradle b/build.gradle index f1486618..3b03f127 100644 --- a/build.gradle +++ b/build.gradle @@ -113,6 +113,10 @@ subprojects { "indent_size": "2", "continuation_indent_size": "4" ]) + suppressLintsFor { + step = 'ktlint' + shortCode = 'standard:function-naming' + } ktfmt(deps.versions.ktfmt) licenseHeaderFile rootProject.file('config/spotless/copyright.kt') trimTrailingWhitespace() From 904122a83c3811f54ffd2315eeb9fc9ff145ab20 Mon Sep 17 00:00:00 2001 From: James Barr Date: Wed, 12 Feb 2025 00:19:02 -0800 Subject: [PATCH 50/56] Run KSP tests with KSP1 --- compiler/src/test/java/motif/compiler/TestHarness.kt | 1 + 1 file changed, 1 insertion(+) diff --git a/compiler/src/test/java/motif/compiler/TestHarness.kt b/compiler/src/test/java/motif/compiler/TestHarness.kt index cab63526..8aca65dc 100644 --- a/compiler/src/test/java/motif/compiler/TestHarness.kt +++ b/compiler/src/test/java/motif/compiler/TestHarness.kt @@ -184,6 +184,7 @@ class TestHarness( classpath = classpath, inheritClasspath = true, kaptProcessors = annotationProcessors, + kotlincArguments = listOf("-language-version", "1.9", "-api-version", "1.9"), symbolProcessorProviders = symbolProcessorProvider?.let { listOf(it) } ?: emptyList(), processorOptions = processorOptions, From 72e578207dbb1e056bc74d1cb179449b6fbf5043 Mon Sep 17 00:00:00 2001 From: James Barr Date: Wed, 12 Feb 2025 14:35:56 -0800 Subject: [PATCH 51/56] Run auto-format using latest ktlint & ktfmt --- ast/src/main/kotlin/motif/ast/IrAnnotated.kt | 9 +- ast/src/main/kotlin/motif/ast/IrClass.kt | 11 +- .../main/kotlin/motif/ast/IrHasModifiers.kt | 16 +- ast/src/main/kotlin/motif/ast/IrMethod.kt | 8 +- ast/src/main/kotlin/motif/ast/IrModifier.kt | 2 +- ast/src/main/kotlin/motif/ast/IrType.kt | 1 + .../test/kotlin/motif/ast/SimpleNameTest.kt | 7 +- .../com/uber/xprocessing/ext/XAnnotation.kt | 30 +- .../com/uber/xprocessing/ext/XElement.kt | 7 +- .../com/uber/xprocessing/ext/XOverrides.kt | 9 +- .../uber/xprocessing/ext/XProcessingEnv.kt | 20 +- .../kotlin/com/uber/xprocessing/ext/XType.kt | 149 +++--- .../com/uber/xprocessing/ext/XTypeElement.kt | 23 +- .../motif/ast/compiler/CompilerAnnotation.kt | 16 +- .../motif/ast/compiler/CompilerClass.kt | 3 +- .../motif/ast/compiler/CompilerField.kt | 2 +- .../motif/ast/compiler/CompilerMethod.kt | 26 +- .../ast/compiler/CompilerMethodParameter.kt | 2 +- .../kotlin/motif/ast/compiler/CompilerType.kt | 25 +- .../main/kotlin/motif/ast/compiler/IrUtil.kt | 9 +- .../motif/ast/compiler/CompilerClassTest.kt | 123 ++--- .../ksp/MotifSymbolProcessorProvider.kt | 9 +- .../kotlin/motif/compiler/CodeGenerator.kt | 37 +- .../motif/compiler/JavaCodeGenerator.kt | 438 ++++++++---------- .../motif/compiler/KotlinCodeGenerator.kt | 419 ++++++++--------- .../motif/compiler/KotlinTypeWorkaround.kt | 66 ++- .../motif/compiler/MotifProcessingStep.kt | 6 +- .../src/main/kotlin/motif/compiler/Names.kt | 28 +- .../main/kotlin/motif/compiler/Processor.kt | 13 +- .../main/kotlin/motif/compiler/ScopeImpl.kt | 66 +-- .../kotlin/motif/compiler/ScopeImplFactory.kt | 239 +++++----- .../main/kotlin/motif/compiler/XFunSpec.kt | 25 +- .../kotlin/motif/compiler/XNameVisitor.kt | 95 ++-- compiler/src/test/java/license/LicenseTest.kt | 3 +- .../src/test/java/motif/compiler/NamesTest.kt | 37 +- .../src/test/java/motif/compiler/ProGuard.kt | 25 +- .../test/java/motif/compiler/TestHarness.kt | 99 ++-- .../java/motif/compiler/TestParameters.kt | 4 +- core/src/main/kotlin/motif/core/Cycle.kt | 7 +- .../main/kotlin/motif/core/ProcessingError.kt | 2 +- .../main/kotlin/motif/core/ResolvedGraph.kt | 15 +- core/src/main/kotlin/motif/core/ScopeGraph.kt | 35 +- core/src/main/kotlin/motif/core/State.kt | 62 ++- .../AccessMethodParametersHandler.kt | 4 +- .../errormessage/CannotResolveTypeHandler.kt | 4 +- .../DependencyMethodWithParametersHandler.kt | 6 +- .../DuplicatedChildParameterSourceHandler.kt | 6 +- .../DuplicatedDependenciesMethodHandler.kt | 6 +- .../kotlin/motif/errormessage/ErrorHandler.kt | 75 ++- .../kotlin/motif/errormessage/ErrorMessage.kt | 13 +- .../InjectAnnotationRequiredHandler.kt | 4 +- .../InvalidFactoryMethodHandler.kt | 4 +- .../errormessage/InvalidQualifierHandler.kt | 4 +- .../NoSuitableConstructorHandler.kt | 4 +- .../kotlin/motif/errormessage/NodeHandler.kt | 61 +-- .../NotAssignableBindsMethodHandler.kt | 4 +- .../NullableDynamicDependencyHandler.kt | 4 +- .../NullableFactoryMethodHandler.kt | 4 +- .../errormessage/NullableParameterHandler.kt | 4 +- .../NullableSpreadMethodHandler.kt | 4 +- .../ObjectsConstructorFoundHandler.kt | 4 +- .../errormessage/ObjectsFieldFoundHandler.kt | 4 +- .../ScopeExtendsScopeMethodHandler.kt | 4 +- .../ScopeMustBeAnInterfaceHandler.kt | 4 +- .../errormessage/UnexposedSourceHandler.kt | 4 +- .../errormessage/UnspreadableTypeHandler.kt | 4 +- .../VoidDependenciesMethodHandler.kt | 4 +- .../errormessage/VoidFactoryMethodHandler.kt | 4 +- .../errormessage/VoidScopeMethodHandler.kt | 4 +- .../motif/ast/intellij/IntelliJAnnotation.kt | 14 +- .../motif/ast/intellij/IntelliJClass.kt | 15 +- .../motif/ast/intellij/IntelliJMethod.kt | 2 +- .../ast/intellij/IntelliJMethodParameter.kt | 2 +- .../kotlin/motif/ast/intellij/IntelliJType.kt | 11 +- .../main/kotlin/motif/ast/intellij/IrUtil.kt | 15 +- .../ast/intellij/IntelliJAnnotationTest.kt | 69 ++- .../motif/ast/intellij/IntelliJClassTest.kt | 68 ++- .../motif/ast/intellij/IntelliJKotlinTest.kt | 9 +- .../kotlin/motif/intellij/GraphFactory.kt | 23 +- .../kotlin/motif/intellij/GraphManager.kt | 31 +- .../kotlin/motif/intellij/MotifService.kt | 16 +- .../main/kotlin/motif/intellij/PsiUtils.kt | 26 +- .../motif/intellij/ScopeHierarchyUtils.kt | 92 ++-- .../actions/MotifAncestorGraphAction.kt | 4 +- .../intellij/actions/MotifUsageAction.kt | 4 +- .../hierarchy/ErrorHierarchyBrowser.kt | 43 +- .../hierarchy/HierarchyBrowserBase.kt | 5 +- .../hierarchy/ScopeHierarchyBrowser.kt | 57 ++- .../hierarchy/ScopeHierarchyTreeStructure.kt | 97 +++- .../ScopePropertyHierarchyBrowser.kt | 76 +-- .../hierarchy/UsageHierarchyBrowser.kt | 43 +- ...eHierarchyDependenciesSectionDescriptor.kt | 6 +- .../ScopeHierarchyDependencyDescriptor.kt | 9 +- .../ScopeHierarchyErrorDescriptor.kt | 172 ++++--- .../ScopeHierarchyNodeDescriptor.kt | 13 +- ...tor.kt => ScopeHierarchyRootDescriptor.kt} | 2 +- .../ScopeHierarchyRootErrorDescriptor.kt | 7 +- .../ScopeHierarchyScopeAncestorDescriptor.kt | 2 +- .../ScopeHierarchyScopeDescriptor.kt | 10 +- .../ScopeHierarchySimpleDescriptor.kt | 10 +- .../ScopeHierarchySinkDescriptor.kt | 63 +-- .../ScopeHierarchySinkDetailsDescriptor.kt | 9 +- .../ScopeHierarchySinksSectionDescriptor.kt | 10 +- .../ScopeHierarchySourceDescriptor.kt | 56 ++- .../ScopeHierarchySourceDetailsDescriptor.kt | 9 +- ...erarchySourcesAndSinksSectionDescriptor.kt | 10 +- .../ScopeHierarchySourcesSectionDescriptor.kt | 10 +- .../ScopeHierarchyUsageSectionDescriptor.kt | 2 +- ...opeHierarchyUsageSinksSectionDescriptor.kt | 6 +- ...eHierarchyUsageSourcesSectionDescriptor.kt | 6 +- .../ScopeHierarchyLineMarkerProvider.kt | 3 +- .../ScopeNavigationLineMarkerProvider.kt | 20 +- .../motif/intellij/ui/MotifErrorPanel.kt | 2 +- .../motif/intellij/ui/MotifScopePanel.kt | 14 +- .../test/kotlin/motif/intellij/TestHarness.kt | 25 +- .../main/kotlin/motif/models/Dependencies.kt | 12 +- .../main/kotlin/motif/models/FactoryMethod.kt | 33 +- .../src/main/kotlin/motif/models/Objects.kt | 5 +- .../main/kotlin/motif/models/ParsingError.kt | 16 +- models/src/main/kotlin/motif/models/Scope.kt | 4 +- .../main/kotlin/motif/models/ScopeMethod.kt | 8 +- models/src/main/kotlin/motif/models/Spread.kt | 8 +- models/src/main/kotlin/motif/models/Type.kt | 15 +- .../kotlin/motif/models/motif/BaseTest.kt | 8 +- .../motif/models/motif/ModelsSmokeTest.kt | 63 ++- .../src/main/java/motif/sample/Greeter.kt | 4 +- .../src/main/java/motif/sample/Greeter.kt | 4 +- .../java/motif/stubcompiler/StubProcessor.kt | 36 +- .../kotlin/motif/viewmodel/GraphViewModel.kt | 20 +- .../motif/viewmodel/ProvidedDependency.kt | 2 +- .../kotlin/motif/viewmodel/ScopeViewModel.kt | 2 +- .../kotlin/motif/viewmodel/TestRenderer.kt | 21 +- 132 files changed, 1996 insertions(+), 1938 deletions(-) rename intellij/src/main/kotlin/motif/intellij/hierarchy/descriptor/{ScopeHierarchyRootScopeNodeDescriptor.kt => ScopeHierarchyRootDescriptor.kt} (97%) diff --git a/ast/src/main/kotlin/motif/ast/IrAnnotated.kt b/ast/src/main/kotlin/motif/ast/IrAnnotated.kt index 436077fd..e05ba649 100644 --- a/ast/src/main/kotlin/motif/ast/IrAnnotated.kt +++ b/ast/src/main/kotlin/motif/ast/IrAnnotated.kt @@ -21,11 +21,8 @@ interface IrAnnotated { val annotations: List - fun hasAnnotation(annotationClass: KClass): Boolean { - return annotations.any { it.matchesClass(annotationClass) } - } + fun hasAnnotation(annotationClass: KClass): Boolean = + annotations.any { it.matchesClass(annotationClass) } - fun isNullable(): Boolean { - return annotations.any { it.className?.endsWith("Nullable") == true } - } + fun isNullable(): Boolean = annotations.any { it.className?.endsWith("Nullable") == true } } diff --git a/ast/src/main/kotlin/motif/ast/IrClass.kt b/ast/src/main/kotlin/motif/ast/IrClass.kt index cb2f8c62..815a3e4a 100644 --- a/ast/src/main/kotlin/motif/ast/IrClass.kt +++ b/ast/src/main/kotlin/motif/ast/IrClass.kt @@ -34,16 +34,13 @@ interface IrClass : IrAnnotated, IrHasModifiers { val simpleName: String get() = type.simpleName - fun hasNonDefaultConstructor(): Boolean { - return constructors.any { it.hasParameters() } - } + fun hasNonDefaultConstructor(): Boolean = constructors.any { it.hasParameters() } - fun annotatedInnerClass(annotationClass: KClass): IrClass? { - return nestedClasses.find { it.hasAnnotation(annotationClass) } - } + fun annotatedInnerClass(annotationClass: KClass): IrClass? = + nestedClasses.find { it.hasAnnotation(annotationClass) } enum class Kind { CLASS, - INTERFACE + INTERFACE, } } diff --git a/ast/src/main/kotlin/motif/ast/IrHasModifiers.kt b/ast/src/main/kotlin/motif/ast/IrHasModifiers.kt index c8edf7c4..efa54737 100644 --- a/ast/src/main/kotlin/motif/ast/IrHasModifiers.kt +++ b/ast/src/main/kotlin/motif/ast/IrHasModifiers.kt @@ -19,19 +19,11 @@ interface IrHasModifiers { val modifiers: Set - fun isStatic(): Boolean { - return IrModifier.STATIC in modifiers - } + fun isStatic(): Boolean = IrModifier.STATIC in modifiers - fun isPrivate(): Boolean { - return IrModifier.PRIVATE in modifiers - } + fun isPrivate(): Boolean = IrModifier.PRIVATE in modifiers - fun isPublic(): Boolean { - return IrModifier.PUBLIC in modifiers - } + fun isPublic(): Boolean = IrModifier.PUBLIC in modifiers - fun isAbstract(): Boolean { - return IrModifier.ABSTRACT in modifiers - } + fun isAbstract(): Boolean = IrModifier.ABSTRACT in modifiers } diff --git a/ast/src/main/kotlin/motif/ast/IrMethod.kt b/ast/src/main/kotlin/motif/ast/IrMethod.kt index 0b6190b0..c782493c 100644 --- a/ast/src/main/kotlin/motif/ast/IrMethod.kt +++ b/ast/src/main/kotlin/motif/ast/IrMethod.kt @@ -21,11 +21,7 @@ interface IrMethod : IrAnnotated, IrHasModifiers { val name: String val isConstructor: Boolean - fun hasParameters(): Boolean { - return parameters.isNotEmpty() - } + fun hasParameters(): Boolean = parameters.isNotEmpty() - fun isVoid(): Boolean { - return returnType.isVoid - } + fun isVoid(): Boolean = returnType.isVoid } diff --git a/ast/src/main/kotlin/motif/ast/IrModifier.kt b/ast/src/main/kotlin/motif/ast/IrModifier.kt index 2c53089d..021d1553 100644 --- a/ast/src/main/kotlin/motif/ast/IrModifier.kt +++ b/ast/src/main/kotlin/motif/ast/IrModifier.kt @@ -30,5 +30,5 @@ enum class IrModifier { VOLATILE, DEFAULT, OPEN, - TRANSITIVE + TRANSITIVE, } diff --git a/ast/src/main/kotlin/motif/ast/IrType.kt b/ast/src/main/kotlin/motif/ast/IrType.kt index 81d3af18..ed10d798 100644 --- a/ast/src/main/kotlin/motif/ast/IrType.kt +++ b/ast/src/main/kotlin/motif/ast/IrType.kt @@ -25,6 +25,7 @@ interface IrType : IrEquivalence { get() = simpleName(qualifiedName) fun resolveClass(): IrClass? + fun isAssignableTo(type: IrType): Boolean } diff --git a/ast/src/test/kotlin/motif/ast/SimpleNameTest.kt b/ast/src/test/kotlin/motif/ast/SimpleNameTest.kt index 61efab06..675ff38d 100644 --- a/ast/src/test/kotlin/motif/ast/SimpleNameTest.kt +++ b/ast/src/test/kotlin/motif/ast/SimpleNameTest.kt @@ -33,13 +33,12 @@ class SimpleNameTest(private val qualifiedName: String, private val expectedSimp "java.util.List" to "List", "java.util.Map" to "Map", "java.util.Map" to - "Map") + "Map", + ) @JvmStatic @Parameterized.Parameters(name = "{0}") - fun data(): Collection> { - return tests.map { (key, value) -> arrayOf(key, value) } - } + fun data(): Collection> = tests.map { (key, value) -> arrayOf(key, value) } } @Test diff --git a/compiler/ast/src/main/kotlin/com/uber/xprocessing/ext/XAnnotation.kt b/compiler/ast/src/main/kotlin/com/uber/xprocessing/ext/XAnnotation.kt index 04dbf2a2..19982c74 100644 --- a/compiler/ast/src/main/kotlin/com/uber/xprocessing/ext/XAnnotation.kt +++ b/compiler/ast/src/main/kotlin/com/uber/xprocessing/ext/XAnnotation.kt @@ -28,25 +28,23 @@ import com.google.auto.common.AnnotationMirrors * Used to find equivalence of two XAnnotation since AnnotationMirrors.equivalence() only applies to * the Javac backend. */ -fun XAnnotation.isEquivalent(other: XAnnotation, env: XProcessingEnv): Boolean { - return if (env.backend == XProcessingEnv.Backend.JAVAC) { - val key = AnnotationMirrors.equivalence().wrap(this.toJavac()) - val otherKey = AnnotationMirrors.equivalence().wrap(other.toJavac()) - key == otherKey - } else { - (type.isEquivalent(other.type, env) && - annotationValues.size == other.annotationValues.size && - annotationValues.zip(other.annotationValues).all { (lhs, rhs) -> lhs.isEquivalent(rhs) }) - } -} +fun XAnnotation.isEquivalent(other: XAnnotation, env: XProcessingEnv): Boolean = + if (env.backend == XProcessingEnv.Backend.JAVAC) { + val key = AnnotationMirrors.equivalence().wrap(this.toJavac()) + val otherKey = AnnotationMirrors.equivalence().wrap(other.toJavac()) + key == otherKey + } else { + (type.isEquivalent(other.type, env) && + annotationValues.size == other.annotationValues.size && + annotationValues.zip(other.annotationValues).all { (lhs, rhs) -> lhs.isEquivalent(rhs) }) + } /** * Used to find equivalence of two XAnnotation since AnnotationMirrors.equivalence() only applies to * the Javac backend. */ -fun XAnnotationValue.isEquivalent(other: XAnnotationValue): Boolean { - return this.name == other.name && this.value == other.value -} +fun XAnnotationValue.isEquivalent(other: XAnnotationValue): Boolean = + this.name == other.name && this.value == other.value /** Cleans up differences in the toString() methods between the JAVAC and KSP backends. */ fun XAnnotation.toPrettyString(): String { @@ -55,7 +53,9 @@ fun XAnnotation.toPrettyString(): String { .map { if (it.name == "value") { "\"${it.value}\"" - } else "${it.name} = ${it.value}" + } else { + "${it.name} = ${it.value}" + } } .joinToString(", ") val annotationValuesList = diff --git a/compiler/ast/src/main/kotlin/com/uber/xprocessing/ext/XElement.kt b/compiler/ast/src/main/kotlin/com/uber/xprocessing/ext/XElement.kt index c9a5dbc6..e8e98677 100644 --- a/compiler/ast/src/main/kotlin/com/uber/xprocessing/ext/XElement.kt +++ b/compiler/ast/src/main/kotlin/com/uber/xprocessing/ext/XElement.kt @@ -33,13 +33,10 @@ val XElement.modifiers: List if (isFinal()) modifiers += Modifier.FINAL if (isTransient()) modifiers += Modifier.TRANSIENT return@let modifiers - } - ?: emptyList() + } ?: emptyList() } val XElement.modifierNames: List get() = modifiers.map { it.name } -fun XHasModifiers.isPackagePrivate(): Boolean { - return !isPrivate() && !isProtected() && !isPublic() -} +fun XHasModifiers.isPackagePrivate(): Boolean = !isPrivate() && !isProtected() && !isPublic() diff --git a/compiler/ast/src/main/kotlin/com/uber/xprocessing/ext/XOverrides.kt b/compiler/ast/src/main/kotlin/com/uber/xprocessing/ext/XOverrides.kt index 38be1a3f..bb7c9abd 100644 --- a/compiler/ast/src/main/kotlin/com/uber/xprocessing/ext/XOverrides.kt +++ b/compiler/ast/src/main/kotlin/com/uber/xprocessing/ext/XOverrides.kt @@ -44,7 +44,11 @@ object XOverrides { return when (env.backend) { XProcessingEnv.Backend.JAVAC -> { MoreElements.overrides( - overrider.toJavac(), overridden.toJavac(), inType.toJavac(), env.toJavac().typeUtils) + overrider.toJavac(), + overridden.toJavac(), + inType.toJavac(), + env.toJavac().typeUtils, + ) false } XProcessingEnv.Backend.KSP -> { @@ -141,7 +145,8 @@ enum class Visibility { DEFAULT, PROTECTED, INTERNAL, - PUBLIC; + PUBLIC, + ; companion object { fun of(element: XMethodElement) = diff --git a/compiler/ast/src/main/kotlin/com/uber/xprocessing/ext/XProcessingEnv.kt b/compiler/ast/src/main/kotlin/com/uber/xprocessing/ext/XProcessingEnv.kt index fe56acd8..da74c5ab 100644 --- a/compiler/ast/src/main/kotlin/com/uber/xprocessing/ext/XProcessingEnv.kt +++ b/compiler/ast/src/main/kotlin/com/uber/xprocessing/ext/XProcessingEnv.kt @@ -25,14 +25,12 @@ val XProcessingEnv.typeUtils get() = XTypeUtils /** Provides access to KSP's resolver since XProcessing does not give us access */ -fun XProcessingEnv.resolver(): Resolver? { - return if (backend == XProcessingEnv.Backend.KSP) { - Class.forName("androidx.room.compiler.processing.ksp.KspProcessingEnv") - ?.getDeclaredField("_resolver") - ?.apply { isAccessible = true } - ?.get(this) as - Resolver? - } else { - null - } -} +fun XProcessingEnv.resolver(): Resolver? = + if (backend == XProcessingEnv.Backend.KSP) { + Class.forName("androidx.room.compiler.processing.ksp.KspProcessingEnv") + ?.getDeclaredField("_resolver") + ?.apply { isAccessible = true } + ?.get(this) as Resolver? + } else { + null + } diff --git a/compiler/ast/src/main/kotlin/com/uber/xprocessing/ext/XType.kt b/compiler/ast/src/main/kotlin/com/uber/xprocessing/ext/XType.kt index d35c2bd4..86a7044c 100644 --- a/compiler/ast/src/main/kotlin/com/uber/xprocessing/ext/XType.kt +++ b/compiler/ast/src/main/kotlin/com/uber/xprocessing/ext/XType.kt @@ -95,20 +95,18 @@ fun TypeName.containsWildcardType(): Boolean { } /** Returns a TypeName with any Wildcard types recursively removed. */ -fun TypeName.removeWildcardType(): TypeName { - return when (this) { - is WildcardTypeName -> this.upperBounds.first() ?: TypeName.OBJECT - is ParameterizedTypeName -> { - val args = this.typeArguments.map { it.removeWildcardType() }.toTypedArray() - ParameterizedTypeName.get(this.rawType, *args) +fun TypeName.removeWildcardType(): TypeName = + when (this) { + is WildcardTypeName -> this.upperBounds.first() ?: TypeName.OBJECT + is ParameterizedTypeName -> { + val args = this.typeArguments.map { it.removeWildcardType() }.toTypedArray() + ParameterizedTypeName.get(this.rawType, *args) + } + else -> this } - else -> this - } -} -fun TypeName.removeWildcardTypeIfContains(): TypeName { - return if (this.containsWildcardType()) this.removeWildcardType() else this -} +fun TypeName.removeWildcardTypeIfContains(): TypeName = + if (this.containsWildcardType()) this.removeWildcardType() else this /** * This adds extra handling to Java TypeNames so that when it is based on an XType that has type @@ -116,7 +114,7 @@ fun TypeName.removeWildcardTypeIfContains(): TypeName { * with Kotlin types. */ fun com.squareup.javapoet.TypeName.withRawTypeFix( - env: XProcessingEnv + env: XProcessingEnv, ): com.squareup.javapoet.TypeName { if (env.backend == XProcessingEnv.Backend.JAVAC) { return when (this) { @@ -128,8 +126,7 @@ fun com.squareup.javapoet.TypeName.withRawTypeFix( val mirror = env.findType(this.toString()) if (mirror != null && mirror.typeArguments.isNotEmpty() && "<" !in this.toString()) { val args = - mirror - .typeArguments + mirror.typeArguments .map { WildcardTypeName.subtypeOf(com.squareup.javapoet.TypeName.OBJECT) } .toTypedArray() ParameterizedTypeName.get(this, *args) @@ -147,42 +144,40 @@ fun com.squareup.javapoet.TypeName.withRawTypeFix( * Used to find equivalence of two XType since MoreTypes.equivalence() only applies to the Javac * backend. */ -fun XType.isEquivalent(other: XType, env: XProcessingEnv): Boolean { - return when (env.backend) { - XProcessingEnv.Backend.JAVAC -> { - val key = MoreTypes.equivalence().wrap(this.toJavac()) - val otherKey = MoreTypes.equivalence().wrap(other.toJavac()) - key == otherKey - } - XProcessingEnv.Backend.KSP -> { - if ("NonExistentClass" in typeName.toString() || - "NonExistentClass" in other.typeName.toString()) { - this.qualifiedName(env) == other.qualifiedName(env) - } else { - this.typeName.removeWildcardTypeIfContains() == - other.typeName.removeWildcardTypeIfContains() +fun XType.isEquivalent(other: XType, env: XProcessingEnv): Boolean = + when (env.backend) { + XProcessingEnv.Backend.JAVAC -> { + val key = MoreTypes.equivalence().wrap(this.toJavac()) + val otherKey = MoreTypes.equivalence().wrap(other.toJavac()) + key == otherKey + } + XProcessingEnv.Backend.KSP -> { + if ("NonExistentClass" in typeName.toString() || + "NonExistentClass" in other.typeName.toString()) { + this.qualifiedName(env) == other.qualifiedName(env) + } else { + this.typeName.removeWildcardTypeIfContains() == + other.typeName.removeWildcardTypeIfContains() + } } } - } -} /** * Used to find the hash of an XType since MoreTypes.equivalence().hashCode() only applies to the * Javac backend. */ -fun XType.hash(): Int { - return try { - MoreTypes.equivalence().wrap(this.toJavac()).hashCode() - } catch (t: Throwable) { - if (typeArguments.any { it.typeName is WildcardTypeName && it.typeName.toString() != "?" }) { - extendsBoundOrSelf().typeName.toString().hashCode() - } else if (this.hasCollectionType()) { - typeName.removeWildcardTypeIfContains().toString().hashCode() - } else { - hashCode() +fun XType.hash(): Int = + try { + MoreTypes.equivalence().wrap(this.toJavac()).hashCode() + } catch (t: Throwable) { + if (typeArguments.any { it.typeName is WildcardTypeName && it.typeName.toString() != "?" }) { + extendsBoundOrSelf().typeName.toString().hashCode() + } else if (this.hasCollectionType()) { + typeName.removeWildcardTypeIfContains().toString().hashCode() + } else { + hashCode() + } } - } -} fun XType.isInternal(): Boolean { val ksType = @@ -190,8 +185,7 @@ fun XType.isInternal(): Boolean { Class.forName("androidx.room.compiler.processing.ksp.KspType") ?.getDeclaredField("ksType") ?.apply { isAccessible = true } - ?.get(this) as? - KSType + ?.get(this) as? KSType } catch (throwable: Throwable) { null } @@ -206,15 +200,14 @@ fun KSType.isRaw(): Boolean { return toString().startsWith("raw ") } -fun XType.makeNonNullByDefault(): XType { - return try { - if (nullability == XNullability.UNKNOWN) makeNonNullable() else this - } catch (e: IllegalStateException) { - // Workaround for tests since we can't call XType#nullibility for types - // created with TypeMirror#toXProcessing(XProcessingEnv) - this - } -} +fun XType.makeNonNullByDefault(): XType = + try { + if (nullability == XNullability.UNKNOWN) makeNonNullable() else this + } catch (e: IllegalStateException) { + // Workaround for tests since we can't call XType#nullibility for types + // created with TypeMirror#toXProcessing(XProcessingEnv) + this + } @OptIn(KspExperimental::class) fun XType.mapToJavaType(env: XProcessingEnv): XType { @@ -225,12 +218,12 @@ fun XType.mapToJavaType(env: XProcessingEnv): XType { env.resolver() ?.getJavaClassByName(toKS().declaration.qualifiedName?.asString().orEmpty()) ?.toXProcessing(env) - ?.type - ?: return this + ?.type ?: return this } else { val rawTypeName = resolver.mapKotlinNameToJava( - typeElement?.type?.toKS()?.declaration?.qualifiedName?.asString().orEmpty()) + typeElement?.type?.toKS()?.declaration?.qualifiedName?.asString().orEmpty(), + ) val rawType = env.resolver()?.getJavaClassByName(rawTypeName)?.toXProcessing(env) ?: return this val types = @@ -238,7 +231,8 @@ fun XType.mapToJavaType(env: XProcessingEnv): XType { .map { val typeArgName = resolver.mapKotlinNameToJava( - it.toKS().declaration.qualifiedName?.asString().orEmpty()) + it.toKS().declaration.qualifiedName?.asString().orEmpty(), + ) env.resolver()?.getJavaClassByName(typeArgName)?.toXProcessing(env)?.type ?: return this } @@ -289,32 +283,25 @@ internal fun Resolver.mapJavaNameToKotlin(qualifiedName: String): String { return mapJavaNameToKotlin(ksName)?.asString() ?: qualifiedName } -fun XType.isDeclaredType(): Boolean { - return typeElement?.let { - when { - it.isClass() -> true - it.isInterface() -> true - it.isEnum() -> true - it.isAnnotationClass() -> true - it.isKotlinObject() -> true - else -> false - } - } - ?: false -} +fun XType.isDeclaredType(): Boolean = + typeElement?.let { + when { + it.isClass() -> true + it.isInterface() -> true + it.isEnum() -> true + it.isAnnotationClass() -> true + it.isKotlinObject() -> true + else -> false + } + } ?: false -fun XType.isEnum(): Boolean { - return typeElement?.isEnum() ?: false -} +fun XType.isEnum(): Boolean = typeElement?.isEnum() ?: false -fun XType.isPrimitive(): Boolean { - return typeName.isPrimitive -} +fun XType.isPrimitive(): Boolean = typeName.isPrimitive -private fun XType.hasCollectionType(): Boolean { - return this.typeElement?.name.orEmpty() in collectionTypes || - typeArguments.any { it.hasCollectionType() } -} +private fun XType.hasCollectionType(): Boolean = + this.typeElement?.name.orEmpty() in collectionTypes || + typeArguments.any { it.hasCollectionType() } private val collectionTypes = setOf("MutableList", "MutableSet", "MutableCollection", "List", "Set", "Collection") diff --git a/compiler/ast/src/main/kotlin/com/uber/xprocessing/ext/XTypeElement.kt b/compiler/ast/src/main/kotlin/com/uber/xprocessing/ext/XTypeElement.kt index ee132563..bb2a28f2 100644 --- a/compiler/ast/src/main/kotlin/com/uber/xprocessing/ext/XTypeElement.kt +++ b/compiler/ast/src/main/kotlin/com/uber/xprocessing/ext/XTypeElement.kt @@ -35,7 +35,7 @@ import motif.ast.compiler.CompilerClass */ fun XTypeElement.getLocalAndInheritedMethods( env: XProcessingEnv, - useMoreElements: Boolean = true + useMoreElements: Boolean = true, ): List { val nonPrivateInstanceMethods = this.getAllNonPrivateInstanceMethods() @@ -71,14 +71,13 @@ fun XTypeElement.getLocalAndInheritedMethods( /** Return where or not this XTypeElement was from an XType defined in Kotlin */ @OptIn(KotlinPoetMetadataPreview::class) -fun XTypeElement?.isKotlinSource(env: XProcessingEnv): Boolean { - return when (env.backend) { - XProcessingEnv.Backend.JAVAC -> - try { - this?.toJavac()?.toKmClass() != null - } catch (e: Throwable) { - false - } - XProcessingEnv.Backend.KSP -> true - } -} +fun XTypeElement?.isKotlinSource(env: XProcessingEnv): Boolean = + when (env.backend) { + XProcessingEnv.Backend.JAVAC -> + try { + this?.toJavac()?.toKmClass() != null + } catch (e: Throwable) { + false + } + XProcessingEnv.Backend.KSP -> true + } diff --git a/compiler/ast/src/main/kotlin/motif/ast/compiler/CompilerAnnotation.kt b/compiler/ast/src/main/kotlin/motif/ast/compiler/CompilerAnnotation.kt index d6f15339..573a571c 100644 --- a/compiler/ast/src/main/kotlin/motif/ast/compiler/CompilerAnnotation.kt +++ b/compiler/ast/src/main/kotlin/motif/ast/compiler/CompilerAnnotation.kt @@ -43,14 +43,14 @@ class CompilerAnnotation(val env: XProcessingEnv, val mirror: XAnnotation) : IrA val executableElement = annotationMethods.firstOrNull { it.jvmName == annotationValue.name } ?: throw IllegalStateException( - "No matching annotations for ${annotationValue.name} in ${mirror.annotationValues.map { it.name }.joinToString(separator = ", ")}") + "No matching annotations for ${annotationValue.name} in ${mirror.annotationValues.map { it.name }.joinToString(separator = ", ")}", + ) CompilerMethod(env, mirror.type, executableElement.executableType, executableElement) } } - override fun matchesClass(annotationClass: KClass): Boolean { - return annotationClass.java.name == className - } + override fun matchesClass(annotationClass: KClass): Boolean = + annotationClass.java.name == className override fun equals(other: Any?): Boolean { if (this === other) return true @@ -63,11 +63,7 @@ class CompilerAnnotation(val env: XProcessingEnv, val mirror: XAnnotation) : IrA return true } - override fun hashCode(): Int { - return pretty.hashCode() - } + override fun hashCode(): Int = pretty.hashCode() - override fun toString(): String { - return pretty - } + override fun toString(): String = pretty } diff --git a/compiler/ast/src/main/kotlin/motif/ast/compiler/CompilerClass.kt b/compiler/ast/src/main/kotlin/motif/ast/compiler/CompilerClass.kt index 61a824b8..0f9ed2f5 100644 --- a/compiler/ast/src/main/kotlin/motif/ast/compiler/CompilerClass.kt +++ b/compiler/ast/src/main/kotlin/motif/ast/compiler/CompilerClass.kt @@ -90,7 +90,8 @@ class CompilerClass(override val env: XProcessingEnv, val declaredType: XType) : typeElement.getEnclosedTypeElements().map { typeElement -> if (typeElement.type.isError()) { throw IllegalStateException( - "Could not resolve type for nested class: ${typeElement.qualifiedName}") + "Could not resolve type for nested class: ${typeElement.qualifiedName}", + ) } CompilerClass(env, typeElement.type) } diff --git a/compiler/ast/src/main/kotlin/motif/ast/compiler/CompilerField.kt b/compiler/ast/src/main/kotlin/motif/ast/compiler/CompilerField.kt index 2d3e6e90..7a4fb55f 100644 --- a/compiler/ast/src/main/kotlin/motif/ast/compiler/CompilerField.kt +++ b/compiler/ast/src/main/kotlin/motif/ast/compiler/CompilerField.kt @@ -25,7 +25,7 @@ import motif.ast.IrType @OptIn(ExperimentalProcessingApi::class) class CompilerField( override val env: XProcessingEnv, - private val variableElement: XVariableElement + private val variableElement: XVariableElement, ) : IrUtil, IrField { override val type: IrType by lazy { CompilerType(env, variableElement.type) } diff --git a/compiler/ast/src/main/kotlin/motif/ast/compiler/CompilerMethod.kt b/compiler/ast/src/main/kotlin/motif/ast/compiler/CompilerMethod.kt index 7fa0af81..7aae4d64 100644 --- a/compiler/ast/src/main/kotlin/motif/ast/compiler/CompilerMethod.kt +++ b/compiler/ast/src/main/kotlin/motif/ast/compiler/CompilerMethod.kt @@ -38,7 +38,7 @@ class CompilerMethod( override val env: XProcessingEnv, val owner: XType, val type: XExecutableType, - val element: XExecutableElement + val element: XExecutableElement, ) : IrMethod, IrUtil { override val name: String = @@ -47,7 +47,8 @@ class CompilerMethod( is XConstructorElement -> "" else -> throw IllegalStateException( - "Could not find name for unknown XExecutableElement kind: ${element.kindName()}") + "Could not find name for unknown XExecutableElement kind: ${element.kindName()}", + ) } override val isConstructor: Boolean = element.isConstructor() @@ -75,19 +76,18 @@ class CompilerMethod( returnType } - override fun isVoid(): Boolean { - return when (env.backend) { - XProcessingEnv.Backend.JAVAC -> returnType.isVoid - XProcessingEnv.Backend.KSP -> { - val returnTypeMirror = (returnType as CompilerType).mirror - if (returnTypeMirror.isError()) { - element.toKS().returnType == null - } else { - returnTypeMirror.isVoid() + override fun isVoid(): Boolean = + when (env.backend) { + XProcessingEnv.Backend.JAVAC -> returnType.isVoid + XProcessingEnv.Backend.KSP -> { + val returnTypeMirror = (returnType as CompilerType).mirror + if (returnTypeMirror.isError()) { + element.toKS().returnType == null + } else { + returnTypeMirror.isVoid() + } } } - } - } val isSynthetic by lazy { env.backend == XProcessingEnv.Backend.KSP && "synthetic" in element.executableType.toString() diff --git a/compiler/ast/src/main/kotlin/motif/ast/compiler/CompilerMethodParameter.kt b/compiler/ast/src/main/kotlin/motif/ast/compiler/CompilerMethodParameter.kt index cef0db8b..541c4f88 100644 --- a/compiler/ast/src/main/kotlin/motif/ast/compiler/CompilerMethodParameter.kt +++ b/compiler/ast/src/main/kotlin/motif/ast/compiler/CompilerMethodParameter.kt @@ -27,7 +27,7 @@ import motif.ast.IrType class CompilerMethodParameter( override val env: XProcessingEnv, val element: XVariableElement, - val typeMirror: XType + val typeMirror: XType, ) : IrUtil, IrParameter { override val type: IrType by lazy { diff --git a/compiler/ast/src/main/kotlin/motif/ast/compiler/CompilerType.kt b/compiler/ast/src/main/kotlin/motif/ast/compiler/CompilerType.kt index 8245e55c..55503b44 100644 --- a/compiler/ast/src/main/kotlin/motif/ast/compiler/CompilerType.kt +++ b/compiler/ast/src/main/kotlin/motif/ast/compiler/CompilerType.kt @@ -37,9 +37,7 @@ class CompilerType(private val env: XProcessingEnv, mirror: XType) : IrType { val mirror = mirror.makeNonNullByDefault() - fun isInterface(): Boolean { - return IrClass.Kind.INTERFACE == resolveClass()?.kind - } + fun isInterface(): Boolean = IrClass.Kind.INTERFACE == resolveClass()?.kind override val qualifiedName: String by lazy { mirror.qualifiedName(env) } @@ -47,9 +45,8 @@ class CompilerType(private val env: XProcessingEnv, mirror: XType) : IrType { override val isPrimitive: Boolean by lazy { mirror.isPrimitive() } - override fun resolveClass(): IrClass? { - return if (!mirror.isDeclaredType()) null else CompilerClass(env, mirror) - } + override fun resolveClass(): IrClass? = + if (!mirror.isDeclaredType()) null else CompilerClass(env, mirror) override fun isAssignableTo(type: IrType): Boolean { val baseMirror = (type as CompilerType).mirror @@ -109,19 +106,11 @@ class CompilerType(private val env: XProcessingEnv, mirror: XType) : IrType { return true } - override fun hashCode(): Int { - return mirror.hash() - } + override fun hashCode(): Int = mirror.hash() - override fun toString(): String { - return mirror.toString() - } + override fun toString(): String = mirror.toString() - fun mapToJavaType(): CompilerType { - return CompilerType(env, mirror.mapToJavaType(env)) - } + fun mapToJavaType(): CompilerType = CompilerType(env, mirror.mapToJavaType(env)) - fun mapToKotlinType(): CompilerType { - return CompilerType(env, mirror.mapToKotlinType(env)) - } + fun mapToKotlinType(): CompilerType = CompilerType(env, mirror.mapToKotlinType(env)) } diff --git a/compiler/ast/src/main/kotlin/motif/ast/compiler/IrUtil.kt b/compiler/ast/src/main/kotlin/motif/ast/compiler/IrUtil.kt index 51f4d41f..00d00ec3 100644 --- a/compiler/ast/src/main/kotlin/motif/ast/compiler/IrUtil.kt +++ b/compiler/ast/src/main/kotlin/motif/ast/compiler/IrUtil.kt @@ -27,11 +27,8 @@ interface IrUtil { val env: XProcessingEnv - fun XElement.irModifiers(): Set { - return modifierNames.map { IrModifier.valueOf(it) }.toSet() - } + fun XElement.irModifiers(): Set = modifierNames.map { IrModifier.valueOf(it) }.toSet() - fun XElement.irAnnotations(): List { - return getAllAnnotations().map { CompilerAnnotation(env, it) } - } + fun XElement.irAnnotations(): List = + getAllAnnotations().map { CompilerAnnotation(env, it) } } diff --git a/compiler/ast/src/test/kotlin/motif/ast/compiler/CompilerClassTest.kt b/compiler/ast/src/test/kotlin/motif/ast/compiler/CompilerClassTest.kt index 9977edbb..15004478 100644 --- a/compiler/ast/src/test/kotlin/motif/ast/compiler/CompilerClassTest.kt +++ b/compiler/ast/src/test/kotlin/motif/ast/compiler/CompilerClassTest.kt @@ -31,22 +31,23 @@ import org.junit.runners.Parameterized @OptIn(ExperimentalProcessingApi::class) class XCompilerClassTest( private val processorType: ProcessorType, - private val srcLang: SourceLanguage + private val srcLang: SourceLanguage, ) { companion object { @JvmStatic @Parameterized.Parameters(name = "{0}_{1}") - fun data(): Collection> { - return cartesianProduct( - ProcessorType.values().toSortedSet(), SourceLanguage.values().toSortedSet()) - .filterNot { (proc, _) -> proc == ProcessorType.KSP } // Investigate this after ksp#1086 - .filterNot { (proc, srcLang) -> - proc == ProcessorType.AP && srcLang == SourceLanguage.KOTLIN - } - .map { it.toTypedArray() as Array } - .toList() - } + fun data(): Collection> = + cartesianProduct( + ProcessorType.values().toSortedSet(), + SourceLanguage.values().toSortedSet(), + ) + .filterNot { (proc, _) -> proc == ProcessorType.KSP } // Investigate this after ksp#1086 + .filterNot { (proc, srcLang) -> + proc == ProcessorType.AP && srcLang == SourceLanguage.KOTLIN + } + .map { it.toTypedArray() as Array } + .toList() } @Test @@ -59,8 +60,9 @@ class XCompilerClassTest( abstract class Bar {} class Foo extends Bar {} - """.trimIndent()) { - fooClass -> + """ + .trimIndent(), + ) { fooClass -> val superClass = fooClass.supertypes.single().resolveClass() as CompilerClass assertThat(superClass.typeArguments.map { it.qualifiedName }) .containsExactly("java.lang.String") @@ -79,8 +81,9 @@ class XCompilerClassTest( class Bar extends Baz {} class Foo extends Bar {} - """.trimIndent()) { - fooClass -> + """ + .trimIndent(), + ) { fooClass -> val barClass = fooClass.supertypes.single().resolveClass() as CompilerClass val bazClass = barClass.supertypes.single().resolveClass() as CompilerClass assertThat(bazClass.typeArguments.map { it.qualifiedName }) @@ -98,8 +101,9 @@ class XCompilerClassTest( class Bar {} class Foo extends Bar {} - """.trimIndent()) { - fooClass -> + """ + .trimIndent(), + ) { fooClass -> val superClass = fooClass.supertypes.single().resolveClass() as CompilerClass assertThat(superClass.typeArguments).isEmpty() } @@ -108,12 +112,14 @@ class XCompilerClassTest( @Test fun testObjectSupertype() { createClass( - "test.Foo", """ + "test.Foo", + """ package test; class Foo {} - """.trimIndent()) { - fooClass -> + """ + .trimIndent(), + ) { fooClass -> val objectClass = fooClass.supertypes.single().resolveClass()!! assertThat(objectClass.qualifiedName).isEqualTo(listOf("java.lang.Object").forLang().first()) assertThat(objectClass.supertypes).isEmpty() @@ -130,15 +136,17 @@ class XCompilerClassTest( interface Bar {} class Foo implements Bar {} - """.trimIndent()) { - fooClass -> + """ + .trimIndent(), + ) { fooClass -> val superTypes = fooClass.supertypes.map { it.qualifiedName } assertThat(superTypes) .containsExactly( *listOf("java.lang.Object", "test.Bar") .forLang() .filter { it != "kotlin.Any" } - .toTypedArray()) + .toTypedArray(), + ) } } @@ -154,29 +162,31 @@ class XCompilerClassTest( interface Baz {} class Foo implements Bar, Baz {} - """.trimIndent()) { - fooClass -> + """ + .trimIndent(), + ) { fooClass -> val superTypes = fooClass.supertypes.map { it.qualifiedName } assertThat(superTypes) .containsExactly( *listOf("java.lang.Object", "test.Bar", "test.Baz") .forLang() .filter { it != "kotlin.Any" } - .toTypedArray()) + .toTypedArray(), + ) } } private fun createClass( qualifiedName: String, @Language("JAVA") text: String, - assertions: (CompilerClass) -> Unit + assertions: (CompilerClass) -> Unit, ) { val pkg = - text.lines() + text + .lines() .firstOrNull { it.startsWith("package ") } ?.substringAfter(" ") - ?.substringBefore(";") - ?: "test" + ?.substringBefore(";") ?: "test" val srcFiles = text.split("\n{2,}".toRegex()).filterNot { it.startsWith("package") } val sources = when (srcLang) { @@ -196,7 +206,7 @@ class XCompilerClassTest( private fun process( invocation: XTestInvocation, qualifiedName: String, - assertions: (CompilerClass) -> Unit + assertions: (CompilerClass) -> Unit, ): CompilerClass { val env = invocation.processingEnv val typeElement = @@ -220,12 +230,14 @@ class XCompilerClassTest( .filter { it != name && it in src } .map { "import $pkg.$it;" } .joinToString("\n") - val code = """ + val code = + """ package $pkg; $imports $src - """.trimIndent() + """ + .trimIndent() return@map Source.java("$pkg.$name", code) } } @@ -256,41 +268,40 @@ class XCompilerClassTest( $imports ${if (hasParentClass) src.replace(" {}", "() {}") else src} - """.trimIndent() + """ + .trimIndent() return@map Source.kotlin("$pkg/$name.kt", code) } } - private fun String.toSourceFor(): String { - return if (srcLang == SourceLanguage.KOTLIN) { - this - } else { - this.replace("open ", "") - } - } - - private fun List.forLang(): Array { - return if (srcLang == SourceLanguage.KOTLIN) { - map { - when (it) { - "java.lang.Object" -> "kotlin.Any" - "java.lang.String" -> "kotlin.String" - else -> it + private fun String.toSourceFor(): String = + if (srcLang == SourceLanguage.KOTLIN) { + this + } else { + this.replace("open ", "") + } + + private fun List.forLang(): Array = + if (srcLang == SourceLanguage.KOTLIN) { + map { + when (it) { + "java.lang.Object" -> "kotlin.Any" + "java.lang.String" -> "kotlin.String" + else -> it + } } + } else { + this } - } else { - this - } - .toTypedArray() - } + .toTypedArray() } enum class ProcessorType { AP, - KSP + KSP, } enum class SourceLanguage { JAVA, - KOTLIN + KOTLIN, } diff --git a/compiler/ksp/src/main/kotlin/motif/compiler/ksp/MotifSymbolProcessorProvider.kt b/compiler/ksp/src/main/kotlin/motif/compiler/ksp/MotifSymbolProcessorProvider.kt index 2aae4b7a..c6c395fe 100644 --- a/compiler/ksp/src/main/kotlin/motif/compiler/ksp/MotifSymbolProcessorProvider.kt +++ b/compiler/ksp/src/main/kotlin/motif/compiler/ksp/MotifSymbolProcessorProvider.kt @@ -27,18 +27,17 @@ import motif.core.ResolvedGraph @AutoService(SymbolProcessorProvider::class) class MotifSymbolProcessorProvider( - private val config: XProcessingEnvConfig = XProcessingEnvConfig.DEFAULT + private val config: XProcessingEnvConfig = XProcessingEnvConfig.DEFAULT, ) : SymbolProcessorProvider { lateinit var graph: ResolvedGraph - override fun create(environment: SymbolProcessorEnvironment): SymbolProcessor { - return MotifSymbolProcessor(environment, config) - } + override fun create(environment: SymbolProcessorEnvironment): SymbolProcessor = + MotifSymbolProcessor(environment, config) @OptIn(ExperimentalProcessingApi::class) private inner class MotifSymbolProcessor( environment: SymbolProcessorEnvironment, - config: XProcessingEnvConfig + config: XProcessingEnvConfig, ) : KspBasicAnnotationProcessor(environment, config) { override fun processingSteps() = listOf(MotifProcessingStep(graphSetter = { graph = it })) diff --git a/compiler/src/main/kotlin/motif/compiler/CodeGenerator.kt b/compiler/src/main/kotlin/motif/compiler/CodeGenerator.kt index 07b025e6..517675bf 100644 --- a/compiler/src/main/kotlin/motif/compiler/CodeGenerator.kt +++ b/compiler/src/main/kotlin/motif/compiler/CodeGenerator.kt @@ -30,7 +30,8 @@ object CodeGenerator { if (env.backend == XProcessingEnv.Backend.JAVAC && kaptKotlinGeneratedDir == null) { throw IllegalStateException( "-A$OPTION_MODE=${OutputMode.KOTLIN.name.lowercase()} " + - "requires -A$OPTION_KAPT_KOTLIN_GENERATED to be set.") + "requires -A$OPTION_KAPT_KOTLIN_GENERATED to be set.", + ) } generateKotlin(env, graph, kaptKotlinGeneratedDir) } else { @@ -46,29 +47,27 @@ object CodeGenerator { } } - private fun generateJava(env: XProcessingEnv, graph: ResolvedGraph): List { - return ScopeImplFactory.create(env, graph) - .map { scopeImpl -> JavaCodeGenerator.generate(scopeImpl) } - .onEach { javaFile -> javaFile.writeTo(env.filer) } - .map { "${it.packageName}.${it.typeSpec.name}" } - } + private fun generateJava(env: XProcessingEnv, graph: ResolvedGraph): List = + ScopeImplFactory.create(env, graph) + .map { scopeImpl -> JavaCodeGenerator.generate(scopeImpl) } + .onEach { javaFile -> javaFile.writeTo(env.filer) } + .map { "${it.packageName}.${it.typeSpec.name}" } private fun generateKotlin( env: XProcessingEnv, graph: ResolvedGraph, - kaptKotlinGeneratedDir: String? = null - ): List { - return ScopeImplFactory.create(env, graph) - .map { scopeImpl -> KotlinCodeGenerator.generate(scopeImpl) } - .onEach { fileSpec -> - if (kaptKotlinGeneratedDir != null) { - fileSpec.writeTo(File(kaptKotlinGeneratedDir)) - } else { - fileSpec.writeTo(env.filer) + kaptKotlinGeneratedDir: String? = null, + ): List = + ScopeImplFactory.create(env, graph) + .map { scopeImpl -> KotlinCodeGenerator.generate(scopeImpl) } + .onEach { fileSpec -> + if (kaptKotlinGeneratedDir != null) { + fileSpec.writeTo(File(kaptKotlinGeneratedDir)) + } else { + fileSpec.writeTo(env.filer) + } } - } - .map { "${it.packageName}.${it.name}" } - } + .map { "${it.packageName}.${it.name}" } } enum class OutputMode { diff --git a/compiler/src/main/kotlin/motif/compiler/JavaCodeGenerator.kt b/compiler/src/main/kotlin/motif/compiler/JavaCodeGenerator.kt index 10830de6..640e9dbb 100644 --- a/compiler/src/main/kotlin/motif/compiler/JavaCodeGenerator.kt +++ b/compiler/src/main/kotlin/motif/compiler/JavaCodeGenerator.kt @@ -38,94 +38,85 @@ object JavaCodeGenerator { return JavaFile.builder(scopeImpl.className.j.packageName(), typeSpec).build() } - private fun ScopeImpl.spec(): TypeSpec { - return TypeSpec.classBuilder(className.j) - .apply { - addAnnotation(scopeImplAnnotation.spec()) - addModifiers(Modifier.PUBLIC) - addSuperinterface(superClassName.j) - objectsField?.let { addField(it.spec()) } - addField(dependenciesField.spec()) - cacheFields.forEach { addField(it.spec()) } - addMethod(constructor.spec()) - alternateConstructor?.let { addMethod(it.spec()) } - accessMethodImpls.forEach { addMethod(it.spec()) } - childMethodImpls.forEach { addMethod(it.spec()) } - addMethod(scopeProviderMethod.spec()) - factoryProviderMethods.forEach { addMethods(it.specs()) } - dependencyProviderMethods.forEach { addMethod(it.spec()) } - dependencies?.let { addType(it.spec()) } - objectsImpl?.let { addType(it.spec()) } - } - .build() - } - - private fun ScopeImplAnnotation.spec(): AnnotationSpec { - return AnnotationSpec.builder(motif.ScopeImpl::class.java) - .apply { - if (children.isEmpty()) { - addMember("children", "{}") - } else { - children.forEach { child -> addMember("children", "\$T.class", child.j) } + private fun ScopeImpl.spec(): TypeSpec = + TypeSpec.classBuilder(className.j) + .apply { + addAnnotation(scopeImplAnnotation.spec()) + addModifiers(Modifier.PUBLIC) + addSuperinterface(superClassName.j) + objectsField?.let { addField(it.spec()) } + addField(dependenciesField.spec()) + cacheFields.forEach { addField(it.spec()) } + addMethod(constructor.spec()) + alternateConstructor?.let { addMethod(it.spec()) } + accessMethodImpls.forEach { addMethod(it.spec()) } + childMethodImpls.forEach { addMethod(it.spec()) } + addMethod(scopeProviderMethod.spec()) + factoryProviderMethods.forEach { addMethods(it.specs()) } + dependencyProviderMethods.forEach { addMethod(it.spec()) } + dependencies?.let { addType(it.spec()) } + objectsImpl?.let { addType(it.spec()) } } - addMember("scope", "\$T.class", scopeClassName.j) - addMember("dependencies", "\$T.class", dependenciesClassName.j) - } - .build() - } - - private fun ObjectsField.spec(): FieldSpec { - return FieldSpec.builder(objectsClassName.j, name, Modifier.PRIVATE, Modifier.FINAL) - .initializer("new \$T()", objectsImplClassName.j) - .build() - } - - private fun DependenciesField.spec(): FieldSpec { - return FieldSpec.builder(dependenciesClassName.j, name, Modifier.PRIVATE, Modifier.FINAL) - .build() - } - - private fun CacheField.spec(): FieldSpec { - return FieldSpec.builder(Object::class.java, name, Modifier.PRIVATE, Modifier.VOLATILE) - .initializer("\$T.NONE", None::class.java) - .build() - } - - private fun Constructor.spec(): MethodSpec { - return MethodSpec.constructorBuilder() - .addModifiers(Modifier.PUBLIC) - .addParameter(dependenciesClassName.j, dependenciesParameterName) - .addStatement("this.\$N = \$N", dependenciesFieldName, dependenciesParameterName) - .build() - } - - private fun AlternateConstructor.spec(): MethodSpec { - return MethodSpec.constructorBuilder() - .addModifiers(Modifier.PUBLIC) - .addStatement("this(new \$T() {})", dependenciesClassName.j) - .build() - } - - private fun AccessMethodImpl.spec(): MethodSpec { - return MethodSpec.overriding( - overriddenMethod.element.toJavac(), - overriddenMethod.owner.toJavac() as DeclaredType, - env.toJavac().typeUtils) - .addStatement("return \$N()", providerMethodName) - .build() - } + .build() - private fun ChildMethodImpl.spec(): MethodSpec { - return MethodSpec.methodBuilder(childMethodName) - .apply { - addAnnotation(Override::class.java) - addModifiers(Modifier.PUBLIC) - returns(childClassName.j) - this@spec.parameters.forEach { addParameter(it.spec()) } - addStatement("return new \$T(\$L)", childImplClassName.j, childDependenciesImpl.spec()) - } - .build() - } + private fun ScopeImplAnnotation.spec(): AnnotationSpec = + AnnotationSpec.builder(motif.ScopeImpl::class.java) + .apply { + if (children.isEmpty()) { + addMember("children", "{}") + } else { + children.forEach { child -> addMember("children", "\$T.class", child.j) } + } + addMember("scope", "\$T.class", scopeClassName.j) + addMember("dependencies", "\$T.class", dependenciesClassName.j) + } + .build() + + private fun ObjectsField.spec(): FieldSpec = + FieldSpec.builder(objectsClassName.j, name, Modifier.PRIVATE, Modifier.FINAL) + .initializer("new \$T()", objectsImplClassName.j) + .build() + + private fun DependenciesField.spec(): FieldSpec = + FieldSpec.builder(dependenciesClassName.j, name, Modifier.PRIVATE, Modifier.FINAL).build() + + private fun CacheField.spec(): FieldSpec = + FieldSpec.builder(Object::class.java, name, Modifier.PRIVATE, Modifier.VOLATILE) + .initializer("\$T.NONE", None::class.java) + .build() + + private fun Constructor.spec(): MethodSpec = + MethodSpec.constructorBuilder() + .addModifiers(Modifier.PUBLIC) + .addParameter(dependenciesClassName.j, dependenciesParameterName) + .addStatement("this.\$N = \$N", dependenciesFieldName, dependenciesParameterName) + .build() + + private fun AlternateConstructor.spec(): MethodSpec = + MethodSpec.constructorBuilder() + .addModifiers(Modifier.PUBLIC) + .addStatement("this(new \$T() {})", dependenciesClassName.j) + .build() + + private fun AccessMethodImpl.spec(): MethodSpec = + MethodSpec.overriding( + overriddenMethod.element.toJavac(), + overriddenMethod.owner.toJavac() as DeclaredType, + env.toJavac().typeUtils, + ) + .addStatement("return \$N()", providerMethodName) + .build() + + private fun ChildMethodImpl.spec(): MethodSpec = + MethodSpec.methodBuilder(childMethodName) + .apply { + addAnnotation(Override::class.java) + addModifiers(Modifier.PUBLIC) + returns(childClassName.j) + this@spec.parameters.forEach { addParameter(it.spec()) } + addStatement("return new \$T(\$L)", childImplClassName.j, childDependenciesImpl.spec()) + } + .build() @OptIn(KotlinPoetJavaPoetPreview::class) private fun ChildDependenciesImpl.spec(): TypeSpec { @@ -140,46 +131,38 @@ object JavaCodeGenerator { private fun ChildDependencyMethodImpl.spec( env: XProcessingEnv, - isKotlinDependenciesInterface: Boolean - ): MethodSpec { - return MethodSpec.methodBuilder(name) - .addAnnotation(Override::class.java) - .addModifiers(Modifier.PUBLIC) - .returns( - if (isKotlinDependenciesInterface) { - returnTypeName.j.withRawTypeFix(env) - } else { - returnTypeName.j - }) - .addStatement(returnExpression.spec()) - .build() - } - - private fun ChildDependencyMethodImpl.ReturnExpression.spec(): CodeBlock { - return when (this) { - is ChildDependencyMethodImpl.ReturnExpression.Parameter -> spec() - is ChildDependencyMethodImpl.ReturnExpression.Provider -> spec() - } - } - - private fun ChildDependencyMethodImpl.ReturnExpression.Parameter.spec(): CodeBlock { - return CodeBlock.of("return \$N", parameterName) - } - - private fun ChildDependencyMethodImpl.ReturnExpression.Provider.spec(): CodeBlock { - return CodeBlock.of("return \$T.this.\$N()", scopeImplName.j, providerName) - } - - private fun ChildMethodImplParameter.spec(): ParameterSpec { - return ParameterSpec.builder(typeName.j, name, Modifier.FINAL).build() - } - - private fun ScopeProviderMethod.spec(): MethodSpec { - return MethodSpec.methodBuilder(name) - .returns(scopeClassName.j) - .addStatement("return this") - .build() - } + isKotlinDependenciesInterface: Boolean, + ): MethodSpec = + MethodSpec.methodBuilder(name) + .addAnnotation(Override::class.java) + .addModifiers(Modifier.PUBLIC) + .returns( + if (isKotlinDependenciesInterface) { + returnTypeName.j.withRawTypeFix(env) + } else { + returnTypeName.j + }, + ) + .addStatement(returnExpression.spec()) + .build() + + private fun ChildDependencyMethodImpl.ReturnExpression.spec(): CodeBlock = + when (this) { + is ChildDependencyMethodImpl.ReturnExpression.Parameter -> spec() + is ChildDependencyMethodImpl.ReturnExpression.Provider -> spec() + } + + private fun ChildDependencyMethodImpl.ReturnExpression.Parameter.spec(): CodeBlock = + CodeBlock.of("return \$N", parameterName) + + private fun ChildDependencyMethodImpl.ReturnExpression.Provider.spec(): CodeBlock = + CodeBlock.of("return \$T.this.\$N()", scopeImplName.j, providerName) + + private fun ChildMethodImplParameter.spec(): ParameterSpec = + ParameterSpec.builder(typeName.j, name, Modifier.FINAL).build() + + private fun ScopeProviderMethod.spec(): MethodSpec = + MethodSpec.methodBuilder(name).returns(scopeClassName.j).addStatement("return this").build() private fun FactoryProviderMethod.specs(): List { val primarySpec = @@ -188,92 +171,81 @@ object JavaCodeGenerator { return listOf(primarySpec) + spreadSpecs } - private fun FactoryProviderMethodBody.spec(): CodeBlock { - return when (this) { - is FactoryProviderMethodBody.Cached -> spec() - is FactoryProviderMethodBody.Uncached -> spec() - } - } - - private fun FactoryProviderMethodBody.Cached.spec(): CodeBlock { - return CodeBlock.builder() - .beginControlFlow("if (\$N == \$T.NONE)", cacheFieldName, None::class.java) - .beginControlFlow("synchronized (this)") - .beginControlFlow("if (\$N == \$T.NONE)", cacheFieldName, None::class.java) - .add("\$N = \$L;", cacheFieldName, instantiation.spec()) - .endControlFlow() - .endControlFlow() - .endControlFlow() - .add("return (\$T) \$N", returnTypeName.j, cacheFieldName) - .build() - } - - private fun FactoryProviderMethodBody.Uncached.spec(): CodeBlock { - return CodeBlock.of("return \$L", instantiation.spec()) - } - - private fun FactoryProviderInstantiation.spec(): CodeBlock { - return when (this) { - is FactoryProviderInstantiation.Basic -> spec() - is FactoryProviderInstantiation.Constructor -> spec() - is FactoryProviderInstantiation.Binds -> spec() - } - } - - private fun FactoryProviderInstantiation.Basic.spec(): CodeBlock { - return if (isStatic) { - CodeBlock.of("\$T.\$N\$L", objectsClassName.j, factoryMethodName, callProviders.spec()) - } else { - CodeBlock.of("\$N.\$N\$L", objectsFieldName, factoryMethodName, callProviders.spec()) - } - } - - private fun FactoryProviderInstantiation.Constructor.spec(): CodeBlock { - return CodeBlock.of("new \$T\$L", returnTypeName.j, callProviders.spec()) - } - - private fun FactoryProviderInstantiation.Binds.spec(): CodeBlock { - return CodeBlock.of("\$N()", providerMethodName) - } + private fun FactoryProviderMethodBody.spec(): CodeBlock = + when (this) { + is FactoryProviderMethodBody.Cached -> spec() + is FactoryProviderMethodBody.Uncached -> spec() + } + + private fun FactoryProviderMethodBody.Cached.spec(): CodeBlock = + CodeBlock.builder() + .beginControlFlow("if (\$N == \$T.NONE)", cacheFieldName, None::class.java) + .beginControlFlow("synchronized (this)") + .beginControlFlow("if (\$N == \$T.NONE)", cacheFieldName, None::class.java) + .add("\$N = \$L;", cacheFieldName, instantiation.spec()) + .endControlFlow() + .endControlFlow() + .endControlFlow() + .add("return (\$T) \$N", returnTypeName.j, cacheFieldName) + .build() + + private fun FactoryProviderMethodBody.Uncached.spec(): CodeBlock = + CodeBlock.of("return \$L", instantiation.spec()) + + private fun FactoryProviderInstantiation.spec(): CodeBlock = + when (this) { + is FactoryProviderInstantiation.Basic -> spec() + is FactoryProviderInstantiation.Constructor -> spec() + is FactoryProviderInstantiation.Binds -> spec() + } + + private fun FactoryProviderInstantiation.Basic.spec(): CodeBlock = + if (isStatic) { + CodeBlock.of("\$T.\$N\$L", objectsClassName.j, factoryMethodName, callProviders.spec()) + } else { + CodeBlock.of("\$N.\$N\$L", objectsFieldName, factoryMethodName, callProviders.spec()) + } + + private fun FactoryProviderInstantiation.Constructor.spec(): CodeBlock = + CodeBlock.of("new \$T\$L", returnTypeName.j, callProviders.spec()) + + private fun FactoryProviderInstantiation.Binds.spec(): CodeBlock = + CodeBlock.of("\$N()", providerMethodName) private fun CallProviders.spec(): String { val callString = providerMethodNames.joinToString { "$it()" } return "($callString)" } - private fun SpreadProviderMethod.spec(): MethodSpec { - return MethodSpec.methodBuilder(name) - .returns(returnTypeName.j) - .addStatement("return \$N().\$N()", sourceProviderMethodName, spreadMethodName) - .build() - } + private fun SpreadProviderMethod.spec(): MethodSpec = + MethodSpec.methodBuilder(name) + .returns(returnTypeName.j) + .addStatement("return \$N().\$N()", sourceProviderMethodName, spreadMethodName) + .build() - private fun DependencyProviderMethod.spec(): MethodSpec { - return MethodSpec.methodBuilder(name) - .returns(returnTypeName.j) - .addStatement("return \$N.\$N()", dependenciesFieldName, dependencyMethodName) - .build() - } - - private fun Dependencies.spec(): TypeSpec { - return TypeSpec.interfaceBuilder(className.j) - .apply { - addModifiers(Modifier.PUBLIC) - methods.forEach { addMethod(it.spec()) } - } - .build() - } + private fun DependencyProviderMethod.spec(): MethodSpec = + MethodSpec.methodBuilder(name) + .returns(returnTypeName.j) + .addStatement("return \$N.\$N()", dependenciesFieldName, dependencyMethodName) + .build() - private fun DependencyMethod.spec(): MethodSpec { - return MethodSpec.methodBuilder(name) - .apply { - qualifier?.let { addAnnotation(it.spec()) } - addModifiers(Modifier.PUBLIC, Modifier.ABSTRACT) - returns(returnTypeName.j) - addJavadoc(javaDoc.spec()) - } - .build() - } + private fun Dependencies.spec(): TypeSpec = + TypeSpec.interfaceBuilder(className.j) + .apply { + addModifiers(Modifier.PUBLIC) + methods.forEach { addMethod(it.spec()) } + } + .build() + + private fun DependencyMethod.spec(): MethodSpec = + MethodSpec.methodBuilder(name) + .apply { + qualifier?.let { addAnnotation(it.spec()) } + addModifiers(Modifier.PUBLIC, Modifier.ABSTRACT) + returns(returnTypeName.j) + addJavadoc(javaDoc.spec()) + } + .build() private fun Qualifier.spec(): AnnotationSpec { val className = @@ -288,41 +260,39 @@ object JavaCodeGenerator { .build() } - private fun DependencyMethodJavaDoc.spec(): CodeBlock { - return CodeBlock.builder() - .apply { - add("
    \nRequested from:\n") - requestedFrom.forEach { add(it.spec()) } - add("
\n") - } - .build() - } + private fun DependencyMethodJavaDoc.spec(): CodeBlock = + CodeBlock.builder() + .apply { + add("
    \nRequested from:\n") + requestedFrom.forEach { add(it.spec()) } + add("
\n") + } + .build() private fun JavaDocMethodLink.spec(): CodeBlock { val parameterTypeString = parameterTypes.joinToString() return CodeBlock.of("
  • {@link \$L#\$N(\$L)}
  • \n", owner, methodName, parameterTypeString) } - private fun ObjectsImpl.spec(): TypeSpec { - return TypeSpec.classBuilder(className.j) - .apply { - addModifiers(Modifier.PRIVATE, Modifier.STATIC) - if (isInterface) { - addSuperinterface(superClassName.j) - } else { - superclass(superClassName.j) + private fun ObjectsImpl.spec(): TypeSpec = + TypeSpec.classBuilder(className.j) + .apply { + addModifiers(Modifier.PRIVATE, Modifier.STATIC) + if (isInterface) { + addSuperinterface(superClassName.j) + } else { + superclass(superClassName.j) + } + abstractMethods.forEach { addMethod(it.spec()) } } - abstractMethods.forEach { addMethod(it.spec()) } - } - .build() - } - - private fun ObjectsAbstractMethod.spec(): MethodSpec { - return MethodSpec.overriding( - overriddenMethod.element.toJavac(), - overriddenMethod.owner.toJavac() as DeclaredType, - env.toJavac().typeUtils) - .addStatement("throw new \$T()", UnsupportedOperationException::class.java) - .build() - } + .build() + + private fun ObjectsAbstractMethod.spec(): MethodSpec = + MethodSpec.overriding( + overriddenMethod.element.toJavac(), + overriddenMethod.owner.toJavac() as DeclaredType, + env.toJavac().typeUtils, + ) + .addStatement("throw new \$T()", UnsupportedOperationException::class.java) + .build() } diff --git a/compiler/src/main/kotlin/motif/compiler/KotlinCodeGenerator.kt b/compiler/src/main/kotlin/motif/compiler/KotlinCodeGenerator.kt index 7dbc87e8..82f00dec 100644 --- a/compiler/src/main/kotlin/motif/compiler/KotlinCodeGenerator.kt +++ b/compiler/src/main/kotlin/motif/compiler/KotlinCodeGenerator.kt @@ -39,92 +39,85 @@ object KotlinCodeGenerator { return FileSpec.get(scopeImpl.className.kt.packageName, typeSpec) } - private fun ScopeImpl.spec(): TypeSpec { - return TypeSpec.classBuilder(className.kt) - .apply { - addAnnotation(suppressAnnotationSpec("REDUNDANT_PROJECTION", "UNCHECKED_CAST")) - addAnnotation(scopeImplAnnotation.spec()) - addModifiers(if (internalScope) KModifier.INTERNAL else KModifier.PUBLIC) - addSuperinterface(superClassName.kt) - objectsField?.let { addProperty(it.spec()) } - addProperty(dependenciesField.spec()) - cacheFields.forEach { addProperty(it.spec()) } - primaryConstructor(constructor.spec()) - alternateConstructor?.let { addFunction(it.spec()) } - accessMethodImpls.filter { !it.overriddenMethod.isSynthetic }.forEach { - addFunction(it.spec()) - } - accessMethodImpls.filter { it.overriddenMethod.isSynthetic }.forEach { - addProperty(it.propSpec()) + private fun ScopeImpl.spec(): TypeSpec = + TypeSpec.classBuilder(className.kt) + .apply { + addAnnotation(suppressAnnotationSpec("REDUNDANT_PROJECTION", "UNCHECKED_CAST")) + addAnnotation(scopeImplAnnotation.spec()) + addModifiers(if (internalScope) KModifier.INTERNAL else KModifier.PUBLIC) + addSuperinterface(superClassName.kt) + objectsField?.let { addProperty(it.spec()) } + addProperty(dependenciesField.spec()) + cacheFields.forEach { addProperty(it.spec()) } + primaryConstructor(constructor.spec()) + alternateConstructor?.let { addFunction(it.spec()) } + accessMethodImpls + .filter { !it.overriddenMethod.isSynthetic } + .forEach { addFunction(it.spec()) } + accessMethodImpls + .filter { it.overriddenMethod.isSynthetic } + .forEach { addProperty(it.propSpec()) } + childMethodImpls.forEach { addFunction(it.spec()) } + addFunction(scopeProviderMethod.spec()) + factoryProviderMethods.forEach { addFunctions(it.specs()) } + dependencyProviderMethods.forEach { addFunction(it.spec()) } + dependencies?.let { addType(it.spec()) } + objectsImpl?.let { addType(it.spec()) } } - childMethodImpls.forEach { addFunction(it.spec()) } - addFunction(scopeProviderMethod.spec()) - factoryProviderMethods.forEach { addFunctions(it.specs()) } - dependencyProviderMethods.forEach { addFunction(it.spec()) } - dependencies?.let { addType(it.spec()) } - objectsImpl?.let { addType(it.spec()) } - } - .build() - } + .build() - private fun ScopeImplAnnotation.spec(): AnnotationSpec { - return AnnotationSpec.builder(motif.ScopeImpl::class) - .apply { - addMember( - CodeBlock.builder() - .apply { - add("children = [") - children.forEachIndexed { i, child -> - val prefix = if (i == 0) "" else ", " - add("%L%T::class", prefix, child.kt) + private fun ScopeImplAnnotation.spec(): AnnotationSpec = + AnnotationSpec.builder(motif.ScopeImpl::class) + .apply { + addMember( + CodeBlock.builder() + .apply { + add("children = [") + children.forEachIndexed { i, child -> + val prefix = if (i == 0) "" else ", " + add("%L%T::class", prefix, child.kt) + } + add("]") } - add("]") - } - .build()) - addMember("scope = %T::class", scopeClassName.kt) - addMember("dependencies = %T::class", dependenciesClassName.kt) - } - .build() - } + .build(), + ) + addMember("scope = %T::class", scopeClassName.kt) + addMember("dependencies = %T::class", dependenciesClassName.kt) + } + .build() - private fun ObjectsField.spec(): PropertySpec { - return PropertySpec.builder(name, objectsClassName.kt, KModifier.PRIVATE, KModifier.FINAL) - .initializer("%T()", objectsImplClassName.kt) - .build() - } + private fun ObjectsField.spec(): PropertySpec = + PropertySpec.builder(name, objectsClassName.kt, KModifier.PRIVATE, KModifier.FINAL) + .initializer("%T()", objectsImplClassName.kt) + .build() - private fun DependenciesField.spec(): PropertySpec { - return PropertySpec.builder(name, dependenciesClassName.kt, KModifier.PRIVATE) - .initializer(name) - .build() - } + private fun DependenciesField.spec(): PropertySpec = + PropertySpec.builder(name, dependenciesClassName.kt, KModifier.PRIVATE) + .initializer(name) + .build() - private fun CacheField.spec(): PropertySpec { - return PropertySpec.builder(name, Any::class, KModifier.PRIVATE) - .mutable(true) - .addAnnotation(Volatile::class) - .initializer("%T.NONE", None::class) - .build() - } + private fun CacheField.spec(): PropertySpec = + PropertySpec.builder(name, Any::class, KModifier.PRIVATE) + .mutable(true) + .addAnnotation(Volatile::class) + .initializer("%T.NONE", None::class) + .build() - private fun Constructor.spec(): FunSpec { - return FunSpec.constructorBuilder() - .addParameter(dependenciesParameterName, dependenciesClassName.kt) - .build() - } + private fun Constructor.spec(): FunSpec = + FunSpec.constructorBuilder() + .addParameter(dependenciesParameterName, dependenciesClassName.kt) + .build() - private fun AlternateConstructor.spec(): FunSpec { - return FunSpec.constructorBuilder() - .addModifiers(KModifier.PUBLIC) - .callThisConstructor(CodeBlock.of("object : %T {}", dependenciesClassName.kt)) - .build() - } + private fun AlternateConstructor.spec(): FunSpec = + FunSpec.constructorBuilder() + .addModifiers(KModifier.PUBLIC) + .callThisConstructor(CodeBlock.of("object : %T {}", dependenciesClassName.kt)) + .build() - private fun AccessMethodImpl.spec(): FunSpec { - return XFunSpec.overriding(overriddenMethod.element, overriddenMethod.owner, env) - .addStatement("return %N()", providerMethodName) - .build() - } + private fun AccessMethodImpl.spec(): FunSpec = + XFunSpec.overriding(overriddenMethod.element, overriddenMethod.owner, env) + .addStatement("return %N()", providerMethodName) + .build() private fun AccessMethodImpl.propSpec(): PropertySpec { val propName = @@ -136,7 +129,9 @@ object KotlinCodeGenerator { } } return PropertySpec.builder( - propName, ClassName.bestGuess(overriddenMethod.returnType.qualifiedName)) + propName, + ClassName.bestGuess(overriddenMethod.returnType.qualifiedName), + ) .addModifiers(KModifier.OVERRIDE) .initializer("%N()", providerMethodName) .build() @@ -154,57 +149,50 @@ object KotlinCodeGenerator { .build() } - private fun ChildDependenciesImpl.spec(): TypeSpec { - return TypeSpec.anonymousClassBuilder() - .apply { - if (isAbstractClass) { - superclass(childDependenciesClassName.kt) - } else { - addSuperinterface(childDependenciesClassName.kt) + private fun ChildDependenciesImpl.spec(): TypeSpec = + TypeSpec.anonymousClassBuilder() + .apply { + if (isAbstractClass) { + superclass(childDependenciesClassName.kt) + } else { + addSuperinterface(childDependenciesClassName.kt) + } + methods.forEach { addFunction(it.spec()) } } - methods.forEach { addFunction(it.spec()) } - } - .build() - } + .build() - private fun ChildDependencyMethodImpl.spec(): FunSpec { - return FunSpec.builder(name) - .addModifiers(KModifier.PUBLIC, KModifier.OVERRIDE) - .returns(returnTypeName.kt) - .addCode(returnExpression.spec()) - .build() - } + private fun ChildDependencyMethodImpl.spec(): FunSpec = + FunSpec.builder(name) + .addModifiers(KModifier.PUBLIC, KModifier.OVERRIDE) + .returns(returnTypeName.kt) + .addCode(returnExpression.spec()) + .build() - private fun ChildDependencyMethodImpl.ReturnExpression.spec(): CodeBlock { - return when (this) { - is ChildDependencyMethodImpl.ReturnExpression.Parameter -> spec() - is ChildDependencyMethodImpl.ReturnExpression.Provider -> spec() - } - } + private fun ChildDependencyMethodImpl.ReturnExpression.spec(): CodeBlock = + when (this) { + is ChildDependencyMethodImpl.ReturnExpression.Parameter -> spec() + is ChildDependencyMethodImpl.ReturnExpression.Provider -> spec() + } - private fun ChildDependencyMethodImpl.ReturnExpression.Parameter.spec(): CodeBlock { - return CodeBlock.of("return %N", parameterName) - } + private fun ChildDependencyMethodImpl.ReturnExpression.Parameter.spec(): CodeBlock = + CodeBlock.of("return %N", parameterName) - private fun ChildDependencyMethodImpl.ReturnExpression.Provider.spec(): CodeBlock { - return CodeBlock.of("return this@%T.%N()", scopeImplName.kt, providerName) - } + private fun ChildDependencyMethodImpl.ReturnExpression.Provider.spec(): CodeBlock = + CodeBlock.of("return this@%T.%N()", scopeImplName.kt, providerName) - private fun ChildMethodImplParameter.spec(): ParameterSpec { - return ParameterSpec.builder(name, typeName.kt).build() - } + private fun ChildMethodImplParameter.spec(): ParameterSpec = + ParameterSpec.builder(name, typeName.kt).build() - private fun ScopeProviderMethod.spec(): FunSpec { - return FunSpec.builder(name) - .apply { - if (isInternal) { - addModifiers(KModifier.INTERNAL) + private fun ScopeProviderMethod.spec(): FunSpec = + FunSpec.builder(name) + .apply { + if (isInternal) { + addModifiers(KModifier.INTERNAL) + } } - } - .returns(scopeClassName.kt) - .addStatement("return this") - .build() - } + .returns(scopeClassName.kt) + .addStatement("return this") + .build() private fun FactoryProviderMethod.specs(): List { val primarySpec = @@ -217,46 +205,41 @@ object KotlinCodeGenerator { return listOf(primarySpec) + spreadSpecs } - private fun FactoryProviderMethodBody.spec(): CodeBlock { - return when (this) { - is FactoryProviderMethodBody.Cached -> spec() - is FactoryProviderMethodBody.Uncached -> spec() - } - } - - private fun FactoryProviderMethodBody.Cached.spec(): CodeBlock { - return CodeBlock.builder() - .beginControlFlow("if (%N == %T.NONE)", cacheFieldName, None::class) - .beginControlFlow("synchronized (this)") - .beginControlFlow("if (%N == %T.NONE)", cacheFieldName, None::class) - .addStatement("%N=%L", cacheFieldName, instantiation.spec()) - .endControlFlow() - .endControlFlow() - .endControlFlow() - .add("return ( %N as %T )", cacheFieldName, returnTypeName.reloadedForTypeArgs(env)) - .build() - } + private fun FactoryProviderMethodBody.spec(): CodeBlock = + when (this) { + is FactoryProviderMethodBody.Cached -> spec() + is FactoryProviderMethodBody.Uncached -> spec() + } + + private fun FactoryProviderMethodBody.Cached.spec(): CodeBlock = + CodeBlock.builder() + .beginControlFlow("if (%N == %T.NONE)", cacheFieldName, None::class) + .beginControlFlow("synchronized (this)") + .beginControlFlow("if (%N == %T.NONE)", cacheFieldName, None::class) + .addStatement("%N=%L", cacheFieldName, instantiation.spec()) + .endControlFlow() + .endControlFlow() + .endControlFlow() + .add("return ( %N as %T )", cacheFieldName, returnTypeName.reloadedForTypeArgs(env)) + .build() - private fun motif.compiler.TypeName.reloadedForTypeArgs(env: XProcessingEnv): TypeName { - return if (kt is ParameterizedTypeName) { - kt - } else { - // ensures that type arguments get loaded - KotlinTypeWorkaround.javaToKotlinType(env.requireType(j)) - } - } + private fun motif.compiler.TypeName.reloadedForTypeArgs(env: XProcessingEnv): TypeName = + if (kt is ParameterizedTypeName) { + kt + } else { + // ensures that type arguments get loaded + KotlinTypeWorkaround.javaToKotlinType(env.requireType(j)) + } - private fun FactoryProviderMethodBody.Uncached.spec(): CodeBlock { - return CodeBlock.of("return %L", instantiation.spec()) - } + private fun FactoryProviderMethodBody.Uncached.spec(): CodeBlock = + CodeBlock.of("return %L", instantiation.spec()) - private fun FactoryProviderInstantiation.spec(): CodeBlock { - return when (this) { - is FactoryProviderInstantiation.Basic -> spec() - is FactoryProviderInstantiation.Constructor -> spec() - is FactoryProviderInstantiation.Binds -> spec() - } - } + private fun FactoryProviderInstantiation.spec(): CodeBlock = + when (this) { + is FactoryProviderInstantiation.Basic -> spec() + is FactoryProviderInstantiation.Constructor -> spec() + is FactoryProviderInstantiation.Binds -> spec() + } private fun FactoryProviderInstantiation.Basic.spec(): CodeBlock { val methodName = factoryMethodName.substringBeforeLast('$') @@ -267,39 +250,35 @@ object KotlinCodeGenerator { } } - private fun FactoryProviderInstantiation.Constructor.spec(): CodeBlock { - return CodeBlock.of("%T%L", returnTypeName.kt, callProviders.spec()) - } + private fun FactoryProviderInstantiation.Constructor.spec(): CodeBlock = + CodeBlock.of("%T%L", returnTypeName.kt, callProviders.spec()) - private fun FactoryProviderInstantiation.Binds.spec(): CodeBlock { - return CodeBlock.of("%N()", providerMethodName) - } + private fun FactoryProviderInstantiation.Binds.spec(): CodeBlock = + CodeBlock.of("%N()", providerMethodName) private fun CallProviders.spec(): String { val callString = providerMethodNames.joinToString { "$it()" } return "($callString)" } - private fun SpreadProviderMethod.spec(): FunSpec { - return FunSpec.builder(name) - .apply { - returns(returnTypeName.kt) - if (isStatic) { - addStatement("return %T.%N()", sourceTypeName.kt, spreadMethodName) - } else { - addStatement("return %N().%N()", sourceProviderMethodName, spreadMethodName) + private fun SpreadProviderMethod.spec(): FunSpec = + FunSpec.builder(name) + .apply { + returns(returnTypeName.kt) + if (isStatic) { + addStatement("return %T.%N()", sourceTypeName.kt, spreadMethodName) + } else { + addStatement("return %N().%N()", sourceProviderMethodName, spreadMethodName) + } } - } - .build() - } + .build() - private fun DependencyProviderMethod.spec(): FunSpec { - return FunSpec.builder(name) - .addModifiers(KModifier.INTERNAL) - .returns(returnTypeName.kt) - .addStatement("return %N.%N()", dependenciesFieldName, dependencyMethodName) - .build() - } + private fun DependencyProviderMethod.spec(): FunSpec = + FunSpec.builder(name) + .addModifiers(KModifier.INTERNAL) + .returns(returnTypeName.kt) + .addStatement("return %N.%N()", dependenciesFieldName, dependencyMethodName) + .build() private fun Dependencies.spec(): TypeSpec { val typeSpecBuilder = @@ -311,17 +290,16 @@ object KotlinCodeGenerator { return typeSpecBuilder.apply { methods.forEach { addFunction(it.spec()) } }.build() } - private fun DependencyMethod.spec(): FunSpec { - return FunSpec.builder(name) - .apply { - qualifier?.let { addAnnotation(it.spec()) } - addModifiers(if (internal) KModifier.INTERNAL else KModifier.PUBLIC) - addModifiers(KModifier.ABSTRACT) - returns(returnTypeName.kt) - addKdoc(javaDoc.spec()) - } - .build() - } + private fun DependencyMethod.spec(): FunSpec = + FunSpec.builder(name) + .apply { + qualifier?.let { addAnnotation(it.spec()) } + addModifiers(if (internal) KModifier.INTERNAL else KModifier.PUBLIC) + addModifiers(KModifier.ABSTRACT) + returns(returnTypeName.kt) + addKdoc(javaDoc.spec()) + } + .build() private fun Qualifier.spec(): AnnotationSpec { val className = @@ -336,39 +314,34 @@ object KotlinCodeGenerator { .build() } - private fun DependencyMethodJavaDoc.spec(): CodeBlock { - return CodeBlock.builder() - .apply { - add("\nRequested from:\n") - requestedFrom.forEach { add(it.spec()) } - add("\n") - } - .build() - } - - private fun JavaDocMethodLink.spec(): CodeBlock { - return CodeBlock.of("* [%L.%N]\n", owner, methodName) - } + private fun DependencyMethodJavaDoc.spec(): CodeBlock = + CodeBlock.builder() + .apply { + add("\nRequested from:\n") + requestedFrom.forEach { add(it.spec()) } + add("\n") + } + .build() - private fun ObjectsImpl.spec(): TypeSpec { - return TypeSpec.classBuilder(className.kt) - .apply { - addModifiers(KModifier.PRIVATE) - if (isInterface) { - addSuperinterface(superClassName.kt) - } else { - superclass(superClassName.kt) + private fun JavaDocMethodLink.spec(): CodeBlock = CodeBlock.of("* [%L.%N]\n", owner, methodName) + + private fun ObjectsImpl.spec(): TypeSpec = + TypeSpec.classBuilder(className.kt) + .apply { + addModifiers(KModifier.PRIVATE) + if (isInterface) { + addSuperinterface(superClassName.kt) + } else { + superclass(superClassName.kt) + } + abstractMethods.forEach { addFunction(it.spec()) } } - abstractMethods.forEach { addFunction(it.spec()) } - } - .build() - } + .build() - private fun ObjectsAbstractMethod.spec(): FunSpec { - return XFunSpec.overriding(overriddenMethod.element, overriddenMethod.owner, env) - .addStatement("throw %T()", UnsupportedOperationException::class) - .build() - } + private fun ObjectsAbstractMethod.spec(): FunSpec = + XFunSpec.overriding(overriddenMethod.element, overriddenMethod.owner, env) + .addStatement("throw %T()", UnsupportedOperationException::class) + .build() private fun suppressAnnotationSpec(vararg names: String): AnnotationSpec = AnnotationSpec.builder(Suppress::class.java) diff --git a/compiler/src/main/kotlin/motif/compiler/KotlinTypeWorkaround.kt b/compiler/src/main/kotlin/motif/compiler/KotlinTypeWorkaround.kt index a51d06fd..94fe75ea 100644 --- a/compiler/src/main/kotlin/motif/compiler/KotlinTypeWorkaround.kt +++ b/compiler/src/main/kotlin/motif/compiler/KotlinTypeWorkaround.kt @@ -33,51 +33,45 @@ import kotlin.reflect.jvm.internal.impl.name.FqName @OptIn(KotlinPoetJavaPoetPreview::class) object KotlinTypeWorkaround { - fun javaToKotlinType(mirror: XType): TypeName { - return javaToKotlinType(asTypeName(mirror), mirror.getProcessingEnv()) - } + fun javaToKotlinType(mirror: XType): TypeName = + javaToKotlinType(asTypeName(mirror), mirror.getProcessingEnv()) fun javaToKotlinType( className: com.squareup.kotlinpoet.ClassName, - env: XProcessingEnv? - ): TypeName { - return javaToKotlinType(className as TypeName, env) - } + env: XProcessingEnv?, + ): TypeName = javaToKotlinType(className as TypeName, env) - private fun asTypeName(mirror: XType): TypeName { - return mirror.typeName.toKTypeName() - } + private fun asTypeName(mirror: XType): TypeName = mirror.typeName.toKTypeName() /** https://github.com/square/kotlinpoet/issues/236#issuecomment-437961476 */ - private fun javaToKotlinType(typeName: TypeName, env: XProcessingEnv?): TypeName { - return when (typeName) { - is ParameterizedTypeName -> - (javaToKotlinType(typeName.rawType, null) as com.squareup.kotlinpoet.ClassName) - .parameterizedBy( - *typeName.typeArguments.map { javaToKotlinType(it, env) }.toTypedArray()) - is WildcardTypeName -> - when { - typeName.inTypes.isNotEmpty() -> - WildcardTypeName.consumerOf(javaToKotlinType(typeName.inTypes.single(), env)) - typeName.outTypes.isNotEmpty() -> - WildcardTypeName.producerOf(javaToKotlinType(typeName.outTypes.single(), env)) - else -> throw IllegalStateException() + private fun javaToKotlinType(typeName: TypeName, env: XProcessingEnv?): TypeName = + when (typeName) { + is ParameterizedTypeName -> + (javaToKotlinType(typeName.rawType, null) as com.squareup.kotlinpoet.ClassName) + .parameterizedBy( + *typeName.typeArguments.map { javaToKotlinType(it, env) }.toTypedArray(), + ) + is WildcardTypeName -> + when { + typeName.inTypes.isNotEmpty() -> + WildcardTypeName.consumerOf(javaToKotlinType(typeName.inTypes.single(), env)) + typeName.outTypes.isNotEmpty() -> + WildcardTypeName.producerOf(javaToKotlinType(typeName.outTypes.single(), env)) + else -> throw IllegalStateException() + } + is TypeVariableName -> STAR + else -> { + val className = + JavaToKotlinClassMap.INSTANCE.mapJavaToKotlin(FqName(typeName.toString())) + ?.asSingleFqName() + ?.asString() + if (className == null) { + typeName.withRawTypeFix(env) + } else { + com.squareup.kotlinpoet.ClassName.bestGuess(className) } - is TypeVariableName -> STAR - else -> { - val className = - JavaToKotlinClassMap.INSTANCE - .mapJavaToKotlin(FqName(typeName.toString())) - ?.asSingleFqName() - ?.asString() - if (className == null) { - typeName.withRawTypeFix(env) - } else { - com.squareup.kotlinpoet.ClassName.bestGuess(className) } } - } - } private fun TypeName.withRawTypeFix(env: XProcessingEnv?): TypeName { if (env?.backend == XProcessingEnv.Backend.KSP && this is com.squareup.kotlinpoet.ClassName) { diff --git a/compiler/src/main/kotlin/motif/compiler/MotifProcessingStep.kt b/compiler/src/main/kotlin/motif/compiler/MotifProcessingStep.kt index 85466b5b..5e5f40a5 100644 --- a/compiler/src/main/kotlin/motif/compiler/MotifProcessingStep.kt +++ b/compiler/src/main/kotlin/motif/compiler/MotifProcessingStep.kt @@ -43,7 +43,7 @@ class MotifProcessingStep( override fun process( env: XProcessingEnv, elementsByAnnotation: Map>, - isLastRound: Boolean + isLastRound: Boolean, ): Set { messageWatcher?.let { env.messager.addMessageWatcher(messageWatcher) } @@ -98,7 +98,9 @@ class MotifProcessingStep( Expected: ${initialScopeNames.sorted().joinToString(", ")} Created: ${createdScopeNames.sorted().joinToString(", ")} Missing: ${missingScopeNames.sorted().joinToString(", ")} - """.trimIndent()) + """ + .trimIndent(), + ) return emptySet() } diff --git a/compiler/src/main/kotlin/motif/compiler/Names.kt b/compiler/src/main/kotlin/motif/compiler/Names.kt index 70f3bcd6..6935beaa 100644 --- a/compiler/src/main/kotlin/motif/compiler/Names.kt +++ b/compiler/src/main/kotlin/motif/compiler/Names.kt @@ -25,11 +25,13 @@ class NameScope(blacklist: Iterable = emptySet()) { private val names = UniqueNameSet(blacklist) - fun name(type: Type): String { - return names.unique( - Names.safeName( - (type.type as CompilerType).mirror, (type.qualifier as? CompilerAnnotation)?.mirror)) - } + fun name(type: Type): String = + names.unique( + Names.safeName( + (type.type as CompilerType).mirror, + (type.qualifier as? CompilerAnnotation)?.mirror, + ), + ) } private class UniqueNameSet(blacklist: Iterable) { @@ -59,13 +61,12 @@ object Names { return name } - private fun annotationString(annotation: XAnnotation?): String { - return if (annotation?.qualifiedName == "javax.inject.Named") { - annotation.getAnnotationValue("value").value.toString() - } else { - annotation?.type?.typeElement?.name.orEmpty() - } - } + private fun annotationString(annotation: XAnnotation?): String = + if (annotation?.qualifiedName == "javax.inject.Named") { + annotation.getAnnotationValue("value").value.toString() + } else { + annotation?.type?.typeElement?.name.orEmpty() + } } private val KEYWORDS = @@ -119,4 +120,5 @@ private val KEYWORDS = "float", "native", "super", - "while") + "while", + ) diff --git a/compiler/src/main/kotlin/motif/compiler/Processor.kt b/compiler/src/main/kotlin/motif/compiler/Processor.kt index 7b71a265..07d136f8 100644 --- a/compiler/src/main/kotlin/motif/compiler/Processor.kt +++ b/compiler/src/main/kotlin/motif/compiler/Processor.kt @@ -26,15 +26,10 @@ const val OPTION_MODE = "motif.mode" class Processor : JavacBasicAnnotationProcessor() { lateinit var graph: ResolvedGraph - override fun getSupportedSourceVersion(): SourceVersion { - return SourceVersion.latestSupported() - } + override fun getSupportedSourceVersion(): SourceVersion = SourceVersion.latestSupported() - override fun processingSteps(): Iterable { - return listOf(MotifProcessingStep(graphSetter = { graph = it })) - } + override fun processingSteps(): Iterable = + listOf(MotifProcessingStep(graphSetter = { graph = it })) - override fun getSupportedOptions(): Set { - return setOf(OPTION_MODE, OPTION_KAPT_KOTLIN_GENERATED) - } + override fun getSupportedOptions(): Set = setOf(OPTION_MODE, OPTION_KAPT_KOTLIN_GENERATED) } diff --git a/compiler/src/main/kotlin/motif/compiler/ScopeImpl.kt b/compiler/src/main/kotlin/motif/compiler/ScopeImpl.kt index 855a5ca5..11e924c8 100644 --- a/compiler/src/main/kotlin/motif/compiler/ScopeImpl.kt +++ b/compiler/src/main/kotlin/motif/compiler/ScopeImpl.kt @@ -50,7 +50,7 @@ class ScopeImpl( val factoryProviderMethods: List, val dependencyProviderMethods: List, val objectsImpl: ObjectsImpl?, - val dependencies: Dependencies? + val dependencies: Dependencies?, ) /** @@ -65,7 +65,7 @@ class ScopeImpl( class ScopeImplAnnotation( val children: List, val scopeClassName: ClassName, - val dependenciesClassName: ClassName + val dependenciesClassName: ClassName, ) /** @@ -76,7 +76,7 @@ class ScopeImplAnnotation( class ObjectsField( val objectsClassName: ClassName, val objectsImplClassName: ClassName, - val name: String + val name: String, ) /** @@ -103,7 +103,7 @@ class CacheField(val name: String) class Constructor( val dependenciesClassName: ClassName, val dependenciesParameterName: String, - val dependenciesFieldName: String + val dependenciesFieldName: String, ) /** @@ -127,7 +127,7 @@ class AccessMethodImpl( // Required work around https://github.com/square/javapoet/issues/656 val env: XProcessingEnv, val overriddenMethod: CompilerMethod, - val providerMethodName: String + val providerMethodName: String, ) /** @@ -143,7 +143,7 @@ class ChildMethodImpl( val childImplClassName: ClassName, val childMethodName: String, val parameters: List, - val childDependenciesImpl: ChildDependenciesImpl + val childDependenciesImpl: ChildDependenciesImpl, ) /** @@ -165,7 +165,7 @@ class ChildDependenciesImpl( val childDependenciesClassName: ClassName, val methods: List, val isAbstractClass: Boolean, - val env: XProcessingEnv + val env: XProcessingEnv, ) /** @@ -180,7 +180,7 @@ class ChildDependencyMethodImpl( val name: String, val returnTypeName: TypeName, val returnExpression: ReturnExpression, - val isInternal: Boolean + val isInternal: Boolean, ) { sealed class ReturnExpression { @@ -222,7 +222,7 @@ class DependencyProviderMethod( val returnTypeName: TypeName, val dependenciesFieldName: String, val dependencyMethodName: String, - val env: XProcessingEnv + val env: XProcessingEnv, ) /** @@ -239,7 +239,7 @@ class FactoryProviderMethod( val returnTypeName: TypeName, val body: FactoryProviderMethodBody, val spreadProviderMethods: List, - val env: XProcessingEnv + val env: XProcessingEnv, ) sealed class FactoryProviderMethodBody { @@ -260,7 +260,7 @@ sealed class FactoryProviderMethodBody { val cacheFieldName: String, val returnTypeName: TypeName, val instantiation: FactoryProviderInstantiation, - val env: XProcessingEnv + val env: XProcessingEnv, ) : FactoryProviderMethodBody() /** @@ -289,7 +289,7 @@ sealed class FactoryProviderInstantiation { val objectsClassName: ClassName, val isStatic: Boolean, val factoryMethodName: String, - val callProviders: CallProviders + val callProviders: CallProviders, ) : FactoryProviderInstantiation() /** @@ -328,7 +328,7 @@ class SpreadProviderMethod( val returnTypeName: TypeName, val sourceTypeName: TypeName, val sourceProviderMethodName: String, - val spreadMethodName: String + val spreadMethodName: String, ) /** @@ -352,7 +352,7 @@ class DependencyMethod( val returnTypeName: TypeName, val qualifier: Qualifier?, val javaDoc: DependencyMethodJavaDoc, - val internal: Boolean + val internal: Boolean, ) /** @@ -380,7 +380,7 @@ class DependencyMethodJavaDoc(val requestedFrom: List) class JavaDocMethodLink( val owner: String, val methodName: String, - val parameterTypes: List + val parameterTypes: List, ) /** @@ -395,7 +395,7 @@ class ObjectsImpl( val className: ClassName, val superClassName: ClassName, val isInterface: Boolean, - val abstractMethods: List + val abstractMethods: List, ) /** @@ -409,7 +409,7 @@ class ObjectsImpl( class ObjectsAbstractMethod( // Required work around https://github.com/square/javapoet/issues/656 val env: XProcessingEnv, - val overriddenMethod: CompilerMethod + val overriddenMethod: CompilerMethod, ) class TypeName private constructor(private val mirror: XType) { @@ -421,17 +421,18 @@ class TypeName private constructor(private val mirror: XType) { jTypeName is com.squareup.javapoet.ClassName) { ParameterizedTypeName.get( jTypeName, - *mirror - .typeArguments + *mirror.typeArguments .map { WildcardTypeName.subtypeOf(Object::class.java) } - .toTypedArray()) + .toTypedArray(), + ) } else if (mirror.typeArguments.isNotEmpty() && "<" in jTypeName.toString() && "$" in jTypeName.toString()) { // Work around issue where JavaPoet returns a TypeName with a '$' for a Kotlin inner class ParameterizedTypeName.get( com.squareup.javapoet.ClassName.get(mirror.typeElement?.toJavac()), - *mirror.typeArguments.map { it.typeName }.toTypedArray()) + *mirror.typeArguments.map { it.typeName }.toTypedArray(), + ) } else { jTypeName } @@ -464,25 +465,27 @@ class TypeName private constructor(private val mirror: XType) { companion object { - fun get(mirror: XType): TypeName { - return TypeName(mirror) - } + fun get(mirror: XType): TypeName = TypeName(mirror) } } class ClassName -private constructor(val j: com.squareup.javapoet.ClassName, val env: XProcessingEnv?) { +private constructor( + val j: com.squareup.javapoet.ClassName, + val env: XProcessingEnv?, +) { val kt: com.squareup.kotlinpoet.ClassName by lazy { val className = com.squareup.kotlinpoet.ClassName( - j.packageName(), j.simpleNames().first(), *j.simpleNames().drop(1).toTypedArray()) + j.packageName(), + j.simpleNames().first(), + *j.simpleNames().drop(1).toTypedArray(), + ) KotlinTypeWorkaround.javaToKotlinType(className, env) as com.squareup.kotlinpoet.ClassName } - fun nestedClass(name: String): ClassName { - return ClassName(j.nestedClass(name), env) - } + fun nestedClass(name: String): ClassName = ClassName(j.nestedClass(name), env) companion object { @@ -491,8 +494,7 @@ private constructor(val j: com.squareup.javapoet.ClassName, val env: XProcessing return ClassName(j, null) } - fun get(j: com.squareup.javapoet.TypeName, env: XProcessingEnv): ClassName { - return ClassName(j as com.squareup.javapoet.ClassName, env) - } + fun get(j: com.squareup.javapoet.TypeName, env: XProcessingEnv): ClassName = + ClassName(j as com.squareup.javapoet.ClassName, env) } } diff --git a/compiler/src/main/kotlin/motif/compiler/ScopeImplFactory.kt b/compiler/src/main/kotlin/motif/compiler/ScopeImplFactory.kt index c730e70c..c56aa5ed 100644 --- a/compiler/src/main/kotlin/motif/compiler/ScopeImplFactory.kt +++ b/compiler/src/main/kotlin/motif/compiler/ScopeImplFactory.kt @@ -38,7 +38,10 @@ import motif.models.Spread import motif.models.Type class ScopeImplFactory -private constructor(private val env: XProcessingEnv, private val graph: ResolvedGraph) { +private constructor( + private val env: XProcessingEnv, + private val graph: ResolvedGraph, +) { private val scopeImplClassNames = mutableMapOf() private val dependenciesClassNames = mutableMapOf() @@ -80,7 +83,8 @@ private constructor(private val env: XProcessingEnv, private val graph: Resolved factoryProviderMethods(), dependencyProviderMethods(), objectsImpl(), - dependencies()) + dependencies(), + ) } private fun scopeImplAnnotation(): ScopeImplAnnotation { @@ -94,19 +98,16 @@ private constructor(private val env: XProcessingEnv, private val graph: Resolved return ObjectsField(objectsClassName, objectsImplClassName, OBJECTS_FIELD_NAME) } - private fun dependenciesField(): DependenciesField { - return DependenciesField(scope.dependenciesClassName, DEPENDENCIES_FIELD_NAME) - } + private fun dependenciesField(): DependenciesField = + DependenciesField(scope.dependenciesClassName, DEPENDENCIES_FIELD_NAME) - private fun cacheFields(): List { - return scope.factoryMethods.filter { it.isCached }.map { factoryMethod -> - CacheField(getCacheFieldName(factoryMethod.returnType.type)) - } - } + private fun cacheFields(): List = + scope.factoryMethods + .filter { it.isCached } + .map { factoryMethod -> CacheField(getCacheFieldName(factoryMethod.returnType.type)) } - private fun constructor(): Constructor { - return Constructor(scope.dependenciesClassName, "dependencies", DEPENDENCIES_FIELD_NAME) - } + private fun constructor(): Constructor = + Constructor(scope.dependenciesClassName, "dependencies", DEPENDENCIES_FIELD_NAME) private fun alternateConstructor(): AlternateConstructor? { if (getDependencyMethodData(scope).isNotEmpty() || @@ -116,35 +117,34 @@ private constructor(private val env: XProcessingEnv, private val graph: Resolved return AlternateConstructor(scope.dependenciesClassName) } - private fun accessMethodImpls(): List { - return scope.accessMethods.map { accessMethod -> - AccessMethodImpl( - env, - accessMethod.method as CompilerMethod, - getProviderMethodName(accessMethod.returnType)) - } - } - - private fun childMethodImpls(): List { - return graph.getChildEdges(scope).map(this::childMethodImpl) - } + private fun accessMethodImpls(): List = + scope.accessMethods.map { accessMethod -> + AccessMethodImpl( + env, + accessMethod.method as CompilerMethod, + getProviderMethodName(accessMethod.returnType), + ) + } - private fun childMethodImpl(childEdge: ScopeEdge): ChildMethodImpl { + private fun childMethodImpls(): List = + graph.getChildEdges(scope).map(this::childMethodImpl) - return ChildMethodImpl( - childEdge.child.typeName, - childEdge.child.implClassName, - childEdge.method.method.name, - childEdge.method.parameters.map(this::childMethodImplParameter), - childDependenciesImpl(childEdge)) - } + private fun childMethodImpl(childEdge: ScopeEdge): ChildMethodImpl = + ChildMethodImpl( + childEdge.child.typeName, + childEdge.child.implClassName, + childEdge.method.method.name, + childEdge.method.parameters.map(this::childMethodImplParameter), + childDependenciesImpl(childEdge), + ) private fun childMethodImplParameter( - childMethodParameter: ChildMethod.Parameter - ): ChildMethodImplParameter { - return ChildMethodImplParameter( - childMethodParameter.parameter.type.typeName, childMethodParameter.parameter.name) - } + childMethodParameter: ChildMethod.Parameter, + ): ChildMethodImplParameter = + ChildMethodImplParameter( + childMethodParameter.parameter.type.typeName, + childMethodParameter.parameter.name, + ) private fun childDependenciesImpl(childEdge: ScopeEdge): ChildDependenciesImpl { val parameters: Map = @@ -155,24 +155,34 @@ private constructor(private val env: XProcessingEnv, private val graph: Resolved } val isAbstractClass = dependencyMethodImpls.any { it.isInternal } return ChildDependenciesImpl( - childEdge.child.dependenciesClassName, dependencyMethodImpls, isAbstractClass, env) + childEdge.child.dependenciesClassName, + dependencyMethodImpls, + isAbstractClass, + env, + ) } private fun childDependencyMethodImpl( parameters: Map, - methodData: DependencyMethodData + methodData: DependencyMethodData, ): ChildDependencyMethodImpl { val parameter = parameters[methodData.returnType] val returnExpression = if (parameter == null) { ChildDependencyMethodImpl.ReturnExpression.Provider( - scope.implClassName, getProviderMethodName(methodData.returnType)) + scope.implClassName, + getProviderMethodName(methodData.returnType), + ) } else { ChildDependencyMethodImpl.ReturnExpression.Parameter(parameter.parameter.name) } val isInternal = (methodData.returnType.type as? CompilerType)?.isInternal() ?: false return ChildDependencyMethodImpl( - methodData.name, methodData.returnTypeName, returnExpression, isInternal) + methodData.name, + methodData.returnTypeName, + returnExpression, + isInternal, + ) } private fun scopeProviderMethod(): ScopeProviderMethod { @@ -181,19 +191,19 @@ private constructor(private val env: XProcessingEnv, private val graph: Resolved return ScopeProviderMethod(name, scope.typeName, isInternal) } - private fun factoryProviderMethods(): List { - return scope.factoryMethods.map { factoryMethod -> - val returnType = factoryMethod.returnType.type - val spreadProviderMethods = - factoryMethod.spread?.let { spreadProviderMethods(it) } ?: emptyList() - FactoryProviderMethod( - getProviderMethodName(returnType), - returnType.type.typeName, - factoryProviderMethodBody(factoryMethod), - spreadProviderMethods, - env) - } - } + private fun factoryProviderMethods(): List = + scope.factoryMethods.map { factoryMethod -> + val returnType = factoryMethod.returnType.type + val spreadProviderMethods = + factoryMethod.spread?.let { spreadProviderMethods(it) } ?: emptyList() + FactoryProviderMethod( + getProviderMethodName(returnType), + returnType.type.typeName, + factoryProviderMethodBody(factoryMethod), + spreadProviderMethods, + env, + ) + } private fun factoryProviderMethodBody(factoryMethod: FactoryMethod): FactoryProviderMethodBody { val instantiation = @@ -207,48 +217,50 @@ private constructor(private val env: XProcessingEnv, private val graph: Resolved getCacheFieldName(factoryMethod.returnType.type), factoryMethod.returnType.type.type.typeName, instantiation, - env) + env, + ) } else { FactoryProviderMethodBody.Uncached(instantiation) } } - private fun spreadProviderMethods(spread: Spread): List { - return spread.methods.map { method -> - SpreadProviderMethod( - getProviderMethodName(method.returnType), - method.method.isStatic(), - method.returnType.type.typeName, - method.sourceType.type.typeName, - getProviderMethodName(method.sourceType), - method.name) - } - } + private fun spreadProviderMethods(spread: Spread): List = + spread.methods.map { method -> + SpreadProviderMethod( + getProviderMethodName(method.returnType), + method.method.isStatic(), + method.returnType.type.typeName, + method.sourceType.type.typeName, + getProviderMethodName(method.sourceType), + method.name, + ) + } private fun basicInstantiation( - factoryMethod: BasicFactoryMethod - ): FactoryProviderInstantiation.Basic { - return FactoryProviderInstantiation.Basic( - OBJECTS_FIELD_NAME, - factoryMethod.objects.clazz.typeName, - factoryMethod.isStatic, - factoryMethod.name, - callProviders(factoryMethod)) - } + factoryMethod: BasicFactoryMethod, + ): FactoryProviderInstantiation.Basic = + FactoryProviderInstantiation.Basic( + OBJECTS_FIELD_NAME, + factoryMethod.objects.clazz.typeName, + factoryMethod.isStatic, + factoryMethod.name, + callProviders(factoryMethod), + ) private fun constructorInstantiation( - factoryMethod: ConstructorFactoryMethod - ): FactoryProviderInstantiation.Constructor { - return FactoryProviderInstantiation.Constructor( - factoryMethod.returnType.type.type.typeName, callProviders(factoryMethod)) - } + factoryMethod: ConstructorFactoryMethod, + ): FactoryProviderInstantiation.Constructor = + FactoryProviderInstantiation.Constructor( + factoryMethod.returnType.type.type.typeName, + callProviders(factoryMethod), + ) private fun bindsInstantiation( - factoryMethod: BindsFactoryMethod - ): FactoryProviderInstantiation.Binds { - return FactoryProviderInstantiation.Binds( - getProviderMethodName(factoryMethod.parameters.single().type)) - } + factoryMethod: BindsFactoryMethod, + ): FactoryProviderInstantiation.Binds = + FactoryProviderInstantiation.Binds( + getProviderMethodName(factoryMethod.parameters.single().type), + ) private fun callProviders(factoryMethod: FactoryMethod): CallProviders { val names = @@ -256,29 +268,30 @@ private constructor(private val env: XProcessingEnv, private val graph: Resolved return CallProviders(names) } - private fun dependencyProviderMethods(): List { - return getDependencyMethodData(scope).map { methodData -> - DependencyProviderMethod( - getProviderMethodName(methodData.returnType), - methodData.returnTypeName, - DEPENDENCIES_FIELD_NAME, - methodData.name, - env) - } - } + private fun dependencyProviderMethods(): List = + getDependencyMethodData(scope).map { methodData -> + DependencyProviderMethod( + getProviderMethodName(methodData.returnType), + methodData.returnTypeName, + DEPENDENCIES_FIELD_NAME, + methodData.name, + env, + ) + } private fun objectsImpl(): ObjectsImpl? { val objects = scope.objects ?: return null val objectsClassName = scope.objectsClassName ?: return null val abstractMethods = - objects.factoryMethods.filter { it.method.isAbstract() }.map { - ObjectsAbstractMethod(env, it.method as CompilerMethod) - } + objects.factoryMethods + .filter { it.method.isAbstract() } + .map { ObjectsAbstractMethod(env, it.method as CompilerMethod) } return ObjectsImpl( scope.objectsImplClassName, objectsClassName, objects.clazz.kind == IrClass.Kind.INTERFACE, - abstractMethods) + abstractMethods, + ) } private fun dependencies(): Dependencies? { @@ -297,7 +310,8 @@ private constructor(private val env: XProcessingEnv, private val graph: Resolved methodData.returnTypeName, qualifier, javaDoc(methodData), - isInternal) + isInternal, + ) } return Dependencies(scope.dependenciesClassName, methods) } @@ -313,8 +327,11 @@ private constructor(private val env: XProcessingEnv, private val graph: Resolved val owner = removeGenerics(ownerType.qualifiedName) val methodName = - if (callerMethod.isConstructor) ownerType.simpleName.substringBefore('<') - else callerMethod.name + if (callerMethod.isConstructor) { + ownerType.simpleName.substringBefore('<') + } else { + callerMethod.name + } val paramList = callerMethod.parameters.map { removeGenerics(it.type.qualifiedName) } JavaDocMethodLink(owner, methodName, paramList) @@ -322,9 +339,7 @@ private constructor(private val env: XProcessingEnv, private val graph: Resolved return DependencyMethodJavaDoc(requestedFrom) } - private fun removeGenerics(name: String): String { - return name.takeWhile { it != '<' } - } + private fun removeGenerics(name: String): String = name.takeWhile { it != '<' } private fun getProviderMethodName(type: Type): String { // val key = getTypeOrMappedType(type, providerMethodNames.keys) @@ -354,12 +369,11 @@ private constructor(private val env: XProcessingEnv, private val graph: Resolved val name: String, val returnTypeName: TypeName, val returnType: Type, - val sinks: List + val sinks: List, ) - private fun getDependencyMethodData(scope: Scope): List { - return dependencyMethods.computeIfAbsent(scope) { createDependencyMethods(scope) } - } + private fun getDependencyMethodData(scope: Scope): List = + dependencyMethods.computeIfAbsent(scope) { createDependencyMethods(scope) } private fun createDependencyMethods(scope: Scope): List { val nameScope = NameScope() @@ -416,8 +430,7 @@ private constructor(private val env: XProcessingEnv, private val graph: Resolved private const val OBJECTS_FIELD_NAME = "objects" private const val DEPENDENCIES_FIELD_NAME = "dependencies" - fun create(env: XProcessingEnv, graph: ResolvedGraph): List { - return ScopeImplFactory(env, graph).create() - } + fun create(env: XProcessingEnv, graph: ResolvedGraph): List = + ScopeImplFactory(env, graph).create() } } diff --git a/compiler/src/main/kotlin/motif/compiler/XFunSpec.kt b/compiler/src/main/kotlin/motif/compiler/XFunSpec.kt index 7768c0fe..62afad73 100644 --- a/compiler/src/main/kotlin/motif/compiler/XFunSpec.kt +++ b/compiler/src/main/kotlin/motif/compiler/XFunSpec.kt @@ -34,7 +34,7 @@ object XFunSpec { fun overriding( executableElement: XExecutableElement, enclosing: XType, - env: XProcessingEnv + env: XProcessingEnv, ): FunSpec.Builder { val methodElement = (executableElement as? XMethodElement) @@ -54,13 +54,16 @@ object XFunSpec { private fun overriding( method: XMethodElement, - resolvedParameterTypes: List + resolvedParameterTypes: List, ): FunSpec.Builder { var modifiers: Set = method.modifiers.toMutableSet() require( Modifier.PRIVATE !in modifiers && Modifier.FINAL !in modifiers && - Modifier.STATIC !in modifiers) { "cannot override method with modifiers: $modifiers" } + Modifier.STATIC !in modifiers, + ) { + "cannot override method with modifiers: $modifiers" + } val methodName = method.name val funBuilder = FunSpec.builder(methodName) @@ -73,16 +76,17 @@ object XFunSpec { // TODO: Unsupported until XProcessing is updated /* - method as XParam - .map { it.asType() as TypeVariable } - .map { it.asTypeVariableName() } - .forEach { funBuilder.addTypeVariable(it) } - */ + method as XParam + .map { it.asType() as TypeVariable } + .map { it.asTypeVariableName() } + .forEach { funBuilder.addTypeVariable(it) } + */ method.parameters.forEachIndexed { index, parameter -> funBuilder.addParameter( ParameterSpec.builder(parameter.name, javaToKotlinType(resolvedParameterTypes[index])) - .build()) + .build(), + ) } if (method.isVarArgs()) { funBuilder.parameters[funBuilder.parameters.lastIndex] = @@ -94,7 +98,8 @@ object XFunSpec { funBuilder.addAnnotation( AnnotationSpec.builder(Throws::class) .addMember(throwsValueString, *method.thrownTypes.toTypedArray()) - .build()) + .build(), + ) } return funBuilder diff --git a/compiler/src/main/kotlin/motif/compiler/XNameVisitor.kt b/compiler/src/main/kotlin/motif/compiler/XNameVisitor.kt index ff65cb7a..f540e9a2 100644 --- a/compiler/src/main/kotlin/motif/compiler/XNameVisitor.kt +++ b/compiler/src/main/kotlin/motif/compiler/XNameVisitor.kt @@ -33,36 +33,34 @@ import com.uber.xprocessing.ext.isPrimitive object XNameVisitor { - fun visit(t: XType): String { - return when { - t.isVoid() -> visitNoType(t) - t.isError() && - t.typeElement?.qualifiedName.orEmpty().let { "ERROR" in it || "NonExistent" in it } -> - visitError(t) - t.isArray() -> visitArray(t) - t.isWildcard() -> visitWildcard(t) - t.isDeclaredType() -> visitDeclared(t) - t.isPrimitive() -> visitPrimitive(t) - t.isEnum() -> visitDeclared(t) - t.isKotlinUnit() -> visitDeclared(t) - t.isTypeVariable() -> visitTypeVariable(t) - else -> visitNoType(t) - } - } - - private fun visitPrimitive(t: XType): String { - return when (t.typeName) { - TypeName.BOOLEAN -> "Boolean" - TypeName.BYTE -> "Byte" - TypeName.SHORT -> "Short" - TypeName.INT -> "Integer" - TypeName.LONG -> "Long" - TypeName.CHAR -> "Character" - TypeName.FLOAT -> "Float" - TypeName.DOUBLE -> "Double" - else -> throw IllegalStateException() - } - } + fun visit(t: XType): String = + when { + t.isVoid() -> visitNoType(t) + t.isError() && + t.typeElement?.qualifiedName.orEmpty().let { "ERROR" in it || "NonExistent" in it } -> + visitError(t) + t.isArray() -> visitArray(t) + t.isWildcard() -> visitWildcard(t) + t.isDeclaredType() -> visitDeclared(t) + t.isPrimitive() -> visitPrimitive(t) + t.isEnum() -> visitDeclared(t) + t.isKotlinUnit() -> visitDeclared(t) + t.isTypeVariable() -> visitTypeVariable(t) + else -> visitNoType(t) + } + + private fun visitPrimitive(t: XType): String = + when (t.typeName) { + TypeName.BOOLEAN -> "Boolean" + TypeName.BYTE -> "Byte" + TypeName.SHORT -> "Short" + TypeName.INT -> "Integer" + TypeName.LONG -> "Long" + TypeName.CHAR -> "Character" + TypeName.FLOAT -> "Float" + TypeName.DOUBLE -> "Double" + else -> throw IllegalStateException() + } private fun visitDeclared(t: XType, p: Void? = null): String { t.typeElement?.kindName() @@ -105,13 +103,10 @@ object XNameVisitor { return "$typeArgumentString$rawString" } - private fun visitArray(t: XArrayType, p: Void? = null): String { - return visit(t.componentType) + "Array" - } + private fun visitArray(t: XArrayType, p: Void? = null): String = visit(t.componentType) + "Array" - private fun visitTypeVariable(t: XType, p: Void? = null): String { - return t.typeName.toString().capitalize() - } + private fun visitTypeVariable(t: XType, p: Void? = null): String = + t.typeName.toString().capitalize() private fun visitWildcard(t: XType, p: Void? = null): String { if (t.typeName.toString() == "?" || t.typeName.toString() == "*") { @@ -119,28 +114,20 @@ object XNameVisitor { } return t.extendsBound()?.let { return visit(it) - } - ?: "" + } ?: "" } - private fun visitNoType(t: XType): String { - return if (t.isVoid()) "Void" else defaultAction(t) - } + private fun visitNoType(t: XType): String = if (t.isVoid()) "Void" else defaultAction(t) - private fun visitError(t: XType, p: Void? = null): String { - throw IllegalStateException( - "Could not generate name for ErrorType: $t. Check your code for missing imports or typos.") - } + private fun visitError(t: XType, p: Void? = null): String = + throw IllegalStateException( + "Could not generate name for ErrorType: $t. Check your code for missing imports or typos.", + ) - private fun defaultAction(t: XType?): String { - throw IllegalArgumentException("Unexpected type mirror: $t") - } + private fun defaultAction(t: XType?): String = + throw IllegalArgumentException("Unexpected type mirror: $t") } -private fun XType.isWildcard(): Boolean { - return typeName is WildcardTypeName -} +private fun XType.isWildcard(): Boolean = typeName is WildcardTypeName -private fun XType.isTypeVariable(): Boolean { - return typeName is TypeVariableName -} +private fun XType.isTypeVariable(): Boolean = typeName is TypeVariableName diff --git a/compiler/src/test/java/license/LicenseTest.kt b/compiler/src/test/java/license/LicenseTest.kt index 71e460d4..60528139 100644 --- a/compiler/src/test/java/license/LicenseTest.kt +++ b/compiler/src/test/java/license/LicenseTest.kt @@ -42,7 +42,8 @@ class LicenseTest { * See the License for the specific language governing permissions and * limitations under the License. */ - """.trimIndent() + """ + .trimIndent() @Test fun test() { diff --git a/compiler/src/test/java/motif/compiler/NamesTest.kt b/compiler/src/test/java/motif/compiler/NamesTest.kt index 5969a992..64ba38d3 100644 --- a/compiler/src/test/java/motif/compiler/NamesTest.kt +++ b/compiler/src/test/java/motif/compiler/NamesTest.kt @@ -31,20 +31,21 @@ import org.junit.runners.Parameterized @RunWith(Parameterized::class) @OptIn(ExperimentalProcessingApi::class) -class XNamesTest(private val processorType: ProcessorType, private val srcLang: SourceLanguage) { +class NamesTest(private val processorType: ProcessorType, private val srcLang: SourceLanguage) { companion object { @JvmStatic @Parameterized.Parameters(name = "{0}_{1}") - fun data(): Collection> { - return cartesianProduct( - ProcessorType.values().toSortedSet(), SourceLanguage.values().toSortedSet()) - .filterNot { (proc, srcLang) -> - proc == ProcessorType.AP && srcLang == SourceLanguage.KOTLIN - } - .map { it.toTypedArray() as Array } - .toList() - } + fun data(): Collection> = + cartesianProduct( + ProcessorType.values().toSortedSet(), + SourceLanguage.values().toSortedSet(), + ) + .filterNot { (proc, srcLang) -> + proc == ProcessorType.AP && srcLang == SourceLanguage.KOTLIN + } + .map { it.toTypedArray() as Array } + .toList() } @Test @@ -67,7 +68,8 @@ class XNamesTest(private val processorType: ProcessorType, private val srcLang: assertSafeName( "java.util.HashMap", "java.util.HashMap", - "stringIntegerHashMap") + "stringIntegerHashMap", + ) } @Test @@ -75,7 +77,8 @@ class XNamesTest(private val processorType: ProcessorType, private val srcLang: assertSafeName( "java.util.HashMap", "java.util.HashMap", - "stringIntegerHashMap") + "stringIntegerHashMap", + ) } @Test @@ -98,7 +101,8 @@ class XNamesTest(private val processorType: ProcessorType, private val srcLang: assertSafeName( "java.util.HashMap, Integer>", "java.util.HashMap, Integer>", - "stringIntegerHashMapIntegerHashMap") + "stringIntegerHashMapIntegerHashMap", + ) } @Test @@ -106,7 +110,8 @@ class XNamesTest(private val processorType: ProcessorType, private val srcLang: assertSafeName( "java.util.Map.Entry", "java.util.Map.Entry", - "stringIntegerMapEntry") + "stringIntegerMapEntry", + ) } @Test @@ -147,7 +152,7 @@ class XNamesTest(private val processorType: ProcessorType, private val srcLang: private fun compile( classString: String, qualifierString: String, - assertion: (XTestInvocation, String) -> Unit + assertion: (XTestInvocation, String) -> Unit, ) { when (processorType) { ProcessorType.AP -> { @@ -236,7 +241,7 @@ class XNamesTest(private val processorType: ProcessorType, private val srcLang: javaClassString: String, ktClassString: String, expectedSafeName: String, - qualifierString: String = "" + qualifierString: String = "", ) { val assertion = { invocation: XTestInvocation, safeName: String -> invocation.assertCompilationResult { diff --git a/compiler/src/test/java/motif/compiler/ProGuard.kt b/compiler/src/test/java/motif/compiler/ProGuard.kt index 0878d5e3..732c7d67 100644 --- a/compiler/src/test/java/motif/compiler/ProGuard.kt +++ b/compiler/src/test/java/motif/compiler/ProGuard.kt @@ -32,20 +32,20 @@ object ProGuard { private val classPathFiles: List by lazy { listOf( - Scope::class, - Truth::class, - Inject::class, - Nullable::class, - Component::class, - Unit::class, - NotNull::class) + Scope::class, + Truth::class, + Inject::class, + Nullable::class, + Component::class, + Unit::class, + NotNull::class, + ) .map { libraryPath(it) } } @JvmStatic - fun run(externalClassesDirs: List, classesDir: File, proguardFile: File): File { - return run(externalClassesDirs, listOf(classesDir), proguardFile) - } + fun run(externalClassesDirs: List, classesDir: File, proguardFile: File): File = + run(externalClassesDirs, listOf(classesDir), proguardFile) @JvmStatic fun run(externalClassesDirs: List, classesDirs: List, proguardFile: File): File { @@ -76,7 +76,6 @@ object ProGuard { return outputJar } - private fun libraryPath(clazz: KClass<*>): File { - return File(clazz.java.protectionDomain.codeSource.location.toURI()) - } + private fun libraryPath(clazz: KClass<*>): File = + File(clazz.java.protectionDomain.codeSource.location.toURI()) } diff --git a/compiler/src/test/java/motif/compiler/TestHarness.kt b/compiler/src/test/java/motif/compiler/TestHarness.kt index 8aca65dc..a2d7e328 100644 --- a/compiler/src/test/java/motif/compiler/TestHarness.kt +++ b/compiler/src/test/java/motif/compiler/TestHarness.kt @@ -80,7 +80,10 @@ class TestHarness( val testCaseDirs = TEST_CASE_ROOT.listFiles { file: File -> isTestDir(file) } val combos = cartesianProduct( - ProcessorType.values().toList(), OutputMode.values().toList(), testCaseDirs.toList()) + ProcessorType.values().toList(), + OutputMode.values().toList(), + testCaseDirs.toList(), + ) return combos .filterNot { (_, mode, dir) -> mode == OutputMode.KOTLIN && (dir as File).resolve("SKIP_KOTLIN").exists() @@ -100,11 +103,10 @@ class TestHarness( .map { it.toTypedArray() as Array } } - private fun isTestDir(file: File): Boolean { - return file.isDirectory && - file.listFiles().isNotEmpty() && - file.name.matches("^K?[TE].*".toRegex()) - } + private fun isTestDir(file: File): Boolean = + file.isDirectory && + file.listFiles().isNotEmpty() && + file.name.matches("^K?[TE].*".toRegex()) } @Test @@ -131,7 +133,8 @@ class TestHarness( result.outputClasspath.filterNot { "/ksp/" in it.absolutePath || "/kapt/" in it.absolutePath }, - proguardFile) + proguardFile, + ) val urls = (externalClassesDirs + proguardedClasses).map { it.toURI().toURL() }.toTypedArray() val classLoader: ClassLoader = URLClassLoader(urls, javaClass.classLoader) @@ -158,7 +161,8 @@ class TestHarness( externalDir, if (shouldProcess) annotationProcessor else null, if (shouldProcess) symbolProcessorProvider else null, - emptyList()) + emptyList(), + ) assertSucceeded(externalResult) return externalResult.outputClasspath.filter { it.listFilesRecursively().isNotEmpty() } } @@ -170,7 +174,7 @@ class TestHarness( sourcesDir: File, annotationProcessor: javax.annotation.processing.Processor?, symbolProcessorProvider: SymbolProcessorProvider?, - classpath: List = emptyList() + classpath: List = emptyList(), ): TestCompilationResult { val processorOptions = mapOf("motif.mode" to outputMode.name.lowercase()) val sources = getFiles(sourcesDir).asSources() @@ -185,10 +189,11 @@ class TestHarness( inheritClasspath = true, kaptProcessors = annotationProcessors, kotlincArguments = listOf("-language-version", "1.9", "-api-version", "1.9"), - symbolProcessorProviders = symbolProcessorProvider?.let { listOf(it) } - ?: emptyList(), + symbolProcessorProviders = + symbolProcessorProvider?.let { listOf(it) } ?: emptyList(), processorOptions = processorOptions, - )) + ), + ) } private fun List.asSources(): List { @@ -203,13 +208,12 @@ class TestHarness( } } - private fun getFiles(dir: File): List { - return dir.walkTopDown() - .filter { - !it.isDirectory && it.extension in setOf("kt", "java") && it.name != "ScopeImpl.java" - } - .toList() - } + private fun getFiles(dir: File): List = + dir.walkTopDown() + .filter { + !it.isDirectory && it.extension in setOf("kt", "java") && it.name != "ScopeImpl.java" + } + .toList() private fun createProcessors(): Pair { val xProcConfig = XProcessingEnvConfig.DEFAULT.copy(false, true) @@ -250,7 +254,9 @@ class TestHarness( Error message has changed. The ERROR.txt file has been automatically updated by this test: 1. Verify that the changes are correct. 2. Commit the changes to source control. - """.trimIndent()) + """ + .trimIndent(), + ) .that(actualErrorString) .isEqualTo(expectedErrorString) } @@ -278,7 +284,9 @@ class TestHarness( Graph representation has changed. The GRAPH.txt file has been automatically updated by this test: 1. Verify that the changes are correct. 2. Commit the changes to source control. - """.trimIndent()) + """ + .trimIndent(), + ) .fail() } } @@ -301,18 +309,18 @@ class TestHarness( # # ######################################################################## - """.trimIndent() + """ + .trimIndent() return "$header\n$message\n" } @Throws(IOException::class) - private fun getExistingGraphString(): String { - return if (graphFile.exists()) { - com.google.common.io.Files.asCharSource(graphFile, Charset.defaultCharset()).read() - } else { - "" - } - } + private fun getExistingGraphString(): String = + if (graphFile.exists()) { + com.google.common.io.Files.asCharSource(graphFile, Charset.defaultCharset()).read() + } else { + "" + } private fun getActualErrorString(result: TestCompilationResult): String { val message = getMessage(result) @@ -331,7 +339,8 @@ class TestHarness( # # ######################################################################## - """.trimIndent() + """ + .trimIndent() return "$header\n$message\n" } @@ -343,23 +352,25 @@ class TestHarness( return "$header$resultMessage$footer".prependIndent(" ") } - private fun toCompilerMessage(message: String): String { - return message.trim().prependIndent(" ") - } + private fun toCompilerMessage(message: String): String = message.trim().prependIndent(" ") @Throws(IOException::class) - private fun getExistingErrorString(): String { - return if (errorFile.exists()) { - com.google.common.io.Files.asCharSource(errorFile, Charset.defaultCharset()).read() - } else { - "" - } - } + private fun getExistingErrorString(): String = + if (errorFile.exists()) { + com.google.common.io.Files.asCharSource(errorFile, Charset.defaultCharset()).read() + } else { + "" + } } internal fun File.listFilesRecursively() = walkTopDown().filter { it.isFile }.toList() -private fun TestCompilationResult.messages(): String { - return diagnostics[Diagnostic.Kind.ERROR].orEmpty().flatMap { it.msg.lines() }.joinToString( - separator = "\n") { " $it" } -} +private fun TestCompilationResult.messages(): String = + diagnostics[Diagnostic.Kind.ERROR] + .orEmpty() + .flatMap { it.msg.lines() } + .joinToString( + separator = "\n", + ) { + " $it" + } diff --git a/compiler/src/test/java/motif/compiler/TestParameters.kt b/compiler/src/test/java/motif/compiler/TestParameters.kt index 6c93a515..d165c36f 100644 --- a/compiler/src/test/java/motif/compiler/TestParameters.kt +++ b/compiler/src/test/java/motif/compiler/TestParameters.kt @@ -17,10 +17,10 @@ package motif.compiler enum class ProcessorType { AP, - KSP + KSP, } enum class SourceLanguage { JAVA, - KOTLIN + KOTLIN, } diff --git a/core/src/main/kotlin/motif/core/Cycle.kt b/core/src/main/kotlin/motif/core/Cycle.kt index 0851a361..d4c2c62a 100644 --- a/core/src/main/kotlin/motif/core/Cycle.kt +++ b/core/src/main/kotlin/motif/core/Cycle.kt @@ -25,15 +25,14 @@ class Cycle(val path: List) { companion object { - fun find(items: Iterable, getChildren: (T) -> Iterable): Cycle? { - return CycleFinder(items, getChildren).find() - } + fun find(items: Iterable, getChildren: (T) -> Iterable): Cycle? = + CycleFinder(items, getChildren).find() } } private class CycleFinder( private val items: Iterable, - private val getChildren: (T) -> Iterable + private val getChildren: (T) -> Iterable, ) { fun find(): Cycle? { diff --git a/core/src/main/kotlin/motif/core/ProcessingError.kt b/core/src/main/kotlin/motif/core/ProcessingError.kt index 09f8e776..0bb336a0 100644 --- a/core/src/main/kotlin/motif/core/ProcessingError.kt +++ b/core/src/main/kotlin/motif/core/ProcessingError.kt @@ -34,5 +34,5 @@ class UnexposedSourceError(val source: Source, val sink: Sink) : ProcessingError class AlreadySatisfiedError( val scope: Scope, val source: Source, - val existingSources: List + val existingSources: List, ) : ProcessingError() diff --git a/core/src/main/kotlin/motif/core/ResolvedGraph.kt b/core/src/main/kotlin/motif/core/ResolvedGraph.kt index a630d2d6..e1c31a72 100644 --- a/core/src/main/kotlin/motif/core/ResolvedGraph.kt +++ b/core/src/main/kotlin/motif/core/ResolvedGraph.kt @@ -128,18 +128,31 @@ private class ErrorGraph(error: MotifError) : ResolvedGraph { override val roots = emptyList() override val scopes = emptyList() override val errors = listOf(error) + override fun getScope(scopeType: IrType) = null + override fun getChildEdges(scope: Scope) = emptyList() + override fun getParentEdges(scope: Scope) = emptyList() + override fun getChildUnsatisfied(scopeEdge: ScopeEdge) = emptyList() + override fun getUnsatisfied(scope: Scope) = emptyMap>() + override fun getSources(scope: Scope) = emptyList() + override fun getSinks(type: Type) = emptyList() + override fun getSinks(irType: IrType) = emptyList() + override fun getSources(irType: IrType) = emptyList() + override fun getSinks(scope: Scope) = emptyList() + override fun getProviders(sink: Sink) = emptyList() + override fun getConsumers(source: Source) = emptyList() + override fun getRequired(source: Source) = emptyList() } @@ -147,7 +160,7 @@ private class ValidResolvedGraph( private val scopeGraph: ScopeGraph, private val scopeStates: Map, private val childStates: Map, - private val graphState: State + private val graphState: State, ) : ResolvedGraph { private val scopeSinks = mutableMapOf>() diff --git a/core/src/main/kotlin/motif/core/ScopeGraph.kt b/core/src/main/kotlin/motif/core/ScopeGraph.kt index 0c03b581..623fb056 100644 --- a/core/src/main/kotlin/motif/core/ScopeGraph.kt +++ b/core/src/main/kotlin/motif/core/ScopeGraph.kt @@ -45,28 +45,21 @@ internal class ScopeGraph private constructor(val scopes: List) { val parsingErrors: List = scopes.filterIsInstance().map { it.parsingError } - fun getChildEdges(scope: Scope): List { - return childEdges[scope] - ?: throw NullPointerException("Scope not found: ${scope.qualifiedName}") - } + fun getChildEdges(scope: Scope): List = + childEdges[scope] ?: throw NullPointerException("Scope not found: ${scope.qualifiedName}") - fun getParentEdges(scope: Scope): List { - return parentEdges[scope] - ?: throw NullPointerException("Scope not found: ${scope.qualifiedName}") - } + fun getParentEdges(scope: Scope): List = + parentEdges[scope] ?: throw NullPointerException("Scope not found: ${scope.qualifiedName}") - fun getScope(scopeType: IrType): Scope? { - return scopeMap[scopeType] - } + fun getScope(scopeType: IrType): Scope? = scopeMap[scopeType] - private fun createChildren(scope: Scope): List { - return scope.childMethods.map { method -> - val childScope = - getScope(method.childScopeClass.type) - ?: throw IllegalStateException("Scope not found: ${scope.qualifiedName}") - ScopeEdge(scope, childScope, method) - } - } + private fun createChildren(scope: Scope): List = + scope.childMethods.map { method -> + val childScope = + getScope(method.childScopeClass.type) + ?: throw IllegalStateException("Scope not found: ${scope.qualifiedName}") + ScopeEdge(scope, childScope, method) + } private fun calculateCycle(): ScopeCycleError? { // Sort for stable tests @@ -78,8 +71,6 @@ internal class ScopeGraph private constructor(val scopes: List) { companion object { - fun create(scopes: List): ScopeGraph { - return ScopeGraph(scopes) - } + fun create(scopes: List): ScopeGraph = ScopeGraph(scopes) } } diff --git a/core/src/main/kotlin/motif/core/State.kt b/core/src/main/kotlin/motif/core/State.kt index 468d6a71..11a78a49 100644 --- a/core/src/main/kotlin/motif/core/State.kt +++ b/core/src/main/kotlin/motif/core/State.kt @@ -24,9 +24,7 @@ import motif.models.Type private typealias SetMultiMap = MutableMap> -private fun setMultiMap(): SetMultiMap { - return LinkedHashMap() -} +private fun setMultiMap(): SetMultiMap = LinkedHashMap() /** Carries state through the ResolvedGraph creation logic. */ internal class State( @@ -38,7 +36,7 @@ internal class State( val irTypeToSinks: SetMultiMap = setMultiMap(), val irTypeToSources: SetMultiMap = setMultiMap(), private val exposeNeeded: MutableSet = mutableSetOf(), - private val visibleSinks: SetMultiMap = setMultiMap() + private val visibleSinks: SetMultiMap = setMultiMap(), ) { val edges = LinkedHashMap>() @@ -95,10 +93,10 @@ internal class State( fun checkCycle() { Cycle.find(edges.keys) { source -> - edges.getOrDefault(source, emptyList()).flatMap { sink -> - sinkToSources.getOrDefault(sink, LinkedHashSet()) - } - } + edges.getOrDefault(source, emptyList()).flatMap { sink -> + sinkToSources.getOrDefault(sink, LinkedHashSet()) + } + } ?.let { cycle -> errors.add(DependencyCycleError(cycle.path)) } } @@ -106,18 +104,18 @@ internal class State( exposeNeeded.addAll(visibleSinks.keys) } - fun copy(): State { - return State( - sinkToSources.copy(), - sourceToSinks.copy(), - unsatisfied.toMutableSet(), - errors.toMutableList(), - sinks.copy(), - irTypeToSinks.copy(), - irTypeToSources.copy(), - exposeNeeded.toMutableSet(), - visibleSinks.copy()) - } + fun copy(): State = + State( + sinkToSources.copy(), + sourceToSinks.copy(), + unsatisfied.toMutableSet(), + errors.toMutableList(), + sinks.copy(), + irTypeToSinks.copy(), + irTypeToSources.copy(), + exposeNeeded.toMutableSet(), + visibleSinks.copy(), + ) private fun satisfy(sink: Sink, source: Source) { if (!visibleSinks.contains(sink)) return @@ -148,18 +146,18 @@ internal class State( companion object { - fun merge(states: List): State { - return State( - states.map { it.sinkToSources }.merge(), - states.map { it.sourceToSinks }.merge(), - states.map { it.unsatisfied }.merge(), - states.map { it.errors }.merge(), - states.map { it.sinks }.merge(), - states.map { it.irTypeToSinks }.merge(), - states.map { it.irTypeToSources }.merge(), - states.map { it.exposeNeeded }.merge(), - states.map { it.visibleSinks }.merge()) - } + fun merge(states: List): State = + State( + states.map { it.sinkToSources }.merge(), + states.map { it.sourceToSinks }.merge(), + states.map { it.unsatisfied }.merge(), + states.map { it.errors }.merge(), + states.map { it.sinks }.merge(), + states.map { it.irTypeToSinks }.merge(), + states.map { it.irTypeToSources }.merge(), + states.map { it.exposeNeeded }.merge(), + states.map { it.visibleSinks }.merge(), + ) } } diff --git a/errormessage/src/main/kotlin/motif/errormessage/AccessMethodParametersHandler.kt b/errormessage/src/main/kotlin/motif/errormessage/AccessMethodParametersHandler.kt index 686e6b24..0ad27475 100644 --- a/errormessage/src/main/kotlin/motif/errormessage/AccessMethodParametersHandler.kt +++ b/errormessage/src/main/kotlin/motif/errormessage/AccessMethodParametersHandler.kt @@ -31,6 +31,8 @@ internal class AccessMethodParametersHandler(private val error: AccessMethodPara Suggestions: * If this method was intended to be a child method, ensure that the return type is a Scope. - """.trimIndent()) + """ + .trimIndent(), + ) } } diff --git a/errormessage/src/main/kotlin/motif/errormessage/CannotResolveTypeHandler.kt b/errormessage/src/main/kotlin/motif/errormessage/CannotResolveTypeHandler.kt index a7c73440..11b2b081 100644 --- a/errormessage/src/main/kotlin/motif/errormessage/CannotResolveTypeHandler.kt +++ b/errormessage/src/main/kotlin/motif/errormessage/CannotResolveTypeHandler.kt @@ -31,6 +31,8 @@ internal class CannotResolveTypeHandler(private val error: CannotResolveType) : Suggestions: * Check if the module of ${error.type.qualifiedName} is provided as a dependency to the module where the parent scope of ${error.scope.qualifiedName} is defined. - """.trimIndent()) + """ + .trimIndent(), + ) } } diff --git a/errormessage/src/main/kotlin/motif/errormessage/DependencyMethodWithParametersHandler.kt b/errormessage/src/main/kotlin/motif/errormessage/DependencyMethodWithParametersHandler.kt index 0d89ea2a..8684eebb 100644 --- a/errormessage/src/main/kotlin/motif/errormessage/DependencyMethodWithParametersHandler.kt +++ b/errormessage/src/main/kotlin/motif/errormessage/DependencyMethodWithParametersHandler.kt @@ -18,7 +18,7 @@ package motif.errormessage import motif.models.DependencyMethodWithParameters internal class DependencyMethodWithParametersHandler( - private val error: DependencyMethodWithParameters + private val error: DependencyMethodWithParameters, ) : ErrorHandler { override val name = "DEPENDENCY METHOD PARAMETER" @@ -29,6 +29,8 @@ internal class DependencyMethodWithParametersHandler( Methods on dependencies interfaces must be parameterless: ${error.dependenciesClass.qualifiedName}.${error.method.name} - """.trimIndent()) + """ + .trimIndent(), + ) } } diff --git a/errormessage/src/main/kotlin/motif/errormessage/DuplicatedChildParameterSourceHandler.kt b/errormessage/src/main/kotlin/motif/errormessage/DuplicatedChildParameterSourceHandler.kt index ce93b62d..84b09ff6 100644 --- a/errormessage/src/main/kotlin/motif/errormessage/DuplicatedChildParameterSourceHandler.kt +++ b/errormessage/src/main/kotlin/motif/errormessage/DuplicatedChildParameterSourceHandler.kt @@ -18,7 +18,7 @@ package motif.errormessage import motif.models.DuplicatedChildParameterSource internal class DuplicatedChildParameterSourceHandler( - private val error: DuplicatedChildParameterSource + private val error: DuplicatedChildParameterSource, ) : ErrorHandler { override val name = "DUPLICATED CHILD PARAMETER SOURCE" @@ -29,7 +29,9 @@ internal class DuplicatedChildParameterSourceHandler( Multiple child method parameters of the same type: ${error.childScopeMethod.qualifiedName}(${highlightDuplicatedParameters()}) - """.trimIndent()) + """ + .trimIndent(), + ) } private fun highlightDuplicatedParameters(): String { diff --git a/errormessage/src/main/kotlin/motif/errormessage/DuplicatedDependenciesMethodHandler.kt b/errormessage/src/main/kotlin/motif/errormessage/DuplicatedDependenciesMethodHandler.kt index 3a40fd99..429a2afe 100644 --- a/errormessage/src/main/kotlin/motif/errormessage/DuplicatedDependenciesMethodHandler.kt +++ b/errormessage/src/main/kotlin/motif/errormessage/DuplicatedDependenciesMethodHandler.kt @@ -18,7 +18,7 @@ package motif.errormessage import motif.models.DuplicatedDependenciesMethod internal class DuplicatedDependenciesMethodHandler( - private val error: DuplicatedDependenciesMethod + private val error: DuplicatedDependenciesMethod, ) : ErrorHandler { override val name = "DUPLICATED DEPENDENCIES METHOD" @@ -32,6 +32,8 @@ internal class DuplicatedDependenciesMethodHandler( """ Suggestions: * Remove the redundant methods - """.trimIndent()) + """ + .trimIndent(), + ) } } diff --git a/errormessage/src/main/kotlin/motif/errormessage/ErrorHandler.kt b/errormessage/src/main/kotlin/motif/errormessage/ErrorHandler.kt index 7e005f11..c5351e67 100644 --- a/errormessage/src/main/kotlin/motif/errormessage/ErrorHandler.kt +++ b/errormessage/src/main/kotlin/motif/errormessage/ErrorHandler.kt @@ -56,44 +56,43 @@ internal interface ErrorHandler { companion object { - fun get(error: MotifError): ErrorHandler { - return when (error) { - is ParsingError -> - when (error) { - is ScopeMustBeAnInterface -> ScopeMustBeAnInterfaceHandler(error) - is VoidScopeMethod -> VoidScopeMethodHandler(error) - is AccessMethodParameters -> AccessMethodParametersHandler(error) - is ObjectsFieldFound -> ObjectsFieldFoundHandler(error) - is ObjectsConstructorFound -> ObjectsConstructorFoundHandler(error) - is VoidFactoryMethod -> VoidFactoryMethodHandler(error) - is NullableFactoryMethod -> NullableFactoryMethodHandler(error) - is NullableParameter -> NullableParameterHandler(error) - is NullableDynamicDependency -> NullableDynamicDependencyHandler(error) - is InvalidFactoryMethod -> InvalidFactoryMethodHandler(error) - is UnspreadableType -> UnspreadableTypeHandler(error) - is NoSuitableConstructor -> NoSuitableConstructorHandler(error) - is InjectAnnotationRequired -> InjectAnnotationRequiredHandler(error) - is NotAssignableBindsMethod -> NotAssignableBindsMethodHandler(error) - is VoidDependenciesMethod -> VoidDependenciesMethodHandler(error) - is DependencyMethodWithParameters -> DependencyMethodWithParametersHandler(error) - is NullableSpreadMethod -> NullableSpreadMethodHandler(error) - is InvalidQualifier -> InvalidQualifierHandler(error) - is DuplicatedChildParameterSource -> DuplicatedChildParameterSourceHandler(error) - is DuplicatedDependenciesMethod -> DuplicatedDependenciesMethodHandler(error) - is ScopeExtendsScope -> ScopeExtendsScopeMethodHandler(error) - is CannotResolveType -> CannotResolveTypeHandler(error) - } - is ProcessingError -> - when (error) { - is ScopeCycleError -> ScopeCycleHandler(error) - is UnsatisfiedDependencyError -> UnsatisfiedDependencyHandler(error) - is DependencyCycleError -> DependencyCycleHandler(error) - is UnexposedSourceError -> UnexposedSourceHandler(error) - is AlreadySatisfiedError -> AlreadySatisfiedHandler(error) - } - else -> throw IllegalStateException("Unknown error type: $${this::class.java.name}") - } - } + fun get(error: MotifError): ErrorHandler = + when (error) { + is ParsingError -> + when (error) { + is ScopeMustBeAnInterface -> ScopeMustBeAnInterfaceHandler(error) + is VoidScopeMethod -> VoidScopeMethodHandler(error) + is AccessMethodParameters -> AccessMethodParametersHandler(error) + is ObjectsFieldFound -> ObjectsFieldFoundHandler(error) + is ObjectsConstructorFound -> ObjectsConstructorFoundHandler(error) + is VoidFactoryMethod -> VoidFactoryMethodHandler(error) + is NullableFactoryMethod -> NullableFactoryMethodHandler(error) + is NullableParameter -> NullableParameterHandler(error) + is NullableDynamicDependency -> NullableDynamicDependencyHandler(error) + is InvalidFactoryMethod -> InvalidFactoryMethodHandler(error) + is UnspreadableType -> UnspreadableTypeHandler(error) + is NoSuitableConstructor -> NoSuitableConstructorHandler(error) + is InjectAnnotationRequired -> InjectAnnotationRequiredHandler(error) + is NotAssignableBindsMethod -> NotAssignableBindsMethodHandler(error) + is VoidDependenciesMethod -> VoidDependenciesMethodHandler(error) + is DependencyMethodWithParameters -> DependencyMethodWithParametersHandler(error) + is NullableSpreadMethod -> NullableSpreadMethodHandler(error) + is InvalidQualifier -> InvalidQualifierHandler(error) + is DuplicatedChildParameterSource -> DuplicatedChildParameterSourceHandler(error) + is DuplicatedDependenciesMethod -> DuplicatedDependenciesMethodHandler(error) + is ScopeExtendsScope -> ScopeExtendsScopeMethodHandler(error) + is CannotResolveType -> CannotResolveTypeHandler(error) + } + is ProcessingError -> + when (error) { + is ScopeCycleError -> ScopeCycleHandler(error) + is UnsatisfiedDependencyError -> UnsatisfiedDependencyHandler(error) + is DependencyCycleError -> DependencyCycleHandler(error) + is UnexposedSourceError -> UnexposedSourceHandler(error) + is AlreadySatisfiedError -> AlreadySatisfiedHandler(error) + } + else -> throw IllegalStateException("Unknown error type: $${this::class.java.name}") + } } } diff --git a/errormessage/src/main/kotlin/motif/errormessage/ErrorMessage.kt b/errormessage/src/main/kotlin/motif/errormessage/ErrorMessage.kt index e2c6883d..1b265bbb 100644 --- a/errormessage/src/main/kotlin/motif/errormessage/ErrorMessage.kt +++ b/errormessage/src/main/kotlin/motif/errormessage/ErrorMessage.kt @@ -30,16 +30,17 @@ class ErrorMessage(val name: String, val text: String) { ==================================== - """.trimIndent() + """ + .trimIndent() - val footer = """ + val footer = + """ ==================================== - """.trimIndent() + """ + .trimIndent() - fun toString(graph: ResolvedGraph): String { - return toString(graph.errors) - } + fun toString(graph: ResolvedGraph): String = toString(graph.errors) fun toString(errors: List): String { val content: String = diff --git a/errormessage/src/main/kotlin/motif/errormessage/InjectAnnotationRequiredHandler.kt b/errormessage/src/main/kotlin/motif/errormessage/InjectAnnotationRequiredHandler.kt index b074ad1f..1ef1d559 100644 --- a/errormessage/src/main/kotlin/motif/errormessage/InjectAnnotationRequiredHandler.kt +++ b/errormessage/src/main/kotlin/motif/errormessage/InjectAnnotationRequiredHandler.kt @@ -36,6 +36,8 @@ internal class InjectAnnotationRequiredHandler(private val error: InjectAnnotati Suggestions: * Annotation the desired constructor with @Inject. * Update the type to have only one constructor. - """.trimIndent()) + """ + .trimIndent(), + ) } } diff --git a/errormessage/src/main/kotlin/motif/errormessage/InvalidFactoryMethodHandler.kt b/errormessage/src/main/kotlin/motif/errormessage/InvalidFactoryMethodHandler.kt index bc67f2e9..6a2b2c84 100644 --- a/errormessage/src/main/kotlin/motif/errormessage/InvalidFactoryMethodHandler.kt +++ b/errormessage/src/main/kotlin/motif/errormessage/InvalidFactoryMethodHandler.kt @@ -27,6 +27,8 @@ internal class InvalidFactoryMethodHandler(private val error: InvalidFactoryMeth Factory method is invalid: ${error.objects.qualifiedName}.${error.method.name} - """.trimIndent()) + """ + .trimIndent(), + ) } } diff --git a/errormessage/src/main/kotlin/motif/errormessage/InvalidQualifierHandler.kt b/errormessage/src/main/kotlin/motif/errormessage/InvalidQualifierHandler.kt index 8f9e08ea..e42fd298 100644 --- a/errormessage/src/main/kotlin/motif/errormessage/InvalidQualifierHandler.kt +++ b/errormessage/src/main/kotlin/motif/errormessage/InvalidQualifierHandler.kt @@ -27,6 +27,8 @@ internal class InvalidQualifierHandler(private val error: InvalidQualifier) : Er Qualifier must define either no members or a single value member of type String: ${error.annotation.className} - """.trimIndent()) + """ + .trimIndent(), + ) } } diff --git a/errormessage/src/main/kotlin/motif/errormessage/NoSuitableConstructorHandler.kt b/errormessage/src/main/kotlin/motif/errormessage/NoSuitableConstructorHandler.kt index b9f13712..4f9c0229 100644 --- a/errormessage/src/main/kotlin/motif/errormessage/NoSuitableConstructorHandler.kt +++ b/errormessage/src/main/kotlin/motif/errormessage/NoSuitableConstructorHandler.kt @@ -32,6 +32,8 @@ internal class NoSuitableConstructorHandler(private val error: NoSuitableConstru [Factory Method] ${error.objects.qualifiedName}.${error.method.name} - """.trimIndent()) + """ + .trimIndent(), + ) } } diff --git a/errormessage/src/main/kotlin/motif/errormessage/NodeHandler.kt b/errormessage/src/main/kotlin/motif/errormessage/NodeHandler.kt index 7b6eed5e..56bd8ceb 100644 --- a/errormessage/src/main/kotlin/motif/errormessage/NodeHandler.kt +++ b/errormessage/src/main/kotlin/motif/errormessage/NodeHandler.kt @@ -25,44 +25,51 @@ import motif.models.SpreadSource object NodeHandler { - fun handle(node: Node): String { - return when (node) { - is ScopeSource -> { - """[SCOPE] - | TYPE: ${node.scope.qualifiedName}""".trimMargin() - } - is FactoryMethodSource -> { - """[FACTORY METHOD RETURN TYPE] + fun handle(node: Node): String = + when (node) { + is ScopeSource -> { + """[SCOPE] + | TYPE: ${node.scope.qualifiedName} + """ + .trimMargin() + } + is FactoryMethodSource -> { + """[FACTORY METHOD RETURN TYPE] | TYPE: ${node.factoryMethod.returnType.qualifiedName} - | METHOD: ${node.factoryMethod.qualifiedName}""".trimMargin() - } - is SpreadSource -> { - """[SPREAD METHOD] + | METHOD: ${node.factoryMethod.qualifiedName} + """ + .trimMargin() + } + is SpreadSource -> { + """[SPREAD METHOD] | TYPE: ${node.spreadMethod.returnType.qualifiedName} | METHOD: ${node.spreadMethod.spread.qualifiedName}.${node.spreadMethod.method.name} | FACTORY METHOD: ${node.spreadMethod.spread.factoryMethod.qualifiedName} - """.trimMargin() - } - is ChildParameterSource -> { - """[CHILD METHOD PARAMETER] + """ + .trimMargin() + } + is ChildParameterSource -> { + """[CHILD METHOD PARAMETER] | TYPE: ${node.parameter.type.qualifiedName} | METHOD: ${node.parameter.method.qualifiedName} | PARAMETER: ${node.parameter.parameter.name} - """.trimMargin() - } - is FactoryMethodSink -> { - """[FACTORY METHOD PARAMETER] + """ + .trimMargin() + } + is FactoryMethodSink -> { + """[FACTORY METHOD PARAMETER] | TYPE: ${node.parameter.type.qualifiedName} | METHOD: ${node.parameter.factoryMethod.qualifiedName} | PARAMETER: ${node.parameter.parameter.name} - """.trimMargin() - } - is AccessMethodSink -> { - """[ACCESS METHOD] + """ + .trimMargin() + } + is AccessMethodSink -> { + """[ACCESS METHOD] | TYPE: ${node.accessMethod.returnType.qualifiedName} | METHOD: ${node.accessMethod.qualifiedName} - """.trimMargin() + """ + .trimMargin() + } } - } - } } diff --git a/errormessage/src/main/kotlin/motif/errormessage/NotAssignableBindsMethodHandler.kt b/errormessage/src/main/kotlin/motif/errormessage/NotAssignableBindsMethodHandler.kt index 5b98fa37..f64881ef 100644 --- a/errormessage/src/main/kotlin/motif/errormessage/NotAssignableBindsMethodHandler.kt +++ b/errormessage/src/main/kotlin/motif/errormessage/NotAssignableBindsMethodHandler.kt @@ -35,6 +35,8 @@ internal class NotAssignableBindsMethodHandler(private val error: NotAssignableB [Parameter Type] ${error.parameterType.qualifiedName} - """.trimIndent()) + """ + .trimIndent(), + ) } } diff --git a/errormessage/src/main/kotlin/motif/errormessage/NullableDynamicDependencyHandler.kt b/errormessage/src/main/kotlin/motif/errormessage/NullableDynamicDependencyHandler.kt index 8f74fb51..12612c63 100644 --- a/errormessage/src/main/kotlin/motif/errormessage/NullableDynamicDependencyHandler.kt +++ b/errormessage/src/main/kotlin/motif/errormessage/NullableDynamicDependencyHandler.kt @@ -35,6 +35,8 @@ internal class NullableDynamicDependencyHandler(private val error: NullableDynam Suggestions: * Consider using Optional<...> instead. - """.trimIndent()) + """ + .trimIndent(), + ) } } diff --git a/errormessage/src/main/kotlin/motif/errormessage/NullableFactoryMethodHandler.kt b/errormessage/src/main/kotlin/motif/errormessage/NullableFactoryMethodHandler.kt index a70cfe84..da0cf4a5 100644 --- a/errormessage/src/main/kotlin/motif/errormessage/NullableFactoryMethodHandler.kt +++ b/errormessage/src/main/kotlin/motif/errormessage/NullableFactoryMethodHandler.kt @@ -31,6 +31,8 @@ internal class NullableFactoryMethodHandler(private val error: NullableFactoryMe Suggestions: * Consider using Optional<...> instead. - """.trimIndent()) + """ + .trimIndent(), + ) } } diff --git a/errormessage/src/main/kotlin/motif/errormessage/NullableParameterHandler.kt b/errormessage/src/main/kotlin/motif/errormessage/NullableParameterHandler.kt index 119c00f7..4a9aae52 100644 --- a/errormessage/src/main/kotlin/motif/errormessage/NullableParameterHandler.kt +++ b/errormessage/src/main/kotlin/motif/errormessage/NullableParameterHandler.kt @@ -34,6 +34,8 @@ internal class NullableParameterHandler(private val error: NullableParameter) : Suggestions: * Consider using Optional<...> instead. - """.trimIndent()) + """ + .trimIndent(), + ) } } diff --git a/errormessage/src/main/kotlin/motif/errormessage/NullableSpreadMethodHandler.kt b/errormessage/src/main/kotlin/motif/errormessage/NullableSpreadMethodHandler.kt index 57c8a58d..f037d2dd 100644 --- a/errormessage/src/main/kotlin/motif/errormessage/NullableSpreadMethodHandler.kt +++ b/errormessage/src/main/kotlin/motif/errormessage/NullableSpreadMethodHandler.kt @@ -34,6 +34,8 @@ internal class NullableSpreadMethodHandler(private val error: NullableSpreadMeth Suggestions: * Use Optional<...> instead. - """.trimIndent()) + """ + .trimIndent(), + ) } } diff --git a/errormessage/src/main/kotlin/motif/errormessage/ObjectsConstructorFoundHandler.kt b/errormessage/src/main/kotlin/motif/errormessage/ObjectsConstructorFoundHandler.kt index e6739632..ace6d98d 100644 --- a/errormessage/src/main/kotlin/motif/errormessage/ObjectsConstructorFoundHandler.kt +++ b/errormessage/src/main/kotlin/motif/errormessage/ObjectsConstructorFoundHandler.kt @@ -28,6 +28,8 @@ internal class ObjectsConstructorFoundHandler(private val error: ObjectsConstruc Objects class may not define constructors: ${error.objectClass.qualifiedName} - """.trimIndent()) + """ + .trimIndent(), + ) } } diff --git a/errormessage/src/main/kotlin/motif/errormessage/ObjectsFieldFoundHandler.kt b/errormessage/src/main/kotlin/motif/errormessage/ObjectsFieldFoundHandler.kt index 18a08668..9f71376e 100644 --- a/errormessage/src/main/kotlin/motif/errormessage/ObjectsFieldFoundHandler.kt +++ b/errormessage/src/main/kotlin/motif/errormessage/ObjectsFieldFoundHandler.kt @@ -27,6 +27,8 @@ internal class ObjectsFieldFoundHandler(private val error: ObjectsFieldFound) : Objects class may not have fields: ${error.objectClass.qualifiedName} - """.trimIndent()) + """ + .trimIndent(), + ) } } diff --git a/errormessage/src/main/kotlin/motif/errormessage/ScopeExtendsScopeMethodHandler.kt b/errormessage/src/main/kotlin/motif/errormessage/ScopeExtendsScopeMethodHandler.kt index 2e8aa513..50e08958 100644 --- a/errormessage/src/main/kotlin/motif/errormessage/ScopeExtendsScopeMethodHandler.kt +++ b/errormessage/src/main/kotlin/motif/errormessage/ScopeExtendsScopeMethodHandler.kt @@ -27,6 +27,8 @@ class ScopeExtendsScopeMethodHandler(private val error: ScopeExtendsScope) : Err Scope can't extend other Scopes: ${error.scope.qualifiedName} - """.trimIndent()) + """ + .trimIndent(), + ) } } diff --git a/errormessage/src/main/kotlin/motif/errormessage/ScopeMustBeAnInterfaceHandler.kt b/errormessage/src/main/kotlin/motif/errormessage/ScopeMustBeAnInterfaceHandler.kt index 3cb11f72..eda45433 100644 --- a/errormessage/src/main/kotlin/motif/errormessage/ScopeMustBeAnInterfaceHandler.kt +++ b/errormessage/src/main/kotlin/motif/errormessage/ScopeMustBeAnInterfaceHandler.kt @@ -28,6 +28,8 @@ internal class ScopeMustBeAnInterfaceHandler(private val error: ScopeMustBeAnInt Scope must be an interface: ${error.scopeClass.qualifiedName} - """.trimIndent()) + """ + .trimIndent(), + ) } } diff --git a/errormessage/src/main/kotlin/motif/errormessage/UnexposedSourceHandler.kt b/errormessage/src/main/kotlin/motif/errormessage/UnexposedSourceHandler.kt index 2bfb8729..d0a5dd0f 100644 --- a/errormessage/src/main/kotlin/motif/errormessage/UnexposedSourceHandler.kt +++ b/errormessage/src/main/kotlin/motif/errormessage/UnexposedSourceHandler.kt @@ -34,6 +34,8 @@ internal class UnexposedSourceHandler(private val error: UnexposedSourceError) : """Suggestions: | * Annotate the source with @Expose. | * Resolve the descendant dependency elsewhere. - """.trimMargin()) + """ + .trimMargin(), + ) } } diff --git a/errormessage/src/main/kotlin/motif/errormessage/UnspreadableTypeHandler.kt b/errormessage/src/main/kotlin/motif/errormessage/UnspreadableTypeHandler.kt index b59ba6dc..86e8fa6c 100644 --- a/errormessage/src/main/kotlin/motif/errormessage/UnspreadableTypeHandler.kt +++ b/errormessage/src/main/kotlin/motif/errormessage/UnspreadableTypeHandler.kt @@ -31,6 +31,8 @@ internal class UnspreadableTypeHandler(private val error: UnspreadableType) : Er [Factory Method] ${error.objects.qualifiedName}.${error.method.name} - """.trimIndent()) + """ + .trimIndent(), + ) } } diff --git a/errormessage/src/main/kotlin/motif/errormessage/VoidDependenciesMethodHandler.kt b/errormessage/src/main/kotlin/motif/errormessage/VoidDependenciesMethodHandler.kt index 66468390..ebed9197 100644 --- a/errormessage/src/main/kotlin/motif/errormessage/VoidDependenciesMethodHandler.kt +++ b/errormessage/src/main/kotlin/motif/errormessage/VoidDependenciesMethodHandler.kt @@ -28,6 +28,8 @@ internal class VoidDependenciesMethodHandler(private val error: VoidDependencies Methods on dependencies interfaces must be non-void: void ${error.dependenciesClass.qualifiedName}.${error.method.name} - """.trimIndent()) + """ + .trimIndent(), + ) } } diff --git a/errormessage/src/main/kotlin/motif/errormessage/VoidFactoryMethodHandler.kt b/errormessage/src/main/kotlin/motif/errormessage/VoidFactoryMethodHandler.kt index 28b9b9e5..8d41cc1e 100644 --- a/errormessage/src/main/kotlin/motif/errormessage/VoidFactoryMethodHandler.kt +++ b/errormessage/src/main/kotlin/motif/errormessage/VoidFactoryMethodHandler.kt @@ -27,6 +27,8 @@ internal class VoidFactoryMethodHandler(private val error: VoidFactoryMethod) : Factory methods must be non-void: void ${error.objects.qualifiedName}.${error.method.name} - """.trimIndent()) + """ + .trimIndent(), + ) } } diff --git a/errormessage/src/main/kotlin/motif/errormessage/VoidScopeMethodHandler.kt b/errormessage/src/main/kotlin/motif/errormessage/VoidScopeMethodHandler.kt index 72511dc6..7ddc7672 100644 --- a/errormessage/src/main/kotlin/motif/errormessage/VoidScopeMethodHandler.kt +++ b/errormessage/src/main/kotlin/motif/errormessage/VoidScopeMethodHandler.kt @@ -27,6 +27,8 @@ internal class VoidScopeMethodHandler(private val error: VoidScopeMethod) : Erro Scope methods must be non-void: ${error.scope.qualifiedName}.${error.method.name} - """.trimIndent()) + """ + .trimIndent(), + ) } } diff --git a/intellij/ast/src/main/kotlin/motif/ast/intellij/IntelliJAnnotation.kt b/intellij/ast/src/main/kotlin/motif/ast/intellij/IntelliJAnnotation.kt index ae6ab7b8..03c95c5c 100644 --- a/intellij/ast/src/main/kotlin/motif/ast/intellij/IntelliJAnnotation.kt +++ b/intellij/ast/src/main/kotlin/motif/ast/intellij/IntelliJAnnotation.kt @@ -59,9 +59,8 @@ class IntelliJAnnotation(private val project: Project, private val psiAnnotation annotationClass.methods.map { IntelliJMethod(project, it, PsiSubstitutor.EMPTY) } } - override fun matchesClass(annotationClass: KClass): Boolean { - return psiAnnotation.qualifiedName == annotationClass.java.name - } + override fun matchesClass(annotationClass: KClass): Boolean = + psiAnnotation.qualifiedName == annotationClass.java.name override fun equals(other: Any?): Boolean { if (this === other) return true @@ -70,9 +69,7 @@ class IntelliJAnnotation(private val project: Project, private val psiAnnotation return key == other.key } - override fun hashCode(): Int { - return key.hashCode() - } + override fun hashCode(): Int = key.hashCode() override fun toString(): String { val value = stringValue?.let { "(\"$it\")" } ?: "" @@ -84,7 +81,7 @@ class IntelliJAnnotation(private val project: Project, private val psiAnnotation private fun getStringConstantValue( project: Project, annotation: PsiAnnotation, - attributeName: String + attributeName: String, ): String? { val value = annotation.findAttributeValue(attributeName) ?: return null @@ -101,8 +98,7 @@ class IntelliJAnnotation(private val project: Project, private val psiAnnotation val constant = JavaPsiFacade.getInstance(project) .constantEvaluationHelper - .computeConstantExpression(referenceTarget.initializer) - ?: return null + .computeConstantExpression(referenceTarget.initializer) ?: return null return constant as? String } diff --git a/intellij/ast/src/main/kotlin/motif/ast/intellij/IntelliJClass.kt b/intellij/ast/src/main/kotlin/motif/ast/intellij/IntelliJClass.kt index 86b628ea..7ce40e87 100644 --- a/intellij/ast/src/main/kotlin/motif/ast/intellij/IntelliJClass.kt +++ b/intellij/ast/src/main/kotlin/motif/ast/intellij/IntelliJClass.kt @@ -35,7 +35,7 @@ import motif.ast.IrType class IntelliJClass( private val project: Project, private val psiClassType: PsiClassType, - val psiClass: PsiClass + val psiClass: PsiClass, ) : IrUtil, IrClass { private val jvmPsiConversionHelper = @@ -48,9 +48,10 @@ class IntelliJClass( } override val typeArguments: List by lazy { - psiClassType.typeArguments().map { jvmPsiConversionHelper.convertType(it) }.map { - IntelliJType(project, it) - } + psiClassType + .typeArguments() + .map { jvmPsiConversionHelper.convertType(it) } + .map { IntelliJType(project, it) } } override val kind: IrClass.Kind by lazy { @@ -81,9 +82,9 @@ class IntelliJClass( } override val fields: List by lazy { - psiClass.allFields.filter { it.containingClass?.qualifiedName != "java.lang.Object" }.map { - IntelliJField(project, it) - } + psiClass.allFields + .filter { it.containingClass?.qualifiedName != "java.lang.Object" } + .map { IntelliJField(project, it) } } override val constructors: List by lazy { diff --git a/intellij/ast/src/main/kotlin/motif/ast/intellij/IntelliJMethod.kt b/intellij/ast/src/main/kotlin/motif/ast/intellij/IntelliJMethod.kt index f387a907..163efa13 100644 --- a/intellij/ast/src/main/kotlin/motif/ast/intellij/IntelliJMethod.kt +++ b/intellij/ast/src/main/kotlin/motif/ast/intellij/IntelliJMethod.kt @@ -27,7 +27,7 @@ import motif.ast.IrType class IntelliJMethod( private val project: Project, val psiMethod: PsiMethod, - val substitutor: PsiSubstitutor + val substitutor: PsiSubstitutor, ) : IrUtil, IrMethod { override val parameters: List by lazy { diff --git a/intellij/ast/src/main/kotlin/motif/ast/intellij/IntelliJMethodParameter.kt b/intellij/ast/src/main/kotlin/motif/ast/intellij/IntelliJMethodParameter.kt index 898d6fc2..5045b730 100644 --- a/intellij/ast/src/main/kotlin/motif/ast/intellij/IntelliJMethodParameter.kt +++ b/intellij/ast/src/main/kotlin/motif/ast/intellij/IntelliJMethodParameter.kt @@ -25,7 +25,7 @@ import motif.ast.IrType class IntelliJMethodParameter( private val project: Project, val psiParameter: PsiParameter, - val substitutor: PsiSubstitutor + val substitutor: PsiSubstitutor, ) : IrUtil, IrParameter { override val type: IrType by lazy { diff --git a/intellij/ast/src/main/kotlin/motif/ast/intellij/IntelliJType.kt b/intellij/ast/src/main/kotlin/motif/ast/intellij/IntelliJType.kt index 110f602a..1a738342 100644 --- a/intellij/ast/src/main/kotlin/motif/ast/intellij/IntelliJType.kt +++ b/intellij/ast/src/main/kotlin/motif/ast/intellij/IntelliJType.kt @@ -43,7 +43,7 @@ class IntelliJType(private val project: Project, val psiType: PsiType) : IrType PsiTypes.longType(), PsiTypes.charType(), PsiTypes.floatType(), - PsiTypes.doubleType() -> true + PsiTypes.doubleType(), -> true else -> false } } @@ -54,9 +54,8 @@ class IntelliJType(private val project: Project, val psiType: PsiType) : IrType return (psiType as? PsiClassType)?.let { IntelliJClass(project, it, psiClass) } } - override fun isAssignableTo(type: IrType): Boolean { - return TypeConversionUtil.isAssignable((type as IntelliJType).psiType, psiType, false) - } + override fun isAssignableTo(type: IrType): Boolean = + TypeConversionUtil.isAssignable((type as IntelliJType).psiType, psiType, false) override fun equals(other: Any?): Boolean { if (this === other) return true @@ -69,7 +68,5 @@ class IntelliJType(private val project: Project, val psiType: PsiType) : IrType return true } - override fun hashCode(): Int { - return psiType.hashCode() - } + override fun hashCode(): Int = psiType.hashCode() } diff --git a/intellij/ast/src/main/kotlin/motif/ast/intellij/IrUtil.kt b/intellij/ast/src/main/kotlin/motif/ast/intellij/IrUtil.kt index 2673ec94..2c8f9901 100644 --- a/intellij/ast/src/main/kotlin/motif/ast/intellij/IrUtil.kt +++ b/intellij/ast/src/main/kotlin/motif/ast/intellij/IrUtil.kt @@ -27,14 +27,11 @@ import motif.ast.IrModifier interface IrUtil { - fun PsiModifierListOwner.irModifiers(): Set { - return PsiModifier.MODIFIERS - .filter { hasModifierProperty(it) } - .map { IrModifier.valueOf(it.uppercase()) } - .toSet() - } + fun PsiModifierListOwner.irModifiers(): Set = + PsiModifier.MODIFIERS.filter { hasModifierProperty(it) } + .map { IrModifier.valueOf(it.uppercase()) } + .toSet() - fun PsiAnnotationOwner.irAnnotations(project: Project): List { - return annotations.map { IntelliJAnnotation(project, it) } - } + fun PsiAnnotationOwner.irAnnotations(project: Project): List = + annotations.map { IntelliJAnnotation(project, it) } } diff --git a/intellij/ast/src/test/kotlin/motif/ast/intellij/IntelliJAnnotationTest.kt b/intellij/ast/src/test/kotlin/motif/ast/intellij/IntelliJAnnotationTest.kt index 4609a646..7dc4c180 100644 --- a/intellij/ast/src/test/kotlin/motif/ast/intellij/IntelliJAnnotationTest.kt +++ b/intellij/ast/src/test/kotlin/motif/ast/intellij/IntelliJAnnotationTest.kt @@ -45,7 +45,8 @@ class IntelliJAnnotationTest : LightJavaCodeInsightFixtureTestCase() { package test; @interface A {} - """.trimIndent()) + """ + .trimIndent()) val fooAnnotation = getClassAnnotation( @@ -53,7 +54,8 @@ class IntelliJAnnotationTest : LightJavaCodeInsightFixtureTestCase() { package test; @A class Foo {} - """.trimIndent()) + """ + .trimIndent()) val barAnnotation = getClassAnnotation( @@ -61,7 +63,8 @@ class IntelliJAnnotationTest : LightJavaCodeInsightFixtureTestCase() { package test; @A class Bar {} - """.trimIndent()) + """ + .trimIndent()) assertThat(fooAnnotation).isEqualTo(barAnnotation) } @@ -72,14 +75,16 @@ class IntelliJAnnotationTest : LightJavaCodeInsightFixtureTestCase() { package test; @interface A {} - """.trimIndent()) + """ + .trimIndent()) createAnnotationClass( """ package test; @interface B {} - """.trimIndent()) + """ + .trimIndent()) val fooAnnotation = getClassAnnotation( @@ -87,7 +92,8 @@ class IntelliJAnnotationTest : LightJavaCodeInsightFixtureTestCase() { package test; @A class Foo {} - """.trimIndent()) + """ + .trimIndent()) val barAnnotation = getClassAnnotation( @@ -95,7 +101,8 @@ class IntelliJAnnotationTest : LightJavaCodeInsightFixtureTestCase() { package test; @B class Bar {} - """.trimIndent()) + """ + .trimIndent()) assertThat(fooAnnotation).isNotEqualTo(barAnnotation) } @@ -106,7 +113,8 @@ class IntelliJAnnotationTest : LightJavaCodeInsightFixtureTestCase() { package test; @interface A {} - """.trimIndent()) + """ + .trimIndent()) val fooAnnotation = getClassAnnotation( @@ -114,7 +122,8 @@ class IntelliJAnnotationTest : LightJavaCodeInsightFixtureTestCase() { package test; @test.A class Foo {} - """.trimIndent()) + """ + .trimIndent()) val barAnnotation = getClassAnnotation( @@ -122,7 +131,8 @@ class IntelliJAnnotationTest : LightJavaCodeInsightFixtureTestCase() { package test; @A class Bar {} - """.trimIndent()) + """ + .trimIndent()) assertThat(fooAnnotation).isEqualTo(barAnnotation) } @@ -135,7 +145,8 @@ class IntelliJAnnotationTest : LightJavaCodeInsightFixtureTestCase() { @javax.inject.Named("a") class Foo {} - """.trimIndent()) + """ + .trimIndent()) val barAnnotation = getClassAnnotation( @@ -144,7 +155,8 @@ class IntelliJAnnotationTest : LightJavaCodeInsightFixtureTestCase() { @javax.inject.Named("a") class Bar {} - """.trimIndent()) + """ + .trimIndent()) assertThat(fooAnnotation).isEqualTo(barAnnotation) } @@ -157,7 +169,8 @@ class IntelliJAnnotationTest : LightJavaCodeInsightFixtureTestCase() { @javax.inject.Named("a") class Foo {} - """.trimIndent()) + """ + .trimIndent()) val barAnnotation = getClassAnnotation( @@ -166,7 +179,8 @@ class IntelliJAnnotationTest : LightJavaCodeInsightFixtureTestCase() { @javax.inject.Named("b") class Bar {} - """.trimIndent()) + """ + .trimIndent()) assertThat(fooAnnotation).isNotEqualTo(barAnnotation) } @@ -181,7 +195,8 @@ class IntelliJAnnotationTest : LightJavaCodeInsightFixtureTestCase() { class Foo { static final String S = "a"; } - """.trimIndent()) + """ + .trimIndent()) val barAnnotation = getClassAnnotation( @@ -192,7 +207,8 @@ class IntelliJAnnotationTest : LightJavaCodeInsightFixtureTestCase() { class Bar { static final String S = "a"; } - """.trimIndent()) + """ + .trimIndent()) assertThat(fooAnnotation).isEqualTo(barAnnotation) } @@ -207,7 +223,8 @@ class IntelliJAnnotationTest : LightJavaCodeInsightFixtureTestCase() { class Foo { static final String S = "a"; } - """.trimIndent()) + """ + .trimIndent()) val barAnnotation = getClassAnnotation( @@ -218,7 +235,8 @@ class IntelliJAnnotationTest : LightJavaCodeInsightFixtureTestCase() { class Bar { static final String S = "b"; } - """.trimIndent()) + """ + .trimIndent()) assertThat(fooAnnotation).isNotEqualTo(barAnnotation) } @@ -231,7 +249,8 @@ class IntelliJAnnotationTest : LightJavaCodeInsightFixtureTestCase() { @javax.inject.Named("a") class Foo {} - """.trimIndent()) + """ + .trimIndent()) val barAnnotation = getClassAnnotation( @@ -242,7 +261,8 @@ class IntelliJAnnotationTest : LightJavaCodeInsightFixtureTestCase() { class Bar { static final String S = "a"; } - """.trimIndent()) + """ + .trimIndent()) assertThat(fooAnnotation).isEqualTo(barAnnotation) } @@ -255,7 +275,8 @@ class IntelliJAnnotationTest : LightJavaCodeInsightFixtureTestCase() { @javax.inject.Named("a") class Foo {} - """.trimIndent()) + """ + .trimIndent()) val barAnnotation = getClassAnnotation( @@ -266,7 +287,8 @@ class IntelliJAnnotationTest : LightJavaCodeInsightFixtureTestCase() { class Bar { static final String S = "b"; } - """.trimIndent()) + """ + .trimIndent()) assertThat(fooAnnotation).isNotEqualTo(barAnnotation) } @@ -279,7 +301,8 @@ class IntelliJAnnotationTest : LightJavaCodeInsightFixtureTestCase() { @javax.inject.Named("a") class Foo {} - """.trimIndent()) + """ + .trimIndent()) assertThat(fooAnnotation.className).isEqualTo("javax.inject.Named") } diff --git a/intellij/ast/src/test/kotlin/motif/ast/intellij/IntelliJClassTest.kt b/intellij/ast/src/test/kotlin/motif/ast/intellij/IntelliJClassTest.kt index cdf467b9..e0020be0 100644 --- a/intellij/ast/src/test/kotlin/motif/ast/intellij/IntelliJClassTest.kt +++ b/intellij/ast/src/test/kotlin/motif/ast/intellij/IntelliJClassTest.kt @@ -36,9 +36,7 @@ class IntelliJClassTest : LightJavaCodeInsightFixtureTestCase() { JavaAwareProjectJdkTableImpl.getInstanceEx().internalJdk } - override fun getTestDataPath(): String { - return "testData" - } + override fun getTestDataPath(): String = "testData" fun testInheritedMethod() { val fooClass = @@ -51,7 +49,9 @@ class IntelliJClassTest : LightJavaCodeInsightFixtureTestCase() { interface Bar { String a(); } - """.trimIndent()) + """ + .trimIndent(), + ) assertThat(fooClass.methods).hasSize(1) } @@ -67,7 +67,9 @@ class IntelliJClassTest : LightJavaCodeInsightFixtureTestCase() { interface Bar { T a(T t); } - """.trimIndent()) + """ + .trimIndent(), + ) assertThat(fooClass.methods).hasSize(1) assertThat(fooClass.methods[0].returnType.qualifiedName).isEqualTo("java.lang.String") @@ -85,7 +87,9 @@ class IntelliJClassTest : LightJavaCodeInsightFixtureTestCase() { class Bar { static String a() {} } - """.trimIndent()) + """ + .trimIndent(), + ) assertThat(fooClass.methods).hasSize(1) } @@ -101,7 +105,9 @@ class IntelliJClassTest : LightJavaCodeInsightFixtureTestCase() { class Bar { private static String a() {} } - """.trimIndent()) + """ + .trimIndent(), + ) assertThat(fooClass.methods).isEmpty() } @@ -117,7 +123,9 @@ class IntelliJClassTest : LightJavaCodeInsightFixtureTestCase() { class Bar { String a; } - """.trimIndent()) + """ + .trimIndent(), + ) assertThat(fooClass.fields).hasSize(1) } @@ -133,7 +141,9 @@ class IntelliJClassTest : LightJavaCodeInsightFixtureTestCase() { class Bar { T t; } - """.trimIndent()) + """ + .trimIndent(), + ) assertThat(fooClass.fields).hasSize(1) @@ -150,7 +160,9 @@ class IntelliJClassTest : LightJavaCodeInsightFixtureTestCase() { package motif.intellij; class Foo extends motif.intellij.Bar {} - """.trimIndent()) + """ + .trimIndent(), + ) val barClass = createIntelliJClass( @@ -158,7 +170,9 @@ class IntelliJClassTest : LightJavaCodeInsightFixtureTestCase() { package motif.intellij; class Bar {} - """.trimIndent()) + """ + .trimIndent(), + ) assertThat(fooClass.type.isAssignableTo(barClass.type)).isTrue() } @@ -172,7 +186,9 @@ class IntelliJClassTest : LightJavaCodeInsightFixtureTestCase() { class Foo extends Bar {} class Bar {} - """.trimIndent()) + """ + .trimIndent(), + ) val stringBarType = createIntelliJType("motif.intellij.Bar") @@ -190,7 +206,9 @@ class IntelliJClassTest : LightJavaCodeInsightFixtureTestCase() { class Bar extends Baz {} class Baz {} - """.trimIndent()) + """ + .trimIndent(), + ) val stringBazType = createIntelliJType("motif.intellij.Baz") @@ -206,7 +224,9 @@ class IntelliJClassTest : LightJavaCodeInsightFixtureTestCase() { class Foo extends Bar {} class Bar {} - """.trimIndent()) + """ + .trimIndent(), + ) val superClass = fooClass.supertypes.single().resolveClass() as IntelliJClass assertThat(superClass.typeArguments.map { it.qualifiedName }) @@ -225,7 +245,9 @@ class IntelliJClassTest : LightJavaCodeInsightFixtureTestCase() { class Bar extends Baz {} class Baz {} - """.trimIndent()) + """ + .trimIndent(), + ) val barClass = fooClass.supertypes.single().resolveClass() as IntelliJClass val bazClass = barClass.supertypes.single().resolveClass() as IntelliJClass @@ -241,7 +263,9 @@ class IntelliJClassTest : LightJavaCodeInsightFixtureTestCase() { class Foo extends Bar {} class Bar {} - """.trimIndent()) + """ + .trimIndent(), + ) val superClass = fooClass.supertypes.single().resolveClass() as IntelliJClass assertThat(superClass.typeArguments).isEmpty() @@ -254,7 +278,9 @@ class IntelliJClassTest : LightJavaCodeInsightFixtureTestCase() { package test; class Foo {} - """.trimIndent()) + """ + .trimIndent(), + ) val objectClass = fooClass.supertypes.single().resolveClass()!! assertThat(objectClass.qualifiedName).isEqualTo("java.lang.Object") @@ -270,7 +296,9 @@ class IntelliJClassTest : LightJavaCodeInsightFixtureTestCase() { class Foo implements Bar {} interface Bar {} - """.trimIndent()) + """ + .trimIndent(), + ) val superTypes = fooClass.supertypes.map { it.qualifiedName } assertThat(superTypes).containsExactly("java.lang.Object", "test.Bar") @@ -288,7 +316,9 @@ class IntelliJClassTest : LightJavaCodeInsightFixtureTestCase() { interface Bar {} interface Baz {} - """.trimIndent()) + """ + .trimIndent(), + ) val superTypes = fooClass.supertypes.map { it.qualifiedName } assertThat(superTypes).containsExactly("java.lang.Object", "test.Bar", "test.Baz") diff --git a/intellij/ast/src/test/kotlin/motif/ast/intellij/IntelliJKotlinTest.kt b/intellij/ast/src/test/kotlin/motif/ast/intellij/IntelliJKotlinTest.kt index 18f37900..b8568cad 100644 --- a/intellij/ast/src/test/kotlin/motif/ast/intellij/IntelliJKotlinTest.kt +++ b/intellij/ast/src/test/kotlin/motif/ast/intellij/IntelliJKotlinTest.kt @@ -37,9 +37,7 @@ class IntelliJKotlinTest : LightJavaCodeInsightFixtureTestCase() { JavaAwareProjectJdkTableImpl.getInstanceEx().internalJdk } - override fun getTestDataPath(): String { - return "testData" - } + override fun getTestDataPath(): String = "testData" fun testImplicitNullabilityAnnotationType() { val fooPsiFile = @@ -50,8 +48,9 @@ class IntelliJKotlinTest : LightJavaCodeInsightFixtureTestCase() { internal fun a() {} } - """.trimIndent()) as - KtFile + """ + .trimIndent(), + ) as KtFile val fooPsiClass = fooPsiFile.declarations[0].toUElementOfType()!!.javaPsi val psiAnnotation = fooPsiClass.constructors[0].parameterList.parameters[0].annotations[0] diff --git a/intellij/src/main/kotlin/motif/intellij/GraphFactory.kt b/intellij/src/main/kotlin/motif/intellij/GraphFactory.kt index 198bf6b7..ccb94672 100644 --- a/intellij/src/main/kotlin/motif/intellij/GraphFactory.kt +++ b/intellij/src/main/kotlin/motif/intellij/GraphFactory.kt @@ -65,21 +65,16 @@ class GraphFactory(private val project: Project) { .map { type -> IntelliJClass(project, type, type.resolve()!!) } } - private fun getScopeClasses(psiFile: PsiJavaFile): Iterable { - return psiFile.classes.toList() - } + private fun getScopeClasses(psiFile: PsiJavaFile): Iterable = psiFile.classes.toList() - private fun getScopeClasses(psiFile: KtFile): Iterable { - return psiFile.declarations.filterIsInstance().map { - it.toUElement(UClass::class.java)!!.javaPsi - } - } + private fun getScopeClasses(psiFile: KtFile): Iterable = + psiFile.declarations.filterIsInstance().map { + it.toUElement(UClass::class.java)!!.javaPsi + } - private fun getClasses(psiClass: PsiClass): List { - return listOf(psiClass) + psiClass.innerClasses.flatMap(this::getClasses) - } + private fun getClasses(psiClass: PsiClass): List = + listOf(psiClass) + psiClass.innerClasses.flatMap(this::getClasses) - private fun isScopeClass(psiClass: PsiClass): Boolean { - return psiClass.annotations.find { it.qualifiedName == Scope::class.qualifiedName } != null - } + private fun isScopeClass(psiClass: PsiClass): Boolean = + psiClass.annotations.find { it.qualifiedName == Scope::class.qualifiedName } != null } diff --git a/intellij/src/main/kotlin/motif/intellij/GraphManager.kt b/intellij/src/main/kotlin/motif/intellij/GraphManager.kt index 9900e82e..a618500e 100644 --- a/intellij/src/main/kotlin/motif/intellij/GraphManager.kt +++ b/intellij/src/main/kotlin/motif/intellij/GraphManager.kt @@ -77,7 +77,8 @@ class GraphManager(private val project: Project) : ProjectComponent { setGraphState(state) } } - }) + }, + ) } fun addListener(listener: Listener) { @@ -105,8 +106,7 @@ class GraphInvalidator(private val project: Project, private val graph: Resolved private val psiElementFactory = PsiElementFactory.SERVICE.getInstance(project) private val relevantTypes: Set by lazy { - graph - .scopes + graph.scopes .flatMap { scope -> (listOfNotNull(scope.objects?.clazz) + scope.clazz + @@ -118,22 +118,19 @@ class GraphInvalidator(private val project: Project, private val graph: Resolved .toSet() } - fun shouldInvalidate(changedElement: PsiElement): Boolean { - return (sequenceOf(changedElement) + changedElement.parentsWithSelf) - .mapNotNull { it as? PsiClass } - .map { psiElementFactory.createType(it) } - .any { IntelliJType(project, it) in relevantTypes } - } + fun shouldInvalidate(changedElement: PsiElement): Boolean = + (sequenceOf(changedElement) + changedElement.parentsWithSelf) + .mapNotNull { it as? PsiClass } + .map { psiElementFactory.createType(it) } + .any { IntelliJType(project, it) in relevantTypes } - private fun spreadClasses(scope: Scope): List { - return scope.factoryMethods.mapNotNull { it.spread }.map { spread -> spread.clazz } - } + private fun spreadClasses(scope: Scope): List = + scope.factoryMethods.mapNotNull { it.spread }.map { spread -> spread.clazz } - private fun constructorClasses(scope: Scope): List { - return scope.factoryMethods.filterIsInstance().mapNotNull { - it.returnType.type.type.resolveClass() - } - } + private fun constructorClasses(scope: Scope): List = + scope.factoryMethods.filterIsInstance().mapNotNull { + it.returnType.type.type.resolveClass() + } private fun typeAndSupertypes(psiClass: PsiClass): Set { if (psiClass.qualifiedName == "java.lang.Object") { diff --git a/intellij/src/main/kotlin/motif/intellij/MotifService.kt b/intellij/src/main/kotlin/motif/intellij/MotifService.kt index cea7ec95..f62b9491 100644 --- a/intellij/src/main/kotlin/motif/intellij/MotifService.kt +++ b/intellij/src/main/kotlin/motif/intellij/MotifService.kt @@ -109,9 +109,11 @@ class MotifService(val project: Project) : Disposable { onGraphUpdated(updatedGraph) val eventName: String = - if (updatedGraph.errors.isNotEmpty()) - MotifAnalyticsActions.GRAPH_UPDATE_ERROR - else MotifAnalyticsActions.GRAPH_UPDATE_SUCCESS + if (updatedGraph.errors.isNotEmpty()) { + MotifAnalyticsActions.GRAPH_UPDATE_ERROR + } else { + MotifAnalyticsActions.GRAPH_UPDATE_SUCCESS + } project.getService(AnalyticsService::class.java).logEvent(eventName) } catch (t: Throwable) { val emptyGraph: ResolvedGraph = ResolvedGraph.create(emptyList()) @@ -126,7 +128,8 @@ class MotifService(val project: Project) : Disposable { } } } - }) + }, + ) } fun refreshGraph(action: () -> Unit) { @@ -244,9 +247,8 @@ class MotifService(val project: Project) : Disposable { return content } - private fun findContentByDescription(toolWindow: ToolWindow, description: String): Content? { - return toolWindow.contentManager.contents.firstOrNull { it.description == description } - } + private fun findContentByDescription(toolWindow: ToolWindow, description: String): Content? = + toolWindow.contentManager.contents.firstOrNull { it.description == description } interface Listener { diff --git a/intellij/src/main/kotlin/motif/intellij/PsiUtils.kt b/intellij/src/main/kotlin/motif/intellij/PsiUtils.kt index 1407551d..147741cc 100644 --- a/intellij/src/main/kotlin/motif/intellij/PsiUtils.kt +++ b/intellij/src/main/kotlin/motif/intellij/PsiUtils.kt @@ -23,18 +23,16 @@ import org.jetbrains.kotlin.asJava.toLightMethods import org.jetbrains.kotlin.psi.KtClass import org.jetbrains.kotlin.psi.KtFunction -internal fun PsiElement.toPsiClass(): PsiElement? { - return when (this) { - is PsiClass -> this - is KtClass -> toLightClass() - else -> this - } -} +internal fun PsiElement.toPsiClass(): PsiElement? = + when (this) { + is PsiClass -> this + is KtClass -> toLightClass() + else -> this + } -internal fun PsiElement.toPsiMethod(): PsiElement? { - return when (this) { - is PsiMethod -> this - is KtFunction -> toLightMethods().singleOrNull() - else -> this - } -} +internal fun PsiElement.toPsiMethod(): PsiElement? = + when (this) { + is PsiMethod -> this + is KtFunction -> toLightMethods().singleOrNull() + else -> this + } diff --git a/intellij/src/main/kotlin/motif/intellij/ScopeHierarchyUtils.kt b/intellij/src/main/kotlin/motif/intellij/ScopeHierarchyUtils.kt index d46a6170..3ff0e620 100644 --- a/intellij/src/main/kotlin/motif/intellij/ScopeHierarchyUtils.kt +++ b/intellij/src/main/kotlin/motif/intellij/ScopeHierarchyUtils.kt @@ -40,21 +40,17 @@ import motif.models.Source object ScopeHierarchyUtils { object ScopeComparator : Comparator { - override fun compare(o1: Scope, o2: Scope): Int { - return o1.simpleName.compareTo(o2.simpleName) - } + override fun compare(o1: Scope, o2: Scope): Int = o1.simpleName.compareTo(o2.simpleName) } object ScopeEdgeParentComparator : Comparator { - override fun compare(o1: ScopeEdge, o2: ScopeEdge): Int { - return o1.parent.simpleName.compareTo(o2.parent.simpleName) - } + override fun compare(o1: ScopeEdge, o2: ScopeEdge): Int = + o1.parent.simpleName.compareTo(o2.parent.simpleName) } object ScopeEdgeChildComparator : Comparator { - override fun compare(o1: ScopeEdge, o2: ScopeEdge): Int { - return o1.child.simpleName.compareTo(o2.child.simpleName) - } + override fun compare(o1: ScopeEdge, o2: ScopeEdge): Int = + o1.child.simpleName.compareTo(o2.child.simpleName) } object SourceComparator : Comparator { @@ -65,33 +61,25 @@ object ScopeHierarchyUtils { } object SinkComparator : Comparator { - override fun compare(o1: Sink, o2: Sink): Int { - return o1.type.simpleName.compareTo(o2.type.simpleName) - } + override fun compare(o1: Sink, o2: Sink): Int = o1.type.simpleName.compareTo(o2.type.simpleName) } object MethodComparator : Comparator { - override fun compare(o1: Dependencies.Method, o2: Dependencies.Method): Int { - return o1.method.name.compareTo(o2.method.name) - } + override fun compare(o1: Dependencies.Method, o2: Dependencies.Method): Int = + o1.method.name.compareTo(o2.method.name) } - fun buildRootElement(project: Project): PsiClass { - return JavaPsiFacade.getInstance(project) - .findClass(Object::class.java.name, GlobalSearchScope.allScope(project))!! - } + fun buildRootElement(project: Project): PsiClass = + JavaPsiFacade.getInstance(project) + .findClass(Object::class.java.name, GlobalSearchScope.allScope(project))!! - fun isRootElement(element: PsiElement?): Boolean { - return element is PsiClass && element.qualifiedName == Object::class.java.name - } + fun isRootElement(element: PsiElement?): Boolean = + element is PsiClass && element.qualifiedName == Object::class.java.name - fun isInitializedGraph(graph: ResolvedGraph): Boolean { - return graph.roots.isNotEmpty() - } + fun isInitializedGraph(graph: ResolvedGraph): Boolean = graph.roots.isNotEmpty() - fun isMotifScopeClass(element: PsiClass?): Boolean { - return element?.hasAnnotation(motif.Scope::class.java.name) ?: false - } + fun isMotifScopeClass(element: PsiClass?): Boolean = + element?.hasAnnotation(motif.Scope::class.java.name) ?: false fun isMotifChildScopeMethod(element: PsiElement?): Boolean { if (element is PsiMethod) { @@ -109,21 +97,23 @@ object ScopeHierarchyUtils { fun getParentScopes( project: Project, graph: ResolvedGraph, - element: PsiClass + element: PsiClass, ): Array? { val scopeType: PsiType = PsiElementFactory.SERVICE.getInstance(project).createType(element) val type: IrType = IntelliJType(project, scopeType) val scope: Scope? = graph.getScope(type) - return if (scope != null) Iterables.toArray(graph.getParentEdges(scope), ScopeEdge::class.java) - else null + return if (scope != null) { + Iterables.toArray(graph.getParentEdges(scope), ScopeEdge::class.java) + } else { + null + } } /* * Returns the list of sources for given scope to display in the UI */ - fun getVisibleSources(graph: ResolvedGraph, scope: Scope): List { - return graph.getSources(scope).filter { it !is ChildParameterSource && it !is ScopeSource } - } + fun getVisibleSources(graph: ResolvedGraph, scope: Scope): List = + graph.getSources(scope).filter { it !is ChildParameterSource && it !is ScopeSource } /* * Returns the number of usage for the given class. @@ -133,7 +123,7 @@ object ScopeHierarchyUtils { graph: ResolvedGraph, clazz: PsiClass, includeSources: Boolean = true, - includeSinks: Boolean = true + includeSinks: Boolean = true, ): Int { var count = 0 val elementType: PsiType = PsiElementFactory.SERVICE.getInstance(project).createType(clazz) @@ -147,30 +137,26 @@ object ScopeHierarchyUtils { return count } - fun getUsageString(count: Int): String { - return when (count) { - 0 -> "No usage" - 1 -> "1 usage" - else -> "$count usages" - } - } + fun getUsageString(count: Int): String = + when (count) { + 0 -> "No usage" + 1 -> "1 usage" + else -> "$count usages" + } - fun getObjectString(count: Int): String { - return when (count) { - 0 -> "No object" - 1 -> "1 object" - else -> "$count objects" - } - } + fun getObjectString(count: Int): String = + when (count) { + 0 -> "No object" + 1 -> "1 object" + else -> "$count objects" + } fun formatQualifiedName(qualifiedName: String): String { val index: Int = qualifiedName.lastIndexOf(".") return if (index > 0) qualifiedName.substring(0, index) else qualifiedName } - fun formatMultilineText(text: String): String { - return "" + text.replace("\n", "
    ") + "" - } + fun formatMultilineText(text: String): String = "" + text.replace("\n", "
    ") + "" /* * Returns all the paths, starting from root scopes, leading to the provided scope. @@ -187,7 +173,7 @@ object ScopeHierarchyUtils { scope: Scope, graph: ResolvedGraph, list: ArrayList, - all: ArrayList> + all: ArrayList>, ) { list.add(scope) val parentEdgesIterator: Iterator = graph.getParentEdges(scope).iterator() diff --git a/intellij/src/main/kotlin/motif/intellij/actions/MotifAncestorGraphAction.kt b/intellij/src/main/kotlin/motif/intellij/actions/MotifAncestorGraphAction.kt index ef770747..8860c355 100644 --- a/intellij/src/main/kotlin/motif/intellij/actions/MotifAncestorGraphAction.kt +++ b/intellij/src/main/kotlin/motif/intellij/actions/MotifAncestorGraphAction.kt @@ -74,7 +74,5 @@ class MotifAncestorGraphAction : AnAction(), MotifService.Listener { (getParentScopes(project, graph, element)?.isNotEmpty() == true)) } - private fun AnActionEvent.getPsiElement(): PsiElement? { - return getData(CommonDataKeys.PSI_ELEMENT) - } + private fun AnActionEvent.getPsiElement(): PsiElement? = getData(CommonDataKeys.PSI_ELEMENT) } diff --git a/intellij/src/main/kotlin/motif/intellij/actions/MotifUsageAction.kt b/intellij/src/main/kotlin/motif/intellij/actions/MotifUsageAction.kt index 63deed0a..530da06f 100644 --- a/intellij/src/main/kotlin/motif/intellij/actions/MotifUsageAction.kt +++ b/intellij/src/main/kotlin/motif/intellij/actions/MotifUsageAction.kt @@ -70,7 +70,5 @@ class MotifUsageAction : AnAction(), MotifService.Listener { getUsageCount(project, graph, element) > 0) } - private fun AnActionEvent.getPsiElement(): PsiElement? { - return getData(CommonDataKeys.PSI_ELEMENT) - } + private fun AnActionEvent.getPsiElement(): PsiElement? = getData(CommonDataKeys.PSI_ELEMENT) } diff --git a/intellij/src/main/kotlin/motif/intellij/hierarchy/ErrorHierarchyBrowser.kt b/intellij/src/main/kotlin/motif/intellij/hierarchy/ErrorHierarchyBrowser.kt index 04b8c238..ac1ac69d 100644 --- a/intellij/src/main/kotlin/motif/intellij/hierarchy/ErrorHierarchyBrowser.kt +++ b/intellij/src/main/kotlin/motif/intellij/hierarchy/ErrorHierarchyBrowser.kt @@ -48,7 +48,7 @@ class ErrorHierarchyBrowser( project: Project, initialGraph: ResolvedGraph, private val rootElement: PsiElement, - private val selectionListener: Listener? + private val selectionListener: Listener?, ) : HierarchyBrowserBase(project, rootElement), MotifService.Listener { private var graph: ResolvedGraph = initialGraph @@ -59,19 +59,14 @@ class ErrorHierarchyBrowser( DataKey.create(ErrorHierarchyBrowser::class.java.name) } - override fun isApplicableElement(element: PsiElement): Boolean { - return element is PsiClass - } + override fun isApplicableElement(element: PsiElement): Boolean = element is PsiClass - override fun getActionPlace(): String { - return ActionPlaces.METHOD_HIERARCHY_VIEW_TOOLBAR - } + override fun getActionPlace(): String = ActionPlaces.METHOD_HIERARCHY_VIEW_TOOLBAR override fun prependActions(actionGroup: DefaultActionGroup) {} - override fun getComparator(): Comparator> { - return JavaHierarchyUtil.getComparator(myProject) - } + override fun getComparator(): Comparator> = + JavaHierarchyUtil.getComparator(myProject) override fun getElementFromDescriptor(descriptor: HierarchyNodeDescriptor): PsiElement? { if (isRootElement(descriptor.psiElement)) { @@ -80,17 +75,11 @@ class ErrorHierarchyBrowser( return descriptor.psiElement } - override fun getPrevOccurenceActionNameImpl(): String { - return LABEL_GO_PREVIOUS_SCOPE - } + override fun getPrevOccurenceActionNameImpl(): String = LABEL_GO_PREVIOUS_SCOPE - override fun getNextOccurenceActionNameImpl(): String { - return LABEL_GO_NEXT_SCOPE - } + override fun getNextOccurenceActionNameImpl(): String = LABEL_GO_NEXT_SCOPE - override fun createLegendPanel(): JPanel? { - return null - } + override fun createLegendPanel(): JPanel? = null override fun createTrees(trees: MutableMap) { trees[ERROR_HIERARCHY_TYPE] = createTree(true) @@ -105,21 +94,25 @@ class ErrorHierarchyBrowser( val descriptor = node.userObject if (descriptor is ScopeHierarchyErrorDescriptor) { selectionListener?.onSelectedErrorChanged( - descriptor.element, descriptor.error, descriptor.errorMessage) + descriptor.element, + descriptor.error, + descriptor.errorMessage, + ) } } } } } - override fun getContentDisplayName(typeName: String, element: PsiElement): String? { - return MessageFormat.format( - typeName, ClassPresentationUtil.getNameForClass(element as PsiClass, false)) - } + override fun getContentDisplayName(typeName: String, element: PsiElement): String? = + MessageFormat.format( + typeName, + ClassPresentationUtil.getNameForClass(element as PsiClass, false), + ) override fun createHierarchyTreeStructure( typeName: String, - psiElement: PsiElement + psiElement: PsiElement, ): HierarchyTreeStructure? { if (psiElement == rootElement) { val descriptor: HierarchyNodeDescriptor = diff --git a/intellij/src/main/kotlin/motif/intellij/hierarchy/HierarchyBrowserBase.kt b/intellij/src/main/kotlin/motif/intellij/hierarchy/HierarchyBrowserBase.kt index 7c2a2f75..a403aa1c 100644 --- a/intellij/src/main/kotlin/motif/intellij/hierarchy/HierarchyBrowserBase.kt +++ b/intellij/src/main/kotlin/motif/intellij/hierarchy/HierarchyBrowserBase.kt @@ -48,9 +48,8 @@ abstract class HierarchyBrowserBase(val project: Project, private val rootElemen TreeSpeedSearch(tree, { path -> path.lastPathComponent.toString() }, true) TreeUtil.installActions(tree) object : AutoScrollToSourceHandler() { - override fun isAutoScrollMode(): Boolean { - return HierarchyBrowserManager.getSettings(myProject).IS_AUTOSCROLL_TO_SOURCE - } + override fun isAutoScrollMode(): Boolean = + HierarchyBrowserManager.getSettings(myProject).IS_AUTOSCROLL_TO_SOURCE override fun setAutoScrollMode(state: Boolean) { HierarchyBrowserManager.getSettings(myProject).IS_AUTOSCROLL_TO_SOURCE = state diff --git a/intellij/src/main/kotlin/motif/intellij/hierarchy/ScopeHierarchyBrowser.kt b/intellij/src/main/kotlin/motif/intellij/hierarchy/ScopeHierarchyBrowser.kt index 43df929f..58b1912e 100644 --- a/intellij/src/main/kotlin/motif/intellij/hierarchy/ScopeHierarchyBrowser.kt +++ b/intellij/src/main/kotlin/motif/intellij/hierarchy/ScopeHierarchyBrowser.kt @@ -59,7 +59,7 @@ class ScopeHierarchyBrowser( project: Project, initialGraph: ResolvedGraph, private val rootElement: PsiElement, - private val selectionListener: Listener? + private val selectionListener: Listener?, ) : HierarchyBrowserBase(project, rootElement), MotifService.Listener { companion object { @@ -85,21 +85,14 @@ class ScopeHierarchyBrowser( super.doRefresh(true) } - fun isUpdating(): Boolean { - return status == Status.INITIALIZING || status == Status.REFRESHING - } + fun isUpdating(): Boolean = status == Status.INITIALIZING || status == Status.REFRESHING - override fun isApplicableElement(element: PsiElement): Boolean { - return element is PsiClass - } + override fun isApplicableElement(element: PsiElement): Boolean = element is PsiClass - override fun getActionPlace(): String { - return ActionPlaces.METHOD_HIERARCHY_VIEW_TOOLBAR - } + override fun getActionPlace(): String = ActionPlaces.METHOD_HIERARCHY_VIEW_TOOLBAR - override fun getComparator(): Comparator> { - return JavaHierarchyUtil.getComparator(myProject) - } + override fun getComparator(): Comparator> = + JavaHierarchyUtil.getComparator(myProject) override fun getElementFromDescriptor(descriptor: HierarchyNodeDescriptor): PsiElement? { if (ScopeHierarchyUtils.isRootElement(descriptor.psiElement)) { @@ -108,21 +101,15 @@ class ScopeHierarchyBrowser( return descriptor.psiElement } - override fun getPrevOccurenceActionNameImpl(): String { - return LABEL_GO_PREVIOUS_SCOPE - } + override fun getPrevOccurenceActionNameImpl(): String = LABEL_GO_PREVIOUS_SCOPE - override fun createLegendPanel(): JPanel? { - return null - } + override fun createLegendPanel(): JPanel? = null override fun createTrees(trees: MutableMap) { trees[TYPE_HIERARCHY_TYPE] = createTree(true) } - override fun getNextOccurenceActionNameImpl(): String { - return LABEL_GO_NEXT_SCOPE - } + override fun getNextOccurenceActionNameImpl(): String = LABEL_GO_NEXT_SCOPE override fun getContentDisplayName(typeName: String, element: PsiElement): String? { if (element !is PsiClass) { @@ -144,12 +131,15 @@ class ScopeHierarchyBrowser( override fun createHierarchyTreeStructure( typeName: String, - psiElement: PsiElement + psiElement: PsiElement, ): HierarchyTreeStructure? { if (psiElement == rootElement) { // Display entire graph hierarchy return ScopeHierarchyTreeStructure( - myProject, graph, ScopeHierarchyRootDescriptor(myProject, graph, psiElement, status)) + myProject, + graph, + ScopeHierarchyRootDescriptor(myProject, graph, psiElement, status), + ) } else if (psiElement is PsiClass && isMotifScopeClass(psiElement)) { // Display the scope ancestors hierarchy val scopeType: PsiType = PsiElementFactory.SERVICE.getInstance(project).createType(psiElement) @@ -192,8 +182,11 @@ class ScopeHierarchyBrowser( project.getService(MotifService::class.java).refreshGraph() val action: String = - if (status == Status.INITIALIZING) MotifAnalyticsActions.GRAPH_INIT - else MotifAnalyticsActions.GRAPH_UPDATE + if (status == Status.INITIALIZING) { + MotifAnalyticsActions.GRAPH_INIT + } else { + MotifAnalyticsActions.GRAPH_UPDATE + } project.getService(AnalyticsService::class.java).logEvent(action) } @@ -214,7 +207,8 @@ class ScopeHierarchyBrowser( com.intellij.ide.actions.RefreshAction( IdeBundle.message("action.refresh"), IdeBundle.message("action.refresh"), - AllIcons.Actions.Refresh) { + AllIcons.Actions.Refresh, + ) { override fun actionPerformed(e: AnActionEvent) { doRefresh(false) @@ -229,7 +223,8 @@ class ScopeHierarchyBrowser( AnAction( IdeBundle.message("action.help"), IdeBundle.message("action.help"), - AllIcons.General.TodoQuestion) { + AllIcons.General.TodoQuestion, + ) { override fun actionPerformed(e: AnActionEvent) { BrowserUtil.open("https://github.com/uber/motif/wiki/Motif-IntelliJ-IDE-Plugin-Help") @@ -244,11 +239,13 @@ class ScopeHierarchyBrowser( AnAction( "File an issue", "File an issue or feature request", - AllIcons.Toolwindows.ToolWindowDebugger) { + AllIcons.Toolwindows.ToolWindowDebugger, + ) { override fun actionPerformed(e: AnActionEvent) { BrowserUtil.open( - "https://github.com/uber/motif/issues/new?title=[Motif%20IDE%20Plugin]%20:%20%3Center%20issue%20title%20here%3E") + "https://github.com/uber/motif/issues/new?title=[Motif%20IDE%20Plugin]%20:%20%3Center%20issue%20title%20here%3E", + ) } override fun update(event: AnActionEvent) { diff --git a/intellij/src/main/kotlin/motif/intellij/hierarchy/ScopeHierarchyTreeStructure.kt b/intellij/src/main/kotlin/motif/intellij/hierarchy/ScopeHierarchyTreeStructure.kt index 9611d361..96a9b0a2 100644 --- a/intellij/src/main/kotlin/motif/intellij/hierarchy/ScopeHierarchyTreeStructure.kt +++ b/intellij/src/main/kotlin/motif/intellij/hierarchy/ScopeHierarchyTreeStructure.kt @@ -57,7 +57,7 @@ import motif.models.Dependencies class ScopeHierarchyTreeStructure( val project: Project, val graph: ResolvedGraph, - descriptor: HierarchyNodeDescriptor + descriptor: HierarchyNodeDescriptor, ) : HierarchyTreeStructure(project, descriptor) { companion object { @@ -77,7 +77,13 @@ class ScopeHierarchyTreeStructure( graph.roots.sortedWith(ScopeComparator).forEach { scope -> descriptors.add( ScopeHierarchyScopeDescriptor( - myProject, graph, descriptor, (scope.clazz as IntelliJClass).psiClass, scope)) + myProject, + graph, + descriptor, + (scope.clazz as IntelliJClass).psiClass, + scope, + ), + ) } } is ScopeHierarchyScopeAncestorDescriptor -> { @@ -89,7 +95,9 @@ class ScopeHierarchyTreeStructure( graph, descriptor, (edge.parent.clazz as IntelliJClass).psiClass, - edge.parent)) + edge.parent, + ), + ) } } is ScopeHierarchyScopeDescriptor -> { @@ -100,7 +108,9 @@ class ScopeHierarchyTreeStructure( graph, descriptor, (edge.child.clazz as IntelliJClass).psiClass, - edge.child)) + edge.child, + ), + ) } } is ScopeHierarchySourcesSectionDescriptor -> { @@ -110,7 +120,13 @@ class ScopeHierarchyTreeStructure( if (descriptors.isEmpty()) { descriptors.add( ScopeHierarchySimpleDescriptor( - myProject, graph, descriptor, descriptor.element, LABEL_SCOPE_NO_PROVIDE)) + myProject, + graph, + descriptor, + descriptor.element, + LABEL_SCOPE_NO_PROVIDE, + ), + ) } } is ScopeHierarchySinksSectionDescriptor -> { @@ -120,16 +136,36 @@ class ScopeHierarchyTreeStructure( if (descriptors.isEmpty()) { descriptors.add( ScopeHierarchySimpleDescriptor( - myProject, graph, descriptor, descriptor.element, LABEL_SCOPE_NO_CONSUME)) + myProject, + graph, + descriptor, + descriptor.element, + LABEL_SCOPE_NO_CONSUME, + ), + ) } } is ScopeHierarchySourcesAndSinksSectionDescriptor -> { descriptors.add( ScopeHierarchySourcesSectionDescriptor( - myProject, graph, descriptor, descriptor.element, descriptor.scope, true)) + myProject, + graph, + descriptor, + descriptor.element, + descriptor.scope, + true, + ), + ) descriptors.add( ScopeHierarchySinksSectionDescriptor( - myProject, graph, descriptor, descriptor.element, descriptor.scope, true)) + myProject, + graph, + descriptor, + descriptor.element, + descriptor.scope, + true, + ), + ) } is ScopeHierarchyDependenciesSectionDescriptor -> { val dependencies: Dependencies? = descriptor.scope.dependencies @@ -141,7 +177,9 @@ class ScopeHierarchyTreeStructure( graph, descriptor, (method.method as IntelliJMethod).psiMethod, - method)) + method, + ), + ) } } if (descriptors.isEmpty()) { @@ -151,7 +189,9 @@ class ScopeHierarchyTreeStructure( graph, descriptor, descriptor.psiElement!!, - LABEL_SCOPE_NO_DEPENDENCIES)) + LABEL_SCOPE_NO_DEPENDENCIES, + ), + ) } } is ScopeHierarchySinkDetailsDescriptor -> { @@ -163,7 +203,8 @@ class ScopeHierarchyTreeStructure( is ScopeHierarchySinkDescriptor -> { graph.getProviders(descriptor.sink).sortedWith(SourceComparator).forEach { source -> descriptors.add( - ScopeHierarchySourceDetailsDescriptor(myProject, graph, descriptor, source)) + ScopeHierarchySourceDetailsDescriptor(myProject, graph, descriptor, source), + ) } } is ScopeHierarchySourceDescriptor -> { @@ -175,25 +216,46 @@ class ScopeHierarchyTreeStructure( graph.errors.forEach { error -> val errorMessage: ErrorMessage = ErrorMessage.get(error) descriptors.add( - ScopeHierarchyErrorDescriptor(myProject, graph, descriptor, error, errorMessage)) + ScopeHierarchyErrorDescriptor(myProject, graph, descriptor, error, errorMessage), + ) } } is ScopeHierarchyUsageSectionDescriptor -> { val countSources: Int = ScopeHierarchyUtils.getUsageCount( - project, graph, descriptor.clazz, includeSources = true, includeSinks = false) + project, + graph, + descriptor.clazz, + includeSources = true, + includeSinks = false, + ) val countSinks: Int = ScopeHierarchyUtils.getUsageCount( - project, graph, descriptor.clazz, includeSources = false, includeSinks = true) + project, + graph, + descriptor.clazz, + includeSources = false, + includeSinks = true, + ) if (countSources > 0) { descriptors.add( ScopeHierarchyUsageSourcesSectionDescriptor( - myProject, graph, descriptor, descriptor.clazz)) + myProject, + graph, + descriptor, + descriptor.clazz, + ), + ) } if (countSinks > 0) { descriptors.add( ScopeHierarchyUsageSinksSectionDescriptor( - myProject, graph, descriptor, descriptor.clazz)) + myProject, + graph, + descriptor, + descriptor.clazz, + ), + ) } } is ScopeHierarchyUsageSourcesSectionDescriptor -> { @@ -202,7 +264,8 @@ class ScopeHierarchyTreeStructure( val type: IrType = IntelliJType(project, elementType) graph.getSources(type).sortedWith(SourceComparator).forEach { source -> descriptors.add( - ScopeHierarchySourceDetailsDescriptor(myProject, graph, descriptor, source)) + ScopeHierarchySourceDetailsDescriptor(myProject, graph, descriptor, source), + ) } } is ScopeHierarchyUsageSinksSectionDescriptor -> { diff --git a/intellij/src/main/kotlin/motif/intellij/hierarchy/ScopePropertyHierarchyBrowser.kt b/intellij/src/main/kotlin/motif/intellij/hierarchy/ScopePropertyHierarchyBrowser.kt index ca7115b5..e88412f6 100644 --- a/intellij/src/main/kotlin/motif/intellij/hierarchy/ScopePropertyHierarchyBrowser.kt +++ b/intellij/src/main/kotlin/motif/intellij/hierarchy/ScopePropertyHierarchyBrowser.kt @@ -60,7 +60,7 @@ class ScopePropertyHierarchyBrowser( project: Project, initialGraph: ResolvedGraph, private val rootElement: PsiElement, - private val hierarchyType: PropertyHierarchyType + private val hierarchyType: PropertyHierarchyType, ) : HierarchyBrowserBase(project, rootElement), MotifService.Listener { private var graph: ResolvedGraph = initialGraph @@ -69,14 +69,15 @@ class ScopePropertyHierarchyBrowser( CONSUME, PROVIDE, CONSUME_AND_PROVIDE, - DEPENDENCIES + DEPENDENCIES, } companion object { const val PROPERTY_HIERARCHY_TYPE: String = "Properties" private val DATA_KEY = DataKey.create( - ScopePropertyHierarchyBrowser::class.java.name) + ScopePropertyHierarchyBrowser::class.java.name, + ) private const val LABEL_NO_SCOPE: String = "No Scope is selected." } @@ -87,31 +88,21 @@ class ScopePropertyHierarchyBrowser( } } - override fun isApplicableElement(element: PsiElement): Boolean { - return element is PsiClass - } + override fun isApplicableElement(element: PsiElement): Boolean = element is PsiClass - override fun getActionPlace(): String { - return ActionPlaces.METHOD_HIERARCHY_VIEW_TOOLBAR - } + override fun getActionPlace(): String = ActionPlaces.METHOD_HIERARCHY_VIEW_TOOLBAR override fun prependActions(actionGroup: DefaultActionGroup) {} - override fun getComparator(): Comparator> { - return JavaHierarchyUtil.getComparator(myProject) - } + override fun getComparator(): Comparator> = + JavaHierarchyUtil.getComparator(myProject) - override fun getElementFromDescriptor(descriptor: HierarchyNodeDescriptor): PsiElement? { - return descriptor.psiElement - } + override fun getElementFromDescriptor(descriptor: HierarchyNodeDescriptor): PsiElement? = + descriptor.psiElement - override fun getPrevOccurenceActionNameImpl(): String { - return LABEL_GO_PREVIOUS_SCOPE - } + override fun getPrevOccurenceActionNameImpl(): String = LABEL_GO_PREVIOUS_SCOPE - override fun getNextOccurenceActionNameImpl(): String { - return LABEL_GO_NEXT_SCOPE - } + override fun getNextOccurenceActionNameImpl(): String = LABEL_GO_NEXT_SCOPE override fun createTrees(trees: MutableMap) { trees[PROPERTY_HIERARCHY_TYPE] = createTree(true) @@ -122,9 +113,7 @@ class ScopePropertyHierarchyBrowser( actionGroup.add(actionManager.getAction(IdeActions.ACTION_EXPAND_ALL)) } - override fun createLegendPanel(): JPanel? { - return null - } + override fun createLegendPanel(): JPanel? = null override fun configureTree(tree: Tree) { super.configureTree(tree) @@ -139,14 +128,15 @@ class ScopePropertyHierarchyBrowser( } } - override fun getContentDisplayName(typeName: String, element: PsiElement): String? { - return MessageFormat.format( - typeName, ClassPresentationUtil.getNameForClass(element as PsiClass, false)) - } + override fun getContentDisplayName(typeName: String, element: PsiElement): String? = + MessageFormat.format( + typeName, + ClassPresentationUtil.getNameForClass(element as PsiClass, false), + ) override fun createHierarchyTreeStructure( typeName: String, - psiElement: PsiElement + psiElement: PsiElement, ): HierarchyTreeStructure? { if (psiElement is PsiClass && isMotifScopeClass(psiElement)) { val scopeType: PsiType = PsiElementFactory.SERVICE.getInstance(project).createType(psiElement) @@ -156,25 +146,45 @@ class ScopePropertyHierarchyBrowser( PropertyHierarchyType.CONSUME -> { val descriptor: HierarchyNodeDescriptor = ScopeHierarchySinksSectionDescriptor( - project, graph, null, (scope.clazz as IntelliJClass).psiClass, scope) + project, + graph, + null, + (scope.clazz as IntelliJClass).psiClass, + scope, + ) ScopeHierarchyTreeStructure(project, graph, descriptor) } PropertyHierarchyType.PROVIDE -> { val descriptor: HierarchyNodeDescriptor = ScopeHierarchySourcesSectionDescriptor( - project, graph, null, (scope.clazz as IntelliJClass).psiClass, scope) + project, + graph, + null, + (scope.clazz as IntelliJClass).psiClass, + scope, + ) ScopeHierarchyTreeStructure(project, graph, descriptor) } PropertyHierarchyType.CONSUME_AND_PROVIDE -> { val descriptor: HierarchyNodeDescriptor = ScopeHierarchySourcesAndSinksSectionDescriptor( - project, graph, null, (scope.clazz as IntelliJClass).psiClass, scope) + project, + graph, + null, + (scope.clazz as IntelliJClass).psiClass, + scope, + ) ScopeHierarchyTreeStructure(project, graph, descriptor) } PropertyHierarchyType.DEPENDENCIES -> { val descriptor: HierarchyNodeDescriptor = ScopeHierarchyDependenciesSectionDescriptor( - project, graph, null, (scope.clazz as IntelliJClass).psiClass, scope) + project, + graph, + null, + (scope.clazz as IntelliJClass).psiClass, + scope, + ) ScopeHierarchyTreeStructure(project, graph, descriptor) } } diff --git a/intellij/src/main/kotlin/motif/intellij/hierarchy/UsageHierarchyBrowser.kt b/intellij/src/main/kotlin/motif/intellij/hierarchy/UsageHierarchyBrowser.kt index 3237ebf8..cadba59d 100644 --- a/intellij/src/main/kotlin/motif/intellij/hierarchy/UsageHierarchyBrowser.kt +++ b/intellij/src/main/kotlin/motif/intellij/hierarchy/UsageHierarchyBrowser.kt @@ -41,7 +41,7 @@ import motif.intellij.hierarchy.descriptor.ScopeHierarchyUsageSectionDescriptor class UsageHierarchyBrowser( project: Project, initialGraph: ResolvedGraph, - private val rootElement: PsiElement + private val rootElement: PsiElement, ) : HierarchyBrowserBase(project, rootElement), MotifService.Listener { private var graph: ResolvedGraph = initialGraph @@ -57,48 +57,37 @@ class UsageHierarchyBrowser( super.doRefresh(true) } - override fun isApplicableElement(element: PsiElement): Boolean { - return element is PsiClass - } + override fun isApplicableElement(element: PsiElement): Boolean = element is PsiClass - override fun getActionPlace(): String { - return ActionPlaces.METHOD_HIERARCHY_VIEW_TOOLBAR - } + override fun getActionPlace(): String = ActionPlaces.METHOD_HIERARCHY_VIEW_TOOLBAR override fun prependActions(actionGroup: DefaultActionGroup) {} - override fun getComparator(): Comparator> { - return JavaHierarchyUtil.getComparator(myProject) - } + override fun getComparator(): Comparator> = + JavaHierarchyUtil.getComparator(myProject) - override fun getElementFromDescriptor(descriptor: HierarchyNodeDescriptor): PsiElement? { - return descriptor.psiElement - } + override fun getElementFromDescriptor(descriptor: HierarchyNodeDescriptor): PsiElement? = + descriptor.psiElement - override fun getPrevOccurenceActionNameImpl(): String { - return LABEL_GO_PREVIOUS_SCOPE - } + override fun getPrevOccurenceActionNameImpl(): String = LABEL_GO_PREVIOUS_SCOPE - override fun getNextOccurenceActionNameImpl(): String { - return LABEL_GO_NEXT_SCOPE - } + override fun getNextOccurenceActionNameImpl(): String = LABEL_GO_NEXT_SCOPE - override fun createLegendPanel(): JPanel? { - return null - } + override fun createLegendPanel(): JPanel? = null override fun createTrees(trees: MutableMap) { trees[USAGE_HIERARCHY_TYPE] = createTree(true) } - override fun getContentDisplayName(typeName: String, element: PsiElement): String? { - return MessageFormat.format( - typeName, ClassPresentationUtil.getNameForClass(element as PsiClass, false)) - } + override fun getContentDisplayName(typeName: String, element: PsiElement): String? = + MessageFormat.format( + typeName, + ClassPresentationUtil.getNameForClass(element as PsiClass, false), + ) override fun createHierarchyTreeStructure( typeName: String, - psiElement: PsiElement + psiElement: PsiElement, ): HierarchyTreeStructure? { if (psiElement is PsiClass) { val descriptor: HierarchyNodeDescriptor = diff --git a/intellij/src/main/kotlin/motif/intellij/hierarchy/descriptor/ScopeHierarchyDependenciesSectionDescriptor.kt b/intellij/src/main/kotlin/motif/intellij/hierarchy/descriptor/ScopeHierarchyDependenciesSectionDescriptor.kt index 1e447ea4..bfc460af 100644 --- a/intellij/src/main/kotlin/motif/intellij/hierarchy/descriptor/ScopeHierarchyDependenciesSectionDescriptor.kt +++ b/intellij/src/main/kotlin/motif/intellij/hierarchy/descriptor/ScopeHierarchyDependenciesSectionDescriptor.kt @@ -27,14 +27,12 @@ open class ScopeHierarchyDependenciesSectionDescriptor( graph: ResolvedGraph, parentDescriptor: HierarchyNodeDescriptor?, element: PsiElement, - val scope: Scope + val scope: Scope, ) : ScopeHierarchyNodeDescriptor(project, graph, parentDescriptor, element, false) { override fun updateText(text: CompositeAppearance) { text.ending.addText(scope.simpleName) } - override fun toString(): String { - return scope.simpleName - } + override fun toString(): String = scope.simpleName } diff --git a/intellij/src/main/kotlin/motif/intellij/hierarchy/descriptor/ScopeHierarchyDependencyDescriptor.kt b/intellij/src/main/kotlin/motif/intellij/hierarchy/descriptor/ScopeHierarchyDependencyDescriptor.kt index 882caad6..5d2c1533 100644 --- a/intellij/src/main/kotlin/motif/intellij/hierarchy/descriptor/ScopeHierarchyDependencyDescriptor.kt +++ b/intellij/src/main/kotlin/motif/intellij/hierarchy/descriptor/ScopeHierarchyDependencyDescriptor.kt @@ -28,17 +28,16 @@ open class ScopeHierarchyDependencyDescriptor( graph: ResolvedGraph, parentDescriptor: HierarchyNodeDescriptor, element: PsiElement, - private val method: Dependencies.Method + private val method: Dependencies.Method, ) : ScopeHierarchyNodeDescriptor(project, graph, parentDescriptor, element, false) { override fun updateText(text: CompositeAppearance) { text.ending.addText(method.returnType.simpleName) text.ending.addText( " (" + formatQualifiedName(method.returnType.qualifiedName) + ")", - getPackageNameAttributes()) + getPackageNameAttributes(), + ) } - override fun toString(): String { - return method.returnType.simpleName - } + override fun toString(): String = method.returnType.simpleName } diff --git a/intellij/src/main/kotlin/motif/intellij/hierarchy/descriptor/ScopeHierarchyErrorDescriptor.kt b/intellij/src/main/kotlin/motif/intellij/hierarchy/descriptor/ScopeHierarchyErrorDescriptor.kt index 9565dd83..f6963ac6 100644 --- a/intellij/src/main/kotlin/motif/intellij/hierarchy/descriptor/ScopeHierarchyErrorDescriptor.kt +++ b/intellij/src/main/kotlin/motif/intellij/hierarchy/descriptor/ScopeHierarchyErrorDescriptor.kt @@ -57,104 +57,102 @@ open class ScopeHierarchyErrorDescriptor( graph: ResolvedGraph, parentDescriptor: HierarchyNodeDescriptor?, val error: MotifError, - val errorMessage: ErrorMessage + val errorMessage: ErrorMessage, ) : ScopeHierarchyNodeDescriptor( - project, graph, parentDescriptor, getElementFromError(error), false) { + project, + graph, + parentDescriptor, + getElementFromError(error), + false, + ) { companion object { - fun getElementFromError(error: MotifError): PsiElement { - return when (error) { - is ScopeMustBeAnInterface -> { - (error.scopeClass as IntelliJClass).psiClass + fun getElementFromError(error: MotifError): PsiElement = + when (error) { + is ScopeMustBeAnInterface -> { + (error.scopeClass as IntelliJClass).psiClass + } + is VoidScopeMethod -> { + (error.method as IntelliJMethod).psiMethod + } + is AccessMethodParameters -> { + (error.scope.clazz as IntelliJClass).psiClass + } + is ObjectsFieldFound -> { + (error.scope.clazz as IntelliJClass).psiClass + } + is ObjectsConstructorFound -> { + (error.scope.clazz as IntelliJClass).psiClass + } + is VoidFactoryMethod -> { + (error.method as IntelliJMethod).psiMethod + } + is NullableFactoryMethod -> { + (error.method as IntelliJMethod).psiMethod + } + is NullableParameter -> { + (error.parameter as IntelliJMethodParameter).psiParameter + } + is NullableDynamicDependency -> { + (error.parameter as IntelliJMethodParameter).psiParameter + } + is InvalidFactoryMethod -> { + (error.method as IntelliJMethod).psiMethod + } + is UnspreadableType -> { + (error.method as IntelliJMethod).psiMethod + } + is NoSuitableConstructor -> { + (error.method as IntelliJMethod).psiMethod + } + is InjectAnnotationRequired -> { + (error.method as IntelliJMethod).psiMethod + } + is NotAssignableBindsMethod -> { + (error.method as IntelliJMethod).psiMethod + } + is VoidDependenciesMethod -> { + (error.method as IntelliJMethod).psiMethod + } + is DependencyMethodWithParameters -> { + (error.method as IntelliJMethod).psiMethod + } + is NullableSpreadMethod -> { + (error.spreadMethod as IntelliJMethod).psiMethod + } + is InvalidQualifier -> { + (error.annotated.annotations[0].members[0] as IntelliJMethod).psiMethod + } + is DuplicatedChildParameterSource -> { + (error.childScopeMethod.method as IntelliJMethod).psiMethod + } + is ScopeCycleError -> { + (error.path[0].clazz as IntelliJClass).psiClass + } + is UnsatisfiedDependencyError -> { + (error.top.clazz as IntelliJClass).psiClass + } + is DependencyCycleError -> { + (error.path[0].scope.clazz as IntelliJClass).psiClass + } + is UnexposedSourceError -> { + (error.source.scope.clazz as IntelliJClass).psiClass + } + is AlreadySatisfiedError -> { + (error.scope.clazz as IntelliJClass).psiClass + } + else -> throw UnsupportedOperationException() } - is VoidScopeMethod -> { - (error.method as IntelliJMethod).psiMethod - } - is AccessMethodParameters -> { - (error.scope.clazz as IntelliJClass).psiClass - } - is ObjectsFieldFound -> { - (error.scope.clazz as IntelliJClass).psiClass - } - is ObjectsConstructorFound -> { - (error.scope.clazz as IntelliJClass).psiClass - } - is VoidFactoryMethod -> { - (error.method as IntelliJMethod).psiMethod - } - is NullableFactoryMethod -> { - (error.method as IntelliJMethod).psiMethod - } - is NullableParameter -> { - (error.parameter as IntelliJMethodParameter).psiParameter - } - is NullableDynamicDependency -> { - (error.parameter as IntelliJMethodParameter).psiParameter - } - is InvalidFactoryMethod -> { - (error.method as IntelliJMethod).psiMethod - } - is UnspreadableType -> { - (error.method as IntelliJMethod).psiMethod - } - is NoSuitableConstructor -> { - (error.method as IntelliJMethod).psiMethod - } - is InjectAnnotationRequired -> { - (error.method as IntelliJMethod).psiMethod - } - is NotAssignableBindsMethod -> { - (error.method as IntelliJMethod).psiMethod - } - is VoidDependenciesMethod -> { - (error.method as IntelliJMethod).psiMethod - } - is DependencyMethodWithParameters -> { - (error.method as IntelliJMethod).psiMethod - } - is NullableSpreadMethod -> { - (error.spreadMethod as IntelliJMethod).psiMethod - } - is InvalidQualifier -> { - (error.annotated.annotations[0].members[0] as IntelliJMethod).psiMethod - } - is DuplicatedChildParameterSource -> { - (error.childScopeMethod.method as IntelliJMethod).psiMethod - } - is ScopeCycleError -> { - (error.path[0].clazz as IntelliJClass).psiClass - } - is UnsatisfiedDependencyError -> { - (error.top.clazz as IntelliJClass).psiClass - } - is DependencyCycleError -> { - (error.path[0].scope.clazz as IntelliJClass).psiClass - } - is UnexposedSourceError -> { - (error.source.scope.clazz as IntelliJClass).psiClass - } - is AlreadySatisfiedError -> { - (error.scope.clazz as IntelliJClass).psiClass - } - else -> throw UnsupportedOperationException() - } - } } override fun updateText(text: CompositeAppearance) { text.ending.addText(errorMessage.name) } - override fun getIcon(element: PsiElement): Icon? { - return AllIcons.RunConfigurations.TestFailed - } + override fun getIcon(element: PsiElement): Icon? = AllIcons.RunConfigurations.TestFailed - override fun getLegend(): String? { - return errorMessage.text - } + override fun getLegend(): String? = errorMessage.text - override fun toString(): String { - return errorMessage.name - } + override fun toString(): String = errorMessage.name } diff --git a/intellij/src/main/kotlin/motif/intellij/hierarchy/descriptor/ScopeHierarchyNodeDescriptor.kt b/intellij/src/main/kotlin/motif/intellij/hierarchy/descriptor/ScopeHierarchyNodeDescriptor.kt index 14b173f9..ca0747df 100644 --- a/intellij/src/main/kotlin/motif/intellij/hierarchy/descriptor/ScopeHierarchyNodeDescriptor.kt +++ b/intellij/src/main/kotlin/motif/intellij/hierarchy/descriptor/ScopeHierarchyNodeDescriptor.kt @@ -35,14 +35,12 @@ open class ScopeHierarchyNodeDescriptor( val graph: ResolvedGraph, val parentDescriptor: HierarchyNodeDescriptor?, val element: PsiElement, - isBase: Boolean + isBase: Boolean, ) : HierarchyNodeDescriptor(project, parentDescriptor, element, isBase) { open fun updateText(text: CompositeAppearance) {} - open fun getLegend(): String? { - return null - } + open fun getLegend(): String? = null override fun update(): Boolean { val changes = super.update() @@ -60,7 +58,10 @@ open class ScopeHierarchyNodeDescriptor( fun getDefaultTextAttributes(isError: Boolean = false): TextAttributes { val font: Int = if (myIsBase) Font.BOLD else Font.PLAIN - return if (isError) TextAttributes(myColor, null, Color.red, EffectType.WAVE_UNDERSCORE, font) - else TextAttributes(myColor, null, null, null, font) + return if (isError) { + TextAttributes(myColor, null, Color.red, EffectType.WAVE_UNDERSCORE, font) + } else { + TextAttributes(myColor, null, null, null, font) + } } } diff --git a/intellij/src/main/kotlin/motif/intellij/hierarchy/descriptor/ScopeHierarchyRootScopeNodeDescriptor.kt b/intellij/src/main/kotlin/motif/intellij/hierarchy/descriptor/ScopeHierarchyRootDescriptor.kt similarity index 97% rename from intellij/src/main/kotlin/motif/intellij/hierarchy/descriptor/ScopeHierarchyRootScopeNodeDescriptor.kt rename to intellij/src/main/kotlin/motif/intellij/hierarchy/descriptor/ScopeHierarchyRootDescriptor.kt index 2e09dfde..095e54be 100644 --- a/intellij/src/main/kotlin/motif/intellij/hierarchy/descriptor/ScopeHierarchyRootScopeNodeDescriptor.kt +++ b/intellij/src/main/kotlin/motif/intellij/hierarchy/descriptor/ScopeHierarchyRootDescriptor.kt @@ -26,7 +26,7 @@ class ScopeHierarchyRootDescriptor( project: Project, graph: ResolvedGraph, element: PsiElement, - private val status: ScopeHierarchyBrowser.Status + private val status: ScopeHierarchyBrowser.Status, ) : ScopeHierarchyNodeDescriptor(project, graph, null, element, true) { companion object { diff --git a/intellij/src/main/kotlin/motif/intellij/hierarchy/descriptor/ScopeHierarchyRootErrorDescriptor.kt b/intellij/src/main/kotlin/motif/intellij/hierarchy/descriptor/ScopeHierarchyRootErrorDescriptor.kt index e5205da4..b215bf85 100644 --- a/intellij/src/main/kotlin/motif/intellij/hierarchy/descriptor/ScopeHierarchyRootErrorDescriptor.kt +++ b/intellij/src/main/kotlin/motif/intellij/hierarchy/descriptor/ScopeHierarchyRootErrorDescriptor.kt @@ -27,7 +27,7 @@ open class ScopeHierarchyRootErrorDescriptor( project: Project, graph: ResolvedGraph, parentDescriptor: HierarchyNodeDescriptor?, - element: PsiElement + element: PsiElement, ) : ScopeHierarchyNodeDescriptor(project, graph, parentDescriptor, element, false) { override fun updateText(text: CompositeAppearance) { @@ -38,7 +38,6 @@ open class ScopeHierarchyRootErrorDescriptor( } } - override fun getIcon(element: PsiElement): Icon? { - return if (graph.errors.isNotEmpty()) null else AllIcons.RunConfigurations.TestPassed - } + override fun getIcon(element: PsiElement): Icon? = + if (graph.errors.isNotEmpty()) null else AllIcons.RunConfigurations.TestPassed } diff --git a/intellij/src/main/kotlin/motif/intellij/hierarchy/descriptor/ScopeHierarchyScopeAncestorDescriptor.kt b/intellij/src/main/kotlin/motif/intellij/hierarchy/descriptor/ScopeHierarchyScopeAncestorDescriptor.kt index 75d76ec5..a34f475c 100644 --- a/intellij/src/main/kotlin/motif/intellij/hierarchy/descriptor/ScopeHierarchyScopeAncestorDescriptor.kt +++ b/intellij/src/main/kotlin/motif/intellij/hierarchy/descriptor/ScopeHierarchyScopeAncestorDescriptor.kt @@ -30,5 +30,5 @@ class ScopeHierarchyScopeAncestorDescriptor( parentDescriptor: HierarchyNodeDescriptor?, clazz: PsiClass, scope: Scope, - isBase: Boolean = false + isBase: Boolean = false, ) : ScopeHierarchyScopeDescriptor(project, graph, parentDescriptor, clazz, scope, isBase) diff --git a/intellij/src/main/kotlin/motif/intellij/hierarchy/descriptor/ScopeHierarchyScopeDescriptor.kt b/intellij/src/main/kotlin/motif/intellij/hierarchy/descriptor/ScopeHierarchyScopeDescriptor.kt index 52a143be..eb96fa49 100644 --- a/intellij/src/main/kotlin/motif/intellij/hierarchy/descriptor/ScopeHierarchyScopeDescriptor.kt +++ b/intellij/src/main/kotlin/motif/intellij/hierarchy/descriptor/ScopeHierarchyScopeDescriptor.kt @@ -37,7 +37,7 @@ open class ScopeHierarchyScopeDescriptor( parentDescriptor: HierarchyNodeDescriptor?, private val clazz: PsiClass, val scope: Scope, - isBase: Boolean = false + isBase: Boolean = false, ) : ScopeHierarchyNodeDescriptor(project, graph, parentDescriptor, clazz, isBase) { override fun updateText(text: CompositeAppearance) { @@ -49,11 +49,7 @@ open class ScopeHierarchyScopeDescriptor( } } - override fun getIcon(element: PsiElement): Icon? { - return AllIcons.Nodes.Interface - } + override fun getIcon(element: PsiElement): Icon? = AllIcons.Nodes.Interface - override fun toString(): String { - return clazz.name ?: "" - } + override fun toString(): String = clazz.name ?: "" } diff --git a/intellij/src/main/kotlin/motif/intellij/hierarchy/descriptor/ScopeHierarchySimpleDescriptor.kt b/intellij/src/main/kotlin/motif/intellij/hierarchy/descriptor/ScopeHierarchySimpleDescriptor.kt index a6796089..4459570e 100644 --- a/intellij/src/main/kotlin/motif/intellij/hierarchy/descriptor/ScopeHierarchySimpleDescriptor.kt +++ b/intellij/src/main/kotlin/motif/intellij/hierarchy/descriptor/ScopeHierarchySimpleDescriptor.kt @@ -32,7 +32,7 @@ class ScopeHierarchySimpleDescriptor( graph: ResolvedGraph, parentDescriptor: HierarchyNodeDescriptor?, element: PsiElement, - private val label: String + private val label: String, ) : ScopeHierarchyNodeDescriptor(project, graph, parentDescriptor, element, false) { override fun updateText(text: CompositeAppearance) { @@ -40,11 +40,7 @@ class ScopeHierarchySimpleDescriptor( text.ending.addText(label, textAttr) } - override fun getIcon(element: PsiElement): Icon? { - return null - } + override fun getIcon(element: PsiElement): Icon? = null - override fun toString(): String { - return label - } + override fun toString(): String = label } diff --git a/intellij/src/main/kotlin/motif/intellij/hierarchy/descriptor/ScopeHierarchySinkDescriptor.kt b/intellij/src/main/kotlin/motif/intellij/hierarchy/descriptor/ScopeHierarchySinkDescriptor.kt index 0b08311c..098b3a4a 100644 --- a/intellij/src/main/kotlin/motif/intellij/hierarchy/descriptor/ScopeHierarchySinkDescriptor.kt +++ b/intellij/src/main/kotlin/motif/intellij/hierarchy/descriptor/ScopeHierarchySinkDescriptor.kt @@ -35,33 +35,36 @@ open class ScopeHierarchySinkDescriptor( project: Project, graph: ResolvedGraph, parentDescriptor: HierarchyNodeDescriptor?, - val sink: Sink + val sink: Sink, ) : ScopeHierarchyNodeDescriptor( - project, graph, parentDescriptor, getElementFromSink(sink), false) { + project, + graph, + parentDescriptor, + getElementFromSink(sink), + false, + ) { companion object { - fun getElementFromSink(sink: Sink): PsiElement { - return when (sink) { - is FactoryMethodSink -> { - (sink.parameter.factoryMethod.method as IntelliJMethod).psiMethod - } - is AccessMethodSink -> { - (sink.accessMethod.method as IntelliJMethod).psiMethod + fun getElementFromSink(sink: Sink): PsiElement = + when (sink) { + is FactoryMethodSink -> { + (sink.parameter.factoryMethod.method as IntelliJMethod).psiMethod + } + is AccessMethodSink -> { + (sink.accessMethod.method as IntelliJMethod).psiMethod + } } - } - } - fun getConsumingTypeFromSink(sink: Sink): Type { - return when (sink) { - is FactoryMethodSink -> { - sink.parameter.factoryMethod.returnType.type - } - is AccessMethodSink -> { - sink.type + fun getConsumingTypeFromSink(sink: Sink): Type = + when (sink) { + is FactoryMethodSink -> { + sink.parameter.factoryMethod.returnType.type + } + is AccessMethodSink -> { + sink.type + } } - } - } } override fun updateText(text: CompositeAppearance) { @@ -70,10 +73,12 @@ open class ScopeHierarchySinkDescriptor( text.ending.addText(" → ${consumingType.simpleName}", getPackageNameAttributes()) } - override fun getIcon(element: PsiElement): Icon? { - return if (element is PsiClass && element.isInterface) AllIcons.Nodes.Interface - else AllIcons.Nodes.Class - } + override fun getIcon(element: PsiElement): Icon? = + if (element is PsiClass && element.isInterface) { + AllIcons.Nodes.Interface + } else { + AllIcons.Nodes.Class + } override fun getLegend(): String? { val sb: StringBuilder = StringBuilder() @@ -89,7 +94,8 @@ open class ScopeHierarchySinkDescriptor( "" + " has a dependency on type " + sink.type.simpleName + - ".") + ".", + ) } graph.getProviders(sink).forEach { source -> when (source) { @@ -100,7 +106,8 @@ open class ScopeHierarchySinkDescriptor( "" + ", via Motif Factory method " + source.factoryMethod.name + - "().") + "().", + ) } else -> { // TODO : Handle all types @@ -116,7 +123,5 @@ open class ScopeHierarchySinkDescriptor( return null } - override fun toString(): String { - return sink.type.simpleName - } + override fun toString(): String = sink.type.simpleName } diff --git a/intellij/src/main/kotlin/motif/intellij/hierarchy/descriptor/ScopeHierarchySinkDetailsDescriptor.kt b/intellij/src/main/kotlin/motif/intellij/hierarchy/descriptor/ScopeHierarchySinkDetailsDescriptor.kt index 4c4a9443..16d87b93 100644 --- a/intellij/src/main/kotlin/motif/intellij/hierarchy/descriptor/ScopeHierarchySinkDetailsDescriptor.kt +++ b/intellij/src/main/kotlin/motif/intellij/hierarchy/descriptor/ScopeHierarchySinkDetailsDescriptor.kt @@ -28,7 +28,7 @@ open class ScopeHierarchySinkDetailsDescriptor( project: Project, graph: ResolvedGraph, parentDescriptor: HierarchyNodeDescriptor?, - sink: Sink + sink: Sink, ) : ScopeHierarchySinkDescriptor(project, graph, parentDescriptor, sink) { override fun updateText(text: CompositeAppearance) { @@ -38,10 +38,9 @@ open class ScopeHierarchySinkDetailsDescriptor( " (" + formatQualifiedName(sink.scope.qualifiedName) + ")", - getPackageNameAttributes()) + getPackageNameAttributes(), + ) } - override fun getIcon(element: PsiElement): Icon? { - return null - } + override fun getIcon(element: PsiElement): Icon? = null } diff --git a/intellij/src/main/kotlin/motif/intellij/hierarchy/descriptor/ScopeHierarchySinksSectionDescriptor.kt b/intellij/src/main/kotlin/motif/intellij/hierarchy/descriptor/ScopeHierarchySinksSectionDescriptor.kt index 445ba448..77b723b0 100644 --- a/intellij/src/main/kotlin/motif/intellij/hierarchy/descriptor/ScopeHierarchySinksSectionDescriptor.kt +++ b/intellij/src/main/kotlin/motif/intellij/hierarchy/descriptor/ScopeHierarchySinksSectionDescriptor.kt @@ -30,7 +30,7 @@ open class ScopeHierarchySinksSectionDescriptor( parentDescriptor: HierarchyNodeDescriptor?, element: PsiElement, val scope: Scope, - private val useLabel: Boolean = false + private val useLabel: Boolean = false, ) : ScopeHierarchyNodeDescriptor(project, graph, parentDescriptor, element, false) { override fun updateText(text: CompositeAppearance) { @@ -38,10 +38,10 @@ open class ScopeHierarchySinksSectionDescriptor( val count: Int = graph.getSinks(scope).count() text.ending.addText(label) text.ending.addText( - " " + ScopeHierarchyUtils.getObjectString(count), getPackageNameAttributes()) + " " + ScopeHierarchyUtils.getObjectString(count), + getPackageNameAttributes(), + ) } - override fun getIcon(element: PsiElement): Icon? { - return null - } + override fun getIcon(element: PsiElement): Icon? = null } diff --git a/intellij/src/main/kotlin/motif/intellij/hierarchy/descriptor/ScopeHierarchySourceDescriptor.kt b/intellij/src/main/kotlin/motif/intellij/hierarchy/descriptor/ScopeHierarchySourceDescriptor.kt index 2180c16c..797a2472 100644 --- a/intellij/src/main/kotlin/motif/intellij/hierarchy/descriptor/ScopeHierarchySourceDescriptor.kt +++ b/intellij/src/main/kotlin/motif/intellij/hierarchy/descriptor/ScopeHierarchySourceDescriptor.kt @@ -38,28 +38,32 @@ open class ScopeHierarchySourceDescriptor( project: Project, graph: ResolvedGraph, parentDescriptor: HierarchyNodeDescriptor?, - val source: Source + val source: Source, ) : ScopeHierarchyNodeDescriptor( - project, graph, parentDescriptor, getElementFromSource(source), false) { + project, + graph, + parentDescriptor, + getElementFromSource(source), + false, + ) { companion object { - fun getElementFromSource(source: Source): PsiElement { - return when (source) { - is FactoryMethodSource -> { - (source.factoryMethod.method as IntelliJMethod).psiMethod + fun getElementFromSource(source: Source): PsiElement = + when (source) { + is FactoryMethodSource -> { + (source.factoryMethod.method as IntelliJMethod).psiMethod + } + is ScopeSource -> { + (source.scope.clazz as IntelliJClass).psiClass + } + is SpreadSource -> { + (source.spreadMethod.method as IntelliJMethod).psiMethod + } + is ChildParameterSource -> { + (source.parameter.method.method as IntelliJMethod).psiMethod + } } - is ScopeSource -> { - (source.scope.clazz as IntelliJClass).psiClass - } - is SpreadSource -> { - (source.spreadMethod.method as IntelliJMethod).psiMethod - } - is ChildParameterSource -> { - (source.parameter.method.method as IntelliJMethod).psiMethod - } - } - } } override fun updateText(text: CompositeAppearance) { @@ -68,7 +72,9 @@ open class ScopeHierarchySourceDescriptor( } text.ending.addText(source.type.simpleName) text.ending.addText( - " (" + formatQualifiedName(source.type.qualifiedName) + ")", getPackageNameAttributes()) + " (" + formatQualifiedName(source.type.qualifiedName) + ")", + getPackageNameAttributes(), + ) } override fun getLegend(): String? { @@ -76,12 +82,12 @@ open class ScopeHierarchySourceDescriptor( return super.getLegend() } - override fun getIcon(element: PsiElement): Icon? { - return if (element is PsiClass && element.isInterface) AllIcons.Nodes.Interface - else AllIcons.Nodes.Class - } + override fun getIcon(element: PsiElement): Icon? = + if (element is PsiClass && element.isInterface) { + AllIcons.Nodes.Interface + } else { + AllIcons.Nodes.Class + } - override fun toString(): String { - return source.type.simpleName - } + override fun toString(): String = source.type.simpleName } diff --git a/intellij/src/main/kotlin/motif/intellij/hierarchy/descriptor/ScopeHierarchySourceDetailsDescriptor.kt b/intellij/src/main/kotlin/motif/intellij/hierarchy/descriptor/ScopeHierarchySourceDetailsDescriptor.kt index 16089c4f..9feae8a3 100644 --- a/intellij/src/main/kotlin/motif/intellij/hierarchy/descriptor/ScopeHierarchySourceDetailsDescriptor.kt +++ b/intellij/src/main/kotlin/motif/intellij/hierarchy/descriptor/ScopeHierarchySourceDetailsDescriptor.kt @@ -28,7 +28,7 @@ open class ScopeHierarchySourceDetailsDescriptor( project: Project, graph: ResolvedGraph, parentDescriptor: HierarchyNodeDescriptor?, - source: Source + source: Source, ) : ScopeHierarchySourceDescriptor(project, graph, parentDescriptor, source) { override fun updateText(text: CompositeAppearance) { @@ -38,10 +38,9 @@ open class ScopeHierarchySourceDetailsDescriptor( " (" + formatQualifiedName(source.scope.qualifiedName) + ")", - getPackageNameAttributes()) + getPackageNameAttributes(), + ) } - override fun getIcon(element: PsiElement): Icon? { - return null - } + override fun getIcon(element: PsiElement): Icon? = null } diff --git a/intellij/src/main/kotlin/motif/intellij/hierarchy/descriptor/ScopeHierarchySourcesAndSinksSectionDescriptor.kt b/intellij/src/main/kotlin/motif/intellij/hierarchy/descriptor/ScopeHierarchySourcesAndSinksSectionDescriptor.kt index 7436256f..d60153a5 100644 --- a/intellij/src/main/kotlin/motif/intellij/hierarchy/descriptor/ScopeHierarchySourcesAndSinksSectionDescriptor.kt +++ b/intellij/src/main/kotlin/motif/intellij/hierarchy/descriptor/ScopeHierarchySourcesAndSinksSectionDescriptor.kt @@ -30,16 +30,16 @@ open class ScopeHierarchySourcesAndSinksSectionDescriptor( graph: ResolvedGraph, parentDescriptor: HierarchyNodeDescriptor?, element: PsiElement, - val scope: Scope + val scope: Scope, ) : ScopeHierarchyNodeDescriptor(project, graph, parentDescriptor, element, false) { override fun updateText(text: CompositeAppearance) { text.ending.addText(scope.simpleName, TextAttributes(myColor, null, null, null, BOLD)) text.ending.addText( - " (" + formatQualifiedName(scope.qualifiedName) + ")", getPackageNameAttributes()) + " (" + formatQualifiedName(scope.qualifiedName) + ")", + getPackageNameAttributes(), + ) } - override fun toString(): String { - return scope.simpleName - } + override fun toString(): String = scope.simpleName } diff --git a/intellij/src/main/kotlin/motif/intellij/hierarchy/descriptor/ScopeHierarchySourcesSectionDescriptor.kt b/intellij/src/main/kotlin/motif/intellij/hierarchy/descriptor/ScopeHierarchySourcesSectionDescriptor.kt index 6739e427..0f639b48 100644 --- a/intellij/src/main/kotlin/motif/intellij/hierarchy/descriptor/ScopeHierarchySourcesSectionDescriptor.kt +++ b/intellij/src/main/kotlin/motif/intellij/hierarchy/descriptor/ScopeHierarchySourcesSectionDescriptor.kt @@ -31,7 +31,7 @@ open class ScopeHierarchySourcesSectionDescriptor( parentDescriptor: HierarchyNodeDescriptor?, element: PsiElement, val scope: Scope, - private val useLabel: Boolean = false + private val useLabel: Boolean = false, ) : ScopeHierarchyNodeDescriptor(project, graph, parentDescriptor, element, false) { override fun updateText(text: CompositeAppearance) { @@ -39,10 +39,10 @@ open class ScopeHierarchySourcesSectionDescriptor( val count: Int = getVisibleSources(graph, scope).count() text.ending.addText(label) text.ending.addText( - " " + ScopeHierarchyUtils.getObjectString(count), getPackageNameAttributes()) + " " + ScopeHierarchyUtils.getObjectString(count), + getPackageNameAttributes(), + ) } - override fun getIcon(element: PsiElement): Icon? { - return null - } + override fun getIcon(element: PsiElement): Icon? = null } diff --git a/intellij/src/main/kotlin/motif/intellij/hierarchy/descriptor/ScopeHierarchyUsageSectionDescriptor.kt b/intellij/src/main/kotlin/motif/intellij/hierarchy/descriptor/ScopeHierarchyUsageSectionDescriptor.kt index 7b215dac..40f310b4 100644 --- a/intellij/src/main/kotlin/motif/intellij/hierarchy/descriptor/ScopeHierarchyUsageSectionDescriptor.kt +++ b/intellij/src/main/kotlin/motif/intellij/hierarchy/descriptor/ScopeHierarchyUsageSectionDescriptor.kt @@ -27,7 +27,7 @@ open class ScopeHierarchyUsageSectionDescriptor( private val nonNullproject: Project, graph: ResolvedGraph, parentDescriptor: HierarchyNodeDescriptor?, - val clazz: PsiClass + val clazz: PsiClass, ) : ScopeHierarchyNodeDescriptor(nonNullproject, graph, parentDescriptor, clazz, false) { override fun updateText(text: CompositeAppearance) { diff --git a/intellij/src/main/kotlin/motif/intellij/hierarchy/descriptor/ScopeHierarchyUsageSinksSectionDescriptor.kt b/intellij/src/main/kotlin/motif/intellij/hierarchy/descriptor/ScopeHierarchyUsageSinksSectionDescriptor.kt index d55130ef..8d5f74d8 100644 --- a/intellij/src/main/kotlin/motif/intellij/hierarchy/descriptor/ScopeHierarchyUsageSinksSectionDescriptor.kt +++ b/intellij/src/main/kotlin/motif/intellij/hierarchy/descriptor/ScopeHierarchyUsageSinksSectionDescriptor.kt @@ -29,7 +29,7 @@ open class ScopeHierarchyUsageSinksSectionDescriptor( private val nonNullProject: Project, graph: ResolvedGraph, parentDescriptor: HierarchyNodeDescriptor?, - val clazz: PsiClass + val clazz: PsiClass, ) : ScopeHierarchyNodeDescriptor(nonNullProject, graph, parentDescriptor, clazz, false) { override fun updateText(text: CompositeAppearance) { @@ -39,7 +39,5 @@ open class ScopeHierarchyUsageSinksSectionDescriptor( text.ending.addText(" " + getUsageString(count), getPackageNameAttributes()) } - override fun getIcon(element: PsiElement): Icon? { - return null - } + override fun getIcon(element: PsiElement): Icon? = null } diff --git a/intellij/src/main/kotlin/motif/intellij/hierarchy/descriptor/ScopeHierarchyUsageSourcesSectionDescriptor.kt b/intellij/src/main/kotlin/motif/intellij/hierarchy/descriptor/ScopeHierarchyUsageSourcesSectionDescriptor.kt index 46222828..3c131060 100644 --- a/intellij/src/main/kotlin/motif/intellij/hierarchy/descriptor/ScopeHierarchyUsageSourcesSectionDescriptor.kt +++ b/intellij/src/main/kotlin/motif/intellij/hierarchy/descriptor/ScopeHierarchyUsageSourcesSectionDescriptor.kt @@ -29,7 +29,7 @@ open class ScopeHierarchyUsageSourcesSectionDescriptor( private val nonNullProject: Project, graph: ResolvedGraph, parentDescriptor: HierarchyNodeDescriptor?, - val clazz: PsiClass + val clazz: PsiClass, ) : ScopeHierarchyNodeDescriptor(nonNullProject, graph, parentDescriptor, clazz, false) { override fun updateText(text: CompositeAppearance) { @@ -39,7 +39,5 @@ open class ScopeHierarchyUsageSourcesSectionDescriptor( text.ending.addText(" " + getUsageString(count), getPackageNameAttributes()) } - override fun getIcon(element: PsiElement): Icon? { - return null - } + override fun getIcon(element: PsiElement): Icon? = null } diff --git a/intellij/src/main/kotlin/motif/intellij/provider/ScopeHierarchyLineMarkerProvider.kt b/intellij/src/main/kotlin/motif/intellij/provider/ScopeHierarchyLineMarkerProvider.kt index 212c2a83..2deef999 100644 --- a/intellij/src/main/kotlin/motif/intellij/provider/ScopeHierarchyLineMarkerProvider.kt +++ b/intellij/src/main/kotlin/motif/intellij/provider/ScopeHierarchyLineMarkerProvider.kt @@ -73,7 +73,8 @@ class ScopeHierarchyLineMarkerProvider : LineMarkerProvider, MotifService.Listen UPDATE_ALL, ConstantFunction(LABEL_ANCESTORS_SCOPE), ScopeHierarchyHandler(element.project), - LEFT) + LEFT, + ) } private class ScopeHierarchyHandler(val project: Project) : diff --git a/intellij/src/main/kotlin/motif/intellij/provider/ScopeNavigationLineMarkerProvider.kt b/intellij/src/main/kotlin/motif/intellij/provider/ScopeNavigationLineMarkerProvider.kt index b50984d7..ffc4b324 100644 --- a/intellij/src/main/kotlin/motif/intellij/provider/ScopeNavigationLineMarkerProvider.kt +++ b/intellij/src/main/kotlin/motif/intellij/provider/ScopeNavigationLineMarkerProvider.kt @@ -84,7 +84,8 @@ class ScopeNavigationLineMarkerProvider : LineMarkerProvider, MotifService.Liste UPDATE_ALL, ConstantFunction(LABEL_NAVIGATE_PARENT_SCOPE), NavigationScopeHandler(element.project, graph), - LEFT) + LEFT, + ) } } else { val methodElement = element.toPsiMethod() @@ -96,7 +97,8 @@ class ScopeNavigationLineMarkerProvider : LineMarkerProvider, MotifService.Liste UPDATE_ALL, ConstantFunction(LABEL_NAVIGATE_CHILD_SCOPE), NavigationScopeHandler(element.project, graph), - LEFT) + LEFT, + ) } } return null @@ -123,19 +125,21 @@ class ScopeNavigationLineMarkerProvider : LineMarkerProvider, MotifService.Liste .createListPopup( object : BaseListPopupStep( - "Select Parent Scope", scopeEdges.toMutableList()) { - override fun getTextFor(value: ScopeEdge): String { - return value.parent.clazz.simpleName - } + "Select Parent Scope", + scopeEdges.toMutableList(), + ) { + override fun getTextFor(value: ScopeEdge): String = + value.parent.clazz.simpleName override fun onChosen( selectedValue: ScopeEdge?, - finalChoice: Boolean + finalChoice: Boolean, ): PopupStep<*>? { selectedValue?.let { navigateToParent(it) } return super.onChosen(selectedValue, finalChoice) } - }) + }, + ) listPopup.show(RelativePoint(mouseEvent)) } } diff --git a/intellij/src/main/kotlin/motif/intellij/ui/MotifErrorPanel.kt b/intellij/src/main/kotlin/motif/intellij/ui/MotifErrorPanel.kt index 58770d64..c775789d 100644 --- a/intellij/src/main/kotlin/motif/intellij/ui/MotifErrorPanel.kt +++ b/intellij/src/main/kotlin/motif/intellij/ui/MotifErrorPanel.kt @@ -62,7 +62,7 @@ class MotifErrorPanel(project: Project, graph: ResolvedGraph) : override fun onSelectedErrorChanged( element: PsiElement, error: MotifError, - errorMessage: ErrorMessage + errorMessage: ErrorMessage, ) { errorDetails.text = errorMessage.text } diff --git a/intellij/src/main/kotlin/motif/intellij/ui/MotifScopePanel.kt b/intellij/src/main/kotlin/motif/intellij/ui/MotifScopePanel.kt index ff443477..575d2d83 100644 --- a/intellij/src/main/kotlin/motif/intellij/ui/MotifScopePanel.kt +++ b/intellij/src/main/kotlin/motif/intellij/ui/MotifScopePanel.kt @@ -51,7 +51,11 @@ class MotifScopePanel(val project: Project, initialGraph: ResolvedGraph) : consumeAndProvideBrowser = buildPropertyHierarchyBrowser( - project, graph, rootElement, PropertyHierarchyType.CONSUME_AND_PROVIDE) + project, + graph, + rootElement, + PropertyHierarchyType.CONSUME_AND_PROVIDE, + ) tabs = JBTabbedPane() splitPane = JSplitPane(JSplitPane.VERTICAL_SPLIT, scopeBrowser, consumeAndProvideBrowser) @@ -79,7 +83,11 @@ class MotifScopePanel(val project: Project, initialGraph: ResolvedGraph) : val previousDividerLocation = splitPane.dividerLocation consumeAndProvideBrowser = buildPropertyHierarchyBrowser( - project, graph, element, PropertyHierarchyType.CONSUME_AND_PROVIDE) + project, + graph, + element, + PropertyHierarchyType.CONSUME_AND_PROVIDE, + ) splitPane.add(consumeAndProvideBrowser, RIGHT) splitPane.dividerLocation = previousDividerLocation } @@ -88,7 +96,7 @@ class MotifScopePanel(val project: Project, initialGraph: ResolvedGraph) : project: Project, graph: ResolvedGraph, rootElement: PsiElement, - type: PropertyHierarchyType + type: PropertyHierarchyType, ): ScopePropertyHierarchyBrowser { val propertyBrowser = ScopePropertyHierarchyBrowser(project, graph, rootElement, type) propertyBrowser.changeView(ScopePropertyHierarchyBrowser.PROPERTY_HIERARCHY_TYPE) diff --git a/intellij/src/test/kotlin/motif/intellij/TestHarness.kt b/intellij/src/test/kotlin/motif/intellij/TestHarness.kt index 2e0ba1aa..688df156 100644 --- a/intellij/src/test/kotlin/motif/intellij/TestHarness.kt +++ b/intellij/src/test/kotlin/motif/intellij/TestHarness.kt @@ -52,8 +52,7 @@ class TestHarness : LightJavaCodeInsightFixtureTestCase() { private fun addLibrary(clazz: KClass<*>) { val fileUri = - clazz - .java + clazz.java .getResource(clazz.simpleName + ".class") ?.toString() ?.let { Regex("file:.*[.]jar").find(it)?.value } @@ -69,13 +68,15 @@ class TestHarness : LightJavaCodeInsightFixtureTestCase() { fun test() { val testFiles = testDir.walk() val externalFiles = EXTERNAL_ROOT.resolve(testDir.name).walk() - (testFiles + externalFiles).filter { !it.isDirectory }.forEach { sourceFile -> - when { - sourceFile.name.endsWith(".java") -> myFixture.addClass(sourceFile.readText()) - sourceFile.name.endsWith(".kt") -> - myFixture.addFileToProject(sourceFile.name, sourceFile.readText()) - } - } + (testFiles + externalFiles) + .filter { !it.isDirectory } + .forEach { sourceFile -> + when { + sourceFile.name.endsWith(".java") -> myFixture.addClass(sourceFile.readText()) + sourceFile.name.endsWith(".kt") -> + myFixture.addFileToProject(sourceFile.name, sourceFile.readText()) + } + } val graph = GraphFactory(project).compute() val errorFile = testDir.resolve("ERROR.txt") @@ -150,9 +151,9 @@ class TestHarness : LightJavaCodeInsightFixtureTestCase() { @JvmStatic fun data(clazz: Class<*>): List> { val testDirs = TEST_CASE_ROOT.listFiles() ?: throw IllegalStateException() - return testDirs.filter { !it.resolve("SKIP_INTELLIJ").exists() }.map { testDir -> - arrayOf(testDir) - } + return testDirs + .filter { !it.resolve("SKIP_INTELLIJ").exists() } + .map { testDir -> arrayOf(testDir) } } @org.junit.runners.Parameterized.Parameters diff --git a/models/src/main/kotlin/motif/models/Dependencies.kt b/models/src/main/kotlin/motif/models/Dependencies.kt index 88c118fa..d20d6627 100644 --- a/models/src/main/kotlin/motif/models/Dependencies.kt +++ b/models/src/main/kotlin/motif/models/Dependencies.kt @@ -62,11 +62,13 @@ class Dependencies(val clazz: IrClass, val scope: Scope) { return clazz } - clazz.supertypes.mapNotNull { it.resolveClass() }.forEach { superinterface -> - findCreatableSuperinterface(superinterface)?.let { - return it - } - } + clazz.supertypes + .mapNotNull { it.resolveClass() } + .forEach { superinterface -> + findCreatableSuperinterface(superinterface)?.let { + return it + } + } return null } diff --git a/models/src/main/kotlin/motif/models/FactoryMethod.kt b/models/src/main/kotlin/motif/models/FactoryMethod.kt index 567a0cea..4ef69ca4 100644 --- a/models/src/main/kotlin/motif/models/FactoryMethod.kt +++ b/models/src/main/kotlin/motif/models/FactoryMethod.kt @@ -49,18 +49,17 @@ sealed class FactoryMethod(val method: IrMethod, val objects: Objects) { val name = method.name val qualifiedName: String by lazy { "${objects.qualifiedName}.${method.name}" } - protected fun getParameters(owner: IrClass, method: IrMethod): List { - return method.parameters.map { parameter -> - Parameter(owner, method, parameter, this, Type.fromParameter(parameter)) - } - } + protected fun getParameters(owner: IrClass, method: IrMethod): List = + method.parameters.map { parameter -> + Parameter(owner, method, parameter, this, Type.fromParameter(parameter)) + } class Parameter( val owner: IrClass, val method: IrMethod, val parameter: IrParameter, val factoryMethod: FactoryMethod, - val type: Type + val type: Type, ) { val qualifiedName: String by lazy { type.qualifiedName } @@ -75,8 +74,9 @@ sealed class FactoryMethod(val method: IrMethod, val objects: Objects) { fun fromObjectsMethod(objects: Objects, method: IrMethod): FactoryMethod { if (method.isVoid()) throw VoidFactoryMethod(objects, method) - if (method.isNullable() || method.returnType.toString().endsWith("?")) - throw NullableFactoryMethod(objects, method) + if (method.isNullable() || method.returnType.toString().endsWith("?")) { + throw NullableFactoryMethod(objects, method) + } ensureNonNullParameters(objects.scope, objects.clazz, method) @@ -98,9 +98,8 @@ class BasicFactoryMethod private constructor(objects: Objects, method: IrMethod) companion object { - fun create(objects: Objects, method: IrMethod): BasicFactoryMethod { - return BasicFactoryMethod(objects, method) - } + fun create(objects: Objects, method: IrMethod): BasicFactoryMethod = + BasicFactoryMethod(objects, method) } } @@ -140,9 +139,8 @@ class ConstructorFactoryMethod private constructor(objects: Objects, method: IrM companion object { - fun create(objects: Objects, method: IrMethod): ConstructorFactoryMethod { - return ConstructorFactoryMethod(objects, method) - } + fun create(objects: Objects, method: IrMethod): ConstructorFactoryMethod = + ConstructorFactoryMethod(objects, method) } } @@ -174,8 +172,9 @@ private fun ensureNonNullParameter( scope: Scope, owner: IrClass, method: IrMethod, - parameter: IrParameter + parameter: IrParameter, ) { - if (parameter.isNullable() || parameter.type.toString().endsWith("?")) - throw NullableParameter(scope, owner, method, parameter) + if (parameter.isNullable() || parameter.type.toString().endsWith("?")) { + throw NullableParameter(scope, owner, method, parameter) + } } diff --git a/models/src/main/kotlin/motif/models/Objects.kt b/models/src/main/kotlin/motif/models/Objects.kt index e64a9970..1d30f892 100644 --- a/models/src/main/kotlin/motif/models/Objects.kt +++ b/models/src/main/kotlin/motif/models/Objects.kt @@ -32,8 +32,9 @@ class Objects private constructor(val clazz: IrClass, val scope: Scope) { val objectsClass = scope.clazz.annotatedInnerClass(motif.Objects::class) ?: return null if (objectsClass.fields.any { !it.isStatic() }) throw ObjectsFieldFound(scope, objectsClass) - if (objectsClass.hasNonDefaultConstructor()) - throw ObjectsConstructorFound(scope, objectsClass) + if (objectsClass.hasNonDefaultConstructor()) { + throw ObjectsConstructorFound(scope, objectsClass) + } return Objects(objectsClass, scope) } diff --git a/models/src/main/kotlin/motif/models/ParsingError.kt b/models/src/main/kotlin/motif/models/ParsingError.kt index 2ebf2190..130e0737 100644 --- a/models/src/main/kotlin/motif/models/ParsingError.kt +++ b/models/src/main/kotlin/motif/models/ParsingError.kt @@ -42,13 +42,13 @@ class NullableParameter( val scope: Scope, val owner: IrClass, val method: IrMethod, - val parameter: IrParameter + val parameter: IrParameter, ) : ParsingError() class NullableDynamicDependency( val scope: Scope, val method: IrMethod, - val parameter: IrParameter + val parameter: IrParameter, ) : ParsingError() class InvalidFactoryMethod(val objects: Objects, val method: IrMethod) : ParsingError() @@ -66,26 +66,26 @@ class NotAssignableBindsMethod( val objects: Objects, val method: IrMethod, val returnType: IrType, - val parameterType: IrType + val parameterType: IrType, ) : ParsingError() class VoidDependenciesMethod( val scope: Scope, val dependenciesClass: IrClass, - val method: IrMethod + val method: IrMethod, ) : ParsingError() class DependencyMethodWithParameters( val scope: Scope, val dependenciesClass: IrClass, - val method: IrMethod + val method: IrMethod, ) : ParsingError() class NullableSpreadMethod( val objects: Objects, val factoryMethod: IrMethod, val spreadClass: IrClass, - val spreadMethod: IrMethod + val spreadMethod: IrMethod, ) : ParsingError() class InvalidQualifier(val annotated: IrAnnotated, val annotation: IrAnnotation) : ParsingError() @@ -93,12 +93,12 @@ class InvalidQualifier(val annotated: IrAnnotated, val annotation: IrAnnotation) class DuplicatedChildParameterSource( val scope: Scope, val childScopeMethod: ChildMethod, - val duplicatedParameters: List + val duplicatedParameters: List, ) : ParsingError() class DuplicatedDependenciesMethod( val scope: Scope, - val duplicatedMethods: List + val duplicatedMethods: List, ) : ParsingError() class ScopeExtendsScope(val scope: Scope) : ParsingError() diff --git a/models/src/main/kotlin/motif/models/Scope.kt b/models/src/main/kotlin/motif/models/Scope.kt index c2eaaa88..b4cf68a5 100644 --- a/models/src/main/kotlin/motif/models/Scope.kt +++ b/models/src/main/kotlin/motif/models/Scope.kt @@ -33,9 +33,7 @@ sealed class Scope(val clazz: IrClass) { companion object { - fun fromClasses(scopeClasses: List): List { - return ScopeFactory(scopeClasses).create() - } + fun fromClasses(scopeClasses: List): List = ScopeFactory(scopeClasses).create() } } diff --git a/models/src/main/kotlin/motif/models/ScopeMethod.kt b/models/src/main/kotlin/motif/models/ScopeMethod.kt index b237d332..5199416b 100644 --- a/models/src/main/kotlin/motif/models/ScopeMethod.kt +++ b/models/src/main/kotlin/motif/models/ScopeMethod.kt @@ -40,9 +40,11 @@ sealed class ScopeMethod { } if (returnClass != null && returnClass.hasAnnotation(motif.Scope::class)) { - method.parameters.find { it.isNullable() }?.let { nullableParameter -> - throw NullableDynamicDependency(scope, method, nullableParameter) - } + method.parameters + .find { it.isNullable() } + ?.let { nullableParameter -> + throw NullableDynamicDependency(scope, method, nullableParameter) + } val childMethod = ChildMethod(method, scope, returnClass) val duplicatedParameterTypes = childMethod.parameters - childMethod.parameters.distinctBy { it.type } diff --git a/models/src/main/kotlin/motif/models/Spread.kt b/models/src/main/kotlin/motif/models/Spread.kt index ee148221..b2ce7d1c 100644 --- a/models/src/main/kotlin/motif/models/Spread.kt +++ b/models/src/main/kotlin/motif/models/Spread.kt @@ -25,8 +25,7 @@ class Spread(val clazz: IrClass, val factoryMethod: FactoryMethod) { val qualifiedName: String by lazy { clazz.qualifiedName } val methods: List = - clazz - .methods + clazz.methods .filter { method -> isSpreadMethod(method) } .onEach { method -> if (method.isNullable()) { @@ -44,8 +43,7 @@ class Spread(val clazz: IrClass, val factoryMethod: FactoryMethod) { companion object { - private fun isSpreadMethod(method: IrMethod): Boolean { - return !method.isVoid() && method.isPublic() && !method.hasParameters() - } + private fun isSpreadMethod(method: IrMethod): Boolean = + !method.isVoid() && method.isPublic() && !method.hasParameters() } } diff --git a/models/src/main/kotlin/motif/models/Type.kt b/models/src/main/kotlin/motif/models/Type.kt index 5c39d12b..c81d26d9 100644 --- a/models/src/main/kotlin/motif/models/Type.kt +++ b/models/src/main/kotlin/motif/models/Type.kt @@ -39,9 +39,7 @@ data class Type(val type: IrType, val qualifier: IrAnnotation?) : Comparable val annotationClass: IrClass = annotation.type?.resolveClass() ?: return@find false annotationClass.hasAnnotation(Qualifier::class) - } - ?: return null + } ?: return null val members = qualifier.members if (members.size > 1) { diff --git a/models/src/test/kotlin/motif/models/motif/BaseTest.kt b/models/src/test/kotlin/motif/models/motif/BaseTest.kt index be7789d1..3315ab5f 100644 --- a/models/src/test/kotlin/motif/models/motif/BaseTest.kt +++ b/models/src/test/kotlin/motif/models/motif/BaseTest.kt @@ -71,12 +71,8 @@ abstract class BaseTest { return true } - override fun getSupportedSourceVersion(): SourceVersion { - return SourceVersion.latestSupported() - } + override fun getSupportedSourceVersion(): SourceVersion = SourceVersion.latestSupported() - override fun getSupportedAnnotationTypes(): Set { - return setOf(motif.Scope::class.java.name) - } + override fun getSupportedAnnotationTypes(): Set = setOf(motif.Scope::class.java.name) } } diff --git a/models/src/test/kotlin/motif/models/motif/ModelsSmokeTest.kt b/models/src/test/kotlin/motif/models/motif/ModelsSmokeTest.kt index 31f3358c..0f750f84 100644 --- a/models/src/test/kotlin/motif/models/motif/ModelsSmokeTest.kt +++ b/models/src/test/kotlin/motif/models/motif/ModelsSmokeTest.kt @@ -22,15 +22,16 @@ import org.junit.Test * Smoke test for :models. * * There are a couple reasons why the tests in this module should remain minimal: - * * 1. Running the integration tests in the :tests module should give us full confidence that our - * implementation is + * implementation is + * * ``` * correct. We should not rely on ModelsSmokeTest for validating correctness. Full coverage in this module * would likely result in missing coverage in :tests. * ``` * 2. Full coverage in this module would couple us to a specific implementation. We want it to be - * possible to + * possible to + * * ``` * safely rewrite the compiler with minimal changes to our test suite. * ``` @@ -46,7 +47,9 @@ class ModelsSmokeTest : BaseTest() { @motif.Scope interface FooScope {} - """.trimIndent()) + """ + .trimIndent(), + ) val scopes = getScopes() @@ -71,7 +74,9 @@ class ModelsSmokeTest : BaseTest() { @motif.Objects class Objects {} } - """.trimIndent()) + """ + .trimIndent(), + ) val scope = getScopes()[0] @@ -95,7 +100,9 @@ class ModelsSmokeTest : BaseTest() { } } } - """.trimIndent()) + """ + .trimIndent(), + ) val factoryMethods = getScopes()[0].factoryMethods @@ -119,7 +126,9 @@ class ModelsSmokeTest : BaseTest() { class Foo { Foo(int i) {} } - """.trimIndent()) + """ + .trimIndent(), + ) addClass( "test.FooScope", """ @@ -133,7 +142,9 @@ class ModelsSmokeTest : BaseTest() { abstract Foo foo(); } } - """.trimIndent()) + """ + .trimIndent(), + ) val factoryMethod = getScopes()[0].factoryMethods[0] @@ -150,7 +161,9 @@ class ModelsSmokeTest : BaseTest() { package test; class Foo {} - """.trimIndent()) + """ + .trimIndent(), + ) addClass( "test.Bar", @@ -158,7 +171,9 @@ class ModelsSmokeTest : BaseTest() { package test; class Bar extends Foo {} - """.trimIndent()) + """ + .trimIndent(), + ) addClass( "test.FooScope", """ @@ -172,7 +187,9 @@ class ModelsSmokeTest : BaseTest() { abstract Foo bar(Bar bar); } } - """.trimIndent()) + """ + .trimIndent(), + ) val factoryMethod = getScopes()[0].factoryMethods[0] @@ -195,7 +212,9 @@ class ModelsSmokeTest : BaseTest() { return ""; } } - """.trimIndent()) + """ + .trimIndent(), + ) addClass( "test.FooScope", """ @@ -211,7 +230,9 @@ class ModelsSmokeTest : BaseTest() { abstract Foo foo(); } } - """.trimIndent()) + """ + .trimIndent(), + ) val factoryMethod = getScopes()[0].factoryMethods[0] @@ -235,7 +256,9 @@ class ModelsSmokeTest : BaseTest() { interface FooScope { String string(); } - """.trimIndent()) + """ + .trimIndent(), + ) val scope = getScopes()[0] @@ -258,7 +281,9 @@ class ModelsSmokeTest : BaseTest() { interface FooScope { BarScope bar(String string); } - """.trimIndent()) + """ + .trimIndent(), + ) addClass( "test.BarScope", @@ -267,7 +292,9 @@ class ModelsSmokeTest : BaseTest() { @motif.Scope interface BarScope {} - """.trimIndent()) + """ + .trimIndent(), + ) // getScopes is alphabetically sorted so FooScope is last val fooScope = getScopes()[1] @@ -296,7 +323,9 @@ class ModelsSmokeTest : BaseTest() { String string(); } } - """.trimIndent()) + """ + .trimIndent(), + ) val scope = getScopes()[0] diff --git a/samples/sample-kotlin-ksp/src/main/java/motif/sample/Greeter.kt b/samples/sample-kotlin-ksp/src/main/java/motif/sample/Greeter.kt index 28b5673f..82906eb9 100644 --- a/samples/sample-kotlin-ksp/src/main/java/motif/sample/Greeter.kt +++ b/samples/sample-kotlin-ksp/src/main/java/motif/sample/Greeter.kt @@ -17,7 +17,5 @@ package motif.sample class Greeter(private val name: String) { - fun greet(): String { - return "Hello $name!" - } + fun greet(): String = "Hello $name!" } diff --git a/samples/sample-kotlin/src/main/java/motif/sample/Greeter.kt b/samples/sample-kotlin/src/main/java/motif/sample/Greeter.kt index de8f41dd..d9d0cd09 100644 --- a/samples/sample-kotlin/src/main/java/motif/sample/Greeter.kt +++ b/samples/sample-kotlin/src/main/java/motif/sample/Greeter.kt @@ -17,7 +17,5 @@ package motif.sample class Greeter(private val name: String) { - fun greet(): String { - return "Hello $name!" - } + fun greet(): String = "Hello $name!" } diff --git a/tests/compiler/src/main/java/motif/stubcompiler/StubProcessor.kt b/tests/compiler/src/main/java/motif/stubcompiler/StubProcessor.kt index e7acbf11..fed0c43f 100644 --- a/tests/compiler/src/main/java/motif/stubcompiler/StubProcessor.kt +++ b/tests/compiler/src/main/java/motif/stubcompiler/StubProcessor.kt @@ -43,21 +43,20 @@ class StubProcessor : AbstractProcessor() { private val env: ProcessingEnvironment by lazy { processingEnv } - override fun getSupportedSourceVersion(): SourceVersion { - return SourceVersion.latestSupported() - } + override fun getSupportedSourceVersion(): SourceVersion = SourceVersion.latestSupported() - override fun getSupportedAnnotationTypes(): Set { - return Collections.singleton(Scope::class.java.name) - } + override fun getSupportedAnnotationTypes(): Set = + Collections.singleton(Scope::class.java.name) override fun process(annotations: Set, roundEnv: RoundEnvironment): Boolean { - roundEnv.getElementsAnnotatedWith(Scope::class.java).map { it as TypeElement }.forEach { - scopeElement -> - val packageName: String = MoreElements.getPackage(scopeElement).qualifiedName.toString() - val spec: TypeSpec = spec(scopeElement.asType() as DeclaredType) ?: return@forEach - JavaFile.builder(packageName, spec).build().writeTo(processingEnv.filer) - } + roundEnv + .getElementsAnnotatedWith(Scope::class.java) + .map { it as TypeElement } + .forEach { scopeElement -> + val packageName: String = MoreElements.getPackage(scopeElement).qualifiedName.toString() + val spec: TypeSpec = spec(scopeElement.asType() as DeclaredType) ?: return@forEach + JavaFile.builder(packageName, spec).build().writeTo(processingEnv.filer) + } return true } @@ -76,7 +75,8 @@ class StubProcessor : AbstractProcessor() { builder.addMethod( MethodSpec.constructorBuilder() .addParameter(TypeName.get(dependenciesType), "dependencies") - .build()) + .build(), + ) } if (scopeType.asElement().kind == ElementKind.INTERFACE) { @@ -103,8 +103,9 @@ class StubProcessor : AbstractProcessor() { private fun dependenciesType(scopeType: DeclaredType): DeclaredType? { val scopeElement = (scopeType.asElement() as? TypeElement) ?: return null val superInterface = scopeElement.interfaces.firstOrNull() as? DeclaredType ?: return null - if (Creatable::class.java.simpleName !in superInterface.asElement().simpleName.toString()) - return null + if (Creatable::class.java.simpleName !in superInterface.asElement().simpleName.toString()) { + return null + } return superInterface.typeArguments.singleOrNull() as? DeclaredType ?: return null } @@ -114,7 +115,6 @@ class StubProcessor : AbstractProcessor() { return ClassName.get(scopeClassName.packageName(), "${prefix}Impl") } - private fun ClassName.qualifiedName(): String { - return "${packageName()}.${simpleNames().joinToString(".")}" - } + private fun ClassName.qualifiedName(): String = + "${packageName()}.${simpleNames().joinToString(".")}" } diff --git a/viewmodel/src/main/kotlin/motif/viewmodel/GraphViewModel.kt b/viewmodel/src/main/kotlin/motif/viewmodel/GraphViewModel.kt index 521bc3ea..13a436ed 100644 --- a/viewmodel/src/main/kotlin/motif/viewmodel/GraphViewModel.kt +++ b/viewmodel/src/main/kotlin/motif/viewmodel/GraphViewModel.kt @@ -25,9 +25,7 @@ class GraphViewModel(val rootScopes: List) { companion object { - fun create(graph: ResolvedGraph): GraphViewModel { - return GraphViewModelFactory(graph).create() - } + fun create(graph: ResolvedGraph): GraphViewModel = GraphViewModelFactory(graph).create() } } @@ -40,16 +38,15 @@ private class GraphViewModelFactory(private val graph: ResolvedGraph) { return GraphViewModel(rootScopes) } - private fun getScopeViewModel(scope: Scope): ScopeViewModel { - return scopeViewModels[scope] - ?: createScopeViewModel(scope).apply { scopeViewModels[scope] = this } - } + private fun getScopeViewModel(scope: Scope): ScopeViewModel = + scopeViewModels[scope] ?: createScopeViewModel(scope).apply { scopeViewModels[scope] = this } private fun createScopeViewModel(scope: Scope): ScopeViewModel { val children = - graph.getChildEdges(scope).map { edge -> getScopeViewModel(edge.child) }.sortedBy { - it.scope.qualifiedName - } + graph + .getChildEdges(scope) + .map { edge -> getScopeViewModel(edge.child) } + .sortedBy { it.scope.qualifiedName } val providedDependencies = graph .getSources(scope) @@ -83,7 +80,8 @@ private class GraphViewModelFactory(private val graph: ResolvedGraph) { sources = graph.getProviders(sink) if (prevSources != null && sources != prevSources) { throw IllegalStateException( - "Inconsistent sources for sinks of the same type: $scope, $type") + "Inconsistent sources for sinks of the same type: $scope, $type", + ) } } diff --git a/viewmodel/src/main/kotlin/motif/viewmodel/ProvidedDependency.kt b/viewmodel/src/main/kotlin/motif/viewmodel/ProvidedDependency.kt index 1697fdf1..c1cab715 100644 --- a/viewmodel/src/main/kotlin/motif/viewmodel/ProvidedDependency.kt +++ b/viewmodel/src/main/kotlin/motif/viewmodel/ProvidedDependency.kt @@ -21,5 +21,5 @@ import motif.models.Source class ProvidedDependency( val source: Source, val consumedBy: List, - val requiredDependencies: List + val requiredDependencies: List, ) diff --git a/viewmodel/src/main/kotlin/motif/viewmodel/ScopeViewModel.kt b/viewmodel/src/main/kotlin/motif/viewmodel/ScopeViewModel.kt index de479274..fd2c7e80 100644 --- a/viewmodel/src/main/kotlin/motif/viewmodel/ScopeViewModel.kt +++ b/viewmodel/src/main/kotlin/motif/viewmodel/ScopeViewModel.kt @@ -21,5 +21,5 @@ class ScopeViewModel( val scope: Scope, val children: List, val providedDependencies: List, - val requiredDependencies: List + val requiredDependencies: List, ) diff --git a/viewmodel/src/main/kotlin/motif/viewmodel/TestRenderer.kt b/viewmodel/src/main/kotlin/motif/viewmodel/TestRenderer.kt index da05ed22..66040354 100644 --- a/viewmodel/src/main/kotlin/motif/viewmodel/TestRenderer.kt +++ b/viewmodel/src/main/kotlin/motif/viewmodel/TestRenderer.kt @@ -54,7 +54,7 @@ object TestRenderer { private fun StringBuilder.renderRequired( indent: Int, requiredDependencies: List, - topLevel: Boolean = true + topLevel: Boolean = true, ) { var header = "Required" header = if (topLevel) "==== $header ====" else "[ $header ]" @@ -67,7 +67,7 @@ object TestRenderer { private fun StringBuilder.renderProvided( indent: Int, - providedDependencies: List + providedDependencies: List, ) { appendLine(indent, "==== Provides ====") appendLine() @@ -79,7 +79,7 @@ object TestRenderer { private fun StringBuilder.renderRequired( indent: Int, requiredDependency: RequiredDependency, - topLevel: Boolean + topLevel: Boolean, ) { var header = requiredDependency.type.simpleName.toJvmSimpleName() header = if (topLevel) "---- $header ----" else header @@ -140,11 +140,10 @@ object TestRenderer { } /** HACK: Map kotlin types to Java for graph validation (issue when KSP processes Java sources) */ -private fun String.toJvmSimpleName(): String { - return when (this) { - "Int" -> "int" - "Boolean" -> "boolean" - "Byte" -> "byte" - else -> this - } -} +private fun String.toJvmSimpleName(): String = + when (this) { + "Int" -> "int" + "Boolean" -> "boolean" + "Byte" -> "byte" + else -> this + } From 6f47cbfbe9f0e94b1cdcf4417cad356d179c692b Mon Sep 17 00:00:00 2001 From: James Barr Date: Wed, 12 Feb 2025 15:22:24 -0800 Subject: [PATCH 52/56] Cast to fix nullability compile issue --- intellij/src/main/kotlin/motif/intellij/ScopeHierarchyUtils.kt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/intellij/src/main/kotlin/motif/intellij/ScopeHierarchyUtils.kt b/intellij/src/main/kotlin/motif/intellij/ScopeHierarchyUtils.kt index 3ff0e620..b16839a0 100644 --- a/intellij/src/main/kotlin/motif/intellij/ScopeHierarchyUtils.kt +++ b/intellij/src/main/kotlin/motif/intellij/ScopeHierarchyUtils.kt @@ -103,7 +103,7 @@ object ScopeHierarchyUtils { val type: IrType = IntelliJType(project, scopeType) val scope: Scope? = graph.getScope(type) return if (scope != null) { - Iterables.toArray(graph.getParentEdges(scope), ScopeEdge::class.java) + Iterables.toArray(graph.getParentEdges(scope), ScopeEdge::class.java) as Array? } else { null } From bb3b37996a288d1c722021dd203c6f751fe06db0 Mon Sep 17 00:00:00 2001 From: James Barr Date: Fri, 14 Feb 2025 02:11:12 -0800 Subject: [PATCH 53/56] Delete accidental file --- kls_database.db | Bin 61440 -> 0 bytes 1 file changed, 0 insertions(+), 0 deletions(-) delete mode 100644 kls_database.db diff --git a/kls_database.db b/kls_database.db deleted file mode 100644 index 17f2914772b88ff39873092402df49514eb674f3..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 61440 zcmeI5Ym6M%mEU__91e%Wu`OvOTe3BjC0Vl6-SvLRmL-a&B$^T>QIfT?y{2zf-5U0= zr+d^7KJ?ro6JQZ+J}edqjO-)H2M77EK!9WsFOUyTg2YHRPJnnf>tK-}4x9&+Y#zog z93b!Ct?KUS>gnlWlcF?S)Ib_Ghf{UWJ@?#m&+~s@e(AYdN3O-q)~4vJnWc}FW@buH zuC0|yr3L<9<^TTIJRj8m{jZt+hY5c!lq&ImTHzNK4*&bo>V?(&k9>3GFY~eZDmYMZ zpx{8kfr0}C2MP`p94I(YaG>D8&EY`eE-c=8^5jfX>xiH(pX%1?(aT}0w$(Xa7wz_o zqI2%J2+zqAjZW+GH9NRj^@dKUUozzIwIxzfWX{O=f_VX_dC}*k6I(FcO%)(Xl<`O^}-9!oj7)Sz~)ES z0woeLbG;y2?OL<3_SDH|Sh;KwUYtE}=Od5Iyq?aX{YD*!`D|Oh(Upx*j{J2lNA<`* zKGYDK@=>0AI9Z%oyt7=MNsguO{4%TvL|gVJH~RP4+*?Qg^;)^mpISPvzJMv;d}j53 zmiVvuDmYMZpx{8kfr0}C2MP`p94I(YaG>Bo!GVGU1qc4rabSLCt~4{hvii46^Q#w2 ztN(fRpRZnA{nbBp(<~-baG>Bo!GVGU1qTWa6dWixP;j8&K*5260|f^@Iu3klZqA<> zU-&S4bbjvS(&Wk#2)}!2{Ns1c&Y81=f7&iYsdc%qT`K zI8bn);6TBFf&&Ey3Jw$;C^%4Xpx{8kfr0}C2R?WX9Gaak9bB0C3p0QHR|D1Le{l8p z)gY^@|7-PUt3O@+qt*Yg`s39bs!KUj7T{kcQSOXm*$_Tv9tY##XG!hc+NasIdF zel{m&|MBd?%!$%(e(=-{zcIQ0o`uqtQ>E&wZTd2*8-ZxGs+IMYi0ZN$s+OI0b+Z|D z>#|)os;Ym3KP!5b#+6F@jjm|P?pF1Dvs14%wwkh2-Vhgr`cTy?x>3=pp5~gG<#>7= z2cGV0wkx&BaHL@vy6x*h;Dn*=d*Qful(TnKXnjc@zZ){&nVL+|h+55Bbg9y6HaDy4 zTe;VA(<*PZnsk@6YmN1)QE@6-S=6`A3C*Y)Qgc1ivLns$EYq-jUBohuLOqOhBd|m) zY~Rs@v+Mid(9ru*`j35Tp>%a&YWfwM*PG4tx~xR>2!k*VOw05=JBWPU8UHfgGW4=^4tIQ# zH7MW697MO%tg3Hn6*ije;d38?mGLVW9iM6`tc7jv2-xjBL-)UDwh*M+=4@ zRl-p*Qo25I7j%7YYPy=O^~yQ18Mb7*Q|*6%u$F`@vuYW_u%pm4bl)=kSd&T~G|kat zSBHm|AHZ=A95#yDp-_W+cyvZo9JC+<;w;+NP+N+l^Wr%T`%58qJRA z&_UH!+;gk3?}pNeWGJLCjlfjPE=|{W{n!f}%Z;I#?FaLAeUaj&n^JxB=b-w;)Km|N z>4wn^Ho|K5$0)T`85v$ABU=|xS*{lh}@}z_M-Wc$%;2{+Q>}1y`!z_B){Q zksF~=F}M=f8d1<)N9VO$re;@7b`5*qmco!;poOOC3D0#+-3%fNd5p|hYPKVV>&05s zd#ap1m9p;K?d7hQDKs@->f$Um zPc;^`Ix`fZ(!)qIYOAV8VXQ~e^bDZ|F>^2@R>QM=n;CdsAVM8o5&G5K!w3ftr^Frp z1jOAvHF4_Tx>Tt(He}eT=Kg{v^<6s>s7_b2G{bfS1UNEuVVHX0I-#%Io{|qQ_Z%cC zX*E9%In(Qbp&cb#t!9hEsv)cC$Fu3@v%`wOKPttNWhxF>f4Kb1ch*`HmI`(e{IosI&ya@XnEiQZl^}v(atT zkjeDBg;`Z)cbk!JYoUfwf@vas-;1$WJY9<%FE(6H3fq%tVf9Q|J(F_i^DA)ZwW&Fz z4oVEc@VsorEgEbuHe2Vby&t6Jl<1T(1?!kmcEzq*raCrFX`;tN4o=;dy3HR#=sG*w zkDR~=Tt6K53Pg}sq{QBH7-GLLHL*h?m?_2VyWuJYf&8WRU^Q^19-40KIA}vX72sx>xi@g^3!ob!L z{_vA!y{A8t$^tZSU{q2))KDP9!m%R|rOK_5w8Bo!GVGU1qTWa6dWixP;j8&K*526 z0|f^P4t(ew2=MEZllk2DrjbRfYMo~5a+PpSbvv9hE_6cP!mk*{NGK%xp^60k1Kk*{~ZNKwN`t<6Y%N~a|n zZFTWryG%W^pb*$GW0Qh>3Me&0r()O_rW;a$Z&(q9JiXtRRJTehb!svytLn^7?SiDl zgO9vO6Cu+sCXsFE=~2$aP|R;Y#46b4Kq<{a9GS^B19P5PT<*^h;#GK1UlWoMqZ$62E)FZ z7w8=dwJkQcXg8{6f0j|Iz2dA|qa$0JGOCFV|Ez?UwxqMIvuQcuSyrNbZSN70C&~RX*_c}zV}{o_z3U%yXqK0%jM&bPI7x)q zCe*QOs!2o-H0gO}sCq;qFLr$Cn0duC*fvAejN3Jda}{b5m#%$iUw3`YXGB^pkYH7} z>=;6Zs;XMoV>2g0gQ3S&D$)^ecn%~dHd&bJ361el$IE};;N>GVPc{UTC!Xhn?WQnS-L@65&rl?JF1e0 zU$a#gozzOA=r%16FPk(|WFOVz$tORDh}-#zkL)gN#j!n-J@0C4Hw2j@8pFGzs?*4H=?RFHa?mu_&}fpPA(6s(2Lm~6 za~tkwNe@*eE#_yTak5U>Lt3t>A@fij*Ng<#{ES(s#9gp4` ze!=Utu53T4_;~7GcHv%S^}Q|JQnmO!#ohC0Q%j2;)T~B7Ir16ic<*)TosMf&;om=@fJkCC3qI(@5HK4rBWL5uf-p1Wn%w%!J1^ zv#b7E)x&NuF#6f!#MCthHq%tCI_!c_Q|*;lPM$zL*gcu(6UC#789|v*>16I;f=V`hiVKwA7QaHkDeY}v%IOE8n|0c z4#H*&DdsHg`+><_Ux%mW)Qj9ZKQC28D?G>9g5;)WbGB1x6;n+{!~|?34rzNbJms9? zOW|12{%7GT6DrXBz=^f=RN+|fZL;)H#o0H%21hPVq-@*t!T9n-OnZ$X4V~5{M>iwO zFljK1&CrbKF3-Eg^%`EKa#G9NF8Ppq+<2X_C+nl!*nu4dL|PDSP!MP}(@aiGrX2w# zKwoBlHMUx;M}8UJ{dvZlBH9zvh8S9!Zn&Ibp^Kqs+6GO)c*dTN$)7Xy>djEpgH{tC zo~^wp8uZhQh(Y(Y>7-AhDQS+xzQ#DlHa60y(<#Yu6j-i9hp$K2z>Pqsz@w$zSlE0f zc!aMq^d!`&-GT7E{VEK3Ya(Ge0Z@nmA-ET|>G%kp$IetOqk-zNBYKe+zTQQmGTLJI z5UHRUJRNxuh-$vV=p&~1h(($kT}E`Mnm#iX`0CQ}P2Y(P&JJA~7QwijIAoWq;<2Y4 zlUX?E^2-c3MU28>XPb2OdoGbTygFg%>@^}LHrA|dJL3i%G?(Uwe*4UHoTkZ?=^2`- z3tiGUNr{ndNZ%Cf!BEq!+|UCDvn?*js1340#_4VS_pz6dz|UU$LIZK&YZf*_Y=ahp zTCoG4ZrDgTIDJkSj30hm-3)pY%R?lko!NbreBnhHGL^III*S@N54^99EJg=^=8>BK&+We`dQ`{2=v9;1mOi4sEbI(eO! z9u9hiHr@U-FP>(&H?Dm+w3@?cn396HYbby^aFFjng+7tNd`#{FN}<_`TH@kha}5Sg zO3$<8bJspHunHRR5I()lejtblLWgTbb_8-sAnd%d8yPu8<>(M;Pc=(_?r%Rgoy^-< z*Ad4FP5zkw(u_pl>I68zvcO)7^V?0dFLPb9xZI?#9S{jbeq^EFI>qQyL___6v1r#< zXg;lwx#iH=S>N4z)+aN5AVAj7~`i>){Y5(8_-)M7Ij*<(cax5k(fPc!BehOAH41PqqI z3OtRhi54PdaGU94Dsr0S6sp?Ma_m%-g%j-Rm22PCAv($nI3#t~1c`(*B`}1gIR^fr z2AooE+`&1rolZf()0^8>&TPnXeDllGEw={rQ3&!0s)QK3ja_96orD(Aeu9^FUW;y% zp|W;00AmzLlGRr$-Q&}-K4kM^F9YFVfqx`PvIL&gY5aEC)?j$$SdeP)ZDScbsXy#n zPciHi`Xq8`J@-Je(8x`KL*T@w#hI@5IewU)-_qMBXPrD{#6|C^`7ju~d5poQFqO0b zY!?lq8S@n-suP`XIaa`^3PLL$$tcyanMbwf8&5LeWbBlj0@JKOmzZV%JJ=$`_QX8) z@#q0vU}uTEWr&Tmu1sat)vP#u1}C#mAlr-AF5CE38cYW40%G<#9CB@&qKeJq`sAPvpWxXCVg?r{KwYUMhPJ_zTc3d=11j-;f;l_>BXwKKU(hbCqCs2Bw&E7^qt7x;iC_Z+UEIloz51qYAY*@>2#(Wm3S9n zIcj4_Fo>8iglD6gflQ*LKsr|bkR6Pgq1L5GT^hi@*k;rzyd@9+2nh^hfWmOifH6ZC zYoP$F({w$1mr>bAD7SVwtSjA{M!GMz7MPhzrJt2!O&A!?V+jThLY}eK=f3&Xec<6Z5Xj;963?`q#X=R(ZunNKJ8L94IZ3!M;s6#T|Ed|Dz+V7*lYBFRjq4%_M&@j(!Qer+gL`%!@JE?X zHmQU_D&%i8VZt=#2G~9pMzr)XurTUO5ZEHZ6^0LnBuk&8BNVM@r?-?GXiPVElbnRf zX$hQ_t;(Q?ub~?;I0(oHs#tPkj-7kouA~TT$gq5Olete36$QYRgr05qmLA(wKw!^% zM1dWNaczO*wl^L5@!NIApTbx5eM|*h2pe!ypcsk8le(dFh@2fRteF?U)JUwU&}H7t zxpbaEr>ONHz9}Ng!QxO5@eGOk3A}Y&)sRpHxs~yg286P6PU%t-gab3Pw86TM97vO7 zJ{FW3Mp$-Kl~DCYYL&EFz>IO)+3&l!P`#luy=vx3c)P~rrwF^+0q(I$ygy{xK9wf; z6|SnZ0OD77^nC1VAbIPxn9Tq{SS#D`eFj`S$LLciSrX)A;%q_#gxdf#bnHOjQ2El8 zWMtxe6n=Yj;sr84@Ehw4JjEurbVIkuV{;&b(FWr^mffWg(ojB3lwb2r6#=S|ZdDp( z;5S{2cg}S$%VE3dWPHUG|K1X<%bA5B+e5WlJ=;Z{+DS?7l(IcWo>*Tpy|I!kN06{r zo^-6)v}d);^wgXWS&7&4X3QS^n5tSXSG$(X1x$S@KiZ@{ZV+E}Jo5K}MX;aRu?P%G z&N=FeEMd8MQ5(qkF7;d(QCT^{l7NakuAK@@CY%LoN)B=w}dc+!78Y<2hc* zZCe#(d5NebmA8#fx)FvBndIlb1ufNyv`lm>w?`R5^}|b0>25=h$#Y}tsQ`n5+QTNp zspOo%OhQXiV5$-E8G4Xi+D~`icNW5?_hAOfu|enrOvZk;GqdoNmz8G72!WWEPgqm> zXwVqcbD#7#kphFvtc*#@n-WCQ(dU()m6<0=>6;Ka#hF1p3l;(~fq=wekowmu$Qc+0 zl#r;)t>pH&gWyjZp2+1(-u?yl&lG1y%$cP?UP(Pu0|XK@HO5dv!EX%2s++gewkg<7 z+~h`A{{N?y|9|et_mAAQk{tfy!!IrWr94kj3Fs86NS1x*%IDO28T-| zxrE|EE$l%?_x>{M_nz#Z$VPaZXZ`3K1%qF21Dhc+5 zZs(HNu)Z=m2Rv@7x!u|en_cP! zzAlwFWru__f%}aMo0OXpN2!8mP2CqL&G?G0;R=`PWFOC!kQtTBU^ffG^!Tk~-$Bu7 zFBX&BpD4`hQ`faNgBrEWSV`-;`lPZhX>Ax3`Wz5`fMHKn8Ua(ftLQ9pfX}6lN#~vo zSC>K#*M{}qff%ZHq%!naqTsHlSK{Ls+Yc!A*OaRR2se-t=1P}dY|`~qrkac?wI5JU z>YDBm;MPg8C~pmegfhp_?30~#M5yTN(5s-nAE!*LM4@3%js=FH_-(un@>EjIm{^V|hGRgz&;V@0m=pG{4()fFNXmpEK& zgRMvo7}HQEGcicO?Dk&F($R}~zL+SS@5$ET2OzqsTbPNj1hU`5zO+c++cKmL5F^Eq z#Cla~nJzjEZFRB0ZsN<5Zj11f36S7><_HF2k{w}rL*PU*e+{xR@`~|?1EAg4aX6$} zAiLyfsPbJ|jbXWcj+lH@^~-35a*HgXNg*d&2p5xPQc{QHFa;GD5n%PchdoE>v&t7! zXsJ`BKlF}r?j5Nxo5?H$-;mWZL~#0X?ByITrTP|9OI;XoH|k?Z-V2AEHbCm!*yB>C zYjH;c5qS|#DAngRDcPS%W+3~CsrR5dD|Wrdp;xP)9%^_xz|(77C1a6>plX#{8&oNL zK!=zKuTf?uexE&BtUox-4kaZhymM*_m0qoP);m4p38y3!Th;8lx}AseF>0Hra*@)a zYsQh1jGAvpL?7aik_@TQp&_E|39Nu#DgJv9^T^c142fl~6kpj@St&m5Igti#vmhDC zg&^EpLe&>RPJ+6$W5%p489&nd{ZjnFlj$-(@-AeJgmtE~8Z*mT3At)t5}j)HgY*)% za_>h3aI18HaKDPl#cNc8Q{51e!8WNguxJs%nOA+_2K7wlnCHxQEz5}(#ZiIbn=I-NqQ`H5f+K~|1;+HP~t!Z_Lz zIC_=;e|zb_l~%uWlTbVul<>g;K^mh-7H~FdMmF?uC3iq z#JB5$&OK$yo=)h_yn63-ZO{*!?U_FnRN6%(UV@BzWPA0T}ULA>2T3Y=HGoWc?iL}J~Q*9nM~@-lsC504%$RdR1fUr4Ae)uG1OMh_HwOQtI7A_3}BSv;H2G<@~8{cBkah#%2MX#q`IvaA{l)45oQYFWO%K;?&W z3=ig_K9p-9;G}dvmZ;9=TSATEgGM!O3D3Nto&<5p_^mBLs>Cy$i=L>P$ZrWl2nh
    hk{@(H*E#GtK^it>GcNX7Y{LFzT7p~0z&fNR-`hR=o{Ta9P?g#7sCw4+R%9YLi zr@d7{KpHYt@&87yx;0(+N}_sN&hAgbgUj>@2i+(dKII=tR0quUMf7g!;i6a_G}%;_ z%c{Y@cNQK^RJ+WH{mEe3=u#uaQ{d(@9xu4s(5H7k0s!C?q}<1$4tsu?Nqu2zLo(0dDY#2TcBUx zwS)SwU*VyOZzwFTy(!W%c9vvEl<%1YpwX)%9ZI*@rm1D7ikARhdS!BD{yy6fN`LZWHx-lTg*z`Mi(-H+%Kytu>!^ySCm) zo65%t-01`~+gmKL)DByhc9Fi4fR=kpZJ|rdqYqxyCMvYq?Wk(LRCB+U0Kj`y zzqLfJhqF3xlv8tUhi&jw0<7=V#an1<<#nKw0P9kivE~mad(qP60qX- zYg9tjdp_L)Jm6xpbv|Y5XOov9_vHSRQiTtfrPtOHQ0cB5-=Ac*vh3x9iGr?sVSmy{ z(67@Bx^cSbk0wCcUHSUHrIboFaBsFFJ>>)_yz8uVz3F?u4`*J^z==`@Kac>Xw_kOC z&nHd^J(?)&y?q*#>^sX3CBXCT*PtXs4vXsj31EKv^_be|HfkL!UHFF*aR2rzPd8{z z8A|7WE&(p^%1irGU8&e7J4$AWV>p5gCbthJU@Y!eqbt4Tq`&T3@)VSY`*Vk>$Uv(h>MypMp=`IyJ=ai6j_rS%%k9fR z*lhM_R{8&>Bo!GVGU1qTWa6dWix zP;em6fn+WD7AF7nk@iW*DD6(9ayco2iBaW3PT+(BlbegVp~kg5E=>ZoS%d)20CevF z(W&lj9sn|APvh)^f0ET#e?C!2Y_Co2O6^S}ZDHr#K57eBYtZN}VsKOi;72A9A^>v% z{*&Hi>TtJ;8@N$y^^qfbgsN9$)MmYipHCDd+s&fZ>r?Bh3x7a80aG@#fi41D20Shw z6cp}L1DuOHL*ft^&YjeH!_=-Nz_;DR_1CJ>iZxK@xl4#5A?{QRLF>1p+`}MItA|w(>SV&@ZF^!r^`lvnv7eqy)OBkkeONmn tWCrgVk2IogO&jS++v^qMkVYO(xDM^gt5ff{4<$n^8lAKel|R)Q{C}M6Z?*sc From 8f10ec52e2d9237357badaac31abc974a025e57e Mon Sep 17 00:00:00 2001 From: James Barr Date: Fri, 14 Feb 2025 02:13:42 -0800 Subject: [PATCH 54/56] Prepare for release v0.4.0-alpha06 --- CHANGELOG.md | 3 +++ gradle.properties | 2 +- 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index fbb8c3c5..11af69a0 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,6 @@ +# 0.4.0-alpha06 +* Add support for Kotlin 2.1.0 + # 0.4.0-alpha05 * Set JvmVersion to 1.8 diff --git a/gradle.properties b/gradle.properties index e418fcc8..671e672d 100644 --- a/gradle.properties +++ b/gradle.properties @@ -14,7 +14,7 @@ # limitations under the License. # GROUP=com.uber.motif -VERSION_NAME=0.4.0-alpha06-SNAPSHOT +VERSION_NAME=0.4.0-alpha06 POM_DESCRIPTION=Simple DI API for Android / Java. POM_URL=https://github.com/uber/motif/ POM_SCM_URL=https://github.com/uber/motif/ From e1fafcc0bba0d0dc51a8eb87cefacc46e29336ed Mon Sep 17 00:00:00 2001 From: Rubin Yoo Date: Wed, 2 Jul 2025 09:34:31 -0700 Subject: [PATCH 55/56] disable field init through the scope parameter --- ast/src/main/kotlin/motif/ast/IrAnnotation.kt | 2 + .../motif/ast/compiler/CompilerAnnotation.kt | 3 + .../motif/compiler/JavaCodeGenerator.kt | 51 +++++++++++++---- .../motif/compiler/KotlinCodeGenerator.kt | 56 ++++++++++++++----- .../main/kotlin/motif/compiler/ScopeImpl.kt | 1 + .../kotlin/motif/compiler/ScopeImplFactory.kt | 6 +- gradle.properties | 4 +- .../motif/ast/intellij/IntelliJAnnotation.kt | 4 ++ lib/src/main/java/motif/Scope.java | 8 ++- models/src/main/kotlin/motif/models/Scope.kt | 7 +-- .../src/main/java/motif/sample/MainScope.kt | 2 +- .../lib/bottom_header/BottomHeaderScope.java | 2 +- samples/sample/build.gradle | 5 ++ .../app/bottom_sheet/BottomSheetScope.java | 2 +- .../sample/app/photo_grid/PhotoGridScope.java | 2 +- .../sample/app/photo_list/PhotoListScope.java | 2 +- .../java/motif/sample/app/root/RootScope.java | 2 +- .../GRAPH.txt | 42 ++++++++++++++ .../KT008_use_null_field_init_kotlin/Scope.kt | 44 +++++++++++++++ .../Test.java | 29 ++++++++++ .../T077_use_null_field_init_java/GRAPH.txt | 42 ++++++++++++++ .../T077_use_null_field_init_java/Scope.java | 46 +++++++++++++++ .../T077_use_null_field_init_java/Test.java | 29 ++++++++++ 23 files changed, 351 insertions(+), 40 deletions(-) create mode 100644 tests/src/main/java/testcases/KT008_use_null_field_init_kotlin/GRAPH.txt create mode 100644 tests/src/main/java/testcases/KT008_use_null_field_init_kotlin/Scope.kt create mode 100644 tests/src/main/java/testcases/KT008_use_null_field_init_kotlin/Test.java create mode 100644 tests/src/main/java/testcases/T077_use_null_field_init_java/GRAPH.txt create mode 100644 tests/src/main/java/testcases/T077_use_null_field_init_java/Scope.java create mode 100644 tests/src/main/java/testcases/T077_use_null_field_init_java/Test.java diff --git a/ast/src/main/kotlin/motif/ast/IrAnnotation.kt b/ast/src/main/kotlin/motif/ast/IrAnnotation.kt index acb46285..934869d4 100644 --- a/ast/src/main/kotlin/motif/ast/IrAnnotation.kt +++ b/ast/src/main/kotlin/motif/ast/IrAnnotation.kt @@ -25,5 +25,7 @@ interface IrAnnotation : IrEquivalence { val members: List + val annotationValueMap: Map + fun matchesClass(annotationClass: KClass): Boolean } diff --git a/compiler/ast/src/main/kotlin/motif/ast/compiler/CompilerAnnotation.kt b/compiler/ast/src/main/kotlin/motif/ast/compiler/CompilerAnnotation.kt index 573a571c..ff3f2c6b 100644 --- a/compiler/ast/src/main/kotlin/motif/ast/compiler/CompilerAnnotation.kt +++ b/compiler/ast/src/main/kotlin/motif/ast/compiler/CompilerAnnotation.kt @@ -37,6 +37,9 @@ class CompilerAnnotation(val env: XProcessingEnv, val mirror: XAnnotation) : IrA override val type: IrType = CompilerType(env, mirror.type) + override val annotationValueMap: Map + get() = mirror.annotationValues.associate { it.name to it.value } + override val members: List by lazy { val annotationMethods = mirror.type.typeElement?.getDeclaredMethods().orEmpty() mirror.annotationValues.map { annotationValue -> diff --git a/compiler/src/main/kotlin/motif/compiler/JavaCodeGenerator.kt b/compiler/src/main/kotlin/motif/compiler/JavaCodeGenerator.kt index 640e9dbb..e8464fc8 100644 --- a/compiler/src/main/kotlin/motif/compiler/JavaCodeGenerator.kt +++ b/compiler/src/main/kotlin/motif/compiler/JavaCodeGenerator.kt @@ -46,13 +46,13 @@ object JavaCodeGenerator { addSuperinterface(superClassName.j) objectsField?.let { addField(it.spec()) } addField(dependenciesField.spec()) - cacheFields.forEach { addField(it.spec()) } + cacheFields.forEach { addField(it.spec(useNullFieldInitialization)) } addMethod(constructor.spec()) alternateConstructor?.let { addMethod(it.spec()) } accessMethodImpls.forEach { addMethod(it.spec()) } childMethodImpls.forEach { addMethod(it.spec()) } addMethod(scopeProviderMethod.spec()) - factoryProviderMethods.forEach { addMethods(it.specs()) } + factoryProviderMethods.forEach { addMethods(it.specs(useNullFieldInitialization)) } dependencyProviderMethods.forEach { addMethod(it.spec()) } dependencies?.let { addType(it.spec()) } objectsImpl?.let { addType(it.spec()) } @@ -80,10 +80,17 @@ object JavaCodeGenerator { private fun DependenciesField.spec(): FieldSpec = FieldSpec.builder(dependenciesClassName.j, name, Modifier.PRIVATE, Modifier.FINAL).build() - private fun CacheField.spec(): FieldSpec = - FieldSpec.builder(Object::class.java, name, Modifier.PRIVATE, Modifier.VOLATILE) - .initializer("\$T.NONE", None::class.java) - .build() + private fun CacheField.spec(useNullFieldInitialization: Boolean): FieldSpec { + return if(useNullFieldInitialization) { + FieldSpec.builder(Object::class.java, name, Modifier.PRIVATE, Modifier.VOLATILE) + .build() + } else { + FieldSpec.builder(Object::class.java, name, Modifier.PRIVATE, Modifier.VOLATILE) + .initializer("\$T.NONE", None::class.java) + .build() + } + } + private fun Constructor.spec(): MethodSpec = MethodSpec.constructorBuilder() @@ -164,21 +171,40 @@ object JavaCodeGenerator { private fun ScopeProviderMethod.spec(): MethodSpec = MethodSpec.methodBuilder(name).returns(scopeClassName.j).addStatement("return this").build() - private fun FactoryProviderMethod.specs(): List { + private fun FactoryProviderMethod.specs(useNullFieldInitialization : Boolean): List { val primarySpec = - MethodSpec.methodBuilder(name).returns(returnTypeName.j).addStatement(body.spec()).build() + MethodSpec.methodBuilder(name).returns(returnTypeName.j).addStatement(body.spec(useNullFieldInitialization)).build() val spreadSpecs = spreadProviderMethods.map { it.spec() } return listOf(primarySpec) + spreadSpecs } - private fun FactoryProviderMethodBody.spec(): CodeBlock = + private fun FactoryProviderMethodBody.spec(useNullFieldInitialization: Boolean): CodeBlock = when (this) { - is FactoryProviderMethodBody.Cached -> spec() + is FactoryProviderMethodBody.Cached -> spec(useNullFieldInitialization) is FactoryProviderMethodBody.Uncached -> spec() } - private fun FactoryProviderMethodBody.Cached.spec(): CodeBlock = - CodeBlock.builder() + private fun FactoryProviderMethodBody.Cached.spec(useNullFieldInitialization : Boolean): CodeBlock { + if(useNullFieldInitialization) { + val localFieldName = "_$cacheFieldName" + return CodeBlock.builder() + // Using a local variable reduces atomic read overhead + .add("Object $localFieldName = \$N;\n", cacheFieldName) + .beginControlFlow("if (\$N == null)", localFieldName) + .beginControlFlow("synchronized (this)") + .beginControlFlow("if (\$N == null)", cacheFieldName) + .add("\$N = \$L;\n", localFieldName, instantiation.spec()) + .beginControlFlow("if (\$N == null)", localFieldName) + .add("throw new \$T(\$S);\n", NullPointerException::class.java, "Factory method cannot return null") + .endControlFlow() + .add("\$N = \$L;\n", cacheFieldName, localFieldName) + .endControlFlow() + .endControlFlow() + .endControlFlow() + .add("return (\$T) \$N", returnTypeName.j, localFieldName) + .build() + } + return CodeBlock.builder() .beginControlFlow("if (\$N == \$T.NONE)", cacheFieldName, None::class.java) .beginControlFlow("synchronized (this)") .beginControlFlow("if (\$N == \$T.NONE)", cacheFieldName, None::class.java) @@ -188,6 +214,7 @@ object JavaCodeGenerator { .endControlFlow() .add("return (\$T) \$N", returnTypeName.j, cacheFieldName) .build() + } private fun FactoryProviderMethodBody.Uncached.spec(): CodeBlock = CodeBlock.of("return \$L", instantiation.spec()) diff --git a/compiler/src/main/kotlin/motif/compiler/KotlinCodeGenerator.kt b/compiler/src/main/kotlin/motif/compiler/KotlinCodeGenerator.kt index 82f00dec..a7eacc56 100644 --- a/compiler/src/main/kotlin/motif/compiler/KotlinCodeGenerator.kt +++ b/compiler/src/main/kotlin/motif/compiler/KotlinCodeGenerator.kt @@ -27,6 +27,7 @@ import com.squareup.kotlinpoet.ParameterizedTypeName import com.squareup.kotlinpoet.PropertySpec import com.squareup.kotlinpoet.TypeName import com.squareup.kotlinpoet.TypeSpec +import com.squareup.kotlinpoet.asTypeName import com.squareup.kotlinpoet.javapoet.KotlinPoetJavaPoetPreview import com.squareup.kotlinpoet.javapoet.toKClassName import motif.internal.None @@ -48,7 +49,7 @@ object KotlinCodeGenerator { addSuperinterface(superClassName.kt) objectsField?.let { addProperty(it.spec()) } addProperty(dependenciesField.spec()) - cacheFields.forEach { addProperty(it.spec()) } + cacheFields.forEach { addProperty(it.spec(useNullFieldInitialization)) } primaryConstructor(constructor.spec()) alternateConstructor?.let { addFunction(it.spec()) } accessMethodImpls @@ -59,7 +60,7 @@ object KotlinCodeGenerator { .forEach { addProperty(it.propSpec()) } childMethodImpls.forEach { addFunction(it.spec()) } addFunction(scopeProviderMethod.spec()) - factoryProviderMethods.forEach { addFunctions(it.specs()) } + factoryProviderMethods.forEach { addFunctions(it.specs(useNullFieldInitialization)) } dependencyProviderMethods.forEach { addFunction(it.spec()) } dependencies?.let { addType(it.spec()) } objectsImpl?.let { addType(it.spec()) } @@ -96,12 +97,21 @@ object KotlinCodeGenerator { .initializer(name) .build() - private fun CacheField.spec(): PropertySpec = - PropertySpec.builder(name, Any::class, KModifier.PRIVATE) - .mutable(true) - .addAnnotation(Volatile::class) - .initializer("%T.NONE", None::class) - .build() + private fun CacheField.spec(useNullFieldInitialization: Boolean): PropertySpec { + return if(useNullFieldInitialization) { + PropertySpec.builder(name, Any::class.asTypeName().copy(true), KModifier.PRIVATE) + .mutable(true) + .addAnnotation(Volatile::class) + .initializer("null") + .build() + } else { + PropertySpec.builder(name, Any::class, KModifier.PRIVATE) + .mutable(true) + .addAnnotation(Volatile::class) + .initializer("%T.NONE", None::class) + .build() + } + } private fun Constructor.spec(): FunSpec = FunSpec.constructorBuilder() @@ -194,25 +204,42 @@ object KotlinCodeGenerator { .addStatement("return this") .build() - private fun FactoryProviderMethod.specs(): List { + private fun FactoryProviderMethod.specs(useNullFieldInitialization : Boolean): List { val primarySpec = FunSpec.builder(name) .addModifiers(KModifier.INTERNAL) .returns(returnTypeName.reloadedForTypeArgs(env)) - .addCode(body.spec()) + .addCode(body.spec(useNullFieldInitialization)) .build() val spreadSpecs = spreadProviderMethods.map { it.spec() } return listOf(primarySpec) + spreadSpecs } - private fun FactoryProviderMethodBody.spec(): CodeBlock = + private fun FactoryProviderMethodBody.spec(useNullFieldInitialization : Boolean): CodeBlock = when (this) { - is FactoryProviderMethodBody.Cached -> spec() + is FactoryProviderMethodBody.Cached -> spec(useNullFieldInitialization) is FactoryProviderMethodBody.Uncached -> spec() } - private fun FactoryProviderMethodBody.Cached.spec(): CodeBlock = - CodeBlock.builder() + private fun FactoryProviderMethodBody.Cached.spec(useNullFieldInitialization : Boolean): CodeBlock { + if(useNullFieldInitialization) { + val localFieldName = "_$cacheFieldName" + val codeBlockBuilder = CodeBlock.builder() + // Using a local variable reduces atomic read overhead + .addStatement("var $localFieldName = %N;\n", cacheFieldName) + .beginControlFlow("if (%N == null)", localFieldName) + .beginControlFlow("synchronized (this)") + .beginControlFlow("if (%N == null)", cacheFieldName) + .addStatement("%N = %L", localFieldName, instantiation.spec()) + .addStatement("%N = %N", cacheFieldName, localFieldName) + .endControlFlow() + .endControlFlow() + .endControlFlow() + return codeBlockBuilder + .add("return ( %N as %T )", localFieldName, returnTypeName.reloadedForTypeArgs(env)) + .build() + } + return CodeBlock.builder() .beginControlFlow("if (%N == %T.NONE)", cacheFieldName, None::class) .beginControlFlow("synchronized (this)") .beginControlFlow("if (%N == %T.NONE)", cacheFieldName, None::class) @@ -222,6 +249,7 @@ object KotlinCodeGenerator { .endControlFlow() .add("return ( %N as %T )", cacheFieldName, returnTypeName.reloadedForTypeArgs(env)) .build() + } private fun motif.compiler.TypeName.reloadedForTypeArgs(env: XProcessingEnv): TypeName = if (kt is ParameterizedTypeName) { diff --git a/compiler/src/main/kotlin/motif/compiler/ScopeImpl.kt b/compiler/src/main/kotlin/motif/compiler/ScopeImpl.kt index 11e924c8..499e9c0b 100644 --- a/compiler/src/main/kotlin/motif/compiler/ScopeImpl.kt +++ b/compiler/src/main/kotlin/motif/compiler/ScopeImpl.kt @@ -35,6 +35,7 @@ import motif.ast.compiler.CompilerMethod * implementations. */ class ScopeImpl( + val useNullFieldInitialization: Boolean, val className: ClassName, val superClassName: ClassName, val internalScope: Boolean, diff --git a/compiler/src/main/kotlin/motif/compiler/ScopeImplFactory.kt b/compiler/src/main/kotlin/motif/compiler/ScopeImplFactory.kt index c56aa5ed..95a6cbad 100644 --- a/compiler/src/main/kotlin/motif/compiler/ScopeImplFactory.kt +++ b/compiler/src/main/kotlin/motif/compiler/ScopeImplFactory.kt @@ -67,7 +67,9 @@ private constructor( fun create(): ScopeImpl { val isInternal = (scope.clazz as? CompilerClass)?.isInternal() ?: false - return ScopeImpl( + return ScopeImpl( + (scope.clazz.annotations.find { + it.className == motif.Scope::class.java.name }!!.annotationValueMap[SCOPE_ANNOTATION_FIELD_USE_NULL] as? Boolean) ?: false, scope.implClassName, scope.typeName, isInternal, @@ -429,6 +431,8 @@ private constructor( private const val OBJECTS_FIELD_NAME = "objects" private const val DEPENDENCIES_FIELD_NAME = "dependencies" + private const val SCOPE_ANNOTATION_FIELD_USE_NULL = "useNullFieldInitialization" + fun create(env: XProcessingEnv, graph: ResolvedGraph): List = ScopeImplFactory(env, graph).create() diff --git a/gradle.properties b/gradle.properties index 671e672d..567f2265 100644 --- a/gradle.properties +++ b/gradle.properties @@ -14,7 +14,7 @@ # limitations under the License. # GROUP=com.uber.motif -VERSION_NAME=0.4.0-alpha06 +VERSION_NAME=0.4.0-alpha07 POM_DESCRIPTION=Simple DI API for Android / Java. POM_URL=https://github.com/uber/motif/ POM_SCM_URL=https://github.com/uber/motif/ @@ -33,4 +33,4 @@ android.useAndroidX=true android.enableJetifier=true # https://github.com/Kotlin/dokka/issues/1405 -org.gradle.jvmargs=-XX:MaxMetaspaceSize=1g +org.gradle.jvmargs=-XX:MaxMetaspaceSize=1g \ No newline at end of file diff --git a/intellij/ast/src/main/kotlin/motif/ast/intellij/IntelliJAnnotation.kt b/intellij/ast/src/main/kotlin/motif/ast/intellij/IntelliJAnnotation.kt index 03c95c5c..b6102ed1 100644 --- a/intellij/ast/src/main/kotlin/motif/ast/intellij/IntelliJAnnotation.kt +++ b/intellij/ast/src/main/kotlin/motif/ast/intellij/IntelliJAnnotation.kt @@ -31,6 +31,7 @@ import kotlin.reflect.KClass import motif.ast.IrAnnotation import motif.ast.IrMethod import motif.ast.IrType +import java.util.Collections class IntelliJAnnotation(private val project: Project, private val psiAnnotation: PsiAnnotation) : IrAnnotation { @@ -62,6 +63,9 @@ class IntelliJAnnotation(private val project: Project, private val psiAnnotation override fun matchesClass(annotationClass: KClass): Boolean = psiAnnotation.qualifiedName == annotationClass.java.name + override val annotationValueMap: Map + get() = Collections.emptyMap() + override fun equals(other: Any?): Boolean { if (this === other) return true if (javaClass != other?.javaClass) return false diff --git a/lib/src/main/java/motif/Scope.java b/lib/src/main/java/motif/Scope.java index 1a4eab4f..fc2c2313 100644 --- a/lib/src/main/java/motif/Scope.java +++ b/lib/src/main/java/motif/Scope.java @@ -15,4 +15,10 @@ */ package motif; -public @interface Scope {} +public @interface Scope { + /** + * + * @return on false, the field will be initialized with [None.NONE]. Otherwise, null & [Initialized.INITIALIZED] will be used to skip the field initialization. + */ + boolean useNullFieldInitialization() default false; +} diff --git a/models/src/main/kotlin/motif/models/Scope.kt b/models/src/main/kotlin/motif/models/Scope.kt index b4cf68a5..e5254954 100644 --- a/models/src/main/kotlin/motif/models/Scope.kt +++ b/models/src/main/kotlin/motif/models/Scope.kt @@ -19,8 +19,7 @@ import motif.ast.IrClass import motif.ast.IrType /** [Wiki](https://github.com/uber/motif/wiki#scope) */ -sealed class Scope(val clazz: IrClass) { - +sealed class Scope(val useNullFieldInitialization : Boolean, val clazz: IrClass) { val source by lazy { ScopeSource(this) } val simpleName: String by lazy { clazz.simpleName } val qualifiedName: String by lazy { clazz.qualifiedName } @@ -38,7 +37,7 @@ sealed class Scope(val clazz: IrClass) { } class ErrorScope internal constructor(clazz: IrClass, val parsingError: ParsingError) : - Scope(clazz) { + Scope(useNullFieldInitialization = false, clazz) { override val objects: Objects? = null override val accessMethods: List = emptyList() override val childMethods: List = emptyList() @@ -46,7 +45,7 @@ class ErrorScope internal constructor(clazz: IrClass, val parsingError: ParsingE override val dependencies: Dependencies? = null } -class ValidScope internal constructor(clazz: IrClass) : Scope(clazz) { +class ValidScope internal constructor(clazz: IrClass, useNullFieldInitialization: Boolean = false) : Scope(useNullFieldInitialization, clazz) { init { if (clazz.kind != IrClass.Kind.INTERFACE) throw ScopeMustBeAnInterface(clazz) diff --git a/samples/sample-kotlin/src/main/java/motif/sample/MainScope.kt b/samples/sample-kotlin/src/main/java/motif/sample/MainScope.kt index e4977ed6..4e6b2ac2 100644 --- a/samples/sample-kotlin/src/main/java/motif/sample/MainScope.kt +++ b/samples/sample-kotlin/src/main/java/motif/sample/MainScope.kt @@ -19,7 +19,7 @@ import javax.inject.Named import motif.Creatable import motif.Scope -@Scope +@Scope(useNullFieldInitialization = true) interface MainScope : Creatable { fun greeter(): Greeter diff --git a/samples/sample-lib/src/main/java/motif/sample/lib/bottom_header/BottomHeaderScope.java b/samples/sample-lib/src/main/java/motif/sample/lib/bottom_header/BottomHeaderScope.java index 03b5aae4..b3b2d869 100644 --- a/samples/sample-lib/src/main/java/motif/sample/lib/bottom_header/BottomHeaderScope.java +++ b/samples/sample-lib/src/main/java/motif/sample/lib/bottom_header/BottomHeaderScope.java @@ -18,7 +18,7 @@ import motif.Scope; import motif.sample.lib.controller.ControllerObjects; -@Scope +@Scope(useNullFieldInitialization = true) public interface BottomHeaderScope { BottomHeaderView view(); diff --git a/samples/sample/build.gradle b/samples/sample/build.gradle index bcaf1e78..8ef8443d 100644 --- a/samples/sample/build.gradle +++ b/samples/sample/build.gradle @@ -11,6 +11,11 @@ android { targetSdkVersion deps.build.targetSdkVersion } + compileOptions { + sourceCompatibility JavaVersion.VERSION_11 + targetCompatibility JavaVersion.VERSION_11 + } + defaultConfig { minSdkVersion deps.build.minSdkVersion targetSdkVersion deps.build.targetSdkVersion diff --git a/samples/sample/src/main/java/motif/sample/app/bottom_sheet/BottomSheetScope.java b/samples/sample/src/main/java/motif/sample/app/bottom_sheet/BottomSheetScope.java index 3f3465d7..986c0699 100644 --- a/samples/sample/src/main/java/motif/sample/app/bottom_sheet/BottomSheetScope.java +++ b/samples/sample/src/main/java/motif/sample/app/bottom_sheet/BottomSheetScope.java @@ -22,7 +22,7 @@ import motif.sample.lib.bottom_header.BottomHeaderScope; import motif.sample.lib.controller.ControllerObjects; -@Scope +@Scope(useNullFieldInitialization = true) public interface BottomSheetScope { BottomSheetView view(); diff --git a/samples/sample/src/main/java/motif/sample/app/photo_grid/PhotoGridScope.java b/samples/sample/src/main/java/motif/sample/app/photo_grid/PhotoGridScope.java index 404d8a93..88acbdbc 100644 --- a/samples/sample/src/main/java/motif/sample/app/photo_grid/PhotoGridScope.java +++ b/samples/sample/src/main/java/motif/sample/app/photo_grid/PhotoGridScope.java @@ -21,7 +21,7 @@ import motif.sample.lib.controller.ControllerObjects; import motif.sample.lib.db.Photo; -@Scope +@Scope(useNullFieldInitialization = true) public interface PhotoGridScope { PhotoGridView view(); diff --git a/samples/sample/src/main/java/motif/sample/app/photo_list/PhotoListScope.java b/samples/sample/src/main/java/motif/sample/app/photo_list/PhotoListScope.java index 7b8936ad..ce22f0e7 100644 --- a/samples/sample/src/main/java/motif/sample/app/photo_list/PhotoListScope.java +++ b/samples/sample/src/main/java/motif/sample/app/photo_list/PhotoListScope.java @@ -21,7 +21,7 @@ import motif.sample.lib.controller.ControllerObjects; import motif.sample.lib.db.Photo; -@Scope +@Scope(useNullFieldInitialization = true) public interface PhotoListScope { PhotoListView view(); diff --git a/samples/sample/src/main/java/motif/sample/app/root/RootScope.java b/samples/sample/src/main/java/motif/sample/app/root/RootScope.java index 02394488..d943ea69 100644 --- a/samples/sample/src/main/java/motif/sample/app/root/RootScope.java +++ b/samples/sample/src/main/java/motif/sample/app/root/RootScope.java @@ -27,7 +27,7 @@ import motif.sample.lib.db.Database; import motif.sample.lib.multiselect.MultiSelector; -@Scope +@Scope(useNullFieldInitialization = true) public interface RootScope { RootView view(); diff --git a/tests/src/main/java/testcases/KT008_use_null_field_init_kotlin/GRAPH.txt b/tests/src/main/java/testcases/KT008_use_null_field_init_kotlin/GRAPH.txt new file mode 100644 index 00000000..abf4850c --- /dev/null +++ b/tests/src/main/java/testcases/KT008_use_null_field_init_kotlin/GRAPH.txt @@ -0,0 +1,42 @@ +######################################################################## +# # +# This file is auto-generated by running the Motif compiler tests and # +# serves a as validation of graph correctness. IntelliJ plugin tests # +# also rely on this file to ensure that the plugin graph understanding # +# is equivalent to the compiler's. # +# # +# - Do not edit manually. # +# - Commit changes to source control. # +# - Since this file is autogenerated, code review changes carefully to # +# ensure correctness. # +# # +######################################################################## + + ------- +| Scope | + ------- + + ==== Required ==== + + ==== Provides ==== + + ---- int | Objects.fooInt ---- + [ Required ] + [ Consumed By ] + * Scope | Scope.fooInt() + + ---- Object | Objects.fooObject ---- + [ Required ] + [ Consumed By ] + * Scope | Scope.fooObject() + + ---- String | Objects.fooString ---- + [ Required ] + [ Consumed By ] + * Scope | Scope.fooString() + + ---- Scope | implicit ---- + [ Required ] + [ Consumed By ] + + diff --git a/tests/src/main/java/testcases/KT008_use_null_field_init_kotlin/Scope.kt b/tests/src/main/java/testcases/KT008_use_null_field_init_kotlin/Scope.kt new file mode 100644 index 00000000..15e32c55 --- /dev/null +++ b/tests/src/main/java/testcases/KT008_use_null_field_init_kotlin/Scope.kt @@ -0,0 +1,44 @@ +/* + * Copyright (c) 2018-2019 Uber Technologies, Inc. + * + * 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 testcases.KT008_use_null_field_init_kotlin + +import motif.Creatable + +@motif.Scope(useNullFieldInitialization = true) +interface Scope : Creatable { + fun fooObject(): Any + + fun fooInt(): Int + + fun fooString(): String + + @motif.Objects + abstract class Objects { + fun fooObject(): Any { + return Any() + } + + fun fooInt(): Int { + return 3 + } + + fun fooString(): String { + return "fooString" + } + } + + interface Dependencies +} \ No newline at end of file diff --git a/tests/src/main/java/testcases/KT008_use_null_field_init_kotlin/Test.java b/tests/src/main/java/testcases/KT008_use_null_field_init_kotlin/Test.java new file mode 100644 index 00000000..1cb8bf80 --- /dev/null +++ b/tests/src/main/java/testcases/KT008_use_null_field_init_kotlin/Test.java @@ -0,0 +1,29 @@ +/* + * Copyright (c) 2018-2019 Uber Technologies, Inc. + * + * 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 testcases.KT008_use_null_field_init_kotlin; + +import static com.google.common.truth.Truth.assertThat; + +public class Test { + + public static void run() { + Scope scope = new ScopeImpl(); + assertThat(scope.fooString()).isEqualTo("fooString"); + assertThat(scope.fooInt()).isEqualTo(3); + assertThat(scope.fooObject()).isNotNull(); + assertThat(scope.fooObject()).isEqualTo(scope.fooObject()); + } +} diff --git a/tests/src/main/java/testcases/T077_use_null_field_init_java/GRAPH.txt b/tests/src/main/java/testcases/T077_use_null_field_init_java/GRAPH.txt new file mode 100644 index 00000000..abf4850c --- /dev/null +++ b/tests/src/main/java/testcases/T077_use_null_field_init_java/GRAPH.txt @@ -0,0 +1,42 @@ +######################################################################## +# # +# This file is auto-generated by running the Motif compiler tests and # +# serves a as validation of graph correctness. IntelliJ plugin tests # +# also rely on this file to ensure that the plugin graph understanding # +# is equivalent to the compiler's. # +# # +# - Do not edit manually. # +# - Commit changes to source control. # +# - Since this file is autogenerated, code review changes carefully to # +# ensure correctness. # +# # +######################################################################## + + ------- +| Scope | + ------- + + ==== Required ==== + + ==== Provides ==== + + ---- int | Objects.fooInt ---- + [ Required ] + [ Consumed By ] + * Scope | Scope.fooInt() + + ---- Object | Objects.fooObject ---- + [ Required ] + [ Consumed By ] + * Scope | Scope.fooObject() + + ---- String | Objects.fooString ---- + [ Required ] + [ Consumed By ] + * Scope | Scope.fooString() + + ---- Scope | implicit ---- + [ Required ] + [ Consumed By ] + + diff --git a/tests/src/main/java/testcases/T077_use_null_field_init_java/Scope.java b/tests/src/main/java/testcases/T077_use_null_field_init_java/Scope.java new file mode 100644 index 00000000..535ddd56 --- /dev/null +++ b/tests/src/main/java/testcases/T077_use_null_field_init_java/Scope.java @@ -0,0 +1,46 @@ +/* + * Copyright (c) 2018-2019 Uber Technologies, Inc. + * + * 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 testcases.T077_use_null_field_init_java; + +import motif.Creatable; + +@motif.Scope(useNullFieldInitialization = true) +public interface Scope extends Creatable { + + Object fooObject(); + + int fooInt(); + + String fooString(); + + @motif.Objects + class Objects { + + Object fooObject() { + return new Object(); + } + + int fooInt() { + return 3; + } + + String fooString() { + return "fooString"; + } + } + + interface Dependencies {} +} \ No newline at end of file diff --git a/tests/src/main/java/testcases/T077_use_null_field_init_java/Test.java b/tests/src/main/java/testcases/T077_use_null_field_init_java/Test.java new file mode 100644 index 00000000..1601cd1b --- /dev/null +++ b/tests/src/main/java/testcases/T077_use_null_field_init_java/Test.java @@ -0,0 +1,29 @@ +/* + * Copyright (c) 2018-2019 Uber Technologies, Inc. + * + * 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 testcases.T077_use_null_field_init_java; + +import static com.google.common.truth.Truth.assertThat; +import static org.junit.Assert.fail; +public class Test { + + public static void run() { + Scope scope = new ScopeImpl(); + assertThat(scope.fooString()).isEqualTo("fooString"); + assertThat(scope.fooInt()).isEqualTo(3); + assertThat(scope.fooObject()).isNotNull(); + assertThat(scope.fooObject()).isEqualTo(scope.fooObject()); + } +} From b3f33c3f285c1e3264f29aaf3cc5175b7eb6af16 Mon Sep 17 00:00:00 2001 From: Zhilu Tang Date: Mon, 11 Aug 2025 11:26:20 -0700 Subject: [PATCH 56/56] Add test code based on the previous assertion --- samples/sample/src/main/java/demo/Bar.java | 26 +++++ .../sample/src/main/java/demo/RootScope.java | 33 +++++++ .../sample/src/main/java/demo/RootScope2.java | 33 +++++++ .../motif/sample/app/root/RootScopeTest.java | 10 +- .../sample/app/root/manual_1/RootScope.java | 18 ++++ .../app/root/manual_1/RootScopeImpl.java | 73 ++++++++++++++ .../root/manual_1/RootScopeManualTest.java | 34 +++++++ .../sample/app/root/manual_2/RootScope.java | 34 +++++++ .../app/root/manual_2/RootScopeImpl.java | 86 +++++++++++++++++ .../root/manual_2/RootScopeManualTest.java | 34 +++++++ .../sample/src/test/resources/java/1_raw.txt | 77 +++++++++++++++ .../sample/src/test/resources/java/2_raw.txt | 95 +++++++++++++++++++ 12 files changed, 552 insertions(+), 1 deletion(-) create mode 100644 samples/sample/src/main/java/demo/Bar.java create mode 100644 samples/sample/src/main/java/demo/RootScope.java create mode 100644 samples/sample/src/main/java/demo/RootScope2.java create mode 100644 samples/sample/src/test/java/motif/sample/app/root/manual_1/RootScope.java create mode 100644 samples/sample/src/test/java/motif/sample/app/root/manual_1/RootScopeImpl.java create mode 100644 samples/sample/src/test/java/motif/sample/app/root/manual_1/RootScopeManualTest.java create mode 100644 samples/sample/src/test/java/motif/sample/app/root/manual_2/RootScope.java create mode 100644 samples/sample/src/test/java/motif/sample/app/root/manual_2/RootScopeImpl.java create mode 100644 samples/sample/src/test/java/motif/sample/app/root/manual_2/RootScopeManualTest.java create mode 100644 samples/sample/src/test/resources/java/1_raw.txt create mode 100644 samples/sample/src/test/resources/java/2_raw.txt diff --git a/samples/sample/src/main/java/demo/Bar.java b/samples/sample/src/main/java/demo/Bar.java new file mode 100644 index 00000000..8eacd62d --- /dev/null +++ b/samples/sample/src/main/java/demo/Bar.java @@ -0,0 +1,26 @@ +/* + * Copyright (c) 2018-2019 Uber Technologies, Inc. + * + * 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 demo; + + +import javax.inject.Inject; + +public class Bar { + + @Inject + public Bar() { + } +} diff --git a/samples/sample/src/main/java/demo/RootScope.java b/samples/sample/src/main/java/demo/RootScope.java new file mode 100644 index 00000000..128bcd46 --- /dev/null +++ b/samples/sample/src/main/java/demo/RootScope.java @@ -0,0 +1,33 @@ +/* + * Copyright (c) 2018-2019 Uber Technologies, Inc. + * + * 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 demo; + + +@motif.Scope +public interface RootScope { + + String foo(); + + @motif.Objects + abstract class Objects { + + abstract Bar bar(); + + String foo(int param) { + return String.valueOf(param); + } + } +} diff --git a/samples/sample/src/main/java/demo/RootScope2.java b/samples/sample/src/main/java/demo/RootScope2.java new file mode 100644 index 00000000..68fce7ad --- /dev/null +++ b/samples/sample/src/main/java/demo/RootScope2.java @@ -0,0 +1,33 @@ +/* + * Copyright (c) 2018-2019 Uber Technologies, Inc. + * + * 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 demo; + + +@motif.Scope(useNullFieldInitialization = true) +public interface RootScope2 { + + String foo(); + + @motif.Objects + abstract class Objects { + + abstract Bar bar(); + + String foo(int param) { + return String.valueOf(param); + } + } +} diff --git a/samples/sample/src/test/java/motif/sample/app/root/RootScopeTest.java b/samples/sample/src/test/java/motif/sample/app/root/RootScopeTest.java index 30555c79..ce8659fe 100644 --- a/samples/sample/src/test/java/motif/sample/app/root/RootScopeTest.java +++ b/samples/sample/src/test/java/motif/sample/app/root/RootScopeTest.java @@ -15,10 +15,18 @@ */ package motif.sample.app.root; +import com.google.common.truth.Truth; +import demo.RootScope2Impl; +import demo.RootScope2Impl.Dependencies; import org.junit.Test; public class RootScopeTest { @Test - public void testIt() {} + public void testIt() { + Dependencies dependencies = () -> 123; + RootScope2Impl rootScope2 = new RootScope2Impl(dependencies); + String foo = rootScope2.foo(); + Truth.assertThat(foo).isEqualTo("123"); + } } diff --git a/samples/sample/src/test/java/motif/sample/app/root/manual_1/RootScope.java b/samples/sample/src/test/java/motif/sample/app/root/manual_1/RootScope.java new file mode 100644 index 00000000..169db4b4 --- /dev/null +++ b/samples/sample/src/test/java/motif/sample/app/root/manual_1/RootScope.java @@ -0,0 +1,18 @@ +package motif.sample.app.root.manual_1; + +import demo.Bar; + +public interface RootScope { + + String foo(); + + @motif.Objects + abstract class Objects { + + abstract Bar bar(); + + String foo(int param) { + return String.valueOf(param); + } + } +} diff --git a/samples/sample/src/test/java/motif/sample/app/root/manual_1/RootScopeImpl.java b/samples/sample/src/test/java/motif/sample/app/root/manual_1/RootScopeImpl.java new file mode 100644 index 00000000..9780d18e --- /dev/null +++ b/samples/sample/src/test/java/motif/sample/app/root/manual_1/RootScopeImpl.java @@ -0,0 +1,73 @@ +package motif.sample.app.root.manual_1; + +import demo.Bar; +import motif.internal.None; + +public class RootScopeImpl implements RootScope { + + private final RootScope.Objects objects = new Objects(); + + private final Dependencies dependencies; + + private volatile Object bar = None.NONE; + + private volatile Object string = None.NONE; + + public RootScopeImpl(Dependencies dependencies) { + this.dependencies = dependencies; + } + + @Override + public String foo() { + return string(); + } + + RootScope rootScope() { + return this; + } + + Bar bar() { + if (bar == None.NONE) { + synchronized (this) { + if (bar == None.NONE) { + bar = new Bar(); + } + } + } + return (Bar) bar; + } + + String string() { + if (string == None.NONE) { + synchronized (this) { + if (string == None.NONE) { + string = objects.foo(integer()); + } + } + } + return (String) string; + } + + int integer() { + return dependencies.integer(); + } + + public interface Dependencies { + + /** + *
      + * Requested from: + *
    • {@link demo.RootScope.Objects#foo(int)}
    • + *
    + */ + int integer(); + } + + private static class Objects extends RootScope.Objects { + + @Override + Bar bar() { + throw new UnsupportedOperationException(); + } + } +} diff --git a/samples/sample/src/test/java/motif/sample/app/root/manual_1/RootScopeManualTest.java b/samples/sample/src/test/java/motif/sample/app/root/manual_1/RootScopeManualTest.java new file mode 100644 index 00000000..1b1b4a66 --- /dev/null +++ b/samples/sample/src/test/java/motif/sample/app/root/manual_1/RootScopeManualTest.java @@ -0,0 +1,34 @@ +/* + * Copyright (c) 2018-2019 Uber Technologies, Inc. + * + * 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 motif.sample.app.root.manual_1; + +import com.google.common.truth.Truth; +import demo.Bar; +import motif.sample.app.root.manual_1.RootScopeImpl.Dependencies; +import org.junit.Test; + +public class RootScopeManualTest { + + @Test + public void testIt() { + Dependencies dependencies = () -> 123; + RootScopeImpl rootScope2 = new RootScopeImpl(dependencies); + Bar bar1 = rootScope2.bar(); + Bar bar2 = rootScope2.bar(); + Truth.assertThat(bar2).isEqualTo(bar1); +// Truth.assertThat(rootScope2.foo()).isEqualTo("123"); + } +} diff --git a/samples/sample/src/test/java/motif/sample/app/root/manual_2/RootScope.java b/samples/sample/src/test/java/motif/sample/app/root/manual_2/RootScope.java new file mode 100644 index 00000000..a2310c34 --- /dev/null +++ b/samples/sample/src/test/java/motif/sample/app/root/manual_2/RootScope.java @@ -0,0 +1,34 @@ +/* + * Copyright (c) 2018-2019 Uber Technologies, Inc. + * + * 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 motif.sample.app.root.manual_2; + + +import demo.Bar; + +public interface RootScope { + + String foo(); + + @motif.Objects + abstract class Objects { + + abstract Bar bar(); + + String foo(int param) { + return String.valueOf(param); + } + } +} diff --git a/samples/sample/src/test/java/motif/sample/app/root/manual_2/RootScopeImpl.java b/samples/sample/src/test/java/motif/sample/app/root/manual_2/RootScopeImpl.java new file mode 100644 index 00000000..0dee22f2 --- /dev/null +++ b/samples/sample/src/test/java/motif/sample/app/root/manual_2/RootScopeImpl.java @@ -0,0 +1,86 @@ +package motif.sample.app.root.manual_2; + +import demo.Bar; +import motif.internal.Initialized; + +public class RootScopeImpl implements RootScope { + + private final RootScope.Objects objects = new Objects(); + + private final Dependencies dependencies; + + private volatile Object bar; + + private volatile Object string; + + public RootScopeImpl(Dependencies dependencies) { + this.dependencies = dependencies; + } + + @Override + public String foo() { + return string(); + } + + RootScope rootScope2() { + return this; + } + + Bar bar() { + Object _bar = bar; + if (_bar == null) { + synchronized (this) { + if (bar == null) { + _bar = new Bar(); + bar = _bar; + } + } + } + if (_bar == Initialized.INITIALIZED) { + return null; + } + return (Bar) _bar; + } + + String string() { + Object _string = string; + if (_string == null) { + synchronized (this) { + if (string == null) { + _string = objects.foo(integer()); + if (_string == null) { + _string = Initialized.INITIALIZED; + } + string = _string; + } + } + } + if (_string == Initialized.INITIALIZED) { + return null; + } + return (String) _string; + } + + int integer() { + return dependencies.integer(); + } + + public interface Dependencies { + + /** + *
      + * Requested from: + *
    • {@link demo.RootScope2.Objects#foo(int)}
    • + *
    + */ + int integer(); + } + + private static class Objects extends RootScope.Objects { + + @Override + Bar bar() { + throw new UnsupportedOperationException(); + } + } +} diff --git a/samples/sample/src/test/java/motif/sample/app/root/manual_2/RootScopeManualTest.java b/samples/sample/src/test/java/motif/sample/app/root/manual_2/RootScopeManualTest.java new file mode 100644 index 00000000..30c67fce --- /dev/null +++ b/samples/sample/src/test/java/motif/sample/app/root/manual_2/RootScopeManualTest.java @@ -0,0 +1,34 @@ +/* + * Copyright (c) 2018-2019 Uber Technologies, Inc. + * + * 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 motif.sample.app.root.manual_2; + +import com.google.common.truth.Truth; +import demo.Bar; +import motif.sample.app.root.manual_2.RootScopeImpl.Dependencies; +import org.junit.Test; + +public class RootScopeManualTest { + + @Test + public void testIt() { + Dependencies dependencies = () -> 123; + RootScopeImpl rootScope2 = new RootScopeImpl(dependencies); + Bar bar1 = rootScope2.bar(); + Bar bar2 = rootScope2.bar(); + Truth.assertThat(bar2).isEqualTo(bar1); +// Truth.assertThat(rootScope2.foo()).isEqualTo("123"); + } +} diff --git a/samples/sample/src/test/resources/java/1_raw.txt b/samples/sample/src/test/resources/java/1_raw.txt new file mode 100644 index 00000000..4f0212fa --- /dev/null +++ b/samples/sample/src/test/resources/java/1_raw.txt @@ -0,0 +1,77 @@ +package demo; + +import java.lang.Object; +import java.lang.Override; +import java.lang.String; +import java.lang.UnsupportedOperationException; +import motif.ScopeImpl; +import motif.internal.None; + +@ScopeImpl( + children = {}, + scope = RootScope.class, + dependencies = RootScopeImpl.Dependencies.class +) +public class RootScopeImpl implements RootScope { + private final RootScope.Objects objects = new Objects(); + + private final Dependencies dependencies; + + private volatile Object bar = None.NONE; + + private volatile Object string = None.NONE; + + public RootScopeImpl(Dependencies dependencies) { + this.dependencies = dependencies; + } + + @Override + public String foo() { + return string(); + } + + RootScope rootScope() { + return this; + } + + Bar bar() { + if (bar == None.NONE) { + synchronized (this) { + if (bar == None.NONE) { + bar = new Bar();} + } + } + return (Bar) bar; + } + + String string() { + if (string == None.NONE) { + synchronized (this) { + if (string == None.NONE) { + string = objects.foo(integer());} + } + } + return (String) string; + } + + int integer() { + return dependencies.integer(); + } + + public interface Dependencies { + /** + *
      + * Requested from: + *
    • {@link demo.RootScope.Objects#foo(int)}
    • + *
    + */ + int integer(); + } + + private static class Objects extends RootScope.Objects { + @Override + Bar bar() { + throw new UnsupportedOperationException(); + } + } +} diff --git a/samples/sample/src/test/resources/java/2_raw.txt b/samples/sample/src/test/resources/java/2_raw.txt new file mode 100644 index 00000000..1e1cca9b --- /dev/null +++ b/samples/sample/src/test/resources/java/2_raw.txt @@ -0,0 +1,95 @@ +package demo; + +import java.lang.Object; +import java.lang.Override; +import java.lang.String; +import java.lang.UnsupportedOperationException; +import motif.ScopeImpl; +import motif.internal.Initialized; + +@ScopeImpl( + children = {}, + scope = RootScope.class, + dependencies = RootScopeImpl.Dependencies.class +) +public class RootScopeImpl implements RootScope { + private final RootScope.Objects objects = new Objects(); + + private final Dependencies dependencies; + + private volatile Object bar; + + private volatile Object string; + + public RootScopeImpl(Dependencies dependencies) { + this.dependencies = dependencies; + } + + @Override + public String foo() { + return string(); + } + + RootScope rootScope() { + return this; + } + + Bar bar() { + Object _bar = bar; + if (_bar == null) { + synchronized (this) { + if (bar == null) { + _bar = new Bar(); + if (_bar == null) { + _bar = Initialized.INITIALIZED; + } + bar = _bar; + } + } + } + if (_bar == Initialized.INITIALIZED) { + return null; + } + return (Bar) _bar; + } + + String string() { + Object _string = string; + if (_string == null) { + synchronized (this) { + if (string == null) { + _string = objects.foo(integer()); + if (_string == null) { + _string = Initialized.INITIALIZED; + } + string = _string; + } + } + } + if (_string == Initialized.INITIALIZED) { + return null; + } + return (String) _string; + } + + int integer() { + return dependencies.integer(); + } + + public interface Dependencies { + /** + *
      + * Requested from: + *
    • {@link demo.RootScope.Objects#foo(int)}
    • + *
    + */ + int integer(); + } + + private static class Objects extends RootScope.Objects { + @Override + Bar bar() { + throw new UnsupportedOperationException(); + } + } +}