godot.annotation.processor.processing.RoundGenerateRegistrarsForCurrentProjectAndDependencyRegistrationFiles.kt Maven / Gradle / Ivy
The newest version!
package godot.annotation.processor.processing
import com.google.devtools.ksp.processing.CodeGenerator
import com.google.devtools.ksp.processing.Dependencies
import com.google.devtools.ksp.processing.KSPLogger
import com.google.devtools.ksp.processing.Resolver
import com.google.devtools.ksp.symbol.KSAnnotated
import godot.annotation.processor.Settings
import godot.annotation.processor.ext.provideRegistrationFilePathForInitialGenerationWithoutExtension
import godot.annotation.processor.utils.JvmTypeProvider
import godot.annotation.processor.utils.LoggerWrapper
import godot.annotation.processor.visitor.MetadataAnnotationVisitor
import godot.annotation.processor.visitor.RegistrationAnnotationVisitor
import godot.entrygenerator.EntryGenerator
import godot.tools.common.constants.FileExtensions
import godot.tools.common.constants.godotEntryBasePackage
import java.io.File
/**
* First round:
*
* Generates entry files for current compilation and registration files for registrars from dependencies
*/
internal class RoundGenerateRegistrarsForCurrentProjectAndDependencyRegistrationFiles(
override val blackboard: ProcessingRoundsBlackboard,
override val resolver: Resolver,
override val codeGenerator: CodeGenerator,
override val logger: KSPLogger,
private val settings: Settings,
) : BaseRound() {
override fun executeInternal(): List {
val registerAnnotationVisitor = RegistrationAnnotationVisitor(
settings = settings,
)
resolver.getNewFiles().ifEmpty { resolver.getAllFiles() }.toList().map {
it.accept(registerAnnotationVisitor, Unit)
}
val metadataAnnotationVisitor = MetadataAnnotationVisitor()
resolver.getDeclarationsFromPackage(godotEntryBasePackage).forEach { declaration ->
declaration.accept(metadataAnnotationVisitor, Unit)
}
// generate entry files for this compilation
EntryGenerator.generateEntryFiles(
projectName = settings.projectName,
projectDir = settings.projectBaseDir.absolutePath,
// in this first round, the received metadata containers are all from dependencies as the ones from this compilation will only be present in the next processing round
classRegistrarFromDependencyCount = metadataAnnotationVisitor.registeredClassMetadataContainers.size,
logger = LoggerWrapper(logger),
sourceFiles = registerAnnotationVisitor.sourceFilesContainingRegisteredClasses,
jvmTypeFqNamesProvider = JvmTypeProvider(),
compilationTimeRelativeRegistrationFilePathProvider = { registeredClass ->
val registrationFile = blackboard
.existingRegistrationFilesMap["${registeredClass.registeredName}.${FileExtensions.GodotKotlinJvm.registrationFile}"]
?.relativeTo(settings.projectBaseDir)
?: File(
provideRegistrationFilePathForInitialGenerationWithoutExtension(
isRegistrationFileHierarchyEnabled = settings.isRegistrationFileHierarchyEnabled,
fqName = registeredClass.fqName,
registeredName = registeredClass.registeredName,
compilationProjectName = settings.projectName,
classProjectName = settings.projectName, // same as project name as no registration file exists for this class, hence it is new / renamed
registrationFileOutDir = settings.registrationBaseDirPathRelativeToProjectDir
)
)
registrationFile.invariantSeparatorsPath
},
classRegistrarAppendableProvider = { registeredClass ->
codeGenerator.createNewFile(
Dependencies(
true,
requireNotNull(registerAnnotationVisitor.registeredClassToKSFileMap[registeredClass]) {
"No KSFile found for $registeredClass. This should never happen"
}
),
godotEntryBasePackage,
"${registeredClass.registeredName}Registrar"
).bufferedWriter()
},
mainBufferedWriterProvider = {
codeGenerator.createNewFile(
Dependencies(
true,
*registerAnnotationVisitor.registeredClassToKSFileMap.map { it.value }.toTypedArray()
),
"godot",
"Entry"
).bufferedWriter()
}
)
if (settings.isRegistrationFileGenerationEnabled) {
EntryGenerator.generateRegistrationFiles(
registeredClassMetadataContainers = metadataAnnotationVisitor.registeredClassMetadataContainers,
registrationFileAppendableProvider = { metadata ->
blackboard.alreadyGeneratedRegistrationFiles.add(metadata.fqName)
val registrationFile = provideRegistrationFilePathForInitialGenerationWithoutExtension(
isRegistrationFileHierarchyEnabled = settings.isRegistrationFileHierarchyEnabled,
fqName = metadata.fqName,
registeredName = metadata.registeredName,
compilationProjectName = settings.projectName,
classProjectName = metadata.projectName,
registrationFileOutDir = settings.registrationBaseDirPathRelativeToProjectDir
)
codeGenerator.createNewFileByPath(
Dependencies.ALL_FILES,
"entryFiles/${registrationFile.removeSuffix(".${FileExtensions.GodotKotlinJvm.registrationFile}")}", // suffix will be added by the codeGenerator of KSP and is defined one line below
FileExtensions.GodotKotlinJvm.registrationFile
).bufferedWriter()
}
)
}
return emptyList()
}
}