Closed peter-ahe-google closed 6 years ago
Issue #29386 mentioned above contains the following text from the language specification (which will be needed in order to determine what we must clarify, so I'll show it here as well, as it is stated in the latest LaTeX source):
A {\em script} is a library whose exported namespace (\ref{exports}) includes a
top-level member named \code{main}. It is a static warning if the static type of
\code{main} is not assignable to a function type or is a function type with more
than two required parameters (1).
A script $S$ may be executed as follows:
First, $S$ is compiled as a library as specified above. Then, the top-level function
\code{main} that is in the exported namespace of $S$ is invoked (2). If \code{main}
has no positional parameters, it is invoked with no arguments. Otherwise if
\code{main} has exactly one positional parameter, it is invoked with a single
actual argument whose runtime type implements \code{List<String>} (3). Otherwise
\code{main} is invoked with the following two actual arguments:
\begin{enumerate}
\item An object whose runtime type implements \code{List<String>}.
\item The initial message of the current isolate $i$ as determined by the invocation of
\code{Isolate.spawnUri} that spawned $i$.
\end{enumerate}
It is a run time error if $S$ does not declare or export either:
\begin{itemize}
\item A top-level function named \code{main}, or
\item A top-level getter named \code{main} that returns a function.
\end{itemize}
I removed a couple of LaTeX commands that do not contribute to the text, and added (number) markers to indicate locations that I need to comment on.
Clarifications needed:
\code{main}
' then it refers to the static type of the-function-main when it is a top-level function, and the return type of the getter when it's a getter.\code{main}
' may be misleading, because it could be a getter. The spec uses phrases like 'An external function may be a top-level function, a method, a getter, ..' which shows that some usages of 'function' include getters and others don't. We could say 'function or getter' to double down on the fact that it could be a getter.\code{main}
has..', 'Otherwise if \code{main}
has..' work perfectly fine when the declaration named main
is a top-level function, but less well when it is a getter. It would be less confusing if we said 'Let $f$
be the value of evaluating the property extraction expression \code{main}
.' and then talked about $f$
rather than \code{main}
.The resulting text could be as shown in this CL.
Note that this is strictly a clarification, because it specifies a semantics which is already a plausible interpretation of the existing text.
The language team decided that Dart will no longer support a main
which is getter. Hence, the CL that I mentioned above (which clarifies what to do when getters are supported) is obsolete. Lasse has written another CL which takes that decision into account.
Done in 13f3df7e0cd4de9c99d344f242afb8514ada06f7.
The current specification makes it really hard to report a decent error message to a user.
The problem is that our tools have no other option to report:
"No 'main' method found in ."
There's a number of situations where this is confusing:
What would be wrong in justifying "main should have at most two parameters" as follows: With input main(a, b, c) {}
we detect that this is not a Dart script, so it cannot be executed: "Cannot execute this library." and then informing the developer how it fails: "Found a top-level main
method, but it fails to declare 0, 1, or 2 required positional arguments".
Similarly, with var main = () {}
, the error message could be "Cannot execute this library." because it isn't a Dart script, and then "Found a top-level variable main
, but main
must be a function.".
So I don't see how the specification prevents giving the messages that you mention.
Can you say why you think the specification prevents such error reports?
The problem is that someone is passing a non-script library to a tool expecting a script library.
The fact that the library is not a script is determined by it not exporting a function declaration accepting zero, one or two arguments under the name main
.
If you can see that the library exports some other entity with the name main
, feel free to include that information in the error message.
The problem is that we have a shared front-end that is supposed to report errors. However, it can't report an error when it sees:
main(a,b,c) {}
var main = ...
All it can do is say is this:
program.mainMethod = null;
As of d7e50427b38f2998ff95ec89875cdc7b5b24c88d, the language specification specifies that It is a compile-time error if a library's export scope contains a declaration named \code{main}, and the library is not a script
, i.e., it is a compile-time error if main
is a getter, even in the situation where it is not known whether the library containing that declaration will be used as a script.
I believe this resolves the issue. I'll close it now, but please reopen and explain remaining issues if needed.
The specification isn't currently clear about what happens when
main
is a getter.Please see #29386 for a detailed description of how the lack of clarity has led to different interpretations in dart2js and the Dart VM.