Skip to content

Commit 87b118b

Browse files
kallentuCommit Queue
authored andcommitted
[analyzer] Dot shorthands: Error when resolving a dot shorthand invocation.
Added error code `DOT_SHORTHAND_UNDEFINED_INVOCATION` for when we are unable to resolve a dot shorthand invocation with a given context type and member name. New unit tests and multiple co19/language tests passing. Bug: #59835 Change-Id: I74fc053d668496539d88bee7d6eeee12acd9b710 Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/425145 Reviewed-by: Paul Berry <[email protected]> Commit-Queue: Kallen Tu <[email protected]> Reviewed-by: Brian Wilkerson <[email protected]>
1 parent bf16ef7 commit 87b118b

File tree

13 files changed

+962
-498
lines changed

13 files changed

+962
-498
lines changed

pkg/analysis_server/lib/src/services/correction/error_fix_status.yaml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -518,6 +518,8 @@ CompileTimeErrorCode.DOT_SHORTHAND_MISSING_CONTEXT:
518518
status: needsEvaluation
519519
CompileTimeErrorCode.DOT_SHORTHAND_UNDEFINED_GETTER:
520520
status: needsEvaluation
521+
CompileTimeErrorCode.DOT_SHORTHAND_UNDEFINED_INVOCATION:
522+
status: needsEvaluation
521523
CompileTimeErrorCode.DUPLICATE_CONSTRUCTOR_DEFAULT:
522524
status: noFix
523525
notes: |-

pkg/analyzer/lib/src/dart/resolver/instance_creation_expression_resolver.dart

Lines changed: 8 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -91,15 +91,18 @@ class InstanceCreationExpressionResolver {
9191
);
9292
}
9393
}
94-
95-
_resolveDotShorthandConstructorInvocation(
94+
} else {
95+
_resolver.errorReporter.atNode(
9696
node,
97-
contextType: contextType,
98-
dotShorthandContextType: dotShorthandContextType,
97+
CompileTimeErrorCode.DOT_SHORTHAND_MISSING_CONTEXT,
9998
);
10099
}
101100

102-
// TODO(kallentu): Report error.
101+
_resolveDotShorthandConstructorInvocation(
102+
node,
103+
contextType: contextType,
104+
dotShorthandContextType: dotShorthandContextType,
105+
);
103106
}
104107

105108
void _resolveDotShorthandConstructorInvocation(

pkg/analyzer/lib/src/dart/resolver/method_invocation_resolver.dart

Lines changed: 22 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -281,6 +281,18 @@ class MethodInvocationResolver with ScopeHelpers {
281281
contextType: contextType,
282282
);
283283
}
284+
285+
_resolver.errorReporter.atNode(
286+
node.memberName,
287+
CompileTimeErrorCode.DOT_SHORTHAND_UNDEFINED_INVOCATION,
288+
arguments: [node.memberName.name, contextType.getDisplayString()],
289+
);
290+
_setInvalidTypeResolutionForDotShorthand(
291+
node,
292+
setNameTypeToDynamic: false,
293+
whyNotPromotedArguments: whyNotPromotedArguments,
294+
contextType: contextType,
295+
);
284296
return null;
285297
}
286298

@@ -1256,13 +1268,17 @@ class MethodInvocationResolver with ScopeHelpers {
12561268
contextType: contextType,
12571269
);
12581270
} else {
1271+
_resolver.errorReporter.atNode(
1272+
nameNode,
1273+
CompileTimeErrorCode.DOT_SHORTHAND_UNDEFINED_INVOCATION,
1274+
arguments: [nameNode.name, receiver.displayName],
1275+
);
12591276
_setInvalidTypeResolutionForDotShorthand(
12601277
node,
12611278
setNameTypeToDynamic: false,
12621279
whyNotPromotedArguments: whyNotPromotedArguments,
12631280
contextType: contextType,
12641281
);
1265-
_reportInvocationOfNonFunction(nameNode);
12661282
}
12671283
return null;
12681284
}
@@ -1286,12 +1302,16 @@ class MethodInvocationResolver with ScopeHelpers {
12861302
return replacement;
12871303
}
12881304

1305+
_resolver.errorReporter.atNode(
1306+
nameNode,
1307+
CompileTimeErrorCode.DOT_SHORTHAND_UNDEFINED_INVOCATION,
1308+
arguments: [nameNode.name, receiver.displayName],
1309+
);
12891310
_setInvalidTypeResolutionForDotShorthand(
12901311
node,
12911312
whyNotPromotedArguments: whyNotPromotedArguments,
12921313
contextType: contextType,
12931314
);
1294-
_reportUndefinedMethodOrNew(receiver, nameNode);
12951315
return null;
12961316
}
12971317

