error code for ambiguous extension method accesses

Change-Id: I97b0bc8ba32d1cb0ee3b361525f4c161845f1d01
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/109463
Commit-Queue: Phil Quitslund <pquitslund@google.com>
Reviewed-by: Brian Wilkerson <brianwilkerson@google.com>
This commit is contained in:
pq
2019-07-18 03:50:27 +00:00
committed by commit-bot@chromium.org
parent 63120303a7
commit 6dfd5766de
4 changed files with 54 additions and 9 deletions
+1
View File
@@ -66,6 +66,7 @@ const List<ErrorCode> errorCodeValues = const [
CompileTimeErrorCode.ABSTRACT_SUPER_MEMBER_REFERENCE,
CompileTimeErrorCode.ACCESS_PRIVATE_ENUM_FIELD,
CompileTimeErrorCode.AMBIGUOUS_EXPORT,
CompileTimeErrorCode.AMBIGUOUS_EXTENSION_METHOD_ACCESS,
CompileTimeErrorCode.AMBIGUOUS_SET_OR_MAP_LITERAL_BOTH,
CompileTimeErrorCode.AMBIGUOUS_SET_OR_MAP_LITERAL_EITHER,
CompileTimeErrorCode.ANNOTATION_WITH_NON_CLASS,
@@ -158,13 +158,12 @@ class MethodInvocationResolver {
var t1 = e1.extendedType;
var t2 = e2.extendedType;
// todo(pq): broaden platform beyond dart:core
if (t2.element.library.isDartCore) {
if (t2.element.library.isInSdk) {
// 1. T2 is declared in a platform library, and T1 is not
if (!t1.element.library.isDartCore) {
if (!t1.element.library.isInSdk) {
return -1;
}
} else if (t1.element.library.isDartCore) {
} else if (t1.element.library.isInSdk) {
return 1;
}
@@ -504,7 +503,17 @@ class MethodInvocationResolver {
ExtensionElement extension =
_chooseMostSpecificExtension(extensions, receiverType);
if (extension == null) {
// todo(pq): report an error
_setDynamicResolution(node);
_resolver.errorReporter.reportErrorForNode(
CompileTimeErrorCode.AMBIGUOUS_EXTENSION_METHOD_ACCESS,
nameNode,
[
name,
extensions[0].name,
extensions[1].name,
],
);
return;
} else {
Element member = extension.getMethod(name) ??
extension.getGetter(name) ??
+18
View File
@@ -142,6 +142,24 @@ class CompileTimeErrorCode extends ErrorCode {
correction: "Try removing the export of one of the libraries, or "
"explicitly hiding the name in one of the export directives.");
/**
* It is a compile time error if there are two applicable extensions defining
* the same member and neither is more specific than the other.
*
* Parameters:
* 0: the name of the member
* 1: the name of the first declaring extension
* 2: the name of the second declaring extension
*/
static const CompileTimeErrorCode AMBIGUOUS_EXTENSION_METHOD_ACCESS =
const CompileTimeErrorCode(
'AMBIGUOUS_EXTENSION_METHOD_ACCESS',
"A member named '{0}' is defined in extensions '{1}' and '{2}' and "
"neither is more specific.",
correction:
"Try using an extension override to specify the extension "
"you want to to be chosen.");
/**
* No parameters.
*/
@@ -60,10 +60,6 @@ f() {
expect(invocation.methodName.staticElement.library.isDartCore, isFalse);
}
test_multi_match_ambiguous() async {
// todo(pq): implement
}
test_multipleExtensions() async {
await assertNoErrorsInCode('''
class A {}
@@ -87,6 +83,27 @@ f() {
''', [StaticTypeWarningCode.UNDEFINED_METHOD]);
}
test_noMostSpecificExtension() async {
await assertErrorsInCode('''
class A { }
extension A1_Ext on A {
void a() { }
}
extension A2_Ext on A {
void a() { }
}
f() {
A a = A();
a.a();
}
''', [
error(CompileTimeErrorCode.AMBIGUOUS_EXTENSION_METHOD_ACCESS, 120, 1),
]);
}
test_one_match() async {
await assertNoErrorsInCode('''
class B { }