Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Abstract class registration #736

Draft
wants to merge 5 commits into
base: feature/refine-registration-annotation-handling
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -106,7 +105,6 @@ object EntryGenerator {
sourceFiles: List<SourceFile>
): Boolean {
return listOf(
DefaultConstructorCheck(logger, sourceFiles).execute(),
ConstructorArgCountCheck(logger, sourceFiles).execute(),
ConstructorOverloadingCheck(logger, sourceFiles).execute(),

Expand Down

This file was deleted.

Original file line number Diff line number Diff line change
Expand Up @@ -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)

Expand All @@ -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
}


Expand All @@ -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()
)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,11 +23,7 @@ data class RegisteredClass(
get() = annotations.getAnnotation<ToolAnnotation>() != null

internal val godotBaseClass: String
get() = if (isAbstract) {
""
} else {
supertypes
.first { it.annotations.hasAnnotation<GodotBaseTypeAnnotation>() }
.name
}
get() = supertypes
.first { it.annotations.hasAnnotation<GodotBaseTypeAnnotation>() }
.name
}
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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
Expand Down
Original file line number Diff line number Diff line change
@@ -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
Expand Down Expand Up @@ -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
}
}
Expand Down
3 changes: 2 additions & 1 deletion kt/godot-library/src/main/kotlin/godot/core/KtClass.kt
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,8 @@ data class KtClass<T : KtObject>(
private val _functions: Map<String, KtFunction<T, *>>,
private val _notificationFunctions: List<Any.(Int) -> Unit>,
private val _signalInfos: Map<String, KtSignalInfo>,
val baseGodotClass: String
val baseGodotClass: String,
val isAbstract: Boolean,
) {
val registeredSupertypes: Array<String>
get() = _registeredSupertypes.toTypedArray()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -77,7 +77,8 @@ class ClassBuilderDsl<T : KtObject>(
private val relativeSourcePath: String,
private val compilationTimeRelativeRegistrationFilePath: String,
private val superClasses: List<String>,
private val baseGodotClass: String
private val baseGodotClass: String,
private val isAbstract: Boolean,
) {
private val constructors = mutableMapOf<Int, KtConstructor<T>>()

Expand Down Expand Up @@ -1274,7 +1275,6 @@ class ClassBuilderDsl<T : KtObject>(
}

internal fun build(): KtClass<T> {
check(constructors.isNotEmpty()) { "Please provide at least one constructor." }
// Constraints.MAX_CONSTRUCTOR_ARG_COUNT + 1 because we have no arg constructor.
val constructorArray = arrayOfNulls<KtConstructor<T>>(Constraints.MAX_CONSTRUCTOR_ARG_COUNT + 1)
constructors.forEach {
Expand All @@ -1290,7 +1290,8 @@ class ClassBuilderDsl<T : KtObject>(
_functions = functions,
_notificationFunctions = notificationFunctions,
_signalInfos = signals,
baseGodotClass = baseGodotClass
baseGodotClass = baseGodotClass,
isAbstract = isAbstract,
)
}
}
Expand All @@ -1305,14 +1306,15 @@ class ClassRegistry(
fun <T : KtObject> registerClass(
superClass: List<String>,
kClass: KClass<out KtObject>,
isAbstract: Boolean = false,
isTool: Boolean = false,
baseGodotClass: String,
registeredName: String,
relativeSourcePath: String,
compilationTimeRelativeRegistrationFilePath: String,
cb: ClassBuilderDsl<T>.() -> Unit
) {
val builder = ClassBuilderDsl<T>(registeredName, relativeSourcePath, compilationTimeRelativeRegistrationFilePath, superClass, baseGodotClass)
val builder = ClassBuilderDsl<T>(registeredName, relativeSourcePath, compilationTimeRelativeRegistrationFilePath, superClass, baseGodotClass, isAbstract)
builder.cb()
TypeManager.registerUserType(registeredName, kClass)
registerClass(builder.build())
Expand Down
Loading