diff --git a/SKIE/acceptance-tests b/SKIE/acceptance-tests index 79d538005..77aad4c97 160000 --- a/SKIE/acceptance-tests +++ b/SKIE/acceptance-tests @@ -1 +1 @@ -Subproject commit 79d5380054ad9a1ea597c7a1b1caf5bbff33a411 +Subproject commit 77aad4c975d1191da10199ce668424ec47aded64 diff --git a/SKIE/common/util/src/commonMain/kotlin/co/touchlab/skie/util/directory/SkieBuildDirectory.kt b/SKIE/common/util/src/commonMain/kotlin/co/touchlab/skie/util/directory/SkieBuildDirectory.kt index c5959fcca..37b24c887 100644 --- a/SKIE/common/util/src/commonMain/kotlin/co/touchlab/skie/util/directory/SkieBuildDirectory.kt +++ b/SKIE/common/util/src/commonMain/kotlin/co/touchlab/skie/util/directory/SkieBuildDirectory.kt @@ -77,8 +77,7 @@ class SkieBuildDirectory( val custom: Custom = Custom(this) - class Generated(parent: Directory) : PermanentDirectory(parent, "generated") { - } + class Generated(parent: Directory) : PermanentDirectory(parent, "generated") class Custom(parent: Directory) : PermanentDirectory(parent, "custom") } @@ -99,9 +98,11 @@ class SkieBuildDirectory( class ObjectFiles(parent: Directory) : PermanentDirectory(parent, "object-files") { + // WIP Replace val allFiles: List get() = directory.walkTopDown().toList() + // WIP Replace val allObjectFiles: List get() = allFiles.filter { it.extension == "o" } diff --git a/SKIE/compiler/kotlin-plugin/src/kgp_common/kotlin/co/touchlab/skie/context/SirPhaseContext.kt b/SKIE/compiler/kotlin-plugin/src/kgp_common/kotlin/co/touchlab/skie/context/SirPhaseContext.kt index cdbd76d14..a24a734f2 100644 --- a/SKIE/compiler/kotlin-plugin/src/kgp_common/kotlin/co/touchlab/skie/context/SirPhaseContext.kt +++ b/SKIE/compiler/kotlin-plugin/src/kgp_common/kotlin/co/touchlab/skie/context/SirPhaseContext.kt @@ -10,8 +10,9 @@ import co.touchlab.skie.oir.type.translation.OirTypeTranslator import co.touchlab.skie.phases.SirPhase import co.touchlab.skie.phases.SkiePhase import co.touchlab.skie.phases.oir.util.ExternalApiNotesProvider +import co.touchlab.skie.sir.ClassNamespaceProvider +import co.touchlab.skie.sir.SirFileProvider import co.touchlab.skie.sir.SirProvider -import co.touchlab.skie.sir.SkieNamespaceProvider import co.touchlab.skie.sir.builtin.SirBuiltins import co.touchlab.skie.sir.type.translation.SirTypeTranslator import org.jetbrains.kotlin.backend.konan.objcexport.ObjCExportNamer @@ -30,13 +31,15 @@ class SirPhaseContext( override val sirProvider: SirProvider = SirProvider(framework, kirProvider, configurationProvider, skieConfiguration) + override val sirFileProvider: SirFileProvider = sirProvider.fileProvider + override val kirBuiltins: KirBuiltins = kirProvider.kirBuiltins override val oirBuiltins: OirBuiltins = oirProvider.oirBuiltins override val sirBuiltins: SirBuiltins = sirProvider.sirBuiltins - override val skieNamespaceProvider: SkieNamespaceProvider = SkieNamespaceProvider( + override val classNamespaceProvider: ClassNamespaceProvider = ClassNamespaceProvider( kirProvider = kirProvider, sirProvider = sirProvider, mainModuleDescriptor = mainSkieContext.mainModuleDescriptor, diff --git a/SKIE/compiler/kotlin-plugin/src/kgp_common/kotlin/co/touchlab/skie/oir/element/OirExtension.kt b/SKIE/compiler/kotlin-plugin/src/kgp_common/kotlin/co/touchlab/skie/oir/element/OirExtension.kt index 6710415ba..f14bd9a3e 100644 --- a/SKIE/compiler/kotlin-plugin/src/kgp_common/kotlin/co/touchlab/skie/oir/element/OirExtension.kt +++ b/SKIE/compiler/kotlin-plugin/src/kgp_common/kotlin/co/touchlab/skie/oir/element/OirExtension.kt @@ -7,6 +7,7 @@ class OirExtension( override val parent: OirTopLevelDeclarationParent, ) : OirTopLevelDeclaration, OirCallableDeclarationParent { + // WIP Should be set lateinit var sirExtension: SirExtension override val callableDeclarations: MutableList = mutableListOf() diff --git a/SKIE/compiler/kotlin-plugin/src/kgp_common/kotlin/co/touchlab/skie/phases/SirPhase.kt b/SKIE/compiler/kotlin-plugin/src/kgp_common/kotlin/co/touchlab/skie/phases/SirPhase.kt index 6f89ccd6d..098ce34c0 100644 --- a/SKIE/compiler/kotlin-plugin/src/kgp_common/kotlin/co/touchlab/skie/phases/SirPhase.kt +++ b/SKIE/compiler/kotlin-plugin/src/kgp_common/kotlin/co/touchlab/skie/phases/SirPhase.kt @@ -8,7 +8,8 @@ import co.touchlab.skie.oir.builtin.OirBuiltins import co.touchlab.skie.oir.type.translation.OirTypeTranslator import co.touchlab.skie.phases.oir.util.ExternalApiNotesProvider import co.touchlab.skie.sir.SirProvider -import co.touchlab.skie.sir.SkieNamespaceProvider +import co.touchlab.skie.sir.ClassNamespaceProvider +import co.touchlab.skie.sir.SirFileProvider import co.touchlab.skie.sir.builtin.SirBuiltins import co.touchlab.skie.sir.type.translation.SirTypeTranslator import org.jetbrains.kotlin.backend.konan.objcexport.ObjCExportNamer @@ -25,13 +26,15 @@ interface SirPhase : SkiePhase { val sirProvider: SirProvider + val sirFileProvider: SirFileProvider + val kirBuiltins: KirBuiltins val oirBuiltins: OirBuiltins val sirBuiltins: SirBuiltins - val skieNamespaceProvider: SkieNamespaceProvider + val classNamespaceProvider: ClassNamespaceProvider val externalApiNotesProvider: ExternalApiNotesProvider diff --git a/SKIE/compiler/kotlin-plugin/src/kgp_common/kotlin/co/touchlab/skie/phases/SkiePhaseScheduler.kt b/SKIE/compiler/kotlin-plugin/src/kgp_common/kotlin/co/touchlab/skie/phases/SkiePhaseScheduler.kt index c61f36836..4b34d782a 100644 --- a/SKIE/compiler/kotlin-plugin/src/kgp_common/kotlin/co/touchlab/skie/phases/SkiePhaseScheduler.kt +++ b/SKIE/compiler/kotlin-plugin/src/kgp_common/kotlin/co/touchlab/skie/phases/SkiePhaseScheduler.kt @@ -43,7 +43,7 @@ import co.touchlab.skie.phases.other.DeclareMissingSymbolsPhase import co.touchlab.skie.phases.other.DeleteSkieFrameworkContentPhase import co.touchlab.skie.phases.other.DisableWildcardExportPhase import co.touchlab.skie.phases.other.ExtraClassExportPhase -import co.touchlab.skie.phases.other.FixDuplicatedOverridenFunctionsPhase +import co.touchlab.skie.phases.other.FixDuplicatedOverriddenFunctionsPhase import co.touchlab.skie.phases.other.FixLibrariesShortNamePhase import co.touchlab.skie.phases.other.VerifyMinOSVersionPhase import co.touchlab.skie.phases.other.VerifyNoBitcodeEmbeddingPhase @@ -61,9 +61,9 @@ import co.touchlab.skie.phases.sir.type.CreateStableNameTypeAliasesPhase import co.touchlab.skie.phases.sir.type.FixNamesOfInaccessibleNestedClassesPhase import co.touchlab.skie.phases.sir.type.InitializeSirTypesSuperTypesForOirPhase import co.touchlab.skie.phases.swift.CompileSwiftPhase -import co.touchlab.skie.phases.swift.GenerateSirFileCodePhase +import co.touchlab.skie.phases.swift.ConvertSirIrFilesToSourceFilesPhase import co.touchlab.skie.phases.swift.SwiftCacheSetupPhase -import co.touchlab.skie.phases.swift.WriteSirFileContentToDiskPhase +import co.touchlab.skie.phases.swift.ConvertSirSourceFilesToCompilableFilesPhase import co.touchlab.skie.phases.typeconflicts.RenameTypesConflictingWithKeywordsPhase import co.touchlab.skie.phases.typeconflicts.RenameTypesConflictingWithKotlinModulePhase import co.touchlab.skie.phases.typeconflicts.RenameTypesConflictsWithOtherTypesPhase @@ -145,6 +145,7 @@ class SkiePhaseScheduler { KotlinRuntimeHidingPhase, SwiftRuntimeGenerator, + // WIP Load custom files RenameConflictingCallableDeclarationsPhase, @@ -181,7 +182,7 @@ class SkiePhaseScheduler { RenameCallableDeclarationsConflictingWithTypeDeclarationsPhase, RenameParametersNamedSelfPhase, RenameConflictingCallableDeclarationsPhase, - FixDuplicatedOverridenFunctionsPhase, + FixDuplicatedOverriddenFunctionsPhase, TemporarilyRenameTypesConflictingWithExternalModulesPhase, FixOirFunctionSignaturesForApiNotesPhase(context), CreateFakeObjCConstructorsPhase, @@ -195,8 +196,8 @@ class SkiePhaseScheduler { ApiNotesGenerationPhase.ForSwiftCompilation, FixForwardDeclarationsPhase(context), AddTypeDefPhase(context), - GenerateSirFileCodePhase, - WriteSirFileContentToDiskPhase, + ConvertSirIrFilesToSourceFilesPhase, + ConvertSirSourceFilesToCompilableFilesPhase, GenerateFakeObjCDependenciesPhase, DisableWildcardExportPhase, SwiftCacheSetupPhase, diff --git a/SKIE/compiler/kotlin-plugin/src/kgp_common/kotlin/co/touchlab/skie/phases/features/enums/ExhaustiveEnumsGenerator.kt b/SKIE/compiler/kotlin-plugin/src/kgp_common/kotlin/co/touchlab/skie/phases/features/enums/ExhaustiveEnumsGenerator.kt index 42b1a5026..16251ec85 100644 --- a/SKIE/compiler/kotlin-plugin/src/kgp_common/kotlin/co/touchlab/skie/phases/features/enums/ExhaustiveEnumsGenerator.kt +++ b/SKIE/compiler/kotlin-plugin/src/kgp_common/kotlin/co/touchlab/skie/phases/features/enums/ExhaustiveEnumsGenerator.kt @@ -12,8 +12,8 @@ import co.touchlab.skie.phases.util.doInPhase import co.touchlab.skie.sir.element.SirClass import co.touchlab.skie.sir.element.SirEnumCase import co.touchlab.skie.sir.element.SirExtension -import co.touchlab.skie.sir.element.SirFile import co.touchlab.skie.sir.element.SirGetter +import co.touchlab.skie.sir.element.SirIrFile import co.touchlab.skie.sir.element.SirProperty import co.touchlab.skie.sir.element.SirScope import co.touchlab.skie.sir.element.SirSimpleFunction @@ -79,9 +79,9 @@ private fun createBridgingEnum(enumKirClass: KirClass): SirClass = parent = enumKirClass.originalSirClass.namespace?.let { namespace -> sirProvider.getExtension( classDeclaration = namespace.classDeclaration, - parent = skieNamespaceProvider.getNamespaceFile(enumKirClass), + parent = classNamespaceProvider.getNamespaceFile(enumKirClass), ) - } ?: skieNamespaceProvider.getNamespaceFile(enumKirClass), + } ?: classNamespaceProvider.getNamespaceFile(enumKirClass), kind = SirClass.Kind.Enum, ).apply { addEnumCases(enumKirClass) @@ -146,14 +146,14 @@ private fun SirClass.addCompanionObjectPropertyIfNeeded(enum: KirClass) { context(SirPhase.Context) private fun KirClass.addConversionExtensions(bridgedEnum: SirClass) { - skieNamespaceProvider.getNamespaceFile(this).apply { + classNamespaceProvider.getNamespaceFile(this).apply { addToKotlinConversionExtension(originalSirClass, bridgedEnum) addToSwiftConversionExtension(originalSirClass, bridgedEnum) } } context(SirPhase.Context) -private fun SirFile.addToKotlinConversionExtension(enum: SirClass, bridgedEnum: SirClass) { +private fun SirIrFile.addToKotlinConversionExtension(enum: SirClass, bridgedEnum: SirClass) { this.getExtension( classDeclaration = bridgedEnum, ).apply { @@ -173,7 +173,7 @@ private fun SirExtension.addToKotlinConversionMethod(enum: SirClass) { } context(SirPhase.Context) -private fun SirFile.addToSwiftConversionExtension(enum: SirClass, bridgedEnum: SirClass) { +private fun SirIrFile.addToSwiftConversionExtension(enum: SirClass, bridgedEnum: SirClass) { this.getExtension( classDeclaration = enum, ).apply { @@ -200,7 +200,7 @@ private fun createStableNameTypeAliasIfRequested(bridgedEnum: SirClass, kirClass SirTypeAlias( baseName = "Enum", - parent = skieNamespaceProvider.getNamespace(kirClass), + parent = classNamespaceProvider.getNamespace(kirClass), visibility = SirVisibility.PublicButReplaced, ) { bridgedEnum.defaultType.withFqName() diff --git a/SKIE/compiler/kotlin-plugin/src/kgp_common/kotlin/co/touchlab/skie/phases/features/flow/FlowConversionConstructorsGenerator.kt b/SKIE/compiler/kotlin-plugin/src/kgp_common/kotlin/co/touchlab/skie/phases/features/flow/FlowConversionConstructorsGenerator.kt index 9f774dd32..59edc35b3 100644 --- a/SKIE/compiler/kotlin-plugin/src/kgp_common/kotlin/co/touchlab/skie/phases/features/flow/FlowConversionConstructorsGenerator.kt +++ b/SKIE/compiler/kotlin-plugin/src/kgp_common/kotlin/co/touchlab/skie/phases/features/flow/FlowConversionConstructorsGenerator.kt @@ -6,7 +6,7 @@ import co.touchlab.skie.sir.element.SirClass import co.touchlab.skie.sir.element.SirConditionalConstraint import co.touchlab.skie.sir.element.SirConstructor import co.touchlab.skie.sir.element.SirExtension -import co.touchlab.skie.sir.element.SirFile +import co.touchlab.skie.sir.element.SirIrFile import co.touchlab.skie.sir.element.SirSimpleFunction import co.touchlab.skie.sir.element.SirTypeParameter import co.touchlab.skie.sir.element.SirValueParameter @@ -28,34 +28,34 @@ class FlowConversionConstructorsGenerator( context(SirPhase.Context) override fun execute() { - val file = sirProvider.getSkieNamespaceFile("FlowConversions") + val file = sirFileProvider.getIrFileFromSkieNamespace("FlowConversions") SupportedFlow.values().forEach { it.generateAllConversions(file) } } - private fun SupportedFlow.generateAllConversions(file: SirFile) { + private fun SupportedFlow.generateAllConversions(file: SirIrFile) { requiredVariant.generateAllConversions(file) optionalVariant.generateAllConversions(file) } - private fun SupportedFlow.Variant.generateAllConversions(file: SirFile) { + private fun SupportedFlow.Variant.generateAllConversions(file: SirIrFile) { generateAllKotlinClassConversions(this, file) generateAllSwiftClassConversions(this, file) } - private fun generateAllKotlinClassConversions(variant: SupportedFlow.Variant, file: SirFile) { + private fun generateAllKotlinClassConversions(variant: SupportedFlow.Variant, file: SirIrFile) { generateKotlinClassWithAnyObjectConversions(variant, file) generateKotlinClassWithBridgeableConversions(variant, file) } - private fun generateAllSwiftClassConversions(variant: SupportedFlow.Variant, file: SirFile) { + private fun generateAllSwiftClassConversions(variant: SupportedFlow.Variant, file: SirIrFile) { generateSwiftClassWithAnyObjectConversions(variant, file) generateSwiftClassWithBridgeableConversions(variant, file) } - private fun generateKotlinClassWithAnyObjectConversions(variant: SupportedFlow.Variant, file: SirFile) { + private fun generateKotlinClassWithAnyObjectConversions(variant: SupportedFlow.Variant, file: SirIrFile) { file.addConversions(variant) { from -> addSwiftToKotlinConversion( from, @@ -65,7 +65,7 @@ class FlowConversionConstructorsGenerator( } } - private fun generateKotlinClassWithBridgeableConversions(variant: SupportedFlow.Variant, file: SirFile) { + private fun generateKotlinClassWithBridgeableConversions(variant: SupportedFlow.Variant, file: SirIrFile) { file.addConversions(variant) { from -> addSwiftToKotlinConversion( from, @@ -75,7 +75,7 @@ class FlowConversionConstructorsGenerator( } } - private fun generateSwiftClassWithAnyObjectConversions(variant: SupportedFlow.Variant, file: SirFile) { + private fun generateSwiftClassWithAnyObjectConversions(variant: SupportedFlow.Variant, file: SirIrFile) { generateSwiftClassConversions( variant, file, @@ -88,7 +88,7 @@ class FlowConversionConstructorsGenerator( } } - private fun generateSwiftClassWithBridgeableConversions(variant: SupportedFlow.Variant, file: SirFile) { + private fun generateSwiftClassWithBridgeableConversions(variant: SupportedFlow.Variant, file: SirIrFile) { generateSwiftClassConversions( variant, file, @@ -107,7 +107,7 @@ class FlowConversionConstructorsGenerator( private fun generateSwiftClassConversions( variant: SupportedFlow.Variant, - file: SirFile, + file: SirIrFile, typeBound: SirType, bodyFactory: SirExtension.(SirTypeParameter) -> Unit, ) { @@ -143,7 +143,7 @@ class FlowConversionConstructorsGenerator( .forEach(action) } - private fun SirFile.addSwiftToKotlinConversion( + private fun SirIrFile.addSwiftToKotlinConversion( from: SupportedFlow.Variant, to: SupportedFlow.Variant, typeBound: SirType, diff --git a/SKIE/compiler/kotlin-plugin/src/kgp_common/kotlin/co/touchlab/skie/phases/features/functions/FileScopeConversionParentProvider.kt b/SKIE/compiler/kotlin-plugin/src/kgp_common/kotlin/co/touchlab/skie/phases/features/functions/FileScopeConversionParentProvider.kt index c9e23f1de..9f2c3aa73 100644 --- a/SKIE/compiler/kotlin-plugin/src/kgp_common/kotlin/co/touchlab/skie/phases/features/functions/FileScopeConversionParentProvider.kt +++ b/SKIE/compiler/kotlin-plugin/src/kgp_common/kotlin/co/touchlab/skie/phases/features/functions/FileScopeConversionParentProvider.kt @@ -9,6 +9,7 @@ import co.touchlab.skie.sir.element.SirClass import co.touchlab.skie.sir.element.SirDeclarationParent import co.touchlab.skie.sir.element.SirExtension import co.touchlab.skie.sir.element.SirFile +import co.touchlab.skie.sir.element.SirIrFile import co.touchlab.skie.sir.element.SirSimpleFunction import co.touchlab.skie.sir.element.receiverDeclaration import co.touchlab.skie.sir.element.resolveAsKirClass @@ -54,7 +55,7 @@ class FileScopeConversionParentProvider( return when (callableDeclaration.origin) { KirCallableDeclaration.Origin.Member -> error("Member callable are not supported. Was: $callableDeclaration") KirCallableDeclaration.Origin.Extension -> getExtensions(callableDeclaration, sirCallableDeclaration) - KirCallableDeclaration.Origin.Global -> context.skieNamespaceProvider.getNamespaceFile(callableDeclaration.owner).let(::listOf) + KirCallableDeclaration.Origin.Global -> context.classNamespaceProvider.getNamespaceFile(callableDeclaration.owner).let(::listOf) } } @@ -99,11 +100,11 @@ class FileScopeConversionParentProvider( private fun getExtensionNamespace( callableDeclaration: KirCallableDeclaration<*>, parentType: SirType, - ): SirFile { + ): SirIrFile { val extensionReceiverKirClass = getExtensionReceiverKirClassIfExists(parentType) - return extensionReceiverKirClass?.let { context.skieNamespaceProvider.getNamespaceFile(it) } - ?: context.skieNamespaceProvider.getNamespaceFile(callableDeclaration.owner) + return extensionReceiverKirClass?.let { context.classNamespaceProvider.getNamespaceFile(it) } + ?: context.classNamespaceProvider.getNamespaceFile(callableDeclaration.owner) } private fun getExtensionReceiverKirClassIfExists(parentType: SirType): KirClass? = @@ -114,7 +115,7 @@ class FileScopeConversionParentProvider( else -> null } - private fun createNonOptionalExtension(file: SirFile, sirClass: SirClass): SirExtension? = + private fun createNonOptionalExtension(file: SirIrFile, sirClass: SirClass): SirExtension? = if (sirClass.typeParameters.isEmpty()) { sirProvider.getExtension( classDeclaration = sirClass, @@ -125,6 +126,7 @@ class FileScopeConversionParentProvider( null } + @Suppress("UNUSED_PARAMETER") private fun getOptionalExtensions(callableDeclaration: KirCallableDeclaration<*>, type: NullableSirType, namespace: SirFile): List { // val nonNullType = type.type // diff --git a/SKIE/compiler/kotlin-plugin/src/kgp_common/kotlin/co/touchlab/skie/phases/features/sealed/SealedEnumGeneratorDelegate.kt b/SKIE/compiler/kotlin-plugin/src/kgp_common/kotlin/co/touchlab/skie/phases/features/sealed/SealedEnumGeneratorDelegate.kt index d630b6f60..d9a82befc 100644 --- a/SKIE/compiler/kotlin-plugin/src/kgp_common/kotlin/co/touchlab/skie/phases/features/sealed/SealedEnumGeneratorDelegate.kt +++ b/SKIE/compiler/kotlin-plugin/src/kgp_common/kotlin/co/touchlab/skie/phases/features/sealed/SealedEnumGeneratorDelegate.kt @@ -17,7 +17,7 @@ class SealedEnumGeneratorDelegate( SirClass( baseName = "Sealed", kind = SirClass.Kind.Enum, - parent = skieNamespaceProvider.getNamespace(kirClass), + parent = classNamespaceProvider.getNamespace(kirClass), visibility = SirVisibility.PublicButReplaced, ).apply { addConformanceToHashableIfPossible(kirClass) diff --git a/SKIE/compiler/kotlin-plugin/src/kgp_common/kotlin/co/touchlab/skie/phases/features/sealed/SealedFunctionGeneratorDelegate.kt b/SKIE/compiler/kotlin-plugin/src/kgp_common/kotlin/co/touchlab/skie/phases/features/sealed/SealedFunctionGeneratorDelegate.kt index b71fdaf91..356592455 100644 --- a/SKIE/compiler/kotlin-plugin/src/kgp_common/kotlin/co/touchlab/skie/phases/features/sealed/SealedFunctionGeneratorDelegate.kt +++ b/SKIE/compiler/kotlin-plugin/src/kgp_common/kotlin/co/touchlab/skie/phases/features/sealed/SealedFunctionGeneratorDelegate.kt @@ -54,7 +54,7 @@ class SealedFunctionGeneratorDelegate( ): SirSimpleFunction = SirSimpleFunction( identifier = kirClass.enumConstructorFunctionName, - parent = context.skieNamespaceProvider.getNamespaceFile(kirClass), + parent = context.classNamespaceProvider.getNamespaceFile(kirClass), returnType = enum.toTypeFromEnclosingTypeParameters(enum.typeParameters).let(returnTypeModifier), ).apply { copyTypeParametersFrom(enum) diff --git a/SKIE/compiler/kotlin-plugin/src/kgp_common/kotlin/co/touchlab/skie/phases/features/suspend/SkieClassSuspendGenerator.kt b/SKIE/compiler/kotlin-plugin/src/kgp_common/kotlin/co/touchlab/skie/phases/features/suspend/SkieClassSuspendGenerator.kt index 7365f4fff..7ed53aac5 100644 --- a/SKIE/compiler/kotlin-plugin/src/kgp_common/kotlin/co/touchlab/skie/phases/features/suspend/SkieClassSuspendGenerator.kt +++ b/SKIE/compiler/kotlin-plugin/src/kgp_common/kotlin/co/touchlab/skie/phases/features/suspend/SkieClassSuspendGenerator.kt @@ -29,7 +29,7 @@ class SkieClassSuspendGenerator { private fun createSkieClass(suspendFunctionOwner: KirClass): SirClass = SirClass( baseName = "Suspend", - parent = skieNamespaceProvider.getNamespace(suspendFunctionOwner), + parent = classNamespaceProvider.getNamespace(suspendFunctionOwner), visibility = SirVisibility.PublicButReplaced, kind = SirClass.Kind.Struct, ).apply { @@ -42,7 +42,7 @@ class SkieClassSuspendGenerator { private fun generateNamespaceProvider(suspendFunctionOwner: KirClass, skieClass: SirClass) { SirSimpleFunction( identifier = "skie", - parent = skieNamespaceProvider.getNamespaceFile(suspendFunctionOwner), + parent = classNamespaceProvider.getNamespaceFile(suspendFunctionOwner), returnType = sirBuiltins.Swift.Void.defaultType, ).apply { copyTypeParametersFrom(skieClass) diff --git a/SKIE/compiler/kotlin-plugin/src/kgp_common/kotlin/co/touchlab/skie/phases/features/suspend/SwiftSuspendGeneratorDelegate.kt b/SKIE/compiler/kotlin-plugin/src/kgp_common/kotlin/co/touchlab/skie/phases/features/suspend/SwiftSuspendGeneratorDelegate.kt index ad44bf4f7..e5809fd50 100644 --- a/SKIE/compiler/kotlin-plugin/src/kgp_common/kotlin/co/touchlab/skie/phases/features/suspend/SwiftSuspendGeneratorDelegate.kt +++ b/SKIE/compiler/kotlin-plugin/src/kgp_common/kotlin/co/touchlab/skie/phases/features/suspend/SwiftSuspendGeneratorDelegate.kt @@ -43,7 +43,7 @@ class SwiftSuspendGeneratorDelegate( val extension = sirProvider.getExtension( classDeclaration = bridgeModel.extensionTypeDeclarationForBridgingFunction, - parent = skieNamespaceProvider.getNamespaceFile(bridgeModel.suspendFunctionOwner), + parent = classNamespaceProvider.getNamespaceFile(bridgeModel.suspendFunctionOwner), ) bridgeModel.suspendKirFunction.bridgedSirFunction = extension.createSwiftBridgingFunction(bridgeModel) diff --git a/SKIE/compiler/kotlin-plugin/src/kgp_common/kotlin/co/touchlab/skie/phases/kir/CreateKirMembersPhase.kt b/SKIE/compiler/kotlin-plugin/src/kgp_common/kotlin/co/touchlab/skie/phases/kir/CreateKirMembersPhase.kt index 261fe56ea..f0d4a1094 100644 --- a/SKIE/compiler/kotlin-plugin/src/kgp_common/kotlin/co/touchlab/skie/phases/kir/CreateKirMembersPhase.kt +++ b/SKIE/compiler/kotlin-plugin/src/kgp_common/kotlin/co/touchlab/skie/phases/kir/CreateKirMembersPhase.kt @@ -121,7 +121,7 @@ class CreateKirMembersPhase( createFunction(descriptor, kirClass, origin) } - private fun getOrCreateOverridenFunction(descriptor: FunctionDescriptor, origin: Origin): KirSimpleFunction { + private fun getOrCreateOverriddenFunction(descriptor: FunctionDescriptor, origin: Origin): KirSimpleFunction { val classDescriptor = descriptorProvider.getReceiverClassDescriptorOrNull(descriptor) ?: error("Unsupported function $descriptor") @@ -160,7 +160,7 @@ class CreateKirMembersPhase( ) getDirectParents(descriptor) - .map { getOrCreateOverridenFunction(it, origin) } + .map { getOrCreateOverriddenFunction(it, origin) } .let { function.addOverrides(it) } createValueParameters(function, descriptor, methodBridge) diff --git a/SKIE/compiler/kotlin-plugin/src/kgp_common/kotlin/co/touchlab/skie/phases/oir/ConfigureExternalOirTypesBridgingPhase.kt b/SKIE/compiler/kotlin-plugin/src/kgp_common/kotlin/co/touchlab/skie/phases/oir/ConfigureExternalOirTypesBridgingPhase.kt index 9f25e190b..58f8ed2ba 100644 --- a/SKIE/compiler/kotlin-plugin/src/kgp_common/kotlin/co/touchlab/skie/phases/oir/ConfigureExternalOirTypesBridgingPhase.kt +++ b/SKIE/compiler/kotlin-plugin/src/kgp_common/kotlin/co/touchlab/skie/phases/oir/ConfigureExternalOirTypesBridgingPhase.kt @@ -51,7 +51,7 @@ class ConfigureExternalOirTypesBridgingPhase( baseName = fqName.simpleName, parent = when { fqName.parent != null -> getOrCreateSirClass(fqName.parent) - else -> sirProvider.getExternalModule(fqName.module.name) + else -> sirProvider.getExternalModule(fqName.module.name).builtInFile }, // TODO All builtin bridges are structs or enums (not classes which is important for type mapping of reference types, however we do not know if this will be true for 3rd party libraries) kind = SirClass.Kind.Struct, diff --git a/SKIE/compiler/kotlin-plugin/src/kgp_common/kotlin/co/touchlab/skie/phases/other/AddFoundationImportsPhase.kt b/SKIE/compiler/kotlin-plugin/src/kgp_common/kotlin/co/touchlab/skie/phases/other/AddFoundationImportsPhase.kt index 82d1abc5a..8b5b99417 100644 --- a/SKIE/compiler/kotlin-plugin/src/kgp_common/kotlin/co/touchlab/skie/phases/other/AddFoundationImportsPhase.kt +++ b/SKIE/compiler/kotlin-plugin/src/kgp_common/kotlin/co/touchlab/skie/phases/other/AddFoundationImportsPhase.kt @@ -1,13 +1,14 @@ package co.touchlab.skie.phases.other import co.touchlab.skie.phases.SirPhase +import co.touchlab.skie.sir.element.SirIrFile object AddFoundationImportsPhase : SirPhase { context(SirPhase.Context) override fun execute() { - sirProvider.files - .filter { it.content.isEmpty() } + sirProvider.skieModuleFiles + .filterIsInstance() .forEach { it.imports.add("Foundation") } diff --git a/SKIE/compiler/kotlin-plugin/src/kgp_common/kotlin/co/touchlab/skie/phases/other/FixDuplicatedOverridenFunctionsPhase.kt b/SKIE/compiler/kotlin-plugin/src/kgp_common/kotlin/co/touchlab/skie/phases/other/FixDuplicatedOverriddenFunctionsPhase.kt similarity index 97% rename from SKIE/compiler/kotlin-plugin/src/kgp_common/kotlin/co/touchlab/skie/phases/other/FixDuplicatedOverridenFunctionsPhase.kt rename to SKIE/compiler/kotlin-plugin/src/kgp_common/kotlin/co/touchlab/skie/phases/other/FixDuplicatedOverriddenFunctionsPhase.kt index def049a95..94fe2e139 100644 --- a/SKIE/compiler/kotlin-plugin/src/kgp_common/kotlin/co/touchlab/skie/phases/other/FixDuplicatedOverridenFunctionsPhase.kt +++ b/SKIE/compiler/kotlin-plugin/src/kgp_common/kotlin/co/touchlab/skie/phases/other/FixDuplicatedOverriddenFunctionsPhase.kt @@ -11,7 +11,7 @@ import co.touchlab.skie.sir.element.shallowCopy // Fix for SKIE-395. // The implementation is somewhat hacky because it creates a fake function that is used to remove the duplicates. // This fake function is not properly linked with the overrides and as a result this phase needs to run after all other phases that rename functions. -object FixDuplicatedOverridenFunctionsPhase : SirPhase { +object FixDuplicatedOverriddenFunctionsPhase : SirPhase { context(SirPhase.Context) override fun execute() { diff --git a/SKIE/compiler/kotlin-plugin/src/kgp_common/kotlin/co/touchlab/skie/phases/runtime/SwiftRuntimeGenerator.kt b/SKIE/compiler/kotlin-plugin/src/kgp_common/kotlin/co/touchlab/skie/phases/runtime/SwiftRuntimeGenerator.kt index 05688a7af..e3b69bc46 100644 --- a/SKIE/compiler/kotlin-plugin/src/kgp_common/kotlin/co/touchlab/skie/phases/runtime/SwiftRuntimeGenerator.kt +++ b/SKIE/compiler/kotlin-plugin/src/kgp_common/kotlin/co/touchlab/skie/phases/runtime/SwiftRuntimeGenerator.kt @@ -12,7 +12,7 @@ object SwiftRuntimeGenerator : SirPhase { context(SirPhase.Context) override fun execute() { getSwiftRuntimeFiles().forEach { - sirProvider.getSkieNamespaceFile(it.swiftFileName).content = it.readText() + sirFileProvider.getWrittenSourceFileFromSkieNamespace(it.swiftFileName).content = it.readText() } } diff --git a/SKIE/compiler/kotlin-plugin/src/kgp_common/kotlin/co/touchlab/skie/phases/sir/member/CreateSirMembersPhase.kt b/SKIE/compiler/kotlin-plugin/src/kgp_common/kotlin/co/touchlab/skie/phases/sir/member/CreateSirMembersPhase.kt index 5eb67dc30..8c205215f 100644 --- a/SKIE/compiler/kotlin-plugin/src/kgp_common/kotlin/co/touchlab/skie/phases/sir/member/CreateSirMembersPhase.kt +++ b/SKIE/compiler/kotlin-plugin/src/kgp_common/kotlin/co/touchlab/skie/phases/sir/member/CreateSirMembersPhase.kt @@ -22,6 +22,7 @@ import co.touchlab.skie.sir.element.SirSetter import co.touchlab.skie.sir.element.SirSimpleFunction import co.touchlab.skie.sir.element.SirValueParameter import co.touchlab.skie.sir.element.SirVisibility +import co.touchlab.skie.sir.element.topLevelParent import co.touchlab.skie.util.collisionFreeIdentifier import co.touchlab.skie.util.swift.toValidSwiftIdentifier @@ -120,7 +121,8 @@ class CreateSirMembersPhase( private fun KirCallableDeclaration<*>.getSirParent(): SirDeclarationNamespace = when (val parent = oirCallableDeclaration.parent) { is OirClass -> parent.originalSirClass - is OirExtension -> sirProvider.getExtension(parent.classDeclaration.originalSirClass, parent.classDeclaration.originalSirClass.module) + // WIP parent.sirExtension should be used instead + is OirExtension -> sirProvider.getExtension(parent.classDeclaration.originalSirClass, parent.classDeclaration.originalSirClass.topLevelParent) } private fun SirFunction.createValueParameters( diff --git a/SKIE/compiler/kotlin-plugin/src/kgp_common/kotlin/co/touchlab/skie/phases/sir/type/CreateExternalSirTypesPhase.kt b/SKIE/compiler/kotlin-plugin/src/kgp_common/kotlin/co/touchlab/skie/phases/sir/type/CreateExternalSirTypesPhase.kt index 19684e7d9..8600be10c 100644 --- a/SKIE/compiler/kotlin-plugin/src/kgp_common/kotlin/co/touchlab/skie/phases/sir/type/CreateExternalSirTypesPhase.kt +++ b/SKIE/compiler/kotlin-plugin/src/kgp_common/kotlin/co/touchlab/skie/phases/sir/type/CreateExternalSirTypesPhase.kt @@ -19,7 +19,7 @@ object CreateExternalSirTypesPhase : SirPhase { private fun createClass(oirClass: OirClass): SirClass { val sirClass = SirClass( baseName = oirClass.name, - parent = sirProvider.findExternalModule(oirClass) ?: SirModule.Unknown, + parent = sirProvider.findExternalModule(oirClass)?.builtInFile ?: SirModule.Unknown.builtInFile, kind = oirClass.kind.toSirKind(), origin = SirClass.Origin.Oir(oirClass), ) diff --git a/SKIE/compiler/kotlin-plugin/src/kgp_common/kotlin/co/touchlab/skie/phases/sir/type/CreateKotlinSirTypesPhase.kt b/SKIE/compiler/kotlin-plugin/src/kgp_common/kotlin/co/touchlab/skie/phases/sir/type/CreateKotlinSirTypesPhase.kt index 7aa262e88..ba82d32ee 100644 --- a/SKIE/compiler/kotlin-plugin/src/kgp_common/kotlin/co/touchlab/skie/phases/sir/type/CreateKotlinSirTypesPhase.kt +++ b/SKIE/compiler/kotlin-plugin/src/kgp_common/kotlin/co/touchlab/skie/phases/sir/type/CreateKotlinSirTypesPhase.kt @@ -69,7 +69,7 @@ class CreateKotlinSirTypesPhase( } private val KirClass.sirParent: SirDeclarationParent - get() = sirFqName.parent?.simpleName?.let { findSirParentRecursively(this, it) } ?: sirProvider.kotlinModule.module + get() = sirFqName.parent?.simpleName?.let { findSirParentRecursively(this, it) } ?: sirProvider.kotlinModule.builtInFile private fun findSirParentRecursively(kirClass: KirClass, parentName: String): SirClass? = when (val parent = kirClass.parent) { diff --git a/SKIE/compiler/kotlin-plugin/src/kgp_common/kotlin/co/touchlab/skie/phases/sir/type/CreateStableTypeAliasesPhase.kt b/SKIE/compiler/kotlin-plugin/src/kgp_common/kotlin/co/touchlab/skie/phases/sir/type/CreateStableTypeAliasesPhase.kt index 28c428b0f..a4578d707 100644 --- a/SKIE/compiler/kotlin-plugin/src/kgp_common/kotlin/co/touchlab/skie/phases/sir/type/CreateStableTypeAliasesPhase.kt +++ b/SKIE/compiler/kotlin-plugin/src/kgp_common/kotlin/co/touchlab/skie/phases/sir/type/CreateStableTypeAliasesPhase.kt @@ -30,9 +30,9 @@ class CreateStableNameTypeAliasesPhase( SirTypeAlias( baseName = "Kotlin", parent = if (shouldGenerateFileForEachExportedClass) { - skieNamespaceProvider.getNamespace(kirClass) + classNamespaceProvider.getNamespace(kirClass) } else { - skieNamespaceProvider.getNamespaceClass(kirClass) + classNamespaceProvider.getNamespaceClass(kirClass) }, visibility = SirVisibility.PublicButReplaced, ) { diff --git a/SKIE/compiler/kotlin-plugin/src/kgp_common/kotlin/co/touchlab/skie/phases/swift/CompileSwiftPhase.kt b/SKIE/compiler/kotlin-plugin/src/kgp_common/kotlin/co/touchlab/skie/phases/swift/CompileSwiftPhase.kt index 008be130d..b7483a146 100644 --- a/SKIE/compiler/kotlin-plugin/src/kgp_common/kotlin/co/touchlab/skie/phases/swift/CompileSwiftPhase.kt +++ b/SKIE/compiler/kotlin-plugin/src/kgp_common/kotlin/co/touchlab/skie/phases/swift/CompileSwiftPhase.kt @@ -31,6 +31,7 @@ class CompileSwiftPhase( context(SirPhase.Context) override fun execute() { + // WIP Replace with load written files phase val sourceFiles = skieBuildDirectory.swift.allSwiftFiles if (sourceFiles.isEmpty()) { return diff --git a/SKIE/compiler/kotlin-plugin/src/kgp_common/kotlin/co/touchlab/skie/phases/swift/GenerateSirFileCodePhase.kt b/SKIE/compiler/kotlin-plugin/src/kgp_common/kotlin/co/touchlab/skie/phases/swift/ConvertSirIrFilesToSourceFilesPhase.kt similarity index 96% rename from SKIE/compiler/kotlin-plugin/src/kgp_common/kotlin/co/touchlab/skie/phases/swift/GenerateSirFileCodePhase.kt rename to SKIE/compiler/kotlin-plugin/src/kgp_common/kotlin/co/touchlab/skie/phases/swift/ConvertSirIrFilesToSourceFilesPhase.kt index 4e6f5578b..5c0689503 100644 --- a/SKIE/compiler/kotlin-plugin/src/kgp_common/kotlin/co/touchlab/skie/phases/swift/GenerateSirFileCodePhase.kt +++ b/SKIE/compiler/kotlin-plugin/src/kgp_common/kotlin/co/touchlab/skie/phases/swift/ConvertSirIrFilesToSourceFilesPhase.kt @@ -8,12 +8,12 @@ import co.touchlab.skie.sir.element.SirConstructor import co.touchlab.skie.sir.element.SirDeclaration import co.touchlab.skie.sir.element.SirDeclarationWithScope import co.touchlab.skie.sir.element.SirElementWithAttributes -import co.touchlab.skie.sir.element.SirElementWithModifiers import co.touchlab.skie.sir.element.SirElementWithFunctionBodyBuilder +import co.touchlab.skie.sir.element.SirElementWithModifiers import co.touchlab.skie.sir.element.SirEnumCase import co.touchlab.skie.sir.element.SirExtension -import co.touchlab.skie.sir.element.SirFile import co.touchlab.skie.sir.element.SirFunction +import co.touchlab.skie.sir.element.SirIrFile import co.touchlab.skie.sir.element.SirOverridableDeclaration import co.touchlab.skie.sir.element.SirProperty import co.touchlab.skie.sir.element.SirScope @@ -43,28 +43,29 @@ import io.outfoxx.swiftpoet.builder.BuilderWithModifiers import io.outfoxx.swiftpoet.builder.BuilderWithTypeParameters import io.outfoxx.swiftpoet.builder.BuilderWithTypeSpecs -object GenerateSirFileCodePhase : SirPhase { +object ConvertSirIrFilesToSourceFilesPhase : SirPhase { context(SirPhase.Context) override fun execute() { - sirProvider.files.forEach { - it.generateCode() - } + sirProvider.skieModuleFiles + .filterIsInstance() + .forEach { + it.generateCode() + } } context(SirPhase.Context) - private fun SirFile.generateCode() { + private fun SirIrFile.generateCode() { val fileBuilder = FileSpec.builder(framework.moduleName, this.name) this.generateCodeUsing(fileBuilder) - val contentOrNull = this.content.takeIf { it.isNotBlank() } - val generatedCode = fileBuilder.build().toString() + val sourceFile = sirFileProvider.getGeneratedSourceFile(this) - this.content = listOfNotNull(contentOrNull, generatedCode).joinToString("\n\n") + sourceFile.content = fileBuilder.build().toString() } - private fun SirFile.generateCodeUsing(fileBuilder: FileSpec.Builder) { + private fun SirIrFile.generateCodeUsing(fileBuilder: FileSpec.Builder) { fileBuilder.apply { generateImports() @@ -72,14 +73,14 @@ object GenerateSirFileCodePhase : SirPhase { } } - context(SirFile) + context(SirIrFile) private fun FileSpec.Builder.generateImports() { imports.forEach { addImport(it) } } - context(SirFile) + context(SirIrFile) private fun FileSpec.Builder.generateDeclarations() { declarations.forEach { generateDeclaration(it) diff --git a/SKIE/compiler/kotlin-plugin/src/kgp_common/kotlin/co/touchlab/skie/phases/swift/WriteSirFileContentToDiskPhase.kt b/SKIE/compiler/kotlin-plugin/src/kgp_common/kotlin/co/touchlab/skie/phases/swift/ConvertSirSourceFilesToCompilableFilesPhase.kt similarity index 70% rename from SKIE/compiler/kotlin-plugin/src/kgp_common/kotlin/co/touchlab/skie/phases/swift/WriteSirFileContentToDiskPhase.kt rename to SKIE/compiler/kotlin-plugin/src/kgp_common/kotlin/co/touchlab/skie/phases/swift/ConvertSirSourceFilesToCompilableFilesPhase.kt index 29c096ab2..93133bef6 100644 --- a/SKIE/compiler/kotlin-plugin/src/kgp_common/kotlin/co/touchlab/skie/phases/swift/WriteSirFileContentToDiskPhase.kt +++ b/SKIE/compiler/kotlin-plugin/src/kgp_common/kotlin/co/touchlab/skie/phases/swift/ConvertSirSourceFilesToCompilableFilesPhase.kt @@ -1,28 +1,25 @@ package co.touchlab.skie.phases.swift import co.touchlab.skie.phases.SirPhase +import co.touchlab.skie.sir.element.SirSourceFile import co.touchlab.skie.util.cache.writeTextIfDifferent import co.touchlab.skie.util.directory.SkieBuildDirectory import java.io.File -import java.nio.file.Path -import kotlin.io.path.absolutePathString import kotlin.io.path.listDirectoryEntries import kotlin.io.path.pathString -object WriteSirFileContentToDiskPhase : SirPhase { +// WIP Extra phase for generating debug files, this should convert and write to cache directory only files that already do not have a object file associated from cache +object ConvertSirSourceFilesToCompilableFilesPhase : SirPhase { context(SirPhase.Context) override fun execute() { val cacheAwareFileGenerator = CacheAwareFileGenerator(skieBuildDirectory.swift.generated) with(cacheAwareFileGenerator) { - sirProvider.files - .groupBy { it.relativePath.absolutePathString().lowercase() } - .values - .forEach { fileGroup -> - val sourceCode = fileGroup.joinToString(separator = "\n\n") { it.content } - - writeFile(fileGroup.first().relativePath, sourceCode) + sirProvider.skieModuleFiles + .filterIsInstance() + .forEach { + it.convertToCompilableFile() } } @@ -35,14 +32,18 @@ object WriteSirFileContentToDiskPhase : SirPhase { private val generatedFiles = mutableSetOf() - fun writeFile(relativePath: Path, content: String) { + context(SirPhase.Context) + fun SirSourceFile.convertToCompilableFile() { val file = generatedSwiftDirectory.directory.resolve(relativePath.pathString) file.parentFile.mkdirs() + // WIP Can be written directly after adding support for proper incremental compilation file.writeTextIfDifferent(content) generatedFiles.add(file) + + sirFileProvider.createCompilableFile(this, file.toPath().toAbsolutePath()) } fun deleteOldFiles() { diff --git a/SKIE/compiler/kotlin-plugin/src/kgp_common/kotlin/co/touchlab/skie/sir/SkieNamespaceProvider.kt b/SKIE/compiler/kotlin-plugin/src/kgp_common/kotlin/co/touchlab/skie/sir/ClassNamespaceProvider.kt similarity index 82% rename from SKIE/compiler/kotlin-plugin/src/kgp_common/kotlin/co/touchlab/skie/sir/SkieNamespaceProvider.kt rename to SKIE/compiler/kotlin-plugin/src/kgp_common/kotlin/co/touchlab/skie/sir/ClassNamespaceProvider.kt index f66a75216..477fa69f0 100644 --- a/SKIE/compiler/kotlin-plugin/src/kgp_common/kotlin/co/touchlab/skie/sir/SkieNamespaceProvider.kt +++ b/SKIE/compiler/kotlin-plugin/src/kgp_common/kotlin/co/touchlab/skie/sir/ClassNamespaceProvider.kt @@ -7,12 +7,12 @@ import co.touchlab.skie.kir.element.KirModule import co.touchlab.skie.kir.element.classDescriptorOrNull import co.touchlab.skie.sir.element.SirClass import co.touchlab.skie.sir.element.SirExtension -import co.touchlab.skie.sir.element.SirFile +import co.touchlab.skie.sir.element.SirIrFile import co.touchlab.skie.sir.element.SirTypeAlias import co.touchlab.skie.util.swift.toValidSwiftIdentifier import org.jetbrains.kotlin.descriptors.ModuleDescriptor -class SkieNamespaceProvider( +class ClassNamespaceProvider( private val kirProvider: KirProvider, private val sirProvider: SirProvider, private val mainModuleDescriptor: ModuleDescriptor, @@ -22,14 +22,14 @@ class SkieNamespaceProvider( private val moduleNamespaceCache = mutableMapOf() - private val skieNamespaceFile by lazy { - sirProvider.getFile(kirProvider.skieModule.name, "Namespace") + private val classNamespaceFile by lazy { + sirProvider.fileProvider.getIrFile(kirProvider.skieModule.name, "Namespace") } - private val skieNamespaceBaseClass: SirClass by lazy { + private val classNamespaceBaseClass: SirClass by lazy { SirClass( baseName = "Skie", - parent = skieNamespaceFile, + parent = classNamespaceFile, kind = SirClass.Kind.Enum, ) } @@ -42,8 +42,8 @@ class SkieNamespaceProvider( .flatten() .toSet() - fun getNamespaceFile(kirClass: KirClass): SirFile = - sirProvider.getFile(kirClass.skieFileNamespaceName, kirClass.skieFileName) + fun getNamespaceFile(kirClass: KirClass): SirIrFile = + sirProvider.fileProvider.getIrFile(kirClass.skieFileNamespaceName, kirClass.skieFileName) fun getNamespace(kirClass: KirClass): SirExtension = sirProvider.getExtension( @@ -54,7 +54,7 @@ class SkieNamespaceProvider( fun getNamespaceClass(kirClass: KirClass): SirClass = namespaceClassCache.getOrPut(kirClass) { SirClass( - baseName = kirClass.skieNamespaceSimpleName, + baseName = kirClass.classNamespaceSimpleName, parent = getNamespaceClass(kirClass.parent), kind = SirClass.Kind.Enum, ) @@ -70,14 +70,14 @@ class SkieNamespaceProvider( moduleNamespaceCache.getOrPut(module) { val sirClass = SirClass( baseName = module.namespaceModuleName, - parent = skieNamespaceBaseClass, + parent = classNamespaceBaseClass, kind = SirClass.Kind.Enum, ) if (!module.shortNameCollides) { SirTypeAlias( baseName = module.fullNamespaceModuleName, - parent = skieNamespaceBaseClass, + parent = classNamespaceBaseClass, ) { sirClass.defaultType } @@ -88,7 +88,7 @@ class SkieNamespaceProvider( private val KirModule.namespaceModuleName: String get() { - val canUseShortName = !this.shortNameCollides && shortNamespaceModuleName != sirProvider.sirBuiltins.Skie.module.name.toValidSwiftIdentifier() + val canUseShortName = !this.shortNameCollides && shortNamespaceModuleName != sirProvider.skieModule.name.toValidSwiftIdentifier() return if (canUseShortName) this.shortNamespaceModuleName else this.fullNamespaceModuleName } @@ -103,12 +103,12 @@ class SkieNamespaceProvider( private val KirModule.shortNameCollides: Boolean get() = this in modulesWithShortNameCollision - private val KirClass.skieNamespaceSimpleName: String + private val KirClass.classNamespaceSimpleName: String get() = this.classDescriptorOrNull?.name?.identifier?.toValidSwiftIdentifier() ?: this.name.swiftName @Suppress("RecursivePropertyAccessor") private val KirClass.skieFileName: String - get() = ((this.parent as? KirClass)?.skieFileName?.let { "$it." } ?: "") + this.skieNamespaceSimpleName + get() = ((this.parent as? KirClass)?.skieFileName?.let { "$it." } ?: "") + this.classNamespaceSimpleName private val KirModule.shortNamespaceModuleName: String get() = this.name diff --git a/SKIE/compiler/kotlin-plugin/src/kgp_common/kotlin/co/touchlab/skie/sir/SirFileProvider.kt b/SKIE/compiler/kotlin-plugin/src/kgp_common/kotlin/co/touchlab/skie/sir/SirFileProvider.kt new file mode 100644 index 000000000..b3483e895 --- /dev/null +++ b/SKIE/compiler/kotlin-plugin/src/kgp_common/kotlin/co/touchlab/skie/sir/SirFileProvider.kt @@ -0,0 +1,62 @@ +package co.touchlab.skie.sir + +import co.touchlab.skie.kir.KirProvider +import co.touchlab.skie.sir.element.SirCompilableFile +import co.touchlab.skie.sir.element.SirIrFile +import co.touchlab.skie.sir.element.SirModule +import co.touchlab.skie.sir.element.SirSourceFile +import java.nio.file.Path + +class SirFileProvider( + private val skieModule: SirModule.Skie, + private val kirProvider: KirProvider, +) { + + private val irFileByPathCache = mutableMapOf() + + private val writtenSourceFileByPathCache = mutableMapOf() + + private val generatedSourceFileByPathCache = mutableMapOf() + + private val skieNamespace: String + get() = kirProvider.skieModule.name + + fun getWrittenSourceFileFromSkieNamespace(name: String): SirSourceFile { + val path = relativePath(skieNamespace, name) + + check(path !in generatedSourceFileByPathCache) { + "Generated source file for $path already exists. Combining written and generated source files is not supported." + } + + return writtenSourceFileByPathCache.getOrPut(path) { + SirSourceFile(skieModule, path) + } + } + + fun getGeneratedSourceFile(irFile: SirIrFile): SirSourceFile { + check(irFile.relativePath !in writtenSourceFileByPathCache) { + "Written source file for ${irFile.relativePath} already exists. Combining written and generated source files is not supported." + } + + return generatedSourceFileByPathCache.getOrPut(irFile.relativePath) { + SirSourceFile(irFile.module, irFile.relativePath, irFile) + } + } + + fun getIrFileFromSkieNamespace(name: String): SirIrFile = + getIrFile(skieNamespace, name) + + fun getIrFile(namespace: String, name: String): SirIrFile = + irFileByPathCache.getOrPut(relativePath(namespace, name)) { + SirIrFile(namespace, name, skieModule) + } + + fun createCompilableFile(sourceFile: SirSourceFile, absoluteFile: Path): SirCompilableFile = + SirCompilableFile(sourceFile, absoluteFile) + + companion object { + + fun relativePath(namespace: String, name: String): Path = + Path.of("$namespace/$namespace.$name.swift") + } +} diff --git a/SKIE/compiler/kotlin-plugin/src/kgp_common/kotlin/co/touchlab/skie/sir/SirProvider.kt b/SKIE/compiler/kotlin-plugin/src/kgp_common/kotlin/co/touchlab/skie/sir/SirProvider.kt index c3a74373a..78413febb 100644 --- a/SKIE/compiler/kotlin-plugin/src/kgp_common/kotlin/co/touchlab/skie/sir/SirProvider.kt +++ b/SKIE/compiler/kotlin-plugin/src/kgp_common/kotlin/co/touchlab/skie/sir/SirProvider.kt @@ -11,10 +11,13 @@ import co.touchlab.skie.sir.builtin.SirBuiltins import co.touchlab.skie.sir.element.SirCallableDeclaration import co.touchlab.skie.sir.element.SirClass import co.touchlab.skie.sir.element.SirDeclaration +import co.touchlab.skie.sir.element.SirDeclarationParent import co.touchlab.skie.sir.element.SirExtension import co.touchlab.skie.sir.element.SirFile +import co.touchlab.skie.sir.element.SirIrFile import co.touchlab.skie.sir.element.SirModule import co.touchlab.skie.sir.element.SirSimpleFunction +import co.touchlab.skie.sir.element.SirSourceFile import co.touchlab.skie.sir.element.SirTopLevelDeclarationParent import co.touchlab.skie.sir.element.SirTypeDeclaration import co.touchlab.skie.sir.element.SirVisibility @@ -33,17 +36,17 @@ class SirProvider( val skieModule: SirModule.Skie = SirModule.Skie(framework.moduleName) + val fileProvider: SirFileProvider = SirFileProvider(skieModule, kirProvider) + val sirBuiltins by lazy { SirBuiltins(this, skieConfiguration) } private val externalModuleCache = mutableMapOf() - private val fileByPathCache = mutableMapOf() - private val extensionCache = mutableMapOf, SirExtension>() - val files: Collection + val skieModuleFiles: Collection get() = skieModule.files val allLocalDeclarations: List @@ -67,7 +70,7 @@ class SirProvider( get() = skieModule.getAllDeclarationsRecursively() val allSkieGeneratedTopLevelDeclarations: List - get() = skieModule.declarations + files.flatMap { it.declarations } + get() = skieModuleFiles.filterIsInstance().flatMap { it.declarations } val allSkieGeneratedCallableDeclarations: List get() = allSkieGeneratedDeclarations.filterIsInstance() @@ -75,14 +78,6 @@ class SirProvider( val allSkieGeneratedSimpleFunctions: List get() = allSkieGeneratedCallableDeclarations.filterIsInstance() - fun getSkieNamespaceFile(name: String): SirFile = - getFile(kirProvider.skieModule.name, name) - - fun getFile(namespace: String, name: String): SirFile = - fileByPathCache.getOrPut(SirFile.relativePath(namespace, name)) { - SirFile(namespace, name, skieModule) - } - // Do not use for Extensions with ConditionalConstraints as that would break caching. fun getExtension( classDeclaration: SirClass, @@ -104,7 +99,7 @@ class SirProvider( val possibleParentDeclarations = if (parent != null) { listOf(parent) } else { - fqName.module.files + fqName.module + fqName.module.files.filterIsInstance() } possibleParentDeclarations.forEach { possibleParent -> @@ -122,7 +117,7 @@ class SirProvider( findClassByFqName(fqName) ?: error("SirClass with fqName $fqName not found.") - fun findExternalModule(oirClass: OirClass): SirModule? { + fun findExternalModule(oirClass: OirClass): SirModule.External? { val classDescriptor = oirClass.cinteropClassDescriptorOrNull ?: error("Invalid origin for OirClass: $oirClass") val moduleName = configurationProvider.getConfiguration(classDescriptor)[ClassInterop.CInteropFrameworkName] ?: return null diff --git a/SKIE/compiler/kotlin-plugin/src/kgp_common/kotlin/co/touchlab/skie/sir/builtin/SirBuiltin.kt b/SKIE/compiler/kotlin-plugin/src/kgp_common/kotlin/co/touchlab/skie/sir/builtin/SirBuiltin.kt index f5dc684ba..dd60f0503 100644 --- a/SKIE/compiler/kotlin-plugin/src/kgp_common/kotlin/co/touchlab/skie/sir/builtin/SirBuiltin.kt +++ b/SKIE/compiler/kotlin-plugin/src/kgp_common/kotlin/co/touchlab/skie/sir/builtin/SirBuiltin.kt @@ -30,7 +30,7 @@ class SirBuiltins( class Swift(sirProvider: SirProvider) : ModuleBase() { - override val module = sirProvider.getExternalModule("Swift") + override val declarationParent = sirProvider.getExternalModule("Swift").builtInFile override val origin: SirClass.Origin = SirClass.Origin.ExternalSwiftFramework @@ -97,7 +97,7 @@ class SirBuiltins( class Foundation(sirProvider: SirProvider, swift: Swift) : ModuleBase() { - override val module = sirProvider.getExternalModule("Foundation") + override val declarationParent = sirProvider.getExternalModule("Foundation").builtInFile override val origin = SirClass.Origin.ExternalSwiftFramework @@ -106,9 +106,11 @@ class SirBuiltins( class Skie( private val skieConfiguration: SkieConfiguration, - override val module: SirModule.Skie, + val module: SirModule.Skie, ) : ModuleBase() { + override val declarationParent: SirDeclarationParent = module.builtInFile + override val origin: SirClass.Origin = SirClass.Origin.Generated // The SkieSwiftFlow classes are only stubs (correct super types, and content are currently not needed) @@ -155,7 +157,7 @@ class SirBuiltins( private fun RuntimeClass( superTypes: List = emptyList(), - parent: SirDeclarationParent = module, + parent: SirDeclarationParent = declarationParent, nameOverride: String? = null, apply: (SirClass.() -> Unit) = { }, ): PropertyDelegateProvider> = @@ -174,13 +176,13 @@ class SirBuiltins( abstract class ModuleBase { - abstract val module: SirDeclarationParent + abstract val declarationParent: SirDeclarationParent abstract val origin: SirClass.Origin protected fun Class( superTypes: List = emptyList(), - parent: SirDeclarationParent = module, + parent: SirDeclarationParent = declarationParent, nameOverride: String? = null, apply: (SirClass.() -> Unit) = { }, ) = ClassDeclarationPropertyProvider( @@ -193,7 +195,7 @@ class SirBuiltins( protected fun Protocol( superTypes: List = emptyList(), - parent: SirDeclarationParent = module, + parent: SirDeclarationParent = declarationParent, apply: (SirClass.() -> Unit) = { }, ) = ClassDeclarationPropertyProvider( kind = SirClass.Kind.Protocol, @@ -204,7 +206,7 @@ class SirBuiltins( protected fun Struct( superTypes: List = emptyList(), - parent: SirDeclarationParent = module, + parent: SirDeclarationParent = declarationParent, apply: (SirClass.() -> Unit) = { }, ) = ClassDeclarationPropertyProvider( kind = SirClass.Kind.Struct, @@ -214,7 +216,7 @@ class SirBuiltins( ) protected fun TypeAlias( - parent: SirDeclarationParent = module, + parent: SirDeclarationParent = declarationParent, apply: (SirTypeAlias.() -> Unit) = { }, typeFactory: ((SirTypeAlias) -> SirType), ) = TypeAliasDeclarationPropertyProvider( diff --git a/SKIE/compiler/kotlin-plugin/src/kgp_common/kotlin/co/touchlab/skie/sir/element/SirBuiltInFile.kt b/SKIE/compiler/kotlin-plugin/src/kgp_common/kotlin/co/touchlab/skie/sir/element/SirBuiltInFile.kt new file mode 100644 index 000000000..e9a91e3ad --- /dev/null +++ b/SKIE/compiler/kotlin-plugin/src/kgp_common/kotlin/co/touchlab/skie/sir/element/SirBuiltInFile.kt @@ -0,0 +1,14 @@ +package co.touchlab.skie.sir.element + +// Instantiate only in SirModule +class SirBuiltInFile( + override val module: SirModule, +) : SirFile, SirTopLevelDeclarationParent { + + override val parent: SirDeclarationParent? + get() = null + + override val declarations: MutableList = mutableListOf() + + override fun toString(): String = "${this::class.simpleName}: (${module.name})" +} diff --git a/SKIE/compiler/kotlin-plugin/src/kgp_common/kotlin/co/touchlab/skie/sir/element/SirCompilableFile.kt b/SKIE/compiler/kotlin-plugin/src/kgp_common/kotlin/co/touchlab/skie/sir/element/SirCompilableFile.kt new file mode 100644 index 000000000..d69935c1e --- /dev/null +++ b/SKIE/compiler/kotlin-plugin/src/kgp_common/kotlin/co/touchlab/skie/sir/element/SirCompilableFile.kt @@ -0,0 +1,19 @@ +package co.touchlab.skie.sir.element + +import java.nio.file.Path + +// Instantiate only in SirFileProvider +class SirCompilableFile( + val originFile: SirSourceFile, + val absolutePath: Path, +) : SirFile { + + override val module: SirModule.Skie + get() = originFile.module + + init { + module.files.add(this) + } + + override fun toString(): String = "${this::class.simpleName}: $absolutePath" +} diff --git a/SKIE/compiler/kotlin-plugin/src/kgp_common/kotlin/co/touchlab/skie/sir/element/SirDeclaration.kt b/SKIE/compiler/kotlin-plugin/src/kgp_common/kotlin/co/touchlab/skie/sir/element/SirDeclaration.kt index 62703df5b..55dbde072 100644 --- a/SKIE/compiler/kotlin-plugin/src/kgp_common/kotlin/co/touchlab/skie/sir/element/SirDeclaration.kt +++ b/SKIE/compiler/kotlin-plugin/src/kgp_common/kotlin/co/touchlab/skie/sir/element/SirDeclaration.kt @@ -15,6 +15,11 @@ val SirDeclaration.firstParentThatIsNotNamespace: SirDeclarationParent val SirDeclaration.topLevelParent: SirTopLevelDeclarationParent get() = (parent as? SirTopLevelDeclarationParent) ?: parent.topLevelParent + ?: error("No top-level parent found for $this. All parent hierarchy should have a top-level parent.") + +@get:JvmName("topLevelParentForCombinedDeclaration") +val T.topLevelParent: SirTopLevelDeclarationParent where T : SirDeclaration, T : SirDeclarationParent + get() = (this as SirDeclaration).topLevelParent @Suppress("RecursivePropertyAccessor") val SirDeclaration.file: SirFile? diff --git a/SKIE/compiler/kotlin-plugin/src/kgp_common/kotlin/co/touchlab/skie/sir/element/SirDeclarationParent.kt b/SKIE/compiler/kotlin-plugin/src/kgp_common/kotlin/co/touchlab/skie/sir/element/SirDeclarationParent.kt index 696f6af36..91e61f3f5 100644 --- a/SKIE/compiler/kotlin-plugin/src/kgp_common/kotlin/co/touchlab/skie/sir/element/SirDeclarationParent.kt +++ b/SKIE/compiler/kotlin-plugin/src/kgp_common/kotlin/co/touchlab/skie/sir/element/SirDeclarationParent.kt @@ -25,11 +25,11 @@ val SirDeclarationParent.firstParentThatIsNotNamespace: SirDeclarationParent get() = if (this is SirDeclarationNamespace) (parent as? SirDeclarationNamespace)?.firstParentThatIsNotNamespace ?: parent ?: this else this @Suppress("RecursivePropertyAccessor") -val SirDeclarationParent.topLevelParent: SirTopLevelDeclarationParent - get() = (parent as? SirTopLevelDeclarationParent) ?: parent?.topLevelParent ?: module +val SirDeclarationParent.topLevelParent: SirTopLevelDeclarationParent? + get() = (parent as? SirTopLevelDeclarationParent) ?: parent?.topLevelParent fun SirDeclarationParent.getAllDeclarationsRecursively(): List { - val declarationParents = ((this as? SirModule)?.files ?: emptyList()) + declarations.filterIsInstance() + val declarationParents = declarations.filterIsInstance() return declarations + declarationParents.flatMap { it.getAllDeclarationsRecursively() } } diff --git a/SKIE/compiler/kotlin-plugin/src/kgp_common/kotlin/co/touchlab/skie/sir/element/SirFile.kt b/SKIE/compiler/kotlin-plugin/src/kgp_common/kotlin/co/touchlab/skie/sir/element/SirFile.kt index 4ba0cf587..a49795845 100644 --- a/SKIE/compiler/kotlin-plugin/src/kgp_common/kotlin/co/touchlab/skie/sir/element/SirFile.kt +++ b/SKIE/compiler/kotlin-plugin/src/kgp_common/kotlin/co/touchlab/skie/sir/element/SirFile.kt @@ -1,36 +1,7 @@ package co.touchlab.skie.sir.element -import java.nio.file.Path +// All subclasses can be instantiated only in SirFileProvider or SirModule +sealed interface SirFile : SirElement { -// Instantiate only in SirProvider -class SirFile( - val namespace: String, - val name: String, - override val module: SirModule.Skie, -) : SirElement, SirTopLevelDeclarationParent { - - val imports: MutableList = mutableListOf() - - // Relative to generated swift directory - val relativePath: Path - get() = relativePath(namespace, name) - - var content: String = "" - - override val parent: SirModule - get() = module - - init { - module.files.add(this) - } - - override val declarations: MutableList = mutableListOf() - - override fun toString(): String = "${this::class.simpleName}: $namespace.$name.swift" - - companion object { - - fun relativePath(namespace: String, name: String): Path = - Path.of("$namespace/$namespace.$name.swift") - } + val module: SirModule } diff --git a/SKIE/compiler/kotlin-plugin/src/kgp_common/kotlin/co/touchlab/skie/sir/element/SirIrFile.kt b/SKIE/compiler/kotlin-plugin/src/kgp_common/kotlin/co/touchlab/skie/sir/element/SirIrFile.kt new file mode 100644 index 000000000..2f7110f4e --- /dev/null +++ b/SKIE/compiler/kotlin-plugin/src/kgp_common/kotlin/co/touchlab/skie/sir/element/SirIrFile.kt @@ -0,0 +1,29 @@ +package co.touchlab.skie.sir.element + +import co.touchlab.skie.sir.SirFileProvider +import java.nio.file.Path + +// Instantiate only in SirFileProvider +class SirIrFile( + val namespace: String, + val name: String, + override val module: SirModule.Skie, +) : SirFile, SirTopLevelDeclarationParent { + + // Relative to the SKIE Swift generated directory + val relativePath: Path + get() = SirFileProvider.relativePath(namespace, name) + + val imports: MutableList = mutableListOf() + + override val parent: SirDeclarationParent? + get() = null + + init { + module.files.add(this) + } + + override val declarations: MutableList = mutableListOf() + + override fun toString(): String = "${this::class.simpleName}: $namespace.$name.swift" +} diff --git a/SKIE/compiler/kotlin-plugin/src/kgp_common/kotlin/co/touchlab/skie/sir/element/SirModule.kt b/SKIE/compiler/kotlin-plugin/src/kgp_common/kotlin/co/touchlab/skie/sir/element/SirModule.kt index cefcf0ade..7a26c3d3d 100644 --- a/SKIE/compiler/kotlin-plugin/src/kgp_common/kotlin/co/touchlab/skie/sir/element/SirModule.kt +++ b/SKIE/compiler/kotlin-plugin/src/kgp_common/kotlin/co/touchlab/skie/sir/element/SirModule.kt @@ -3,47 +3,33 @@ package co.touchlab.skie.sir.element // Instantiate only in SirProvider sealed class SirModule( val name: String, -) : SirElement, SirTopLevelDeclarationParent { +) : SirElement { - override val module: SirModule - get() = this - - override val parent: SirDeclarationParent? = null - - abstract val files: List - - override var declarations: MutableList = mutableListOf() - - class Kotlin( - name: String, - ) : SirModule(name) { - - override val files: List = emptyList() + val builtInFile by lazy { + SirBuiltInFile(this) } - class Skie( - name: String, - ) : SirModule(name) { - - override val files: MutableList = mutableListOf() + open val files: List by lazy { + listOf(builtInFile) } - class External( - name: String, - ) : SirModule(name) { + class Kotlin(name: String) : SirModule(name) - override val files: List = emptyList() - } - - object Unknown : SirModule("") { + class Skie(name: String) : SirModule(name) { - override val files: List = emptyList() + override val files: MutableList by lazy { + mutableListOf(builtInFile) + } } - object None : SirModule("") { + class External(name: String) : SirModule(name) - override val files: List = emptyList() - } + object Unknown : SirModule("") + + object None : SirModule("") override fun toString(): String = "SirModule${this::class.simpleName}: $name" } + +fun SirModule.getAllDeclarationsRecursively(): List = + files.filterIsInstance().flatMap { it.getAllDeclarationsRecursively() } diff --git a/SKIE/compiler/kotlin-plugin/src/kgp_common/kotlin/co/touchlab/skie/sir/element/SirSourceFile.kt b/SKIE/compiler/kotlin-plugin/src/kgp_common/kotlin/co/touchlab/skie/sir/element/SirSourceFile.kt new file mode 100644 index 000000000..26beb77f0 --- /dev/null +++ b/SKIE/compiler/kotlin-plugin/src/kgp_common/kotlin/co/touchlab/skie/sir/element/SirSourceFile.kt @@ -0,0 +1,20 @@ +package co.touchlab.skie.sir.element + +import java.nio.file.Path + +// Instantiate only in SirFileProvider +class SirSourceFile( + override val module: SirModule.Skie, + // Relative to the SKIE Swift generated directory + val relativePath: Path, + val originFile: SirIrFile? = null +) : SirFile { + + var content: String = "" + + init { + module.files.add(this) + } + + override fun toString(): String = "${this::class.simpleName}: $relativePath" +}