This changes wrapInCompileTimeError so we are certain that
compile-time errors are reported before the erroneous nodes.
We want to preserve erroneous nodes as, long term, this should help
with code completion.
Also introduce a located version as my next CL I'll have slightly
more accurate locations.
Change-Id: Id83d4b7a7d4fe260916816d72fac331251bad948
Reviewed-on: https://dart-review.googlesource.com/50422
Commit-Queue: Peter von der Ahé <ahe@google.com>
Reviewed-by: Aske Simon Christensen <askesc@google.com>
It complicates the intermediate language, none of the back ends are
using it, and it's not something that we want transformation writers
and code generators to deal with.
Change-Id: Ic79f7935dd8619bd233346bb25947e864f38a104
Reviewed-on: https://dart-review.googlesource.com/50440
Commit-Queue: Kevin Millikin <kmillikin@google.com>
Reviewed-by: Samir Jindel <sjindel@google.com>
We want the implicit tear-off of a `call` method to succeed even if
the value is `null`, so we need the implicit tear-off to be equivalent
to `?.call`.
Change-Id: I5134858b84e501081a52d59b78b101597bdfcc4a
Reviewed-on: https://dart-review.googlesource.com/43480
Reviewed-by: Dmitry Stefantsov <dmitryas@google.com>
Commit-Queue: Paul Berry <paulberry@google.com>
Original description:
Change front_end handling of callable classes.
This CL is the first in a series of CLs to change the handling of
callable classes in Dart 2.0.
For purposes of this description, a "callable class" is a class whose
interface contains a `.call` method.
In Dart 1.0, a callable class was considered to be a subtype of the
`.call` method's function type. This allowed the user to create
custom objects with similar behavior to closures, but with additional
fields and methods.
In Dart 2.0, a callable class is just an ordinary class, with no
subtype relation to any particular function type. (Note however that
it is still permissible for a class to declare that it "implements
Function").
To reduce the amount of code broken by this change, a piece of
syntactic sugar is being added: if an expression whose static type is
a callable class appears where a function type is expected, an
implicit tear-off of the `.call` method is inserted.
Note that it is still possible at compile time to invoke an expression
whose static type is a callable class, and it is still possible at
runtime to invoke an expression whose runtime type is a callable
class; in both cases, this is considered an implicit invocation of the
class's `.call` method. This is unchanged from Dart 1.0 behavior.
This CL introduces test cases for the new behavior, and implements the
implicit tear-off of `.call` in the front end.
Still to be implemented in future CLs:
- Spec text needs to be written.
- DDC/analyzer code needs to be written to perform implicit tear-offs
of `.call`.
- The subtyping algorithm in DDC, analyzer, VM, and dart2js needs to
be changed so that callable classes are no longer considered
subtypes of any particular function type.
- A small corner case involving type parameters still needs to be
addressed (see TODO in
pkg/front_end/lib/src/fasta/type_inference/type_inferrer.dart).
Fixes#32064.
Change-Id: I0d397c608321e25ba42cc02aa8a516aa77aa7c9d
Reviewed-on: https://dart-review.googlesource.com/41280
Reviewed-by: Vyacheslav Egorov <vegorov@google.com>
Commit-Queue: Paul Berry <paulberry@google.com>
This reverts commit f0a6330db0.
Reason for revert: Broken bots
Original change's description:
> Change front_end handling of callable classes.
>
> This CL is the first in a series of CLs to change the handling of
> callable classes in Dart 2.0.
>
> For purposes of this description, a "callable class" is a class whose
> interface contains a `.call` method.
>
> In Dart 1.0, a callable class was considered to be a subtype of the
> `.call` method's function type. This allowed the user to create
> custom objects with similar behavior to closures, but with additional
> fields and methods.
>
> In Dart 2.0, a callable class is just an ordinary class, with no
> subtype relation to any particular function type. (Note however that
> it is still permissible for a class to declare that it "implements
> Function").
>
> To reduce the amount of code broken by this change, a piece of
> syntactic sugar is being added: if an expression whose static type is
> a callable class appears where a function type is expected, an
> implicit tear-off of the `.call` method is inserted.
>
> Note that it is still possible at compile time to invoke an expression
> whose static type is a callable class, and it is still possible at
> runtime to invoke an expression whose runtime type is a callable
> class; in both cases, this is considered an implicit invocation of the
> class's `.call` method. This is unchanged from Dart 1.0 behavior.
>
> This CL introduces test cases for the new behavior, and implements the
> implicit tear-off of `.call` in the front end.
>
> Still to be implemented in future CLs:
>
> - Spec text needs to be written.
>
> - DDC/analyzer code needs to be written to perform implicit tear-offs
> of `.call`.
>
> - The subtyping algorithm in DDC, analyzer, VM, and dart2js needs to
> be changed so that callable classes are no longer considered
> subtypes of any particular function type.
>
> - A small corner case involving type parameters still needs to be
> addressed (see TODO in
> pkg/front_end/lib/src/fasta/type_inference/type_inferrer.dart).
>
> Fixes#32064.
>
> Change-Id: I6a86491047ae467a5e767cb3cc7cecb570b29308
> Reviewed-on: https://dart-review.googlesource.com/40508
> Commit-Queue: Paul Berry <paulberry@google.com>
> Reviewed-by: Kevin Millikin <kmillikin@google.com>
> Reviewed-by: Leaf Petersen <leafp@google.com>
> Reviewed-by: Erik Ernst <eernst@google.com>
TBR=paulberry@google.com,lrn@google.com,leafp@google.com,dmitryas@google.com,eernst@google.com,kmillikin@google.com
Change-Id: Ia3d3a6e46ceee2b2c55938bec95d09d50bbf06a7
No-Presubmit: true
No-Tree-Checks: true
No-Try: true
Reviewed-on: https://dart-review.googlesource.com/41240
Reviewed-by: Paul Berry <paulberry@google.com>
Commit-Queue: Paul Berry <paulberry@google.com>
This CL is the first in a series of CLs to change the handling of
callable classes in Dart 2.0.
For purposes of this description, a "callable class" is a class whose
interface contains a `.call` method.
In Dart 1.0, a callable class was considered to be a subtype of the
`.call` method's function type. This allowed the user to create
custom objects with similar behavior to closures, but with additional
fields and methods.
In Dart 2.0, a callable class is just an ordinary class, with no
subtype relation to any particular function type. (Note however that
it is still permissible for a class to declare that it "implements
Function").
To reduce the amount of code broken by this change, a piece of
syntactic sugar is being added: if an expression whose static type is
a callable class appears where a function type is expected, an
implicit tear-off of the `.call` method is inserted.
Note that it is still possible at compile time to invoke an expression
whose static type is a callable class, and it is still possible at
runtime to invoke an expression whose runtime type is a callable
class; in both cases, this is considered an implicit invocation of the
class's `.call` method. This is unchanged from Dart 1.0 behavior.
This CL introduces test cases for the new behavior, and implements the
implicit tear-off of `.call` in the front end.
Still to be implemented in future CLs:
- Spec text needs to be written.
- DDC/analyzer code needs to be written to perform implicit tear-offs
of `.call`.
- The subtyping algorithm in DDC, analyzer, VM, and dart2js needs to
be changed so that callable classes are no longer considered
subtypes of any particular function type.
- A small corner case involving type parameters still needs to be
addressed (see TODO in
pkg/front_end/lib/src/fasta/type_inference/type_inferrer.dart).
Fixes#32064.
Change-Id: I6a86491047ae467a5e767cb3cc7cecb570b29308
Reviewed-on: https://dart-review.googlesource.com/40508
Commit-Queue: Paul Berry <paulberry@google.com>
Reviewed-by: Kevin Millikin <kmillikin@google.com>
Reviewed-by: Leaf Petersen <leafp@google.com>
Reviewed-by: Erik Ernst <eernst@google.com>
Before: Kernel static errors were represented by throwing a distinguished
error or else by calling a distinguished library const constructor.
Now: Kernel static errors are represented by InvalidExpression. To support
error reporting, InvalidExpression has an optional message and a file
offset. A back end can choose to signal these errors at any time; for
example, when deserializing the binary, or when compiling the procedure
containing the static error, or when the erroneous expression is evaluated
at run time.
InvalidStatement is removed because it can be encoded as ExpressionStatement
of InvalidExpression.
Future work:
* supporting static errors where an expression cannot appear in the AST
* allowing InvalidExpression to contain an Expression for error recovery
* adding a top-level list of static errors and warnings to the binary
Bug: https://github.com/dart-lang/sdk/issues/29840
Change-Id: Ifdfe9a76cee6cefed28061bf245be70531d2f413
Reviewed-on: https://dart-review.googlesource.com/31320
Commit-Queue: Kevin Millikin <kmillikin@google.com>
Reviewed-by: Dan Rubel <danrubel@google.com>
Reviewed-by: Konstantin Shcheglov <scheglov@google.com>
Previously, the front end recovered from an invalid assignment by
producing an "as" expression, e.g.:
int x;
String y;
x = y;
Would produce an "invalid assignment" error, as well as this kernel
code:
int x;
String y;
x = y as{TypeError} int;
The rationale was that the "as" check was guaranteed to fail, so this
code would produce a runtime error at the correct location. However,
there were two problems:
1. (Minor problem) the "as" doesn't actually fail if the RHS is null.
2. (Major problem) for type inference, the type of an assignment
expression is defined to be the type of the RHS. This means that if
the invalid assignment gets used for type inference, we generate
mal-typed kernel code, e.g.:
int x;
String y;
var z = (x = y);
Gets compiled to:
int x;
String y;
String z = (x = y as{TypeError} int);
This CL addresses both problems by changing the kernel representation
so that it evaluates the RHS and then throws an exception. Since a
"throw" expression has type Bottom, the kernel representation is
guaranteed to be properly typed. This also ensures that an exception
gets thrown if the RHS is null. Finally, as a side bonus, it makes
the error-recovered kernel code more similar to the kernel code we
generate in other error recovery scenarios.
Change-Id: Iac74e0c726ce029ac0560d271413e85c15bfec5c
Reviewed-on: https://dart-review.googlesource.com/24140
Reviewed-by: Kevin Millikin <kmillikin@google.com>
Reviewed-by: Konstantin Shcheglov <scheglov@google.com>
Commit-Queue: Paul Berry <paulberry@google.com>
This reverts commit 8e4b0bda23.
Reason for revert: Failures on most kernel bots
Original change's description:
> Route all messages through Loader.
>
> This ensures that all messages are passed to instrumentation.
>
> Issues addressed in this CL:
>
> * When I added addCompileTimeError, I forgot to remove addError.
>
> * All messages now all arrive in a single location (Loader). SourceLoader adds instrumentation by overriding recordMessage.
>
> * As I changed the type inferrer to use addCompileTimeError, I broke DDC. This is because the front_end API (generateKernelInternal in kernel_generator_impl.dart) returns null if there are any errors reported via addCompileTimeError (and this didn't happen with addError, that shouldn't have been there anyways).
>
> * Due to the previous problem, I changed generateKernelInternal to ignore errors, but then I started getting missing compile-time errors. This turned out to be due to the the silent parameter used during outline- and diet-parsing.
>
> * I've removed all the "silent" parameters. This didn't work reliably and have been confusing Brian, Dan, and me several times when making parser changes. Instead we detect duplicated messages and avoid reporting them more than once.
>
> * Types in error messages got names that where using a global object (globalDebuggingNames in pkg/kernel/lib/text/ast_to_text.dart). This meant that the #lib prefix would vary depending on how many tests were run which affected the serialized error message in pkg/front_end/testcases/invalid_assignment.dart.strong.expect.
>
> Change-Id: I3d89372d6593a6e7e50cce733f61eedb881e15ed
> Reviewed-on: https://dart-review.googlesource.com/24481
> Commit-Queue: Peter von der Ahé <ahe@google.com>
> Reviewed-by: Paul Berry <paulberry@google.com>
> Reviewed-by: Kevin Millikin <kmillikin@google.com>
TBR=paulberry@google.com,ahe@google.com,kmillikin@google.com
Change-Id: I9f7b345a8ff040fc7aa73c5cb605190e47fd284b
No-Presubmit: true
No-Tree-Checks: true
No-Try: true
Reviewed-on: https://dart-review.googlesource.com/25660
Reviewed-by: Ryan Macnak <rmacnak@google.com>
Commit-Queue: Ryan Macnak <rmacnak@google.com>
Assert initializers in Dart may be compiled directly to this form of initializer,
rather than through local initializers as is done now.
Bug:
Change-Id: Ia149ea3d1df5d1dc18be5636801604ffaf7ca7d8
Reviewed-on: https://dart-review.googlesource.com/14760
Commit-Queue: Samir Jindel <sjindel@google.com>
Reviewed-by: Kevin Millikin <kmillikin@google.com>
This ensures that all messages are passed to instrumentation.
Issues addressed in this CL:
* When I added addCompileTimeError, I forgot to remove addError.
* All messages now all arrive in a single location (Loader). SourceLoader adds instrumentation by overriding recordMessage.
* As I changed the type inferrer to use addCompileTimeError, I broke DDC. This is because the front_end API (generateKernelInternal in kernel_generator_impl.dart) returns null if there are any errors reported via addCompileTimeError (and this didn't happen with addError, that shouldn't have been there anyways).
* Due to the previous problem, I changed generateKernelInternal to ignore errors, but then I started getting missing compile-time errors. This turned out to be due to the the silent parameter used during outline- and diet-parsing.
* I've removed all the "silent" parameters. This didn't work reliably and have been confusing Brian, Dan, and me several times when making parser changes. Instead we detect duplicated messages and avoid reporting them more than once.
* Types in error messages got names that where using a global object (globalDebuggingNames in pkg/kernel/lib/text/ast_to_text.dart). This meant that the #lib prefix would vary depending on how many tests were run which affected the serialized error message in pkg/front_end/testcases/invalid_assignment.dart.strong.expect.
Change-Id: I3d89372d6593a6e7e50cce733f61eedb881e15ed
Reviewed-on: https://dart-review.googlesource.com/24481
Commit-Queue: Peter von der Ahé <ahe@google.com>
Reviewed-by: Paul Berry <paulberry@google.com>
Reviewed-by: Kevin Millikin <kmillikin@google.com>
Before: mixin application classes could not have methods of their
own.
After: type inference will sometimes insert forwarding stubs in mixin
application classes. In the mixin elimination transformation, these
forwarding stubs are replaced with the methods of the mixin class if
they have the same name, but the parameter flags from the forwarding
stub are retained. The other forwarding stubs are left as methods of
the class.
Change-Id: I5ee89d6b1fc83194df82009c2800b54ce856e8c5
Reviewed-on: https://dart-review.googlesource.com/15887
Reviewed-by: Paul Berry <paulberry@google.com>
Commit-Queue: Kevin Millikin <kmillikin@google.com>
This has no effect on the generated kernel output; it just affects tests.
Also fix an incorrect type in field_forwarding_stub_explicit_covariant.dart.
Change-Id: Ic89d59a52648dc37a43cb12c4289611daaf422c6
Reviewed-on: https://dart-review.googlesource.com/15647
Reviewed-by: Konstantin Shcheglov <scheglov@google.com>
Commit-Queue: Paul Berry <paulberry@google.com>
Also add a test to verify that contravariance is properly handled for
method calls using "if-null" syntax (since this is handled by a
slightly different code path in the front end).
Change-Id: I93ee8b38ff39d78e25cac23ff048fcf69f15b5db
Reviewed-on: https://dart-review.googlesource.com/15000
Reviewed-by: Konstantin Shcheglov <scheglov@google.com>
Commit-Queue: Paul Berry <paulberry@google.com>
The outer loops are now through the arguments of the method to be
fixed, and the inner loops are through the inherited methods. This
allows us to handle the situation where a forwarding stub is needed
because isGenericCovariantInterface changes from true to false, but
the forwarding stub doesn't need to be concrete, since
isGenericCovariantImpl is inherited from the base class. (Previously
that situation didn't work because by the time we processed the
inheritance of isGenericCovariantImpl, we had already created a
concrete forwarding stub).
Additional fixes in this CL (necessary to get tests to pass in
meaningful ways):
- Updated InstrumentationValueForForwardingStub to print covariance
annotations on type parameters.
- Updated _createForwardingStub to copy covariance annotations from
the target procedure to the procedure being created.
- Moved call_through_this.dart from runtime_checks/ to
runtime_checks_new/ because the analyzer implementation doesn't
handle this case correctly.
Change-Id: I984a46826a3a4d8ad1a1ce840269498df049fef0
Reviewed-on: https://dart-review.googlesource.com/13963
Reviewed-by: Konstantin Shcheglov <scheglov@google.com>
Commit-Queue: Paul Berry <paulberry@google.com>
This allows covariance information to propagate properly between
classes and avoids creation of unnecessary forwarding stubs.
Change-Id: Ib55c62adb74d16f94282e752e387634086001946
Reviewed-on: https://dart-review.googlesource.com/12600
Reviewed-by: Konstantin Shcheglov <scheglov@google.com>
Commit-Queue: Paul Berry <paulberry@google.com>