-
Notifications
You must be signed in to change notification settings - Fork 205
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Do extensions on a class apply to this
within that class?
#470
Comments
Based on the second to last paragraph of this section I believe that the answer is "yes", though it's not 100% clear that that paragraph was intended to be talking about references inside of classes instead of just inside of classes. So, yes. |
If I'm understanding that section correctly, then references to And if there are conflicting extensions of the extended type, then it's an error (as opposed to favoring the member from the enclosing extension). |
That is correct. But note that if we write that as just |
We need to make a small adjustment here regarding the forms that do not have an explicit
That's true, given the specification of which scopes exist and how they are nested inside each other. However, the current rules governing resolution of an identifier reference (static part here, dynamic part here) specify that a reference The same thing applies to unqualified function invocations (here): We check that a number of criteria don't apply ( However, I believe that we agree that we want these rules to be able to select the instance member as if by lexical scoping. I gave a draft specification of how we could achieve this in #328. That proposal is aimed at specifying the meaning of a declaration named So for the original question in this issue, 'Do extensions on a class apply to |
I don't have an opinion about which order of lookup we use, but I do think it would be confusing to users if the lookup behaved differently in extensions than it does in classes. I'll proceed for the time being assuming that |
But if you use the current rules for unqualified function invocations in an extension method body then you will transform In a class there is no such discrepancy because the transformation from (The feature spec uses the phrase 'instance member of the extension' many times. We may get around this discrepancy by saying that they are not instance methods, but if we call them 'extension methods' or something like that then we still need to change the rules about unqualified function invocations and identifier references in order to say what to do when the declaration with the requested name turns out to be an 'extension method'; and as long as they are called 'instance methods' then our current rules are applicable, but they will give rise to the transformation from |
I obviously haven't thought about it as deeply as you have, but why do you say that it should? Consider this simple case, under the assumption that unqualified references to extension members are always bound to the extension member even when they're implemented in the extended class:
In this case, I can see why these might seem like the right semantics. It would be confusing for But consider a slightly more complex case, under the same assumption:
Isn't it even more confusing for I think one downside to performing local lookup inside the extension is that it produces the same behavior that a user would expect if members in extensions could override members in the extended class. But members in extensions don't override the members in the extended class and I'm concerned that this might cause some users to think they can. If we changed the semantics so that lookup works the same both inside and outside the extension, even though it would be confusing for the first example to print 'C, C', I think it would be easier overall for users because they wouldn't have to remember that there are two different lookup algorithms. |
The reason why I said that it should resolve to the
.. so
If the rule had been "transform the unqualified Lasse and I have discussed this topic area several times—starting at the time when I wrote #328, where I wanted to make sure that we maintain the existing rationale for lookups: "The nearest lexically visible declaration wins." That is true today: If the nearest lexically visible declaration is top-level, static, or local then we just use that; otherwise we transform (It will also ensure that we can access an inherited member when there is no declaration named I'm just pointing out that we need to adjust the rules for identifier reference resolution and unqualified function invocation resolution in order to preserve that property when we add With respect to the example: class C {
String get name => 'C';
String get displayName => name;
}
extension E on C {
String get name => 'E';
void printNameTwice() {
print('$name, $displayName');
}
} I believe that "the nearest lexically visible declaration wins" is a meaningful and understandable property to maintain for our detailed name resolution rules: When the developer explicitly writes |
Thanks! I think I understand much better now. I was confused before and thought you were saying something different. |
Given the following code:
is the invocation of
methodOnExtension
valid?I'm guessing the answer is "yes" because the target of the invocation is
this
, which matches the type being extended byE
.The text was updated successfully, but these errors were encountered: