diff --git a/pkg/analyzer/lib/src/dart/ast/ast.dart b/pkg/analyzer/lib/src/dart/ast/ast.dart index 345b2abe73a..4b6454cce7f 100644 --- a/pkg/analyzer/lib/src/dart/ast/ast.dart +++ b/pkg/analyzer/lib/src/dart/ast/ast.dart @@ -10091,7 +10091,7 @@ abstract final class IndexExpression } final class IndexExpressionImpl extends ExpressionImpl - with NullShortableExpressionImpl + with NullShortableExpressionImpl, DotShorthandMixin implements IndexExpression { @override Token? period; diff --git a/pkg/analyzer/lib/src/generated/resolver.dart b/pkg/analyzer/lib/src/generated/resolver.dart index d990675180c..a851114edb7 100644 --- a/pkg/analyzer/lib/src/generated/resolver.dart +++ b/pkg/analyzer/lib/src/generated/resolver.dart @@ -3074,6 +3074,12 @@ class ResolverVisitor extends ThrowingAstVisitor TypeImpl contextType = UnknownInferredType.instance, }) { inferenceLogWriter?.enterExpression(node, contextType); + + // If [isDotShorthand] is set, cache the context type for resolution. + if (isDotShorthand(node)) { + pushDotShorthandContext(node, SharedTypeSchemaView(contextType)); + } + checkUnreachableNode(node); var target = node.target; @@ -3132,6 +3138,11 @@ class ResolverVisitor extends ThrowingAstVisitor nullShortingTermination(node, rewrittenExpression: replacement); _insertImplicitCallReference(replacement, contextType: contextType); nullSafetyDeadCodeVerifier.verifyIndexExpression(node); + + if (isDotShorthand(node)) { + popDotShorthandContext(); + } + inferenceLogWriter?.exitExpression(node); } 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 507f55e958a..2b2e6e20451 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 @@ -321,6 +321,35 @@ DotShorthandInvocation '''); } + test_equality_indexExpression() async { + await assertNoErrorsInCode(r''' +class C { + int x; + C(this.x); + static List instances() => [C(1)]; +} + +void main() { + print(C(1) == .instances()[0]); +} +'''); + + var identifier = findNode.singleDotShorthandInvocation; + assertResolvedNodeText(identifier, r''' +DotShorthandInvocation + period: . + memberName: SimpleIdentifier + token: instances + element: ::@class::C::@method::instances#element + staticType: List Function() + argumentList: ArgumentList + leftParenthesis: ( + rightParenthesis: ) + staticInvokeType: List Function() + staticType: List +'''); + } + test_extensionType() async { await assertNoErrorsInCode(r''' extension type C(int integer) { 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 2d1ab7e877e..7ebbd2de706 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 @@ -270,6 +270,31 @@ DotShorthandPropertyAccess '''); } + test_equality_indexExpression() async { + await assertNoErrorsInCode(r''' +class C { + int x; + C(this.x); + static List instances = [C(1)]; +} + +void main() { + print(C(1) == .instances[0]); +} +'''); + + var identifier = findNode.singleDotShorthandPropertyAccess; + assertResolvedNodeText(identifier, r''' +DotShorthandPropertyAccess + period: . + propertyName: SimpleIdentifier + token: instances + element: ::@class::C::@getter::instances#element + staticType: List + staticType: List +'''); + } + test_equality_pattern() async { await assertNoErrorsInCode(''' enum Color { red, blue }