[analyzer] Dot shorthands: FunctionReferences have dot shorthand flag.
`FunctionReference`s like `.foo<T>` can also be dot shorthands. This CL adds the flag onto that AST. Unit test added and co19 tests that have function references are now passing. Bug: https://github.com/dart-lang/sdk/issues/59835 Change-Id: I8c85e7915b665de5c4de2b249b22c6e8d8fc364d Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/426001 Reviewed-by: Paul Berry <paulberry@google.com> Commit-Queue: Kallen Tu <kallentu@google.com>
This commit is contained in:
@@ -8700,9 +8700,10 @@ abstract final class FunctionReference
|
||||
///
|
||||
/// In error-free code, this is either a [SimpleIdentifier] (indicating a
|
||||
/// function that is in scope), a [PrefixedIdentifier] (indicating a either
|
||||
/// function imported via prefix or a static method in a class), or a
|
||||
/// function imported via prefix or a static method in a class), a
|
||||
/// [PropertyAccess] (indicating a static method in a class imported via
|
||||
/// prefix). In code with errors, this could be other kinds of expressions.
|
||||
/// prefix), or a [DotShorthandPropertyAccess] (indicating a static method in
|
||||
/// a class). In code with errors, this could be other kinds of expressions.
|
||||
/// For example, `(...)<int>` parses as a [FunctionReference] whose referent
|
||||
/// is a [ParenthesizedExpression].
|
||||
Expression get function;
|
||||
@@ -8720,6 +8721,7 @@ abstract final class FunctionReference
|
||||
}
|
||||
|
||||
final class FunctionReferenceImpl extends CommentReferableExpressionImpl
|
||||
with DotShorthandMixin
|
||||
implements FunctionReference {
|
||||
ExpressionImpl _function;
|
||||
|
||||
|
||||
@@ -2967,11 +2967,22 @@ class ResolverVisitor extends ThrowingAstVisitor<void>
|
||||
|
||||
@override
|
||||
void visitFunctionReference(
|
||||
FunctionReference node, {
|
||||
covariant FunctionReferenceImpl node, {
|
||||
TypeImpl contextType = UnknownInferredType.instance,
|
||||
}) {
|
||||
inferenceLogWriter?.enterExpression(node, contextType);
|
||||
_functionReferenceResolver.resolve(node as FunctionReferenceImpl);
|
||||
|
||||
// If [isDotShorthand] is set, cache the context type for resolution.
|
||||
if (isDotShorthand(node)) {
|
||||
pushDotShorthandContext(node, SharedTypeSchemaView(contextType));
|
||||
}
|
||||
|
||||
_functionReferenceResolver.resolve(node);
|
||||
|
||||
if (isDotShorthand(node)) {
|
||||
popDotShorthandContext();
|
||||
}
|
||||
|
||||
inferenceLogWriter?.exitExpression(node);
|
||||
}
|
||||
|
||||
|
||||
@@ -398,6 +398,38 @@ DotShorthandPropertyAccess
|
||||
''');
|
||||
}
|
||||
|
||||
test_functionReference() async {
|
||||
await assertNoErrorsInCode(r'''
|
||||
class C<T> {
|
||||
static String foo<X>() => "C<$X>";
|
||||
|
||||
@override
|
||||
bool operator ==(Object other) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
void test<T extends num>() {
|
||||
C() == .foo<T>;
|
||||
}
|
||||
|
||||
main() {
|
||||
test<int>();
|
||||
}
|
||||
''');
|
||||
|
||||
var identifier = findNode.singleDotShorthandPropertyAccess;
|
||||
assertResolvedNodeText(identifier, r'''
|
||||
DotShorthandPropertyAccess
|
||||
period: .
|
||||
propertyName: SimpleIdentifier
|
||||
token: foo
|
||||
element: <testLibraryFragment>::@class::C::@method::foo#element
|
||||
staticType: String Function<X>()
|
||||
staticType: String Function<X>()
|
||||
''');
|
||||
}
|
||||
|
||||
test_futureOr() async {
|
||||
await assertNoErrorsInCode('''
|
||||
import 'dart:async';
|
||||
|
||||
Reference in New Issue
Block a user