diff --git a/kt/entry-generation/godot-class-graph-symbol-processor/src/main/kotlin/godot/annotation/processor/classgraph/constants/Types.kt b/kt/entry-generation/godot-class-graph-symbol-processor/src/main/kotlin/godot/annotation/processor/classgraph/constants/Types.kt new file mode 100644 index 0000000000..4486fae6bf --- /dev/null +++ b/kt/entry-generation/godot-class-graph-symbol-processor/src/main/kotlin/godot/annotation/processor/classgraph/constants/Types.kt @@ -0,0 +1,27 @@ +package godot.annotation.processor.classgraph.constants + +const val BOOLEAN = "boolean" +const val INT = "int" +const val LONG = "long" +const val FLOAT = "float" +const val DOUBLE = "double" +const val BYTE = "byte" +const val SHORT = "short" + +val jvmPrimitives = listOf( + BOOLEAN, + INT, + LONG, + FLOAT, + DOUBLE, + BYTE, + SHORT +) + +const val VOID = "void" + +const val STRING = "java.lang.String" + +const val JVM_OBJECT = "java.lang.Object" + +const val SET = "java.util.Set" \ No newline at end of file diff --git a/kt/entry-generation/godot-class-graph-symbol-processor/src/main/kotlin/godot/annotation/processor/classgraph/extensions/AnnotationExtensions.kt b/kt/entry-generation/godot-class-graph-symbol-processor/src/main/kotlin/godot/annotation/processor/classgraph/extensions/AnnotationExtensions.kt index 8a551e317f..90b2de3915 100644 --- a/kt/entry-generation/godot-class-graph-symbol-processor/src/main/kotlin/godot/annotation/processor/classgraph/extensions/AnnotationExtensions.kt +++ b/kt/entry-generation/godot-class-graph-symbol-processor/src/main/kotlin/godot/annotation/processor/classgraph/extensions/AnnotationExtensions.kt @@ -18,6 +18,7 @@ import godot.annotation.RpcMode import godot.annotation.Sync import godot.annotation.Tool import godot.annotation.TransferMode +import godot.annotation.processor.classgraph.constants.SET import godot.annotation.processor.classgraph.models.TypeDescriptor import godot.entrygenerator.model.ColorNoAlphaHintAnnotation import godot.entrygenerator.model.DirHintAnnotation @@ -39,7 +40,9 @@ import godot.entrygenerator.model.RegisterPropertyAnnotation import godot.entrygenerator.model.RegisterSignalAnnotation import godot.entrygenerator.model.RpcAnnotation import godot.entrygenerator.model.ToolAnnotation +import io.github.classgraph.AnnotationEnumValue import io.github.classgraph.AnnotationInfo +import io.github.classgraph.ClassRefTypeSignature import io.github.classgraph.FieldInfo import io.github.classgraph.ScanResult @@ -69,7 +72,21 @@ fun AnnotationInfo.mapToGodotAnnotation(parentDeclaration: Any): GodotAnnotation require(parentDeclaration is FieldInfo) { "EnumFlag annotation should be placed on property." } - val enumValues = TypeDescriptor(parentDeclaration).enumValues + + val typeDescriptor = parentDeclaration.typeSignature + + require(typeDescriptor is ClassRefTypeSignature) + + require(typeDescriptor.fullyQualifiedClassName == SET) { + "Property annotated with EnumFlag should be of type $SET" + } + + val typeArgument = typeDescriptor.typeArguments.first().typeSignature as ClassRefTypeSignature + + val enumValues = this@ScanResult.getClassInfo(typeArgument.fullyQualifiedClassName) + .fieldInfo + .filter { it.typeDescriptor == typeArgument } + .map { it.name } EnumFlagHintStringAnnotation(enumValueNames = enumValues, source = this) } IntFlag::class.java.name -> IntFlagHintAnnotation( @@ -131,10 +148,10 @@ private fun AnnotationInfo.getTransferMode(): godot.entrygenerator.model.Transfe @Suppress("UNCHECKED_CAST") private fun AnnotationInfo.provideRangeHintAnnotation(stepDefault: T): RangeHintAnnotation { - val start = parameterValues.getValue("start") as T - val end = parameterValues.getValue("end") as T + val start = parameterValues.getValue("min") as T + val end = parameterValues.getValue("max") as T val step = parameterValues.getValue("step") as? T ?: stepDefault - val or = Range.NONE // Adjust this logic based on available data + val or = Range.valueOf((parameterValues.getValue("or") as AnnotationEnumValue).valueName) // Adjust this logic based on available data val hideSlider = parameterValues.getValue("hideSlider") as? Boolean ?: false val isRadians = parameterValues.getValue("isRadians") as? Boolean ?: false val isDegrees = parameterValues.getValue("isDegrees") as? Boolean ?: false diff --git a/kt/entry-generation/godot-class-graph-symbol-processor/src/main/kotlin/godot/annotation/processor/classgraph/extensions/ClassExtentions.kt b/kt/entry-generation/godot-class-graph-symbol-processor/src/main/kotlin/godot/annotation/processor/classgraph/extensions/ClassExtentions.kt index d6c8a28001..578c0a155a 100644 --- a/kt/entry-generation/godot-class-graph-symbol-processor/src/main/kotlin/godot/annotation/processor/classgraph/extensions/ClassExtentions.kt +++ b/kt/entry-generation/godot-class-graph-symbol-processor/src/main/kotlin/godot/annotation/processor/classgraph/extensions/ClassExtentions.kt @@ -6,6 +6,7 @@ import godot.annotation.RegisterFunction import godot.annotation.RegisterProperty import godot.annotation.RegisterSignal import godot.annotation.processor.classgraph.Settings +import godot.annotation.processor.classgraph.constants.JVM_OBJECT import godot.entrygenerator.model.ClassAnnotation import godot.entrygenerator.model.Clazz import godot.entrygenerator.model.RegisteredClass @@ -13,7 +14,7 @@ import godot.entrygenerator.model.Type import godot.entrygenerator.model.TypeKind import io.github.classgraph.ClassInfo import io.github.classgraph.ScanResult -import org.jetbrains.annotations.NotNull +import io.github.classgraph.TypeArgument context(ScanResult) fun ClassInfo.mapToClazz(settings: Settings): Clazz { @@ -31,13 +32,13 @@ fun ClassInfo.mapToClazz(settings: Settings): Clazz { .filter { fieldInfo -> fieldInfo.hasAnnotation(RegisterProperty::class.java, this) } - .map { it.mapToRegisteredProperty(settings) } + .map { it.mapToRegisteredProperty(settings, this) } val signals = fieldInfo .filter { fieldInfo -> fieldInfo.hasAnnotation(RegisterSignal::class.java, this) } - .map { it.mapFieldToRegisteredSignal(settings) } + .map { it.mapFieldToRegisteredSignal(settings, this) } val duplicateConstructorArgumentCount = constructorInfo .groupBy { it.parameterInfo.size } @@ -137,25 +138,19 @@ internal fun ClassInfo.provideRegisteredClassName( } // TODO: remove when https://github.com/classgraph/classgraph/issues/703 is fixed -internal fun getJavaLangObjectType(isNullable: Boolean, settings: Settings): Type { - val fqName = "java.lang.Object" +internal fun getJavaLangObjectType(settings: Settings): Type { + val fqName = JVM_OBJECT return Type( fqName = fqName, kind = TypeKind.CLASS, - isNullable = isNullable, supertypes = listOf(), arguments = { listOf() }, registeredName = { getDefaultRegisteredName(fqName, settings) } ) } -context(ScanResult) -internal fun ClassInfo.mapToType(settings: Settings, nullable: Boolean): Type { - val fqName = name - - val superTypes = superclasses.map { it.mapToType(settings, nullable) } - - val typeKind = when { +val ClassInfo.typeKind: TypeKind + get() = when { isAnnotation -> TypeKind.ANNOTATION_CLASS isInterface -> TypeKind.INTERFACE isEnum -> TypeKind.ENUM_CLASS @@ -163,17 +158,15 @@ internal fun ClassInfo.mapToType(settings: Settings, nullable: Boolean): Type { else -> TypeKind.UNKNOWN } +context(ScanResult) +internal fun ClassInfo.mapToType(typeArguments: List, settings: Settings): Type { + val superTypes = superclasses.map { it.mapToType(listOf(), settings) } + return Type( - fqName = fqName, + fqName = name, kind = typeKind, - isNullable = hasAnnotation(NotNull::class.java), supertypes = superTypes, - arguments = { getTypeParameters(settings) }, + arguments = { typeArguments.map { it.getType(settings) } }, registeredName = { provideRegisteredClassName(settings) }, ) } - -context(ScanResult) -internal fun ClassInfo.getTypeParameters(settings: Settings): List = typeDescriptor - .typeParameters - .map { it.typeClassInfo.mapToType(settings, false) } //TODO: See how to manage nullables diff --git a/kt/entry-generation/godot-class-graph-symbol-processor/src/main/kotlin/godot/annotation/processor/classgraph/extensions/ClassMemberExtension.kt b/kt/entry-generation/godot-class-graph-symbol-processor/src/main/kotlin/godot/annotation/processor/classgraph/extensions/ClassMemberExtension.kt index d930a36177..3f1f3d81b1 100644 --- a/kt/entry-generation/godot-class-graph-symbol-processor/src/main/kotlin/godot/annotation/processor/classgraph/extensions/ClassMemberExtension.kt +++ b/kt/entry-generation/godot-class-graph-symbol-processor/src/main/kotlin/godot/annotation/processor/classgraph/extensions/ClassMemberExtension.kt @@ -2,8 +2,10 @@ package godot.annotation.processor.classgraph.extensions import io.github.classgraph.ClassMemberInfo +const val DELEGATE_SUFFIX = "\$delegate" + val ClassMemberInfo.fqdn: String get() = "${classInfo.name}\$$sanitizedName" val ClassMemberInfo.sanitizedName: String - get() = name.removeSuffix("\$delegate") + get() = name.removeSuffix(DELEGATE_SUFFIX) diff --git a/kt/entry-generation/godot-class-graph-symbol-processor/src/main/kotlin/godot/annotation/processor/classgraph/extensions/FieldExtensions.kt b/kt/entry-generation/godot-class-graph-symbol-processor/src/main/kotlin/godot/annotation/processor/classgraph/extensions/FieldExtensions.kt index e329c46e84..61a88d6311 100644 --- a/kt/entry-generation/godot-class-graph-symbol-processor/src/main/kotlin/godot/annotation/processor/classgraph/extensions/FieldExtensions.kt +++ b/kt/entry-generation/godot-class-graph-symbol-processor/src/main/kotlin/godot/annotation/processor/classgraph/extensions/FieldExtensions.kt @@ -3,35 +3,33 @@ package godot.annotation.processor.classgraph.extensions import godot.annotation.processor.classgraph.Settings import godot.annotation.processor.classgraph.models.TypeDescriptor import godot.entrygenerator.ext.hasAnnotation -import godot.entrygenerator.model.EnumAnnotation -import godot.entrygenerator.model.EnumHintStringAnnotation -import godot.entrygenerator.model.EnumListHintStringAnnotation -import godot.entrygenerator.model.PropertyAnnotation -import godot.entrygenerator.model.RegisteredProperty -import godot.entrygenerator.model.RegisteredSignal +import godot.entrygenerator.model.* +import io.github.classgraph.AnnotationInfo +import io.github.classgraph.AnnotationInfoList import io.github.classgraph.ClassInfo import io.github.classgraph.FieldInfo +import io.github.classgraph.MethodInfo import io.github.classgraph.ScanResult context(ScanResult) -fun FieldInfo.mapToRegisteredProperty(settings: Settings): RegisteredProperty { +fun FieldInfo.mapToRegisteredProperty(settings: Settings, classInfo: ClassInfo): RegisteredProperty { // Map annotations - val annotations = annotationInfo + val annotations = getAnnotations(classInfo) .mapNotNull { it.mapToGodotAnnotation(this) as? PropertyAnnotation } .toMutableList() // Handle enums and collections with enums val fieldType = this.typeDescriptor?.toString() ?: throw IllegalStateException("Type cannot be null") - val typeDescriptor = TypeDescriptor(this) + val typeDescriptor = TypeDescriptor(this, classInfo) if (!typeDescriptor.isPrimitive) { - val classInfo = typeDescriptor.typeClassInfo + val typeClassInfo = typeDescriptor.typeClassInfo - if (!annotations.hasAnnotation() && classInfo.isEnum) { + if (!annotations.hasAnnotation() && typeClassInfo.isEnum) { annotations.add( EnumHintStringAnnotation( - enumValueNames = classInfo.fieldInfo + enumValueNames = typeClassInfo.fieldInfo .filter { it.isEnum } .map { it.name }, source = this @@ -41,7 +39,7 @@ fun FieldInfo.mapToRegisteredProperty(settings: Settings): RegisteredProperty { // Check if the property is a collection of enums if (!annotations.hasAnnotation() && fieldType.startsWith("kotlin.collections")) { - val containingTypeDeclaration = classInfo.typeSignature.typeParameters.firstOrNull()?.typeClassInfo + val containingTypeDeclaration = typeClassInfo.typeSignature.typeParameters.firstOrNull()?.typeClassInfo if (containingTypeDeclaration?.isEnum == true) { annotations.add( EnumListHintStringAnnotation( @@ -57,14 +55,13 @@ fun FieldInfo.mapToRegisteredProperty(settings: Settings): RegisteredProperty { // Check modifiers val isMutable = !this.isFinal - val isLateinit = this.annotationInfo.any { it.name == "kotlin.Lateinit" } val isOverridee = this.isOverridee return RegisteredProperty( fqName = fqdn, - type = typeDescriptor.getMappedType(settings), + type = typeDescriptor.getMappedPropertyType(settings), isMutable = isMutable, - isLateinit = isLateinit, + isLateinit = typeDescriptor.isLateInit, isOverridee = isOverridee, annotations = annotations.toList(), symbolProcessorSource = this @@ -72,19 +69,37 @@ fun FieldInfo.mapToRegisteredProperty(settings: Settings): RegisteredProperty { } context(ScanResult) -fun FieldInfo.mapFieldToRegisteredSignal(settings: Settings): RegisteredSignal { - val typeDescriptor = TypeDescriptor(this) - val annotations = annotationInfo.mapNotNull { it.mapToGodotAnnotation(this) as? PropertyAnnotation } +fun FieldInfo.mapFieldToRegisteredSignal(settings: Settings, classInfo: ClassInfo): RegisteredSignal { + return if (name.endsWith(DELEGATE_SUFFIX)) { + val methodInfo = getGetter(classInfo) + val typeDescriptor = TypeDescriptor(methodInfo) - return RegisteredSignal( - fqName = fqdn, - type = typeDescriptor.getMappedType(settings), - parameterTypes = typeDescriptor.typeClassInfo.getTypeParameters(settings), - parameterNames = listOf(), //TODO: ClassGraph cannot parse expressions, if we want to use it we need to add parameters to the annotation - isOverridee = isOverridee, - annotations = annotations, - symbolProcessorSource = this - ) + val type = typeDescriptor.getMappedType(settings) + + RegisteredSignal( + fqName = fqdn, + type = type, + parameterTypes = type.arguments(), + parameterNames = listOf(), //TODO: ClassGraph cannot parse expressions, if we want to use it we need to add parameters to the annotation + isOverridee = isOverridee, + annotations = getAnnotations(classInfo).mapNotNull { it.mapToGodotAnnotation(this) as? PropertyAnnotation }, + symbolProcessorSource = this + ) + } else { + val typeDescriptor = TypeDescriptor(this, classInfo) + val annotations = annotationInfo.mapNotNull { it.mapToGodotAnnotation(this) as? PropertyAnnotation } + + val type = typeDescriptor.getMappedType(settings) + RegisteredSignal( + fqName = fqdn, + type = type, + parameterTypes = type.arguments(), + parameterNames = listOf(), //TODO: ClassGraph cannot parse expressions, if we want to use it we need to add parameters to the annotation + isOverridee = isOverridee, + annotations = annotations, + symbolProcessorSource = this + ) + } } val FieldInfo.isOverridee: Boolean @@ -100,12 +115,33 @@ fun FieldInfo.hasAnnotation(annotationClass: Class, classInf hasAnnotation(annotationClass) || classInfo.methodInfo .any { - it.hasAnnotation(annotationClass) && it.name == toSyntheticAnnotations() + it.hasAnnotation(annotationClass) && (it.name == toSyntheticAnnotations() || it.name == toGetterName()) } +fun FieldInfo.hasAnnotation(annotationName: String, classInfo: ClassInfo): Boolean = + hasAnnotation(annotationName) || + classInfo.methodInfo + .any { + it.hasAnnotation(annotationName) && (it.name == toSyntheticAnnotations() || it.name == toGetterName()) + } + + fun FieldInfo.toGetterName(): String = "get${capitalizedName()}" fun FieldInfo.toSetterName(): String = "set${capitalizedName()}" fun FieldInfo.toSyntheticAnnotations(): String = "${toGetterName()}\$annotations" -private fun FieldInfo.capitalizedName(): String = - sanitizedName.replaceFirstChar { char -> if (char.isLowerCase()) char.titlecase() else char.toString() } +fun FieldInfo.getGetter(classInfo: ClassInfo): MethodInfo = classInfo + .getMethodInfo(toGetterName()) + .first { it.parameterInfo.isEmpty() } + +fun FieldInfo.getAnnotations(classInfo: ClassInfo): Collection = classInfo + .getMethodInfo(toSyntheticAnnotations()) + .firstOrNull() + ?.annotationInfo ?: listOf() + .union( + annotationInfo + ) + .distinct() + +private fun FieldInfo.capitalizedName(): String = sanitizedName + .replaceFirstChar { char -> if (char.isLowerCase()) char.titlecase() else char.toString() } diff --git a/kt/entry-generation/godot-class-graph-symbol-processor/src/main/kotlin/godot/annotation/processor/classgraph/extensions/MethodExtensions.kt b/kt/entry-generation/godot-class-graph-symbol-processor/src/main/kotlin/godot/annotation/processor/classgraph/extensions/MethodExtensions.kt index 1b91c1eabf..0f4b8a5593 100644 --- a/kt/entry-generation/godot-class-graph-symbol-processor/src/main/kotlin/godot/annotation/processor/classgraph/extensions/MethodExtensions.kt +++ b/kt/entry-generation/godot-class-graph-symbol-processor/src/main/kotlin/godot/annotation/processor/classgraph/extensions/MethodExtensions.kt @@ -54,9 +54,10 @@ private fun MethodInfo.isOverrideInHierarchyOf(classInfo: ClassInfo): Boolean { context(ScanResult) fun MethodInfo.mapToRegisteredConstructor(settings: Settings): RegisteredConstructor { + val parameters = parameterInfo.map { it.mapToValueParameter(settings) } return RegisteredConstructor( fqName = fqdn, - parameters = parameterInfo.map { it.mapToValueParameter(settings) }, + parameters = parameters, annotations = annotationInfo .mapNotNull { it.mapToGodotAnnotation(settings) as? ConstructorAnnotation }, symbolProcessorSource = this diff --git a/kt/entry-generation/godot-class-graph-symbol-processor/src/main/kotlin/godot/annotation/processor/classgraph/extensions/ParameterExtensions.kt b/kt/entry-generation/godot-class-graph-symbol-processor/src/main/kotlin/godot/annotation/processor/classgraph/extensions/ParameterExtensions.kt index 8054ace6ce..df2240542b 100644 --- a/kt/entry-generation/godot-class-graph-symbol-processor/src/main/kotlin/godot/annotation/processor/classgraph/extensions/ParameterExtensions.kt +++ b/kt/entry-generation/godot-class-graph-symbol-processor/src/main/kotlin/godot/annotation/processor/classgraph/extensions/ParameterExtensions.kt @@ -9,13 +9,10 @@ import io.github.classgraph.ScanResult context(ScanResult) fun MethodParameterInfo.mapToValueParameter(settings: Settings): ValueParameter { val typeDescriptor = TypeDescriptor(this) + val type = typeDescriptor.getMappedType(settings) return ValueParameter( name, - typeDescriptor.getMappedType(settings), - if (typeDescriptor.isPrimitive || typeDescriptor.isObject) { - listOf() - } else { - typeDescriptor.typeClassInfo.getTypeParameters(settings) - } + type, + type.arguments() ) } diff --git a/kt/entry-generation/godot-class-graph-symbol-processor/src/main/kotlin/godot/annotation/processor/classgraph/extensions/TypeArgumentExtensions.kt b/kt/entry-generation/godot-class-graph-symbol-processor/src/main/kotlin/godot/annotation/processor/classgraph/extensions/TypeArgumentExtensions.kt new file mode 100644 index 0000000000..f0aff2ae5e --- /dev/null +++ b/kt/entry-generation/godot-class-graph-symbol-processor/src/main/kotlin/godot/annotation/processor/classgraph/extensions/TypeArgumentExtensions.kt @@ -0,0 +1,26 @@ +package godot.annotation.processor.classgraph.extensions + +import godot.annotation.processor.classgraph.Settings +import godot.annotation.processor.classgraph.constants.JVM_OBJECT +import godot.entrygenerator.model.Type +import io.github.classgraph.ClassRefTypeSignature +import io.github.classgraph.ScanResult +import io.github.classgraph.TypeArgument + +context(ScanResult) +fun TypeArgument.getType(settings: Settings): Type { + val typeSignature = typeSignature as ClassRefTypeSignature + return typeSignature.getMappedType(settings) +} + +context(ScanResult) +private fun ClassRefTypeSignature.getMappedType(settings: Settings): Type { + return if (fullyQualifiedClassName == JVM_OBJECT) { + getJavaLangObjectType(settings) + } else { + this@ScanResult.getClassInfo(fullyQualifiedClassName).mapToType( + typeArguments, + settings + ) + } +} \ No newline at end of file diff --git a/kt/entry-generation/godot-class-graph-symbol-processor/src/main/kotlin/godot/annotation/processor/classgraph/models/TypeDescriptor.kt b/kt/entry-generation/godot-class-graph-symbol-processor/src/main/kotlin/godot/annotation/processor/classgraph/models/TypeDescriptor.kt index 67e499db3b..cbed98b1bc 100644 --- a/kt/entry-generation/godot-class-graph-symbol-processor/src/main/kotlin/godot/annotation/processor/classgraph/models/TypeDescriptor.kt +++ b/kt/entry-generation/godot-class-graph-symbol-processor/src/main/kotlin/godot/annotation/processor/classgraph/models/TypeDescriptor.kt @@ -1,83 +1,93 @@ package godot.annotation.processor.classgraph.models import godot.annotation.processor.classgraph.Settings +import godot.annotation.processor.classgraph.constants.* import godot.annotation.processor.classgraph.extensions.getJavaLangObjectType +import godot.annotation.processor.classgraph.extensions.hasAnnotation import godot.annotation.processor.classgraph.extensions.mapToType +import godot.entrygenerator.model.PropertyType import godot.entrygenerator.model.Type import godot.entrygenerator.model.TypeKind import io.github.classgraph.ClassInfo +import io.github.classgraph.ClassRefTypeSignature import io.github.classgraph.FieldInfo import io.github.classgraph.MethodInfo import io.github.classgraph.MethodParameterInfo import io.github.classgraph.ScanResult +import io.github.classgraph.TypeArgument import io.github.classgraph.TypeSignature import org.jetbrains.annotations.NotNull class TypeDescriptor private constructor( - private val value: TypeSignature, + private val descriptor: TypeSignature, + val typeArguments: List, private val nullable: Boolean, + val isLateInit: Boolean, private val descriptorType: DescriptorType ) { - constructor(fieldInfo: FieldInfo) : this( + constructor(fieldInfo: FieldInfo, classInfo: ClassInfo) : this( fieldInfo.typeDescriptor, - !fieldInfo.hasAnnotation(NotNull::class.java), + (fieldInfo.typeSignature as? ClassRefTypeSignature)?.typeArguments ?: listOf(), + !fieldInfo.hasAnnotation(NotNull::class.java, classInfo), + fieldInfo.hasAnnotation("kotlin.Lateinit", classInfo), FieldType(fieldInfo.name) ) constructor(parameterInfo: MethodParameterInfo) : this( parameterInfo.typeDescriptor, + (parameterInfo.typeSignature as? ClassRefTypeSignature)?.typeArguments ?: listOf(), !parameterInfo.hasAnnotation(NotNull::class.java), + false, ParameterType(parameterInfo.name) ) constructor(methodInfo: MethodInfo) : this( methodInfo.typeDescriptor.resultType, + (methodInfo.typeSignature?.resultType as? ClassRefTypeSignature)?.typeArguments ?: listOf(), !methodInfo.hasAnnotation(NotNull::class.java), + false, MethodType(methodInfo.name) ) - private val primitiveType = when(value.toString()) { - "boolean", "int", "long", "float", "double", "byte", "short", "java.lang.String" -> { - val fqName = value.toString() + private val primitiveType = when(descriptor.toString()) { + BOOLEAN, INT, LONG, FLOAT, DOUBLE, BYTE, SHORT, STRING -> { + val fqName = descriptor.toString() Type( fqName = fqName, kind = TypeKind.UNKNOWN, - isNullable = nullable, supertypes = listOf(), arguments = { listOf() }, registeredName = { fqName } ) } - "void" -> null + VOID -> null else -> null } + private val isJvmPrimitive: Boolean = jvmPrimitives.contains(descriptor.toString()) + val isPrimitive = primitiveType != null - val isVoid = value.toString() == "void" - val isObject = value.toString() == "java.lang.Object" + val isVoid = descriptor.toString() == VOID + val isObject = descriptor.toString() == JVM_OBJECT context(ScanResult) val typeClassInfo: ClassInfo - get() = this@ScanResult.getClassInfo(value.toString()) + get() = this@ScanResult.getClassInfo(descriptor.toString()) + +// val typeArguments = signature. context(ScanResult) fun getMappedType(settings: Settings): Type = primitiveType ?: if (isObject) { - getJavaLangObjectType(nullable, settings) + getJavaLangObjectType(settings) } else { - typeClassInfo.mapToType(settings, nullable) + typeClassInfo.mapToType(typeArguments, settings) } context(ScanResult) - val enumValues: List - get() { - val classInfo = typeClassInfo - require(classInfo.isEnum) { - "Content type of enumFlag set has to be of class kind ENUM but was class kind ${classInfo.name}. $descriptorType" - } - return classInfo.fieldInfo - .filter { it.isEnum } - .map { it.name } - } + fun getMappedPropertyType(settings: Settings): PropertyType = PropertyType( + getMappedType(settings), + !isJvmPrimitive && !isLateInit && nullable + ) private sealed interface DescriptorType { val name: String diff --git a/kt/entry-generation/godot-entry-generator/src/main/kotlin/godot/entrygenerator/model/RegisteredProperty.kt b/kt/entry-generation/godot-entry-generator/src/main/kotlin/godot/entrygenerator/model/RegisteredProperty.kt index 5c73601ba9..f957e288ac 100644 --- a/kt/entry-generation/godot-entry-generator/src/main/kotlin/godot/entrygenerator/model/RegisteredProperty.kt +++ b/kt/entry-generation/godot-entry-generator/src/main/kotlin/godot/entrygenerator/model/RegisteredProperty.kt @@ -2,7 +2,7 @@ package godot.entrygenerator.model data class RegisteredProperty( val fqName: String, - val type: Type, + val type: PropertyType, val isMutable: Boolean = true, val isLateinit: Boolean = false, val isOverridee: Boolean = false, diff --git a/kt/entry-generation/godot-entry-generator/src/main/kotlin/godot/entrygenerator/model/Type.kt b/kt/entry-generation/godot-entry-generator/src/main/kotlin/godot/entrygenerator/model/Type.kt index a1c17475a9..3f8fb3c8ba 100644 --- a/kt/entry-generation/godot-entry-generator/src/main/kotlin/godot/entrygenerator/model/Type.kt +++ b/kt/entry-generation/godot-entry-generator/src/main/kotlin/godot/entrygenerator/model/Type.kt @@ -1,9 +1,8 @@ package godot.entrygenerator.model -data class Type( +open class Type( val fqName: String, val kind: TypeKind, - val isNullable: Boolean, val supertypes: List, val arguments: () -> List, val registeredName: () -> String?, @@ -19,6 +18,17 @@ data class Type( } } +class PropertyType( + type: Type, + val isNullable: Boolean, +) : Type( + type.fqName, + type.kind, + type.supertypes, + type.arguments, + type.registeredName +) + enum class TypeKind { INTERFACE, CLASS, diff --git a/kt/entry-generation/godot-kotlin-symbol-processor/src/main/kotlin/godot/annotation/processor/ext/ksPropertyDeclarationExt.kt b/kt/entry-generation/godot-kotlin-symbol-processor/src/main/kotlin/godot/annotation/processor/ext/ksPropertyDeclarationExt.kt index c173aa42a6..0dfb7d87be 100644 --- a/kt/entry-generation/godot-kotlin-symbol-processor/src/main/kotlin/godot/annotation/processor/ext/ksPropertyDeclarationExt.kt +++ b/kt/entry-generation/godot-kotlin-symbol-processor/src/main/kotlin/godot/annotation/processor/ext/ksPropertyDeclarationExt.kt @@ -7,12 +7,7 @@ import com.google.devtools.ksp.symbol.Modifier import godot.annotation.processor.Settings import godot.annotation.processor.compiler.PsiProvider import godot.entrygenerator.ext.hasAnnotation -import godot.entrygenerator.model.EnumAnnotation -import godot.entrygenerator.model.EnumHintStringAnnotation -import godot.entrygenerator.model.EnumListHintStringAnnotation -import godot.entrygenerator.model.PropertyAnnotation -import godot.entrygenerator.model.RegisteredProperty -import godot.entrygenerator.model.RegisteredSignal +import godot.entrygenerator.model.* internal fun KSPropertyDeclaration.mapToRegisteredProperty( settings: Settings, @@ -79,7 +74,7 @@ internal fun KSPropertyDeclaration.mapToRegisteredProperty( return RegisteredProperty( fqName = fqName, - type = mappedType, + type = PropertyType(mappedType, type.resolve().isMarkedNullable), isMutable = isMutable, isLateinit = modifiers.contains(Modifier.LATEINIT), isOverridee = findOverridee() != null, diff --git a/kt/entry-generation/godot-kotlin-symbol-processor/src/main/kotlin/godot/annotation/processor/ext/ksTypeReferenceExt.kt b/kt/entry-generation/godot-kotlin-symbol-processor/src/main/kotlin/godot/annotation/processor/ext/ksTypeReferenceExt.kt index 229c76f3d1..c10458d543 100644 --- a/kt/entry-generation/godot-kotlin-symbol-processor/src/main/kotlin/godot/annotation/processor/ext/ksTypeReferenceExt.kt +++ b/kt/entry-generation/godot-kotlin-symbol-processor/src/main/kotlin/godot/annotation/processor/ext/ksTypeReferenceExt.kt @@ -40,7 +40,6 @@ internal fun KSTypeReference.mapToType( return Type( fqName = fqName, kind = typeKind, - isNullable = resolvedType.isMarkedNullable, supertypes = superTypes, arguments = { resolvedType.arguments.mapNotNull { it.type?.mapToType(settings) } }, registeredName = { resolvedType.provideRegisteredClassName(settings) },