pkg/analyzer/lib/src/error/codes.g.dart

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1403,11 +1403,25 @@ class CompileTimeErrorCode extends ErrorCode {
14031403
/// 1: the name of the enclosing type where the getter is being looked for
14041404
static const CompileTimeErrorCode
14051405
DOT_SHORTHAND_UNDEFINED_GETTER = CompileTimeErrorCode(
1406-
'DOT_SHORTHAND_UNDEFINED_GETTER',
1406+
'DOT_SHORTHAND_UNDEFINED_MEMBER',
14071407
"The static getter '{0}' isn't defined for the context type '{1}'.",
14081408
correctionMessage:
14091409
"Try correcting the name to the name of an existing static getter, or "
14101410
"defining a getter or field named '{0}'.",
1411+
uniqueName: 'DOT_SHORTHAND_UNDEFINED_GETTER',
1412+
);
1413+
1414+
/// Parameters:
1415+
/// 0: the name of the static method or constructor
1416+
/// 1: the name of the enclosing type where the method or constructor is being looked for
1417+
static const CompileTimeErrorCode
1418+
DOT_SHORTHAND_UNDEFINED_INVOCATION = CompileTimeErrorCode(
1419+
'DOT_SHORTHAND_UNDEFINED_MEMBER',
1420+
"The static method or constructor '{0}' isn't defined for the type '{1}'.",
1421+
correctionMessage:
1422+
"Try correcting the name to the name of an existing static method or "
1423+
"constructor, or defining a static method or constructor named '{0}'.",
1424+
uniqueName: 'DOT_SHORTHAND_UNDEFINED_INVOCATION',
14111425
);
14121426

14131427
/// No parameters.

pkg/analyzer/lib/src/error/error_code_values.g.dart

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -176,6 +176,7 @@ const List<ErrorCode> errorCodeValues = [
176176
CompileTimeErrorCode.DISALLOWED_TYPE_INSTANTIATION_EXPRESSION,
177177
CompileTimeErrorCode.DOT_SHORTHAND_MISSING_CONTEXT,
178178
CompileTimeErrorCode.DOT_SHORTHAND_UNDEFINED_GETTER,
179+
CompileTimeErrorCode.DOT_SHORTHAND_UNDEFINED_INVOCATION,
179180
CompileTimeErrorCode.DUPLICATE_CONSTRUCTOR_DEFAULT,
180181
CompileTimeErrorCode.DUPLICATE_CONSTRUCTOR_NAME,
181182
CompileTimeErrorCode.DUPLICATE_DEFINITION,

pkg/analyzer/messages.yaml

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3863,12 +3863,21 @@ CompileTimeErrorCode:
38633863
DOT_SHORTHAND_MISSING_CONTEXT:
38643864
problemMessage: "A dot shorthand can't be used where there is no context type."
38653865
DOT_SHORTHAND_UNDEFINED_GETTER:
3866+
sharedName: DOT_SHORTHAND_UNDEFINED_MEMBER
38663867
problemMessage: "The static getter '{0}' isn't defined for the context type '{1}'."
38673868
correctionMessage: "Try correcting the name to the name of an existing static getter, or defining a getter or field named '{0}'."
38683869
comment: |-
38693870
Parameters:
38703871
0: the name of the static getter
38713872
1: the name of the enclosing type where the getter is being looked for
3873+
DOT_SHORTHAND_UNDEFINED_INVOCATION:
3874+
sharedName: DOT_SHORTHAND_UNDEFINED_MEMBER
3875+
problemMessage: "The static method or constructor '{0}' isn't defined for the type '{1}'."
3876+
correctionMessage: "Try correcting the name to the name of an existing static method or constructor, or defining a static method or constructor named '{0}'."
3877+
comment: |-
3878+
Parameters:
3879+
0: the name of the static method or constructor
3880+
1: the name of the enclosing type where the method or constructor is being looked for
38723881
DUPLICATE_CONSTRUCTOR_DEFAULT:
38733882
sharedName: DUPLICATE_CONSTRUCTOR
38743883
problemMessage: The unnamed constructor is already defined.

pkg/analyzer/test/src/dart/resolution/dot_shorthand_invocation_test.dart

Lines changed: 73 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,23 @@ main() {
1717

1818
@reflectiveTest
1919
class DotShorthandInvocationResolutionTest extends PubPackageResolutionTest {
20+
test_assert_lhs() async {
21+
await assertErrorsInCode(
22+
r'''
23+
class C {
24+
final int x;
25+
const C.named(this.x);
26+
}
27+
28+
class CAssert {
29+
const CAssert.regular(C ctor)
30+
: assert(const .named(1) == ctor);
31+
}
32+
''',
33+
[error(CompileTimeErrorCode.DOT_SHORTHAND_MISSING_CONTEXT, 114, 15)],
34+
);
35+
}
36+
2037
test_basic() async {
2138
await assertNoErrorsInCode(r'''
2239
class C {
@@ -350,6 +367,62 @@ DotShorthandInvocation
350367
''');
351368
}
352369

370+
test_error_context_invalid() async {
371+
await assertErrorsInCode(
372+
r'''
373+
class C { }
374+
375+
void main() {
376+
C Function() c = .member();
377+
print(c);
378+
}
379+
''',
380+
[error(CompileTimeErrorCode.DOT_SHORTHAND_UNDEFINED_INVOCATION, 47, 6)],
381+
);
382+
}
383+
384+
test_error_context_none() async {
385+
await assertErrorsInCode(
386+
r'''
387+
void main() {
388+
var c = .member();
389+
print(c);
390+
}
391+
''',
392+
[error(CompileTimeErrorCode.DOT_SHORTHAND_UNDEFINED_INVOCATION, 25, 6)],
393+
);
394+
}
395+
396+
test_error_unresolved() async {
397+
await assertErrorsInCode(
398+
r'''
399+
class C { }
400+
401+
void main() {
402+
C c = .member();
403+
print(c);
404+
}
405+
''',
406+
[error(CompileTimeErrorCode.DOT_SHORTHAND_UNDEFINED_INVOCATION, 36, 6)],
407+
);
408+
}
409+
410+
test_error_unresolved_new() async {
411+
await assertErrorsInCode(
412+
r'''
413+
class C {
414+
C.named();
415+
}
416+
417+
void main() {
418+
C c = .new();
419+
print(c);
420+
}
421+
''',
422+
[error(CompileTimeErrorCode.DOT_SHORTHAND_UNDEFINED_INVOCATION, 49, 3)],
423+
);
424+
}
425+
353426
test_extensionType() async {
354427
await assertNoErrorsInCode(r'''
355428
extension type C(int integer) {

tests/language/dot_shorthands/constructor/constructor_error_test.dart

Lines changed: 20 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -12,27 +12,32 @@ void main() {
1212
// Using a constructor shorthand without any context.
1313

1414
var ctorNew = .new();
15-
// ^
16-
// [analyzer] unspecified
17-
// [cfe] unspecified
15+
// ^^^
16+
// [analyzer] COMPILE_TIME_ERROR.DOT_SHORTHAND_UNDEFINED_MEMBER
17+
// [cfe] No type was provided to find the dot shorthand 'new'.
1818

1919
const ctorConstNew = .new();
20-
// ^
21-
// [analyzer] unspecified
22-
// [cfe] unspecified
20+
// ^^^^^^
21+
// [analyzer] COMPILE_TIME_ERROR.CONST_INITIALIZED_WITH_NON_CONSTANT_VALUE
22+
// ^^^
23+
// [analyzer] COMPILE_TIME_ERROR.DOT_SHORTHAND_UNDEFINED_MEMBER
24+
// [cfe] No type was provided to find the dot shorthand 'new'.
2325

2426
var ctorNamed = .regular();
25-
// ^
26-
// [analyzer] unspecified
27-
// [cfe] unspecified
27+
// ^^^^^^^
28+
// [analyzer] COMPILE_TIME_ERROR.DOT_SHORTHAND_UNDEFINED_MEMBER
29+
// [cfe] No type was provided to find the dot shorthand 'regular'.
2830

2931
const ctorConstNamed = .regular();
30-
// ^
31-
// [analyzer] unspecified
32-
// [cfe] unspecified
32+
// ^^^^^^^^^^
33+
// [analyzer] COMPILE_TIME_ERROR.CONST_INITIALIZED_WITH_NON_CONSTANT_VALUE
34+
// ^^^^^^^
35+
// [analyzer] COMPILE_TIME_ERROR.DOT_SHORTHAND_UNDEFINED_MEMBER
36+
// [cfe] No type was provided to find the dot shorthand 'regular'.
3337

3438
UnnamedConstructor Function() ctorTearoff = .new;
35-
// ^
36-
// [analyzer] unspecified
37-
// [cfe] unspecified
39+
// ^^^^
40+
// [analyzer] COMPILE_TIME_ERROR.DOT_SHORTHAND_MISSING_CONTEXT
41+
// ^
42+
// [cfe] The static getter or field 'new' isn't defined for the type 'UnnamedConstructor Function()'.
3843
}

0 commit comments

Comments
 (0)