In kernel, library import URIs now support an "app" scheme as an
alternative to the "file" scheme, representing a path relative to
the application root.
dartk takes an --app-root flag giving the application root. If none
is given, file URIs are used instead.
The intention is that kernel binaries should not carry irrelevant
path information, such as the path to the home directory of the
user who compiled a given file.
It is not the intention that end-users should see an app URI.
Import paths are currently not shown to users at all, and if we need
to do this, they should be translated to file paths first.
In theory we could stick to file URIs with relative paths, but the Uri
class from dart:core makes this difficult, as certain operations on it
assume that file paths should be absolute.
Source mapping URIs are not yet affected by this change.
R=kmillikin@google.com
Committed: https://github.com/dart-lang/sdk/commit/60adb852ad706ecf9424c77d47fa05583d543def
Review URL: https://codereview.chromium.org/2532053005 .
Reverted: https://github.com/dart-lang/sdk/commit/bb540416f27c39d75ee7f243899939fc37a2cd03
In kernel, library import URIs now have the "app" scheme instead of
the "file" scheme, representing a path relative to the application root.
dartk takes an --app-root flag giving the application root. This
defaults to the current working directory.
The intention is that kernel binaries should not carry irrelevant
path information, such as the path to the home directory of the
user who compiled a given file.
It is not the intention that end-users should see an app URI.
Import paths are currently not shown to users at all, and if we need
to do this, they should be translated to file paths first.
In theory we could stick to file URIs with relative paths, but the Uri
class from dart:core makes this difficult, as certain operations on it
assume that file paths should be absolute.
Source mapping URIs are not yet affected by this change.
R=kmillikin@google.com
Review URL: https://codereview.chromium.org/2532053005 .
This replaces the old --sanity-check flag from dartk. Some files have
been renamed to avoid the wording "sanity check".
Compared to --sanity-check, the following checks have been added:
- variables are not referenced out of scope
- variables are not redeclared
- class type parameters are not referenced from static context
A unit test has been added to check that the verifier rejects certain
invalid ASTs.
BUG=
R=kmillikin@google.com
Review URL: https://codereview.chromium.org/2531873002 .
This was originally done to be consistent with FunctionType,
where the named parameters are sorted, but for FunctionNode
it is not necessary.
It causes issues for natives that expect parameters to be
declared in a certain order. It is also an issue if we
ever want to reuse the kernel format for summaries, where
it is also preferable to present the named parameters in
their original order.
BUG=
R=kmillikin@google.com
Review URL: https://codereview.chromium.org/2527933002 .
FunctionType now has a List<NamedType> which must be sorted by name.
Previously, named parameters were stored in a Map<String, DartType>.
FunctionNode still has a List<VariableDeclaration>, but this list must
now be sorted by name.
BUG=
R=ahe@google.com
Review URL: https://codereview.chromium.org/2502343002 .
Previously, the type of a conditional expression could be omitted if
one of the arms was just a null literal. This was meant to simplify
translation into kernel, but wasn't really worth it in terms of
complexity, and it does not work well for types that carry nullability
information.
BUG=
R=ahe@google.com
Review URL: https://codereview.chromium.org/2465263002 .
This is a piece of the upcoming strong mode-based type propagation.
The new type propagator will build its inference graph based on the
subtyping constraints found during type checking.
This type checker is not intended to report type errors to end-users.
In its current form, it is quite redundant with the front end's type
checker, but this will not be the case once we augment kernel's type
system.
The internals of "dart:" libraries are not type checked -- they are
simply assumed to satisfy the type annotations on their interfaces.
BUG=
R=kmillikin@google.com
Review URL: https://codereview.chromium.org/2465893002 .
BlockExpression allowed statements to appear in an expression context.
It is unsafe for its original use case, allowing 'yield' to appear as an
expression, because the VM's yield implementation does not work when
there are live expression intermediate values.
Eliminate it by changing the async ExpressionLifter to return a
transformed expression and emit statements into a given list as a side
effect. This requires implementing the transformation for all
statements to account for how they may contain a nested expression.
BUG=
R=asgerf@google.com
Review URL: https://codereview.chromium.org/2460373002 .
TreeNode.location is a getter for use in diagnostics and debugging.
It uses parent pointers to find the enclosing file URI and line ending
table of the node. If the node has no offset stored, it will use that
of the first enclosing parent that has an offset.
BUG=
R=ahe@google.com, jensj@google.com
Review URL: https://codereview.chromium.org/2448873004 .
Type annotations in the supertype clauses of a class are now Supertypes
instead of InterfaceTypes. In the current version, the two classes
contain the same information, but they are about to diverge in the
following ways:
- An InterfaceType may be nullable, whereas a supertype cannot.
- An InterfaceType may represent the exact class, a subclass, or
a subtype of the given class.
- The type arguments to an interface type represent bounds, whereas
the arguments to a supertype are always exact.
We also introduce a class Substitution that represents an operator
that replaces type parameters with types, depending on the variance
of their use site.
A substitution can be applied to a DartType or a Supertype, and can
be generated independently of how it will be applied.
BUG=
R=kmillikin@google.com
Review URL: https://codereview.chromium.org/2439043002 .
The VM does not support function type parameters at the moment, but we
can erase them at the last minute, to enable testing of other parts of
strong mode.
This also disables error checking in the SDK since the VM's
patch files are not in strong mode.
BUG=
R=kustermann@google.com
Review URL: https://chromereviews.googleplex.com/518647013 .
The concept of a binary library file no longer exists.
A kernel file can contain any number of libraries, and some of these
libraries can be "external". To reference a class or member from
another build, the class or member must be declared in an external
library.
Members in an external library contain all their type information,
but have no body.
Classes in an external library have their hierarchy information
present, but are not guaranteed to contain all their actual members.
The idea is that references themselves don't really cross module
boundaries, but rather refer to a local definition whose body is
contributed from elsewhere, much like 'external' members in Dart.
A modular backend such as DDC should be able to compile from one of
these kernel files without needing to load auxiliary information from
summaries or other kernel files.
For whole program transformations or backends, a linking step, which
is not yet implemented, must merge classes and members in external
libraries based on their name.
External libraries share the same IR and binary format as ordinary
libraries. Transformations that affect the interface for a member
or class should transform the external libraries alongside with the
internal ones, ideally without needing to treat them any different.
R=kmillikin@google.com
Review URL: https://chromereviews.googleplex.com/516847013 .
For now the focus is on getting stacktraces to look right.
What that basically means is to include source positions for throws,
calls (in many forms).
Includes source file uri for libraries, field, classes and methods.
Methods and fields for instance needs it because of top-level
procedures that might be included via 'parts'.
Corresponding kernel-sdk change in review at
https://chromereviews.googleplex.com/516617014R=asgerf@google.com, kasperl@google.com
Review URL: https://chromereviews.googleplex.com/509247013 .
Fields getters and setters should be implicit whenever possible
to ensure JS compilers can easily control how they are generated.
However, it is still useful to be able to take control of the getter
or setter in the IR. We should just refrain from doing so for common
cases, where it can have significant code size impact in JS.
We can use this to insert checked setters for fields that override
a setter with an incompatible type, or whose type references a type
variable.
There are two changes to facilitate this:
- Fields have two flags indicating if the implicit getter and/or
setter should be generated. If not set, there can be an explicit
getter/setter for it in the same class.
- Interface targets that reference a field now go through one
level of indirection. This lets us update interface targets in
the IR, which is necessary for redirecting calls to an explicit
getter or setter.
BUG=
R=kmillikin@google.com
Review URL: https://chromereviews.googleplex.com/504357013 .
The interface target can now be stored on PropertyGet, PropertySet, and
MethodInvocation If set, we know the concrete target overrides or
implements that member.
All expressions have a method getStaticType for computing its type,
which relies on interface targets for the expressions that have one.
Expressions whose type is a least upper bound have the type stored
explicitly, so the definition of least upper bounds is contained only
in the frontend.
This is a work in progress towards strong mode support, it is still
not complete.
Still missing in the frontend:
- checks from implicit downcasts
- parameter checks from covariant override or covariant generics
Implemented but not part of this CL:
- subtype tests
- IR type checker (for debugging)
BUG=
R=kmillikin@google.com
Review URL: https://chromereviews.googleplex.com/496717014 .
For example:
class A extends Foo<int> with Bar<String> {}
class B extends Foo<int> with Bar<double> {}
becomes:
class Foo&Bar<S,T> = Foo<S> with Bar<T>;
class A extends Foo&Bar<int, String> {}
class B extends Foo&Bar<int, double> {}
BUG=
R=kmillikin@google.com
Review URL: https://chromereviews.googleplex.com/493197013 .
This makes super calls name-based (no target) and add direct calls with
both receiver and explicit target.
Super call resolution translates the name-based super calls into direct
calls after they have been cloned into the mixin application.
For JS backends, it should suffice to clone mixed-in methods that
contain super calls, but that transformation is not part of this CL.
This also adds a --target option to dartk designating the target to
which the kernel IR should be specialized. The new transformation
is run when --target=vm.
BUG=
R=kmillikin@google.com
Review URL: https://chromereviews.googleplex.com/486537013 .
We need the ability to efficiently transform a mixin application class
into a regular class, and the separation was obstructing it. It also
simplifies the IR a bit, although it no longer enforces the invariant
that mixin applications cannot contain fields and procedures.
The binary format is unchanged, so the separation still shows up in
there. This ensures the CL can land without any changes to the SDK.
BUG=
R=vegorov@google.com
Review URL: https://chromereviews.googleplex.com/488407013 .
Instance members are now cloned for every class that inherits it.
The constraint system now explicitly requires all values to be
created using `newValue()`.
There is now a notion of "unions" for representing sets of values.
For class values, unions correspond to types. For function values,
unions are based on overriding and method names.
The solver's internal map of type (Value,Field) -> Value denoting
the value of a given field has been removed.
The builder must instead register store and load locations for
every valid (Value,Field) pair. Dynamic stores assign into the
store location, and dynamic loads take the value from the load
location.
Final fields have no store location, so they cannot be polluted
by dynamic stores.
R=vegorov@google.com
Review URL: https://chromereviews.googleplex.com/455987013 .
This transformer is responsible for lifting subexpression into temporary variables preserved across yield points.
To maintain AST validity I introduced an expression that can contain a block of statements inside called BlockExpression.
BUG=
R=kustermann@google.com
Review URL: https://chromereviews.googleplex.com/458577014 .
LocalInitializer lets us to bind temporaries to variables in the
initializer list. We use it to ensure the arguments to super() are
evaluated at the right time.
accessors.dart and the new file super_calls.dart have been moved into
a folder "frontend" for frontend helpers that operate on Kernel IR.
BUG=
R=kustermann@google.com
Review URL: https://chromereviews.googleplex.com/457457013 .
For constructor bodies, we arbitrarily set the return type to 'void'.
Although there is hardly any legitimate use for the "return type" of
a constructor, this doesn't have any overhead and it simplifies the
restriction on FunctionNode.
BUG=
R=kmillikin@google.com
Review URL: https://chromereviews.googleplex.com/446827013 .