Skip to content

Commit

Permalink
Dart: fix problems with default values that use immutable types (#1623)
Browse files Browse the repository at this point in the history
This series fixes problems that occur when either 'Immutable'
or 'PositionalDefaults' annotation is used in combination with
immutable types that have default value.

In both cases the resulting code did not contain the required
'const' keyword.

-------- Content of change --------
- New smoke and functional tests that were used to confirm
   the invalid behavior.
- Adjustments of 'DartStructConstructors.mustache' file to
  correctly prepend 'const' keyword when needed for immutable
  struct fields.

Signed-off-by: Patryk Wrobel <[email protected]>
  • Loading branch information
pwrobeldev authored Nov 27, 2024
1 parent aa0f504 commit 92226b7
Show file tree
Hide file tree
Showing 11 changed files with 735 additions and 1 deletion.
3 changes: 2 additions & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,8 @@
* Implemented validation of comments used for lambdas. When the description of parameters or return value is missing, then warning is generated. The user may also treat the warning as error via 'werror' flag.
* Implemented validation of comments used for functions. When the description of parameters or return value is missing, then warning is generated. The user may also treat the warning as error via 'werror' flag.
### Bug fixes:
* Dart: fixed a bug related to missing/superflous 'const' keyword usage in definition of default values in constructors that used collections when `@Immutable` or `PositionalDefaults` were specified.
* Dart: fixed a bug related to missing 'const' keyword usage in definition of default values in constructors that used immutable structure types when `@Immutable` or `@PositionalDefaults` were specified.
* Dart: fixed a bug related to missing/superflous 'const' keyword usage in definition of default values in constructors that used collections when `@Immutable` or `@PositionalDefaults` were specified.

## 13.9.7
Release date 2024-11-13
Expand Down
20 changes: 20 additions & 0 deletions functional-tests/functional/input/lime/Defaults.lime
Original file line number Diff line number Diff line change
Expand Up @@ -77,6 +77,26 @@ class Defaults {
@Dart("withIntegers")
field constructor(someField, anotherField)
}
@Immutable
struct SomeImmutableStructWithDefaults {
intField: Int = 42
}
@Immutable
struct ImmutableStructWithFieldUsingImmutableStruct {
someField1: SomeImmutableStructWithDefaults = {}
someField2: ImmutableStructWithCollections = {}
}
@Immutable
struct ImmutableStructWithFieldConstructorAndFieldUsingImmutableStruct {
someField1: SomeImmutableStructWithDefaults = {}
someField2: ImmutableStructWithCollections = {}

someField: Int = 5
anotherField: Int = 7

@Dart("withIntegers")
field constructor(someField, anotherField)
}
struct StructWithSpecialDefaults {
floatNanField: Float = NaN
floatInfinityField: Float = Infinity
Expand Down
12 changes: 12 additions & 0 deletions functional-tests/functional/input/lime/PositionalDefaults.lime
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,18 @@ struct StructWithNullableCollectionDefaults {
nullableSetField: Set<String>? = null
}

@Immutable
@Java(Skip) @Swift(Skip)
struct AnotherImmutableStructWithDefaults {
intField: Int = 42
}

@Dart(PositionalDefaults)
@Java(Skip) @Swift(Skip)
struct PosDefaultStructWithFieldUsingImmutableStruct {
someField1: AnotherImmutableStructWithDefaults = {}
}

@Dart(PositionalDefaults)
@Java(Skip) @Swift(Skip)
struct PosDefaultsWithDuration {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -86,6 +86,7 @@ Explicit `field constructor` definitions
}}{{#instanceOf type "LimeList"}}const {{/instanceOf}}{{!!
}}{{#instanceOf type "LimeMap"}}const {{/instanceOf}}{{!!
}}{{#instanceOf type "LimeSet"}}const {{/instanceOf}}{{!!
}}{{#instanceOf type "LimeStruct"}}const {{/instanceOf}}{{!!
}}{{/set}}{{!!
}}{{/notInstanceOf}}{{/constPrefix}}{{!!
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,18 @@ struct StructWithNullableCollectionDefaults {
nullableSetField: Set<String>? = null
}

@Immutable
@Java(Skip) @Swift(Skip)
struct ImmutableStructWithDefaults {
intField: Int = 42
}

@Dart(PositionalDefaults)
@Java(Skip) @Swift(Skip)
struct PosDefaultStructWithFieldUsingImmutableStruct {
someField1: ImmutableStructWithDefaults = {}
}

// Foo Bar this is a comment
// @constructor buzz fizz
@Dart(PositionalDefaults = "Sorry, this is deprecated.")
Expand Down
23 changes: 23 additions & 0 deletions gluecodium/src/test/resources/smoke/defaults/input/Defaults.lime
Original file line number Diff line number Diff line change
Expand Up @@ -118,6 +118,29 @@ struct TypesWithDefaults {
@Dart("withIntegers")
field constructor(someField, anotherField)
}

@Immutable
struct SomeImmutableStructWithDefaults {
intField: Int = 42
}

@Immutable
struct ImmutableStructWithFieldUsingImmutableStruct {
someField1: SomeImmutableStructWithDefaults = {}
someField2: ImmutableStructWithCollections = {}
}

@Immutable
struct ImmutableStructWithFieldConstructorAndFieldUsingImmutableStruct {
someField1: SomeImmutableStructWithDefaults = {}
someField2: ImmutableStructWithCollections = {}

someField: Int = 5
anotherField: Int = 7

@Dart("withIntegers")
field constructor(someField, anotherField)
}
}

struct StructWithInitializerDefaults {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -169,6 +169,64 @@ public ImmutableStructWithFieldConstructorAndCollections(final int someField, fi

}

public static final class SomeImmutableStructWithDefaults {
public final int intField;

public SomeImmutableStructWithDefaults() {
this.intField = 42;
}

public SomeImmutableStructWithDefaults(final int intField) {
this.intField = intField;
}


}

public static final class ImmutableStructWithFieldUsingImmutableStruct {
@NonNull
public final TypesWithDefaults.SomeImmutableStructWithDefaults someField1;
@NonNull
public final TypesWithDefaults.ImmutableStructWithCollections someField2;

public ImmutableStructWithFieldUsingImmutableStruct() {
this.someField1 = new TypesWithDefaults.SomeImmutableStructWithDefaults();
this.someField2 = new TypesWithDefaults.ImmutableStructWithCollections();
}

public ImmutableStructWithFieldUsingImmutableStruct(@NonNull final TypesWithDefaults.SomeImmutableStructWithDefaults someField1, @NonNull final TypesWithDefaults.ImmutableStructWithCollections someField2) {
this.someField1 = someField1;
this.someField2 = someField2;
}


}

public static final class ImmutableStructWithFieldConstructorAndFieldUsingImmutableStruct {
@NonNull
public final TypesWithDefaults.SomeImmutableStructWithDefaults someField1;
@NonNull
public final TypesWithDefaults.ImmutableStructWithCollections someField2;
public final int someField;
public final int anotherField;

public ImmutableStructWithFieldConstructorAndFieldUsingImmutableStruct(@NonNull final TypesWithDefaults.SomeImmutableStructWithDefaults someField1, @NonNull final TypesWithDefaults.ImmutableStructWithCollections someField2, final int someField, final int anotherField) {
this.someField1 = someField1;
this.someField2 = someField2;
this.someField = someField;
this.anotherField = anotherField;
}

public ImmutableStructWithFieldConstructorAndFieldUsingImmutableStruct(final int someField, final int anotherField) {
this.someField = someField;
this.anotherField = anotherField;
this.someField1 = new TypesWithDefaults.SomeImmutableStructWithDefaults();
this.someField2 = new TypesWithDefaults.ImmutableStructWithCollections();
}


}



}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -83,6 +83,37 @@ struct _GLUECODIUM_CPP_EXPORT TypesWithDefaults {

};

struct _GLUECODIUM_CPP_EXPORT SomeImmutableStructWithDefaults {
const int32_t int_field = 42;

SomeImmutableStructWithDefaults( );
explicit SomeImmutableStructWithDefaults( int32_t int_field );

};

struct _GLUECODIUM_CPP_EXPORT ImmutableStructWithFieldUsingImmutableStruct {
const ::smoke::TypesWithDefaults::SomeImmutableStructWithDefaults some_field1 = ::smoke::TypesWithDefaults::SomeImmutableStructWithDefaults{};
const ::smoke::TypesWithDefaults::ImmutableStructWithCollections some_field2 = ::smoke::TypesWithDefaults::ImmutableStructWithCollections{};

ImmutableStructWithFieldUsingImmutableStruct( );
ImmutableStructWithFieldUsingImmutableStruct( ::smoke::TypesWithDefaults::SomeImmutableStructWithDefaults some_field1, ::smoke::TypesWithDefaults::ImmutableStructWithCollections some_field2 );

};

struct _GLUECODIUM_CPP_EXPORT ImmutableStructWithFieldConstructorAndFieldUsingImmutableStruct {
const ::smoke::TypesWithDefaults::SomeImmutableStructWithDefaults some_field1 = ::smoke::TypesWithDefaults::SomeImmutableStructWithDefaults{};
const ::smoke::TypesWithDefaults::ImmutableStructWithCollections some_field2 = ::smoke::TypesWithDefaults::ImmutableStructWithCollections{};
const int32_t some_field = 5;
const int32_t another_field = 7;

ImmutableStructWithFieldConstructorAndFieldUsingImmutableStruct( );

ImmutableStructWithFieldConstructorAndFieldUsingImmutableStruct( int32_t some_field, int32_t another_field );

ImmutableStructWithFieldConstructorAndFieldUsingImmutableStruct( ::smoke::TypesWithDefaults::SomeImmutableStructWithDefaults some_field1, ::smoke::TypesWithDefaults::ImmutableStructWithCollections some_field2, int32_t some_field, int32_t another_field );

};

};


Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,89 @@


import 'dart:ffi';
import 'package:library/src/_library_context.dart' as __lib;
import 'package:library/src/smoke/immutable_struct_with_defaults.dart';


class PosDefaultStructWithFieldUsingImmutableStruct {
ImmutableStructWithDefaults someField1;

PosDefaultStructWithFieldUsingImmutableStruct([ImmutableStructWithDefaults someField1 = const ImmutableStructWithDefaults.withDefaults()])
: someField1 = someField1;
}


// PosDefaultStructWithFieldUsingImmutableStruct "private" section, not exported.

final _smokePosdefaultstructwithfieldusingimmutablestructCreateHandle = __lib.catchArgumentError(() => __lib.nativeLibrary.lookupFunction<
Pointer<Void> Function(Pointer<Void>),
Pointer<Void> Function(Pointer<Void>)
>('library_smoke_PosDefaultStructWithFieldUsingImmutableStruct_create_handle'));
final _smokePosdefaultstructwithfieldusingimmutablestructReleaseHandle = __lib.catchArgumentError(() => __lib.nativeLibrary.lookupFunction<
Void Function(Pointer<Void>),
void Function(Pointer<Void>)
>('library_smoke_PosDefaultStructWithFieldUsingImmutableStruct_release_handle'));
final _smokePosdefaultstructwithfieldusingimmutablestructGetFieldsomeField1 = __lib.catchArgumentError(() => __lib.nativeLibrary.lookupFunction<
Pointer<Void> Function(Pointer<Void>),
Pointer<Void> Function(Pointer<Void>)
>('library_smoke_PosDefaultStructWithFieldUsingImmutableStruct_get_field_someField1'));



Pointer<Void> smokePosdefaultstructwithfieldusingimmutablestructToFfi(PosDefaultStructWithFieldUsingImmutableStruct value) {
final _someField1Handle = smokeImmutablestructwithdefaultsToFfi(value.someField1);
final _result = _smokePosdefaultstructwithfieldusingimmutablestructCreateHandle(_someField1Handle);
smokeImmutablestructwithdefaultsReleaseFfiHandle(_someField1Handle);
return _result;
}

PosDefaultStructWithFieldUsingImmutableStruct smokePosdefaultstructwithfieldusingimmutablestructFromFfi(Pointer<Void> handle) {
final _someField1Handle = _smokePosdefaultstructwithfieldusingimmutablestructGetFieldsomeField1(handle);
try {
return PosDefaultStructWithFieldUsingImmutableStruct(
smokeImmutablestructwithdefaultsFromFfi(_someField1Handle)
);
} finally {
smokeImmutablestructwithdefaultsReleaseFfiHandle(_someField1Handle);
}
}

void smokePosdefaultstructwithfieldusingimmutablestructReleaseFfiHandle(Pointer<Void> handle) => _smokePosdefaultstructwithfieldusingimmutablestructReleaseHandle(handle);

// Nullable PosDefaultStructWithFieldUsingImmutableStruct

final _smokePosdefaultstructwithfieldusingimmutablestructCreateHandleNullable = __lib.catchArgumentError(() => __lib.nativeLibrary.lookupFunction<
Pointer<Void> Function(Pointer<Void>),
Pointer<Void> Function(Pointer<Void>)
>('library_smoke_PosDefaultStructWithFieldUsingImmutableStruct_create_handle_nullable'));
final _smokePosdefaultstructwithfieldusingimmutablestructReleaseHandleNullable = __lib.catchArgumentError(() => __lib.nativeLibrary.lookupFunction<
Void Function(Pointer<Void>),
void Function(Pointer<Void>)
>('library_smoke_PosDefaultStructWithFieldUsingImmutableStruct_release_handle_nullable'));
final _smokePosdefaultstructwithfieldusingimmutablestructGetValueNullable = __lib.catchArgumentError(() => __lib.nativeLibrary.lookupFunction<
Pointer<Void> Function(Pointer<Void>),
Pointer<Void> Function(Pointer<Void>)
>('library_smoke_PosDefaultStructWithFieldUsingImmutableStruct_get_value_nullable'));

Pointer<Void> smokePosdefaultstructwithfieldusingimmutablestructToFfiNullable(PosDefaultStructWithFieldUsingImmutableStruct? value) {
if (value == null) return Pointer<Void>.fromAddress(0);
final _handle = smokePosdefaultstructwithfieldusingimmutablestructToFfi(value);
final result = _smokePosdefaultstructwithfieldusingimmutablestructCreateHandleNullable(_handle);
smokePosdefaultstructwithfieldusingimmutablestructReleaseFfiHandle(_handle);
return result;
}

PosDefaultStructWithFieldUsingImmutableStruct? smokePosdefaultstructwithfieldusingimmutablestructFromFfiNullable(Pointer<Void> handle) {
if (handle.address == 0) return null;
final _handle = _smokePosdefaultstructwithfieldusingimmutablestructGetValueNullable(handle);
final result = smokePosdefaultstructwithfieldusingimmutablestructFromFfi(_handle);
smokePosdefaultstructwithfieldusingimmutablestructReleaseFfiHandle(_handle);
return result;
}

void smokePosdefaultstructwithfieldusingimmutablestructReleaseFfiHandleNullable(Pointer<Void> handle) =>
_smokePosdefaultstructwithfieldusingimmutablestructReleaseHandleNullable(handle);

// End of PosDefaultStructWithFieldUsingImmutableStruct "private" section.


Loading

0 comments on commit 92226b7

Please sign in to comment.