diff --git a/pkg/analyzer/lib/src/generated/resolver.dart b/pkg/analyzer/lib/src/generated/resolver.dart index 89bd309dfae..33e0c43166b 100644 --- a/pkg/analyzer/lib/src/generated/resolver.dart +++ b/pkg/analyzer/lib/src/generated/resolver.dart @@ -1455,10 +1455,14 @@ class ResolverVisitor extends ThrowingAstVisitor if (node is IndexExpressionImpl) { var target = node.target; if (target != null) { - analyzeExpression( - target, - SharedTypeSchemaView(UnknownInferredType.instance), - ); + if (isDotShorthand(node)) { + // Recovery. + // It's a compile-time error to use postfix or prefix operators with + // dot shorthands. We provide an unknown type since this shouldn't be + // valid code, but we want to prevent any crashes. + pushDotShorthandContext(target, operations.unknownType); + } + analyzeExpression(target, operations.unknownType); popRewrite(); } diff --git a/pkg/analyzer/test/src/dart/resolution/dot_shorthand_constructor_invocation_test.dart b/pkg/analyzer/test/src/dart/resolution/dot_shorthand_constructor_invocation_test.dart index 9f021b15900..e74b77864b5 100644 --- a/pkg/analyzer/test/src/dart/resolution/dot_shorthand_constructor_invocation_test.dart +++ b/pkg/analyzer/test/src/dart/resolution/dot_shorthand_constructor_invocation_test.dart @@ -2,6 +2,7 @@ // for details. All rights reserved. Use of this source code is governed by a // BSD-style license that can be found in the LICENSE file. +import 'package:analyzer/src/dart/error/syntactic_errors.dart'; import 'package:analyzer/src/error/codes.dart'; import 'package:test_reflective_loader/test_reflective_loader.dart'; @@ -566,6 +567,40 @@ DotShorthandConstructorInvocation '''); } + test_postfixOperator() async { + await assertErrorsInCode( + r''' +class C {} + +void main() { + C c = .new()++; + print(c); +} +''', + [ + error(CompileTimeErrorCode.DOT_SHORTHAND_UNDEFINED_INVOCATION, 35, 3), + error(ParserErrorCode.ILLEGAL_ASSIGNMENT_TO_NON_ASSIGNABLE, 40, 2), + ], + ); + } + + test_prefixOperator() async { + await assertErrorsInCode( + r''' +class C {} + +void main() { + C c = ++.new(); + print(c); +} +''', + [ + error(CompileTimeErrorCode.DOT_SHORTHAND_UNDEFINED_INVOCATION, 37, 3), + error(ParserErrorCode.MISSING_ASSIGNABLE_SELECTOR, 41, 1), + ], + ); + } + test_requiredParameters_missing() async { await assertErrorsInCode( r''' diff --git a/pkg/analyzer/test/src/dart/resolution/dot_shorthand_invocation_test.dart b/pkg/analyzer/test/src/dart/resolution/dot_shorthand_invocation_test.dart index 533a4c76d18..d4f53ef8556 100644 --- a/pkg/analyzer/test/src/dart/resolution/dot_shorthand_invocation_test.dart +++ b/pkg/analyzer/test/src/dart/resolution/dot_shorthand_invocation_test.dart @@ -2,6 +2,7 @@ // for details. All rights reserved. Use of this source code is governed by a // BSD-style license that can be found in the LICENSE file. +import 'package:analyzer/src/dart/error/syntactic_errors.dart'; import 'package:analyzer/src/error/codes.dart'; import 'package:test_reflective_loader/test_reflective_loader.dart'; @@ -619,6 +620,48 @@ DotShorthandInvocation '''); } + test_postfixOperator() async { + await assertErrorsInCode( + r''' +class C { + static C member() => C(1); + int x; + C(this.x); +} + +void main() { + C c = .member()++; + print(c); +} +''', + [ + error(CompileTimeErrorCode.DOT_SHORTHAND_UNDEFINED_INVOCATION, 87, 6), + error(ParserErrorCode.ILLEGAL_ASSIGNMENT_TO_NON_ASSIGNABLE, 95, 2), + ], + ); + } + + test_prefixOperator() async { + await assertErrorsInCode( + r''' +class C { + static C member() => C(1); + int x; + C(this.x); +} + +void main() { + C c = ++.member(); + print(c); +} +''', + [ + error(CompileTimeErrorCode.DOT_SHORTHAND_UNDEFINED_INVOCATION, 89, 6), + error(ParserErrorCode.MISSING_ASSIGNABLE_SELECTOR, 96, 1), + ], + ); + } + test_requiredParameters_missing() async { await assertErrorsInCode( r''' diff --git a/pkg/analyzer/test/src/dart/resolution/dot_shorthand_property_access_test.dart b/pkg/analyzer/test/src/dart/resolution/dot_shorthand_property_access_test.dart index ab2ffef63fe..b086744f6d9 100644 --- a/pkg/analyzer/test/src/dart/resolution/dot_shorthand_property_access_test.dart +++ b/pkg/analyzer/test/src/dart/resolution/dot_shorthand_property_access_test.dart @@ -2,6 +2,7 @@ // for details. All rights reserved. Use of this source code is governed by a // BSD-style license that can be found in the LICENSE file. +import 'package:analyzer/src/dart/error/syntactic_errors.dart'; import 'package:analyzer/src/error/codes.dart'; import 'package:test_reflective_loader/test_reflective_loader.dart'; @@ -563,6 +564,48 @@ DotShorthandPropertyAccess '''); } + test_postfixOperator() async { + await assertErrorsInCode( + r''' +class C { + static C get member => C(1); + int x; + C(this.x); +} + +void main() { + C c = .member++; + print(c); +} +''', + [ + error(CompileTimeErrorCode.DOT_SHORTHAND_MISSING_CONTEXT, 88, 7), + error(ParserErrorCode.ILLEGAL_ASSIGNMENT_TO_NON_ASSIGNABLE, 95, 2), + ], + ); + } + + test_prefixOperator() async { + await assertErrorsInCode( + r''' +class C { + static C get member => C(1); + int x; + C(this.x); +} + +void main() { + C c = ++.member; + print(c); +} +''', + [ + error(CompileTimeErrorCode.DOT_SHORTHAND_MISSING_CONTEXT, 90, 7), + error(ParserErrorCode.MISSING_ASSIGNABLE_SELECTOR, 91, 6), + ], + ); + } + test_tearOff_constructor() async { await assertNoErrorsInCode(r''' class C1 {