Coder Social home page Coder Social logo

Comments (7)

bwilkerson avatar bwilkerson commented on July 18, 2024

@scheglov

from sdk.

lrhn avatar lrhn commented on July 18, 2024

I think the analyzer is correct, and the compilers are wrong.

Implicit call invocation/insertion is only specified to work for types with a method named call, not call getters that happen to have a function type (which this one doesn't even, it's just the type Function).

That is: The type Callable is not callable. The analyzer is correct.

See: dart-lang/language#3482, #45551, #54616, #54351

from sdk.

mmcdon20 avatar mmcdon20 commented on July 18, 2024

Also the following code compiles:

extension on String {
  void Function() get call => () => print(this);
}

void main() {
  'Hello World!'();
}

output:

Hello World!

analyzer errors:

The expression doesn't evaluate to a function, so it can't be invoked. • invocation_of_non_function_expression

from sdk.

mmcdon20 avatar mmcdon20 commented on July 18, 2024

I'll also add that this:

void main() {
  (call: print)('Hello World');
}

produces no analyzer warnings, but does not compile:

Error: The 'call' property on the record type isn't directly callable but could be invoked by `.call(...)`
  (call: print)('Hello World');
  ^

from sdk.

eernstg avatar eernstg commented on July 18, 2024

The language team decided to keep the semantics as specified (as mentioned here), that is, implicitly inserted .call invocations cannot invoke a getter.

The common front end was changed in https://dart-review.googlesource.com/c/sdk/+/346240 such that the required information is available (that is, backends can make the distinction that some invocations encoded as r.call(...) were specified as such in source code, which means that call can be a getter, or they were specified as r(...) in source code and .call was inserted implicitly, in which case call must be a method).

@johnniwinther, do those changes cover extension typed receivers as well? I'd actually expect the extension type member invocations to be processed early in the compilation pipeline such that later stages would just see an invocation of a function where the syntactic receiver is passed as an actual argument, and this might well eliminate the whole topic of .call insertion during the CFE processing...?

from sdk.

johnniwinther avatar johnniwinther commented on July 18, 2024

We have a lot of parallel code paths to handle the various calls so I would assume we just need to add some missing checks.

from sdk.

lrhn avatar lrhn commented on July 18, 2024

The last one is an analyzer error. A getter named call does not make an object callable, according to the language specification and (q.v. dart-lang/language#3482) there is no plans to change that.

The .call insertion is intended as a static, type-based feature. If you do expr(args), where expr is not of the form expr2.id (because then it's a method invocation, not a function call), then:

  • If the static type of expr is a function type, it's a plain function invocation.
  • If the static type is Function or dynamic, it's a dynamic function invocation.
  • If the static type has a call method, it invokes expr.call with the argument list of (args).
  • If the static type has a unique applicable call extension method, that is invoked with the value of expr as this and (args) as argument list.
  • Otherwise it's a compile-time error.

The current implementations fails to follow the specification in different ways.
I whipped up a test.
It shows the analyzer failing only by allowing a record call getter to be invoked.
The CFE/DDC (DartPad) fails by allowing call extension getters and extension type getters to be invoked.

I also checked the specification for dynamic function expression invocation.
If the type does not have a call method, we (should) invoke noSuchMethod with an Invocation with member name call, which isMethod and has the arguments, even if there is a call getter. That's actually pretty reasonable, and DDC does that correctly. (Haven't checked other than in DartPad yet.)

from sdk.

Related Issues (20)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.