-
Notifications
You must be signed in to change notification settings - Fork 205
/
dartLangSpec.tex
23507 lines (20345 loc) · 822 KB
/
dartLangSpec.tex
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
\documentclass[makeidx]{article}
\usepackage{xspace}
\usepackage{epsfig}
\usepackage{xcolor}
\usepackage{syntax}
\usepackage[fleqn]{amsmath}
\usepackage{amssymb}
\usepackage{semantic}
\usepackage{dart}
\usepackage{hyperref}
\usepackage{lmodern}
\usepackage[T1]{fontenc}
\usepackage{makeidx}
\makeindex
\title{Dart Programming Language Specification\\
{6th edition draft}\\
{\large Version 2.13-dev}}
\author{}
% For information about Location Markers (and in particular the
% commands \LMHash and \LMLabel), see the long comment at the
% end of this file.
% CHANGES
% =======
%
% Significant changes to the specification. Note that the versions specified
% below indicate the current tool chain version when those changes were made.
% In practice, new features have always been integrated into the language
% specification (this document) a while after the change was accepted into
% the language and implemented. As of September 2022, the upcoming version of
% the language which is being specified is indicated by a version number in
% parentheses after the tool chain version.
%
% Note that the version numbers used below (up to 2.15) were associated with
% the currently released language and tools at the time of the spec change,
% they were not aligned with the actual version of the language which is being
% specified in that version of this document. This is highly misleading, so we
% changed the subtitles to be a month rather than a version number. Similarly,
% the 'Version' specified on the front page has been changed to indicate the
% version of the language which will actually be specified by the next stable
% release of this document.
%
% Dec 2023
% - Allow `~/` on operands of type `double` in constant expressions, aligning
% the specification with already implemented behavior.
% - Broaden the grammar rule about `initializerExpression` to match the
% implemented behavior. Specify that an initializer expression can not be
% a function literal.
% - Specify in which situations it is an error to declare an initializing
% formal parameter.
%
% Nov 2023
% - Specify that the dynamic error for calling a function in a deferred and
% not yet loaded library will occur before actual argument evaluation, not
% after.
%
% Oct 2023
% - Introduce the rule that an `extension` declaration cannot have the name
% `type`. This is needed in order to disambiguate an `extension type`
% named `on`.
%
% Aug 2023
% - Correct text about built-in identifier error and turn it into commentary
% (the normative text is in grammar rules using `typeIdentifier`), and
% correct the grammar for import prefixes to use `typeIdentifier`.
%
% Jul 2023
% - Land the null-safety updates for sections about variables.
% - Change terminology: A 'static variable' is now a variable whose declaration
% includes `static` (which used to be called a 'class variable'); the old
% meaning of 'static variable' is now never used (we spell out every time
% that it is a 'library variable or a static variable', where the latter is
% the new meaning of that phrase). This avoids the confusion that came up
% just about every single time the phrase 'static variable' came up in a
% discussion.
% - Change terminology: The notion of 'mutable' and 'immutable' variables has
% been eliminated (it is spelled out each time which modifiers must be
% present or not present). The concept is confusing now where a variable can
% be late and final, and assignments to it are allowed by the static analysis.
% - Change the definition of the 'element type of a generator function', due to
% soundness issue with the current definition.
%
% Mar 2023
% - Clarify how line breaks are handled in a multi-line string literal. Rename
% the lexical token NEWLINE to LINE\_BREAK (clarifying that it is not `\n`).
% - Clean up grammar rules (avoid `T?` as a superclass/etc., which is an
% error anyway; change extension names to `typeIdentifier`, avoiding
% built-in identifiers).
%
% Feb 2023
% - Change the specification of constant expressions of the form `e1 == e2`
% to use primitive equality.
%
% Dec 2022
% - Change the definition of the type function 'flatten' to resolve soundness
% issue, cf. SDK issue #49396.
% - Introducing null-safety related changes to the sections about variables
% and local variables.
% - Change 'primitive operator ==' to 'primitive equality', and include
% constraints on `hashCode` corresponding to the ones we have on `==`.
%
% 2.15
% - Allow generic instantiation of expressions with a generic function type
% (until now, it was an error unless the expression denoted a declaration).
% - Allow generic instantiation of the `call` method of a function object.
% - Clarify that `TypeLiteral.extensionMethod()` is an error, in line with the
% error for `int.toString()`.
% - Add support for function closurization for callable objects, in the sense
% that `o` is desugared as `o.call` when the context type is a function type.
% - Clarify the treatment of `covariant` parameters in the interface of a class
% that inherits an implementation where those parameters are not covariant.
% - Adjust and clarify simple string interpolation (to allow `'$this'`, which
% is already implemented and useful).
% - Add several lexical rules about identifiers, clarifying different kinds.
% - Clarify the conflicts between extension members and `Object` instance
% members.
% - Correct <partDeclaration> to include metadata.
% - Clarify the section about assignable expressions.
%
% 2.14
% - Add constraint on type of parameter which is covariant-by-declaration in
% the case where the method is inherited (that case was omitted by mistake).
% - Clarify symbol equality and identity.
%
% 2.12 - 2.13 (there was no 2.11)
% - Revert the CL where certain null safety features were removed (to enable
% publishing a stable version of the specification).
% - Add rule that a top-level pair of declarations with the same basename
% is a compile-time error except when it is a getter/setter pair.
% - Change grammar to enable non-function type aliases. Correct rule for
% invoking `F.staticMethod()` where `F` is a type alias.
% - Add missing error for cyclic redirecting generative constructor.
%
% 2.8 - 2.10
% - Change several warnings to compile-time errors, matching the actual
% behavior of tools.
% - Eliminate error for library name conflicts in imports and exports.
% - Clarify the specification of initializing formals. Fix error: Add
% missing `?` at the end for function typed initializing formal.
% - Adjust specification of JS number semantics.
% - Revise and clarify the sections Imports and Exports.
% - Bug fix: Change <qualifiedName> to omit the single identifier, then add it
% back when <qualifiedName> is used, as <typeIdentifier> resp. <identifier>.
% - Clarify that a function-type bounded receiver has a `.call` method.
% - Merge the `static' and `instance' scope of a class, yielding a single
% `class' scope.
% - Add specification of `>>` in JavaScript compiled code, in appendix.
% - Integrate the specification of extension methods into this document.
% - Specify identifier references denoting extension members.
% - Remove a few null safety features, to enable publishing a stable
% version of the specification which is purely about Dart 2.10.
% - Reorganize specification of type aliases to be in section `Type Aliases'
% (this used to be both there, and in 'Generics').
% - Clarify the cyclicity error for type aliases ("F is not allowed to depend
% on itself).
% - Add the error for a type alias $F$ used in an instance creation etc., when
% $F$ expands to a type variable.
% - Correct lexical lookup rules to include implicit extension method
% invocation.
%
% 2.7
% - Rename non-terminals `<...Definition>` to `<...Declaration>` (e.g., it is
% 'class declaration' everywhere, so `<classDefinition>` is inconsistent).
% - Clarify that <libraryDeclaration> and <partDeclaration> are the
% start symbols of the grammar.
% - Clarify the notion of being `noSuchMethod forwarded': `m` is indeed
% noSuchMethod forwarded if an implementation of `m` is inherited, but
% it does not have the required signature.
% - Clarify static checks on `yield` and `yield*` to explicitly ensure that
% assignability is enforced per element.
% - Update whitelist for expressions of type void to include `await e`,
% consistent with decision in SDK issue #33415.
% - Re-adjust `yield*` rules: Per-element type checks are not supported,
% the given Iterable/Stream must have a safe element type.
% - Clarify that an expression of type `X extends T` can be invoked when
% `T` is a function type, plus other similar cases.
% - Specify actual type arguments passed to a generic function which is invoked
% with no type arguments (so it must be a dynamic invocation).
%
% 2.6
% - Specify static analysis of a "callable object" invocation (where
% the callee is an instance of a class that has a `call` method).
% - Specify that <libraryImport> string literals cannot use string
% interpolation; specify that it is a dynamic error for `loadLibrary`
% to load a different library than the one which was used for
% compile-time checks.
% - Specify that a constant expression `e.length` can only invoke an instance
% getter (in particular, it cannot execute/tear-off an extension member);
% similar changes were made for several operators.
% - Specify the type arguments of the fields of an `Invocation` received by
% `noSuchMethod`, when invoked in response to a failed instance member
% invocation.
%
% 2.4
% - Clarify the section `Exports'.
% - Update grammar rules for <declaration>, to support `static late final`
% variables with no initializer; for several top-level declarations,
% to correct the existence and placement of <metadata>; for
% <assignableSelectorPart>, to simplify the grammar (preserving the
% derivable terms); for <topLevelDeclaration>, to allow top-level final
% and const variables with no type, and to allow `late final` top-level
% variables, to allow `late` on a top-level variable declaration; and
% adding <namedParameterType> to allow `required` parameters.
% - Make lexical identifier lookups use the rules for 'Identifier Reference'
% consistently; that is, always look up `id` as well as `id=`, and commit
% to the kind of declaration found by that lookup.
% - Specify the signature of the `call` method of a function object.
% - Add the rule that it is an error for a type variable of a class to occur
% in a non-covariant position in a superinterface.
% - Correct several grammar rules, including: added <functionExpressionBody> (to
% avoid semicolon in <functionBody>), adjusted <importSpecification>.
% - Revise section on cascades. Now uses compositional grammar, and
% specifies static type, compile-time errors, and includes `?..`.
% - Correct the grammar and lexical rules for string literals.
% - Change specification of `await` to be type-safe, avoiding cases like:
% FutureOr<Future<S>> ffs = Future<S>.value(s);
% Future<S> fs = await ffs;
%
% 2.3
% - Add requirement that the iterator of a for-in statement must have
% type `Iterator`.
% - Clarify which constructors are covered by the section 'Constant
% Constructors' and removed confusing redundancy in definiton of
% potentially constant expressions.
% - Integrate the feature specification of collection literal elements
% (aka UI-as-code).
%
% 2.2
% - Specify whether the values of literal expressions override Object.==.
% - Allow Type objects as case expressions and const map keys.
% - Introduce set literals.
% - Specify that a getter/setter and a method with the same basename is
% an error, also in the case where a class obtains both from its
% superinterfaces.
% - Specify the Dart 2.0 rule that you cannot implement, extend or mix-in
% Function.
% - Generalize specification of type aliases such that they can denote any
% type, not just function types.
% - Clarify that 'Constant Constructors' is concerned with non-redirecting
% generative constructors only.
%
% 2.1
% - Remove 64-bit constraint on integer literals compiled to JavaScript numbers.
% - Allow integer literals in a double context to evaluate to a double value.
% - Specify dynamic error for a failing downcast in redirecting factory
% constructor invocation.
% - Specify that type arguments passed in a redirecting factory constructor
% declaration must be taken into account during static checks.
% - Disallow any expression statement starting with `{`, not just
% those that are map literals.
% - Define a notion of lookup that is needed for superinvocations, adjust
% specification of superinvocations accordingly.
% - Specify that it is a dynamic error to initialize a non-static variable
% with an object that does not have the declared type (e.g., a failed cast).
% - Specify for constructor initializers that target variable must exist and
% the initializing expression must have a type which is assignable to its
% type.
% - Specify for superinitializers that the target constructor must exist and
% the argument part must have a matching shape and pass type and value
% arguments satisfying the relevant constraints.
% - Reword rules about abstract methods and inheritance to use 'class
% interface'.
% - Specify that it is an error for a concrete class with no non-trivial
% \code{noSuchMethod} to not have a concrete declaration for some member
% in its interface, or to have one which is not a correct override.
% - Use \ref{bindingActualsToFormals} in 3 locations, eliminating 2 extra
% copies of nearly the same text.
% - Add figure in \ref{bindingActualsToFormals} for improved readability.
% - Introduce a notion of lookup which is needed for superinvocations.
% - Use new lookup concept to simplify specification of getter, setter, method
% lookup.
% - Introduce several `Case<SomeTopic>` markers in order to improve
% readability.
% - Reorganize several sections to specify static analysis first and then
% dynamic semantics; clarify many details along the way. The sections are:
% \ref{variables}, \ref{new}, \ref{const}, \ref{bindingActualsToFormals},
% \ref{unqualifiedInvocation}, \ref{functionExpressionInvocation},
% \ref{superInvocations}, \ref{assignment}, \ref{compoundAssignment},
% \ref{localVariableDeclaration}, and \ref{return}.
% - Corrected error involving multiple uses of the same part in the same
% program such that it takes exports into account.
% - Eliminate all references to checked and production mode, Dart 2 does
% not have modes.
% - Integrate feature specification on noSuchMethod forwarders.
% - Specify that bound satisfaction in generic type alias type parameters
% must imply bound satisfaction everywhere in the body.
% - Specify that super-bounded generic type alias applications must trigger
% a well-boundedness check on all types occurring in the denoted type.
% - Corrected corner case of rules for generation of noSuchMethod forwarders.
% - Integrate feature specification on parameters that are
% covariant-by-declaration.
% - Integrate feature specification on parameters that are
% covariant-by-class.
% - Correct section 'Type of a function', allowing for adjustments needed
% for rules related to covariant parameters.
% - Specified the dynamic type of function objects in several contexts, such
% that the special treatment of covariant parameters can be mentioned.
% - Specified what it means for an override relation to be correct, thus
% adding the parts that are not captured by a function type subtype check.
% - Introduced the notion of member signatures, specified that they are the
% kind of entity that a class interface contains.
% - Corrected super-boundedness check to take variance into account at the
% top level.
%
% 2.0
% - Don't allow functions as assert test values.
% - Start running "async" functions synchronously.
% - It is a static warning and dynamic error to assign to a final local.
% - Specify what "is equivalent to" means.
% - Remove @proxy.
% - Don't specify the exact object used for empty positionalArguments and
% namedArguments on Invocation.
% - Remove the, now unnecessary, handling of invalid overrides of noSuchMethod.
% - Add >>> as overridable operator.
% - If initializing formal has type annotation, require subtype of field type.
% - Constant `==` operations now also allowed if just one operand is null.
% - Make flatten not be recursive.
% - Disallow implementing two instantiations of the same generic interface.
% - Update "FutureOr" specification for Dart 2.0.
% - Require that a top-level "main" declaration is a valid script-entry
% function declaration.
% - State that the return type of a setter or []= is void when not specified.
% - Clarify that "noSuchMethod" must be implemented, not just redeclared
% abstractly, to eliminate certain diagnostic messages.
% - Add generic functions and methods to the language.
% - Don't cause warning if a non-system library import shadows a system library.
% - Update mixin application forwarding constructors to correctly handle
% optional parameters and const constructors.
% - Specify `call` for Dart 2 (no function type given to enclosing class).
% - Clarify that an identifier reference denoting a top-level, static, or
% local function evaluates to the closurization of that declaration.
% - Make `mixin` and `interface` built-in identifiers.
% - Make `async` *not* a reserved word inside async functions.
% - Add 'Class Member Conflicts', simplifying and adjusting rules about
% member declaration conflicts beyond "`n` declared twice in one scope".
% - Specify that integer literals are limited to signed 64-bit values,
% and that the `int` class is intended as signed 64-bit integer, but
% that platforms may differ.
% - Specify variance and super-bounded types.
% - Introduce `subterm' and `immediate subterm'.
% - Introduce `top type'.
% - Specify configurable imports.
% - Specify the dynamic type of the Iterable/Future/Stream returned from
% invocations of functions marked sync*/async/async*.
% - Add appendix listing the major differences between 64-bit integers
% and JavaScript integers.
% - Remove appendix on naming conventions.
% - Make it explicit that "dynamic" is exported from dart:core.
% - Remove "boolean conversion". It's just an error to not be a bool.
% - Adjust cyclic subtype prevention rule for type variables.
% - Clarify that it is an error to use FutureOr<T> as a superinterface etc.
% - Eliminate the notion of static warnings, all program faults are now errors.
% - It is no longer an error for a getter to have return type `void`.
% - Specify that each redirection of a constructor is checked, statically and
% dynamically.
% - Specify that it is an error for a superinitializer to occur anywhere else
% than at the end of an initializer list.
% - Update the potentially/compile-time constant expression definitions
% so that "potentially constant" depends only on the grammar, not the types
% of sub-expressions.
% - Make `==` recognize `null` and make `&&` and `||` short-circuit in constant
% expressions.
% - Add `as` and `is` expressions as constant expressions
% - Make `^`, `|` and `&` operations on `bool` constant operations.
% - Integrate subtyping.md. This introduces the Dart 2 rules for subtyping,
% which in particular means that the notion of being a more specific type
% is eliminated, and function types are made contravariant in their
% parameter types.
% - Integrate instantiation to bound. This introduces the notions of raw
% types, the raw-depends relation, and simple bounds; and it specifies
% the algorithm which is used to expand a raw type (e.g., `C`) to a
% parameterized type (e.g., `C<int>`).
% - Integrate invalid_returns.md. This replaces the rules about when it is
% an error to have `return;` or `return e;` in a function.
% - Integrate generalized-void.md. Introduces syntactic support for using
% `void` in many new locations, including variable type annotations and
% actual type arguments; also adds errors for using values of type `void`.
% - Integrate implicit_creation.md, specifying how some constant expressions
% can be written without `const`, and all occurrences of `new` can be
% omitted.
%
% 1.15
% - Change how language specification describes control flow.
% - Object initialization now specifies initialization order correctly.
% - Specifies that leaving an await-for loop must wait for the subscription
% to be canceled.
% - An await-for loop only pauses the subscription if it does something async.
% - Assert statements allows a "message" operand and a trailing comma.
% - The Null type is now considered a subtype of all types in most cases.
% - Specify what NEWLINE means in multiline strings.
% - Specified the FutureOf type.
% - Asserts can occur in initializer lists.
%
% 1.14
% - The call "C()" where "C" is a class name, is a now compile-time error.
% - Changed description of rewrites that depended on a function literal.
% In many cases, the rewrite wasn't safe for asynchronous code.
% - Removed generalized tear-offs.
% - Allow "rethrow" to also end a switch case. Allow braces around switch cases.
% - Allow using `=` as default-value separator for named parameters.
% - Make it a compile-time error if a library includes the same part twice.
% - Now more specific about the return types of sync*/async/async* functions
% in relation to return statements.
% - Allow Unicode surrogate values in String literals.
% - Make an initializing formal's value accessible in the initializer list.
% - Allow any expression in assert statements (was only conditionalExpression).
% - Allow trailing commas in argument and parameter lists.
%
% 1.11 - ECMA 408 - 4th Edition
% - Specify that potentially constant expressions must be valid expressions
% if the parameters are non-constant.
% - Make "??" a compile-time constant operator.
% - Having multiple unnamed libraries no longer causes warnings.
% - Specify null-aware operators for static methods.
%
% 1.10
% - Allow mixins to have super-classes and super-calls.
% - Specify static type checking for the implicit for-in iterator variable.
% - Specify static types for a number of expressions where it was missing.
% - Make calls on the exact type "Function" not cause warnings.
% - Specify null-aware behavior of "e?.v++" and similar expressions.
% - Specify that `package:` URIs are treated in an implementation dependent way.
% - Require warning if for-in is used on object with no "iterator" member.
%
% 1.9 - ECMA-408 - 3rd Edition
%
\begin{document}
\maketitle
\tableofcontents
\newpage
\pagestyle{myheadings}
\markright{Dart Programming Language Specification}
% begin Ecma boilerplate
\section{Scope}
\LMLabel{ecmaScope}
\LMHash{}%
This Ecma standard specifies the syntax and semantics of
the Dart programming language.
It does not specify the APIs of the Dart libraries
except where those library elements are essential to
the correct functioning of the language itself
(e.g., the existence of class \code{Object} with methods
such as \code{noSuchMethod}, \code{runtimeType}).
\section{Conformance}
\LMLabel{ecmaConformance}
\LMHash{}%
A conforming implementation of the Dart programming language
must provide and support all the APIs
(libraries, types, functions, getters, setters,
whether top-level, static, instance or local)
mandated in this specification.
\LMHash{}%
A conforming implementation is permitted to provide additional APIs,
but not additional syntax,
except for experimental features.
\section{Normative References}
\LMLabel{ecmaNormativeReferences}
\LMHash{}%
The following referenced documents are indispensable for
the application of this document.
For dated references, only the edition cited applies.
For undated references, the latest edition of the referenced document
(including any amendments) applies.
\begin{enumerate}
\item
The Unicode Standard, Version 5.0, as amended by Unicode 5.1.0, or successor.
\item
Dart API Reference, https://api.dartlang.org/
\end{enumerate}
\section{Terms and Definitions}
\LMLabel{ecmaTermsAndDefinitions}
\LMHash{}%
Terms and definitions used in this specification are given in
the body of the specification proper.
% End Ecma Boilerplate
\section{Notation}
\LMLabel{notation}
\LMHash{}%
We distinguish between normative and non-normative text.
Normative text defines the rules of Dart.
It is given in this font.
At this time, non-normative text includes:
\begin{itemize}
\item[Rationale]
Discussion of the motivation for language design decisions appears in italics.
\rationale{%
Distinguishing normative from non-normative helps clarify
what part of the text is binding and what part is merely expository.%
}
\item[Commentary]
Comments such as
``\commentary{%
The careful reader will have noticed
that the name Dart has four characters%
}''
serve to illustrate or clarify the specification,
but are redundant with the normative text.
\commentary{%
The difference between commentary and rationale can be subtle.%
}
\rationale{%
Commentary is more general than rationale,
and may include illustrative examples or clarifications.%
}
\end{itemize}
\LMHash{}%
Reserved words and built-in identifiers
(\ref{identifierReference})
appear in {\bf bold}.
\commentary{%
Examples would be \SWITCH{} or \CLASS.%
}
\LMHash{}%
Grammar productions are given in a common variant of EBNF.
The left hand side of a production ends with `\lit{::=}'.
On the right hand side, alternation is represented by vertical bars,
and sequencing by spacing.
As in PEGs, alternation gives priority to the left.
Optional elements of a production are suffixed by a question mark
like so: \code{anElephant?}.
Appending a star to an element of a production means
it may be repeated zero or more times.
Appending a plus sign to a production means it occurs one or more times.
Parentheses are used for grouping.
Negation is represented by prefixing an element of a production with a tilde.
Negation is similar to the not combinator of PEGs,
but it consumes input if it matches.
In the context of a lexical production it consumes
a single character if there is one;
otherwise, a single token if there is one.
\commentary{%
An example would be:%
}
\begin{grammar}\color{commentaryColor}
<aProduction> ::= <anAlternative>
\alt <anotherAlternative>
\alt <oneThing> <after> <another>
\alt <zeroOrMoreThings>*
\alt <oneOrMoreThings>+
\alt <anOptionalThing>?
\alt (<some> <grouped> <things>)
\alt \gtilde<notAThing>
\alt `aTerminal'
\alt <A\_LEXICAL\_THING>
\end{grammar}
\LMHash{}%
Both syntactic and lexical productions are represented this way.
Lexical productions are distinguished by their names.
The names of lexical productions consist exclusively of
upper case characters and underscores.
As always, within grammatical productions,
whitespace and comments between elements of the production
are implicitly ignored unless stated otherwise.
Punctuation tokens appear in quotes.
\LMHash{}%
Productions are embedded, as much as possible,
in the discussion of the constructs they represent.
\LMHash{}%
A \Index{term} is a syntactic construct.
It may be considered to be a piece of text which is derivable in the grammar,
and it may be considered to be a tree created by such a derivation.
An \Index{immediate subterm} of a given term $t$ is a syntactic construct
which corresponds to an immediate subtree of $t$
considered as a derivation tree.
A \Index{subterm} of a given term $t$ is $t$,
or an immediate subterm of $t$,
or a subterm of an immediate subterm of $t$.
\LMHash{}%
A list \DefineSymbol{x_1, \ldots, x_n} denotes any list of
$n$ elements of the form $x_i, 1 \le i \le n$.
Note that $n$ may be zero, in which case the list is empty.
We use such lists extensively throughout this specification.
\BlindDefineSymbol{j, y_j, x_j}%
\LMHash{}%
For $j \in 1 .. n$,
let $y_j$ be an atomic syntactic entity (like an identifier),
$x_j$ a composite syntactic entity (like an expression or a type),
and \DefineSymbol{E} again a composite syntactic entity.
The notation
\IndexCustom{$[x_1/y_1, \ldots, x_n/y_n]E$}{[x1/y1, ..., xn/yn]E@$[x/y\ldots]E$}
then denotes a copy of $E$
in which each occurrence of $y_i, 1 \le i \le n$ has been replaced by $x_i$.
\LMHash{}%
This operation is also known as \Index{substitution},
and it is the variant that avoids capture.
That is, when $E$ contains a construct that introduces $y_i$ into
a nested scope for some $i \in 1 .. n$,
the substitution will not replace $y_i$ in that scope.
Conversely, if such a replacement would put an identifier \id{}
(a subterm of $x_i$) into a scope where \id{} is declared,
the relevant declarations in $E$ are systematically renamed to fresh names.
\commentary{%
In short, capture freedom ensures that the ``meaning'' of each identifier
is preserved during substitution.%
}
\LMHash{}%
We sometimes abuse list or map literal syntax, writing \code{[\List{o}{1}{n}]}
(respectively \code{\{$k_1$:\ $o_1$, \ldots, $k_n$:\ $o_n$\}})
where the $o_i$ and $k_i$ may be objects rather than expressions.
The intent is to denote a list (respectively map) object
whose elements are the $o_i$
(respectively, whose keys are the $k_i$ and values are the $o_i$).
\LMHash{}%
\BlindDefineSymbol{x, op, y}%
The specifications of operators often involve statements such as
\code{$x$ \metavar{op} $y$} is equivalent to the method invocation
\IndexCustom{\rm\code{$x$.\metavar{op}($y$)}}{%
x.op(y)@\code{$x$.\metavar{op}($y$)}}.
Such specifications should be understood as a shorthand for:
\begin{itemize}
\item
$x$ $op$ $y$ is equivalent to the method invocation
\code{$x$.\metavar{op'}($y$)},
assuming the class of $x$ actually declared a non-operator method named $op'$
defining the same function as the operator $op$.
\end{itemize}
\rationale{%
This circumlocution is required because
{\rm\code{$x$.\metavar{op}($y$)}}, where op is an operator, is not legal syntax.
However, it is painfully verbose, and we prefer to state this rule once here,
and use a concise and clear notation across the specification.%
}
\LMHash{}%
When the specification refers to the order given in the program,
it means the order of the program source code text,
scanning left-to-right and top-to-bottom.
\LMHash{}%
When the specification refers to a
\IndexCustom{fresh variable}{variable!fresh},
it means a local variable with a name that doesn't occur anywhere
in the current program.
When the specification introduces a fresh variable bound to an object,
the fresh variable is implicitly bound in a surrounding scope.
\LMHash{}%
References to otherwise unspecified names of program entities
(such as classes or functions)
are interpreted as the names of members of the Dart core library.
\commentary{%
Examples would be the classes \code{Object} and \code{Type}
representing, respectively, the root of the class hierarchy and
the reification of run-time types.
%
It would be possible to declare, e.g.,
a local variable named \code{Object},
so it is generally incorrect to assume that
the name \code{Object} will actually resolve to said core class.
However, we will generally omit mentioning this, for brevity.%
}
%% TODO(eernst): We need to get rid of the concept of `is equivalent to`,
%% cf. language issue https://github.com/dart-lang/language/issues/227.
%% In this CL the phrase `treated as` has been introduced in a few places,
%% and the above-mentioned issue 227 will give rise to a complete revision
%% of this aspect of this document. In particular, the next paragraph will
%% be deleted.
\LMHash{}%
When the specification says that one piece of syntax \Index{is equivalent to}
another piece of syntax, it means that it is equivalent in all ways,
and the former syntax should generate the same compile-time errors
and have the same run-time behavior as the latter, if any.
\commentary{%
Error messages, if any, should always refer to the original syntax.%
}
If execution or evaluation of a construct is said to be
equivalent to execution or evaluation of another construct,
then only the run-time behavior is equivalent,
and compile-time errors apply only for the original syntax.
\LMHash{}%
\BlindDefineSymbol{s, s'}%
When the specification says that one piece of syntax $s$ is
\Index{treated as}
another piece of syntax $s'$,
it means that the static analysis of $s$ is the static analysis of $s'$
(\commentary{in particular, exactly the same compile-time errors occur}).
Moreover, if $s$ has no compile-time errors then
the behavior of $s$ at run time is exactly the behavior of $s'$.
\rationale{%
Error \emph{messages}, if any, should always refer to the original syntax $s$.%
}
\commentary{%
In short, whenever $s$ is treated as $s'$,
the reader should immediately switch to the section about $s'$
in order to get any further information about
the static analysis and dynamic semantics of $s$.%
}
\rationale{%
The notion of being `treated as' is similar to the notion of syntactic sugar:
``$s$ is treated as $s'$''
could as well have been worded
``$s$ is desugared into $s'$''.
Of course, it should then actually be called ``semantic sugar'',
because the applicability of the transformation and the construction of $s'$
may rely on information from static analysis.
The point is that we only specify the static analysis and dynamic semantics
of a core language which is a subset of Dart
(just slightly smaller than Dart),
and desugaring transforms any given Dart program to
a program in that core language.
This helps keeping the language specification consistent and comprehensible,
because it shows directly
that some language features are introducing essential semantics,
and others are better described as mere abbreviations of existing constructs.%
}
\LMHash{}%
The specification uses one syntactic construct, the
\IndexCustom{\LET{} expression}{let expression@\LET{} expression},
which is not derivable in the grammar
(\commentary{that is, no Dart source code contains such an expression}).
This expression is helpful in specifying certain syntactic forms
that are treated as other syntactic forms,
because it allows for introducing and initializing one or more fresh variables,
and using them in an expression.
\commentary{%
That is, a \LET{} expression is only introduced as a tool
to define the evaluation semantics of an expression
in terms of other expressions containing \LET{} expressions.%
}
\LMHash{}%
The syntax of a \LET{} expression is as follows:
\begin{grammar}
<letExpression> ::= \LET{} <staticFinalDeclarationList> \IN{} <expression>
\end{grammar}
\LMHash{}%
\BlindDefineSymbol{e_{\metavar{let}}, e_j, v_j, k}%
Let $e_{\metavar{let}}$ be a \LET{} expression of the form
\LetMany{$v_1$}{$e_1$}{$v_k$}{$e_k$}{$e$}.
It is tacitly assumed that $v_j$ is a fresh variable, $j \in 1 .. k$,
unless something is stated to the contrary.
\LMHash{}%
$e_{\metavar{let}}$ contains $k$ nested scopes, \DefineSymbol{\List{S}{1}{k}}.
The enclosing scope for $S_1$ is the current scope for $e_{\metavar{let}}$,
and the enclosing scope for $S_j$ is $S_{j-1}$, $j \in 2 .. k$.
The current scope of $e_1$ is the current scope of $e_{\metavar{let}}$,
the current scope of $e_j$ is $S_{j-1}$, $j \in 2 .. k$,
and the current scope of $e$ is $S_k$.
For $j \in 1 .. k$, $v_j$ introduces a final, local variable into $S_j$,
with the static type of $e_j$ as its declared type.
\commentary{%
Type inference of $e_j$ and the context type used for inference of $e_j$
are not relevant.
It is generally assumed that type inference has occurred already
(\ref{overview}).%
}
\LMHash{}%
Evaluation of $e_{\metavar{let}}$ proceeds by
evaluating $e_j$ to an object $o_j$ and binding $v_j$ to $o_j$,
where $j \in 1 .. k$, in that order.
Finally, $e$ is evaluated to an object $o$ and then
$e_{\metavar{let}}$ evaluates to $o$.
\LMHash{}%
The right margin of each page in this document is used to indicate
referenced entities.
\LMHash{}%
The document contains an index at the end.
Each entry in the index refers to a page number, $p$.
On page $p$ there is a `$\diamond$' in the margin
at the definition of the given indexed phrase,
and the phrase itself is shown using \emph{this typeface}.
We have hereby introduced the
\Index{index marker $\diamond$}
itself.
\LMHash{}%
The right margin also contains symbols.
Whenever a symbol
\BlindDefineSymbol{\textcolor{commentaryColor}{C}}%
\BlindDefineSymbol{\textcolor{commentaryColor}{x_j}}%
(\commentary{say, $C$ or $x_j$})
is introduced and used in more than a few lines of text,
it is shown in the margin.
\commentary{%
The point is that it is easy to find the definition of a symbol
by scanning back in the text until that symbol occurs in the margin.
To avoid useless verbosity, some symbols are not mentioned in the margin.
For instance, we may introduce \List{e}{1}{k},
but only show $e_j$ and $k$ in the margin.
Note that it may be necessary to look at a few lines of text
above the `$\diamond$' or symbol,
because the margin markers can be pushed down one line
when there is more than one marker for a single line.%
}
\section{Overview}
\LMLabel{overview}
\LMHash{}%
Dart is a class-based, single-inheritance, pure
object-oriented programming language.
Dart is optionally typed (\ref{types}) and supports reified generics.
The run-time type of every object is represented as
an instance of class \code{Type} which can be obtained
by calling the getter \code{runtimeType} declared in class \code{Object},
the root of the Dart class hierarchy.
\LMHash{}%
Dart programs may be statically checked.
Programs with compile-time errors do not have a specified dynamic semantics.
This specification makes no attempt to answer additional questions
about a library or program at the point
where it is known to have a compile-time error.
\commentary{%
However, tools may choose to support execution of some programs with errors.
For instance, a compiler may compile certain constructs with errors such that
a dynamic error will be raised if an attempt is made to
execute such a construct,
or an IDE integrated runtime may support opening
an editor window when such a construct is executed,
allowing developers to correct the error.
It is expected that such features would amount to a natural extension of the
dynamic semantics of Dart as specified here, but, as mentioned,
this specification makes no attempt to specify exactly what that means.%
}
\LMHash{}%
As specified in this document,
dynamic checks are guaranteed to be performed in certain situations,
and certain violations of the type system throw exceptions at run time.
\commentary{%
An implementation is free to omit such checks whenever they are
guaranteed to succeed, e.g., based on results from the static analysis.%
}
\commentary{%
The coexistence between optional typing and reification
is based on the following:
\begin{enumerate}
\item
Reified type information reflects the types of objects at run time
and may always be queried by dynamic typechecking constructs
(the analogs of instanceOf, casts, typecase etc.\ in other languages).
Reified type information includes
access to instances of class \code{Type} representing types,
the run-time type (aka class) of an object,
and the actual values of type parameters
to constructors and generic function invocations.
\item
Type annotations declare the types of
variables and functions (including methods and constructors).
\item
%% TODO(eernst): Change when integrating instantiate-to-bounds.md.
Type annotations may be omitted, in which case they are generally
filled in with the type \DYNAMIC{}
(\ref{typeDynamic}).
\end{enumerate}%
}
%% TODO(eernst): Update when we add inference.
\commentary{%
Dart as implemented includes extensive support for inference of omitted types.
This specification makes the assumption that inference has taken place,
and hence inferred types are considered to be present in the program already.
However, in some cases no information is available
to infer an omitted type annotation,
and hence this specification still needs to specify how to deal with that.
A future version of this specification will also specify type inference.%
}
\LMHash{}%
Dart programs are organized in a modular fashion into
units called \NoIndex{libraries} (\ref{librariesAndScripts}).
Libraries are units of encapsulation and may be mutually recursive.
\commentary{%
However they are not first class.
To get multiple copies of a library running simultaneously,
one needs to spawn an isolate.%
}
\LMHash{}%
A dart program execution may occur with assertions enabled or disabled.
The method used to enable or disable assertions is implementation specific.
\subsection{Scoping}
\LMLabel{scoping}
\LMHash{}%
A \IndexCustom{compile-time namespace}{namespace!compile-time}
is a partial function that maps names to namespace values.
Compile-time namespaces are used much more frequently than run-time namespaces
(\commentary{defined later in this section}),
so when the word \Index{namespace} is used alone,
it means compile-time namespace.
A \Index{name} is a lexical token which is an \synt{IDENTIFIER},
an \synt{IDENTIFIER} followed by \lit{=}, or
an \synt{operator},
or \code{unary-};
and a \Index{namespace value} is
a declaration, a namespace, or the special value \ConflictValue{}
(\ref{conflictMergingOfNamespaces}).
\LMHash{}%
If $\Namespace{}{n} = V$ then we say that \NamespaceName{}
\IndexCustom{maps}{namespace!maps a key to a value}
the
\IndexCustom{key}{namespace!key}
$n$ to the
\IndexCustom{value}{namespace!value}
$V$,
and that \NamespaceName{}
\IndexCustom{has the binding}{namespace!has a binding}
$n\mapsto{}V$.
\commentary{%
The fact that \NamespaceName{} is a partial function just means that
each name is mapped to at most one namespace value.
That is, if \NamespaceName{} has the bindings
$n\mapsto{}V_1$ and $n\mapsto{}V_2$
then $V_1 = V_2$.%
}
\LMHash{}%
Let \NamespaceName{} be a namespace.
We say that a name $n$ \Index{is in} \NamespaceName{}
if $n$ is a key of \NamespaceName.
We say a declaration $d$ \NoIndex{is in} \NamespaceName{}
if a key of \NamespaceName{} is mapped to $d$.
\LMHash{}%
A scope $S_0$ has an associated namespace \NamespaceName{0}.
The bindings of \NamespaceName{0} is specified in this document by saying that
a given declaration \BlindDefineSymbol{D, n}$D$ named $n$
\IndexCustom{introduces}{declaration!introduces an entity into a scope}
a specific entity \DefineSymbol{V} into $S_0$,
which means that the binding $n\mapsto{}V$ is added to \NamespaceName{0}.
\commentary{%
In some cases, the name of the declaration differs from
the identifier that occurs in the declaration syntax used to declare it.
Setters have names that are distinct from the corresponding getters
because they always have an \lit{=} automatically added at the end,
and the unary minus operator has the special name \code{unary-}.%
}
\commentary{%
It is typically the case that $V$ is the declaration $D$ itself,
but there are exceptions.
For example,
a variable declaration introduces an implicitly induced getter declaration,
and in some cases also an implicitly induced setter declaration into the