Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 4 additions & 1 deletion analysis_options.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ analyzer:
language:
strict-casts: true
strict-inference: true
strict-raw-types: true

linter:
rules:
Expand All @@ -28,6 +29,7 @@ linter:

# correctness
- always_declare_return_types
- avoid_annotating_with_dynamic
- avoid_catching_errors
- avoid_dynamic_calls
- comment_references
Expand All @@ -41,4 +43,5 @@ linter:

- omit_obvious_local_variable_types
- specify_nonobvious_local_variable_types
- specify_nonobvious_property_types
- specify_nonobvious_property_types
- strict_top_level_inference
Original file line number Diff line number Diff line change
Expand Up @@ -24,17 +24,15 @@ class BookingService {
}

Future<HotelSearchResult> listHotels(HotelSearch search) async {
// ignore: inference_failure_on_instance_creation
await Future.delayed(const Duration(milliseconds: 100));
await Future<void>.delayed(const Duration(milliseconds: 100));
return listHotelsSync(search);
}

Future<void> bookSelections(
List<String> listingSelectionIds,
String paymentMethodId,
) async {
// ignore: inference_failure_on_instance_creation
await Future.delayed(const Duration(milliseconds: 400));
await Future<void>.delayed(const Duration(milliseconds: 400));
}

/// Synchronous version for example data generation.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ class LoadingState {
} else if (_isProcessingValue && !isProcessing.value) {
// Went from true to false, reset messages after a short delay
// to allow the fade-out animation to complete.
Future.delayed(const Duration(milliseconds: 500), clearMessages);
Future<void>.delayed(const Duration(milliseconds: 500), clearMessages);
}
_isProcessingValue = isProcessing.value;
});
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ class AppNavigator extends ConsumerStatefulWidget {
}

class _AppNavigatorState extends ConsumerState<AppNavigator> {
StreamSubscription? _subscription;
StreamSubscription<void>? _subscription;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

high

The type argument for StreamSubscription should be String to match the stream it's subscribing to. The surfaceUpdateController.stream is a Stream<String>, so the subscription should be of type StreamSubscription<String>? to correctly reflect the type of data flowing through the stream.

Suggested change
StreamSubscription<void>? _subscription;
StreamSubscription<String>? _subscription;

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In this case, we explicitly don't care about the data flowing through the stream. We only use the subscription for cancellation, so void helps indicate we shouldn't/don't want to access the data through it.


@override
void initState() {
Expand Down
19 changes: 12 additions & 7 deletions packages/genui/test/model/data_model_test.dart
Original file line number Diff line number Diff line change
Expand Up @@ -148,9 +148,9 @@ void main() {
});

test('notifies on child updates', () {
final ValueNotifier<Map<dynamic, dynamic>?> notifier = dataModel
.subscribe<Map>(DataPath('/a'));
Map? value;
final ValueNotifier<Map<Object?, Object?>?> notifier = dataModel
.subscribe<Map<Object?, Object?>>(DataPath('/a'));
Map<Object?, Object?>? value;
notifier.addListener(() => value = notifier.value);
dataModel.update(DataPath('/a/b'), 1);
expect(value, {'b': 1});
Expand Down Expand Up @@ -180,8 +180,8 @@ void main() {
});

test('does not notify on child updates', () {
final ValueNotifier<Map<dynamic, dynamic>?> notifier = dataModel
.subscribeToValue<Map>(DataPath('/a'));
final ValueNotifier<Map<Object?, Object?>?> notifier = dataModel
.subscribeToValue<Map<Object?, Object?>>(DataPath('/a'));
var callCount = 0;
notifier.addListener(() => callCount++);
dataModel.update(DataPath('/a/b'), 1);
Expand Down Expand Up @@ -232,7 +232,10 @@ void main() {
],
},
]);
expect(dataModel.getValue<Map>(DataPath('/d')), {'d1': 'v1', 'd2': 2});
expect(dataModel.getValue<Map<Object?, Object?>>(DataPath('/d')), {
'd1': 'v1',
'd2': 2,
});
});

