Skip to content
4 changes: 4 additions & 0 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -999,6 +999,10 @@ jobs:
run: |
cd dart/packages/fory-test
dart test
- name: Run web tests
run: |
cd dart/packages/fory
dart test -p chrome
- name: Run code analysis
run: |
cd dart/packages/fory-test
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -244,8 +244,8 @@ void _verifyDecimalCase() {

Uint8List _hashBytes(int low, int high) {
final buffer = Buffer();
buffer.writeInt64(low);
buffer.writeInt64(high);
buffer.writeInt64(Int64(low));
buffer.writeInt64(Int64(high));
return buffer.toBytes();
}

Expand Down
4 changes: 2 additions & 2 deletions dart/packages/fory/example/manual_serializer.dart
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ final class Person {
Person(this.name, this.age);

final String name;
final int age;
final Int64 age;
}

final class PersonSerializer extends Serializer<Person> {
Expand Down Expand Up @@ -52,7 +52,7 @@ void main() {
typeName: 'Person',
);

final person = Person('Ada', 36);
final person = Person('Ada', Int64(36));
final bytes = fory.serialize(person);
final roundTrip = fory.deserialize<Person>(bytes);
print(roundTrip.name);
Expand Down
3 changes: 2 additions & 1 deletion dart/packages/fory/lib/fory.dart
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ export 'src/annotation/fory_struct.dart';
export 'src/annotation/fory_union.dart';
export 'src/annotation/type_spec.dart';
export 'src/annotation/numeric_types.dart';
export 'src/buffer.dart'
export 'src/memory/buffer.dart'
hide
bufferByteData,
bufferBytes,
Expand All @@ -55,6 +55,7 @@ export 'src/types/float16.dart';
export 'src/types/float32.dart';
export 'src/types/int16.dart';
export 'src/types/int32.dart';
export 'src/types/int64.dart';
export 'src/types/int8.dart';
export 'src/types/local_date.dart';
export 'src/types/timestamp.dart';
Expand Down
123 changes: 98 additions & 25 deletions dart/packages/fory/lib/src/codegen/fory_generator.dart
Original file line number Diff line number Diff line change
Expand Up @@ -33,10 +33,12 @@ class DebugGeneratedFieldTypeSpec {
required this.nullable,
required this.ref,
required this.dynamic,
this.declaredTypeName,
this.arguments = const <DebugGeneratedFieldTypeSpec>[],
});

final String typeLiteral;
final String? declaredTypeName;
final int typeId;
final bool nullable;
final bool ref;
Expand Down Expand Up @@ -93,7 +95,7 @@ final class ForyGenerator extends Generator {
annotatedClasses.map(_analyzeStruct).toList(growable: false);
final output = StringBuffer()
..writeln(
'// ignore_for_file: implementation_imports, invalid_use_of_internal_member, no_leading_underscores_for_local_identifiers, unused_element, unused_element_parameter, unnecessary_null_comparison',
'// ignore_for_file: implementation_imports, invalid_use_of_internal_member, no_leading_underscores_for_local_identifiers, unreachable_switch_case, unused_element, unused_element_parameter, unnecessary_null_comparison',
)
..writeln();

Expand Down Expand Up @@ -218,6 +220,7 @@ final class ForyGenerator extends Generator {
typeSpec is _ListTypeSpecInfo ? typeSpec.element : null;
return _GeneratedFieldTypeSpec(
typeLiteral: _typeReferenceLiteral(type),
declaredTypeName: _typeReferenceLiteral(type),
typeId: _typeIdFor(type),
nullable: nullable,
ref: ref,
Expand All @@ -239,6 +242,7 @@ final class ForyGenerator extends Generator {
final valueSpec = typeSpec is _MapTypeSpecInfo ? typeSpec.value : null;
return _GeneratedFieldTypeSpec(
typeLiteral: _typeReferenceLiteral(type),
declaredTypeName: _typeReferenceLiteral(type),
typeId: _typeIdFor(type),
nullable: nullable,
ref: ref,
Expand All @@ -263,6 +267,7 @@ final class ForyGenerator extends Generator {
}
return _GeneratedFieldTypeSpec(
typeLiteral: _typeReferenceLiteral(type),
declaredTypeName: _typeReferenceLiteral(type),
typeId: _typeIdFor(type, integerAnnotation: integerAnnotation),
nullable: nullable,
ref: ref,
Expand Down Expand Up @@ -885,6 +890,7 @@ final class ForyGenerator extends Generator {
return '''
GeneratedFieldType(
type: ${fieldType.typeLiteral},
declaredTypeName: '${fieldType.typeLiteral}',
typeId: ${fieldType.typeId},
nullable: ${fieldType.nullable},
ref: ${fieldType.ref},
Expand Down Expand Up @@ -912,6 +918,7 @@ GeneratedFieldType(
) {
return _GeneratedFieldTypeSpec(
typeLiteral: fieldType.typeLiteral,
declaredTypeName: fieldType.declaredTypeName,
typeId: fieldType.typeId,
nullable: fieldType.nullable,
ref: fieldType.ref,
Expand Down Expand Up @@ -1035,6 +1042,10 @@ GeneratedFieldType(
case TypeIds.int32:
case TypeIds.varInt32:
return 'switch ($valueExpression) { int typed => typed, Int32 typed => typed.value, _ => throw StateError(\'Expected int or Int32.\') }';
case TypeIds.int64:
case TypeIds.varInt64:
case TypeIds.taggedInt64:
return 'switch ($valueExpression) { Int64 typed => typed.toInt(), int typed => typed, _ => throw StateError(\'Expected int or Int64.\') }';
case TypeIds.uint8:
return 'switch ($valueExpression) { int typed => typed, Uint8 typed => typed.value, _ => throw StateError(\'Expected int or Uint8.\') }';
case TypeIds.uint16:
Expand All @@ -1045,7 +1056,7 @@ GeneratedFieldType(
case TypeIds.uint64:
case TypeIds.varUint64:
case TypeIds.taggedUint64:
return 'switch ($valueExpression) { int typed => typed, Uint64 typed => typed.value, _ => throw StateError(\'Expected int or Uint64.\') }';
return 'switch ($valueExpression) { Uint64 typed => typed.toInt(), int typed => typed, _ => throw StateError(\'Expected int or Uint64.\') }';
default:
return '$valueExpression as int';
}
Expand Down Expand Up @@ -1223,10 +1234,19 @@ GeneratedFieldType(
case TypeIds.varInt32:
return 'buffer.writeVarInt32(${_directGeneratedScalarExpression(field, valueExpression)})';
case TypeIds.int64:
if (field.type.isDartCoreInt) {
return 'buffer.writeInt64FromInt($valueExpression)';
}
return 'buffer.writeInt64(${_directGeneratedScalarExpression(field, valueExpression)})';
case TypeIds.varInt64:
if (field.type.isDartCoreInt) {
return 'buffer.writeVarInt64FromInt($valueExpression)';
}
return 'buffer.writeVarInt64(${_directGeneratedScalarExpression(field, valueExpression)})';
case TypeIds.taggedInt64:
if (field.type.isDartCoreInt) {
return 'buffer.writeTaggedInt64FromInt($valueExpression)';
}
return 'buffer.writeTaggedInt64(${_directGeneratedScalarExpression(field, valueExpression)})';
case TypeIds.uint8:
return 'buffer.writeUint8(${_directGeneratedScalarExpression(field, valueExpression)})';
Expand Down Expand Up @@ -1305,10 +1325,19 @@ GeneratedFieldType(
case TypeIds.varInt32:
return '$cursorExpression.writeVarInt32(${_directGeneratedScalarExpression(field, valueExpression)})';
case TypeIds.int64:
if (field.type.isDartCoreInt) {
return '$cursorExpression.writeInt64FromInt($valueExpression)';
}
return '$cursorExpression.writeInt64(${_directGeneratedScalarExpression(field, valueExpression)})';
case TypeIds.varInt64:
if (field.type.isDartCoreInt) {
return '$cursorExpression.writeVarInt64FromInt($valueExpression)';
}
return '$cursorExpression.writeVarInt64(${_directGeneratedScalarExpression(field, valueExpression)})';
case TypeIds.taggedInt64:
if (field.type.isDartCoreInt) {
return '$cursorExpression.writeTaggedInt64FromInt($valueExpression)';
}
return '$cursorExpression.writeTaggedInt64(${_directGeneratedScalarExpression(field, valueExpression)})';
case TypeIds.uint8:
return '$cursorExpression.writeUint8(${_directGeneratedScalarExpression(field, valueExpression)})';
Expand All @@ -1319,10 +1348,19 @@ GeneratedFieldType(
case TypeIds.varUint32:
return '$cursorExpression.writeVarUint32(${_directGeneratedScalarExpression(field, valueExpression)})';
case TypeIds.uint64:
if (field.type.isDartCoreInt) {
return '$cursorExpression.writeUint64FromInt($valueExpression)';
}
return '$cursorExpression.writeUint64(${_directGeneratedScalarExpression(field, valueExpression)})';
case TypeIds.varUint64:
if (field.type.isDartCoreInt) {
return '$cursorExpression.writeVarUint64FromInt($valueExpression)';
}
return '$cursorExpression.writeVarUint64(${_directGeneratedScalarExpression(field, valueExpression)})';
case TypeIds.taggedUint64:
if (field.type.isDartCoreInt) {
return '$cursorExpression.writeTaggedUint64FromInt($valueExpression)';
}
return '$cursorExpression.writeTaggedUint64(${_directGeneratedScalarExpression(field, valueExpression)})';
case TypeIds.float16:
return '$cursorExpression.writeFloat16($valueExpression)';
Expand Down Expand Up @@ -1370,11 +1408,17 @@ GeneratedFieldType(
? 'buffer.readVarInt32()'
: 'Int32(buffer.readVarInt32())';
case TypeIds.int64:
return 'buffer.readInt64()';
return field.type.isDartCoreInt
? 'buffer.readInt64AsInt()'
: 'buffer.readInt64()';
case TypeIds.varInt64:
return 'buffer.readVarInt64()';
return field.type.isDartCoreInt
? 'buffer.readVarInt64AsInt()'
: 'buffer.readVarInt64()';
case TypeIds.taggedInt64:
return 'buffer.readTaggedInt64()';
return field.type.isDartCoreInt
? 'buffer.readTaggedInt64AsInt()'
: 'buffer.readTaggedInt64()';
case TypeIds.uint8:
return field.type.isDartCoreInt
? 'buffer.readUint8()'
Expand All @@ -1393,16 +1437,16 @@ GeneratedFieldType(
: 'Uint32(buffer.readVarUint32())';
case TypeIds.uint64:
return field.type.isDartCoreInt
? 'buffer.readUint64()'
: 'Uint64(buffer.readUint64())';
? 'buffer.readUint64().toInt()'
: 'buffer.readUint64()';
case TypeIds.varUint64:
return field.type.isDartCoreInt
? 'buffer.readVarUint64()'
: 'Uint64(buffer.readVarUint64())';
? 'buffer.readVarUint64().toInt()'
: 'buffer.readVarUint64()';
case TypeIds.taggedUint64:
return field.type.isDartCoreInt
? 'buffer.readTaggedUint64()'
: 'Uint64(buffer.readTaggedUint64())';
? 'buffer.readTaggedUint64().toInt()'
: 'buffer.readTaggedUint64()';
case TypeIds.float16:
return 'buffer.readFloat16()';
case TypeIds.bfloat16:
Expand Down Expand Up @@ -1436,7 +1480,7 @@ GeneratedFieldType(
case TypeIds.int32Array:
return 'readGeneratedTypedArrayValue<Int32List>(context, 4, (bytes) => bytes.buffer.asInt32List(bytes.offsetInBytes, bytes.lengthInBytes ~/ 4))';
case TypeIds.int64Array:
return 'readGeneratedTypedArrayValue<Int64List>(context, 8, (bytes) => bytes.buffer.asInt64List(bytes.offsetInBytes, bytes.lengthInBytes ~/ 8))';
return 'readGeneratedTypedArrayValue<Int64List>(context, 8, (bytes) => Int64List.view(bytes.buffer, bytes.offsetInBytes, bytes.lengthInBytes ~/ 8))';
case TypeIds.uint8Array:
return 'readGeneratedBinaryValue(context)';
case TypeIds.uint16Array:
Expand All @@ -1448,7 +1492,7 @@ GeneratedFieldType(
case TypeIds.uint32Array:
return 'readGeneratedTypedArrayValue<Uint32List>(context, 4, (bytes) => bytes.buffer.asUint32List(bytes.offsetInBytes, bytes.lengthInBytes ~/ 4))';
case TypeIds.uint64Array:
return 'readGeneratedTypedArrayValue<Uint64List>(context, 8, (bytes) => bytes.buffer.asUint64List(bytes.offsetInBytes, bytes.lengthInBytes ~/ 8))';
return 'readGeneratedTypedArrayValue<Uint64List>(context, 8, (bytes) => Uint64List.view(bytes.buffer, bytes.offsetInBytes, bytes.lengthInBytes ~/ 8))';
case TypeIds.float32Array:
return 'readGeneratedTypedArrayValue<Float32List>(context, 4, (bytes) => bytes.buffer.asFloat32List(bytes.offsetInBytes, bytes.lengthInBytes ~/ 4))';
case TypeIds.float64Array:
Expand Down Expand Up @@ -1482,11 +1526,17 @@ GeneratedFieldType(
? '$cursorExpression.readVarInt32()'
: 'Int32($cursorExpression.readVarInt32())';
case TypeIds.int64:
return '$cursorExpression.readInt64()';
return field.type.isDartCoreInt
? '$cursorExpression.readInt64AsInt()'
: '$cursorExpression.readInt64()';
case TypeIds.varInt64:
return '$cursorExpression.readVarInt64()';
return field.type.isDartCoreInt
? '$cursorExpression.readVarInt64AsInt()'
: '$cursorExpression.readVarInt64()';
case TypeIds.taggedInt64:
return '$cursorExpression.readTaggedInt64()';
return field.type.isDartCoreInt
? '$cursorExpression.readTaggedInt64AsInt()'
: '$cursorExpression.readTaggedInt64()';
case TypeIds.uint8:
return field.type.isDartCoreInt
? '$cursorExpression.readUint8()'
Expand All @@ -1505,16 +1555,16 @@ GeneratedFieldType(
: 'Uint32($cursorExpression.readVarUint32())';
case TypeIds.uint64:
return field.type.isDartCoreInt
? '$cursorExpression.readUint64()'
: 'Uint64($cursorExpression.readUint64())';
? '$cursorExpression.readUint64AsInt()'
: '$cursorExpression.readUint64()';
case TypeIds.varUint64:
return field.type.isDartCoreInt
? '$cursorExpression.readVarUint64()'
: 'Uint64($cursorExpression.readVarUint64())';
? '$cursorExpression.readVarUint64AsInt()'
: '$cursorExpression.readVarUint64()';
case TypeIds.taggedUint64:
return field.type.isDartCoreInt
? '$cursorExpression.readTaggedUint64()'
: 'Uint64($cursorExpression.readTaggedUint64())';
? '$cursorExpression.readTaggedUint64AsInt()'
: '$cursorExpression.readTaggedUint64()';
case TypeIds.float16:
return '$cursorExpression.readFloat16()';
case TypeIds.bfloat16:
Expand Down Expand Up @@ -1568,15 +1618,33 @@ GeneratedFieldType(
_GeneratedFieldSpec field,
String valueExpression,
) {
if (field.type.isDartCoreInt ||
field.type.isDartCoreDouble ||
if (field.type.isDartCoreInt) {
switch (field.fieldType.typeId) {
case TypeIds.int64:
case TypeIds.varInt64:
case TypeIds.taggedInt64:
return 'Int64($valueExpression)';
case TypeIds.uint64:
case TypeIds.varUint64:
case TypeIds.taggedUint64:
return 'Uint64($valueExpression)';
default:
return valueExpression;
}
}
if (field.type.isDartCoreDouble ||
field.type.isDartCoreBool ||
field.type.isDartCoreString) {
return valueExpression;
}
switch (field.fieldType.typeId) {
case TypeIds.int64:
case TypeIds.varInt64:
case TypeIds.taggedInt64:
case TypeIds.uint64:
case TypeIds.varUint64:
case TypeIds.taggedUint64:
case TypeIds.float16:
return valueExpression;
case TypeIds.bfloat16:
return valueExpression;
default:
Expand Down Expand Up @@ -1607,6 +1675,7 @@ GeneratedFieldType(
}
return _GeneratedFieldTypeSpec(
typeLiteral: fieldType.typeLiteral,
declaredTypeName: fieldType.declaredTypeName,
typeId: fieldType.typeId,
nullable: false,
ref: fieldType.ref,
Expand Down Expand Up @@ -2101,6 +2170,8 @@ GeneratedFieldType(
return TypeIds.uint32;
case 'Uint64':
return TypeIds.uint64;
case 'Int64':
return TypeIds.varInt64;
case 'Float16':
return TypeIds.float16;
case 'Bfloat16':
Expand Down Expand Up @@ -2381,6 +2452,7 @@ final class _DirectGeneratedWriteReservationRun {

final class _GeneratedFieldTypeSpec {
final String typeLiteral;
final String? declaredTypeName;
final int typeId;
final bool nullable;
final bool ref;
Expand All @@ -2389,6 +2461,7 @@ final class _GeneratedFieldTypeSpec {

const _GeneratedFieldTypeSpec({
required this.typeLiteral,
this.declaredTypeName,
required this.typeId,
required this.nullable,
required this.ref,
Expand Down
21 changes: 21 additions & 0 deletions dart/packages/fory/lib/src/codegen/generated_cursor.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
/*
* 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.
*/

export 'generated_cursor_native.dart'
if (dart.library.js_interop) 'generated_cursor_web.dart';
Loading
Loading