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 8ef0bf593 feat(dart): add uint annotation types to the fory's codegen
system (#3181)
8ef0bf593 is described below
commit 8ef0bf5932d6044e9282dac4cec41f5bf17af502
Author: Ayush Kumar <[email protected]>
AuthorDate: Thu Jan 22 16:18:34 2026 +0530
feat(dart): add uint annotation types to the fory's codegen system (#3181)
## Why?
While unsigned integer type annotations (`@Uint8Type`, `@Uint16Type`,
`@Uint32Type`, `@Uint64Type`) were added in PR #3144, they were not
integrated into the code generation system. This meant:
* The annotation definitions existed but were not recognized by the code
generator
* No support for annotation-based type specification like `@Uint8Type()
int age` in struct fields
* Users couldn't use the protobuf/flatbuffer-style ergonomic API that
was intended
* No way to specify encoding variants (fixed vs varint) for
uint32/uint64 via annotations during code generation
## What does this PR do?
### 1. Created Uint Annotation Analyzer
Added `uint_annotation_analyzer.dart` to detect and parse uint type
annotations during code generation:
```dart
class UintAnnotationAnalyzer {
UintAnnotationResult analyze(
List<ElementAnnotation> metadata,
LocationMark locationMark,
) {
// Detects @Uint8Type, @Uint16Type, @Uint32Type, @Uint64Type
// Extracts encoding options (fixed, varint, tagged)
// Returns appropriate ObjType
}
}
```
**Supported annotations:**
* `@Uint8Type()` → `ObjType.UINT8`
* `@Uint16Type()` → `ObjType.UINT16`
* `@Uint32Type()` → `ObjType.UINT32`
* `@Uint32Type(encoding: UintEncoding.varint)` → `ObjType.VAR_UINT32`
* `@Uint64Type()` → `ObjType.UINT64`
* `@Uint64Type(encoding: UintEncoding.varint)` → `ObjType.VAR_UINT64`
* `@Uint64Type(encoding: UintEncoding.tagged)` → `ObjType.TAGGED_UINT64`
### 2. Extended Type Identifier System
Updated `analysis_type_identifier.dart` to recognize uint annotation
types:
```dart
static final List<Type3StringKey> _keys = [
// ... existing annotations
Type3StringKey('Uint8Type', 'package',
'fory/src/annotation/uint_types.dart'),
Type3StringKey('Uint16Type', 'package',
'fory/src/annotation/uint_types.dart'),
Type3StringKey('Uint32Type', 'package',
'fory/src/annotation/uint_types.dart'),
Type3StringKey('Uint64Type', 'package',
'fory/src/annotation/uint_types.dart'),
];
```
### 3. Integrated Annotation-Based Type Override
Modified `type_analyzer_impl.dart` to support annotation-based type
override:
```dart
TypeSpecGen getTypeImmutableAndTagWithOverride(
TypeDecision typeDecision,
LocationMark locationMark,
ObjType objTypeOverride,
) {
// Uses annotation-specified ObjType instead of default type resolution
}
```
### 4. Updated Field Analyzer
Modified `field_analyzer_impl.dart` to check for uint annotations:
```dart
// Check for uint annotations
final uintAnnotationResult = Analyzer.uintAnnotationAnalyzer.analyze(
element.metadata,
locationMark,
);
if (uintAnnotationResult.hasAnnotation) {
// Use annotation-based type override
fieldType = Analyzer.typeAnalyzer.getTypeImmutableAndTagWithOverride(
typeDecision, locationMark, uintAnnotationResult.objType!,
);
}
```
## Related issues
Completes the unsigned integer annotation types support initiated in PR
#3144 by integrating the annotations into the code generation system.
## Does this PR introduce any user-facing change?
* [x] Does this PR introduce any public API change?
* **Dart**: Users can now use `@Uint8Type()`, `@Uint16Type()`,
`@Uint32Type()`, `@Uint64Type()` annotations on native `int` fields in
`@ForyClass` structs
* Enables encoding variant specification via `encoding` parameter for
uint32/uint64
* Provides more ergonomic API: `@Uint8Type() int age` instead of `UInt8
age`
* [ ] Does this PR introduce any binary protocol compatibility change?
* No changes to binary encoding format
* Uses existing ObjType mappings and serializers
* Type IDs remain the same: UINT8 (40), UINT16 (41), UINT32 (42),
VAR_UINT32 (43), UINT64 (44), VAR_UINT64 (45), TAGGED_UINT64 (46)
## Benchmark
N/A - This PR only adds annotation processing during code generation
(build-time). No runtime performance impact.
---------
Co-authored-by: Shawn Yang <[email protected]>
---
.../uint_annotation_analyzer_test.dart | 136 +++++++++++++++++++
.../codegen/analyze/analysis_type_identifier.dart | 38 +++++-
.../fory/lib/src/codegen/analyze/analyzer.dart | 2 +
.../impl/annotation/uint_annotation_analyzer.dart | 149 +++++++++++++++++++++
.../analyze/impl/field/field_analyzer_impl.dart | 30 ++++-
.../analyze/impl/type/type_analyzer_impl.dart | 36 +++++
.../codegen/analyze/interface/type_analyzer.dart | 10 ++
.../exception/constraint_violation_exception.dart | 10 ++
8 files changed, 408 insertions(+), 3 deletions(-)
diff --git
a/dart/packages/fory-test/test/codegen_test/uint_annotation_analyzer_test.dart
b/dart/packages/fory-test/test/codegen_test/uint_annotation_analyzer_test.dart
new file mode 100644
index 000000000..84621f0f9
--- /dev/null
+++
b/dart/packages/fory-test/test/codegen_test/uint_annotation_analyzer_test.dart
@@ -0,0 +1,136 @@
+/*
+ * 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.
+ */
+
+library;
+
+import 'package:analyzer/dart/element/element.dart';
+import 'package:build_test/build_test.dart';
+import
'package:fory/src/codegen/analyze/impl/annotation/uint_annotation_analyzer.dart';
+import 'package:fory/src/codegen/entity/location_mark.dart';
+import 'package:fory/src/const/obj_type.dart';
+import 'package:test/test.dart';
+
+void main() {
+ group('UintAnnotationAnalyzer integration tests', () {
+ const analyzer = UintAnnotationAnalyzer();
+
+ Future<UintAnnotationResult> analyzeField(String source, String fieldName)
async {
+ final library = await resolveSource(source, (resolver) =>
resolver.findLibraryByName('test_lib'));
+ final classElement = library!.topLevelElements.firstWhere((e) => e is
ClassElement) as ClassElement;
+ final fieldElement = classElement.fields.firstWhere((f) => f.name ==
fieldName);
+
+ final locationMark = LocationMark.fieldLevel(
+ 'test_lib',
+ 'TestClass',
+ fieldName,
+ );
+
+ return analyzer.analyze(fieldElement.metadata, locationMark);
+ }
+
+ const String commonSource = '''
+library test_lib;
+import 'package:fory/fory.dart';
+
+class TestClass {
+ @Uint8Type()
+ int f8;
+
+ @Uint16Type()
+ int f16;
+
+ @Uint32Type()
+ int f32;
+
+ @Uint32Type(encoding: UintEncoding.varint)
+ int f32v;
+
+ @Uint64Type()
+ int f64;
+
+ @Uint64Type(encoding: UintEncoding.varint)
+ int f64v;
+
+ @Uint64Type(encoding: UintEncoding.tagged)
+ int f64t;
+
+ int fNone;
+
+ @Uint8Type()
+ @Uint16Type()
+ int fDup;
+}
+''';
+
+ test('analyzes @Uint8Type correctly', () async {
+ final result = await analyzeField(commonSource, 'f8');
+ expect(result.hasAnnotation, isTrue);
+ expect(result.objType, equals(ObjType.UINT8));
+ });
+
+ test('analyzes @Uint16Type correctly', () async {
+ final result = await analyzeField(commonSource, 'f16');
+ expect(result.hasAnnotation, isTrue);
+ expect(result.objType, equals(ObjType.UINT16));
+ });
+
+ test('analyzes @Uint32Type (default) correctly', () async {
+ final result = await analyzeField(commonSource, 'f32');
+ expect(result.hasAnnotation, isTrue);
+ expect(result.objType, equals(ObjType.UINT32));
+ });
+
+ test('analyzes @Uint32Type (varint) correctly', () async {
+ final result = await analyzeField(commonSource, 'f32v');
+ expect(result.hasAnnotation, isTrue);
+ expect(result.objType, equals(ObjType.VAR_UINT32));
+ });
+
+ test('analyzes @Uint64Type (default) correctly', () async {
+ final result = await analyzeField(commonSource, 'f64');
+ expect(result.hasAnnotation, isTrue);
+ expect(result.objType, equals(ObjType.UINT64));
+ });
+
+ test('analyzes @Uint64Type (varint) correctly', () async {
+ final result = await analyzeField(commonSource, 'f64v');
+ expect(result.hasAnnotation, isTrue);
+ expect(result.objType, equals(ObjType.VAR_UINT64));
+ });
+
+ test('analyzes @Uint64Type (tagged) correctly', () async {
+ final result = await analyzeField(commonSource, 'f64t');
+ expect(result.hasAnnotation, isTrue);
+ expect(result.objType, equals(ObjType.TAGGED_UINT64));
+ });
+
+ test('returns none for unannotated field', () async {
+ final result = await analyzeField(commonSource, 'fNone');
+ expect(result.hasAnnotation, isFalse);
+ expect(result.objType, isNull);
+ });
+
+ test('throws exception for duplicated uint annotations', () async {
+ expect(
+ () => analyzeField(commonSource, 'fDup'),
+ throwsA(anything), // Should throw DuplicatedAnnotationException
+ );
+ });
+ });
+}
diff --git
a/dart/packages/fory/lib/src/codegen/analyze/analysis_type_identifier.dart
b/dart/packages/fory/lib/src/codegen/analyze/analysis_type_identifier.dart
index 82b6fff8b..4a55a760a 100644
--- a/dart/packages/fory/lib/src/codegen/analyze/analysis_type_identifier.dart
+++ b/dart/packages/fory/lib/src/codegen/analyze/analysis_type_identifier.dart
@@ -35,7 +35,7 @@ class AnalysisTypeIdentifier{
static int get dartCoreLibId => objectType.element.library.id;
- static final List<int?> _ids = [null,null,null,null];
+ static final List<int?> _ids = [null,null,null,null,null,null,null,null];
static final List<Type3StringKey> _keys = [
Type3StringKey(
'ForyClass',
@@ -57,6 +57,26 @@ class AnalysisTypeIdentifier{
'package',
'fory/src/annotation/fory_enum.dart',
),
+ Type3StringKey(
+ 'Uint8Type',
+ 'package',
+ 'fory/src/annotation/uint_types.dart',
+ ),
+ Type3StringKey(
+ 'Uint16Type',
+ 'package',
+ 'fory/src/annotation/uint_types.dart',
+ ),
+ Type3StringKey(
+ 'Uint32Type',
+ 'package',
+ 'fory/src/annotation/uint_types.dart',
+ ),
+ Type3StringKey(
+ 'Uint64Type',
+ 'package',
+ 'fory/src/annotation/uint_types.dart',
+ ),
];
static bool _check(ClassElement element, int index){
@@ -100,4 +120,20 @@ class AnalysisTypeIdentifier{
_ids[0] = id;
}
+ static bool isUint8Type(ClassElement element){
+ return _check(element, 4);
+ }
+
+ static bool isUint16Type(ClassElement element){
+ return _check(element, 5);
+ }
+
+ static bool isUint32Type(ClassElement element){
+ return _check(element, 6);
+ }
+
+ static bool isUint64Type(ClassElement element){
+ return _check(element, 7);
+ }
+
}
\ No newline at end of file
diff --git a/dart/packages/fory/lib/src/codegen/analyze/analyzer.dart
b/dart/packages/fory/lib/src/codegen/analyze/analyzer.dart
index 46add8502..55b6701ae 100644
--- a/dart/packages/fory/lib/src/codegen/analyze/analyzer.dart
+++ b/dart/packages/fory/lib/src/codegen/analyze/analyzer.dart
@@ -20,6 +20,7 @@
import
'package:fory/src/codegen/analyze/impl/annotation/class_annotation_analyzer.dart';
import
'package:fory/src/codegen/analyze/impl/annotation/enum_annotation_analyzer.dart';
import
'package:fory/src/codegen/analyze/impl/annotation/key_annotation_analyzer.dart';
+import
'package:fory/src/codegen/analyze/impl/annotation/uint_annotation_analyzer.dart';
import
'package:fory/src/codegen/analyze/impl/constructor/constructor_analyzer.dart';
import 'package:fory/src/codegen/analyze/impl/field/access_info_analyzer.dart';
import 'package:fory/src/codegen/analyze/impl/field/field_analyzer_impl.dart';
@@ -44,6 +45,7 @@ abstract class Analyzer {
static const ClassAnnotationAnalyzer classAnnotationAnalyzer =
ClassAnnotationAnalyzer();
static const KeyAnnotationAnalyzer keyAnnotationAnalyzer =
KeyAnnotationAnalyzer();
static const EnumAnnotationAnalyzer enumAnnotationAnalyzer =
EnumAnnotationAnalyzer();
+ static const UintAnnotationAnalyzer uintAnnotationAnalyzer =
UintAnnotationAnalyzer();
// Enum analyzers
static const EnumAnalyzer enumAnalyzer = EnumAnalyzerImpl();
diff --git
a/dart/packages/fory/lib/src/codegen/analyze/impl/annotation/uint_annotation_analyzer.dart
b/dart/packages/fory/lib/src/codegen/analyze/impl/annotation/uint_annotation_analyzer.dart
new file mode 100644
index 000000000..208de6a85
--- /dev/null
+++
b/dart/packages/fory/lib/src/codegen/analyze/impl/annotation/uint_annotation_analyzer.dart
@@ -0,0 +1,149 @@
+/*
+ * 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:analyzer/dart/constant/value.dart';
+import 'package:analyzer/dart/element/element.dart';
+import 'package:fory/src/codegen/analyze/analysis_type_identifier.dart';
+import
'package:fory/src/codegen/analyze/annotation/location_level_ensure.dart';
+import 'package:fory/src/codegen/const/location_level.dart';
+import 'package:fory/src/codegen/entity/location_mark.dart';
+import 'package:fory/src/codegen/exception/annotation_exception.dart';
+import 'package:fory/src/const/obj_type.dart';
+
+/// Result of uint annotation analysis
+class UintAnnotationResult {
+ final ObjType? objType;
+ final bool hasAnnotation;
+
+ const UintAnnotationResult(this.objType, this.hasAnnotation);
+
+ static const none = UintAnnotationResult(null, false);
+}
+
+class UintAnnotationAnalyzer {
+ const UintAnnotationAnalyzer();
+
+ /// Analyzes uint type annotations on a field.
+ /// Returns the appropriate ObjType if a uint annotation is found, null
otherwise.
+ UintAnnotationResult analyze(
+ List<ElementAnnotation> metadata,
+ @LocationEnsure(LocationLevel.fieldLevel) LocationMark locationMark,
+ ) {
+ assert(locationMark.ensureFieldLevel);
+
+ DartObject? uintAnno;
+ String? annotationType;
+
+ for (ElementAnnotation annoElement in metadata) {
+ final anno = annoElement.computeConstantValue()!;
+ final annoClsElement = anno.type!.element as ClassElement;
+
+ if (AnalysisTypeIdentifier.isUint8Type(annoClsElement)) {
+ if (uintAnno != null) {
+ throw DuplicatedAnnotationException(
+ 'Uint type annotation',
+ locationMark.fieldName!,
+ locationMark.clsLocation,
+ );
+ }
+ uintAnno = anno;
+ annotationType = 'Uint8Type';
+ } else if (AnalysisTypeIdentifier.isUint16Type(annoClsElement)) {
+ if (uintAnno != null) {
+ throw DuplicatedAnnotationException(
+ 'Uint type annotation',
+ locationMark.fieldName!,
+ locationMark.clsLocation,
+ );
+ }
+ uintAnno = anno;
+ annotationType = 'Uint16Type';
+ } else if (AnalysisTypeIdentifier.isUint32Type(annoClsElement)) {
+ if (uintAnno != null) {
+ throw DuplicatedAnnotationException(
+ 'Uint type annotation',
+ locationMark.fieldName!,
+ locationMark.clsLocation,
+ );
+ }
+ uintAnno = anno;
+ annotationType = 'Uint32Type';
+ } else if (AnalysisTypeIdentifier.isUint64Type(annoClsElement)) {
+ if (uintAnno != null) {
+ throw DuplicatedAnnotationException(
+ 'Uint type annotation',
+ locationMark.fieldName!,
+ locationMark.clsLocation,
+ );
+ }
+ uintAnno = anno;
+ annotationType = 'Uint64Type';
+ }
+ }
+
+ if (uintAnno == null) {
+ return UintAnnotationResult.none;
+ }
+
+ // Determine the ObjType based on the annotation
+ ObjType objType;
+ switch (annotationType) {
+ case 'Uint8Type':
+ objType = ObjType.UINT8;
+ break;
+ case 'Uint16Type':
+ objType = ObjType.UINT16;
+ break;
+ case 'Uint32Type':
+ // Check encoding parameter
+ final encodingField = uintAnno.getField('encoding');
+ if (encodingField != null && !encodingField.isNull) {
+ final encodingValue =
encodingField.getField('_name')?.toStringValue();
+ if (encodingValue == 'varint') {
+ objType = ObjType.VAR_UINT32;
+ } else {
+ objType = ObjType.UINT32;
+ }
+ } else {
+ objType = ObjType.UINT32;
+ }
+ break;
+ case 'Uint64Type':
+ // Check encoding parameter
+ final encodingField = uintAnno.getField('encoding');
+ if (encodingField != null && !encodingField.isNull) {
+ final encodingValue =
encodingField.getField('_name')?.toStringValue();
+ if (encodingValue == 'varint') {
+ objType = ObjType.VAR_UINT64;
+ } else if (encodingValue == 'tagged') {
+ objType = ObjType.TAGGED_UINT64;
+ } else {
+ objType = ObjType.UINT64;
+ }
+ } else {
+ objType = ObjType.UINT64;
+ }
+ break;
+ default:
+ return UintAnnotationResult.none;
+ }
+
+ return UintAnnotationResult(objType, true);
+ }
+}
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 838b4f54a..aacfebf3e 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
@@ -90,11 +90,37 @@ class FieldAnalyzerImpl implements FieldAnalyzer{
return null;
}
- TypeSpecGen fieldType = Analyzer.typeAnalyzer.getTypeImmutableAndTag(
- Analyzer.typeSystemAnalyzer.decideInterfaceType(element.type),
+ // Check for uint annotations
+ final uintAnnotationResult = Analyzer.uintAnnotationAnalyzer.analyze(
+ element.metadata,
locationMark,
);
+ TypeSpecGen fieldType;
+ if (uintAnnotationResult.hasAnnotation) {
+ // Validate that @uint is only used on int fields
+ if (!element.type.isDartCoreInt) {
+ throw ConstraintViolationException(
+ locationMark.libPath,
+ locationMark.clsName,
+ element.name,
+ 'Please Validate @uint usage only on int fields',
+ );
+ }
+ // Use annotation-based type override
+ fieldType = Analyzer.typeAnalyzer.getTypeImmutableAndTagWithOverride(
+ Analyzer.typeSystemAnalyzer.decideInterfaceType(element.type),
+ locationMark,
+ uintAnnotationResult.objType!,
+ );
+ } else {
+ // Use default type resolution
+ fieldType = Analyzer.typeAnalyzer.getTypeImmutableAndTag(
+ Analyzer.typeSystemAnalyzer.decideInterfaceType(element.type),
+ locationMark,
+ );
+ }
+
return Either.left(
FieldSpecImmutable.publicOr(
element.isPublic,
diff --git
a/dart/packages/fory/lib/src/codegen/analyze/impl/type/type_analyzer_impl.dart
b/dart/packages/fory/lib/src/codegen/analyze/impl/type/type_analyzer_impl.dart
index 54bbd7d7e..7330a3156 100644
---
a/dart/packages/fory/lib/src/codegen/analyze/impl/type/type_analyzer_impl.dart
+++
b/dart/packages/fory/lib/src/codegen/analyze/impl/type/type_analyzer_impl.dart
@@ -29,6 +29,7 @@ import 'package:fory/src/codegen/const/location_level.dart';
import 'package:fory/src/codegen/entity/location_mark.dart';
import 'package:fory/src/codegen/meta/impl/type_immutable.dart';
import 'package:fory/src/codegen/meta/impl/type_spec_gen.dart';
+import 'package:fory/src/const/obj_type.dart';
class TypeAnalyzerImpl extends TypeAnalyzer{
@@ -92,6 +93,41 @@ class TypeAnalyzerImpl extends TypeAnalyzer{
);
}
+ /// Version of getTypeImmutableAndTag that supports annotation-based ObjType
override.
+ /// Used when uint annotations are present on int fields.
+ TypeSpecGen getTypeImmutableAndTagWithOverride(
+ TypeDecision typeDecision,
+ @LocationEnsure(LocationLevel.fieldLevel) LocationMark locationMark,
+ ObjType objTypeOverride,
+ ){
+ InterfaceType type = typeDecision.type;
+
+ InterfaceElement element = type.element;
+ int libId = element.library.id;
+ bool nullable = (typeDecision.forceNullable) ? true:
type.nullabilitySuffix == NullabilitySuffix.question;
+
+ List<TypeSpecGen> typeArgsTypes = [];
+ for (DartType arg in type.typeArguments){
+ typeArgsTypes.add(
+ _analyze(
+ Analyzer.typeSystemAnalyzer.decideInterfaceType(arg),
+ locationMark,
+ ),
+ );
+ }
+ return TypeSpecGen(
+ TypeImmutable(
+ element.name,
+ libId,
+ objTypeOverride,
+ objTypeOverride.independent,
+ true, // certainForSer is true for annotation-based types
+ ),
+ nullable,
+ typeArgsTypes,
+ );
+ }
+
TypeImmutable _analyzeTypeImmutable(
InterfaceElement element,
@LocationEnsure(LocationLevel.fieldLevel) LocationMark locationMark,
diff --git
a/dart/packages/fory/lib/src/codegen/analyze/interface/type_analyzer.dart
b/dart/packages/fory/lib/src/codegen/analyze/interface/type_analyzer.dart
index bc17b824e..819267ee9 100644
--- a/dart/packages/fory/lib/src/codegen/analyze/interface/type_analyzer.dart
+++ b/dart/packages/fory/lib/src/codegen/analyze/interface/type_analyzer.dart
@@ -22,6 +22,7 @@ import
'package:fory/src/codegen/analyze/annotation/location_level_ensure.dart';
import 'package:fory/src/codegen/const/location_level.dart';
import 'package:fory/src/codegen/entity/location_mark.dart';
import 'package:fory/src/codegen/meta/impl/type_spec_gen.dart';
+import 'package:fory/src/const/obj_type.dart';
abstract class TypeAnalyzer{
@@ -29,4 +30,13 @@ abstract class TypeAnalyzer{
TypeDecision typeDecision,
@LocationEnsure(LocationLevel.fieldLevel) LocationMark locationMark,
);
+
+ /// Version of getTypeImmutableAndTag that supports annotation-based ObjType
override.
+ /// Used when uint annotations are present on int fields.
+ TypeSpecGen getTypeImmutableAndTagWithOverride(
+ TypeDecision typeDecision,
+ @LocationEnsure(LocationLevel.fieldLevel) LocationMark locationMark,
+ ObjType objTypeOverride,
+ );
+
}
\ No newline at end of file
diff --git
a/dart/packages/fory/lib/src/codegen/exception/constraint_violation_exception.dart
b/dart/packages/fory/lib/src/codegen/exception/constraint_violation_exception.dart
index a6d3bc305..e068a4d52 100644
---
a/dart/packages/fory/lib/src/codegen/exception/constraint_violation_exception.dart
+++
b/dart/packages/fory/lib/src/codegen/exception/constraint_violation_exception.dart
@@ -197,3 +197,13 @@ class UnsupportedTypeException extends
ForyCodegenException {
return buf.toString();
}
}
+
+class ConstraintViolationException extends FieldException {
+ ConstraintViolationException(
+ String libPath,
+ String className,
+ String fieldName,
+ String constraint, [
+ String? where,
+ ]) : super(libPath, className, [fieldName], constraint, where);
+}
---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]