diff --git a/CHANGELOG.md b/CHANGELOG.md index bf75361f46..80e7cc6444 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,7 @@ ## Unreleased ### Bug fixes: + * Dart: fixed a bug related to compilation error caused by usage of `@PositionalDefaults` and default value for a field that uses type, which does not provide const constructor. * Dart: disabled generation of `invalid_use_of_visible_for_testing_member` warning from the generated code for a hierarchy of classes. * Dart: removed generation of redundant import for constants declared with external types. The redundant import caused linter warnings. * Dart: removed generation of redundant `default` clause in exhaustive switch-cases for enumerations. The redundant `default` caused linter warnings. diff --git a/docs/lime_attributes.md b/docs/lime_attributes.md index de1ce0c892..3ddfbf285f 100644 --- a/docs/lime_attributes.md +++ b/docs/lime_attributes.md @@ -131,6 +131,12 @@ name was defined through command-line parameters. If the tag is not present, the positional parameters in Dart. Can only be applied to a struct that has at least one field with a default value. The positional defaults constructor will be generated with a `@Deprecated` annotation, if _DeprecationMessage_ is specified. +> **Important:** if the constructor used for the default value is non-const, then the generated constructor will use +> optional value to prevent compilation error. However, this implies certain limitation for default values of nullable +> types, which do not provide const constructor (i.a. Blob type or custom structures that are not annotated as `@Immutable`). +> +> If the field is nullable and its type does not provide const constructor then the only default value that is accepted +> can be null. If any other value is used then the generator will raise validation error. * **Attribute** **=** **"**_Annotation_**"**: marks an element to be marked with the given annotation in Dart generated code. _Annotation_ does not need to be prepended with `@`. _Annotation_ can contain parameters, e.g. `@Dart(Attribute="Deprecated(\"It's deprecated.\")")`. If some of the parameters are string literals, their enclosing diff --git a/functional-tests/functional/dart/test/Defaults_test.dart b/functional-tests/functional/dart/test/Defaults_test.dart index c206f4d830..ce8c802e24 100644 --- a/functional-tests/functional/dart/test/Defaults_test.dart +++ b/functional-tests/functional/dart/test/Defaults_test.dart @@ -18,6 +18,7 @@ // // ------------------------------------------------------------------------------------------------- +import 'dart:typed_data'; import "package:test/test.dart"; import "package:functional/test.dart"; import "../test_suite.dart"; @@ -103,6 +104,48 @@ void main() { expect(result.intField, 13); expect(result.stringField, "foobar"); }); + _testSuite.test("Check positional defaults for non-const constructible types", () { + // Case 1: all defaults. + final first = PosDefaultStructWithCustomStructsFields(); + expect(first.nonConstCtorField0.intField, 42); + expect(first.nonConstCtorField1.someField1.intField, 42); + expect(first.nonConstCtorField2.stringField, "Some string"); + expect(first.nonConstCtorField3.nullableListField, null); + expect(first.nonConstCtorField5, Uint8List.fromList([])); + expect(first.nonConstCtorField6, Uint8List.fromList([222, 173, 190, 239])); + expect(first.nonConstCtorField7, null); + + // Case 2: custom values. + final second = PosDefaultStructWithCustomStructsFields( + // Fields with const constructors. + AnotherImmutableStructWithDefaults.withDefaults(), + null, + [], + null, + 0, + 0.0, + null, + null, + // Fields without const constructor. + StructWithAllDefaults(21, "ABC"), + PosDefaultStructWithFieldUsingImmutableStruct(), + SomeMutableCustomStructWithDefaults(21, "Another string", [7, 7, 7]), + StructWithNullableCollectionDefaults(), + StructWithAllDefaults(44, "DEF"), + Uint8List.fromList([1, 2, 3]), + Uint8List.fromList([4, 5, 6]), + Uint8List.fromList([7, 8, 9]) + ); + + expect(second.nonConstCtorField0.intField, 21); + expect(second.nonConstCtorField1.someField1.intField, 42); + expect(second.nonConstCtorField2.stringField, "Another string"); + expect(second.nonConstCtorField3.nullableListField, null); + expect(second.nonConstCtorField4?.stringField, "DEF"); + expect(second.nonConstCtorField5, Uint8List.fromList([1, 2, 3])); + expect(second.nonConstCtorField6, Uint8List.fromList([4, 5, 6])); + expect(second.nonConstCtorField7, Uint8List.fromList([7, 8, 9])); + }); _testSuite.test("Check positional enumerator defaults", () { final result = StructWithEnums(); diff --git a/functional-tests/functional/input/lime/PositionalDefaults.lime b/functional-tests/functional/input/lime/PositionalDefaults.lime index bc6ad208a6..c9275cacff 100644 --- a/functional-tests/functional/input/lime/PositionalDefaults.lime +++ b/functional-tests/functional/input/lime/PositionalDefaults.lime @@ -72,6 +72,36 @@ struct PosDefaultStructWithFieldUsingImmutableStruct { someField1: AnotherImmutableStructWithDefaults = {} } +@Dart(PositionalDefaults) +@Java(Skip) @Swift(Skip) +struct SomeMutableCustomStructWithDefaults { + intField: Int = 77 + stringField: String = "Some string" + listField: List = [1, 2, 3] +} + +@Dart(PositionalDefaults) +@Java(Skip) @Swift(Skip) +struct PosDefaultStructWithCustomStructsFields { + constCtorField0: AnotherImmutableStructWithDefaults = {} + constCtorField1: AnotherImmutableStructWithDefaults? = {} + constCtorField2: List = ["abc", "def", "ghi"] + constCtorField3: Map? = null + constCtorField4: Int = 77 + constCtorField5: Double = 77.77 + constCtorField6: AnotherImmutableStructWithDefaults? = {} + constCtorField7: AnotherImmutableStructWithDefaults? = null + + nonConstCtorField0: StructWithAllDefaults = {} + nonConstCtorField1: PosDefaultStructWithFieldUsingImmutableStruct = {} + nonConstCtorField2: SomeMutableCustomStructWithDefaults = {} + nonConstCtorField3: StructWithNullableCollectionDefaults = {} + nonConstCtorField4: StructWithAllDefaults? = null + nonConstCtorField5: Blob = [] + nonConstCtorField6: Blob = [222, 173, 190, 239] + nonConstCtorField7: Blob? = null +} + @Dart(PositionalDefaults) @Java(Skip) @Swift(Skip) struct PosDefaultsWithDuration { diff --git a/gluecodium/src/main/java/com/here/gluecodium/generator/dart/DartDefaultValuesValidator.kt b/gluecodium/src/main/java/com/here/gluecodium/generator/dart/DartDefaultValuesValidator.kt new file mode 100644 index 0000000000..7a8f3a1861 --- /dev/null +++ b/gluecodium/src/main/java/com/here/gluecodium/generator/dart/DartDefaultValuesValidator.kt @@ -0,0 +1,76 @@ +/* + * Copyright (C) 2016-2024 HERE Europe B.V. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * SPDX-License-Identifier: Apache-2.0 + * License-Filename: LICENSE + */ + +package com.here.gluecodium.generator.dart + +import com.here.gluecodium.common.LimeLogger +import com.here.gluecodium.model.lime.LimeAttributeType.DART +import com.here.gluecodium.model.lime.LimeAttributeType.IMMUTABLE +import com.here.gluecodium.model.lime.LimeAttributeValueType +import com.here.gluecodium.model.lime.LimeBasicType +import com.here.gluecodium.model.lime.LimeElement +import com.here.gluecodium.model.lime.LimeStruct +import com.here.gluecodium.model.lime.LimeValue + +class DartDefaultValuesValidator(private val logger: LimeLogger) { + fun validate(referenceMap: Map): Boolean { + val allStructs = referenceMap.values.filterIsInstance() + return !allStructs.map { validatePositionalDefaults(it) }.contains(false) + } + + private fun validatePositionalDefaults(limeStruct: LimeStruct): Boolean { + if (!limeStruct.attributes.have(DART, LimeAttributeValueType.POSITIONAL_DEFAULTS)) { + return true + } + + var result = true + for (field in limeStruct.initializedFields) { + // Types other than BLOB and custom LimeStructs provide const constructors. + val basicType = field.typeRef.type as? LimeBasicType + if (field.typeRef.type !is LimeStruct && (basicType?.typeId != LimeBasicType.TypeId.BLOB)) { + continue + } + + // Custom immutable types provide const constructors. + if (field.typeRef.type.attributes.have(IMMUTABLE)) { + continue + } + + // If the type does not provide const constructor, then generated 'PositionalDefaults' constructor + // will utilize optional field to avoid compilation errors. + // However, if the user uses 'nullable type' and wants to set value that is different from 'null' as the + // default one, then if somebody passed 'null' to the generated constructor, then it wouldn't be honored. + // + // Do not allow users to do that. + if (field.typeRef.isNullable && field.defaultValue!! !is LimeValue.Null) { + logger.error(field, "$NULLABLE_ERROR_REASON; please check $DOCS_LINK") + result = false + } + } + + return result + } + + companion object { + const val NULLABLE_ERROR_REASON = + "For '@PositionalDefaults' structs, nullable fields that do not provide" + + " const constructors must use 'null' default value" + const val DOCS_LINK = "https://github.com/heremaps/gluecodium/blob/master/docs/lime_attributes.md#dart-specific-attributes" + } +} diff --git a/gluecodium/src/main/java/com/here/gluecodium/generator/dart/DartGenerator.kt b/gluecodium/src/main/java/com/here/gluecodium/generator/dart/DartGenerator.kt index a3784c254b..27e21d64f4 100644 --- a/gluecodium/src/main/java/com/here/gluecodium/generator/dart/DartGenerator.kt +++ b/gluecodium/src/main/java/com/here/gluecodium/generator/dart/DartGenerator.kt @@ -122,10 +122,12 @@ internal class DartGenerator : Generator { val dartNameResolver = DartNameResolver(ffiReferenceMap, nameRules, limeLogger, commentsProcessor) val ffiNameResolver = FfiNameResolver(ffiReferenceMap, nameRules, internalPrefix) - val validationResult = + val overloadsValidationResult = DartOverloadsValidator(dartNameResolver, limeLogger, overloadsWerror) .validate(dartFilteredModel.referenceMap.values) - if (!validationResult) { + val defaultValuesValidationResult = + DartDefaultValuesValidator(limeLogger).validate(dartFilteredModel.referenceMap) + if (!overloadsValidationResult || !defaultValuesValidationResult) { throw GluecodiumExecutionException("Validation errors found, see log for details.") } diff --git a/gluecodium/src/main/java/com/here/gluecodium/generator/dart/DartGeneratorPredicates.kt b/gluecodium/src/main/java/com/here/gluecodium/generator/dart/DartGeneratorPredicates.kt index 704020cacb..30377deacb 100644 --- a/gluecodium/src/main/java/com/here/gluecodium/generator/dart/DartGeneratorPredicates.kt +++ b/gluecodium/src/main/java/com/here/gluecodium/generator/dart/DartGeneratorPredicates.kt @@ -25,9 +25,11 @@ import com.here.gluecodium.generator.common.CommonGeneratorPredicates import com.here.gluecodium.model.lime.LimeAttributeType.DART import com.here.gluecodium.model.lime.LimeAttributeType.IMMUTABLE import com.here.gluecodium.model.lime.LimeAttributeValueType.POSITIONAL_DEFAULTS +import com.here.gluecodium.model.lime.LimeBasicType import com.here.gluecodium.model.lime.LimeContainer import com.here.gluecodium.model.lime.LimeElement import com.here.gluecodium.model.lime.LimeExternalDescriptor +import com.here.gluecodium.model.lime.LimeField import com.here.gluecodium.model.lime.LimeNamedElement import com.here.gluecodium.model.lime.LimeStruct import com.here.gluecodium.model.lime.LimeType @@ -45,6 +47,23 @@ internal class DartGeneratorPredicates( "allFieldsCtorIsPublic" to { limeStruct: Any -> limeStruct is LimeStruct && allFieldsCtorIsPublic(limeStruct) }, + "fieldHasConstCtor" to { limeField: Any -> + if (limeField is LimeField) { + when (limeField.typeRef.type) { + is LimeBasicType -> { + val basicType = limeField.typeRef.type as LimeBasicType + basicType.typeId != LimeBasicType.TypeId.BLOB + } + is LimeStruct -> limeField.typeRef.type.attributes.have(IMMUTABLE) + else -> true + } + } else { + false + } + }, + "fieldHasDefaultValue" to { limeField: Any -> + limeField is LimeField && limeField.defaultValue != null + }, "isInternal" to { element: Any -> when (element) { // Dart has no type nesting, so all types are "outside" and have to check for an internal outer type. diff --git a/gluecodium/src/main/resources/templates/dart/DartStructConstructors.mustache b/gluecodium/src/main/resources/templates/dart/DartStructConstructors.mustache index 13722d792f..e49c38917b 100644 --- a/gluecodium/src/main/resources/templates/dart/DartStructConstructors.mustache +++ b/gluecodium/src/main/resources/templates/dart/DartStructConstructors.mustache @@ -28,8 +28,27 @@ {{/instanceOf}}{{!! }} {{#if attributes.immutable}}const {{/if}}{{resolveName}}{{#if external.dart.converter}}Internal{{/if}}({{!! }}{{#uninitializedFields}}{{resolveName typeRef}} {{resolveName}}, {{/uninitializedFields}}{{!! - }}[{{#initializedFields}}{{resolveName typeRef}} {{resolveName}} = {{>constPrefix}}{{resolveName defaultValue}}{{#if iter.hasNext}}, {{/if}}{{/initializedFields}}]) - : {{#fields}}{{resolveName "visibility"}}{{resolveName}} = {{resolveName}}{{#if iter.hasNext}}, {{/if}}{{/fields}}; + }}[{{#initializedFields}}{{!! +}}{{#ifPredicate "fieldHasConstCtor"}}{{!! +}}{{resolveName typeRef}} {{resolveName}} = {{>constPrefix}}{{resolveName defaultValue}}{{#if iter.hasNext}}, {{/if}}{{!! +}}{{/ifPredicate}}{{!! +}}{{#unlessPredicate "fieldHasConstCtor"}}{{!! +}}{{resolveName typeRef.asNullable}} {{resolveName}} = null{{#if iter.hasNext}}, {{/if}}{{!! +}}{{/unlessPredicate}}{{!! +}}{{/initializedFields}}]) + : {{#fields}}{{!! +}}{{#ifPredicate "fieldHasDefaultValue"}}{{!! +}}{{#ifPredicate "fieldHasConstCtor"}}{{!! +}}{{resolveName "visibility"}}{{resolveName}} = {{resolveName}}{{#if iter.hasNext}}, {{/if}}{{!! +}}{{/ifPredicate}}{{!! +}}{{#unlessPredicate "fieldHasConstCtor"}}{{!! +}}{{resolveName "visibility"}}{{resolveName}} = {{resolveName}} ?? {{resolveName defaultValue}}{{#if iter.hasNext}}, {{/if}}{{!! +}}{{/unlessPredicate}}{{!! +}}{{/ifPredicate}}{{!! +}}{{#unlessPredicate "fieldHasDefaultValue"}}{{!! +}}{{resolveName "visibility"}}{{resolveName}} = {{resolveName}}{{#if iter.hasNext}}, {{/if}}{{!! +}}{{/unlessPredicate}}{{!! +}}{{/fields}}; {{/if}}{{!! }}{{#unless attributes.dart.positionalDefaults initializedFields}}{{!! diff --git a/gluecodium/src/test/java/com/here/gluecodium/generator/dart/DartDefaultValuesValidatorTest.kt b/gluecodium/src/test/java/com/here/gluecodium/generator/dart/DartDefaultValuesValidatorTest.kt new file mode 100644 index 0000000000..a7173eaaf2 --- /dev/null +++ b/gluecodium/src/test/java/com/here/gluecodium/generator/dart/DartDefaultValuesValidatorTest.kt @@ -0,0 +1,208 @@ +/* + * Copyright (C) 2016-2024 HERE Europe B.V. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * SPDX-License-Identifier: Apache-2.0 + * License-Filename: LICENSE + */ + +package com.here.gluecodium.generator.dart + +import com.here.gluecodium.model.lime.LimeAttributeType +import com.here.gluecodium.model.lime.LimeAttributeValueType +import com.here.gluecodium.model.lime.LimeAttributes +import com.here.gluecodium.model.lime.LimeBasicType +import com.here.gluecodium.model.lime.LimeBasicTypeRef +import com.here.gluecodium.model.lime.LimeDirectTypeRef +import com.here.gluecodium.model.lime.LimeElement +import com.here.gluecodium.model.lime.LimeField +import com.here.gluecodium.model.lime.LimePath +import com.here.gluecodium.model.lime.LimeStruct +import com.here.gluecodium.model.lime.LimeValue +import io.mockk.mockk +import org.junit.Assert.assertFalse +import org.junit.Assert.assertTrue +import org.junit.Test +import org.junit.runner.RunWith +import org.junit.runners.JUnit4 + +@RunWith(JUnit4::class) +class DartDefaultValuesValidatorTest { + private val allElements = mutableMapOf() + private val typePath = LimePath(emptyList(), listOf("someType")) + private val anotherTypePath = LimePath(emptyList(), listOf("anotherType")) + private val anotherType = LimeStruct(path = anotherTypePath) + private val positionalDefaultsAttributes = + LimeAttributes.Builder().addAttribute( + LimeAttributeType.DART, + LimeAttributeValueType.POSITIONAL_DEFAULTS, + ).build() + private val immutableAttributes = LimeAttributes.Builder().addAttribute(LimeAttributeType.IMMUTABLE).build() + private val anotherImmutableType = LimeStruct(path = anotherTypePath, attributes = immutableAttributes) + private val validator = DartDefaultValuesValidator(mockk(relaxed = true)) + + @Test + fun validateStructWithoutPositionalDefaults() { + // Given a structure that is not annotated with 'PositionalDefaults' + // and has nullable field with default value different from 'null'. + val field = + LimeField( + path = typePath.child("someField"), + typeRef = LimeDirectTypeRef(type = anotherType, isNullable = true), + defaultValue = LimeValue.StructInitializer(LimeDirectTypeRef(type = anotherType, isNullable = true), listOf()), + ) + + val structWithFields = LimeStruct(path = typePath, fields = listOf(field)) + allElements[typePath.toString()] = structWithFields + + // When validating default values. + val result = validator.validate(allElements) + + // Then validation succeeds. + assertTrue(result) + } + + @Test + fun validatePositionalDefaultsStructThatDoesNotHaveStructFields() { + // Given a structure that is annotated with 'PositionalDefaults' + // and has nullable field that is not struct and has value different from 'null'. + val field = + LimeField( + path = typePath.child("someField"), + typeRef = LimeBasicTypeRef(LimeBasicType.TypeId.INT32, isNullable = true), + defaultValue = LimeValue.Literal(LimeBasicTypeRef(LimeBasicType.TypeId.INT32, isNullable = true), "123"), + ) + + val structWithFields = LimeStruct(path = typePath, fields = listOf(field), attributes = positionalDefaultsAttributes) + allElements[typePath.toString()] = structWithFields + + // When validating default values. + val result = validator.validate(allElements) + + // Then validation succeeds. + assertTrue(result) + } + + @Test + fun validatePositionalDefaultsStructThatHasImmutableField() { + // Given a structure that is annotated with 'PositionalDefaults' + // and has nullable field annotated as immutable with default value different from 'null'. + val field = + LimeField( + path = typePath.child("someField"), + typeRef = LimeDirectTypeRef(type = anotherImmutableType, isNullable = true), + defaultValue = LimeValue.StructInitializer(LimeDirectTypeRef(type = anotherImmutableType, isNullable = true), listOf()), + ) + + val structWithFields = LimeStruct(path = typePath, fields = listOf(field), attributes = positionalDefaultsAttributes) + allElements[typePath.toString()] = structWithFields + + // When validating default values. + val result = validator.validate(allElements) + + // Then validation succeeds. + assertTrue(result) + } + + @Test + fun validatePositionalDefaultsStructThatHasMutableStructFieldEqualsNull() { + // Given a structure that is annotated with 'PositionalDefaults' + // and has nullable field with default value equals 'null'. + val field = + LimeField( + path = typePath.child("someField"), + typeRef = LimeDirectTypeRef(type = anotherType, isNullable = true), + defaultValue = LimeValue.Null(LimeDirectTypeRef(type = anotherType, isNullable = true)), + ) + + val structWithFields = LimeStruct(path = typePath, fields = listOf(field), attributes = positionalDefaultsAttributes) + allElements[typePath.toString()] = structWithFields + + // When validating default values. + val result = validator.validate(allElements) + + // Then validation succeeds. + assertTrue(result) + } + + @Test + fun validatePositionalDefaultsStructThatHasMutableStructFieldNotEqualNull() { + // Given a structure that is annotated with 'PositionalDefaults' + // and has nullable field with default value different from 'null'. + val field = + LimeField( + path = typePath.child("someField"), + typeRef = LimeDirectTypeRef(type = anotherType, isNullable = true), + defaultValue = LimeValue.StructInitializer(LimeDirectTypeRef(type = anotherType, isNullable = true), listOf()), + ) + + val structWithFields = LimeStruct(path = typePath, fields = listOf(field), attributes = positionalDefaultsAttributes) + allElements[typePath.toString()] = structWithFields + + // When validating default values. + val result = validator.validate(allElements) + + // Then validation fails. + assertFalse(result) + } + + @Test + fun validatePositionalDefaultsStructThatHasMutableBlobFieldEqualsNull() { + // Given a structure that is annotated with 'PositionalDefaults' + // and has nullable BLOB field with default value equals 'null'. + val field = + LimeField( + path = typePath.child("someField"), + typeRef = LimeBasicTypeRef(LimeBasicType.TypeId.BLOB, isNullable = true), + defaultValue = LimeValue.Null(LimeBasicTypeRef(LimeBasicType.TypeId.BLOB, isNullable = true)), + ) + + val structWithFields = LimeStruct(path = typePath, fields = listOf(field), attributes = positionalDefaultsAttributes) + allElements[typePath.toString()] = structWithFields + + // When validating default values. + val result = validator.validate(allElements) + + // Then validation succeeds. + assertTrue(result) + } + + @Test + fun validatePositionalDefaultsStructThatHasMutableBlobFieldNotEqualToNull() { + // Given a structure that is annotated with 'PositionalDefaults' + // and has nullable BLOB field with default value different from 'null'. + val field = + LimeField( + path = typePath.child("someField"), + typeRef = LimeBasicTypeRef(LimeBasicType.TypeId.BLOB, isNullable = true), + defaultValue = + LimeValue.InitializerList( + type = LimeBasicTypeRef(LimeBasicType.TypeId.BLOB, isNullable = true), + listOf( + LimeValue.Literal(type = LimeBasicTypeRef(LimeBasicType.TypeId.BLOB), value = "128"), + LimeValue.Literal(type = LimeBasicTypeRef(LimeBasicType.TypeId.BLOB), value = "230"), + ), + ), + ) + + val structWithFields = LimeStruct(path = typePath, fields = listOf(field), attributes = positionalDefaultsAttributes) + allElements[typePath.toString()] = structWithFields + + // When validating default values. + val result = validator.validate(allElements) + + // Then validation fails. + assertFalse(result) + } +} diff --git a/gluecodium/src/test/resources/smoke/defaults/input/DartPositionalDefaults.lime b/gluecodium/src/test/resources/smoke/defaults/input/DartPositionalDefaults.lime index df1d944637..43caa3eb51 100644 --- a/gluecodium/src/test/resources/smoke/defaults/input/DartPositionalDefaults.lime +++ b/gluecodium/src/test/resources/smoke/defaults/input/DartPositionalDefaults.lime @@ -62,6 +62,35 @@ struct PosDefaultStructWithFieldUsingImmutableStruct { someField1: ImmutableStructWithDefaults = {} } +@Java(Skip) @Swift(Skip) +struct SomeMutableCustomStructWithDefaults { + intField: Int = 77 + stringField: String = "Some string" + listField: List = [1, 2, 3] +} + +@Dart(PositionalDefaults) +@Java(Skip) @Swift(Skip) +struct PosDefaultStructWithCustomStructsFields { + constCtorField0: ImmutableStructWithDefaults = {} + constCtorField1: ImmutableStructWithDefaults? = {} + constCtorField2: List = ["abc", "def", "ghi"] + constCtorField3: Map? = null + constCtorField4: Int = 77 + constCtorField5: Double = 77.77 + constCtorField6: ImmutableStructWithDefaults? = {} + constCtorField7: ImmutableStructWithDefaults? = null + + nonConstCtorField0: StructWithAllDefaults = {} + nonConstCtorField1: PosDefaultStructWithFieldUsingImmutableStruct = {} + nonConstCtorField2: SomeMutableCustomStructWithDefaults = {} + nonConstCtorField3: StructWithNullableCollectionDefaults = {} + nonConstCtorField4: StructWithAllDefaults? = null + nonConstCtorField5: Blob = [] + nonConstCtorField6: Blob = [222, 173, 190, 239] + nonConstCtorField7: Blob? = null +} + // Foo Bar this is a comment // @constructor buzz fizz @Dart(PositionalDefaults = "Sorry, this is deprecated.") diff --git a/gluecodium/src/test/resources/smoke/defaults/output/dart/lib/src/smoke/pos_default_struct_with_custom_structs_fields.dart b/gluecodium/src/test/resources/smoke/defaults/output/dart/lib/src/smoke/pos_default_struct_with_custom_structs_fields.dart new file mode 100644 index 0000000000..fc056284f0 --- /dev/null +++ b/gluecodium/src/test/resources/smoke/defaults/output/dart/lib/src/smoke/pos_default_struct_with_custom_structs_fields.dart @@ -0,0 +1,261 @@ + + +import 'dart:ffi'; +import 'dart:typed_data'; +import 'package:library/src/_library_context.dart' as __lib; +import 'package:library/src/builtin_types__conversion.dart'; +import 'package:library/src/generic_types__conversion.dart'; +import 'package:library/src/smoke/immutable_struct_with_defaults.dart'; +import 'package:library/src/smoke/pos_default_struct_with_field_using_immutable_struct.dart'; +import 'package:library/src/smoke/some_mutable_custom_struct_with_defaults.dart'; +import 'package:library/src/smoke/struct_with_all_defaults.dart'; +import 'package:library/src/smoke/struct_with_nullable_collection_defaults.dart'; + + +class PosDefaultStructWithCustomStructsFields { + ImmutableStructWithDefaults constCtorField0; + + ImmutableStructWithDefaults? constCtorField1; + + List constCtorField2; + + Map? constCtorField3; + + int constCtorField4; + + double constCtorField5; + + ImmutableStructWithDefaults? constCtorField6; + + ImmutableStructWithDefaults? constCtorField7; + + StructWithAllDefaults nonConstCtorField0; + + PosDefaultStructWithFieldUsingImmutableStruct nonConstCtorField1; + + SomeMutableCustomStructWithDefaults nonConstCtorField2; + + StructWithNullableCollectionDefaults nonConstCtorField3; + + StructWithAllDefaults? nonConstCtorField4; + + Uint8List nonConstCtorField5; + + Uint8List nonConstCtorField6; + + Uint8List? nonConstCtorField7; + + PosDefaultStructWithCustomStructsFields([ImmutableStructWithDefaults constCtorField0 = const ImmutableStructWithDefaults.withDefaults(), ImmutableStructWithDefaults? constCtorField1 = const ImmutableStructWithDefaults.withDefaults(), List constCtorField2 = const ["abc", "def", "ghi"], Map? constCtorField3 = null, int constCtorField4 = 77, double constCtorField5 = 77.77, ImmutableStructWithDefaults? constCtorField6 = const ImmutableStructWithDefaults.withDefaults(), ImmutableStructWithDefaults? constCtorField7 = null, StructWithAllDefaults? nonConstCtorField0 = null, PosDefaultStructWithFieldUsingImmutableStruct? nonConstCtorField1 = null, SomeMutableCustomStructWithDefaults? nonConstCtorField2 = null, StructWithNullableCollectionDefaults? nonConstCtorField3 = null, StructWithAllDefaults? nonConstCtorField4 = null, Uint8List? nonConstCtorField5 = null, Uint8List? nonConstCtorField6 = null, Uint8List? nonConstCtorField7 = null]) + : constCtorField0 = constCtorField0, constCtorField1 = constCtorField1, constCtorField2 = constCtorField2, constCtorField3 = constCtorField3, constCtorField4 = constCtorField4, constCtorField5 = constCtorField5, constCtorField6 = constCtorField6, constCtorField7 = constCtorField7, nonConstCtorField0 = nonConstCtorField0 ?? StructWithAllDefaults(), nonConstCtorField1 = nonConstCtorField1 ?? PosDefaultStructWithFieldUsingImmutableStruct(), nonConstCtorField2 = nonConstCtorField2 ?? SomeMutableCustomStructWithDefaults(), nonConstCtorField3 = nonConstCtorField3 ?? StructWithNullableCollectionDefaults(), nonConstCtorField4 = nonConstCtorField4 ?? null, nonConstCtorField5 = nonConstCtorField5 ?? Uint8List.fromList([]), nonConstCtorField6 = nonConstCtorField6 ?? Uint8List.fromList([222, 173, 190, 239]), nonConstCtorField7 = nonConstCtorField7 ?? null; +} + + +// PosDefaultStructWithCustomStructsFields "private" section, not exported. + +final _smokePosdefaultstructwithcustomstructsfieldsCreateHandle = __lib.catchArgumentError(() => __lib.nativeLibrary.lookupFunction< + Pointer Function(Pointer, Pointer, Pointer, Pointer, Int32, Double, Pointer, Pointer, Pointer, Pointer, Pointer, Pointer, Pointer, Pointer, Pointer, Pointer), + Pointer Function(Pointer, Pointer, Pointer, Pointer, int, double, Pointer, Pointer, Pointer, Pointer, Pointer, Pointer, Pointer, Pointer, Pointer, Pointer) + >('library_smoke_PosDefaultStructWithCustomStructsFields_create_handle')); +final _smokePosdefaultstructwithcustomstructsfieldsReleaseHandle = __lib.catchArgumentError(() => __lib.nativeLibrary.lookupFunction< + Void Function(Pointer), + void Function(Pointer) + >('library_smoke_PosDefaultStructWithCustomStructsFields_release_handle')); +final _smokePosdefaultstructwithcustomstructsfieldsGetFieldconstCtorField0 = __lib.catchArgumentError(() => __lib.nativeLibrary.lookupFunction< + Pointer Function(Pointer), + Pointer Function(Pointer) + >('library_smoke_PosDefaultStructWithCustomStructsFields_get_field_constCtorField0')); +final _smokePosdefaultstructwithcustomstructsfieldsGetFieldconstCtorField1 = __lib.catchArgumentError(() => __lib.nativeLibrary.lookupFunction< + Pointer Function(Pointer), + Pointer Function(Pointer) + >('library_smoke_PosDefaultStructWithCustomStructsFields_get_field_constCtorField1')); +final _smokePosdefaultstructwithcustomstructsfieldsGetFieldconstCtorField2 = __lib.catchArgumentError(() => __lib.nativeLibrary.lookupFunction< + Pointer Function(Pointer), + Pointer Function(Pointer) + >('library_smoke_PosDefaultStructWithCustomStructsFields_get_field_constCtorField2')); +final _smokePosdefaultstructwithcustomstructsfieldsGetFieldconstCtorField3 = __lib.catchArgumentError(() => __lib.nativeLibrary.lookupFunction< + Pointer Function(Pointer), + Pointer Function(Pointer) + >('library_smoke_PosDefaultStructWithCustomStructsFields_get_field_constCtorField3')); +final _smokePosdefaultstructwithcustomstructsfieldsGetFieldconstCtorField4 = __lib.catchArgumentError(() => __lib.nativeLibrary.lookupFunction< + Int32 Function(Pointer), + int Function(Pointer) + >('library_smoke_PosDefaultStructWithCustomStructsFields_get_field_constCtorField4')); +final _smokePosdefaultstructwithcustomstructsfieldsGetFieldconstCtorField5 = __lib.catchArgumentError(() => __lib.nativeLibrary.lookupFunction< + Double Function(Pointer), + double Function(Pointer) + >('library_smoke_PosDefaultStructWithCustomStructsFields_get_field_constCtorField5')); +final _smokePosdefaultstructwithcustomstructsfieldsGetFieldconstCtorField6 = __lib.catchArgumentError(() => __lib.nativeLibrary.lookupFunction< + Pointer Function(Pointer), + Pointer Function(Pointer) + >('library_smoke_PosDefaultStructWithCustomStructsFields_get_field_constCtorField6')); +final _smokePosdefaultstructwithcustomstructsfieldsGetFieldconstCtorField7 = __lib.catchArgumentError(() => __lib.nativeLibrary.lookupFunction< + Pointer Function(Pointer), + Pointer Function(Pointer) + >('library_smoke_PosDefaultStructWithCustomStructsFields_get_field_constCtorField7')); +final _smokePosdefaultstructwithcustomstructsfieldsGetFieldnonConstCtorField0 = __lib.catchArgumentError(() => __lib.nativeLibrary.lookupFunction< + Pointer Function(Pointer), + Pointer Function(Pointer) + >('library_smoke_PosDefaultStructWithCustomStructsFields_get_field_nonConstCtorField0')); +final _smokePosdefaultstructwithcustomstructsfieldsGetFieldnonConstCtorField1 = __lib.catchArgumentError(() => __lib.nativeLibrary.lookupFunction< + Pointer Function(Pointer), + Pointer Function(Pointer) + >('library_smoke_PosDefaultStructWithCustomStructsFields_get_field_nonConstCtorField1')); +final _smokePosdefaultstructwithcustomstructsfieldsGetFieldnonConstCtorField2 = __lib.catchArgumentError(() => __lib.nativeLibrary.lookupFunction< + Pointer Function(Pointer), + Pointer Function(Pointer) + >('library_smoke_PosDefaultStructWithCustomStructsFields_get_field_nonConstCtorField2')); +final _smokePosdefaultstructwithcustomstructsfieldsGetFieldnonConstCtorField3 = __lib.catchArgumentError(() => __lib.nativeLibrary.lookupFunction< + Pointer Function(Pointer), + Pointer Function(Pointer) + >('library_smoke_PosDefaultStructWithCustomStructsFields_get_field_nonConstCtorField3')); +final _smokePosdefaultstructwithcustomstructsfieldsGetFieldnonConstCtorField4 = __lib.catchArgumentError(() => __lib.nativeLibrary.lookupFunction< + Pointer Function(Pointer), + Pointer Function(Pointer) + >('library_smoke_PosDefaultStructWithCustomStructsFields_get_field_nonConstCtorField4')); +final _smokePosdefaultstructwithcustomstructsfieldsGetFieldnonConstCtorField5 = __lib.catchArgumentError(() => __lib.nativeLibrary.lookupFunction< + Pointer Function(Pointer), + Pointer Function(Pointer) + >('library_smoke_PosDefaultStructWithCustomStructsFields_get_field_nonConstCtorField5')); +final _smokePosdefaultstructwithcustomstructsfieldsGetFieldnonConstCtorField6 = __lib.catchArgumentError(() => __lib.nativeLibrary.lookupFunction< + Pointer Function(Pointer), + Pointer Function(Pointer) + >('library_smoke_PosDefaultStructWithCustomStructsFields_get_field_nonConstCtorField6')); +final _smokePosdefaultstructwithcustomstructsfieldsGetFieldnonConstCtorField7 = __lib.catchArgumentError(() => __lib.nativeLibrary.lookupFunction< + Pointer Function(Pointer), + Pointer Function(Pointer) + >('library_smoke_PosDefaultStructWithCustomStructsFields_get_field_nonConstCtorField7')); + + + +Pointer smokePosdefaultstructwithcustomstructsfieldsToFfi(PosDefaultStructWithCustomStructsFields value) { + final _constCtorField0Handle = smokeImmutablestructwithdefaultsToFfi(value.constCtorField0); + final _constCtorField1Handle = smokeImmutablestructwithdefaultsToFfiNullable(value.constCtorField1); + final _constCtorField2Handle = foobarListofStringToFfi(value.constCtorField2); + final _constCtorField3Handle = foobarMapofStringToStringToFfiNullable(value.constCtorField3); + final _constCtorField4Handle = (value.constCtorField4); + final _constCtorField5Handle = (value.constCtorField5); + final _constCtorField6Handle = smokeImmutablestructwithdefaultsToFfiNullable(value.constCtorField6); + final _constCtorField7Handle = smokeImmutablestructwithdefaultsToFfiNullable(value.constCtorField7); + final _nonConstCtorField0Handle = smokeStructwithalldefaultsToFfi(value.nonConstCtorField0); + final _nonConstCtorField1Handle = smokePosdefaultstructwithfieldusingimmutablestructToFfi(value.nonConstCtorField1); + final _nonConstCtorField2Handle = smokeSomemutablecustomstructwithdefaultsToFfi(value.nonConstCtorField2); + final _nonConstCtorField3Handle = smokeStructwithnullablecollectiondefaultsToFfi(value.nonConstCtorField3); + final _nonConstCtorField4Handle = smokeStructwithalldefaultsToFfiNullable(value.nonConstCtorField4); + final _nonConstCtorField5Handle = blobToFfi(value.nonConstCtorField5); + final _nonConstCtorField6Handle = blobToFfi(value.nonConstCtorField6); + final _nonConstCtorField7Handle = blobToFfiNullable(value.nonConstCtorField7); + final _result = _smokePosdefaultstructwithcustomstructsfieldsCreateHandle(_constCtorField0Handle, _constCtorField1Handle, _constCtorField2Handle, _constCtorField3Handle, _constCtorField4Handle, _constCtorField5Handle, _constCtorField6Handle, _constCtorField7Handle, _nonConstCtorField0Handle, _nonConstCtorField1Handle, _nonConstCtorField2Handle, _nonConstCtorField3Handle, _nonConstCtorField4Handle, _nonConstCtorField5Handle, _nonConstCtorField6Handle, _nonConstCtorField7Handle); + smokeImmutablestructwithdefaultsReleaseFfiHandle(_constCtorField0Handle); + smokeImmutablestructwithdefaultsReleaseFfiHandleNullable(_constCtorField1Handle); + foobarListofStringReleaseFfiHandle(_constCtorField2Handle); + foobarMapofStringToStringReleaseFfiHandleNullable(_constCtorField3Handle); + + + smokeImmutablestructwithdefaultsReleaseFfiHandleNullable(_constCtorField6Handle); + smokeImmutablestructwithdefaultsReleaseFfiHandleNullable(_constCtorField7Handle); + smokeStructwithalldefaultsReleaseFfiHandle(_nonConstCtorField0Handle); + smokePosdefaultstructwithfieldusingimmutablestructReleaseFfiHandle(_nonConstCtorField1Handle); + smokeSomemutablecustomstructwithdefaultsReleaseFfiHandle(_nonConstCtorField2Handle); + smokeStructwithnullablecollectiondefaultsReleaseFfiHandle(_nonConstCtorField3Handle); + smokeStructwithalldefaultsReleaseFfiHandleNullable(_nonConstCtorField4Handle); + blobReleaseFfiHandle(_nonConstCtorField5Handle); + blobReleaseFfiHandle(_nonConstCtorField6Handle); + blobReleaseFfiHandleNullable(_nonConstCtorField7Handle); + return _result; +} + +PosDefaultStructWithCustomStructsFields smokePosdefaultstructwithcustomstructsfieldsFromFfi(Pointer handle) { + final _constCtorField0Handle = _smokePosdefaultstructwithcustomstructsfieldsGetFieldconstCtorField0(handle); + final _constCtorField1Handle = _smokePosdefaultstructwithcustomstructsfieldsGetFieldconstCtorField1(handle); + final _constCtorField2Handle = _smokePosdefaultstructwithcustomstructsfieldsGetFieldconstCtorField2(handle); + final _constCtorField3Handle = _smokePosdefaultstructwithcustomstructsfieldsGetFieldconstCtorField3(handle); + final _constCtorField4Handle = _smokePosdefaultstructwithcustomstructsfieldsGetFieldconstCtorField4(handle); + final _constCtorField5Handle = _smokePosdefaultstructwithcustomstructsfieldsGetFieldconstCtorField5(handle); + final _constCtorField6Handle = _smokePosdefaultstructwithcustomstructsfieldsGetFieldconstCtorField6(handle); + final _constCtorField7Handle = _smokePosdefaultstructwithcustomstructsfieldsGetFieldconstCtorField7(handle); + final _nonConstCtorField0Handle = _smokePosdefaultstructwithcustomstructsfieldsGetFieldnonConstCtorField0(handle); + final _nonConstCtorField1Handle = _smokePosdefaultstructwithcustomstructsfieldsGetFieldnonConstCtorField1(handle); + final _nonConstCtorField2Handle = _smokePosdefaultstructwithcustomstructsfieldsGetFieldnonConstCtorField2(handle); + final _nonConstCtorField3Handle = _smokePosdefaultstructwithcustomstructsfieldsGetFieldnonConstCtorField3(handle); + final _nonConstCtorField4Handle = _smokePosdefaultstructwithcustomstructsfieldsGetFieldnonConstCtorField4(handle); + final _nonConstCtorField5Handle = _smokePosdefaultstructwithcustomstructsfieldsGetFieldnonConstCtorField5(handle); + final _nonConstCtorField6Handle = _smokePosdefaultstructwithcustomstructsfieldsGetFieldnonConstCtorField6(handle); + final _nonConstCtorField7Handle = _smokePosdefaultstructwithcustomstructsfieldsGetFieldnonConstCtorField7(handle); + try { + return PosDefaultStructWithCustomStructsFields( + smokeImmutablestructwithdefaultsFromFfi(_constCtorField0Handle), + smokeImmutablestructwithdefaultsFromFfiNullable(_constCtorField1Handle), + foobarListofStringFromFfi(_constCtorField2Handle), + foobarMapofStringToStringFromFfiNullable(_constCtorField3Handle), + (_constCtorField4Handle), + (_constCtorField5Handle), + smokeImmutablestructwithdefaultsFromFfiNullable(_constCtorField6Handle), + smokeImmutablestructwithdefaultsFromFfiNullable(_constCtorField7Handle), + smokeStructwithalldefaultsFromFfi(_nonConstCtorField0Handle), + smokePosdefaultstructwithfieldusingimmutablestructFromFfi(_nonConstCtorField1Handle), + smokeSomemutablecustomstructwithdefaultsFromFfi(_nonConstCtorField2Handle), + smokeStructwithnullablecollectiondefaultsFromFfi(_nonConstCtorField3Handle), + smokeStructwithalldefaultsFromFfiNullable(_nonConstCtorField4Handle), + blobFromFfi(_nonConstCtorField5Handle), + blobFromFfi(_nonConstCtorField6Handle), + blobFromFfiNullable(_nonConstCtorField7Handle) + ); + } finally { + smokeImmutablestructwithdefaultsReleaseFfiHandle(_constCtorField0Handle); + smokeImmutablestructwithdefaultsReleaseFfiHandleNullable(_constCtorField1Handle); + foobarListofStringReleaseFfiHandle(_constCtorField2Handle); + foobarMapofStringToStringReleaseFfiHandleNullable(_constCtorField3Handle); + + + smokeImmutablestructwithdefaultsReleaseFfiHandleNullable(_constCtorField6Handle); + smokeImmutablestructwithdefaultsReleaseFfiHandleNullable(_constCtorField7Handle); + smokeStructwithalldefaultsReleaseFfiHandle(_nonConstCtorField0Handle); + smokePosdefaultstructwithfieldusingimmutablestructReleaseFfiHandle(_nonConstCtorField1Handle); + smokeSomemutablecustomstructwithdefaultsReleaseFfiHandle(_nonConstCtorField2Handle); + smokeStructwithnullablecollectiondefaultsReleaseFfiHandle(_nonConstCtorField3Handle); + smokeStructwithalldefaultsReleaseFfiHandleNullable(_nonConstCtorField4Handle); + blobReleaseFfiHandle(_nonConstCtorField5Handle); + blobReleaseFfiHandle(_nonConstCtorField6Handle); + blobReleaseFfiHandleNullable(_nonConstCtorField7Handle); + } +} + +void smokePosdefaultstructwithcustomstructsfieldsReleaseFfiHandle(Pointer handle) => _smokePosdefaultstructwithcustomstructsfieldsReleaseHandle(handle); + +// Nullable PosDefaultStructWithCustomStructsFields + +final _smokePosdefaultstructwithcustomstructsfieldsCreateHandleNullable = __lib.catchArgumentError(() => __lib.nativeLibrary.lookupFunction< + Pointer Function(Pointer), + Pointer Function(Pointer) + >('library_smoke_PosDefaultStructWithCustomStructsFields_create_handle_nullable')); +final _smokePosdefaultstructwithcustomstructsfieldsReleaseHandleNullable = __lib.catchArgumentError(() => __lib.nativeLibrary.lookupFunction< + Void Function(Pointer), + void Function(Pointer) + >('library_smoke_PosDefaultStructWithCustomStructsFields_release_handle_nullable')); +final _smokePosdefaultstructwithcustomstructsfieldsGetValueNullable = __lib.catchArgumentError(() => __lib.nativeLibrary.lookupFunction< + Pointer Function(Pointer), + Pointer Function(Pointer) + >('library_smoke_PosDefaultStructWithCustomStructsFields_get_value_nullable')); + +Pointer smokePosdefaultstructwithcustomstructsfieldsToFfiNullable(PosDefaultStructWithCustomStructsFields? value) { + if (value == null) return Pointer.fromAddress(0); + final _handle = smokePosdefaultstructwithcustomstructsfieldsToFfi(value); + final result = _smokePosdefaultstructwithcustomstructsfieldsCreateHandleNullable(_handle); + smokePosdefaultstructwithcustomstructsfieldsReleaseFfiHandle(_handle); + return result; +} + +PosDefaultStructWithCustomStructsFields? smokePosdefaultstructwithcustomstructsfieldsFromFfiNullable(Pointer handle) { + if (handle.address == 0) return null; + final _handle = _smokePosdefaultstructwithcustomstructsfieldsGetValueNullable(handle); + final result = smokePosdefaultstructwithcustomstructsfieldsFromFfi(_handle); + smokePosdefaultstructwithcustomstructsfieldsReleaseFfiHandle(_handle); + return result; +} + +void smokePosdefaultstructwithcustomstructsfieldsReleaseFfiHandleNullable(Pointer handle) => + _smokePosdefaultstructwithcustomstructsfieldsReleaseHandleNullable(handle); + +// End of PosDefaultStructWithCustomStructsFields "private" section. + +