Skip to content

Commit eceb378

Browse files
author
Dart CI
committed
Version 3.11.0-87.0.dev
Merge fc8b3d7 into dev
2 parents 2e9ae2a + fc8b3d7 commit eceb378

32 files changed

+2394
-1758
lines changed

pkg/analysis_server/lib/src/services/completion/dart/feature_computer.dart

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -626,6 +626,21 @@ class _ContextTypeVisitor extends SimpleAstVisitor<DartType> {
626626
@override
627627
DartType? visitBinaryExpression(BinaryExpression node) {
628628
if (node.operator.end <= offset) {
629+
if (node.operator.type == TokenType.EQ_EQ ||
630+
node.operator.type == TokenType.BANG_EQ_EQ) {
631+
// TODO(kallentu): Fix the parser implementation where dot shorthand
632+
// const constructor declarations recover with a wrapping function
633+
// expression invocation and then remove this.
634+
var rightOperand = node.rightOperand;
635+
if (rightOperand is FunctionExpressionInvocation &&
636+
rightOperand.function is DotShorthandMixin) {
637+
rightOperand = rightOperand.function;
638+
}
639+
if (rightOperand is DotShorthandMixin && rightOperand.isDotShorthand) {
640+
return node.leftOperand.staticType;
641+
}
642+
}
643+
629644
return node.rightOperand.correspondingParameter?.type;
630645
}
631646
return _visitParent(node);
@@ -648,6 +663,11 @@ class _ContextTypeVisitor extends SimpleAstVisitor<DartType> {
648663
}
649664
}
650665

666+
@override
667+
DartType? visitConstantPattern(ConstantPattern node) {
668+
return _visitParent(node);
669+
}
670+
651671
@override
652672
DartType? visitConstructorFieldInitializer(ConstructorFieldInitializer node) {
653673
if (node.equals.end <= offset) {
@@ -823,6 +843,21 @@ class _ContextTypeVisitor extends SimpleAstVisitor<DartType> {
823843
return null;
824844
}
825845

846+
@override
847+
DartType? visitGuardedPattern(GuardedPattern node) {
848+
if (node.parent
849+
case SwitchExpressionCase(parent: SwitchExpression(:var expression)) ||
850+
SwitchPatternCase(parent: SwitchStatement(:var expression))) {
851+
var when = node.whenClause;
852+
if (when != null && range.startEnd(when, node).contains(offset)) {
853+
return typeProvider.boolType;
854+
} else {
855+
return expression.staticType;
856+
}
857+
}
858+
return null;
859+
}
860+
826861
@override
827862
DartType? visitIfElement(IfElement node) {
828863
if (range
@@ -1391,6 +1426,10 @@ extension on ArgumentList {
13911426
case ConstructorElement constructorElement) {
13921427
return constructorElement.type;
13931428
}
1429+
} else if (parent is SuperConstructorInvocation) {
1430+
if (parent.element case ConstructorElement constructorElement) {
1431+
return constructorElement.type;
1432+
}
13941433
}
13951434
return null;
13961435
}

pkg/analysis_server/lib/src/services/completion/dart/in_scope_completion_pass.dart

Lines changed: 11 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -951,6 +951,7 @@ class InScopeCompletionPass extends SimpleAstVisitor<void> {
951951
var period = node.period;
952952
if (offset >= period.end && offset <= node.constructorName.end) {
953953
var contextType = _computeContextType(node);
954+
contextType = _resolveFutureOrType(contextType);
954955
if (contextType is! InterfaceType) return;
955956
declarationHelper(
956957
mustBeConstant: node.isConst,
@@ -965,6 +966,7 @@ class InScopeCompletionPass extends SimpleAstVisitor<void> {
965966
var period = node.period;
966967
if (offset >= period.end && offset <= node.memberName.end) {
967968
var contextType = _computeContextType(node);
969+
contextType = _resolveFutureOrType(contextType);
968970
if (contextType == null) return;
969971

970972
var element = contextType.element;
@@ -981,6 +983,7 @@ class InScopeCompletionPass extends SimpleAstVisitor<void> {
981983
@override
982984
void visitDotShorthandPropertyAccess(DotShorthandPropertyAccess node) {
983985
var contextType = _computeContextType(node);
986+
contextType = _resolveFutureOrType(contextType);
984987
if (contextType == null) return;
985988

986989
var element = contextType.element;
@@ -4086,6 +4089,13 @@ class InScopeCompletionPass extends SimpleAstVisitor<void> {
40864089
return 'ArgumentList_${context}_$argumentKind';
40874090
}
40884091

4092+
DartType? _resolveFutureOrType(DartType? contextType) {
4093+
if (contextType is InterfaceType && contextType.isDartAsyncFutureOr) {
4094+
return contextType.typeArguments.firstOrNull;
4095+
}
4096+
return contextType;
4097+
}
4098+
40894099
/// Suggests overrides in the context of the given [element].
40904100
///
40914101
/// If the budget has been exceeded, then the results are marked as incomplete
@@ -4114,9 +4124,7 @@ class InScopeCompletionPass extends SimpleAstVisitor<void> {
41144124
required RecordLiteral? recordLiteral,
41154125
required bool isNewField,
41164126
}) {
4117-
if (contextType != null && (contextType.isDartAsyncFutureOr)) {
4118-
contextType = (contextType as InterfaceType).typeArguments.firstOrNull;
4119-
}
4127+
contextType = _resolveFutureOrType(contextType);
41204128
RecordType recordType;
41214129
if (contextType is RecordType) {
41224130
recordType = contextType;

pkg/analysis_server/test/services/completion/dart/location/dot_shorthand_constructor_invocation_test.dart

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,44 @@ suggestions
3636
''');
3737
}
3838

39+
Future<void> test_constructor_const_equality() async {
40+
allowedIdentifiers = {'named', 'notConstant'};
41+
await computeSuggestions('''
42+
class C {
43+
const C.named();
44+
C.notConstant();
45+
}
46+
void f() {
47+
print(C() == const .^);
48+
}
49+
''');
50+
assertResponse(r'''
51+
suggestions
52+
named
53+
kind: constructorInvocation
54+
''');
55+
}
56+
57+
Future<void> test_constructor_const_equality_withPrefix() async {
58+
allowedIdentifiers = {'named', 'notConstant'};
59+
await computeSuggestions('''
60+
class C {
61+
const C.named();
62+
C.notConstant();
63+
}
64+
void f() {
65+
print(C.named() == const .n^);
66+
}
67+
''');
68+
assertResponse(r'''
69+
replacement
70+
left: 1
71+
suggestions
72+
named
73+
kind: constructorInvocation
74+
''');
75+
}
76+
3977
Future<void> test_constructor_const_withPrefix() async {
4078
allowedIdentifiers = {'named', 'notConstant'};
4179
await computeSuggestions('''

pkg/analysis_server/test/services/completion/dart/location/dot_shorthand_invocation_test.dart

Lines changed: 85 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,25 @@ suggestions
3434
''');
3535
}
3636

37+
Future<void> test_constructor_class_named_equality_withPrefix() async {
38+
allowedIdentifiers = {'named'};
39+
await computeSuggestions('''
40+
class C {
41+
C.named();
42+
}
43+
void f() {
44+
print(C.named() == .n^);
45+
}
46+
''');
47+
assertResponse(r'''
48+
replacement
49+
left: 1
50+
suggestions
51+
named
52+
kind: constructorInvocation
53+
''');
54+
}
55+
3756
Future<void> test_constructor_class_unnamed() async {
3857
allowedIdentifiers = {'new'};
3958
await computeSuggestions('''
@@ -49,6 +68,21 @@ suggestions
4968
''');
5069
}
5170

71+
Future<void> test_constructor_class_unnamed_equality() async {
72+
allowedIdentifiers = {'new'};
73+
await computeSuggestions('''
74+
class C {}
75+
void f() {
76+
print(C() == .^);
77+
}
78+
''');
79+
assertResponse(r'''
80+
suggestions
81+
new
82+
kind: constructorInvocation
83+
''');
84+
}
85+
5286
Future<void> test_constructor_class_withParentheses() async {
5387
allowedIdentifiers = {'named'};
5488
await computeSuggestions('''
@@ -181,6 +215,21 @@ suggestions
181215
''');
182216
}
183217

218+
Future<void> test_constructor_extensionType_unnamed_equality() async {
219+
allowedIdentifiers = {'new'};
220+
await computeSuggestions('''
221+
extension type C(int x) {}
222+
void f() {
223+
print(C() == .^);
224+
}
225+
''');
226+
assertResponse(r'''
227+
suggestions
228+
new
229+
kind: constructorInvocation
230+
''');
231+
}
232+
184233
Future<void> test_constructor_extensionType_withPrefix_named() async {
185234
allowedIdentifiers = {'named'};
186235
await computeSuggestions('''
@@ -281,6 +330,24 @@ suggestions
281330
''');
282331
}
283332

333+
Future<void> test_method_class_equality() async {
334+
allowedIdentifiers = {'method', 'notStatic'};
335+
await computeSuggestions('''
336+
class C {
337+
static C method() => C();
338+
C notStatic() => C();
339+
}
340+
void f() {
341+
print(C() == .^);
342+
}
343+
''');
344+
assertResponse(r'''
345+
suggestions
346+
method
347+
kind: methodInvocation
348+
''');
349+
}
350+
284351
Future<void> test_method_class_withParentheses() async {
285352
allowedIdentifiers = {'method', 'notStatic'};
286353
await computeSuggestions('''
@@ -338,6 +405,24 @@ suggestions
338405
''');
339406
}
340407

408+
Future<void> test_method_extensionType_equality() async {
409+
allowedIdentifiers = {'method', 'notStatic'};
410+
await computeSuggestions('''
411+
extension type C(int x) {
412+
static C method() => C(1);
413+
C notStatic() => C(1);
414+
}
415+
void f() {
416+
print(C(1) == .^);
417+
}
418+
''');
419+
assertResponse(r'''
420+
suggestions
421+
method
422+
kind: methodInvocation
423+
''');
424+
}
425+
341426
Future<void> test_method_extensionType_withPrefix() async {
342427
allowedIdentifiers = {'method', 'anotherMethod', 'notStatic'};
343428
await computeSuggestions('''

0 commit comments

Comments
 (0)