Skip to content

Commit 5784336

Browse files
authored
Rework Variant.kt (#684)
* Remove nullables from Variant::toKotlin * Prevent creation of VariantArray and Dictionary with nullable core types. * Rework Variant.kt * Change how PropertyHint and PropertyUsage are used
1 parent 947816f commit 5784336

File tree

692 files changed

+7682
-7792
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

692 files changed

+7682
-7792
lines changed

harness/tests/Spatial.tscn

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -15,8 +15,6 @@
1515
[node name="Spatial" type="Node3D" node_paths=PackedStringArray("button")]
1616
script = ExtResource("1")
1717
button = NodePath("CanvasLayer/Button")
18-
nullable_long = 2
19-
lateinit_string = "works also from inspector"
2018
resource_test = SubResource("NavigationMesh_prd4u")
2119
jvm_id = 319061373
2220
nav_meshes = Array[NavigationMesh]([SubResource("NavigationMesh_tuyoa")])

harness/tests/scripts/godot/tests/Invocation.gdj

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -23,8 +23,6 @@ properties = [
2323
enum_list,
2424
vector_list,
2525
enum_list_mutable,
26-
nullable_long,
27-
lateinit_string,
2826
register_object,
2927
register_object_nullable,
3028
register_object_nullable_pre_init,
@@ -171,4 +169,4 @@ functions = [
171169
nullable_string_is_null,
172170
nullable_return_type,
173171
create_variant_array_of_user_type
174-
]
172+
]

harness/tests/src/main/kotlin/godot/tests/Invocation.kt

Lines changed: 8 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -70,15 +70,17 @@ class Invocation : Node3D() {
7070
@RegisterProperty
7171
var enumListMutable = mutableListOf(TestEnum.ENUM_1, TestEnum.ENUM_2)
7272

73-
@Export
74-
@RegisterProperty
75-
var nullableLong: Long? = null
73+
// Can't export nullable coretypes
74+
//@Export
75+
//@RegisterProperty
76+
//var nullableLong: Long? = null
7677

7778
private var hasInitializedLateInits = false
7879

79-
@Export
80-
@RegisterProperty
81-
var lateinitString: String? = null
80+
// Can't export nullable coretypes
81+
//@Export
82+
//@RegisterProperty
83+
//var lateinitString: String? = null
8284

8385
@RegisterProperty
8486
lateinit var registerObject: OtherScript
@@ -369,8 +371,6 @@ class Invocation : Node3D() {
369371

370372
@RegisterFunction
371373
fun initNullables() {
372-
nullableLong = 1
373-
lateinitString = "works"
374374
registerObject = OtherScript()
375375
registerObjectNullable = OtherScript()
376376
hasInitializedLateInits = true
@@ -753,16 +753,6 @@ class Invocation : Node3D() {
753753
fun isSentXrSameInstanceAsJvmSingleton(arvrServer: XRServer) =
754754
XRServer.getInstanceId() == arvrServer.getInstanceId()
755755

756-
@RegisterFunction
757-
fun nullableStringIsNull(nullableString: String?) = nullableString == null
758-
759-
@RegisterFunction
760-
fun nullableReturnType(shouldReturnNull: Boolean): String? = if (shouldReturnNull) {
761-
null
762-
} else {
763-
"not null"
764-
}
765-
766756
@RegisterFunction
767757
fun createVariantArrayOfUserType() = variantArrayOf<OtherScript>()
768758
}

harness/tests/test/unit/test_nullability_and_lateinit.gd

Lines changed: 0 additions & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -7,8 +7,6 @@ func test_nullables_are_correctly_set_from_function_lika_a_ready_call():
77
get_tree().root.add_child(node3d)
88
# simulate _ready call because we don't actually want to set it in ready in the Invocation script for the other tests
99
invocation_script.init_nullables()
10-
assert_eq(invocation_script.nullable_long, 1, "nullable_long should have been set in ready to 1")
11-
assert_eq(invocation_script.lateinit_string, "works", "lateinit_string should have been set in ready to wokrs")
1210
# TODO: check type once bug is fixed where with `kotlin_script_Name.new()` does not set the script on the object
1311
assert_true(invocation_script.register_object != null, "register_object should have been initialized in ready to an instance of OtherScript")
1412
# TODO: check type once bug is fixed where with `kotlin_script_Name.new()` does not set the script on the object
@@ -18,8 +16,6 @@ func test_nullables_are_correctly_set_from_function_lika_a_ready_call():
1816
func test_nullables_are_correctly_set_from_inspector():
1917
var test_scene = load("res://Spatial.tscn").instantiate()
2018
get_tree().root.add_child(test_scene)
21-
assert_eq(test_scene.nullable_long, 2, "nullable_long should have been set in inspector to 2")
22-
assert_eq(test_scene.lateinit_string, "works also from inspector", "lateinit_string should have been set in ready to works also from inspector")
2319
assert_true(test_scene.register_object_nullable == null, "register_object_nullable should still be null")
2420
assert_true(test_scene.register_object_nullable_pre_init != null, "register_object_nullable_pre_init should still not be null")
2521
test_scene.free()
@@ -30,34 +26,12 @@ func test_nullables_are_correctly_set_without_attaching_to_a_scene():
3026
var invocation_script = Invocation.new()
3127
node3d.add_child(invocation_script)
3228
invocation_script.init_nullables()
33-
assert_eq(invocation_script.nullable_long, 1, "nullable_long should have been set in ready to 1")
34-
assert_eq(invocation_script.lateinit_string, "works", "lateinit_string should have been set in ready to wokrs")
3529
# TODO: check type once bug is fixed where with `kotlin_script_Name.new()` does not set the script on the object
3630
assert_true(invocation_script.register_object != null, "register_object should have been initialized in ready to an instance of OtherScript")
3731
# TODO: check type once bug is fixed where with `kotlin_script_Name.new()` does not set the script on the object
3832
assert_true(invocation_script.register_object_nullable != null, "register_object_nullable should have been initialized in ready to an instance of OtherScript")
3933
node3d.free()
4034

41-
42-
func test_set_lateinit_from_gdscript():
43-
var node3d = Node3D.new()
44-
var invocation_script = Invocation.new()
45-
node3d.add_child(invocation_script)
46-
invocation_script.lateinit_string = "huhu"
47-
assert_eq(invocation_script.lateinit_string, "huhu", "lateinit_string should have been set from gdScript to huhu")
48-
node3d.free()
49-
50-
51-
func test_set_nullable_from_gdscript():
52-
var node3d = Node3D.new()
53-
var invocation_script = Invocation.new()
54-
node3d.add_child(invocation_script)
55-
assert_eq(invocation_script.nullable_long, null, "nullable_long should be null")
56-
invocation_script.nullable_long = 1234
57-
assert_eq(invocation_script.nullable_long, 1234, "nullable_long should be 1234")
58-
node3d.free()
59-
60-
6135
func test_set_objects_from_gdscript():
6236
var node3d = Node3D.new()
6337
var invocation_script = Invocation.new()
@@ -78,19 +52,3 @@ func test_set_objects_from_gdscript():
7852

7953
invocation_script.free()
8054
node3d.free()
81-
82-
func test_function_nullable_param():
83-
var node3d = Node3D.new()
84-
var invocation_script: Object = Invocation.new()
85-
node3d.add_child(invocation_script)
86-
assert_eq(invocation_script.nullable_string_is_null("huhu"), false, "nullable_string_is_null should return false when string is passed as arg")
87-
assert_eq(invocation_script.nullable_string_is_null(null), true, "nullable_string_is_null should return true when null is passed as arg")
88-
node3d.free()
89-
90-
func test_function_nullable_return():
91-
var node3d = Node3D.new()
92-
var invocation_script = Invocation.new()
93-
node3d.add_child(invocation_script)
94-
assert_eq(invocation_script.nullable_return_type(false), "not null", "nullable_return_type should return \"not null\"")
95-
assert_eq(invocation_script.nullable_return_type(true), null, "nullable_return_type should return null")
96-
node3d.free()

kt/api-generator/src/main/kotlin/godot/codegen/services/impl/GenerationService.kt

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -881,10 +881,9 @@ class GenerationService(
881881
)
882882
} else {
883883
addStatement(
884-
"return·(%T.readReturnValue(%T, %L)·as·%T)${callable.getFromBufferCastingMethod()}",
884+
"return·(%T.readReturnValue(%T)·as·%T)${callable.getFromBufferCastingMethod()}",
885885
TRANSFER_CONTEXT,
886886
returnTypeVariantTypeClass,
887-
callable.nullable,
888887
methodReturnType.typeName
889888
)
890889
}

kt/api-generator/src/main/kotlin/godot/codegen/services/impl/KtCallableGenerationService.kt

Lines changed: 8 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,6 @@ package godot.codegen.services.impl
22

33
import com.squareup.kotlinpoet.ANY
44
import com.squareup.kotlinpoet.AnnotationSpec
5-
import com.squareup.kotlinpoet.BOOLEAN
65
import com.squareup.kotlinpoet.ClassName
76
import com.squareup.kotlinpoet.CodeBlock
87
import com.squareup.kotlinpoet.FileSpec
@@ -15,7 +14,6 @@ import com.squareup.kotlinpoet.ParameterizedTypeName.Companion.parameterizedBy
1514
import com.squareup.kotlinpoet.PropertySpec
1615
import com.squareup.kotlinpoet.TypeSpec
1716
import com.squareup.kotlinpoet.TypeVariableName
18-
import com.squareup.kotlinpoet.asClassName
1917
import godot.codegen.services.IKtCallableGenerationService
2018
import godot.tools.common.constants.GodotFunctions
2119
import godot.tools.common.constants.GodotKotlinJvmTypes
@@ -80,28 +78,21 @@ class KtCallableGenerationService : IKtCallableGenerationService {
8078
.build()
8179
)
8280

83-
val variantTypeClassName = ClassName(
81+
val variantConverterClassName = ClassName(
8482
godotCorePackage,
85-
GodotKotlinJvmTypes.variantType
83+
GodotKotlinJvmTypes.variantConverter
8684
)
8785

8886
primaryConstructor
8987
.addParameter(
9088
ParameterSpec
9189
.builder(
9290
VARIANT_TYPE_ARGUMENT_NAME,
93-
variantTypeClassName
91+
variantConverterClassName
9492
)
9593
.build()
9694
)
9795

98-
val variantTypeToBooleanTypeName = Pair::class
99-
.asClassName()
100-
.parameterizedBy(
101-
variantTypeClassName,
102-
BOOLEAN
103-
)
104-
10596
for (arg in argumentRange) {
10697
val typeProperty = "p${arg}Type"
10798

@@ -111,7 +102,7 @@ class KtCallableGenerationService : IKtCallableGenerationService {
111102
PropertySpec
112103
.builder(
113104
typeProperty,
114-
variantTypeToBooleanTypeName,
105+
variantConverterClassName,
115106
KModifier.PRIVATE
116107
)
117108
.initializer(typeProperty)
@@ -124,7 +115,7 @@ class KtCallableGenerationService : IKtCallableGenerationService {
124115
ParameterSpec
125116
.builder(
126117
typeProperty,
127-
variantTypeToBooleanTypeName
118+
variantConverterClassName
128119
)
129120
.build()
130121
)
@@ -296,7 +287,7 @@ class KtCallableGenerationService : IKtCallableGenerationService {
296287
append("return·$KT_CALLABLE_NAME$argCount(")
297288
append("%M.getOrDefault(%T::class,·%T),·")
298289
for (typeParameter in typeVariableNames) {
299-
append("%M[%T::class]!!·to·%L")
290+
append("%M[%T::class]!!,·")
300291
}
301292
append(FUNCTION_PARAMETER_NAME)
302293
append(')')
@@ -306,7 +297,7 @@ class KtCallableGenerationService : IKtCallableGenerationService {
306297
VARIANT_TYPE_NIL,
307298
*typeVariableNames
308299
.flatMap {
309-
listOf(variantMapperMember, it, true)
300+
listOf(variantMapperMember, it)
310301
}
311302
.toTypedArray()
312303
)
@@ -340,7 +331,7 @@ class KtCallableGenerationService : IKtCallableGenerationService {
340331
const val FUNCTION_PARAMETER_NAME = "function"
341332
const val KT_CALLABLE_NAME = "KtCallable"
342333
const val CALLABLE_FUNCTION_NAME = "callable"
343-
const val VARIANT_TYPE_ARGUMENT_NAME = "variantType"
334+
const val VARIANT_TYPE_ARGUMENT_NAME = "variantConverter"
344335
val KT_CALLABLE_CLASS_NAME = ClassName(callablePackage, KT_CALLABLE_NAME)
345336
val returnTypeParameter = TypeVariableName("R", ANY.copy(nullable = true))
346337
}

kt/entry-generation/godot-entry-generator/src/main/kotlin/godot/entrygenerator/ext/TypeExtensions.kt

Lines changed: 37 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -3,22 +3,55 @@ package godot.entrygenerator.ext
33
import com.squareup.kotlinpoet.ClassName
44
import com.squareup.kotlinpoet.TypeName
55
import godot.entrygenerator.model.Type
6-
import godot.tools.common.constants.*
6+
import godot.tools.common.constants.GodotKotlinJvmTypes
7+
import godot.tools.common.constants.GodotTypes
8+
import godot.tools.common.constants.VARIANT_CASTER_BYTE
9+
import godot.tools.common.constants.VARIANT_CASTER_FLOAT
10+
import godot.tools.common.constants.VARIANT_CASTER_INT
11+
import godot.tools.common.constants.VARIANT_TYPE_AABB
12+
import godot.tools.common.constants.VARIANT_TYPE_ANY
13+
import godot.tools.common.constants.VARIANT_TYPE_ARRAY
14+
import godot.tools.common.constants.VARIANT_TYPE_BOOL
15+
import godot.tools.common.constants.VARIANT_TYPE_DOUBLE
16+
import godot.tools.common.constants.VARIANT_TYPE_LONG
17+
import godot.tools.common.constants.VARIANT_TYPE_NIL
18+
import godot.tools.common.constants.VARIANT_TYPE_NODE_PATH
19+
import godot.tools.common.constants.VARIANT_TYPE_OBJECT
20+
import godot.tools.common.constants.VARIANT_TYPE_PACKED_BYTE_ARRAY
21+
import godot.tools.common.constants.VARIANT_TYPE_PACKED_CALLABLE
22+
import godot.tools.common.constants.VARIANT_TYPE_PACKED_COLOR_ARRAY
23+
import godot.tools.common.constants.VARIANT_TYPE_PACKED_FLOAT_32_ARRAY
24+
import godot.tools.common.constants.VARIANT_TYPE_PACKED_FLOAT_64_ARRAY
25+
import godot.tools.common.constants.VARIANT_TYPE_PACKED_INT_32_ARRAY
26+
import godot.tools.common.constants.VARIANT_TYPE_PACKED_INT_64_ARRAY
27+
import godot.tools.common.constants.VARIANT_TYPE_PACKED_STRING_ARRAY
28+
import godot.tools.common.constants.VARIANT_TYPE_PACKED_VECTOR2_ARRAY
29+
import godot.tools.common.constants.VARIANT_TYPE_PACKED_VECTOR3_ARRAY
30+
import godot.tools.common.constants.VARIANT_TYPE_STRING
31+
import godot.tools.common.constants.VARIANT_TYPE_STRING_NAME
32+
import godot.tools.common.constants.VARIANT_TYPE_TRANSFORM2D
33+
import godot.tools.common.constants.VARIANT_TYPE_TRANSFORM3D
34+
import godot.tools.common.constants.VARIANT_TYPE__RID
35+
import godot.tools.common.constants.godotApiPackage
36+
import godot.tools.common.constants.godotCallablePackage
37+
import godot.tools.common.constants.godotCorePackage
38+
import godot.tools.common.constants.godotUtilPackage
39+
import godot.tools.common.constants.variantTypePackage
740
import godot.tools.common.extensions.convertToCamelCase
841
import java.util.*
942

1043
//TODO: make compatible with other languages
1144
fun Type?.toKtVariantType(): ClassName = when {
1245
this == null || fqName == Unit::class.qualifiedName -> VARIANT_TYPE_NIL
13-
fqName == Int::class.qualifiedName -> VARIANT_TYPE_JVM_INT
46+
fqName == Byte::class.qualifiedName -> VARIANT_CASTER_BYTE
47+
fqName == Int::class.qualifiedName -> VARIANT_CASTER_INT
1448
fqName == "$godotUtilPackage.${GodotKotlinJvmTypes.naturalT}" ||
1549
fqName == Long::class.qualifiedName -> VARIANT_TYPE_LONG
16-
fqName == Float::class.qualifiedName -> VARIANT_TYPE_JVM_FLOAT
50+
fqName == Float::class.qualifiedName -> VARIANT_CASTER_FLOAT
1751
fqName == "$godotUtilPackage.${GodotKotlinJvmTypes.realT}" ||
1852
fqName == Double::class.qualifiedName -> VARIANT_TYPE_DOUBLE
1953
fqName == String::class.qualifiedName -> VARIANT_TYPE_STRING
2054
fqName == Boolean::class.qualifiedName -> VARIANT_TYPE_BOOL
21-
fqName == Byte::class.qualifiedName -> VARIANT_TYPE_JVM_BYTE
2255
fqName == "$godotCorePackage.${GodotKotlinJvmTypes.variantArray}" -> VARIANT_TYPE_ARRAY
2356
fqName == "$godotCorePackage.${GodotTypes.stringName}" -> VARIANT_TYPE_STRING_NAME
2457
fqName == "$godotCorePackage.${GodotTypes.rid}" -> VARIANT_TYPE__RID

kt/entry-generation/godot-entry-generator/src/main/kotlin/godot/entrygenerator/generator/ConstructorRegistrationGenerator.kt

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,7 @@ object ConstructorRegistrationGenerator {
3636
templateArgs.add(valueParameter.name)
3737
templateArgs.add(
3838
valueParameter.type.toTypeName()
39-
) //setting nullables explicitly to false in case of type parameters for generic types, setting nullablility later
39+
) //setting nullables explicitly to false in case of type parameters for generic types, setting nullability later
4040

4141
if (valueParameter.typeArguments.isNotEmpty()) {
4242
append("<")
@@ -79,9 +79,8 @@ object ConstructorRegistrationGenerator {
7979
append(")},·")
8080

8181
registeredConstructor.parameters.forEachIndexed { index, valueParameter ->
82-
append("%T·to·%L")
82+
append("%T")
8383
templateArgs.add(valueParameter.type.toKtVariantType())
84-
templateArgs.add(valueParameter.type.isNullable)
8584

8685
if (index != registeredConstructor.parameters.size - 1) {
8786
append("")

kt/entry-generation/godot-entry-generator/src/main/kotlin/godot/entrygenerator/generator/FunctionRegistrationGenerator.kt

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -80,7 +80,7 @@ object FunctionRegistrationGenerator {
8080

8181
if (registeredFunction.parameters.isNotEmpty()) {
8282
registeredFunction.parameters.forEach { _ ->
83-
append(",·%T·to·%L") //Variant type
83+
append(",·%T") //Variant type
8484
}
8585
registeredFunction.parameters.forEach { _ ->
8686
append(",·%T(%T,·%S,·%S)") //argument KtFunctionArgument
@@ -100,7 +100,6 @@ object FunctionRegistrationGenerator {
100100
if (registeredFunction.parameters.isNotEmpty()) {
101101
registeredFunction.parameters.forEach { parameter ->
102102
add(parameter.type.toKtVariantType())
103-
add(parameter.type.isNullable)
104103
}
105104
registeredFunction.parameters.forEach { valueParameter ->
106105
add(ktFunctionArgumentClassName)

0 commit comments

Comments
 (0)