Skip to content

Commit f849516

Browse files
kallentuCommit Queue
authored and
Commit Queue
committed
[analyzer] Dot shorthands: Avoid crashing with prefix and postfix operators.
When we evaluate the `target` for this `IndexExpression`, we don't cache the dot shorthand context which causes the analyzer to crash. Added a context push of the `target` (whose context is `UnknownType`) which allows the analyzer to error out without crashing. Passing co19 tests and unit tests. Bug: #59835 Change-Id: I6a19b3e92ed803a51d0cfd320df886a26a36b33d Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/426289 Commit-Queue: Kallen Tu <[email protected]> Reviewed-by: Chloe Stefantsova <[email protected]>
1 parent 701c611 commit f849516

File tree

4 files changed

+129
-4
lines changed

4 files changed

+129
-4
lines changed

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

+8-4
Original file line numberDiff line numberDiff line change
@@ -1455,10 +1455,14 @@ class ResolverVisitor extends ThrowingAstVisitor<void>
14551455
if (node is IndexExpressionImpl) {
14561456
var target = node.target;
14571457
if (target != null) {
1458-
analyzeExpression(
1459-
target,
1460-
SharedTypeSchemaView(UnknownInferredType.instance),
1461-
);
1458+
if (isDotShorthand(node)) {
1459+
// Recovery.
1460+
// It's a compile-time error to use postfix or prefix operators with
1461+
// dot shorthands. We provide an unknown type since this shouldn't be
1462+
// valid code, but we want to prevent any crashes.
1463+
pushDotShorthandContext(target, operations.unknownType);
1464+
}
1465+
analyzeExpression(target, operations.unknownType);
14621466
popRewrite();
14631467
}
14641468

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

+35
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
// for details. All rights reserved. Use of this source code is governed by a
33
// BSD-style license that can be found in the LICENSE file.
44

5+
import 'package:analyzer/src/dart/error/syntactic_errors.dart';
56
import 'package:analyzer/src/error/codes.dart';
67
import 'package:test_reflective_loader/test_reflective_loader.dart';
78

@@ -566,6 +567,40 @@ DotShorthandConstructorInvocation
566567
''');
567568
}
568569

570+
test_postfixOperator() async {
571+
await assertErrorsInCode(
572+
r'''
573+
class C {}
574+
575+
void main() {
576+
C c = .new()++;
577+
print(c);
578+
}
579+
''',
580+
[
581+
error(CompileTimeErrorCode.DOT_SHORTHAND_UNDEFINED_INVOCATION, 35, 3),
582+
error(ParserErrorCode.ILLEGAL_ASSIGNMENT_TO_NON_ASSIGNABLE, 40, 2),
583+
],
584+
);
585+
}
586+
587+
test_prefixOperator() async {
588+
await assertErrorsInCode(
589+
r'''
590+
class C {}
591+
592+
void main() {
593+
C c = ++.new();
594+
print(c);
595+
}
596+
''',
597+
[
598+
error(CompileTimeErrorCode.DOT_SHORTHAND_UNDEFINED_INVOCATION, 37, 3),
599+
error(ParserErrorCode.MISSING_ASSIGNABLE_SELECTOR, 41, 1),
600+
],
601+
);
602+
}
603+
569604
test_requiredParameters_missing() async {
570605
await assertErrorsInCode(
571606
r'''

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

+43
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
// for details. All rights reserved. Use of this source code is governed by a
33
// BSD-style license that can be found in the LICENSE file.
44

5+
import 'package:analyzer/src/dart/error/syntactic_errors.dart';
56
import 'package:analyzer/src/error/codes.dart';
67
import 'package:test_reflective_loader/test_reflective_loader.dart';
78

@@ -619,6 +620,48 @@ DotShorthandInvocation
619620
''');
620621
}
621622

623+
test_postfixOperator() async {
624+
await assertErrorsInCode(
625+
r'''
626+
class C {
627+
static C member() => C(1);
628+
int x;
629+
C(this.x);
630+
}
631+
632+
void main() {
633+
C c = .member()++;
634+
print(c);
635+
}
636+
''',
637+
[
638+
error(CompileTimeErrorCode.DOT_SHORTHAND_UNDEFINED_INVOCATION, 87, 6),
639+
error(ParserErrorCode.ILLEGAL_ASSIGNMENT_TO_NON_ASSIGNABLE, 95, 2),
640+
],
641+
);
642+
}
643+
644+
test_prefixOperator() async {
645+
await assertErrorsInCode(
646+
r'''
647+
class C {
648+
static C member() => C(1);
649+
int x;
650+
C(this.x);
651+
}
652+
653+
void main() {
654+
C c = ++.member();
655+
print(c);
656+
}
657+
''',
658+
[
659+
error(CompileTimeErrorCode.DOT_SHORTHAND_UNDEFINED_INVOCATION, 89, 6),
660+
error(ParserErrorCode.MISSING_ASSIGNABLE_SELECTOR, 96, 1),
661+
],
662+
);
663+
}
664+
622665
test_requiredParameters_missing() async {
623666
await assertErrorsInCode(
624667
r'''

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

+43
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
// for details. All rights reserved. Use of this source code is governed by a
33
// BSD-style license that can be found in the LICENSE file.
44

5+
import 'package:analyzer/src/dart/error/syntactic_errors.dart';
56
import 'package:analyzer/src/error/codes.dart';
67
import 'package:test_reflective_loader/test_reflective_loader.dart';
78

@@ -563,6 +564,48 @@ DotShorthandPropertyAccess
563564
''');
564565
}
565566

567+
test_postfixOperator() async {
568+
await assertErrorsInCode(
569+
r'''
570+
class C {
571+
static C get member => C(1);
572+
int x;
573+
C(this.x);
574+
}
575+
576+
void main() {
577+
C c = .member++;
578+
print(c);
579+
}
580+
''',
581+
[
582+
error(CompileTimeErrorCode.DOT_SHORTHAND_MISSING_CONTEXT, 88, 7),
583+
error(ParserErrorCode.ILLEGAL_ASSIGNMENT_TO_NON_ASSIGNABLE, 95, 2),
584+
],
585+
);
586+
}
587+
588+
test_prefixOperator() async {
589+
await assertErrorsInCode(
590+
r'''
591+
class C {
592+
static C get member => C(1);
593+
int x;
594+
C(this.x);
595+
}
596+
597+
void main() {
598+
C c = ++.member;
599+
print(c);
600+
}
601+
''',
602+
[
603+
error(CompileTimeErrorCode.DOT_SHORTHAND_MISSING_CONTEXT, 90, 7),
604+
error(ParserErrorCode.MISSING_ASSIGNABLE_SELECTOR, 91, 6),
605+
],
606+
);
607+
}
608+
566609
test_tearOff_constructor() async {
567610
await assertNoErrorsInCode(r'''
568611
class C1 {

0 commit comments

Comments
 (0)