diff --git a/arrow-reflect-annotations/src/main/kotlin/arrow/meta/Meta.kt b/arrow-reflect-annotations/src/main/kotlin/arrow/meta/Meta.kt index 18a65ce..d581024 100644 --- a/arrow-reflect-annotations/src/main/kotlin/arrow/meta/Meta.kt +++ b/arrow-reflect-annotations/src/main/kotlin/arrow/meta/Meta.kt @@ -51,7 +51,7 @@ annotation class Meta { newElement: FirFunctionCall ): FirCall { val args = newElement.arguments - val argsApplied = args.mapIndexed { n, expr -> "args[$n] as ${+expr.typeRef}" } + val argsApplied = args.mapIndexed { n, expr -> "args[$n] as ${+expr.resolvedType}" } val name = newElement.toResolvedCallableSymbol()?.callableId?.asSingleFqName()?.asString() return compile( @@ -182,7 +182,7 @@ annotation class Meta { } interface ArrayOfCall : FrontendTransformer { - fun FirMetaCheckerContext.arrayOfCall(arrayOfCall: FirArrayOfCall): FirStatement + fun FirMetaCheckerContext.arrayOfCall(arrayOfCall: FirArrayLiteral): FirStatement } interface AssignmentOperatorStatement : FrontendTransformer { @@ -394,7 +394,7 @@ annotation class Meta { } interface QualifiedAccess : FrontendTransformer { - fun FirMetaCheckerContext.qualifiedAccess(qualifiedAccess: FirQualifiedAccess): FirStatement + fun FirMetaCheckerContext.qualifiedAccess(qualifiedAccess: FirQualifiedAccessExpression): FirStatement } interface QualifiedAccessExpression : FrontendTransformer { diff --git a/arrow-reflect-annotations/src/main/kotlin/arrow/meta/MetaContext.kt b/arrow-reflect-annotations/src/main/kotlin/arrow/meta/MetaContext.kt index 099f1d9..a5fdb45 100644 --- a/arrow-reflect-annotations/src/main/kotlin/arrow/meta/MetaContext.kt +++ b/arrow-reflect-annotations/src/main/kotlin/arrow/meta/MetaContext.kt @@ -19,6 +19,7 @@ import org.jetbrains.kotlin.fir.extensions.MemberGenerationContext import org.jetbrains.kotlin.fir.symbols.SymbolInternals import org.jetbrains.kotlin.fir.symbols.impl.FirClassSymbol import org.jetbrains.kotlin.fir.symbols.impl.FirRegularClassSymbol +import org.jetbrains.kotlin.fir.types.ConeKotlinType import org.jetbrains.kotlin.fir.types.FirTypeRef import org.jetbrains.kotlin.fir.types.coneType import org.jetbrains.kotlin.fir.types.renderReadableWithFqNames @@ -128,6 +129,9 @@ abstract class FirMetaContext( ?: source?.text?.toString() ?: error("$this has no source psi text element") + operator fun ConeKotlinType.unaryPlus(): String = + type.renderReadableWithFqNames().replace("/", ".") + val String.call: FirCall get() = compile( diff --git a/arrow-reflect-annotations/src/main/kotlin/arrow/meta/TemplateCompiler.kt b/arrow-reflect-annotations/src/main/kotlin/arrow/meta/TemplateCompiler.kt index dd85c67..534e817 100644 --- a/arrow-reflect-annotations/src/main/kotlin/arrow/meta/TemplateCompiler.kt +++ b/arrow-reflect-annotations/src/main/kotlin/arrow/meta/TemplateCompiler.kt @@ -1,3 +1,5 @@ +@file:OptIn(PrivateForInline::class) + package arrow.meta import com.intellij.psi.PsiDocumentManager @@ -6,21 +8,29 @@ import org.jetbrains.kotlin.KtInMemoryTextSourceFile import org.jetbrains.kotlin.KtIoFileSourceFile import org.jetbrains.kotlin.KtSourceFile import org.jetbrains.kotlin.backend.jvm.JvmIrDeserializerImpl +import org.jetbrains.kotlin.backend.jvm.JvmIrTypeSystemContext +import org.jetbrains.kotlin.builtins.DefaultBuiltIns import org.jetbrains.kotlin.cli.common.messages.* import org.jetbrains.kotlin.cli.common.messages.CompilerMessageSeverity.* import org.jetbrains.kotlin.cli.common.modules.ModuleBuilder import org.jetbrains.kotlin.cli.jvm.compiler.* import org.jetbrains.kotlin.config.* +import org.jetbrains.kotlin.constant.EvaluatedConstTracker import org.jetbrains.kotlin.diagnostics.* import org.jetbrains.kotlin.diagnostics.impl.BaseDiagnosticsCollector import org.jetbrains.kotlin.fir.* import org.jetbrains.kotlin.fir.analysis.collectors.FirDiagnosticsCollector +import org.jetbrains.kotlin.fir.backend.Fir2IrConfiguration import org.jetbrains.kotlin.fir.backend.Fir2IrResult +import org.jetbrains.kotlin.fir.backend.jvm.FirJvmVisibilityConverter import org.jetbrains.kotlin.fir.backend.jvm.JvmFir2IrExtensions +import org.jetbrains.kotlin.fir.builder.AbstractRawFirBuilder import org.jetbrains.kotlin.fir.builder.BodyBuildingMode -import org.jetbrains.kotlin.fir.builder.RawFirBuilder +import org.jetbrains.kotlin.fir.builder.PsiRawFirBuilder import org.jetbrains.kotlin.fir.declarations.* import org.jetbrains.kotlin.fir.lightTree.LightTree2Fir +import org.jetbrains.kotlin.fir.pipeline.Fir2IrActualizedResult +import org.jetbrains.kotlin.fir.pipeline.ModuleCompilerAnalyzedOutput import org.jetbrains.kotlin.fir.resolve.* import org.jetbrains.kotlin.fir.resolve.calls.ImplicitDispatchReceiverValue import org.jetbrains.kotlin.fir.resolve.dfa.DataFlowAnalyzerContext @@ -53,6 +63,12 @@ import org.jetbrains.kotlin.readSourceFileWithMapping import java.io.File import java.util.concurrent.atomic.AtomicInteger import org.jetbrains.kotlin.fir.pipeline.convertToIrAndActualize +import org.jetbrains.kotlin.fir.pipeline.convertToIrAndActualizeForJvm +import org.jetbrains.kotlin.fir.resolve.providers.FirSymbolProvider +import org.jetbrains.kotlin.fir.resolve.providers.impl.FirCachingCompositeSymbolProvider +import org.jetbrains.kotlin.fir.resolve.providers.symbolProvider +import org.jetbrains.kotlin.util.PrivateForInline +import kotlin.reflect.jvm.internal.impl.builtins.jvm.JvmBuiltIns class FirResult( val session: FirSession, @@ -87,7 +103,7 @@ class TemplateCompiler( data class TemplateResult( val firResults: List, - val irResults: List + val irResults: List ) var compiling: Boolean = false @@ -105,7 +121,7 @@ class TemplateCompiler( println("parsing source:\n$source") println("session: ${session::class}") val outputs: ArrayList = arrayListOf() - val irOutput: ArrayList = arrayListOf() + val irOutput: ArrayList = arrayListOf() val messageCollector: MessageCollector = MessageCollector.NONE for (module in chunk) { val moduleConfiguration = projectConfiguration//.applyModuleProperties(module, buildFile) @@ -121,7 +137,7 @@ class TemplateCompiler( if (produceIr) { outputs.forEach { - irOutput.add(convertToIR(it, moduleConfiguration)) + irOutput.add(convertToIR(metaCheckerContext, it, moduleConfiguration)) } } } @@ -147,18 +163,46 @@ class TemplateCompiler( return firResult } - fun convertToIR(firResult: FirResult, moduleConfiguration: CompilerConfiguration): Fir2IrResult { + fun convertToIR(metaCheckerContext: FirMetaCheckerContext?, firResult: FirResult, moduleConfiguration: CompilerConfiguration): Fir2IrActualizedResult { + val diagnosticReporter = DiagnosticReporterFactory.createPendingReporter() val fir2IrExtensions = JvmFir2IrExtensions(moduleConfiguration, JvmIrDeserializerImpl(), JvmIrMangler) - val linkViaSignatures = moduleConfiguration.getBoolean(JVMConfigurationKeys.LINK_VIA_SIGNATURES) val scopeFiles = firResult.scopeDeclarations.filterIsInstance() val files = firResult.files + scopeFiles val validatedFirResult = with(firResult) { - org.jetbrains.kotlin.fir.pipeline.FirResult(platformOutput = org.jetbrains.kotlin.fir.pipeline.ModuleCompilerAnalyzedOutput( - session = session, scopeSession = scopeSession, fir = files - ), commonOutput = null) + org.jetbrains.kotlin.fir.pipeline.FirResult( + listOf( + ModuleCompilerAnalyzedOutput(session = session, scopeSession = scopeSession, fir = files) + ) + ) } - val fir2IrResult = validatedFirResult.convertToIrAndActualize(fir2IrExtensions= fir2IrExtensions, irGeneratorExtensions = emptyList(), linkViaSignatures = linkViaSignatures) + + val fir2IrConfiguration = Fir2IrConfiguration( + languageVersionSettings = moduleConfiguration.languageVersionSettings, + diagnosticReporter = diagnosticReporter, + linkViaSignatures = moduleConfiguration.getBoolean(JVMConfigurationKeys.LINK_VIA_SIGNATURES), + evaluatedConstTracker = moduleConfiguration + .putIfAbsent(CommonConfigurationKeys.EVALUATED_CONST_TRACKER, EvaluatedConstTracker.create()), + inlineConstTracker = moduleConfiguration[CommonConfigurationKeys.INLINE_CONST_TRACKER], + // TODO: read notes on these new flags + allowNonCachedDeclarations = false, + // TODO: see KT-61514 + useIrFakeOverrideBuilder = moduleConfiguration.getBoolean(CommonConfigurationKeys.USE_IR_FAKE_OVERRIDE_BUILDER) + ) + + val fir2IrResult = validatedFirResult.convertToIrAndActualizeForJvm( + fir2IrExtensions= fir2IrExtensions, + irGeneratorExtensions = emptyList(), + fir2IrConfiguration = fir2IrConfiguration, + ) ProgressIndicatorAndCompilationCanceledStatus.checkCanceled() + val diagnosticsContext = metaCheckerContext?.checkerContext + if (diagnosticsContext != null) { + diagnosticReporter.diagnostics.forEach { + metaCheckerContext.diagnosticReporter.report(it, diagnosticsContext) + println("error: [" + it.factory.name + "] " + it.factory.ktRenderer.render(it)) + } + } + return fir2IrResult } @@ -204,20 +248,31 @@ class TemplateCompiler( val scopeSession: ScopeSession, scopeDeclarations: List ) { - private val processors: List = createAllCompilerResolveProcessors( session, scopeSession, scopeDeclarations ) + @OptIn(SessionConfiguration::class) fun process(files: List) { for (processor in processors) { + if (processor.session.symbolProvider is FirCachingCompositeSymbolProvider) { + // TODO: clear the cache? + //val wrapProviders = (processor.session.symbolProvider as FirCachingCompositeSymbolProvider).providers + // TODO: or keep the cache and wrap it to prevent clearing: + val wrapProviders = listOf(processor.session.symbolProvider) + processor.session.register(FirSymbolProvider::class, + FirCachingCompositeSymbolProvider(processor.session, wrapProviders, true) + ) + } processor.beforePhase() when (processor) { is FirTransformerBasedResolveProcessor -> { for (file in files) { - processor.processFile(file) + withFileAnalysisExceptionWrapping(file) { + processor.processFile(file) + } } } @@ -258,7 +313,7 @@ class TemplateCompiler( fun FirSession.buildFirFromKtFiles(ktFiles: Collection): List { val firProvider = (firProvider as? FirProviderImpl) - val builder = RawFirBuilder(this, kotlinScopeProvider, BodyBuildingMode.NORMAL) + val builder = PsiRawFirBuilder(this, kotlinScopeProvider, BodyBuildingMode.NORMAL) return ktFiles.map { builder.buildFirFile(it).also { firFile -> firProvider?.recordFile(firFile) @@ -345,7 +400,7 @@ class FirBodyResolveTransformerAdapter( implicitTypeOnly = false, scopeSession = scopeSession, outerBodyResolveContext = BodyResolveContext( - ReturnTypeCalculatorForFullBodyResolve, + ReturnTypeCalculatorForFullBodyResolve.Default, DataFlowAnalyzerContext(session), scopeDeclarations.filterIsInstance().toSet() ) diff --git a/arrow-reflect-compiler-plugin/src/main/kotlin/arrow/reflect/compiler/plugin/fir/codegen/FirMetaCodegenExtension.kt b/arrow-reflect-compiler-plugin/src/main/kotlin/arrow/reflect/compiler/plugin/fir/codegen/FirMetaCodegenExtension.kt index 45fe6fa..3d120f7 100644 --- a/arrow-reflect-compiler-plugin/src/main/kotlin/arrow/reflect/compiler/plugin/fir/codegen/FirMetaCodegenExtension.kt +++ b/arrow-reflect-compiler-plugin/src/main/kotlin/arrow/reflect/compiler/plugin/fir/codegen/FirMetaCodegenExtension.kt @@ -9,10 +9,7 @@ import org.jetbrains.kotlin.fir.FirElement import org.jetbrains.kotlin.fir.FirSession import org.jetbrains.kotlin.fir.declarations.* import org.jetbrains.kotlin.fir.declarations.builder.buildSimpleFunctionCopy -import org.jetbrains.kotlin.fir.extensions.AnnotationFqn -import org.jetbrains.kotlin.fir.extensions.FirDeclarationGenerationExtension -import org.jetbrains.kotlin.fir.extensions.FirDeclarationPredicateRegistrar -import org.jetbrains.kotlin.fir.extensions.MemberGenerationContext +import org.jetbrains.kotlin.fir.extensions.* import org.jetbrains.kotlin.fir.extensions.predicate.DeclarationPredicate import org.jetbrains.kotlin.fir.resolve.defaultType import org.jetbrains.kotlin.fir.resolve.providers.symbolProvider @@ -37,7 +34,7 @@ class FirMetaCodegenExtension( private fun metaContext(generationContext: MemberGenerationContext?): FirMetaContext = FirMetaMemberGenerationContext(templateCompiler, session, generationContext) - override fun generateNestedClassLikeDeclaration(owner: FirClassSymbol<*>, name: Name): FirClassLikeSymbol<*>? { + override fun generateNestedClassLikeDeclaration(owner: FirClassSymbol<*>, name: Name, context: NestedClassGenerationContext): FirClassLikeSymbol<*>? { return if (!templateCompiler.compiling) { val firClass: FirClass? = invokeMeta( true, @@ -46,7 +43,7 @@ class FirMetaCodegenExtension( Meta.Generate.Members.NestedClasses::class, "nestedClasses" ) - firClass?.symbol ?: super.generateNestedClassLikeDeclaration(owner, name) + firClass?.symbol ?: super.generateNestedClassLikeDeclaration(owner, name, context) } else null } @@ -142,7 +139,7 @@ class FirMetaCodegenExtension( } else super.generateProperties(callableId, context) } - override fun getCallableNamesForClass(classSymbol: FirClassSymbol<*>): Set = + override fun getCallableNamesForClass(classSymbol: FirClassSymbol<*>, context: MemberGenerationContext): Set = constructors(classSymbol).orEmpty() + properties(classSymbol).orEmpty() + functions(classSymbol).orEmpty() @@ -197,7 +194,7 @@ class FirMetaCodegenExtension( ) // else null - override fun getNestedClassifiersNames(classSymbol: FirClassSymbol<*>): Set = + override fun getNestedClassifiersNames(classSymbol: FirClassSymbol<*>, context: NestedClassGenerationContext): Set = nestedClasses(classSymbol).orEmpty() fun topLevelFunctions(): Set? = diff --git a/arrow-reflect-compiler-plugin/src/test/kotlin/arrow/reflect/compiler/plugin/runners/BaseTestRunner.kt b/arrow-reflect-compiler-plugin/src/test/kotlin/arrow/reflect/compiler/plugin/runners/BaseTestRunner.kt index 6a355af..d5c9ef0 100644 --- a/arrow-reflect-compiler-plugin/src/test/kotlin/arrow/reflect/compiler/plugin/runners/BaseTestRunner.kt +++ b/arrow-reflect-compiler-plugin/src/test/kotlin/arrow/reflect/compiler/plugin/runners/BaseTestRunner.kt @@ -2,9 +2,11 @@ package arrow.reflect.compiler.plugin.runners import arrow.reflect.compiler.plugin.services.* import org.jetbrains.kotlin.platform.jvm.JvmPlatforms +import org.jetbrains.kotlin.test.FirParser import org.jetbrains.kotlin.test.TargetBackend import org.jetbrains.kotlin.test.builders.TestConfigurationBuilder import org.jetbrains.kotlin.test.directives.FirDiagnosticsDirectives +import org.jetbrains.kotlin.test.directives.configureFirParser import org.jetbrains.kotlin.test.frontend.fir.FirFrontendFacade import org.jetbrains.kotlin.test.initIdeaConfiguration import org.jetbrains.kotlin.test.model.DependencyKind @@ -37,6 +39,8 @@ fun TestConfigurationBuilder.commonFirWithPluginFrontendConfiguration() { +AdditionalFilesDirectives.SOME_FILE_DIRECTIVE } + configureFirParser(FirParser.LightTree) + globalDefaults { targetBackend = TargetBackend.JVM_IR targetPlatform = JvmPlatforms.defaultJvmPlatform diff --git a/arrow-reflect-compiler-plugin/src/test/kotlin/arrow/reflect/compiler/plugin/services/PluginAnnotationsConfigurator.kt b/arrow-reflect-compiler-plugin/src/test/kotlin/arrow/reflect/compiler/plugin/services/PluginAnnotationsConfigurator.kt index a9f18e1..da3293f 100644 --- a/arrow-reflect-compiler-plugin/src/test/kotlin/arrow/reflect/compiler/plugin/services/PluginAnnotationsConfigurator.kt +++ b/arrow-reflect-compiler-plugin/src/test/kotlin/arrow/reflect/compiler/plugin/services/PluginAnnotationsConfigurator.kt @@ -2,7 +2,9 @@ package arrow.reflect.compiler.plugin.services import org.jetbrains.kotlin.cli.jvm.config.addJvmClasspathRoot import org.jetbrains.kotlin.config.CompilerConfiguration +import org.jetbrains.kotlin.test.FirParser import org.jetbrains.kotlin.test.builders.TestConfigurationBuilder +import org.jetbrains.kotlin.test.directives.configureFirParser import org.jetbrains.kotlin.test.model.TestModule import org.jetbrains.kotlin.test.services.EnvironmentConfigurator import org.jetbrains.kotlin.test.services.RuntimeClasspathProvider @@ -58,5 +60,6 @@ class MetaRuntimeClasspathProvider(testServices: TestServices) : RuntimeClasspat fun TestConfigurationBuilder.configureForRuntimeAnnotationLibrary() { useConfigurators(::PluginAnnotationsConfigurator) useCustomRuntimeClasspathProviders(::MetaRuntimeClasspathProvider) + configureFirParser(FirParser.LightTree) } diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index c1dbd32..67f76fd 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -1,7 +1,7 @@ [versions] arrowGradleConfig = "0.11.0" classgraph = "4.8.154" -kotlin = "1.8.255-SNAPSHOT" +kotlin = "1.9.30-dev-3330" reflections = "0.10.2" [libraries] diff --git a/sandbox/build.gradle.kts b/sandbox/build.gradle.kts index 8c693dc..b3fd2d4 100644 --- a/sandbox/build.gradle.kts +++ b/sandbox/build.gradle.kts @@ -1,10 +1,11 @@ import org.jetbrains.kotlin.gradle.dsl.JvmTarget +import org.jetbrains.kotlin.gradle.dsl.KotlinVersion import org.jetbrains.kotlin.gradle.tasks.KotlinCompile -val kotlinVersion = "1.8.255-SNAPSHOT" +val kotlinVersion = "1.9.30-dev-3330" plugins { - id("org.jetbrains.kotlin.jvm") version "1.8.255-SNAPSHOT" + id("org.jetbrains.kotlin.jvm") version "1.9.30-dev-3330" id("io.arrow-kt.reflect") version "0.1.0" application } @@ -22,7 +23,7 @@ tasks { withType().configureEach { compilerOptions { jvmTarget.set(JvmTarget.JVM_1_8) - useK2.set(true) + languageVersion.set(KotlinVersion.KOTLIN_2_0) freeCompilerArgs.add("-Xcontext-receivers") } } diff --git a/sandbox/gradle/libs.versions.toml b/sandbox/gradle/libs.versions.toml index c1dbd32..67f76fd 100644 --- a/sandbox/gradle/libs.versions.toml +++ b/sandbox/gradle/libs.versions.toml @@ -1,7 +1,7 @@ [versions] arrowGradleConfig = "0.11.0" classgraph = "4.8.154" -kotlin = "1.8.255-SNAPSHOT" +kotlin = "1.9.30-dev-3330" reflections = "0.10.2" [libraries] diff --git a/sandbox/settings.gradle.kts b/sandbox/settings.gradle.kts index eb53e75..2efdbf7 100644 --- a/sandbox/settings.gradle.kts +++ b/sandbox/settings.gradle.kts @@ -1,29 +1,31 @@ pluginManagement { repositories { - mavenCentral() - gradlePluginPortal() - maven(url = "https://oss.sonatype.org/content/repositories/snapshots") - maven(url = "https://maven.pkg.jetbrains.space/kotlin/p/kotlin/bootstrap") mavenLocal { content { includeGroup("io.arrow-kt") includeGroup("io.arrow-kt.reflect") } } + mavenCentral() + gradlePluginPortal() + maven(url = "https://oss.sonatype.org/content/repositories/snapshots") + maven(url = "https://maven.pkg.jetbrains.space/kotlin/p/kotlin/bootstrap") + maven(url = "https://maven.pkg.jetbrains.space/kotlin/p/kotlin/dev/") } } dependencyResolutionManagement { repositories { - mavenCentral() - maven(url = "https://oss.sonatype.org/content/repositories/snapshots") - maven(url = "https://maven.pkg.jetbrains.space/kotlin/p/kotlin/bootstrap") mavenLocal { content { includeGroup("io.arrow-kt") includeGroup("io.arrow-kt.reflect") } } + mavenCentral() + maven(url = "https://oss.sonatype.org/content/repositories/snapshots") + maven(url = "https://maven.pkg.jetbrains.space/kotlin/p/kotlin/bootstrap") + maven(url = "https://maven.pkg.jetbrains.space/kotlin/p/kotlin/dev/") } } diff --git a/settings.gradle.kts b/settings.gradle.kts index e403e1a..782dbcc 100644 --- a/settings.gradle.kts +++ b/settings.gradle.kts @@ -1,30 +1,32 @@ pluginManagement { repositories { - mavenCentral() - gradlePluginPortal() - maven(url = "https://oss.sonatype.org/content/repositories/snapshots") - maven(url = "https://maven.pkg.jetbrains.space/kotlin/p/kotlin/bootstrap") mavenLocal { content { includeGroup("io.arrow-kt") includeGroup("io.arrow-kt.reflect") } } + mavenCentral() + gradlePluginPortal() + maven(url = "https://oss.sonatype.org/content/repositories/snapshots") + maven(url = "https://maven.pkg.jetbrains.space/kotlin/p/kotlin/bootstrap") + maven(url = "https://maven.pkg.jetbrains.space/kotlin/p/kotlin/dev/") } } dependencyResolutionManagement { repositories { - mavenCentral() - gradlePluginPortal() - maven(url = "https://oss.sonatype.org/content/repositories/snapshots") - maven(url = "https://maven.pkg.jetbrains.space/kotlin/p/kotlin/bootstrap") mavenLocal { content { includeGroup("io.arrow-kt") includeGroup("io.arrow-kt.reflect") } } + mavenCentral() + gradlePluginPortal() + maven(url = "https://oss.sonatype.org/content/repositories/snapshots") + maven(url = "https://maven.pkg.jetbrains.space/kotlin/p/kotlin/bootstrap") + maven(url = "https://maven.pkg.jetbrains.space/kotlin/p/kotlin/dev/") } }