From 283fefca34bd8012c0bf30d560bdb0fd0c023e66 Mon Sep 17 00:00:00 2001 From: James Barr Date: Tue, 11 Feb 2025 11:53:44 -0800 Subject: [PATCH 01/11] 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 06c52114696d07e74bf8852b991818ef174da3f8 Mon Sep 17 00:00:00 2001 From: James Barr Date: Tue, 11 Feb 2025 11:55:59 -0800 Subject: [PATCH 02/11] 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 d7019bb4d63f0af1794f19ea8a6140a844350e60 Mon Sep 17 00:00:00 2001 From: James Barr Date: Tue, 11 Feb 2025 11:56:55 -0800 Subject: [PATCH 03/11] 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 62fd78eff04e11573db3ba531d33b79ed432fd27 Mon Sep 17 00:00:00 2001 From: James Barr Date: Tue, 11 Feb 2025 12:00:21 -0800 Subject: [PATCH 04/11] 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 a441458b9ff569e52066592ac4e15d5a06833e21 Mon Sep 17 00:00:00 2001 From: James Barr Date: Tue, 11 Feb 2025 12:53:58 -0800 Subject: [PATCH 05/11] 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 05c90408ab621802ea18e59dec4a41a0b04a2a93 Mon Sep 17 00:00:00 2001 From: James Barr Date: Tue, 11 Feb 2025 12:55:39 -0800 Subject: [PATCH 06/11] 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 f9e01c5ca2d22e375a88d62f09a69d7b66aead33 Mon Sep 17 00:00:00 2001 From: James Barr Date: Tue, 11 Feb 2025 14:15:23 -0800 Subject: [PATCH 07/11] 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 054b13039e858402aefdd295a0d946e33a4243f6 Mon Sep 17 00:00:00 2001 From: James Barr Date: Tue, 11 Feb 2025 15:17:54 -0800 Subject: [PATCH 08/11] 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 8f7a525edcb74918c688e90ede2cf15dace737b9 Mon Sep 17 00:00:00 2001 From: James Barr Date: Wed, 12 Feb 2025 00:19:02 -0800 Subject: [PATCH 09/11] 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 4b4e380bc5bac857ad70b3b37ca38fcf3df79fdd Mon Sep 17 00:00:00 2001 From: James Barr Date: Wed, 12 Feb 2025 14:35:56 -0800 Subject: [PATCH 10/11] 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 854fbf46722a7ad49f8b7562a2f00d2a5b77f39e Mon Sep 17 00:00:00 2001 From: James Barr Date: Wed, 12 Feb 2025 15:22:24 -0800 Subject: [PATCH 11/11] 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 }