Skip to content

Commit 7e5885e

Browse files
srawlinsCommit Queue
authored andcommitted
analyzer: Allow awaitNotRequired on a Future-returning typedef
This includes bumping meta to 1.18.1. To support flutter/flutter#168555 Change-Id: I6830a413efcf9939467e97faf58b1255d2d3d8eb Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/475760 Reviewed-by: Konstantin Shcheglov <scheglov@google.com> Commit-Queue: Samuel Rawlins <srawlins@google.com>
1 parent 3f5bac9 commit 7e5885e

8 files changed

Lines changed: 66 additions & 1 deletion

File tree

pkg/analyzer/lib/src/error/annotation_verifier.dart

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -109,6 +109,8 @@ class AnnotationVerifier {
109109
errorNode: variable,
110110
);
111111
}
112+
} else if (parent case GenericTypeAlias(functionType: var type?)) {
113+
checkType(type.returnType?.type);
112114
} else {
113115
// Warning reported by `_checkKinds`.
114116
}

pkg/analyzer/test/src/diagnostics/invalid_await_not_required_annotation_test.dart

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -99,6 +99,17 @@ int x = 0;
9999
);
100100
}
101101

102+
test_invalid_typedef_intReturnType() async {
103+
await assertErrorsInCode(
104+
'''
105+
import 'package:meta/meta.dart';
106+
@awaitNotRequired
107+
typedef Td = int Function();
108+
''',
109+
[error(diag.invalidAwaitNotRequiredAnnotation, 34, 16)],
110+
);
111+
}
112+
102113
test_valid_field_futureReturnType() async {
103114
await assertNoErrorsInCode('''
104115
import 'package:meta/meta.dart';
@@ -189,6 +200,14 @@ class D extends C {
189200
import 'package:meta/meta.dart';
190201
@awaitNotRequired
191202
Future<int> x = Future.value(7);
203+
''');
204+
}
205+
206+
test_valid_typedef_futureReturnType() async {
207+
await assertNoErrorsInCode('''
208+
import 'package:meta/meta.dart';
209+
@awaitNotRequired
210+
typedef Td = Future<void> Function();
192211
''');
193212
}
194213
}

pkg/analyzer_testing/lib/src/mock_packages/meta/meta.dart

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -124,6 +124,7 @@ class _AlwaysThrows {
124124
TargetKind.getter,
125125
TargetKind.method,
126126
TargetKind.topLevelVariable,
127+
TargetKind.typedefType,
127128
})
128129
class _AwaitNotRequired {
129130
const _AwaitNotRequired();

pkg/linter/lib/src/extensions.dart

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -369,6 +369,17 @@ extension ExpressionExtension on Expression {
369369
PropertyAccess(:var propertyName) => propertyName.element,
370370
_ => null,
371371
};
372+
373+
// This handles `p();` where `p` is a parameter typed with a typedef which
374+
// is annotated with `@awaitNotRequired`.
375+
if (this case FunctionExpressionInvocation self) {
376+
if (self.function.staticType?.alias case var alias?) {
377+
if (alias.element.hasAwaitNotRequired) {
378+
return true;
379+
}
380+
}
381+
}
382+
372383
if (element == null) return false;
373384
if (element.hasAwaitNotRequired) return true;
374385

pkg/linter/test/rules/unawaited_futures_test.dart

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -182,6 +182,20 @@ Future<int> g() => Future.value(0);
182182
''');
183183
}
184184

185+
test_functionCall_unawaited_awaitNotRequiredOnTypedef() async {
186+
await assertNoDiagnostics(r'''
187+
import 'package:meta/meta.dart';
188+
void f(C c) async {
189+
c.td();
190+
}
191+
@awaitNotRequired
192+
typedef Td = Future<void> Function();
193+
abstract class C {
194+
Td td = () async {};
195+
}
196+
''');
197+
}
198+
185199
test_functionCallInCascade() async {
186200
await assertDiagnostics(
187201
r'''
@@ -325,6 +339,19 @@ void f(Future<int> p) async {
325339
);
326340
}
327341

342+
test_parameter_unawaited_awaitNotRequiredOnTypedef() async {
343+
await assertNoDiagnostics(r'''
344+
import 'package:meta/meta.dart';
345+
346+
@awaitNotRequired
347+
typedef Td = Future<void> Function();
348+
349+
void f(Td p) async {
350+
p();
351+
}
352+
''');
353+
}
354+
328355
test_prefixExpression_unawaited() async {
329356
await assertDiagnostics(
330357
r'''

pkg/meta/CHANGELOG.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,7 @@
1+
## 1.18.1
2+
3+
- Allow `@awaitNotRequired` to annotate a typedef.
4+
15
## 1.18.0
26

37
- The `@redeclare` annotation is no longer considered experimental.

pkg/meta/lib/meta.dart

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -673,6 +673,7 @@ class _AlwaysThrows {
673673
TargetKind.getter,
674674
TargetKind.method,
675675
TargetKind.topLevelVariable,
676+
TargetKind.typedefType,
676677
})
677678
class _AwaitNotRequired {
678679
const _AwaitNotRequired();

pkg/meta/pubspec.yaml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
name: meta
22
# Note, because version `2.0.0` was mistakenly released,
33
# the next major version must be `3.x.y`.
4-
version: 1.18.0
4+
version: 1.18.1
55
description: >-
66
Annotations used to express developer intentions that can't otherwise be
77
deduced by statically analyzing source code.

0 commit comments

Comments
 (0)