Skip to content
This repository was archived by the owner on Feb 25, 2025. It is now read-only.

Commit 41e17af

Browse files
author
Dart CI
committed
Version 2.18.0-179.0.dev
Merge commit '57b192f3a63ac109cd7550071c52cec69e637aeb' into 'dev'
2 parents e7281c5 + 57b192f commit 41e17af

File tree

8 files changed

+178
-15
lines changed

8 files changed

+178
-15
lines changed

pkg/analysis_server/lib/src/services/correction/dart/add_await.dart

Lines changed: 44 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,15 +4,31 @@
44

55
import 'package:analysis_server/src/services/correction/dart/abstract_producer.dart';
66
import 'package:analysis_server/src/services/correction/fix.dart';
7+
import 'package:analyzer/dart/ast/ast.dart';
8+
import 'package:analyzer/dart/element/type.dart';
79
import 'package:analyzer_plugin/utilities/change_builder/change_builder_core.dart';
810
import 'package:analyzer_plugin/utilities/fixes/fixes.dart';
11+
import 'package:collection/collection.dart';
912

1013
class AddAwait extends CorrectionProducer {
14+
/// The kind of correction to be made.
15+
final _CorrectionKind _correctionKind;
16+
1117
@override
12-
bool get canBeAppliedInBulk => true;
18+
bool canBeAppliedInBulk;
1319

1420
@override
15-
bool get canBeAppliedToFile => true;
21+
bool canBeAppliedToFile;
22+
23+
AddAwait.nonBool()
24+
: _correctionKind = _CorrectionKind.nonBool,
25+
canBeAppliedInBulk = false,
26+
canBeAppliedToFile = false;
27+
28+
AddAwait.unawaited()
29+
: _correctionKind = _CorrectionKind.unawaited,
30+
canBeAppliedInBulk = true,
31+
canBeAppliedToFile = true;
1632

1733
@override
1834
FixKind get fixKind => DartFixKind.ADD_AWAIT;
@@ -22,8 +38,34 @@ class AddAwait extends CorrectionProducer {
2238

2339
@override
2440
Future<void> compute(ChangeBuilder builder) async {
41+
if (_correctionKind == _CorrectionKind.unawaited) {
42+
await _addAwait(builder);
43+
} else if (_correctionKind == _CorrectionKind.nonBool) {
44+
await _computeNonBool(builder);
45+
}
46+
}
47+
48+
Future<void> _addAwait(ChangeBuilder builder) async {
2549
await builder.addDartFileEdit(file, (builder) {
2650
builder.addSimpleInsertion(node.offset, 'await ');
2751
});
2852
}
53+
54+
Future<void> _computeNonBool(ChangeBuilder builder) async {
55+
var expr = node;
56+
if (expr is! Expression) return;
57+
var staticType = expr.staticType;
58+
if (staticType is! ParameterizedType) return;
59+
60+
if (staticType.isDartAsyncFuture &&
61+
staticType.typeArguments.firstOrNull?.isDartCoreBool == true) {
62+
await _addAwait(builder);
63+
}
64+
}
65+
}
66+
67+
/// The kinds of corrections supported by [AddAwait].
68+
enum _CorrectionKind {
69+
unawaited,
70+
nonBool,
2971
}

pkg/analysis_server/lib/src/services/correction/dart/remove_type_annotation.dart

Lines changed: 45 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -49,8 +49,8 @@ class RemoveTypeAnnotation extends CorrectionProducer {
4949
Future<void> _removeFromDeclarationList(
5050
ChangeBuilder builder, VariableDeclarationList declarationList) async {
5151
// we need a type
52-
var typeNode = declarationList.type;
53-
if (typeNode == null) {
52+
var type = declarationList.type;
53+
if (type == null) {
5454
return;
5555
}
5656
// ignore if an incomplete variable declaration
@@ -63,19 +63,60 @@ class RemoveTypeAnnotation extends CorrectionProducer {
6363
if (selectionOffset > firstVariable.name.end) {
6464
return;
6565
}
66+
67+
var initializer = firstVariable.initializer;
6668
// The variable must have an initializer, otherwise there is no other
6769
// source for its type.
68-
if (firstVariable.initializer == null) {
70+
if (initializer == null) {
71+
return;
72+
}
73+
74+
String? typeArgumentsText;
75+
int? typeArgumentsOffset;
76+
if (type is NamedType) {
77+
var typeArguments = type.typeArguments;
78+
if (typeArguments != null) {
79+
if (initializer is CascadeExpression) {
80+
initializer = initializer.target;
81+
}
82+
if (initializer is TypedLiteral) {
83+
if (initializer.typeArguments == null) {
84+
typeArgumentsText = utils.getNodeText(typeArguments);
85+
if (initializer is ListLiteral) {
86+
typeArgumentsOffset = initializer.leftBracket.offset;
87+
} else if (initializer is SetOrMapLiteral) {
88+
typeArgumentsOffset = initializer.leftBracket.offset;
89+
} else {
90+
throw StateError('Unhandled subclass of TypedLiteral');
91+
}
92+
}
93+
} else if (initializer is InstanceCreationExpression) {
94+
if (initializer.constructorName.type.typeArguments == null) {
95+
typeArgumentsText = utils.getNodeText(typeArguments);
96+
typeArgumentsOffset = initializer.constructorName.type.end;
97+
}
98+
}
99+
}
100+
}
101+
if (initializer is SetOrMapLiteral &&
102+
initializer.typeArguments == null &&
103+
typeArgumentsText == null) {
104+
// This is to prevent the fix from converting a valid map or set literal
105+
// into an ambiguous literal. We could apply this in more places
106+
// by examining the elements of the collection.
69107
return;
70108
}
71109
var keyword = declarationList.keyword;
72110
await builder.addDartFileEdit(file, (builder) {
73-
var typeRange = range.startStart(typeNode, firstVariable);
111+
var typeRange = range.startStart(type, firstVariable);
74112
if (keyword != null && keyword.lexeme != 'var') {
75113
builder.addSimpleReplacement(typeRange, '');
76114
} else {
77115
builder.addSimpleReplacement(typeRange, 'var ');
78116
}
117+
if (typeArgumentsText != null && typeArgumentsOffset != null) {
118+
builder.addSimpleInsertion(typeArgumentsOffset, typeArgumentsText);
119+
}
79120
});
80121
}
81122

pkg/analysis_server/lib/src/services/correction/dart/replace_with_var.dart

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -64,6 +64,8 @@ class ReplaceWithVar extends CorrectionProducer {
6464
typeArgumentsOffset = initializer.leftBracket.offset;
6565
} else if (initializer is SetOrMapLiteral) {
6666
typeArgumentsOffset = initializer.leftBracket.offset;
67+
} else {
68+
throw StateError('Unhandled subclass of TypedLiteral');
6769
}
6870
}
6971
} else if (initializer is InstanceCreationExpression) {
@@ -77,9 +79,9 @@ class ReplaceWithVar extends CorrectionProducer {
7779
if (initializer is SetOrMapLiteral &&
7880
initializer.typeArguments == null &&
7981
typeArgumentsText == null) {
80-
// TODO(brianwilkerson) This is to prevent the fix from converting a
81-
// valid map or set literal into an ambiguous literal. We could apply
82-
// this in more places by examining the elements of the collection.
82+
// This is to prevent the fix from converting a valid map or set literal
83+
// into an ambiguous literal. We could apply this in more places
84+
// by examining the elements of the collection.
8385
return;
8486
}
8587
await builder.addDartFileEdit(file, (builder) {

pkg/analysis_server/lib/src/services/correction/fix_internal.dart

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -621,7 +621,7 @@ class FixProcessor extends BaseProcessor {
621621
RemoveTypeAnnotation.new,
622622
],
623623
LintNames.unawaited_futures: [
624-
AddAwait.new,
624+
AddAwait.unawaited,
625625
],
626626
LintNames.unnecessary_brace_in_string_interps: [
627627
RemoveInterpolationBraces.new,
@@ -1010,6 +1010,7 @@ class FixProcessor extends BaseProcessor {
10101010
],
10111011
CompileTimeErrorCode.NON_BOOL_CONDITION: [
10121012
AddNeNull.new,
1013+
AddAwait.nonBool,
10131014
],
10141015
CompileTimeErrorCode.NON_CONST_GENERATIVE_ENUM_CONSTRUCTOR: [
10151016
AddConst.new,

pkg/analysis_server/test/src/services/correction/assist/remove_type_annotation_test.dart

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,45 @@ class A {
5454
await assertNoAssistAt('v');
5555
}
5656

57+
Future<void> test_generic_instanceCreation_withoutArguments() async {
58+
await resolveTestCode('''
59+
C<int> c = C();
60+
class C<T> {}
61+
''');
62+
await assertHasAssistAt('c = ', '''
63+
var c = C<int>();
64+
class C<T> {}
65+
''');
66+
}
67+
68+
Future<void> test_generic_listLiteral() async {
69+
await resolveTestCode('''
70+
List<int> l = [];
71+
''');
72+
await assertHasAssistAt('l = ', '''
73+
var l = <int>[];
74+
''');
75+
}
76+
77+
Future<void> test_generic_setLiteral_ambiguous() async {
78+
await resolveTestCode('''
79+
Set f() {
80+
/*caret*/Set s = {};
81+
return s;
82+
}
83+
''');
84+
await assertNoAssist();
85+
}
86+
87+
Future<void> test_generic_setLiteral_cascade() async {
88+
await resolveTestCode('''
89+
Set<String> s = {}..addAll([]);
90+
''');
91+
await assertHasAssistAt('s = ', '''
92+
var s = <String>{}..addAll([]);
93+
''');
94+
}
95+
5796
Future<void> test_instanceCreation_freeStanding() async {
5897
await resolveTestCode('''
5998
class A {}

pkg/analysis_server/test/src/services/correction/fix/add_await_test.dart

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -67,4 +67,35 @@ void f() async {
6767
}
6868
''');
6969
}
70+
71+
Future<void> test_nonBoolCondition_futureBool() async {
72+
await resolveTestCode('''
73+
Future<bool> doSomething() async => true;
74+
75+
Future<void> f() async {
76+
if (doSomething()) {
77+
}
78+
}
79+
''');
80+
await assertHasFix('''
81+
Future<bool> doSomething() async => true;
82+
83+
Future<void> f() async {
84+
if (await doSomething()) {
85+
}
86+
}
87+
''');
88+
}
89+
90+
Future<void> test_nonBoolCondition_futureInt() async {
91+
await resolveTestCode('''
92+
Future<int> doSomething() async => 0;
93+
94+
Future<void> f() async {
95+
if (doSomething()) {
96+
}
97+
}
98+
''');
99+
await assertNoFix();
100+
}
70101
}

pkg/analyzer/lib/src/lint/linter.dart

Lines changed: 11 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ import 'package:analyzer/dart/element/element.dart';
1313
import 'package:analyzer/dart/element/scope.dart';
1414
import 'package:analyzer/dart/element/type_provider.dart';
1515
import 'package:analyzer/dart/element/type_system.dart';
16+
import 'package:analyzer/diagnostic/diagnostic.dart';
1617
import 'package:analyzer/error/error.dart';
1718
import 'package:analyzer/error/listener.dart';
1819
import 'package:analyzer/file_system/file_system.dart' as file_system;
@@ -636,25 +637,31 @@ abstract class LintRule extends Linter implements Comparable<LintRule> {
636637

637638
void reportLint(AstNode? node,
638639
{List<Object> arguments = const [],
640+
List<DiagnosticMessage>? contextMessages,
639641
ErrorCode? errorCode,
640642
bool ignoreSyntheticNodes = true}) {
641643
if (node != null && (!node.isSynthetic || !ignoreSyntheticNodes)) {
642-
reporter.reportErrorForNode(errorCode ?? lintCode, node, arguments);
644+
reporter.reportErrorForNode(
645+
errorCode ?? lintCode, node, arguments, contextMessages);
643646
}
644647
}
645648

646649
void reportLintForOffset(int offset, int length,
647-
{List<Object> arguments = const [], ErrorCode? errorCode}) {
650+
{List<Object> arguments = const [],
651+
List<DiagnosticMessage>? contextMessages,
652+
ErrorCode? errorCode}) {
648653
reporter.reportErrorForOffset(
649-
errorCode ?? lintCode, offset, length, arguments);
654+
errorCode ?? lintCode, offset, length, arguments, contextMessages);
650655
}
651656

652657
void reportLintForToken(Token? token,
653658
{List<Object> arguments = const [],
659+
List<DiagnosticMessage>? contextMessages,
654660
ErrorCode? errorCode,
655661
bool ignoreSyntheticTokens = true}) {
656662
if (token != null && (!token.isSynthetic || !ignoreSyntheticTokens)) {
657-
reporter.reportErrorForToken(errorCode ?? lintCode, token, arguments);
663+
reporter.reportErrorForToken(
664+
errorCode ?? lintCode, token, arguments, contextMessages);
658665
}
659666
}
660667

tools/VERSION

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,5 +27,5 @@ CHANNEL dev
2727
MAJOR 2
2828
MINOR 18
2929
PATCH 0
30-
PRERELEASE 178
30+
PRERELEASE 179
3131
PRERELEASE_PATCH 0

0 commit comments

Comments
 (0)