Skip to content
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

Dart2js not treating (a.b)() the same as a.b(). #6428

Closed
lrhn opened this issue Oct 31, 2012 · 12 comments
Closed

Dart2js not treating (a.b)() the same as a.b(). #6428

lrhn opened this issue Oct 31, 2012 · 12 comments
Assignees
Labels
area-language New language issues should be filed at https://github.com/dart-lang/language
Milestone

Comments

@lrhn
Copy link
Member

lrhn commented Oct 31, 2012

Example code:

  class C {
    noSuchMethod(m) => m;
  }

  main() {
    var c = new C();
    var r = (c.bar)();
    print(r);
  }
According to the spec, this should do the same as if "c.bar" had not been parenthesized. From the section "Function Expression Invocation": "If e_f is a property access expression, then i is treated as an ordinary method invocation". In this case "(c.bar)" is a property access. (Or is it, Gilad? Are parentheses not just grouping here?)

@kasperl
Copy link

kasperl commented Oct 31, 2012

Issue #6429 has been merged into this issue.

@gbracha
Copy link
Contributor

gbracha commented Oct 31, 2012

I believe the spec holds in this case.

@kasperl
Copy link

kasperl commented Nov 1, 2012

Could you update the bug with information about what you see and what you'd expect to see? I'm guessing it's the difference between getting an InvocationMirror that's a getter rather than a method?


Added this to the M2 milestone.

@lrhn
Copy link
Member Author

lrhn commented Nov 1, 2012

Yes, exactly.
The expected behavior is to call the noSuchMethod method on c with an InvocationMirror of the method call ".bar()". This is the behavior you get if there are no parentheses around "c.bar".
What I see is that the noSuchMethod method is called with an InvocationMirror of the getter access ".bar" (and then that mirror is attempted called with no arguments, which throws a NoSuchMethodError since the invocation mirror has no "call" method).

@rakudrama
Copy link
Member

So are you saying that the spec demands

(a.b)();

to behave differently to

var temp = a.b;
(temp)();

?
This somewhat surprising, I generally expect expressions to compose.

@kasperl
Copy link

kasperl commented Nov 2, 2012

I agree with Stephen that this is highly surprising and it certainly may trip up Dart-to-Dart translators if they aren't super careful.

@kasperl
Copy link

kasperl commented Nov 2, 2012

cc @larsbak.

@gbracha
Copy link
Contributor

gbracha commented Nov 7, 2012

The intent of the spec was exactly the opposite: to make clear that e.m(...) is not the same as (e.m)(...). That is, given e.m(...), we do not first evaluate e.m and then do a call() which is what happens if you have the parentheses, but rather do a regular method invocation. So we need to be clear that the text that says "if e_f is a property access expression" applies to e.m but not to (e.m). I'll find away to rephrase this so it does not cause such confusion.


Set owner to @gbracha.
Removed Area-Dart2JS label.
Added Area-Language, Accepted labels.

@lrhn
Copy link
Member Author

lrhn commented Nov 8, 2012

Ok, so this is not a dart2js error. Good, I'll adapt the test that depends on this.

Would it make sense to define a closurized method as delegating the call to the original object?
If you call (o.m)(42) it works the same as o.m(42) when m accepts one parameter.
If you give an incorrect number of parameters, we could then define that to work as well, so (o.m)(42,37) should work the same as o.m(42,37) and hit the noSuchMethod on o, not on (o.m).
Effectively we define o.m to be a closure that acts as if it had a
 noSuchMethod(im) {
  if (im.memberName == "call") return im.invokeOn(o);
  return super.noSuchMethod(im); // forwarding to Object.noSuchMethod.
 }
(except that it shouldn't actually have it, it should be the call method that accepts any arguments and forwards them to o.m).

That means that o.m(...) and (o.m)(...) would act the same in all cases, not just with correct parameters.

@gbracha
Copy link
Contributor

gbracha commented Nov 8, 2012

I don't think this is necessary.

@gbracha
Copy link
Contributor

gbracha commented Nov 12, 2012

I've revised the relevant text to make this clear.

@gbracha
Copy link
Contributor

gbracha commented Nov 16, 2012

Added Done label.

@lrhn lrhn added Type-Defect area-language New language issues should be filed at https://github.com/dart-lang/language labels Nov 16, 2012
@lrhn lrhn added this to the M2 milestone Nov 16, 2012
This issue was closed.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
area-language New language issues should be filed at https://github.com/dart-lang/language
Projects
None yet
Development

No branches or pull requests

5 participants