diff --git a/kt/entry-generation/godot-entry-generator/src/main/kotlin/godot/entrygenerator/EntryGenerator.kt b/kt/entry-generation/godot-entry-generator/src/main/kotlin/godot/entrygenerator/EntryGenerator.kt index cb0faed87..9d7e96253 100644 --- a/kt/entry-generation/godot-entry-generator/src/main/kotlin/godot/entrygenerator/EntryGenerator.kt +++ b/kt/entry-generation/godot-entry-generator/src/main/kotlin/godot/entrygenerator/EntryGenerator.kt @@ -2,7 +2,6 @@ package godot.entrygenerator import godot.entrygenerator.checks.ConstructorArgCountCheck import godot.entrygenerator.checks.ConstructorOverloadingCheck -import godot.entrygenerator.checks.DefaultConstructorCheck import godot.entrygenerator.checks.FunctionArgCountCheck import godot.entrygenerator.checks.LateinitPropertyCheck import godot.entrygenerator.checks.NullablePropertyCheck @@ -106,7 +105,6 @@ object EntryGenerator { sourceFiles: List ): Boolean { return listOf( - DefaultConstructorCheck(logger, sourceFiles).execute(), ConstructorArgCountCheck(logger, sourceFiles).execute(), ConstructorOverloadingCheck(logger, sourceFiles).execute(), diff --git a/kt/entry-generation/godot-entry-generator/src/main/kotlin/godot/entrygenerator/checks/DefaultConstructorCheck.kt b/kt/entry-generation/godot-entry-generator/src/main/kotlin/godot/entrygenerator/checks/DefaultConstructorCheck.kt deleted file mode 100644 index f862368da..000000000 --- a/kt/entry-generation/godot-entry-generator/src/main/kotlin/godot/entrygenerator/checks/DefaultConstructorCheck.kt +++ /dev/null @@ -1,20 +0,0 @@ -package godot.entrygenerator.checks - -import godot.entrygenerator.model.SourceFile -import godot.entrygenerator.utils.Logger - -class DefaultConstructorCheck(logger: Logger, sourceFiles: List): BaseCheck(logger, sourceFiles) { - override fun execute(): Boolean { - var hasIssue = false - sourceFiles - .flatMap { it.registeredClasses } - .filter { !it.isAbstract } - .forEach { registeredClass -> - if (registeredClass.constructors.none { it.parameters.isEmpty() }) { - hasIssue = true - logger.error(registeredClass, "RegisteredClass does not have a public default constructor") - } - } - return hasIssue - } -} diff --git a/kt/entry-generation/godot-entry-generator/src/main/kotlin/godot/entrygenerator/filebuilder/ClassRegistrarFileBuilder.kt b/kt/entry-generation/godot-entry-generator/src/main/kotlin/godot/entrygenerator/filebuilder/ClassRegistrarFileBuilder.kt index f367f6104..524004c73 100644 --- a/kt/entry-generation/godot-entry-generator/src/main/kotlin/godot/entrygenerator/filebuilder/ClassRegistrarFileBuilder.kt +++ b/kt/entry-generation/godot-entry-generator/src/main/kotlin/godot/entrygenerator/filebuilder/ClassRegistrarFileBuilder.kt @@ -45,11 +45,6 @@ class ClassRegistrarFileBuilder( ) } } - .let { classBuilder -> - if (registeredClass.isAbstract) { - classBuilder.addKdoc("Registrar for abstract class. Does not register any members as it's only used for default value providing if any properties with default values are provided in the abstract class. Members of this abstract class are registered by the inheriting registrars") - } else classBuilder - } private val className = ClassName(registeredClass.containingPackage, registeredClass.name) @@ -59,29 +54,24 @@ class ClassRegistrarFileBuilder( .addParameter("registry", ClassName(godotRegistrationPackage, GodotKotlinJvmTypes.classRegistry)) .beginControlFlow("with(registry)") //START: with registry .let { funSpecBuilder -> - if (!registeredClass.isAbstract) { - val superClasses = registeredClass.supertypes.mapNotNull { supertype -> - //Used to implement script inheritance methods, so we remove base types and abstract parents. - val value = if (supertype is RegisteredClass && !supertype.isAbstract) { - "\"${supertype.registeredName}\"" - } else { - null - } - value - }.reduceOrNull { statement, name -> "$statement,$name" } ?: "" - funSpecBuilder.beginControlFlow( - "registerClass<%T>(listOf($superClasses),·%T::class,·${registeredClass.isTool},·%S,·%S,·%S,·%S)·{", - className, - className, - registeredClass.godotBaseClass, - registeredClass.registeredName, - registeredClass.relativeSourcePath, - compilationTimeRelativeRegistrationFilePath, - ) //START: registerClass - } else { - funSpecBuilder - .addComment("Abstract classes don't need to have any members to be registered") - } + val superClasses = registeredClass.supertypes.mapNotNull { supertype -> + //Used to implement script inheritance methods, so we remove base types + val value = if (supertype is RegisteredClass) { + "\"${supertype.registeredName}\"" + } else { + null + } + value + }.reduceOrNull { statement, name -> "$statement,$name" } ?: "" + funSpecBuilder.beginControlFlow( + "registerClass<%T>(listOf($superClasses),·%T::class,·${registeredClass.isAbstract},·${registeredClass.isTool},·%S,·%S,·%S,·%S)·{", + className, + className, + registeredClass.godotBaseClass, + registeredClass.registeredName, + registeredClass.relativeSourcePath, + compilationTimeRelativeRegistrationFilePath, + ) //START: registerClass } @@ -92,18 +82,14 @@ class ClassRegistrarFileBuilder( if (!registeredClass.isAbstract) { ConstructorRegistrationGenerator.generate(registeredClass, className, registerClassControlFlow) - FunctionRegistrationGenerator.generate(registeredClass, className, registerClassControlFlow) - SignalRegistrationGenerator.generate(registeredClass, className, registerClassControlFlow) - PropertyRegistrationGenerator.generate(registeredClass, className, registerClassControlFlow) } + FunctionRegistrationGenerator.generate(registeredClass, className, registerClassControlFlow) + SignalRegistrationGenerator.generate(registeredClass, className, registerClassControlFlow) + PropertyRegistrationGenerator.generate(registeredClass, className, registerClassControlFlow) classRegistrarBuilder.addFunction( registerClassControlFlow - .let { funSpecBuilder -> - if (!registeredClass.isAbstract) { - funSpecBuilder.endControlFlow() //END: registerClass - } else funSpecBuilder - } + .endControlFlow() //END: registerClass .endControlFlow() //END: with registry .build() ) diff --git a/kt/entry-generation/godot-entry-generator/src/main/kotlin/godot/entrygenerator/model/RegisteredClass.kt b/kt/entry-generation/godot-entry-generator/src/main/kotlin/godot/entrygenerator/model/RegisteredClass.kt index 31d4b0931..5635a257a 100644 --- a/kt/entry-generation/godot-entry-generator/src/main/kotlin/godot/entrygenerator/model/RegisteredClass.kt +++ b/kt/entry-generation/godot-entry-generator/src/main/kotlin/godot/entrygenerator/model/RegisteredClass.kt @@ -23,11 +23,7 @@ data class RegisteredClass( get() = annotations.getAnnotation() != null internal val godotBaseClass: String - get() = if (isAbstract) { - "" - } else { - supertypes - .first { it.annotations.hasAnnotation() } - .name - } + get() = supertypes + .first { it.annotations.hasAnnotation() } + .name } diff --git a/kt/entry-generation/godot-kotlin-symbol-processor/src/main/kotlin/godot/annotation/processor/ext/ksClassDeclarationExt.kt b/kt/entry-generation/godot-kotlin-symbol-processor/src/main/kotlin/godot/annotation/processor/ext/ksClassDeclarationExt.kt index d5754d456..1e772ae64 100644 --- a/kt/entry-generation/godot-kotlin-symbol-processor/src/main/kotlin/godot/annotation/processor/ext/ksClassDeclarationExt.kt +++ b/kt/entry-generation/godot-kotlin-symbol-processor/src/main/kotlin/godot/annotation/processor/ext/ksClassDeclarationExt.kt @@ -9,6 +9,7 @@ import com.google.devtools.ksp.symbol.ClassKind import com.google.devtools.ksp.symbol.KSClassDeclaration import com.google.devtools.ksp.symbol.KSFunctionDeclaration import com.google.devtools.ksp.symbol.KSPropertyDeclaration +import com.google.devtools.ksp.symbol.Modifier import godot.annotation.GodotApiMember import godot.annotation.Member import godot.annotation.processor.Settings @@ -95,7 +96,7 @@ internal fun KSClassDeclaration.mapToClazz( functions = registeredFunctions, signals = registeredSignals, properties = registeredProperties, - isAbstract = isAbstract(), + isAbstract = this.modifiers.contains(Modifier.ABSTRACT), isFqNameRegistrationEnabled = settings.isFqNameRegistrationEnabled, classNamePrefix = settings.classPrefix, symbolProcessorSource = this diff --git a/kt/entry-generation/godot-kotlin-symbol-processor/src/main/kotlin/godot/annotation/processor/visitor/RegistrationAnnotationVisitor.kt b/kt/entry-generation/godot-kotlin-symbol-processor/src/main/kotlin/godot/annotation/processor/visitor/RegistrationAnnotationVisitor.kt index 250ce840a..aed980cd3 100644 --- a/kt/entry-generation/godot-kotlin-symbol-processor/src/main/kotlin/godot/annotation/processor/visitor/RegistrationAnnotationVisitor.kt +++ b/kt/entry-generation/godot-kotlin-symbol-processor/src/main/kotlin/godot/annotation/processor/visitor/RegistrationAnnotationVisitor.kt @@ -1,5 +1,6 @@ package godot.annotation.processor.visitor +import com.google.devtools.ksp.symbol.ClassKind import com.google.devtools.ksp.symbol.KSClassDeclaration import com.google.devtools.ksp.symbol.KSFile import com.google.devtools.ksp.symbol.KSVisitorVoid @@ -36,9 +37,11 @@ internal class RegistrationAnnotationVisitor( if (declaration.hasCompilationErrors()) { null } else { - val clazz = declaration.mapToClazz(settings) - if (clazz is RegisteredClass) { - clazz + if (declaration.classKind == ClassKind.CLASS) { + val clazz = declaration.mapToClazz(settings) + if (clazz is RegisteredClass) { + clazz + } else null } else null } } diff --git a/kt/godot-library/src/main/kotlin/godot/core/KtClass.kt b/kt/godot-library/src/main/kotlin/godot/core/KtClass.kt index 243a2e9ed..225ef3e33 100644 --- a/kt/godot-library/src/main/kotlin/godot/core/KtClass.kt +++ b/kt/godot-library/src/main/kotlin/godot/core/KtClass.kt @@ -13,7 +13,8 @@ data class KtClass( private val _functions: Map>, private val _notificationFunctions: List Unit>, private val _signalInfos: Map, - val baseGodotClass: String + val baseGodotClass: String, + val isAbstract: Boolean, ) { val registeredSupertypes: Array get() = _registeredSupertypes.toTypedArray() diff --git a/kt/godot-library/src/main/kotlin/godot/registration/Registration.kt b/kt/godot-library/src/main/kotlin/godot/registration/Registration.kt index 7acb04779..dc8c300b4 100644 --- a/kt/godot-library/src/main/kotlin/godot/registration/Registration.kt +++ b/kt/godot-library/src/main/kotlin/godot/registration/Registration.kt @@ -77,7 +77,8 @@ class ClassBuilderDsl( private val relativeSourcePath: String, private val compilationTimeRelativeRegistrationFilePath: String, private val superClasses: List, - private val baseGodotClass: String + private val baseGodotClass: String, + private val isAbstract: Boolean, ) { private val constructors = mutableMapOf>() @@ -1274,7 +1275,6 @@ class ClassBuilderDsl( } internal fun build(): KtClass { - check(constructors.isNotEmpty()) { "Please provide at least one constructor." } // Constraints.MAX_CONSTRUCTOR_ARG_COUNT + 1 because we have no arg constructor. val constructorArray = arrayOfNulls>(Constraints.MAX_CONSTRUCTOR_ARG_COUNT + 1) constructors.forEach { @@ -1290,7 +1290,8 @@ class ClassBuilderDsl( _functions = functions, _notificationFunctions = notificationFunctions, _signalInfos = signals, - baseGodotClass = baseGodotClass + baseGodotClass = baseGodotClass, + isAbstract = isAbstract, ) } } @@ -1305,6 +1306,7 @@ class ClassRegistry( fun registerClass( superClass: List, kClass: KClass, + isAbstract: Boolean = false, isTool: Boolean = false, baseGodotClass: String, registeredName: String, @@ -1312,7 +1314,7 @@ class ClassRegistry( compilationTimeRelativeRegistrationFilePath: String, cb: ClassBuilderDsl.() -> Unit ) { - val builder = ClassBuilderDsl(registeredName, relativeSourcePath, compilationTimeRelativeRegistrationFilePath, superClass, baseGodotClass) + val builder = ClassBuilderDsl(registeredName, relativeSourcePath, compilationTimeRelativeRegistrationFilePath, superClass, baseGodotClass, isAbstract) builder.cb() TypeManager.registerUserType(registeredName, kClass) registerClass(builder.build())