This is an automated email from the ASF dual-hosted git repository.
chaokunyang pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/fory.git
The following commit(s) were added to refs/heads/main by this push:
new 3cd75123c refactor(dart): register xlang types by Type (#3332)
3cd75123c is described below
commit 3cd75123cf73ddc1d229425debf1ab0c8c831e43
Author: Shawn Yang <[email protected]>
AuthorDate: Tue Feb 17 21:41:51 2026 +0800
refactor(dart): register xlang types by Type (#3332)
## Why?
- Dart registration currently requires generated `$TypeName` schema
symbols, which exposes codegen internals and makes usage less ergonomic.
- Cross-language Dart tests relied on a large hand-maintained schema
definition file, which is hard to maintain and easy to drift.
- Some declared-type serializer and type-fingerprint paths need stronger
handling to keep schema behavior consistent.
## What does this PR do?
- Refactors Dart registration APIs to register by `Type` (`register`,
`registerType`, `registerStruct`, `registerEnum`, `registerUnion`)
instead of passing `CustomTypeSpec` directly.
- Adds `SpecLookup` with manual registration plus mirrors/stub lookup so
generated specs can be resolved from `Type` at runtime.
- Adds `ref` support to `@ForyKey` and propagates it through codegen to
field `trackingRef` metadata.
- Updates class/list/map deserialization paths to resolve registered
serializers for declared element/key/value/field types and throw clearer
state errors when declared type metadata is missing.
- Aligns field sorting and struct hash fingerprinting for
`INT32`/`INT64` by mapping them to `VAR_INT32`/`VAR_INT64` IDs.
- Replaces the large manual xlang test schema file with
annotation-driven models and migrates Dart examples/tests/perf usage
from `$TypeName` registration to `Type` registration.
## Related issues
## Does this PR introduce any user-facing change?
- Dart registration usage changes from generated spec symbols (for
example, `$Person`) to Dart types (for example, `Person`).
- [x] Does this PR introduce any public API change?
- [ ] Does this PR introduce any binary protocol compatibility change?
## Benchmark
N/A
---
.github/workflows/ci.yml | 4 +
dart/example/example.dart | 4 +-
dart/example/example.g.dart | 5 -
dart/example/nested_collection_example.dart | 2 +-
dart/example/nested_collection_example.g.dart | 5 -
dart/example/typed_data_array_example.dart | 2 +-
dart/example/typed_data_array_example.g.dart | 5 -
.../fory-test/lib/entity/complex_obj_1.dart | 2 +-
.../fory-test/lib/entity/complex_obj_2.dart | 2 +-
.../fory-test/lib/entity/complex_obj_3.dart | 2 +-
.../fory-test/lib/entity/complex_obj_4.dart | 2 +-
.../fory-test/lib/entity/simple_struct1.dart | 2 +-
dart/packages/fory-test/lib/entity/some_class.dart | 2 +-
dart/packages/fory-test/lib/entity/time_obj.dart | 2 +-
.../lib/entity/uint_annotated_struct.dart | 2 +-
.../packages/fory-test/lib/entity/uint_struct.dart | 2 +-
.../fory-test/lib/entity/xlang_test_models.dart | 293 ++++
.../codegen_test/simple_struct_codegen_test.dart | 6 +-
.../cross_lang_struct_serialization_test.dart | 10 +-
.../cross_lang_test/cross_language_type_test.dart | 8 +-
.../register_serialization_test.dart | 2 +-
.../test/cross_lang_test/units/algorithm_test.dart | 2 +-
.../cross_lang_test/units/preserve_type_test.dart | 2 +-
.../test/cross_lang_test/xlang_test_defs.dart | 1723 --------------------
.../test/cross_lang_test/xlang_test_main.dart | 80 +-
.../fory-test/test/perf_test/serial_perf_test.dart | 20 +-
.../struct_test/uint_annotated_struct_test.dart | 12 +-
.../test/struct_test/uint_struct_test.dart | 6 +-
dart/packages/fory/README.md | 8 +-
dart/packages/fory/example/example.dart | 4 +-
dart/packages/fory/example/example.g.dart | 5 -
.../packages/fory/lib/src/annotation/fory_key.dart | 4 +
.../impl/annotation/key_annotation_analyzer.dart | 3 +
.../analyze/impl/field/field_analyzer_impl.dart | 1 +
.../codegen/meta/impl/class_spec_generator.dart | 17 -
.../codegen/meta/impl/field_spec_immutable.dart | 9 +-
dart/packages/fory/lib/src/fory_impl.dart | 40 +-
.../fory/lib/src/meta/specs/field_sorter.dart | 4 +-
.../lib/src/resolver/impl/type_resolver_impl.dart | 107 ++
.../fory/lib/src/resolver/spec_lookup.dart | 52 +
.../fory/lib/src/resolver/spec_lookup_mirrors.dart | 89 +
.../fory/lib/src/resolver/spec_lookup_stub.dart} | 11 +-
.../lib/src/resolver/struct_hash_resolver.dart | 6 +
.../fory/lib/src/resolver/type_resolver.dart | 26 +-
.../fory/lib/src/serializer/class_serializer.dart | 18 +
.../collection/list/list_serializer.dart | 7 +-
.../serializer/collection/map/map_serializer.dart | 39 +-
.../java/org/apache/fory/xlang/DartXlangTest.java | 31 +-
48 files changed, 785 insertions(+), 1905 deletions(-)
diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml
index 8071b79da..e289bbe06 100644
--- a/.github/workflows/ci.yml
+++ b/.github/workflows/ci.yml
@@ -708,6 +708,10 @@ jobs:
run: |
cd dart
dart pub get
+ - name: Generate Dart code
+ run: |
+ cd dart/packages/fory-test
+ dart run build_runner build --delete-conflicting-outputs
- name: Run Dart Xlang Test
env:
FORY_DART_JAVA_CI: "1"
diff --git a/dart/example/example.dart b/dart/example/example.dart
index 12b965991..44b88a6e5 100644
--- a/dart/example/example.dart
+++ b/dart/example/example.dart
@@ -24,7 +24,7 @@ import 'package:fory/fory.dart';
part 'example.g.dart';
@foryClass
-class Person with _$PersonFory {
+class Person {
final String firstName, lastName;
final int age;
final LocalDate dateOfBirth;
@@ -34,7 +34,7 @@ class Person with _$PersonFory {
void main() {
Fory fory = Fory(ref: true);
- fory.register($Person, typename: "example.Person");
+ fory.register(Person, typename: "example.Person");
Person obj = Person('Leo', 'Leo', 21, LocalDate(2004, 1, 1));
// Serialize
diff --git a/dart/example/example.g.dart b/dart/example/example.g.dart
index 31635b0ab..016177afb 100644
--- a/dart/example/example.g.dart
+++ b/dart/example/example.g.dart
@@ -99,8 +99,3 @@ final $Person = TypeSpec(
),
null,
);
-
-mixin _$PersonFory implements ForyTypeProvider {
- @override
- Type get foryType => Person;
-}
diff --git a/dart/example/nested_collection_example.dart
b/dart/example/nested_collection_example.dart
index 805932705..0754ca6a5 100644
--- a/dart/example/nested_collection_example.dart
+++ b/dart/example/nested_collection_example.dart
@@ -22,7 +22,7 @@ import 'package:fory/fory.dart';
part 'nested_collection_example.g.dart';
@foryClass
-class NestedObject with _$NestedObjectFory {
+class NestedObject {
late final String name;
late final List<String> names;
late final Map<double, Map<String, int>> map;
diff --git a/dart/example/nested_collection_example.g.dart
b/dart/example/nested_collection_example.g.dart
index 919e914fa..4f9ff7110 100644
--- a/dart/example/nested_collection_example.g.dart
+++ b/dart/example/nested_collection_example.g.dart
@@ -127,8 +127,3 @@ final $NestedObject = TypeSpec(
null,
() => NestedObject(),
);
-
-mixin _$NestedObjectFory implements ForyTypeProvider {
- @override
- Type get foryType => NestedObject;
-}
diff --git a/dart/example/typed_data_array_example.dart
b/dart/example/typed_data_array_example.dart
index a314d810e..ef630c7f5 100644
--- a/dart/example/typed_data_array_example.dart
+++ b/dart/example/typed_data_array_example.dart
@@ -24,7 +24,7 @@ import 'package:fory/fory.dart';
part 'typed_data_array_example.g.dart';
@foryClass
-class TypedDataArrayExample with _$TypedDataArrayExampleFory {
+class TypedDataArrayExample {
late final Uint8List bytes;
late final Int32List nums;
late final BoolList bools;
diff --git a/dart/example/typed_data_array_example.g.dart
b/dart/example/typed_data_array_example.g.dart
index 4526efbe8..50d5fd60d 100644
--- a/dart/example/typed_data_array_example.g.dart
+++ b/dart/example/typed_data_array_example.g.dart
@@ -82,8 +82,3 @@ final $TypedDataArrayExample = TypeSpec(
null,
() => TypedDataArrayExample(),
);
-
-mixin _$TypedDataArrayExampleFory implements ForyTypeProvider {
- @override
- Type get foryType => TypedDataArrayExample;
-}
diff --git a/dart/packages/fory-test/lib/entity/complex_obj_1.dart
b/dart/packages/fory-test/lib/entity/complex_obj_1.dart
index b580cfc39..37be47dc2 100644
--- a/dart/packages/fory-test/lib/entity/complex_obj_1.dart
+++ b/dart/packages/fory-test/lib/entity/complex_obj_1.dart
@@ -24,7 +24,7 @@ import 'package:fory_test/extensions/map_ext.dart';
part '../generated/complex_obj_1.g.dart';
@foryClass
-class ComplexObject1 with _$ComplexObject1Fory {
+class ComplexObject1 {
late Object f1;
late String f2;
late List<Object> f3;
diff --git a/dart/packages/fory-test/lib/entity/complex_obj_2.dart
b/dart/packages/fory-test/lib/entity/complex_obj_2.dart
index 1cf17f58e..8b96ea764 100644
--- a/dart/packages/fory-test/lib/entity/complex_obj_2.dart
+++ b/dart/packages/fory-test/lib/entity/complex_obj_2.dart
@@ -23,7 +23,7 @@ import 'package:fory_test/extensions/map_ext.dart';
part '../generated/complex_obj_2.g.dart';
@ForyClass(promiseAcyclic: true)
-class ComplexObject2 with _$ComplexObject2Fory {
+class ComplexObject2 {
final Object f1;
final Map<Int8, Int32> f2;
diff --git a/dart/packages/fory-test/lib/entity/complex_obj_3.dart
b/dart/packages/fory-test/lib/entity/complex_obj_3.dart
index 4a6abbfa4..7949ff23b 100644
--- a/dart/packages/fory-test/lib/entity/complex_obj_3.dart
+++ b/dart/packages/fory-test/lib/entity/complex_obj_3.dart
@@ -24,7 +24,7 @@ import 'package:fory_test/extensions/map_ext.dart';
part '../generated/complex_obj_3.g.dart';
@foryClass
-class ComplexObject3 with _$ComplexObject3Fory {
+class ComplexObject3 {
late final List<Map<int, Float32>> f1;
late final HashMap<String, List<SplayTreeMap<int, Float32>>> f2;
late final LinkedHashMap<String, HashSet<Int8>> f3;
diff --git a/dart/packages/fory-test/lib/entity/complex_obj_4.dart
b/dart/packages/fory-test/lib/entity/complex_obj_4.dart
index 02e2c37c0..b76c9ec65 100644
--- a/dart/packages/fory-test/lib/entity/complex_obj_4.dart
+++ b/dart/packages/fory-test/lib/entity/complex_obj_4.dart
@@ -23,7 +23,7 @@ import 'package:fory_test/extensions/map_ext.dart';
part '../generated/complex_obj_4.g.dart';
@foryClass
-class ComplexObject4 with _$ComplexObject4Fory {
+class ComplexObject4 {
late String f1;
late String f2;
late List<String> f3;
diff --git a/dart/packages/fory-test/lib/entity/simple_struct1.dart
b/dart/packages/fory-test/lib/entity/simple_struct1.dart
index dc1794b67..bcaf3e719 100644
--- a/dart/packages/fory-test/lib/entity/simple_struct1.dart
+++ b/dart/packages/fory-test/lib/entity/simple_struct1.dart
@@ -21,7 +21,7 @@ import 'package:fory/fory.dart';
part '../generated/simple_struct1.g.dart';
@foryClass
-class SimpleStruct1 with _$SimpleStruct1Fory {
+class SimpleStruct1 {
late Int32 a;
@override
diff --git a/dart/packages/fory-test/lib/entity/some_class.dart
b/dart/packages/fory-test/lib/entity/some_class.dart
index 78eb65fdb..2ea6eab7b 100644
--- a/dart/packages/fory-test/lib/entity/some_class.dart
+++ b/dart/packages/fory-test/lib/entity/some_class.dart
@@ -22,7 +22,7 @@ import 'package:fory/fory.dart';
part '../generated/some_class.g.dart';
@foryClass
-class SomeClass with _$SomeClassFory {
+class SomeClass {
late int id;
late String name;
late Map<String, double> map;
diff --git a/dart/packages/fory-test/lib/entity/time_obj.dart
b/dart/packages/fory-test/lib/entity/time_obj.dart
index 55f0f1837..302c6f48c 100644
--- a/dart/packages/fory-test/lib/entity/time_obj.dart
+++ b/dart/packages/fory-test/lib/entity/time_obj.dart
@@ -22,7 +22,7 @@ import 'package:fory/fory.dart';
part '../generated/time_obj.g.dart';
@ForyClass(promiseAcyclic: true)
-class TimeObj with _$TimeObjFory {
+class TimeObj {
final LocalDate date1;
final LocalDate date2;
final LocalDate date3;
diff --git a/dart/packages/fory-test/lib/entity/uint_annotated_struct.dart
b/dart/packages/fory-test/lib/entity/uint_annotated_struct.dart
index dcc8b0595..bea56b34f 100644
--- a/dart/packages/fory-test/lib/entity/uint_annotated_struct.dart
+++ b/dart/packages/fory-test/lib/entity/uint_annotated_struct.dart
@@ -24,7 +24,7 @@ part '../generated/uint_annotated_struct.g.dart';
/// Test struct for uint type annotations.
/// Uses native int types with annotations to specify serialization format.
@ForyClass(promiseAcyclic: true)
-class UIntAnnotatedStruct with _$UIntAnnotatedStructFory {
+class UIntAnnotatedStruct {
@Uint8Type()
final int age;
diff --git a/dart/packages/fory-test/lib/entity/uint_struct.dart
b/dart/packages/fory-test/lib/entity/uint_struct.dart
index 70563e12b..ba7fa3515 100644
--- a/dart/packages/fory-test/lib/entity/uint_struct.dart
+++ b/dart/packages/fory-test/lib/entity/uint_struct.dart
@@ -22,7 +22,7 @@ import 'package:fory/fory.dart';
part '../generated/uint_struct.g.dart';
@ForyClass(promiseAcyclic: true)
-class UIntStruct with _$UIntStructFory {
+class UIntStruct {
final UInt8 age;
final UInt16 port;
final UInt32 count;
diff --git a/dart/packages/fory-test/lib/entity/xlang_test_models.dart
b/dart/packages/fory-test/lib/entity/xlang_test_models.dart
new file mode 100644
index 000000000..6f9aef9b9
--- /dev/null
+++ b/dart/packages/fory-test/lib/entity/xlang_test_models.dart
@@ -0,0 +1,293 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you 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.
+ */
+
+import 'package:fory/fory.dart';
+import 'package:fory/src/resolver/spec_lookup.dart';
+
+part '../generated/xlang_test_models.g.dart';
+
+bool _xlangSpecLookupReady = false;
+
+void _ensureXlangSpecLookupReady() {
+ if (_xlangSpecLookupReady) {
+ return;
+ }
+ SpecLookup.register($TestEnum);
+ SpecLookup.register($TwoEnumFieldStructEvolution);
+ SpecLookup.register($RefOverrideElement);
+ SpecLookup.register($RefOverrideContainer);
+ SpecLookup.register($NullableComprehensiveCompatible);
+ SpecLookup.register($Color);
+ SpecLookup.register($Item);
+ SpecLookup.register($SimpleStruct);
+ SpecLookup.register($Item1);
+ SpecLookup.register($StructWithList);
+ SpecLookup.register($StructWithMap);
+ SpecLookup.register($VersionCheckStruct);
+ SpecLookup.register($OneStringFieldStruct);
+ SpecLookup.register($TwoStringFieldStruct);
+ SpecLookup.register($OneEnumFieldStruct);
+ SpecLookup.register($TwoEnumFieldStruct);
+ SpecLookup.register($NullableComprehensiveSchemaConsistent);
+ SpecLookup.register($RefInnerSchemaConsistent);
+ SpecLookup.register($RefOuterSchemaConsistent);
+ SpecLookup.register($RefInnerCompatible);
+ SpecLookup.register($RefOuterCompatible);
+ SpecLookup.register($CircularRefStruct);
+ _xlangSpecLookupReady = true;
+}
+
+void registerXlangStruct(
+ Fory fory,
+ Type type, {
+ int? typeId,
+ String? namespace,
+ String? typename,
+}) {
+ _ensureXlangSpecLookupReady();
+ fory.registerStruct(
+ type,
+ typeId: typeId,
+ namespace: namespace,
+ typename: typename,
+ );
+}
+
+void registerXlangEnum(
+ Fory fory,
+ Type type, {
+ int? typeId,
+ String? namespace,
+ String? typename,
+}) {
+ _ensureXlangSpecLookupReady();
+ fory.registerEnum(
+ type,
+ typeId: typeId,
+ namespace: namespace,
+ typename: typename,
+ );
+}
+
+@foryEnum
+enum TestEnum {
+ VALUE_A,
+ VALUE_B,
+ VALUE_C,
+}
+
+@foryClass
+class TwoEnumFieldStructEvolution {
+ TestEnum f1 = TestEnum.VALUE_A;
+
+ @ForyKey(includeFromFory: false)
+ TestEnum f2 = TestEnum.VALUE_A;
+}
+
+@foryClass
+class RefOverrideElement {
+ Int32 id = Int32(0);
+ String name = '';
+}
+
+@foryClass
+class RefOverrideContainer {
+ List<RefOverrideElement> listField = <RefOverrideElement>[];
+ Map<String, RefOverrideElement> mapField = <String, RefOverrideElement>{};
+}
+
+@foryClass
+class NullableComprehensiveCompatible {
+ double boxedDouble = 0.0;
+ double doubleField = 0.0;
+ Float32 boxedFloat = Float32(0);
+ Float32 floatField = Float32(0);
+ Int16 shortField = Int16(0);
+ Int8 byteField = Int8(0);
+ bool boolField = false;
+ bool boxedBool = false;
+ int boxedLong = 0;
+ int longField = 0;
+ Int32 boxedInt = Int32(0);
+ Int32 intField = Int32(0);
+
+ double? nullableDouble1;
+ Float32? nullableFloat1;
+ bool? nullableBool1;
+ int? nullableLong1;
+ Int32? nullableInt1;
+
+ String? nullableString2;
+ String stringField = '';
+ List<String?> listField = <String?>[];
+ List<String?>? nullableList2;
+ Set<String?>? nullableSet2;
+ Set<String?> setField = <String?>{};
+ Map<String?, String?> mapField = <String?, String?>{};
+ Map<String?, String?>? nullableMap2;
+
+ void normalizeForCompatibleRoundTrip() {
+ nullableDouble1 ??= 0.0;
+ nullableFloat1 ??= Float32(0);
+ nullableBool1 ??= false;
+ nullableLong1 ??= 0;
+ nullableInt1 ??= Int32(0);
+ nullableString2 ??= '';
+ nullableList2 ??= <String>[];
+ nullableSet2 ??= <String>{};
+ nullableMap2 ??= <String, String>{};
+ }
+}
+
+@foryEnum
+enum Color {
+ Green,
+ Red,
+ Blue,
+ White,
+}
+
+@foryClass
+class Item {
+ String name = '';
+}
+
+@foryClass
+class SimpleStruct {
+ Map<Int32?, double?> f1 = <Int32?, double?>{};
+ Int32 f2 = Int32(0);
+ Item f3 = Item();
+ String f4 = '';
+ Color f5 = Color.Green;
+ List<String> f6 = <String>[];
+ Int32 f7 = Int32(0);
+ Int32 f8 = Int32(0);
+ Int32 last = Int32(0);
+}
+
+@foryClass
+class Item1 {
+ Int32 f1 = Int32(0);
+ Int32 f2 = Int32(0);
+ Int32 f3 = Int32(0);
+ Int32 f4 = Int32(0);
+ Int32 f5 = Int32(0);
+ Int32 f6 = Int32(0);
+}
+
+@foryClass
+class StructWithList {
+ List<String?> items = <String?>[];
+}
+
+@foryClass
+class StructWithMap {
+ Map<String?, String?> data = <String?, String?>{};
+}
+
+@foryClass
+class VersionCheckStruct {
+ Int32 f1 = Int32(0);
+ String? f2 = '';
+ double f3 = 0.0;
+}
+
+@foryClass
+class OneStringFieldStruct {
+ String? f1 = '';
+}
+
+@foryClass
+class TwoStringFieldStruct {
+ String f1 = '';
+ String f2 = '';
+}
+
+@foryClass
+class OneEnumFieldStruct {
+ TestEnum f1 = TestEnum.VALUE_A;
+}
+
+@foryClass
+class TwoEnumFieldStruct {
+ TestEnum f1 = TestEnum.VALUE_A;
+ TestEnum f2 = TestEnum.VALUE_A;
+}
+
+@foryClass
+class NullableComprehensiveSchemaConsistent {
+ Int8 byteField = Int8(0);
+ Int16 shortField = Int16(0);
+ Int32 intField = Int32(0);
+ int longField = 0;
+ Float32 floatField = Float32(0);
+ double doubleField = 0.0;
+ bool boolField = false;
+ String stringField = '';
+ List<String?> listField = <String?>[];
+ Set<String?> setField = <String?>{};
+ Map<String?, String?> mapField = <String?, String?>{};
+ Int32? nullableInt;
+ int? nullableLong;
+ Float32? nullableFloat;
+ double? nullableDouble;
+ bool? nullableBool;
+ String? nullableString;
+ List<String?>? nullableList;
+ Set<String?>? nullableSet;
+ Map<String?, String?>? nullableMap;
+}
+
+@foryClass
+class RefInnerSchemaConsistent {
+ Int32 id = Int32(0);
+ String name = '';
+}
+
+@foryClass
+class RefOuterSchemaConsistent {
+ @ForyKey(ref: true)
+ RefInnerSchemaConsistent? inner1;
+
+ @ForyKey(ref: true)
+ RefInnerSchemaConsistent? inner2;
+}
+
+@foryClass
+class RefInnerCompatible {
+ Int32 id = Int32(0);
+ String name = '';
+}
+
+@foryClass
+class RefOuterCompatible {
+ @ForyKey(ref: true)
+ RefInnerCompatible? inner1;
+
+ @ForyKey(ref: true)
+ RefInnerCompatible? inner2;
+}
+
+@foryClass
+class CircularRefStruct {
+ String name = '';
+
+ @ForyKey(ref: true)
+ CircularRefStruct? selfRef;
+}
diff --git
a/dart/packages/fory-test/test/codegen_test/simple_struct_codegen_test.dart
b/dart/packages/fory-test/test/codegen_test/simple_struct_codegen_test.dart
index 9763d6b67..a9e190f40 100644
--- a/dart/packages/fory-test/test/codegen_test/simple_struct_codegen_test.dart
+++ b/dart/packages/fory-test/test/codegen_test/simple_struct_codegen_test.dart
@@ -51,14 +51,13 @@ void main() {
check(variables.equals(['\$EnumFoo', '\$EnumSubClass'])).isTrue();
});
- test('generates TypeSpec and mixin from time_obj.dart', () async {
+ test('generates TypeSpec without mixin from time_obj.dart', () async {
// await runBuild();
AssetId inputId = AssetId('fory-test', 'lib/entity/time_obj.dart');
var lib = await resolveAsset(inputId, (resolver) async {
return resolver.libraryFor(inputId);
});
List<String> variables = [];
- List<String> mixins = [];
for (var libPart in lib.children) {
for (var ele in libPart.children) {
if (ele is VariableElement) {
@@ -67,15 +66,12 @@ void main() {
// print('found EnumSpec: ${ele.name}');
variables.add(ele.name);
}
- } else if (ele is MixinElement) {
- mixins.add(ele.name);
}
}
}
check(variables.equals([
'\$TimeObj',
])).isTrue();
- check(mixins).contains('_\$TimeObjFory');
});
});
}
diff --git
a/dart/packages/fory-test/test/cross_lang_test/cross_lang_struct_serialization_test.dart
b/dart/packages/fory-test/test/cross_lang_test/cross_lang_struct_serialization_test.dart
index 24e554996..7059910ab 100644
---
a/dart/packages/fory-test/test/cross_lang_test/cross_lang_struct_serialization_test.dart
+++
b/dart/packages/fory-test/test/cross_lang_test/cross_lang_struct_serialization_test.dart
@@ -39,7 +39,7 @@ void main() {
Fory fory = Fory(
ref: true,
);
- fory.register($SimpleStruct1, typename: "SimpleStruct1");
+ fory.register(SimpleStruct1, typename: "SimpleStruct1");
SimpleStruct1 obj = SimpleStruct1();
obj.a = Int32.maxValue;
Uint8List lis = fory.serialize(obj);
@@ -51,7 +51,7 @@ void main() {
Fory fory = Fory(
ref: true,
);
- fory.register($ComplexObject2, typename: "test.ComplexObject2");
+ fory.register(ComplexObject2, typename: "test.ComplexObject2");
ComplexObject2 o = ComplexObject2(true, {Int8(-1): Int32(2)});
CrossLangUtil.structRoundBack(fory, o, "test_serialize_simple_struct");
},
@@ -62,8 +62,8 @@ void main() {
Fory fory = Fory(
ref: true,
);
- fory.register($ComplexObject2, typename: "test.ComplexObject2");
- fory.register($ComplexObject1, typename: "test.ComplexObject1");
+ fory.register(ComplexObject2, typename: "test.ComplexObject2");
+ fory.register(ComplexObject1, typename: "test.ComplexObject1");
ComplexObject2 obj2 = ComplexObject2(true, {Int8(-1): Int32(2)});
ComplexObject1 obj = ComplexObject1();
obj.f1 = obj2;
@@ -119,7 +119,7 @@ void main() {
Fory fory = Fory(
ref: true,
);
- fory.register($ComplexObject3, typename: "test.ComplexObject3");
+ fory.register(ComplexObject3, typename: "test.ComplexObject3");
ComplexObject3 obj = ComplexObject3();
Map<int, Float32> map1 = {
diff --git
a/dart/packages/fory-test/test/cross_lang_test/cross_language_type_test.dart
b/dart/packages/fory-test/test/cross_lang_test/cross_language_type_test.dart
index 1ee145c66..a4559b41b 100644
--- a/dart/packages/fory-test/test/cross_lang_test/cross_language_type_test.dart
+++ b/dart/packages/fory-test/test/cross_lang_test/cross_language_type_test.dart
@@ -105,10 +105,10 @@ void _basicTypeTest(bool ref) {
check('2023年10月23日').equals(serDe(fory1, fory2, '2023年10月23日'));
check(true).equals(CrossLangUtil.serDe(fory1, fory2, true));
- fory1.register($EnumFoo);
- fory2.register($EnumFoo);
- fory1.register($EnumSubClass);
- fory2.register($EnumSubClass);
+ fory1.register(EnumFoo);
+ fory2.register(EnumFoo);
+ fory1.register(EnumSubClass);
+ fory2.register(EnumSubClass);
check(EnumFoo.A).equals(serDe(fory1, fory2, EnumFoo.A));
check(EnumFoo.B).equals(serDe(fory1, fory2, EnumFoo.B));
diff --git
a/dart/packages/fory-test/test/cross_lang_test/register_serialization_test.dart
b/dart/packages/fory-test/test/cross_lang_test/register_serialization_test.dart
index a766aa8d8..eef6a2ed0 100644
---
a/dart/packages/fory-test/test/cross_lang_test/register_serialization_test.dart
+++
b/dart/packages/fory-test/test/cross_lang_test/register_serialization_test.dart
@@ -59,7 +59,7 @@ void main() {
Fory fory = Fory(
ref: true,
);
- fory.register($ComplexObject1, typename: "test.ComplexObject1");
+ fory.register(ComplexObject1, typename: "test.ComplexObject1");
fory.registerSerializer(ComplexObject1, const
ComplexObject1Serializer());
ComplexObject1 obj = ComplexObject1();
diff --git
a/dart/packages/fory-test/test/cross_lang_test/units/algorithm_test.dart
b/dart/packages/fory-test/test/cross_lang_test/units/algorithm_test.dart
index 19f05ce71..94a8de448 100644
--- a/dart/packages/fory-test/test/cross_lang_test/units/algorithm_test.dart
+++ b/dart/packages/fory-test/test/cross_lang_test/units/algorithm_test.dart
@@ -51,7 +51,7 @@ void main() {
Fory fory = Fory(
ref: true,
);
- fory.register($ComplexObject1, typename: "test.ComplexObject1");
+ fory.register(ComplexObject1, typename: "test.ComplexObject1");
var hashPair = fory.structHashPairForTest(ComplexObject1);
ByteData byteData = ByteData(4);
byteData.setUint32(0, hashPair.fromForyHash, Endian.little);
diff --git
a/dart/packages/fory-test/test/cross_lang_test/units/preserve_type_test.dart
b/dart/packages/fory-test/test/cross_lang_test/units/preserve_type_test.dart
index 48114eb39..9c3b1106a 100644
--- a/dart/packages/fory-test/test/cross_lang_test/units/preserve_type_test.dart
+++ b/dart/packages/fory-test/test/cross_lang_test/units/preserve_type_test.dart
@@ -180,7 +180,7 @@ void main() {
TimeStamp(-1714490301000000),
);
- fory.register($TimeObj, typename: "test.TimeObj");
+ fory.register(TimeObj, typename: "test.TimeObj");
Object? obj1 = _roundTrip(fory, timeObj);
check(obj1).isNotNull().isA<TimeObj>();
TimeObj timeObj1 = obj1 as TimeObj;
diff --git a/dart/packages/fory-test/test/cross_lang_test/xlang_test_defs.dart
b/dart/packages/fory-test/test/cross_lang_test/xlang_test_defs.dart
deleted file mode 100644
index 51bfcf9b8..000000000
--- a/dart/packages/fory-test/test/cross_lang_test/xlang_test_defs.dart
+++ /dev/null
@@ -1,1723 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you 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.
- */
-
-part of 'xlang_test_main.dart';
-
-enum TestEnum {
- VALUE_A,
- VALUE_B,
- VALUE_C,
-}
-
-const EnumSpec _testEnumSpec = EnumSpec(
- TestEnum,
- TestEnum.values,
-);
-
-class TwoEnumFieldStructEvolution {
- TestEnum f1 = TestEnum.VALUE_A;
- TestEnum f2 = TestEnum.VALUE_A;
-}
-
-final TypeSpec _twoEnumFieldStructEvolutionSpec = TypeSpec(
- TwoEnumFieldStructEvolution,
- false,
- true,
- [
- FieldSpec(
- 'f1',
- const FieldTypeSpec(
- TestEnum,
- ObjType.ENUM,
- false,
- true,
- _testEnumSpec,
- [],
- ),
- true,
- true,
- (Object inst) => (inst as TwoEnumFieldStructEvolution).f1,
- (Object inst, dynamic v) =>
- (inst as TwoEnumFieldStructEvolution).f1 = v as TestEnum,
- ),
- FieldSpec(
- 'f2',
- const FieldTypeSpec(
- TestEnum,
- ObjType.ENUM,
- false,
- true,
- _testEnumSpec,
- [],
- ),
- false,
- true,
- (Object inst) => (inst as TwoEnumFieldStructEvolution).f2,
- (Object inst, dynamic v) =>
- (inst as TwoEnumFieldStructEvolution).f2 = v as TestEnum,
- ),
- ],
- null,
- () => TwoEnumFieldStructEvolution(),
-);
-
-class RefOverrideElement {
- Int32 id = Int32(0);
- String name = '';
-}
-
-class RefOverrideContainer {
- List<RefOverrideElement> listField = <RefOverrideElement>[];
- Map<String, RefOverrideElement> mapField = <String, RefOverrideElement>{};
-}
-
-final TypeSpec _refOverrideElementSpec = TypeSpec(
- RefOverrideElement,
- false,
- true,
- [
- FieldSpec(
- 'id',
- const FieldTypeSpec(
- Int32,
- ObjType.VAR_INT32,
- false,
- true,
- null,
- [],
- ),
- true,
- true,
- (Object inst) => (inst as RefOverrideElement).id,
- (Object inst, dynamic v) => (inst as RefOverrideElement).id = v as Int32,
- ),
- FieldSpec(
- 'name',
- const FieldTypeSpec(
- String,
- ObjType.STRING,
- false,
- true,
- null,
- [],
- ),
- true,
- true,
- (Object inst) => (inst as RefOverrideElement).name,
- (Object inst, dynamic v) =>
- (inst as RefOverrideElement).name = v as String,
- ),
- ],
- null,
- () => RefOverrideElement(),
-);
-
-final TypeSpec _refOverrideContainerSpec = TypeSpec(
- RefOverrideContainer,
- false,
- true,
- [
- FieldSpec(
- 'list_field',
- const FieldTypeSpec(
- List,
- ObjType.LIST,
- false,
- false,
- null,
- [
- FieldTypeSpec(
- RefOverrideElement,
- ObjType.STRUCT,
- false,
- true,
- null,
- [],
- ),
- ],
- ),
- true,
- true,
- (Object inst) => (inst as RefOverrideContainer).listField,
- (Object inst, dynamic v) => (inst as RefOverrideContainer).listField =
- (v as List).cast<RefOverrideElement>(),
- ),
- FieldSpec(
- 'map_field',
- const FieldTypeSpec(
- Map,
- ObjType.MAP,
- false,
- false,
- null,
- [
- FieldTypeSpec(
- String,
- ObjType.STRING,
- true,
- true,
- null,
- [],
- ),
- FieldTypeSpec(
- RefOverrideElement,
- ObjType.STRUCT,
- false,
- true,
- null,
- [],
- ),
- ],
- ),
- true,
- true,
- (Object inst) => (inst as RefOverrideContainer).mapField,
- (Object inst, dynamic v) =>
- (inst as RefOverrideContainer).mapField = (v as Map).map(
- (Object? k, Object? value) => MapEntry(
- k as String,
- value as RefOverrideElement,
- ),
- ),
- ),
- ],
- null,
- () => RefOverrideContainer(),
-);
-
-class NullableComprehensiveCompatible {
- double boxedDouble = 0.0;
- double doubleField = 0.0;
- Float32 boxedFloat = Float32(0);
- Float32 floatField = Float32(0);
- Int16 shortField = Int16(0);
- Int8 byteField = Int8(0);
- bool boolField = false;
- bool boxedBool = false;
- int boxedLong = 0;
- int longField = 0;
- Int32 boxedInt = Int32(0);
- Int32 intField = Int32(0);
-
- double nullableDouble1 = 0.0;
- Float32 nullableFloat1 = Float32(0);
- bool nullableBool1 = false;
- int nullableLong1 = 0;
- Int32 nullableInt1 = Int32(0);
-
- String nullableString2 = '';
- String stringField = '';
- List<String> listField = <String>[];
- List<String> nullableList2 = <String>[];
- Set<String> nullableSet2 = <String>{};
- Set<String> setField = <String>{};
- Map<String, String> mapField = <String, String>{};
- Map<String, String> nullableMap2 = <String, String>{};
-}
-
-Map<String, String> _asStringMap(Object? value) {
- if (value == null) {
- return <String, String>{};
- }
- return (value as Map).map(
- (Object? k, Object? v) => MapEntry(k as String, v as String),
- );
-}
-
-final TypeSpec _nullableComprehensiveCompatibleSpec = TypeSpec(
- NullableComprehensiveCompatible,
- false,
- true,
- [
- FieldSpec(
- 'boxed_double',
- const FieldTypeSpec(
- double,
- ObjType.FLOAT64,
- false,
- true,
- null,
- [],
- ),
- true,
- true,
- (Object inst) => (inst as NullableComprehensiveCompatible).boxedDouble,
- (Object inst, dynamic v) =>
- (inst as NullableComprehensiveCompatible).boxedDouble = v as double,
- ),
- FieldSpec(
- 'double_field',
- const FieldTypeSpec(
- double,
- ObjType.FLOAT64,
- false,
- true,
- null,
- [],
- ),
- true,
- true,
- (Object inst) => (inst as NullableComprehensiveCompatible).doubleField,
- (Object inst, dynamic v) =>
- (inst as NullableComprehensiveCompatible).doubleField = v as double,
- ),
- FieldSpec(
- 'boxed_float',
- const FieldTypeSpec(
- Float32,
- ObjType.FLOAT32,
- false,
- true,
- null,
- [],
- ),
- true,
- true,
- (Object inst) => (inst as NullableComprehensiveCompatible).boxedFloat,
- (Object inst, dynamic v) =>
- (inst as NullableComprehensiveCompatible).boxedFloat = v as Float32,
- ),
- FieldSpec(
- 'float_field',
- const FieldTypeSpec(
- Float32,
- ObjType.FLOAT32,
- false,
- true,
- null,
- [],
- ),
- true,
- true,
- (Object inst) => (inst as NullableComprehensiveCompatible).floatField,
- (Object inst, dynamic v) =>
- (inst as NullableComprehensiveCompatible).floatField = v as Float32,
- ),
- FieldSpec(
- 'short_field',
- const FieldTypeSpec(
- Int16,
- ObjType.INT16,
- false,
- true,
- null,
- [],
- ),
- true,
- true,
- (Object inst) => (inst as NullableComprehensiveCompatible).shortField,
- (Object inst, dynamic v) =>
- (inst as NullableComprehensiveCompatible).shortField = v as Int16,
- ),
- FieldSpec(
- 'byte_field',
- const FieldTypeSpec(
- Int8,
- ObjType.INT8,
- false,
- true,
- null,
- [],
- ),
- true,
- true,
- (Object inst) => (inst as NullableComprehensiveCompatible).byteField,
- (Object inst, dynamic v) =>
- (inst as NullableComprehensiveCompatible).byteField = v as Int8,
- ),
- FieldSpec(
- 'bool_field',
- const FieldTypeSpec(
- bool,
- ObjType.BOOL,
- false,
- true,
- null,
- [],
- ),
- true,
- true,
- (Object inst) => (inst as NullableComprehensiveCompatible).boolField,
- (Object inst, dynamic v) =>
- (inst as NullableComprehensiveCompatible).boolField = v as bool,
- ),
- FieldSpec(
- 'boxed_bool',
- const FieldTypeSpec(
- bool,
- ObjType.BOOL,
- false,
- true,
- null,
- [],
- ),
- true,
- true,
- (Object inst) => (inst as NullableComprehensiveCompatible).boxedBool,
- (Object inst, dynamic v) =>
- (inst as NullableComprehensiveCompatible).boxedBool = v as bool,
- ),
- FieldSpec(
- 'boxed_long',
- const FieldTypeSpec(
- int,
- ObjType.VAR_INT64,
- false,
- true,
- null,
- [],
- ),
- true,
- true,
- (Object inst) => (inst as NullableComprehensiveCompatible).boxedLong,
- (Object inst, dynamic v) =>
- (inst as NullableComprehensiveCompatible).boxedLong = v as int,
- ),
- FieldSpec(
- 'long_field',
- const FieldTypeSpec(
- int,
- ObjType.VAR_INT64,
- false,
- true,
- null,
- [],
- ),
- true,
- true,
- (Object inst) => (inst as NullableComprehensiveCompatible).longField,
- (Object inst, dynamic v) =>
- (inst as NullableComprehensiveCompatible).longField = v as int,
- ),
- FieldSpec(
- 'boxed_int',
- const FieldTypeSpec(
- Int32,
- ObjType.VAR_INT32,
- false,
- true,
- null,
- [],
- ),
- true,
- true,
- (Object inst) => (inst as NullableComprehensiveCompatible).boxedInt,
- (Object inst, dynamic v) =>
- (inst as NullableComprehensiveCompatible).boxedInt = v as Int32,
- ),
- FieldSpec(
- 'int_field',
- const FieldTypeSpec(
- Int32,
- ObjType.VAR_INT32,
- false,
- true,
- null,
- [],
- ),
- true,
- true,
- (Object inst) => (inst as NullableComprehensiveCompatible).intField,
- (Object inst, dynamic v) =>
- (inst as NullableComprehensiveCompatible).intField = v as Int32,
- ),
- FieldSpec(
- 'nullable_double1',
- const FieldTypeSpec(
- double,
- ObjType.FLOAT64,
- true,
- true,
- null,
- [],
- ),
- true,
- true,
- (Object inst) =>
- (inst as NullableComprehensiveCompatible).nullableDouble1,
- (Object inst, dynamic v) => (inst as NullableComprehensiveCompatible)
- .nullableDouble1 = (v as double?) ?? 0.0,
- ),
- FieldSpec(
- 'nullable_float1',
- const FieldTypeSpec(
- Float32,
- ObjType.FLOAT32,
- true,
- true,
- null,
- [],
- ),
- true,
- true,
- (Object inst) => (inst as
NullableComprehensiveCompatible).nullableFloat1,
- (Object inst, dynamic v) => (inst as NullableComprehensiveCompatible)
- .nullableFloat1 = (v as Float32?) ?? Float32(0),
- ),
- FieldSpec(
- 'nullable_bool1',
- const FieldTypeSpec(
- bool,
- ObjType.BOOL,
- true,
- true,
- null,
- [],
- ),
- true,
- true,
- (Object inst) => (inst as NullableComprehensiveCompatible).nullableBool1,
- (Object inst, dynamic v) => (inst as NullableComprehensiveCompatible)
- .nullableBool1 = (v as bool?) ?? false,
- ),
- FieldSpec(
- 'nullable_long1',
- const FieldTypeSpec(
- int,
- ObjType.VAR_INT64,
- true,
- true,
- null,
- [],
- ),
- true,
- true,
- (Object inst) => (inst as NullableComprehensiveCompatible).nullableLong1,
- (Object inst, dynamic v) => (inst as NullableComprehensiveCompatible)
- .nullableLong1 = (v as int?) ?? 0,
- ),
- FieldSpec(
- 'nullable_int1',
- const FieldTypeSpec(
- Int32,
- ObjType.VAR_INT32,
- true,
- true,
- null,
- [],
- ),
- true,
- true,
- (Object inst) => (inst as NullableComprehensiveCompatible).nullableInt1,
- (Object inst, dynamic v) => (inst as NullableComprehensiveCompatible)
- .nullableInt1 = (v as Int32?) ?? Int32(0),
- ),
- FieldSpec(
- 'nullable_string2',
- const FieldTypeSpec(
- String,
- ObjType.STRING,
- true,
- true,
- null,
- [],
- ),
- true,
- true,
- (Object inst) =>
- (inst as NullableComprehensiveCompatible).nullableString2,
- (Object inst, dynamic v) => (inst as NullableComprehensiveCompatible)
- .nullableString2 = (v as String?) ?? '',
- ),
- FieldSpec(
- 'string_field',
- const FieldTypeSpec(
- String,
- ObjType.STRING,
- false,
- true,
- null,
- [],
- ),
- true,
- true,
- (Object inst) => (inst as NullableComprehensiveCompatible).stringField,
- (Object inst, dynamic v) =>
- (inst as NullableComprehensiveCompatible).stringField = v as String,
- ),
- FieldSpec(
- 'list_field',
- const FieldTypeSpec(
- List,
- ObjType.LIST,
- false,
- false,
- null,
- [
- FieldTypeSpec(
- String,
- ObjType.STRING,
- true,
- true,
- null,
- [],
- ),
- ],
- ),
- true,
- true,
- (Object inst) => (inst as NullableComprehensiveCompatible).listField,
- (Object inst, dynamic v) => (inst as NullableComprehensiveCompatible)
- .listField = (v as List).cast<String>(),
- ),
- FieldSpec(
- 'nullable_list2',
- const FieldTypeSpec(
- List,
- ObjType.LIST,
- true,
- false,
- null,
- [
- FieldTypeSpec(
- String,
- ObjType.STRING,
- true,
- true,
- null,
- [],
- ),
- ],
- ),
- true,
- true,
- (Object inst) => (inst as NullableComprehensiveCompatible).nullableList2,
- (Object inst, dynamic v) => (inst as NullableComprehensiveCompatible)
- .nullableList2 = v == null ? <String>[] : (v as List).cast<String>(),
- ),
- FieldSpec(
- 'nullable_set2',
- const FieldTypeSpec(
- Set,
- ObjType.SET,
- true,
- false,
- null,
- [
- FieldTypeSpec(
- String,
- ObjType.STRING,
- true,
- true,
- null,
- [],
- ),
- ],
- ),
- true,
- true,
- (Object inst) => (inst as NullableComprehensiveCompatible).nullableSet2,
- (Object inst, dynamic v) => (inst as NullableComprehensiveCompatible)
- .nullableSet2 = v == null ? <String>{} : (v as Set).cast<String>(),
- ),
- FieldSpec(
- 'set_field',
- const FieldTypeSpec(
- Set,
- ObjType.SET,
- false,
- false,
- null,
- [
- FieldTypeSpec(
- String,
- ObjType.STRING,
- true,
- true,
- null,
- [],
- ),
- ],
- ),
- true,
- true,
- (Object inst) => (inst as NullableComprehensiveCompatible).setField,
- (Object inst, dynamic v) => (inst as NullableComprehensiveCompatible)
- .setField = (v as Set).cast<String>(),
- ),
- FieldSpec(
- 'map_field',
- const FieldTypeSpec(
- Map,
- ObjType.MAP,
- false,
- false,
- null,
- [
- FieldTypeSpec(
- String,
- ObjType.STRING,
- true,
- true,
- null,
- [],
- ),
- FieldTypeSpec(
- String,
- ObjType.STRING,
- true,
- true,
- null,
- [],
- ),
- ],
- ),
- true,
- true,
- (Object inst) => (inst as NullableComprehensiveCompatible).mapField,
- (Object inst, dynamic v) =>
- (inst as NullableComprehensiveCompatible).mapField = _asStringMap(v),
- ),
- FieldSpec(
- 'nullable_map2',
- const FieldTypeSpec(
- Map,
- ObjType.MAP,
- true,
- false,
- null,
- [
- FieldTypeSpec(
- String,
- ObjType.STRING,
- true,
- true,
- null,
- [],
- ),
- FieldTypeSpec(
- String,
- ObjType.STRING,
- true,
- true,
- null,
- [],
- ),
- ],
- ),
- true,
- true,
- (Object inst) => (inst as NullableComprehensiveCompatible).nullableMap2,
- (Object inst, dynamic v) => (inst as NullableComprehensiveCompatible)
- .nullableMap2 = _asStringMap(v),
- ),
- ],
- null,
- () => NullableComprehensiveCompatible(),
-);
-
-enum Color {
- Green,
- Red,
- Blue,
- White,
-}
-
-const EnumSpec _colorSpec = EnumSpec(
- Color,
- Color.values,
-);
-
-class Item {
- String name = '';
-}
-
-final TypeSpec _itemSpec = TypeSpec(
- Item,
- false,
- true,
- [
- FieldSpec(
- 'name',
- const FieldTypeSpec(String, ObjType.STRING, false, true, null, []),
- true,
- true,
- (Object inst) => (inst as Item).name,
- (Object inst, dynamic v) => (inst as Item).name = v as String,
- ),
- ],
- null,
- () => Item(),
-);
-
-class SimpleStruct {
- Map<Int32, double> f1 = <Int32, double>{};
- Int32 f2 = Int32(0);
- Item f3 = Item();
- String f4 = '';
- Color f5 = Color.Green;
- List<String> f6 = <String>[];
- Int32 f7 = Int32(0);
- Int32 f8 = Int32(0);
- Int32 last = Int32(0);
-}
-
-Map<Int32, double> _asInt32DoubleMap(Object? value) {
- if (value == null) {
- return <Int32, double>{};
- }
- return (value as Map).map(
- (Object? k, Object? v) => MapEntry(k as Int32, v as double),
- );
-}
-
-final TypeSpec _simpleStructSpec = TypeSpec(
- SimpleStruct,
- false,
- true,
- [
- FieldSpec(
- 'f1',
- const FieldTypeSpec(
- Map,
- ObjType.MAP,
- false,
- false,
- null,
- [
- FieldTypeSpec(Int32, ObjType.VAR_INT32, true, true, null, []),
- FieldTypeSpec(double, ObjType.FLOAT64, true, true, null, []),
- ],
- ),
- true,
- true,
- (Object inst) => (inst as SimpleStruct).f1,
- (Object inst, dynamic v) =>
- (inst as SimpleStruct).f1 = _asInt32DoubleMap(v),
- ),
- FieldSpec(
- 'f2',
- const FieldTypeSpec(Int32, ObjType.VAR_INT32, false, true, null, []),
- true,
- true,
- (Object inst) => (inst as SimpleStruct).f2,
- (Object inst, dynamic v) => (inst as SimpleStruct).f2 = v as Int32,
- ),
- FieldSpec(
- 'f3',
- const FieldTypeSpec(Item, ObjType.STRUCT, false, false, null, []),
- true,
- true,
- (Object inst) => (inst as SimpleStruct).f3,
- (Object inst, dynamic v) => (inst as SimpleStruct).f3 = v as Item,
- ),
- FieldSpec(
- 'f4',
- const FieldTypeSpec(String, ObjType.STRING, false, true, null, []),
- true,
- true,
- (Object inst) => (inst as SimpleStruct).f4,
- (Object inst, dynamic v) => (inst as SimpleStruct).f4 = v as String,
- ),
- FieldSpec(
- 'f5',
- const FieldTypeSpec(Color, ObjType.ENUM, false, true, _colorSpec, []),
- true,
- true,
- (Object inst) => (inst as SimpleStruct).f5,
- (Object inst, dynamic v) => (inst as SimpleStruct).f5 = v as Color,
- ),
- FieldSpec(
- 'f6',
- const FieldTypeSpec(
- List,
- ObjType.LIST,
- false,
- false,
- null,
- [
- FieldTypeSpec(String, ObjType.STRING, true, true, null, []),
- ],
- ),
- true,
- true,
- (Object inst) => (inst as SimpleStruct).f6,
- (Object inst, dynamic v) =>
- (inst as SimpleStruct).f6 = (v as List).cast<String>(),
- ),
- FieldSpec(
- 'f7',
- const FieldTypeSpec(Int32, ObjType.VAR_INT32, false, true, null, []),
- true,
- true,
- (Object inst) => (inst as SimpleStruct).f7,
- (Object inst, dynamic v) => (inst as SimpleStruct).f7 = v as Int32,
- ),
- FieldSpec(
- 'f8',
- const FieldTypeSpec(Int32, ObjType.VAR_INT32, false, true, null, []),
- true,
- true,
- (Object inst) => (inst as SimpleStruct).f8,
- (Object inst, dynamic v) => (inst as SimpleStruct).f8 = v as Int32,
- ),
- FieldSpec(
- 'last',
- const FieldTypeSpec(Int32, ObjType.VAR_INT32, false, true, null, []),
- true,
- true,
- (Object inst) => (inst as SimpleStruct).last,
- (Object inst, dynamic v) => (inst as SimpleStruct).last = v as Int32,
- ),
- ],
- null,
- () => SimpleStruct(),
-);
-
-class Item1 {
- Int32 f1 = Int32(0);
- Int32 f2 = Int32(0);
- Int32 f3 = Int32(0);
- Int32 f4 = Int32(0);
- Int32 f5 = Int32(0);
- Int32 f6 = Int32(0);
-}
-
-final TypeSpec _item1Spec = TypeSpec(
- Item1,
- false,
- true,
- [
- FieldSpec(
- 'f1',
- const FieldTypeSpec(Int32, ObjType.VAR_INT32, false, true, null, []),
- true,
- true,
- (Object inst) => (inst as Item1).f1,
- (Object inst, dynamic v) => (inst as Item1).f1 = v as Int32,
- ),
- FieldSpec(
- 'f2',
- const FieldTypeSpec(Int32, ObjType.VAR_INT32, false, true, null, []),
- true,
- true,
- (Object inst) => (inst as Item1).f2,
- (Object inst, dynamic v) => (inst as Item1).f2 = v as Int32,
- ),
- FieldSpec(
- 'f3',
- const FieldTypeSpec(Int32, ObjType.VAR_INT32, false, true, null, []),
- true,
- true,
- (Object inst) => (inst as Item1).f3,
- (Object inst, dynamic v) => (inst as Item1).f3 = v as Int32,
- ),
- FieldSpec(
- 'f4',
- const FieldTypeSpec(Int32, ObjType.VAR_INT32, false, true, null, []),
- true,
- true,
- (Object inst) => (inst as Item1).f4,
- (Object inst, dynamic v) => (inst as Item1).f4 = v as Int32,
- ),
- FieldSpec(
- 'f5',
- const FieldTypeSpec(Int32, ObjType.VAR_INT32, false, true, null, []),
- true,
- true,
- (Object inst) => (inst as Item1).f5,
- (Object inst, dynamic v) => (inst as Item1).f5 = v as Int32,
- ),
- FieldSpec(
- 'f6',
- const FieldTypeSpec(Int32, ObjType.VAR_INT32, false, true, null, []),
- true,
- true,
- (Object inst) => (inst as Item1).f6,
- (Object inst, dynamic v) => (inst as Item1).f6 = v as Int32,
- ),
- ],
- null,
- () => Item1(),
-);
-
-class StructWithList {
- List<String?> items = <String?>[];
-}
-
-final TypeSpec _structWithListSpec = TypeSpec(
- StructWithList,
- false,
- true,
- [
- FieldSpec(
- 'items',
- const FieldTypeSpec(
- List,
- ObjType.LIST,
- false,
- false,
- null,
- [FieldTypeSpec(String, ObjType.STRING, true, true, null, [])],
- ),
- true,
- true,
- (Object inst) => (inst as StructWithList).items,
- (Object inst, dynamic v) =>
- (inst as StructWithList).items = (v as List).cast<String?>(),
- ),
- ],
- null,
- () => StructWithList(),
-);
-
-class StructWithMap {
- Map<String?, String?> data = <String?, String?>{};
-}
-
-Map<String?, String?> _asNullableStringMap(Object? value) {
- if (value == null) {
- return <String?, String?>{};
- }
- return (value as Map).map(
- (Object? k, Object? v) => MapEntry(k as String?, v as String?),
- );
-}
-
-final TypeSpec _structWithMapSpec = TypeSpec(
- StructWithMap,
- false,
- true,
- [
- FieldSpec(
- 'data',
- const FieldTypeSpec(
- Map,
- ObjType.MAP,
- false,
- false,
- null,
- [
- FieldTypeSpec(String, ObjType.STRING, true, true, null, []),
- FieldTypeSpec(String, ObjType.STRING, true, true, null, []),
- ],
- ),
- true,
- true,
- (Object inst) => (inst as StructWithMap).data,
- (Object inst, dynamic v) =>
- (inst as StructWithMap).data = _asNullableStringMap(v),
- ),
- ],
- null,
- () => StructWithMap(),
-);
-
-class VersionCheckStruct {
- Int32 f1 = Int32(0);
- String f2 = '';
- double f3 = 0.0;
-}
-
-final TypeSpec _versionCheckStructSpec = TypeSpec(
- VersionCheckStruct,
- false,
- true,
- [
- FieldSpec(
- 'f1',
- const FieldTypeSpec(Int32, ObjType.VAR_INT32, false, true, null, []),
- true,
- true,
- (Object inst) => (inst as VersionCheckStruct).f1,
- (Object inst, dynamic v) => (inst as VersionCheckStruct).f1 = v as Int32,
- ),
- FieldSpec(
- 'f2',
- const FieldTypeSpec(String, ObjType.STRING, true, true, null, []),
- true,
- true,
- (Object inst) => (inst as VersionCheckStruct).f2,
- (Object inst, dynamic v) =>
- (inst as VersionCheckStruct).f2 = (v as String?) ?? '',
- ),
- FieldSpec(
- 'f3',
- const FieldTypeSpec(double, ObjType.FLOAT64, false, true, null, []),
- true,
- true,
- (Object inst) => (inst as VersionCheckStruct).f3,
- (Object inst, dynamic v) => (inst as VersionCheckStruct).f3 = v as
double,
- ),
- ],
- null,
- () => VersionCheckStruct(),
-);
-
-class OneStringFieldStruct {
- String f1 = '';
-}
-
-final TypeSpec _oneStringFieldStructSpec = TypeSpec(
- OneStringFieldStruct,
- false,
- true,
- [
- FieldSpec(
- 'f1',
- const FieldTypeSpec(String, ObjType.STRING, true, true, null, []),
- true,
- true,
- (Object inst) => (inst as OneStringFieldStruct).f1,
- (Object inst, dynamic v) =>
- (inst as OneStringFieldStruct).f1 = (v as String?) ?? '',
- ),
- ],
- null,
- () => OneStringFieldStruct(),
-);
-
-class TwoStringFieldStruct {
- String f1 = '';
- String f2 = '';
-}
-
-final TypeSpec _twoStringFieldStructSpec = TypeSpec(
- TwoStringFieldStruct,
- false,
- true,
- [
- FieldSpec(
- 'f1',
- const FieldTypeSpec(String, ObjType.STRING, false, true, null, []),
- true,
- true,
- (Object inst) => (inst as TwoStringFieldStruct).f1,
- (Object inst, dynamic v) =>
- (inst as TwoStringFieldStruct).f1 = v as String,
- ),
- FieldSpec(
- 'f2',
- const FieldTypeSpec(String, ObjType.STRING, false, true, null, []),
- true,
- true,
- (Object inst) => (inst as TwoStringFieldStruct).f2,
- (Object inst, dynamic v) =>
- (inst as TwoStringFieldStruct).f2 = v as String,
- ),
- ],
- null,
- () => TwoStringFieldStruct(),
-);
-
-class OneEnumFieldStruct {
- TestEnum f1 = TestEnum.VALUE_A;
-}
-
-final TypeSpec _oneEnumFieldStructSpec = TypeSpec(
- OneEnumFieldStruct,
- false,
- true,
- [
- FieldSpec(
- 'f1',
- const FieldTypeSpec(
- TestEnum, ObjType.ENUM, false, true, _testEnumSpec, []),
- true,
- true,
- (Object inst) => (inst as OneEnumFieldStruct).f1,
- (Object inst, dynamic v) =>
- (inst as OneEnumFieldStruct).f1 = v as TestEnum,
- ),
- ],
- null,
- () => OneEnumFieldStruct(),
-);
-
-class TwoEnumFieldStruct {
- TestEnum f1 = TestEnum.VALUE_A;
- TestEnum f2 = TestEnum.VALUE_A;
-}
-
-final TypeSpec _twoEnumFieldStructSpec = TypeSpec(
- TwoEnumFieldStruct,
- false,
- true,
- [
- FieldSpec(
- 'f1',
- const FieldTypeSpec(
- TestEnum, ObjType.ENUM, false, true, _testEnumSpec, []),
- true,
- true,
- (Object inst) => (inst as TwoEnumFieldStruct).f1,
- (Object inst, dynamic v) =>
- (inst as TwoEnumFieldStruct).f1 = v as TestEnum,
- ),
- FieldSpec(
- 'f2',
- const FieldTypeSpec(
- TestEnum, ObjType.ENUM, false, true, _testEnumSpec, []),
- true,
- true,
- (Object inst) => (inst as TwoEnumFieldStruct).f2,
- (Object inst, dynamic v) =>
- (inst as TwoEnumFieldStruct).f2 = v as TestEnum,
- ),
- ],
- null,
- () => TwoEnumFieldStruct(),
-);
-
-class NullableComprehensiveSchemaConsistent {
- Int8 byteField = Int8(0);
- Int16 shortField = Int16(0);
- Int32 intField = Int32(0);
- int longField = 0;
- Float32 floatField = Float32(0);
- double doubleField = 0.0;
- bool boolField = false;
- String stringField = '';
- List<String> listField = <String>[];
- Set<String> setField = <String>{};
- Map<String, String> mapField = <String, String>{};
- Int32? nullableInt;
- int? nullableLong;
- Float32? nullableFloat;
- double? nullableDouble;
- bool? nullableBool;
- String? nullableString;
- List<String>? nullableList;
- Set<String>? nullableSet;
- Map<String, String>? nullableMap;
-}
-
-final TypeSpec _nullableComprehensiveSchemaConsistentSpec = TypeSpec(
- NullableComprehensiveSchemaConsistent,
- false,
- true,
- [
- FieldSpec(
- 'byte_field',
- const FieldTypeSpec(Int8, ObjType.INT8, false, true, null, []),
- true,
- true,
- (Object inst) =>
- (inst as NullableComprehensiveSchemaConsistent).byteField,
- (Object inst, dynamic v) =>
- (inst as NullableComprehensiveSchemaConsistent).byteField = v as
Int8,
- ),
- FieldSpec(
- 'short_field',
- const FieldTypeSpec(Int16, ObjType.INT16, false, true, null, []),
- true,
- true,
- (Object inst) =>
- (inst as NullableComprehensiveSchemaConsistent).shortField,
- (Object inst, dynamic v) =>
- (inst as NullableComprehensiveSchemaConsistent).shortField =
- v as Int16,
- ),
- FieldSpec(
- 'int_field',
- const FieldTypeSpec(Int32, ObjType.VAR_INT32, false, true, null, []),
- true,
- true,
- (Object inst) => (inst as
NullableComprehensiveSchemaConsistent).intField,
- (Object inst, dynamic v) =>
- (inst as NullableComprehensiveSchemaConsistent).intField = v as
Int32,
- ),
- FieldSpec(
- 'long_field',
- const FieldTypeSpec(int, ObjType.VAR_INT64, false, true, null, []),
- true,
- true,
- (Object inst) =>
- (inst as NullableComprehensiveSchemaConsistent).longField,
- (Object inst, dynamic v) =>
- (inst as NullableComprehensiveSchemaConsistent).longField = v as int,
- ),
- FieldSpec(
- 'float_field',
- const FieldTypeSpec(Float32, ObjType.FLOAT32, false, true, null, []),
- true,
- true,
- (Object inst) =>
- (inst as NullableComprehensiveSchemaConsistent).floatField,
- (Object inst, dynamic v) =>
- (inst as NullableComprehensiveSchemaConsistent).floatField =
- v as Float32,
- ),
- FieldSpec(
- 'double_field',
- const FieldTypeSpec(double, ObjType.FLOAT64, false, true, null, []),
- true,
- true,
- (Object inst) =>
- (inst as NullableComprehensiveSchemaConsistent).doubleField,
- (Object inst, dynamic v) =>
- (inst as NullableComprehensiveSchemaConsistent).doubleField =
- v as double,
- ),
- FieldSpec(
- 'bool_field',
- const FieldTypeSpec(bool, ObjType.BOOL, false, true, null, []),
- true,
- true,
- (Object inst) =>
- (inst as NullableComprehensiveSchemaConsistent).boolField,
- (Object inst, dynamic v) =>
- (inst as NullableComprehensiveSchemaConsistent).boolField = v as
bool,
- ),
- FieldSpec(
- 'string_field',
- const FieldTypeSpec(String, ObjType.STRING, false, true, null, []),
- true,
- true,
- (Object inst) =>
- (inst as NullableComprehensiveSchemaConsistent).stringField,
- (Object inst, dynamic v) =>
- (inst as NullableComprehensiveSchemaConsistent).stringField =
- v as String,
- ),
- FieldSpec(
- 'list_field',
- const FieldTypeSpec(
- List,
- ObjType.LIST,
- false,
- false,
- null,
- [FieldTypeSpec(String, ObjType.STRING, true, true, null, [])],
- ),
- true,
- true,
- (Object inst) =>
- (inst as NullableComprehensiveSchemaConsistent).listField,
- (Object inst, dynamic v) =>
- (inst as NullableComprehensiveSchemaConsistent).listField =
- (v as List).cast<String>(),
- ),
- FieldSpec(
- 'set_field',
- const FieldTypeSpec(
- Set,
- ObjType.SET,
- false,
- false,
- null,
- [FieldTypeSpec(String, ObjType.STRING, true, true, null, [])],
- ),
- true,
- true,
- (Object inst) => (inst as
NullableComprehensiveSchemaConsistent).setField,
- (Object inst, dynamic v) =>
- (inst as NullableComprehensiveSchemaConsistent).setField =
- (v as Set).cast<String>(),
- ),
- FieldSpec(
- 'map_field',
- const FieldTypeSpec(
- Map,
- ObjType.MAP,
- false,
- false,
- null,
- [
- FieldTypeSpec(String, ObjType.STRING, true, true, null, []),
- FieldTypeSpec(String, ObjType.STRING, true, true, null, []),
- ],
- ),
- true,
- true,
- (Object inst) => (inst as
NullableComprehensiveSchemaConsistent).mapField,
- (Object inst, dynamic v) =>
- (inst as NullableComprehensiveSchemaConsistent).mapField =
- _asStringMap(v),
- ),
- FieldSpec(
- 'nullable_int',
- const FieldTypeSpec(Int32, ObjType.VAR_INT32, true, true, null, []),
- true,
- true,
- (Object inst) =>
- (inst as NullableComprehensiveSchemaConsistent).nullableInt,
- (Object inst, dynamic v) =>
- (inst as NullableComprehensiveSchemaConsistent).nullableInt =
- v as Int32?,
- ),
- FieldSpec(
- 'nullable_long',
- const FieldTypeSpec(int, ObjType.VAR_INT64, true, true, null, []),
- true,
- true,
- (Object inst) =>
- (inst as NullableComprehensiveSchemaConsistent).nullableLong,
- (Object inst, dynamic v) =>
- (inst as NullableComprehensiveSchemaConsistent).nullableLong =
- v as int?,
- ),
- FieldSpec(
- 'nullable_float',
- const FieldTypeSpec(Float32, ObjType.FLOAT32, true, true, null, []),
- true,
- true,
- (Object inst) =>
- (inst as NullableComprehensiveSchemaConsistent).nullableFloat,
- (Object inst, dynamic v) =>
- (inst as NullableComprehensiveSchemaConsistent).nullableFloat =
- v as Float32?,
- ),
- FieldSpec(
- 'nullable_double',
- const FieldTypeSpec(double, ObjType.FLOAT64, true, true, null, []),
- true,
- true,
- (Object inst) =>
- (inst as NullableComprehensiveSchemaConsistent).nullableDouble,
- (Object inst, dynamic v) =>
- (inst as NullableComprehensiveSchemaConsistent).nullableDouble =
- v as double?,
- ),
- FieldSpec(
- 'nullable_bool',
- const FieldTypeSpec(bool, ObjType.BOOL, true, true, null, []),
- true,
- true,
- (Object inst) =>
- (inst as NullableComprehensiveSchemaConsistent).nullableBool,
- (Object inst, dynamic v) =>
- (inst as NullableComprehensiveSchemaConsistent).nullableBool =
- v as bool?,
- ),
- FieldSpec(
- 'nullable_string',
- const FieldTypeSpec(String, ObjType.STRING, true, true, null, []),
- true,
- true,
- (Object inst) =>
- (inst as NullableComprehensiveSchemaConsistent).nullableString,
- (Object inst, dynamic v) =>
- (inst as NullableComprehensiveSchemaConsistent).nullableString =
- v as String?,
- ),
- FieldSpec(
- 'nullable_list',
- const FieldTypeSpec(
- List,
- ObjType.LIST,
- true,
- false,
- null,
- [FieldTypeSpec(String, ObjType.STRING, true, true, null, [])],
- ),
- true,
- true,
- (Object inst) =>
- (inst as NullableComprehensiveSchemaConsistent).nullableList,
- (Object inst, dynamic v) =>
- (inst as NullableComprehensiveSchemaConsistent).nullableList =
- v == null ? null : (v as List).cast<String>(),
- ),
- FieldSpec(
- 'nullable_set',
- const FieldTypeSpec(
- Set,
- ObjType.SET,
- true,
- false,
- null,
- [FieldTypeSpec(String, ObjType.STRING, true, true, null, [])],
- ),
- true,
- true,
- (Object inst) =>
- (inst as NullableComprehensiveSchemaConsistent).nullableSet,
- (Object inst, dynamic v) =>
- (inst as NullableComprehensiveSchemaConsistent).nullableSet =
- v == null ? null : (v as Set).cast<String>(),
- ),
- FieldSpec(
- 'nullable_map',
- const FieldTypeSpec(
- Map,
- ObjType.MAP,
- true,
- false,
- null,
- [
- FieldTypeSpec(String, ObjType.STRING, true, true, null, []),
- FieldTypeSpec(String, ObjType.STRING, true, true, null, []),
- ],
- ),
- true,
- true,
- (Object inst) =>
- (inst as NullableComprehensiveSchemaConsistent).nullableMap,
- (Object inst, dynamic v) =>
- (inst as NullableComprehensiveSchemaConsistent).nullableMap =
- v == null ? null : _asStringMap(v),
- ),
- ],
- null,
- () => NullableComprehensiveSchemaConsistent(),
-);
-
-class RefInnerSchemaConsistent {
- Int32 id = Int32(0);
- String name = '';
-}
-
-class RefOuterSchemaConsistent {
- RefInnerSchemaConsistent? inner1;
- RefInnerSchemaConsistent? inner2;
-}
-
-final TypeSpec _refInnerSchemaConsistentSpec = TypeSpec(
- RefInnerSchemaConsistent,
- false,
- true,
- [
- FieldSpec(
- 'id',
- const FieldTypeSpec(Int32, ObjType.VAR_INT32, false, true, null, []),
- true,
- true,
- (Object inst) => (inst as RefInnerSchemaConsistent).id,
- (Object inst, dynamic v) =>
- (inst as RefInnerSchemaConsistent).id = v as Int32,
- ),
- FieldSpec(
- 'name',
- const FieldTypeSpec(String, ObjType.STRING, false, true, null, []),
- true,
- true,
- (Object inst) => (inst as RefInnerSchemaConsistent).name,
- (Object inst, dynamic v) =>
- (inst as RefInnerSchemaConsistent).name = v as String,
- ),
- ],
- null,
- () => RefInnerSchemaConsistent(),
-);
-
-final TypeSpec _refOuterSchemaConsistentSpec = TypeSpec(
- RefOuterSchemaConsistent,
- false,
- true,
- [
- FieldSpec(
- 'inner1',
- const FieldTypeSpec(
- RefInnerSchemaConsistent,
- ObjType.STRUCT,
- true,
- true,
- null,
- [],
- ),
- true,
- true,
- (Object inst) => (inst as RefOuterSchemaConsistent).inner1,
- (Object inst, dynamic v) => (inst as RefOuterSchemaConsistent).inner1 =
- v as RefInnerSchemaConsistent?,
- trackingRef: true,
- ),
- FieldSpec(
- 'inner2',
- const FieldTypeSpec(
- RefInnerSchemaConsistent,
- ObjType.STRUCT,
- true,
- true,
- null,
- [],
- ),
- true,
- true,
- (Object inst) => (inst as RefOuterSchemaConsistent).inner2,
- (Object inst, dynamic v) => (inst as RefOuterSchemaConsistent).inner2 =
- v as RefInnerSchemaConsistent?,
- trackingRef: true,
- ),
- ],
- null,
- () => RefOuterSchemaConsistent(),
-);
-
-class RefInnerCompatible {
- Int32 id = Int32(0);
- String name = '';
-}
-
-class RefOuterCompatible {
- RefInnerCompatible? inner1;
- RefInnerCompatible? inner2;
-}
-
-final TypeSpec _refInnerCompatibleSpec = TypeSpec(
- RefInnerCompatible,
- false,
- true,
- [
- FieldSpec(
- 'id',
- const FieldTypeSpec(Int32, ObjType.VAR_INT32, false, true, null, []),
- true,
- true,
- (Object inst) => (inst as RefInnerCompatible).id,
- (Object inst, dynamic v) => (inst as RefInnerCompatible).id = v as Int32,
- ),
- FieldSpec(
- 'name',
- const FieldTypeSpec(String, ObjType.STRING, false, true, null, []),
- true,
- true,
- (Object inst) => (inst as RefInnerCompatible).name,
- (Object inst, dynamic v) =>
- (inst as RefInnerCompatible).name = v as String,
- ),
- ],
- null,
- () => RefInnerCompatible(),
-);
-
-final TypeSpec _refOuterCompatibleSpec = TypeSpec(
- RefOuterCompatible,
- false,
- true,
- [
- FieldSpec(
- 'inner1',
- const FieldTypeSpec(
- RefInnerCompatible, ObjType.STRUCT, true, false, null, []),
- true,
- true,
- (Object inst) => (inst as RefOuterCompatible).inner1,
- (Object inst, dynamic v) =>
- (inst as RefOuterCompatible).inner1 = v as RefInnerCompatible?,
- trackingRef: true,
- ),
- FieldSpec(
- 'inner2',
- const FieldTypeSpec(
- RefInnerCompatible, ObjType.STRUCT, true, false, null, []),
- true,
- true,
- (Object inst) => (inst as RefOuterCompatible).inner2,
- (Object inst, dynamic v) =>
- (inst as RefOuterCompatible).inner2 = v as RefInnerCompatible?,
- trackingRef: true,
- ),
- ],
- null,
- () => RefOuterCompatible(),
-);
-
-class CircularRefStruct {
- String name = '';
- CircularRefStruct? selfRef;
-}
-
-final TypeSpec _circularRefStructSpec = TypeSpec(
- CircularRefStruct,
- false,
- false,
- [
- FieldSpec(
- 'name',
- const FieldTypeSpec(String, ObjType.STRING, false, true, null, []),
- true,
- true,
- (Object inst) => (inst as CircularRefStruct).name,
- (Object inst, dynamic v) =>
- (inst as CircularRefStruct).name = v as String,
- ),
- FieldSpec(
- 'self_ref',
- const FieldTypeSpec(
- CircularRefStruct, ObjType.STRUCT, true, true, null, []),
- true,
- true,
- (Object inst) => (inst as CircularRefStruct).selfRef,
- (Object inst, dynamic v) =>
- (inst as CircularRefStruct).selfRef = v as CircularRefStruct?,
- trackingRef: true,
- ),
- ],
- null,
- () => CircularRefStruct(),
-);
-
-final Map<Type, TypeSpec> _structSpecByType = <Type, TypeSpec>{
- TwoEnumFieldStructEvolution: _twoEnumFieldStructEvolutionSpec,
- RefOverrideElement: _refOverrideElementSpec,
- RefOverrideContainer: _refOverrideContainerSpec,
- NullableComprehensiveCompatible: _nullableComprehensiveCompatibleSpec,
- Item: _itemSpec,
- SimpleStruct: _simpleStructSpec,
- Item1: _item1Spec,
- StructWithList: _structWithListSpec,
- StructWithMap: _structWithMapSpec,
- VersionCheckStruct: _versionCheckStructSpec,
- OneStringFieldStruct: _oneStringFieldStructSpec,
- TwoStringFieldStruct: _twoStringFieldStructSpec,
- OneEnumFieldStruct: _oneEnumFieldStructSpec,
- TwoEnumFieldStruct: _twoEnumFieldStructSpec,
- NullableComprehensiveSchemaConsistent:
- _nullableComprehensiveSchemaConsistentSpec,
- RefInnerSchemaConsistent: _refInnerSchemaConsistentSpec,
- RefOuterSchemaConsistent: _refOuterSchemaConsistentSpec,
- RefInnerCompatible: _refInnerCompatibleSpec,
- RefOuterCompatible: _refOuterCompatibleSpec,
- CircularRefStruct: _circularRefStructSpec,
-};
-
-final Map<Type, EnumSpec> _enumSpecByType = <Type, EnumSpec>{
- TestEnum: _testEnumSpec,
- Color: _colorSpec,
-};
-
-void _registerStructType(
- Fory fory,
- Type type, {
- int? typeId,
- String? namespace,
- String? typename,
-}) {
- final TypeSpec? spec = _structSpecByType[type];
- if (spec == null) {
- throw StateError('No struct spec registered for $type');
- }
- fory.registerStruct(
- spec,
- typeId: typeId,
- namespace: namespace,
- typename: typename,
- );
-}
-
-void _registerEnumType(
- Fory fory,
- Type type, {
- int? typeId,
- String? namespace,
- String? typename,
-}) {
- final EnumSpec? spec = _enumSpecByType[type];
- if (spec == null) {
- throw StateError('No enum spec registered for $type');
- }
- fory.registerEnum(
- spec,
- typeId: typeId,
- namespace: namespace,
- typename: typename,
- );
-}
diff --git a/dart/packages/fory-test/test/cross_lang_test/xlang_test_main.dart
b/dart/packages/fory-test/test/cross_lang_test/xlang_test_main.dart
index 7d59be0c3..67733af6a 100644
--- a/dart/packages/fory-test/test/cross_lang_test/xlang_test_main.dart
+++ b/dart/packages/fory-test/test/cross_lang_test/xlang_test_main.dart
@@ -20,8 +20,7 @@
import 'dart:io';
import 'dart:typed_data';
import 'package:fory/fory.dart';
-
-part 'xlang_test_defs.dart';
+import 'package:fory_test/entity/xlang_test_models.dart';
String _getDataFile() {
final String? dataFile = Platform.environment['DATA_FILE'];
@@ -61,8 +60,8 @@ void _runEnumSchemaEvolutionCompatibleReverse() {
final String dataFile = _getDataFile();
final Uint8List data = _readFile(dataFile);
final Fory fory = Fory(compatible: true);
- _registerEnumType(fory, TestEnum, typeId: 210);
- _registerStructType(fory, TwoEnumFieldStructEvolution, typeId: 211);
+ registerXlangEnum(fory, TestEnum, typeId: 210);
+ registerXlangStruct(fory, TwoEnumFieldStructEvolution, typeId: 211);
final TwoEnumFieldStructEvolution obj =
fory.deserialize(data) as TwoEnumFieldStructEvolution;
if (obj.f1 != TestEnum.VALUE_C) {
@@ -75,9 +74,10 @@ void _runNullableFieldCompatibleNull() {
final String dataFile = _getDataFile();
final Uint8List data = _readFile(dataFile);
final Fory fory = Fory(compatible: true);
- _registerStructType(fory, NullableComprehensiveCompatible, typeId: 402);
+ registerXlangStruct(fory, NullableComprehensiveCompatible, typeId: 402);
final NullableComprehensiveCompatible obj =
fory.deserialize(data) as NullableComprehensiveCompatible;
+ obj.normalizeForCompatibleRoundTrip();
_writeFile(dataFile, fory.serialize(obj));
}
@@ -85,8 +85,8 @@ void _runCollectionElementRefOverride() {
final String dataFile = _getDataFile();
final Uint8List data = _readFile(dataFile);
final Fory fory = Fory(ref: true);
- _registerStructType(fory, RefOverrideElement, typeId: 701);
- _registerStructType(fory, RefOverrideContainer, typeId: 702);
+ registerXlangStruct(fory, RefOverrideElement, typeId: 701);
+ registerXlangStruct(fory, RefOverrideContainer, typeId: 702);
final RefOverrideContainer obj =
fory.deserialize(data) as RefOverrideContainer;
@@ -104,15 +104,15 @@ void _runCollectionElementRefOverride() {
}
void _registerSimpleById(Fory fory) {
- _registerEnumType(fory, Color, typeId: 101);
- _registerStructType(fory, Item, typeId: 102);
- _registerStructType(fory, SimpleStruct, typeId: 103);
+ registerXlangEnum(fory, Color, typeId: 101);
+ registerXlangStruct(fory, Item, typeId: 102);
+ registerXlangStruct(fory, SimpleStruct, typeId: 103);
}
void _registerSimpleByName(Fory fory) {
- _registerEnumType(fory, Color, namespace: 'demo', typename: 'color');
- _registerStructType(fory, Item, namespace: 'demo', typename: 'item');
- _registerStructType(fory, SimpleStruct,
+ registerXlangEnum(fory, Color, namespace: 'demo', typename: 'color');
+ registerXlangStruct(fory, Item, namespace: 'demo', typename: 'item');
+ registerXlangStruct(fory, SimpleStruct,
namespace: 'demo', typename: 'simple_struct');
}
@@ -138,7 +138,7 @@ void _runRoundTripCase(String caseName) {
return;
case 'test_cross_language_serializer':
final Fory fory = Fory(compatible: true);
- _registerEnumType(fory, Color, typeId: 101);
+ registerXlangEnum(fory, Color, typeId: 101);
_roundTripFory(fory);
return;
case 'test_simple_struct':
@@ -155,88 +155,88 @@ void _runRoundTripCase(String caseName) {
case 'test_map':
case 'test_item':
final Fory fory = Fory(compatible: true);
- _registerStructType(fory, Item, typeId: 102);
+ registerXlangStruct(fory, Item, typeId: 102);
_roundTripFory(fory);
return;
case 'test_integer':
final Fory fory = Fory(compatible: true);
- _registerStructType(fory, Item1, typeId: 101);
+ registerXlangStruct(fory, Item1, typeId: 101);
_roundTripFory(fory);
return;
case 'test_color':
final Fory fory = Fory(compatible: true);
- _registerEnumType(fory, Color, typeId: 101);
+ registerXlangEnum(fory, Color, typeId: 101);
_roundTripFory(fory);
return;
case 'test_struct_with_list':
final Fory fory = Fory(compatible: true);
- _registerStructType(fory, StructWithList, typeId: 201);
+ registerXlangStruct(fory, StructWithList, typeId: 201);
_roundTripFory(fory);
return;
case 'test_struct_with_map':
final Fory fory = Fory(compatible: true);
- _registerStructType(fory, StructWithMap, typeId: 202);
+ registerXlangStruct(fory, StructWithMap, typeId: 202);
_roundTripFory(fory);
return;
case 'test_struct_version_check':
final Fory fory = Fory();
- _registerStructType(fory, VersionCheckStruct, typeId: 201);
+ registerXlangStruct(fory, VersionCheckStruct, typeId: 201);
_roundTripFory(fory);
return;
case 'test_one_string_field_schema':
final Fory fory = Fory();
- _registerStructType(fory, OneStringFieldStruct, typeId: 200);
+ registerXlangStruct(fory, OneStringFieldStruct, typeId: 200);
_roundTripFory(fory);
return;
case 'test_one_string_field_compatible':
final Fory fory = Fory(compatible: true);
- _registerStructType(fory, OneStringFieldStruct, typeId: 200);
+ registerXlangStruct(fory, OneStringFieldStruct, typeId: 200);
_roundTripFory(fory);
return;
case 'test_two_string_field_compatible':
final Fory fory = Fory(compatible: true);
- _registerStructType(fory, TwoStringFieldStruct, typeId: 201);
+ registerXlangStruct(fory, TwoStringFieldStruct, typeId: 201);
_roundTripFory(fory);
return;
case 'test_schema_evolution_compatible':
final Fory fory = Fory(compatible: true);
- _registerStructType(fory, TwoStringFieldStruct, typeId: 200);
+ registerXlangStruct(fory, TwoStringFieldStruct, typeId: 200);
_roundTripFory(fory);
return;
case 'test_one_enum_field_schema':
final Fory fory = Fory();
- _registerEnumType(fory, TestEnum, typeId: 210);
- _registerStructType(fory, OneEnumFieldStruct, typeId: 211);
+ registerXlangEnum(fory, TestEnum, typeId: 210);
+ registerXlangStruct(fory, OneEnumFieldStruct, typeId: 211);
_roundTripFory(fory);
return;
case 'test_one_enum_field_compatible':
final Fory fory = Fory(compatible: true);
- _registerEnumType(fory, TestEnum, typeId: 210);
- _registerStructType(fory, OneEnumFieldStruct, typeId: 211);
+ registerXlangEnum(fory, TestEnum, typeId: 210);
+ registerXlangStruct(fory, OneEnumFieldStruct, typeId: 211);
_roundTripFory(fory);
return;
case 'test_two_enum_field_compatible':
final Fory fory = Fory(compatible: true);
- _registerEnumType(fory, TestEnum, typeId: 210);
- _registerStructType(fory, TwoEnumFieldStruct, typeId: 212);
+ registerXlangEnum(fory, TestEnum, typeId: 210);
+ registerXlangStruct(fory, TwoEnumFieldStruct, typeId: 212);
_roundTripFory(fory);
return;
case 'test_enum_schema_evolution_compatible':
final Fory fory = Fory(compatible: true);
- _registerEnumType(fory, TestEnum, typeId: 210);
- _registerStructType(fory, TwoEnumFieldStruct, typeId: 211);
+ registerXlangEnum(fory, TestEnum, typeId: 210);
+ registerXlangStruct(fory, TwoEnumFieldStruct, typeId: 211);
_roundTripFory(fory);
return;
case 'test_nullable_field_schema_consistent_not_null':
case 'test_nullable_field_schema_consistent_null':
final Fory fory = Fory();
- _registerStructType(fory, NullableComprehensiveSchemaConsistent,
+ registerXlangStruct(fory, NullableComprehensiveSchemaConsistent,
typeId: 401);
_roundTripFory(fory);
return;
case 'test_nullable_field_compatible_not_null':
final Fory fory = Fory(compatible: true);
- _registerStructType(fory, NullableComprehensiveCompatible, typeId: 402);
+ registerXlangStruct(fory, NullableComprehensiveCompatible, typeId: 402);
_roundTripFory(fory);
return;
case 'test_nullable_field_compatible_null':
@@ -244,14 +244,14 @@ void _runRoundTripCase(String caseName) {
return;
case 'test_ref_schema_consistent':
final Fory fory = Fory(ref: true);
- _registerStructType(fory, RefInnerSchemaConsistent, typeId: 501);
- _registerStructType(fory, RefOuterSchemaConsistent, typeId: 502);
+ registerXlangStruct(fory, RefInnerSchemaConsistent, typeId: 501);
+ registerXlangStruct(fory, RefOuterSchemaConsistent, typeId: 502);
_roundTripFory(fory);
return;
case 'test_ref_compatible':
final Fory fory = Fory(compatible: true, ref: true);
- _registerStructType(fory, RefInnerCompatible, typeId: 503);
- _registerStructType(fory, RefOuterCompatible, typeId: 504);
+ registerXlangStruct(fory, RefInnerCompatible, typeId: 503);
+ registerXlangStruct(fory, RefOuterCompatible, typeId: 504);
_roundTripFory(fory);
return;
case 'test_collection_element_ref_override':
@@ -259,12 +259,12 @@ void _runRoundTripCase(String caseName) {
return;
case 'test_circular_ref_schema_consistent':
final Fory fory = Fory(ref: true);
- _registerStructType(fory, CircularRefStruct, typeId: 601);
+ registerXlangStruct(fory, CircularRefStruct, typeId: 601);
_roundTripFory(fory);
return;
case 'test_circular_ref_compatible':
final Fory fory = Fory(compatible: true, ref: true);
- _registerStructType(fory, CircularRefStruct, typeId: 602);
+ registerXlangStruct(fory, CircularRefStruct, typeId: 602);
_roundTripFory(fory);
return;
case 'test_enum_schema_evolution_compatible_reverse':
diff --git a/dart/packages/fory-test/test/perf_test/serial_perf_test.dart
b/dart/packages/fory-test/test/perf_test/serial_perf_test.dart
index 1e61648dd..aa4f10a28 100644
--- a/dart/packages/fory-test/test/perf_test/serial_perf_test.dart
+++ b/dart/packages/fory-test/test/perf_test/serial_perf_test.dart
@@ -63,7 +63,7 @@ void main() {
Fory fory = Fory(
ref: true,
);
- fory.register($ComplexObject2, typename: "test.ComplexObject2");
+ fory.register(ComplexObject2, typename: "test.ComplexObject2");
ComplexObject2 o = ComplexObject2(true, {Int8(-1): Int32(2)});
_testPerfSerialize(fory, o, 1000000, 'Serialize simple struct');
});
@@ -72,7 +72,7 @@ void main() {
Fory fory = Fory(
ref: true,
);
- fory.register($ComplexObject2, typename: "test.ComplexObject2");
+ fory.register(ComplexObject2, typename: "test.ComplexObject2");
ComplexObject2 o = ComplexObject2(true, {Int8(-1): Int32(2)});
_testPerfDeserialize(fory, o, 1000000, 'Deserialize simple struct');
});
@@ -81,8 +81,8 @@ void main() {
Fory fory = Fory(
ref: true,
);
- fory.register($ComplexObject2, typename: "test.ComplexObject2");
- fory.register($ComplexObject1, typename: "test.ComplexObject1");
+ fory.register(ComplexObject2, typename: "test.ComplexObject2");
+ fory.register(ComplexObject1, typename: "test.ComplexObject1");
ComplexObject2 obj2 = ComplexObject2(true, {Int8(-1): Int32(2)});
ComplexObject1 obj = ComplexObject1();
obj.f1 = obj2;
@@ -104,8 +104,8 @@ void main() {
Fory fory = Fory(
ref: true,
);
- fory.register($ComplexObject2, typename: "test.ComplexObject2");
- fory.register($ComplexObject1, typename: "test.ComplexObject1");
+ fory.register(ComplexObject2, typename: "test.ComplexObject2");
+ fory.register(ComplexObject1, typename: "test.ComplexObject1");
ComplexObject2 obj2 = ComplexObject2(true, {Int8(-1): Int32(2)});
ComplexObject1 obj = ComplexObject1();
obj.f1 = obj2;
@@ -128,8 +128,8 @@ void main() {
// Fory fory = Fory(
// ref: true,
// );
- // fory.register($ComplexObject2, typename: "test.ComplexObject2");
- // fory.register($ComplexObject1, typename: "test.ComplexObject1");
+ // fory.register(ComplexObject2, typename: "test.ComplexObject2");
+ // fory.register(ComplexObject1, typename: "test.ComplexObject1");
// ComplexObject2 obj2 = ComplexObject2(true,{Int8(-1):Int32(2)});
// ComplexObject1 obj = ComplexObject1();
// obj.f1 = obj2;
@@ -151,8 +151,8 @@ void main() {
// Fory fory = Fory(
// ref: true,
// );
- // fory.register($ComplexObject2, typename: "test.ComplexObject2");
- // fory.register($ComplexObject1, typename: "test.ComplexObject1");
+ // fory.register(ComplexObject2, typename: "test.ComplexObject2");
+ // fory.register(ComplexObject1, typename: "test.ComplexObject1");
// ComplexObject2 obj2 = ComplexObject2(true,{Int8(-1):Int32(2)});
// ComplexObject1 obj = ComplexObject1();
// obj.f1 = obj2;
diff --git
a/dart/packages/fory-test/test/struct_test/uint_annotated_struct_test.dart
b/dart/packages/fory-test/test/struct_test/uint_annotated_struct_test.dart
index c351dcab3..ffb3e40df 100644
--- a/dart/packages/fory-test/test/struct_test/uint_annotated_struct_test.dart
+++ b/dart/packages/fory-test/test/struct_test/uint_annotated_struct_test.dart
@@ -39,7 +39,7 @@ void main() {
// Serialize
var fory = Fory();
- fory.register($UIntAnnotatedStruct);
+ fory.register(UIntAnnotatedStruct);
var bytes = fory.serialize(original);
expect(bytes.isNotEmpty, isTrue);
@@ -69,7 +69,7 @@ void main() {
);
var fory = Fory();
- fory.register($UIntAnnotatedStruct);
+ fory.register(UIntAnnotatedStruct);
var bytes = fory.serialize(original);
var decoded = fory.deserialize(bytes) as UIntAnnotatedStruct;
@@ -88,7 +88,7 @@ void main() {
);
var fory = Fory();
- fory.register($UIntAnnotatedStruct);
+ fory.register(UIntAnnotatedStruct);
var bytes = fory.serialize(original);
var decoded = fory.deserialize(bytes) as UIntAnnotatedStruct;
@@ -107,7 +107,7 @@ void main() {
);
var fory = Fory();
- fory.register($UIntAnnotatedStruct);
+ fory.register(UIntAnnotatedStruct);
var bytes = fory.serialize(original);
var decoded = fory.deserialize(bytes) as UIntAnnotatedStruct;
@@ -127,7 +127,7 @@ void main() {
);
var fory = Fory();
- fory.register($UIntAnnotatedStruct);
+ fory.register(UIntAnnotatedStruct);
var bytes = fory.serialize(original);
var decoded = fory.deserialize(bytes) as UIntAnnotatedStruct;
@@ -162,7 +162,7 @@ void main() {
);
var fory = Fory();
- fory.register($UIntAnnotatedStruct);
+ fory.register(UIntAnnotatedStruct);
var smallBytes = fory.serialize(smallValues);
var largeBytes = fory.serialize(largeValues);
diff --git a/dart/packages/fory-test/test/struct_test/uint_struct_test.dart
b/dart/packages/fory-test/test/struct_test/uint_struct_test.dart
index 89b340667..97aaa3e6c 100644
--- a/dart/packages/fory-test/test/struct_test/uint_struct_test.dart
+++ b/dart/packages/fory-test/test/struct_test/uint_struct_test.dart
@@ -35,7 +35,7 @@ void main() {
// Serialize
var fory = Fory();
- fory.register($UIntStruct);
+ fory.register(UIntStruct);
var bytes = fory.serialize(original);
expect(bytes.isNotEmpty, isTrue);
@@ -57,7 +57,7 @@ void main() {
);
var fory = Fory();
- fory.register($UIntStruct);
+ fory.register(UIntStruct);
var bytes = fory.serialize(original);
var decoded = fory.deserialize(bytes) as UIntStruct;
@@ -74,7 +74,7 @@ void main() {
);
var fory = Fory();
- fory.register($UIntStruct);
+ fory.register(UIntStruct);
var bytes = fory.serialize(original);
var decoded = fory.deserialize(bytes) as UIntStruct;
diff --git a/dart/packages/fory/README.md b/dart/packages/fory/README.md
index 0e194eedc..8dce617e0 100644
--- a/dart/packages/fory/README.md
+++ b/dart/packages/fory/README.md
@@ -34,7 +34,7 @@ import 'package:fory/fory.dart';
part 'example.g.dart';
@foryClass
-class SomeClass with _$SomeClassFory {
+class SomeClass {
late int id;
late String name;
late Map<String, double> map;
@@ -51,13 +51,13 @@ After annotating your class with `@foryClass`, run:
dart run build_runner build
```
-This generates the necessary code in `example.g.dart` and creates the
`_$SomeClassFory` mixin.
+This generates the necessary schema metadata in `example.g.dart`.
### Serializing and Deserializing
```dart
Fory fory = Fory(ref: true);
-fory.register($SomeClass, typename: "example.SomeClass");
+fory.registerStruct(SomeClass, typename: "example.SomeClass");
SomeClass obj = SomeClass(1, 'SomeClass', {'a': 1.0});
// Serialize
@@ -84,7 +84,7 @@ enum EnumFoo {
Registration is similar to classes:
```dart
-fory.register($EnumFoo, typename: "example.EnumFoo");
+fory.registerEnum(EnumFoo, typename: "example.EnumFoo");
```
## Type Support
diff --git a/dart/packages/fory/example/example.dart
b/dart/packages/fory/example/example.dart
index 12b965991..44b88a6e5 100644
--- a/dart/packages/fory/example/example.dart
+++ b/dart/packages/fory/example/example.dart
@@ -24,7 +24,7 @@ import 'package:fory/fory.dart';
part 'example.g.dart';
@foryClass
-class Person with _$PersonFory {
+class Person {
final String firstName, lastName;
final int age;
final LocalDate dateOfBirth;
@@ -34,7 +34,7 @@ class Person with _$PersonFory {
void main() {
Fory fory = Fory(ref: true);
- fory.register($Person, typename: "example.Person");
+ fory.register(Person, typename: "example.Person");
Person obj = Person('Leo', 'Leo', 21, LocalDate(2004, 1, 1));
// Serialize
diff --git a/dart/packages/fory/example/example.g.dart
b/dart/packages/fory/example/example.g.dart
index 31635b0ab..016177afb 100644
--- a/dart/packages/fory/example/example.g.dart
+++ b/dart/packages/fory/example/example.g.dart
@@ -99,8 +99,3 @@ final $Person = TypeSpec(
),
null,
);
-
-mixin _$PersonFory implements ForyTypeProvider {
- @override
- Type get foryType => Person;
-}
diff --git a/dart/packages/fory/lib/src/annotation/fory_key.dart
b/dart/packages/fory/lib/src/annotation/fory_key.dart
index b6d9f34c0..28903a055 100644
--- a/dart/packages/fory/lib/src/annotation/fory_key.dart
+++ b/dart/packages/fory/lib/src/annotation/fory_key.dart
@@ -47,9 +47,13 @@ class ForyKey {
/// A boolean value indicating whether to include this field during
serialization.
final bool includeToFory;
+ /// A boolean value indicating whether to track references for this field.
+ final bool ref;
+
/// Both [includeFromFory] and [includeToFory] default to `true`.
const ForyKey({
this.includeFromFory = true,
this.includeToFory = true,
+ this.ref = false,
});
}
diff --git
a/dart/packages/fory/lib/src/codegen/analyze/impl/annotation/key_annotation_analyzer.dart
b/dart/packages/fory/lib/src/codegen/analyze/impl/annotation/key_annotation_analyzer.dart
index f8c210fe3..db0b9efa6 100644
---
a/dart/packages/fory/lib/src/codegen/analyze/impl/annotation/key_annotation_analyzer.dart
+++
b/dart/packages/fory/lib/src/codegen/analyze/impl/annotation/key_annotation_analyzer.dart
@@ -56,9 +56,11 @@ class KeyAnnotationAnalyzer {
// If there is no annotation, both includeFromFory and includeToFory
default to true.
bool includeFromFory = true;
bool includeToFory = true;
+ bool ref = false;
if (getMeta && anno != null) {
includeFromFory = anno.getField("includeFromFory")!.toBoolValue()!;
includeToFory = anno.getField("includeToFory")!.toBoolValue()!;
+ ref = anno.getField("ref")!.toBoolValue()!;
// serializeToVar = anno.getField("serializeTo")?.variable;
// deserializeFromVar = anno.getField("deserializeFrom")?.variable;
// if (serializeToVar != null){
@@ -74,6 +76,7 @@ class KeyAnnotationAnalyzer {
// deserializeFrom: deserializeFrom,
includeFromFory: includeFromFory,
includeToFory: includeToFory,
+ ref: ref,
);
return foryKey;
}
diff --git
a/dart/packages/fory/lib/src/codegen/analyze/impl/field/field_analyzer_impl.dart
b/dart/packages/fory/lib/src/codegen/analyze/impl/field/field_analyzer_impl.dart
index e7d5e83ec..c16f02862 100644
---
a/dart/packages/fory/lib/src/codegen/analyze/impl/field/field_analyzer_impl.dart
+++
b/dart/packages/fory/lib/src/codegen/analyze/impl/field/field_analyzer_impl.dart
@@ -128,6 +128,7 @@ class FieldAnalyzerImpl implements FieldAnalyzer {
hasInitializer: element.hasInitializer,
includeFromFory: key.includeFromFory,
includeToFory: key.includeToFory,
+ trackingRef: key.ref,
),
);
}
diff --git
a/dart/packages/fory/lib/src/codegen/meta/impl/class_spec_generator.dart
b/dart/packages/fory/lib/src/codegen/meta/impl/class_spec_generator.dart
index f629ec9d8..8d6a3b6dc 100644
--- a/dart/packages/fory/lib/src/codegen/meta/impl/class_spec_generator.dart
+++ b/dart/packages/fory/lib/src/codegen/meta/impl/class_spec_generator.dart
@@ -57,21 +57,6 @@ class ClassSpecGenerator extends CustomTypeSpecGenerator {
);
}
- void _genMixinPart(StringBuffer buf) {
- buf.write("mixin ");
- buf.write('_\$');
- buf.write(name);
- buf.write("Fory");
- buf.write(" implements ForyTypeProvider {\n");
- CodegenTool.writeIndent(buf, CodegenStyle.indent);
- buf.write("@override\n");
- CodegenTool.writeIndent(buf, CodegenStyle.indent);
- buf.write("Type get foryType => ");
- buf.write(name);
- buf.write(";\n");
- buf.write("}\n");
- }
-
@override
void writeCode(StringBuffer buf, [int indentLevel = 0]) {
int totalIndent = indentLevel * CodegenStyle.indent;
@@ -136,7 +121,5 @@ class ClassSpecGenerator extends CustomTypeSpecGenerator {
// tail part
buf.write(");\n\n");
-
- _genMixinPart(buf);
}
}
diff --git
a/dart/packages/fory/lib/src/codegen/meta/impl/field_spec_immutable.dart
b/dart/packages/fory/lib/src/codegen/meta/impl/field_spec_immutable.dart
index 8a628c602..0ad37a0dd 100644
--- a/dart/packages/fory/lib/src/codegen/meta/impl/field_spec_immutable.dart
+++ b/dart/packages/fory/lib/src/codegen/meta/impl/field_spec_immutable.dart
@@ -35,6 +35,7 @@ class FieldSpecImmutable extends GeneratedCodePart {
final bool includeFromFory;
final bool includeToFory;
+ final bool trackingRef;
final bool isPublic;
@@ -65,6 +66,7 @@ class FieldSpecImmutable extends GeneratedCodePart {
required this.hasInitializer,
required this.includeFromFory,
required this.includeToFory,
+ required this.trackingRef,
}) : typeAdapter = TypeAdapter(typeSpec) {
if (isPublic) {
assert(name.isNotEmpty && name[0] != "_");
@@ -124,7 +126,7 @@ class FieldSpecImmutable extends GeneratedCodePart {
// ForyFieldSpec::name part
CodegenTool.writeIndent(buf, nextTotalIndent);
buf.write("'");
- buf.write(name);
+ buf.write(transName ?? name);
buf.write("',\n");
// ForyFieldSpec::type part
@@ -169,6 +171,11 @@ class FieldSpecImmutable extends GeneratedCodePart {
buf.write("null,\n");
}
+ if (trackingRef) {
+ CodegenTool.writeIndent(buf, nextTotalIndent);
+ buf.write("trackingRef: true,\n");
+ }
+
// tail part
CodegenTool.writeIndent(buf, totalIndent);
buf.write("),\n");
diff --git a/dart/packages/fory/lib/src/fory_impl.dart
b/dart/packages/fory/lib/src/fory_impl.dart
index 75a097323..d2298ad46 100644
--- a/dart/packages/fory/lib/src/fory_impl.dart
+++ b/dart/packages/fory/lib/src/fory_impl.dart
@@ -20,14 +20,10 @@
import 'dart:typed_data';
import 'package:fory/src/codegen/entity/struct_hash_pair.dart';
import 'package:fory/src/config/fory_config.dart';
-import 'package:fory/src/const/types.dart';
import 'package:fory/src/deserialization_dispatcher.dart';
import 'package:fory/src/dev_annotation/optimize.dart';
import 'package:fory/src/memory/byte_reader.dart';
import 'package:fory/src/memory/byte_writer.dart';
-import 'package:fory/src/meta/specs/type_spec.dart';
-import 'package:fory/src/meta/specs/custom_type_spec.dart';
-import 'package:fory/src/meta/specs/enum_spec.dart';
import 'package:fory/src/resolver/type_resolver.dart';
import 'package:fory/src/serialization_dispatcher.dart';
import 'package:fory/src/serializer/serializer.dart';
@@ -64,13 +60,13 @@ final class Fory {
@inline
void register(
- CustomTypeSpec spec, {
+ Type type, {
int? typeId,
String? namespace,
String? typename,
}) {
registerType(
- spec,
+ type,
typeId: typeId,
namespace: namespace,
typename: typename,
@@ -79,13 +75,13 @@ final class Fory {
@inline
void registerType(
- CustomTypeSpec spec, {
+ Type type, {
int? typeId,
String? namespace,
String? typename,
}) {
_typeResolver.registerType(
- spec,
+ type,
typeId: typeId,
namespace: namespace,
typename: typename,
@@ -94,13 +90,13 @@ final class Fory {
@inline
void registerStruct(
- TypeSpec spec, {
+ Type type, {
int? typeId,
String? namespace,
String? typename,
}) {
- register(
- spec,
+ _typeResolver.registerStruct(
+ type,
typeId: typeId,
namespace: namespace,
typename: typename,
@@ -109,13 +105,13 @@ final class Fory {
@inline
void registerEnum(
- EnumSpec spec, {
+ Type type, {
int? typeId,
String? namespace,
String? typename,
}) {
- register(
- spec,
+ _typeResolver.registerEnum(
+ type,
typeId: typeId,
namespace: namespace,
typename: typename,
@@ -124,23 +120,13 @@ final class Fory {
@inline
void registerUnion(
- CustomTypeSpec spec, {
+ Type type, {
int? typeId,
String? namespace,
String? typename,
}) {
- final ObjType objType = spec.objType;
- if (objType != ObjType.UNION &&
- objType != ObjType.TYPED_UNION &&
- objType != ObjType.NAMED_UNION) {
- throw ArgumentError.value(
- objType,
- 'spec.objType',
- 'registerUnion only accepts union specs',
- );
- }
- register(
- spec,
+ _typeResolver.registerUnion(
+ type,
typeId: typeId,
namespace: namespace,
typename: typename,
diff --git a/dart/packages/fory/lib/src/meta/specs/field_sorter.dart
b/dart/packages/fory/lib/src/meta/specs/field_sorter.dart
index fbf95b659..b6d615d05 100644
--- a/dart/packages/fory/lib/src/meta/specs/field_sorter.dart
+++ b/dart/packages/fory/lib/src/meta/specs/field_sorter.dart
@@ -152,8 +152,10 @@ final class FieldSorter {
}
static bool _isCompressed(ObjType objType) {
- return objType == ObjType.VAR_INT32 ||
+ return objType == ObjType.INT32 ||
+ objType == ObjType.VAR_INT32 ||
objType == ObjType.VAR_UINT32 ||
+ objType == ObjType.INT64 ||
objType == ObjType.VAR_INT64 ||
objType == ObjType.SLI_INT64 ||
objType == ObjType.VAR_UINT64 ||
diff --git a/dart/packages/fory/lib/src/resolver/impl/type_resolver_impl.dart
b/dart/packages/fory/lib/src/resolver/impl/type_resolver_impl.dart
index 4dee4f3d0..cb2ff6a52 100644
--- a/dart/packages/fory/lib/src/resolver/impl/type_resolver_impl.dart
+++ b/dart/packages/fory/lib/src/resolver/impl/type_resolver_impl.dart
@@ -45,6 +45,7 @@ import 'package:fory/src/meta/specs/field_sorter.dart';
import 'package:fory/src/meta/specs/field_type_spec.dart';
import 'package:fory/src/resolver/dart_type_resolver.dart';
import 'package:fory/src/resolver/meta_string_resolver.dart';
+import 'package:fory/src/resolver/spec_lookup.dart';
import 'package:fory/src/resolver/tag_string_resolver.dart';
import 'package:fory/src/resolver/struct_hash_resolver.dart';
import 'package:fory/src/resolver/type_resolver.dart';
@@ -125,6 +126,82 @@ final class TypeResolverImpl extends TypeResolver {
@override
void registerType(
+ Type type, {
+ int? typeId,
+ String? namespace,
+ String? typename,
+ }) {
+ final CustomTypeSpec spec = _resolveSpec(type);
+ _registerResolvedSpec(spec,
+ typeId: typeId, namespace: namespace, typename: typename);
+ }
+
+ @override
+ void registerStruct(
+ Type type, {
+ int? typeId,
+ String? namespace,
+ String? typename,
+ }) {
+ final CustomTypeSpec spec = _resolveSpec(type);
+ if (!_isStructSpec(spec.objType)) {
+ throw RegistrationArgumentException(
+ 'registerStruct requires a struct type, got ${spec.objType} for
$type');
+ }
+ _registerResolvedSpec(spec,
+ typeId: typeId, namespace: namespace, typename: typename);
+ }
+
+ @override
+ void registerEnum(
+ Type type, {
+ int? typeId,
+ String? namespace,
+ String? typename,
+ }) {
+ final CustomTypeSpec spec = _resolveSpec(type);
+ if (!_isEnumSpec(spec.objType)) {
+ throw RegistrationArgumentException(
+ 'registerEnum requires an enum type, got ${spec.objType} for $type');
+ }
+ _registerResolvedSpec(spec,
+ typeId: typeId, namespace: namespace, typename: typename);
+ }
+
+ @override
+ void registerUnion(
+ Type type, {
+ int? typeId,
+ String? namespace,
+ String? typename,
+ }) {
+ final CustomTypeSpec spec = _resolveSpec(type);
+ if (!_isUnionSpec(spec.objType)) {
+ throw RegistrationArgumentException(
+ 'registerUnion requires a union type, got ${spec.objType} for
$type');
+ }
+ _registerResolvedSpec(spec,
+ typeId: typeId, namespace: namespace, typename: typename);
+ }
+
+ CustomTypeSpec _resolveSpec(Type type) {
+ final CustomTypeSpec? cachedSpec = _type2Spec[type];
+ if (cachedSpec != null) {
+ return cachedSpec;
+ }
+ final CustomTypeSpec? lookedUpSpec = SpecLookup.resolve(type);
+ if (lookedUpSpec == null) {
+ throw RegistrationArgumentException(
+ 'No generated schema found for type $type. Ensure generated code is
available and imported.');
+ }
+ if (lookedUpSpec.dartType != type) {
+ throw RegistrationArgumentException(
+ 'Resolved schema type mismatch for $type, got
${lookedUpSpec.dartType}.');
+ }
+ return lookedUpSpec;
+ }
+
+ void _registerResolvedSpec(
CustomTypeSpec spec, {
int? typeId,
String? namespace,
@@ -167,6 +244,23 @@ final class TypeResolverImpl extends TypeResolver {
_regWithNamespace(spec, typename, simpleName, inferredNamespace);
}
+ bool _isStructSpec(ObjType objType) {
+ return objType == ObjType.NAMED_STRUCT ||
+ objType == ObjType.STRUCT ||
+ objType == ObjType.NAMED_COMPATIBLE_STRUCT ||
+ objType == ObjType.COMPATIBLE_STRUCT;
+ }
+
+ bool _isEnumSpec(ObjType objType) {
+ return objType == ObjType.NAMED_ENUM || objType == ObjType.ENUM;
+ }
+
+ bool _isUnionSpec(ObjType objType) {
+ return objType == ObjType.UNION ||
+ objType == ObjType.TYPED_UNION ||
+ objType == ObjType.NAMED_UNION;
+ }
+
@override
void registerSerializer(Type type, Serializer serializer) {
TypeInfo? typeInfo = _ctx.type2TypeInfo[type];
@@ -291,6 +385,15 @@ final class TypeResolverImpl extends TypeResolver {
return tag;
}
+ @override
+ Serializer getRegisteredSerializer(Type type) {
+ TypeInfo? typeInfo = _ctx.type2TypeInfo[type];
+ if (typeInfo == null) {
+ throw UnregisteredTypeException(type);
+ }
+ return typeInfo.serializer;
+ }
+
@override
void bindSerializers(List<TypeSpecWrap> typeWraps) {
TypeSpecWrap wrap;
@@ -715,6 +818,10 @@ final class TypeResolverImpl extends TypeResolver {
case ObjType.TYPED_UNION:
case ObjType.NAMED_UNION:
return ObjType.UNION.id;
+ case ObjType.INT32:
+ return ObjType.VAR_INT32.id;
+ case ObjType.INT64:
+ return ObjType.VAR_INT64.id;
case ObjType.STRUCT:
case ObjType.COMPATIBLE_STRUCT:
case ObjType.NAMED_STRUCT:
diff --git a/dart/packages/fory/lib/src/resolver/spec_lookup.dart
b/dart/packages/fory/lib/src/resolver/spec_lookup.dart
new file mode 100644
index 000000000..e87182066
--- /dev/null
+++ b/dart/packages/fory/lib/src/resolver/spec_lookup.dart
@@ -0,0 +1,52 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you 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.
+ */
+
+import 'dart:collection';
+import 'package:fory/src/meta/specs/custom_type_spec.dart';
+import 'package:fory/src/resolver/spec_lookup_stub.dart'
+ if (dart.library.mirrors)
'package:fory/src/resolver/spec_lookup_mirrors.dart'
+ as impl;
+
+final class SpecLookup {
+ static final Map<Type, CustomTypeSpec?> _resolvedCache =
+ HashMap<Type, CustomTypeSpec?>();
+ static final Map<Type, CustomTypeSpec> _manualSpecs =
+ HashMap<Type, CustomTypeSpec>();
+
+ static CustomTypeSpec? resolve(Type type) {
+ if (_resolvedCache.containsKey(type)) {
+ return _resolvedCache[type];
+ }
+ final CustomTypeSpec? spec =
+ _manualSpecs[type] ?? impl.resolveByMirrors(type);
+ _resolvedCache[type] = spec;
+ return spec;
+ }
+
+ static void register(CustomTypeSpec spec) {
+ _manualSpecs[spec.dartType] = spec;
+ _resolvedCache[spec.dartType] = spec;
+ }
+
+ static void registerAll(Iterable<CustomTypeSpec> specs) {
+ for (final CustomTypeSpec spec in specs) {
+ register(spec);
+ }
+ }
+}
diff --git a/dart/packages/fory/lib/src/resolver/spec_lookup_mirrors.dart
b/dart/packages/fory/lib/src/resolver/spec_lookup_mirrors.dart
new file mode 100644
index 000000000..30d7634d1
--- /dev/null
+++ b/dart/packages/fory/lib/src/resolver/spec_lookup_mirrors.dart
@@ -0,0 +1,89 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you 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.
+ */
+
+import 'dart:mirrors';
+import 'package:fory/src/meta/specs/custom_type_spec.dart';
+
+CustomTypeSpec? resolveByMirrors(Type type) {
+ final ClassMirror? classMirror = _classMirrorOf(type);
+ if (classMirror == null) {
+ return null;
+ }
+ final String simpleName = MirrorSystem.getName(classMirror.simpleName);
+ if (simpleName.isEmpty) {
+ return null;
+ }
+ final Symbol symbol = Symbol('\$$simpleName');
+ final LibraryMirror? ownerLibrary = _ownerLibraryOf(classMirror);
+ if (ownerLibrary != null) {
+ final CustomTypeSpec? inOwner = _readSpecFromLibrary(ownerLibrary, symbol);
+ if (inOwner != null && inOwner.dartType == type) {
+ return inOwner;
+ }
+ }
+ for (final LibraryMirror library in currentMirrorSystem().libraries.values) {
+ if (identical(library, ownerLibrary)) {
+ continue;
+ }
+ final CustomTypeSpec? candidate = _readSpecFromLibrary(library, symbol);
+ if (candidate != null && candidate.dartType == type) {
+ return candidate;
+ }
+ }
+ return null;
+}
+
+ClassMirror? _classMirrorOf(Type type) {
+ try {
+ final TypeMirror typeMirror = reflectType(type);
+ if (typeMirror is ClassMirror) {
+ return typeMirror;
+ }
+ } catch (_) {
+ return null;
+ }
+ return null;
+}
+
+LibraryMirror? _ownerLibraryOf(ClassMirror classMirror) {
+ DeclarationMirror? owner = classMirror.owner;
+ while (owner != null && owner is! LibraryMirror) {
+ if (owner is ClassMirror) {
+ owner = owner.owner;
+ continue;
+ }
+ return null;
+ }
+ return owner is LibraryMirror ? owner : null;
+}
+
+CustomTypeSpec? _readSpecFromLibrary(LibraryMirror library, Symbol symbol) {
+ if (!library.declarations.containsKey(symbol)) {
+ return null;
+ }
+ try {
+ final Object? reflectee = library.getField(symbol).reflectee;
+ if (reflectee is CustomTypeSpec) {
+ return reflectee;
+ }
+ } catch (_) {
+ return null;
+ }
+ return null;
+}
diff --git a/dart/example/nested_collection_example.dart
b/dart/packages/fory/lib/src/resolver/spec_lookup_stub.dart
similarity index 77%
copy from dart/example/nested_collection_example.dart
copy to dart/packages/fory/lib/src/resolver/spec_lookup_stub.dart
index 805932705..0bcd0f0fd 100644
--- a/dart/example/nested_collection_example.dart
+++ b/dart/packages/fory/lib/src/resolver/spec_lookup_stub.dart
@@ -17,13 +17,8 @@
* under the License.
*/
-import 'package:fory/fory.dart';
+import 'package:fory/src/meta/specs/custom_type_spec.dart';
-part 'nested_collection_example.g.dart';
-
-@foryClass
-class NestedObject with _$NestedObjectFory {
- late final String name;
- late final List<String> names;
- late final Map<double, Map<String, int>> map;
+CustomTypeSpec? resolveByMirrors(Type type) {
+ return null;
}
diff --git a/dart/packages/fory/lib/src/resolver/struct_hash_resolver.dart
b/dart/packages/fory/lib/src/resolver/struct_hash_resolver.dart
index b8feaed67..340f53ea4 100644
--- a/dart/packages/fory/lib/src/resolver/struct_hash_resolver.dart
+++ b/dart/packages/fory/lib/src/resolver/struct_hash_resolver.dart
@@ -87,6 +87,12 @@ class StructHashResolver {
}
int _fingerprintTypeId(ObjType objType) {
+ if (objType == ObjType.INT32) {
+ return ObjType.VAR_INT32.id;
+ }
+ if (objType == ObjType.INT64) {
+ return ObjType.VAR_INT64.id;
+ }
if (objType == ObjType.UNKNOWN) {
return ObjType.UNKNOWN.id;
}
diff --git a/dart/packages/fory/lib/src/resolver/type_resolver.dart
b/dart/packages/fory/lib/src/resolver/type_resolver.dart
index b65307cf3..dffeadc79 100644
--- a/dart/packages/fory/lib/src/resolver/type_resolver.dart
+++ b/dart/packages/fory/lib/src/resolver/type_resolver.dart
@@ -25,7 +25,6 @@ import
'package:fory/src/resolver/impl/type_resolver_impl.dart';
import 'package:fory/src/serializer/serializer.dart';
import 'package:fory/src/config/fory_config.dart';
import 'package:fory/src/memory/byte_writer.dart';
-import 'package:fory/src/meta/specs/custom_type_spec.dart';
import 'package:fory/src/serialization_context.dart';
abstract base class TypeResolver {
@@ -36,7 +35,28 @@ abstract base class TypeResolver {
}
void registerType(
- CustomTypeSpec spec, {
+ Type type, {
+ int? typeId,
+ String? namespace,
+ String? typename,
+ });
+
+ void registerStruct(
+ Type type, {
+ int? typeId,
+ String? namespace,
+ String? typename,
+ });
+
+ void registerEnum(
+ Type type, {
+ int? typeId,
+ String? namespace,
+ String? typename,
+ });
+
+ void registerUnion(
+ Type type, {
int? typeId,
String? namespace,
String? typename,
@@ -56,6 +76,8 @@ abstract base class TypeResolver {
TypeInfo writeTypeInfo(ByteWriter bw, Object obj, SerializationContext pack);
+ Serializer getRegisteredSerializer(Type type);
+
/*-----For test only------------------------------------------------*/
StructHashPair getHashPairForTest(
Type type,
diff --git a/dart/packages/fory/lib/src/serializer/class_serializer.dart
b/dart/packages/fory/lib/src/serializer/class_serializer.dart
index 836efa970..750dbe215 100644
--- a/dart/packages/fory/lib/src/serializer/class_serializer.dart
+++ b/dart/packages/fory/lib/src/serializer/class_serializer.dart
@@ -133,6 +133,12 @@ final class ClassSerializer extends
CustomSerializer<Object> {
}
late Object? fieldValue;
Serializer? serializer = _fieldTypeWraps[i].serializer;
+ if (serializer == null &&
+ !_compatible &&
+ fieldSpec.trackingRef &&
+ typeWrap.objType != ObjType.UNKNOWN) {
+ serializer = pack.typeResolver.getRegisteredSerializer(typeWrap.type);
+ }
if (serializer == null) {
if (fieldSpec.trackingRef || typeWrap.nullable) {
fieldValue =
@@ -183,6 +189,12 @@ final class ClassSerializer extends
CustomSerializer<Object> {
}
Object? fieldValue = fieldSpec.getter!(v);
Serializer? serializer = typeWrap.serializer;
+ if (serializer == null &&
+ !_compatible &&
+ fieldSpec.trackingRef &&
+ typeWrap.objType != ObjType.UNKNOWN) {
+ serializer = pack.typeResolver.getRegisteredSerializer(typeWrap.type);
+ }
if (serializer == null) {
if (fieldSpec.trackingRef || typeWrap.nullable) {
pack.serializationDispatcher
@@ -216,6 +228,12 @@ final class ClassSerializer extends
CustomSerializer<Object> {
pack.typeWrapStack.push(typeWrap);
}
Serializer? serializer = typeWrap.serializer;
+ if (serializer == null &&
+ !_compatible &&
+ fieldSpec.trackingRef &&
+ typeWrap.objType != ObjType.UNKNOWN) {
+ serializer = pack.typeResolver.getRegisteredSerializer(typeWrap.type);
+ }
if (serializer == null) {
if (fieldSpec.trackingRef || typeWrap.nullable) {
args[i] = pack.deserializationDispatcher.readDynamicWithRef(br,
pack);
diff --git
a/dart/packages/fory/lib/src/serializer/collection/list/list_serializer.dart
b/dart/packages/fory/lib/src/serializer/collection/list/list_serializer.dart
index 07628d002..55e75c43d 100644
--- a/dart/packages/fory/lib/src/serializer/collection/list/list_serializer.dart
+++ b/dart/packages/fory/lib/src/serializer/collection/list/list_serializer.dart
@@ -58,7 +58,12 @@ abstract base class ListSerializer extends
IterableSerializer {
(flags & IterableSerializer.isDeclElementTypeFlag) ==
IterableSerializer.isDeclElementTypeFlag;
if (isDeclElemType) {
- serializer = elemWrap?.serializer;
+ if (elemWrap == null) {
+ throw StateError(
+ 'List element declared type flag set but element type is
unavailable');
+ }
+ serializer = elemWrap.serializer ??
+ pack.typeResolver.getRegisteredSerializer(elemWrap.type);
}
if (serializer == null) {
serializer = pack.typeResolver.readTypeInfo(br).serializer;
diff --git
a/dart/packages/fory/lib/src/serializer/collection/map/map_serializer.dart
b/dart/packages/fory/lib/src/serializer/collection/map/map_serializer.dart
index e37efd492..27e698a16 100644
--- a/dart/packages/fory/lib/src/serializer/collection/map/map_serializer.dart
+++ b/dart/packages/fory/lib/src/serializer/collection/map/map_serializer.dart
@@ -92,14 +92,24 @@ abstract base class MapSerializer<T extends Map<Object?,
Object?>>
int chunkSize = br.readUint8();
Serializer keySerializer;
- if (keyDeclaredType && keyWrap?.serializer != null) {
- keySerializer = keyWrap!.serializer!;
+ if (keyDeclaredType) {
+ if (keyWrap == null) {
+ throw StateError(
+ 'Map key declared type flag set but key type is unavailable');
+ }
+ keySerializer = keyWrap.serializer ??
+ pack.typeResolver.getRegisteredSerializer(keyWrap.type);
} else {
keySerializer = pack.typeResolver.readTypeInfo(br).serializer;
}
Serializer valueSerializer;
- if (valueDeclaredType && valueWrap?.serializer != null) {
- valueSerializer = valueWrap!.serializer!;
+ if (valueDeclaredType) {
+ if (valueWrap == null) {
+ throw StateError(
+ 'Map value declared type flag set but value type is
unavailable');
+ }
+ valueSerializer = valueWrap.serializer ??
+ pack.typeResolver.getRegisteredSerializer(valueWrap.type);
} else {
valueSerializer = pack.typeResolver.readTypeInfo(br).serializer;
}
@@ -311,9 +321,14 @@ abstract base class MapSerializer<T extends Map<Object?,
Object?>>
) {
bool trackRef = (chunkHeader & _trackingKeyRef) != 0;
bool keyDeclaredType = (chunkHeader & _keyDeclType) != 0;
- if (keyDeclaredType && keyWrap?.serializer != null) {
- return _readWithSerializer(
- br, keyWrap!.serializer!, trackRef, pack, keyWrap);
+ if (keyDeclaredType) {
+ if (keyWrap == null) {
+ throw StateError(
+ 'Map key declared type flag set but key type is unavailable');
+ }
+ Serializer keySerializer = keyWrap.serializer ??
+ pack.typeResolver.getRegisteredSerializer(keyWrap.type);
+ return _readWithSerializer(br, keySerializer, trackRef, pack, keyWrap);
}
return _readWithDynamic(br, trackRef, pack, keyWrap);
}
@@ -326,9 +341,15 @@ abstract base class MapSerializer<T extends Map<Object?,
Object?>>
) {
bool trackRef = (chunkHeader & _trackingValueRef) != 0;
bool valueDeclaredType = (chunkHeader & _valueDeclType) != 0;
- if (valueDeclaredType && valueWrap?.serializer != null) {
+ if (valueDeclaredType) {
+ if (valueWrap == null) {
+ throw StateError(
+ 'Map value declared type flag set but value type is unavailable');
+ }
+ Serializer valueSerializer = valueWrap.serializer ??
+ pack.typeResolver.getRegisteredSerializer(valueWrap.type);
return _readWithSerializer(
- br, valueWrap!.serializer!, trackRef, pack, valueWrap);
+ br, valueSerializer, trackRef, pack, valueWrap);
}
return _readWithDynamic(br, trackRef, pack, valueWrap);
}
diff --git
a/java/fory-core/src/test/java/org/apache/fory/xlang/DartXlangTest.java
b/java/fory-core/src/test/java/org/apache/fory/xlang/DartXlangTest.java
index 26fd0d0c1..f27cabf6b 100644
--- a/java/fory-core/src/test/java/org/apache/fory/xlang/DartXlangTest.java
+++ b/java/fory-core/src/test/java/org/apache/fory/xlang/DartXlangTest.java
@@ -24,8 +24,10 @@ import java.io.IOException;
import java.nio.file.Path;
import java.util.ArrayList;
import java.util.Arrays;
+import java.util.Collections;
import java.util.List;
import java.util.Map;
+import org.apache.fory.test.TestUtils;
import org.testng.SkipException;
import org.testng.annotations.Test;
@@ -33,8 +35,18 @@ import org.testng.annotations.Test;
@Test
public class DartXlangTest extends XlangTestBase {
private static final String DART_EXECUTABLE = "dart";
+ private static final int DART_SETUP_TIMEOUT_SECONDS = 300;
+ private static final File DART_WORK_DIR = new File("../../dart");
+ private static final File DART_FORY_TEST_WORK_DIR = new
File("../../dart/packages/fory-test");
+ private static final File DART_XLANG_SOURCE_FILE =
+ new File(DART_FORY_TEST_WORK_DIR, "lib/entity/xlang_test_models.dart");
+ private static final File DART_XLANG_GENERATED_FILE =
+ new File(DART_FORY_TEST_WORK_DIR,
"lib/generated/xlang_test_models.g.dart");
private static final String DART_MODULE =
"packages/fory-test/test/cross_lang_test/xlang_test_main.dart";
+ private static final List<String> DART_CODEGEN_COMMAND =
+ Arrays.asList(
+ DART_EXECUTABLE, "run", "build_runner", "build",
"--delete-conflicting-outputs");
private static final List<String> DART_BASE_COMMAND =
Arrays.asList(DART_EXECUTABLE, "run", DART_MODULE, "<DART_TESTCASE>");
@@ -63,6 +75,7 @@ public class DartXlangTest extends XlangTestBase {
if (!dartInstalled) {
throw new SkipException("Skipping DartXlangTest: dart not installed");
}
+ ensureGeneratedXlangSpecs();
}
@Override
@@ -71,7 +84,23 @@ public class DartXlangTest extends XlangTestBase {
command.set(DART_TESTCASE_INDEX, caseName);
Map<String, String> env = envBuilder(dataFile);
env.put("ENABLE_FORY_DEBUG_OUTPUT", "1");
- return new CommandContext(command, env, new File("../../dart"));
+ return new CommandContext(command, env, DART_WORK_DIR);
+ }
+
+ private static synchronized void ensureGeneratedXlangSpecs() {
+ if (DART_XLANG_GENERATED_FILE.isFile()
+ && DART_XLANG_GENERATED_FILE.lastModified() >=
DART_XLANG_SOURCE_FILE.lastModified()) {
+ return;
+ }
+ if (!TestUtils.executeCommand(
+ DART_CODEGEN_COMMAND,
+ DART_SETUP_TIMEOUT_SECONDS,
+ Collections.emptyMap(),
+ DART_FORY_TEST_WORK_DIR)) {
+ throw new IllegalStateException(
+ "Failed to generate Dart xlang specs by command: "
+ + String.join(" ", DART_CODEGEN_COMMAND));
+ }
}
//
============================================================================
---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]