Skip to content
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
53 changes: 53 additions & 0 deletions accepted/future-releases/nnbd/feature-specification.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,9 @@ Status: Draft

## CHANGELOG

2020.08.12
- Specify constraints on the `main` function.

2020.08.06
- Specify error for uninitialized final instance variable in class
with no generative constructors.
Expand Down Expand Up @@ -901,6 +904,56 @@ These are extended as
per
[separate proposal](https://github.com/dart-lang/language/blob/master/resources/type-system/flow-analysis.md).

### The main function

The section 'Scripts' in the language specification is replaced by the
following:

Let _L_ be a library that exports a declaration _D_ named `main`. It is a
compile-time error unless _D_ is a function declaration. It is a
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This excludes getters, right? co19/Language/Libraries_and_Scripts/Scripts/top_level_main_t05 seems to assume it doesn't.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It is intended to exclude getters. The old version of this text in section Scripts said explicitly in commentary that we couldn't have a 'top-level getter or field named main', and we did not discuss nor intend to change that when this spec change was landed.

However, section 'Functions' implies that 'function' includes getters, setters, constructors, and "functions" (no, we don't have a separate term for the ones that have a <formalParameterList> and aren't constructors, I had a CL a long time ago to fix that, but it hasn't been landed). So the text should say unless _D_ is a non-getter function declaration. It can't be a top-level constructor and a setter can't have the name main, so that should be enough.

Copy link
Member Author

@eernstg eernstg Oct 5, 2020

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Edit: #1248

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

When calling main from external code, e.g. JavaScript, it is necessary to convert arguments. We can't just say that main is called dynamically from 'outside'. This conversion happens in the context of the program but before entering main, e.g. needs to access the type List<String> for that program. This interstitial place a special place that we want to constrain heavily in a platform dependent way. For dart2js we want limit the conversion to just Array-to-List<String>, for which we need to know the static type of the entry point.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@rakudrama does line 920 not address your concerns?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, it does. I was just adding colour for Johnni.

compile-time error if _D_ declares more than two required positional
parameters, or if there are any required named parameters. It is a
compile-time error if _D_ declares at least one positional parameter, and
the first positional parameter has a type which is not a supertype of
`List<String>`.

Implementations are free to impose any additional restrictions on the
signature of `main`.

A _script_ is a library that exports a declaration named `main`.
A script _L_ is executed as follows:

First, _L_ is compiled as a library as specified above.
Then, the top-level function defined by `main`
in the exported namespace of _L_ is invoked as follows:

If `main` can be called with with two positional arguments,
it is invoked with the following two actual arguments:

- An object whose run-time type implements `List<String>`.
- An object specified when the current isolate _i_ was created,
for example through the invocation of `Isolate.spawnUri` that spawned _i_,
or the null object if no such object was supplied.
A dynamic error occurs if the run-time type of this object is not a
subtype of the declared type of the corresponding parameter of `main`.

If `main` cannot be called with two positional arguments, but it can be
called with one positional argument, it is invoked with an object whose
run-time type implements `List<String>` as the only argument.

If `main` cannot be called with one or two positional arguments, it is
invoked with no arguments.

In each of the above three cases, an implementation is free to provide
additional arguments allowed by the signature of `main` (*the above rules
ensure that the corresponding parameters are optional*). But the
implementation must ensure that a dynamic error occurs if an actual
argument does not have a run-time type which is a subtype of the declared
type of the parameter.

A Dart program will typically be executed by executing a script. The
procedure whereby this script is chosen is implementation specific.

## Runtime semantics

### Weak and strong semantics
Expand Down