test('is permissive with multiple value types', () {
Expand Down Expand Up @@ -304,7 +307,9 @@ void main() {

test('Empty path on getValue returns current data', () {
dataModel.update(DataPath('/a'), {'b': 1});
expect(dataModel.getValue<Map>(DataPath('/a')), {'b': 1});
expect(dataModel.getValue<Map<Object?, Object?>>(DataPath('/a')), {
'b': 1,
});
});

test('Nested structures are created automatically', () {
Expand Down
6 changes: 4 additions & 2 deletions packages/genui_dartantic/example/lib/src/jumping_dots.dart
Original file line number Diff line number Diff line change
Expand Up @@ -55,9 +55,11 @@ class _JumpingDotsState extends State<JumpingDots>
controller.reverse();
}
});
await Future.delayed(const Duration(milliseconds: 100)); // Stagger delay
await Future<void>.delayed(
const Duration(milliseconds: 100),
); // Stagger delay
}
await Future.delayed(
await Future<void>.delayed(
const Duration(milliseconds: 1000),
); // Delay between loops
if (mounted) _startAnimations(); // Loop
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -116,7 +116,7 @@ void main() {
final result = adaptSchema(schema);

expect(result, isNotNull);
expect(result!.schemaMap!['anyOf'], isA<List>());
expect(result!.schemaMap!['anyOf'], isA<List<Object?>>());
});
});
}
4 changes: 2 additions & 2 deletions packages/json_schema_builder/lib/src/schema_registry.dart
Original file line number Diff line number Diff line change
Expand Up @@ -97,7 +97,7 @@ class SchemaRegistry {
_registerIds(Schema.fromMap(map), baseUri);
}

void recurseOnList(List list) {
void recurseOnList(List<Object?> list) {
for (final item in list) {
if (item is Map<String, Object?>) {
recurseOnMap(item);
Expand Down Expand Up @@ -144,7 +144,7 @@ class SchemaRegistry {
// Keywords with list-of-schemas values
const listOfSchemasKeywords = ['allOf', 'anyOf', 'oneOf', 'prefixItems'];
for (final keyword in listOfSchemasKeywords) {
if (schema.value[keyword] case final List list) {
if (schema.value[keyword] case final List<Object?> list) {
recurseOnList(list);
}
}
Expand Down
10 changes: 5 additions & 5 deletions packages/json_schema_builder/lib/src/schema_validation.dart
Original file line number Diff line number Diff line change
Expand Up @@ -352,7 +352,7 @@ extension SchemaValidation on Schema {
}

// 2. Schema Combiners: allOf, anyOf, oneOf, not
if (allOf case final List allOfList?) {
if (allOf case final List<Object?> allOfList) {
final allOfAnnotations = <AnnotationSet>[];
for (final subSchema in allOfList) {
final ValidationResult result = await validateSubSchema(
Expand All @@ -370,7 +370,7 @@ extension SchemaValidation on Schema {
allAnnotations = allAnnotations.mergeAll(allOfAnnotations);
}

if (anyOf case final List anyOfList?) {
if (anyOf case final List<Object?> anyOfList) {
var passedCount = 0;
final anyOfAnnotations = <AnnotationSet>[];
final allAnyOfErrors = <ValidationError>[];
Expand All @@ -397,7 +397,7 @@ extension SchemaValidation on Schema {
allAnnotations = allAnnotations.mergeAll(anyOfAnnotations);
}

if (oneOf case final List oneOfList?) {
if (oneOf case final List<Object?> oneOfList) {
var passedCount = 0;
AnnotationSet? oneOfAnnotations;
for (final subSchema in oneOfList) {
Expand Down Expand Up @@ -590,7 +590,7 @@ extension SchemaValidation on Schema {
);
case JsonType.list:
return await (this as ListSchema).validateList(
data as List,
data as List<Object?>,
currentPath,
context,
dynamicScope,
Expand Down Expand Up @@ -895,7 +895,7 @@ extension SchemaValidation on Schema {
/// This method is called by [validateTypeSpecificKeywords] when the data is
/// a [List].
Future<ValidationResult> validateList(
List data,
List<Object?> data,
List<String> currentPath,
ValidationContext context,
List<Schema> dynamicScope,
Expand Down
2 changes: 1 addition & 1 deletion tool/fix_copyright/test/fix_copyright_test.dart
Original file line number Diff line number Diff line change
Expand Up @@ -388,7 +388,7 @@ class FakeProcessManager implements ProcessManager {
final List<List<String>> commands = [];

@override
bool canRun(dynamic executable, {String? workingDirectory}) => true;
bool canRun(Object? executable, {String? workingDirectory}) => true;

@override
bool killPid(int pid, [ProcessSignal signal = ProcessSignal.sigterm]) => true;
Expand Down
Loading