Analyzer: tidy function reference parsing.

Check for odd case of attempting to type instantiate an extension (it's not supported).

Re-write some TODOs as comments.

Change-Id: I14fd2a4e21139939ca60e415be9ac31b93ea50ca
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/213240
Reviewed-by: Brian Wilkerson <brianwilkerson@google.com>
Reviewed-by: Konstantin Shcheglov <scheglov@google.com>
Commit-Queue: Samuel Rawlins <srawlins@google.com>
This commit is contained in:
Sam Rawlins 2021-09-13 15:29:39 +00:00 committed by commit-bot@chromium.org
parent d74199de8f
commit 02afb5a7f5
2 changed files with 64 additions and 5 deletions

View file

@ -387,7 +387,8 @@ class FunctionReferenceResolver {
);
if (methodElement == null) {
// TODO(srawlins): Can we get here?
// The target is known, but the method is not; [UNDEFINED_GETTER] is
// reported elsewhere.
node.staticType = DynamicTypeImpl.instance;
return;
} else {
@ -395,7 +396,7 @@ class FunctionReferenceResolver {
return;
}
} else {
// TODO(srawlins): Can we get here?
// The prefix is unknown; [UNDEFINED_IDENTIFIER] is reported elsewhere.
node.staticType = DynamicTypeImpl.instance;
return;
}
@ -440,7 +441,7 @@ class FunctionReferenceResolver {
void _resolveReceiverPrefix(
FunctionReferenceImpl node,
PrefixElement prefixElement,
PrefixedIdentifier prefix,
PrefixedIdentifierImpl prefix,
Element element,
) {
if (element is MultiplyDefinedElement) {
@ -477,10 +478,19 @@ class FunctionReferenceResolver {
name: element.name,
);
return;
} else if (element is ExtensionElement) {
prefix.identifier.staticElement = element;
prefix.identifier.staticType = DynamicTypeImpl.instance;
prefix.staticType = DynamicTypeImpl.instance;
_resolveDisallowedExpression(node, DynamicTypeImpl.instance);
return;
}
// TODO(srawlins): Report undefined prefixed identifier.
assert(
false,
'Member of prefixed element, $prefixElement, is not a class, mixin, '
'type alias, or executable element: $element (${element.runtimeType})',
);
node.staticType = DynamicTypeImpl.instance;
}
@ -590,6 +600,11 @@ class FunctionReferenceResolver {
function.staticType = element.type;
_resolve(node: node, rawType: element.type);
return;
} else if (element is ExtensionElement) {
function.staticElement = element;
function.staticType = DynamicTypeImpl.instance;
_resolveDisallowedExpression(node, DynamicTypeImpl.instance);
return;
} else {
_resolveDisallowedExpression(node, DynamicTypeImpl.instance);
return;

View file

@ -109,6 +109,50 @@ bar() {
findNode.functionReference('foo<int>;'), null, 'dynamic');
}
test_extension() async {
await assertErrorsInCode('''
extension E<T> on String {}
void foo() {
E<int>;
}
''', [
error(
CompileTimeErrorCode.DISALLOWED_TYPE_INSTANTIATION_EXPRESSION, 44, 1),
]);
var reference = findNode.functionReference('E<int>;');
assertFunctionReference(
reference,
findElement.extension_('E'),
'dynamic',
);
}
test_extension_prefixed() async {
newFile('$testPackageLibPath/a.dart', content: '''
extension E<T> on String {}
''');
await assertErrorsInCode('''
import 'a.dart' as a;
void foo() {
a.E<int>;
}
''', [
error(
CompileTimeErrorCode.DISALLOWED_TYPE_INSTANTIATION_EXPRESSION, 38, 3),
]);
assertImportPrefix(findNode.simple('a.E'), findElement.prefix('a'));
var reference = findNode.functionReference('E<int>;');
assertFunctionReference(
reference,
findElement.importFind('package:test/a.dart').extension_('E'),
'dynamic',
);
}
test_extensionGetter_extensionOverride() async {
await assertErrorsInCode('''
class A {}