OLD | NEW |
---|---|
1 \documentclass{article} | 1 \documentclass{article} |
2 \usepackage{epsfig} | 2 \usepackage{epsfig} |
3 \usepackage{color} | 3 \usepackage{color} |
4 \usepackage{dart} | 4 \usepackage{dart} |
5 \usepackage{bnf} | 5 \usepackage{bnf} |
6 \usepackage{hyperref} | 6 \usepackage{hyperref} |
7 \usepackage{lmodern} | 7 \usepackage{lmodern} |
8 \newcommand{\code}[1]{{\sf #1}} | 8 \newcommand{\code}[1]{{\sf #1}} |
9 \title{Dart Programming Language Specification \\ | 9 \title{Dart Programming Language Specification \\ |
10 (4th edition draft)\\ | 10 {4th edition draft}\\ |
11 {\large Version 1.11}} | 11 {\large Version 1.14}} |
12 | 12 |
13 % For information about Location Markers (and in particular the | 13 % For information about Location Markers (and in particular the |
14 % commands \LMHash and \LMLabel), see the long comment at the | 14 % commands \LMHash and \LMLabel), see the long comment at the |
15 % end of this file. | 15 % end of this file. |
16 | 16 |
17 \begin{document} | 17 \begin{document} |
18 \maketitle | 18 \maketitle |
19 \tableofcontents | 19 \tableofcontents |
20 | 20 |
21 | 21 |
22 \newpage | 22 \newpage |
23 | 23 |
24 \pagestyle{myheadings} | 24 \pagestyle{myheadings} |
25 \markright{Dart Programming Language Specification} | 25 \markright{Dart Programming Language Specification} |
26 | 26 |
27 % begin Ecma boilerplate | 27 % begin Ecma boilerplate |
28 \section{Scope} | 28 \section{Scope} |
29 \LMLabel{ecmaScope} | 29 \LMLabel{ecmaScope} |
30 | 30 |
31 \LMHash{} | 31 \LMHash{} |
32 This Ecma standard specifies the syntax and semantics of the Dart programming la nguage. It does not specify the APIs of the Dart libraries except where those l ibrary elements are essential to the correct functioning of the language itself (e.g., the existence of class \cd{Object} with methods such as \cd{noSuchMethod} , \cd{runtimeType}). | 32 This Ecma standard specifies the syntax and semantics of the Dart programming la nguage. It does not specify the APIs of the Dart libraries except where those l ibrary elements are essential to the correct functioning of the language itself (e.g., the existence of class \cd{Object} with methods such as \cd{noSuchMethod} , \cd{runtimeType}). |
33 | 33 |
34 \section{Conformance} | 34 \section{Conformance} |
35 \LMLabel{ecmaConformance} | 35 \LMLabel{ecmaConformance} |
36 | 36 |
37 \LMHash{} | 37 \LMHash{} |
38 A conforming implementation of the Dart programming language must provide and s upport all the APIs (libraries, types, functions, getters, setters, whether top -level, static, instance or local) mandated in this specification. | 38 A conforming implementation of the Dart programming language must provide and s upport all the APIs (libraries, types, functions, getters, setters, whether top -level, static, instance or local) mandated in this specification. |
39 | 39 |
40 \LMHash{} | 40 \LMHash{} |
41 A conforming implementation is permitted to provide additional APIs, but not add itional syntax, except for experimental features in support of null-aware cascad es and tear-offs that are likely to be introduced in the next revision of this s pecification. | 41 A conforming implementation is permitted to provide additional APIs, but not add itional syntax, except for experimental features in support of null-aware cascad es and tear-offs that are likely to be introduced in the next revision of this s pecification. |
42 | 42 |
43 \section{Normative References} | 43 \section{Normative References} |
44 \LMLabel{ecmaNormativeReferences} | 44 \LMLabel{ecmaNormativeReferences} |
45 | 45 |
46 \LMHash{} | 46 \LMHash{} |
47 The following referenced documents are indispensable for the application of this document. For dated references, only the edition cited applies. For undated ref erences, the latest edition of the referenced document (including any amendments ) applies. | 47 The following referenced documents are indispensable for the application of this document. For dated references, only the edition cited applies. For undated ref erences, the latest edition of the referenced document (including any amendments ) applies. |
48 | 48 |
49 \begin{enumerate} | 49 \begin{enumerate} |
50 \item | 50 \item |
51 The Unicode Standard, Version 5.0, as amended by Unicode 5.1.0, or successor. | 51 The Unicode Standard, Version 5.0, as amended by Unicode 5.1.0, or successor. |
52 \item | 52 \item |
53 Dart API Reference, https://api.dartlang.org/ | 53 Dart API Reference, https://api.dartlang.org/ |
54 \end{enumerate} | 54 \end{enumerate} |
55 | 55 |
56 | 56 |
57 \section{Terms and Definitions} | 57 \section{Terms and Definitions} |
58 \LMLabel{ecmaTermsAndDefinitions} | 58 \LMLabel{ecmaTermsAndDefinitions} |
59 | 59 |
60 \LMHash{} | 60 \LMHash{} |
61 Terms and definitions used in this specification are given in the body of the sp ecification proper. Such terms are highlighted in italics when they are introduc ed, e.g., `we use the term {\em verbosity} to refer to the property of excess ve rbiage'. | 61 Terms and definitions used in this specification are given in the body of the sp ecification proper. Such terms are highlighted in italics when they are introduc ed, e.g., `we use the term {\em verbosity} to refer to the property of excess ve rbiage'. |
62 % End Ecma Boilerplate | 62 % End Ecma Boilerplate |
63 | 63 |
64 | 64 |
65 \section{Notation} | 65 \section{Notation} |
66 \LMLabel{notation} | 66 \LMLabel{notation} |
67 | 67 |
68 \LMHash{} | 68 \LMHash{} |
69 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 in cludes: | 69 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 in cludes: |
70 \begin{itemize} | 70 \begin{itemize} |
71 \item[Rationale] Discussion of the motivation for language design decisions appe ars in italics. \rationale{Distinguishing normative from non-normative helps cla rify what part of the text is binding and what part is merely expository.} | 71 \item[Rationale] Discussion of the motivation for language design decisions appe ars in italics. \rationale{Distinguishing normative from non-normative helps cla rify what part of the text is binding and what part is merely expository.} |
72 \item[Commentary] Comments such as ``\commentary{The careful reader will have n oticed that the name Dart has four characters}'' serve to illustrate or clarify the specification, but are redundant with the normative text. \commentary{The d ifference between commentary and rationale can be subtle.} \rationale{ Commentar y is more general than rationale, and may include illustrative examples or clari fications. } | 72 \item[Commentary] Comments such as ``\commentary{The careful reader will have n oticed that the name Dart has four characters}'' serve to illustrate or clarify the specification, but are redundant with the normative text. \commentary{The d ifference between commentary and rationale can be subtle.} \rationale{ Commentar y is more general than rationale, and may include illustrative examples or clari fications. } |
73 \item[Open questions] (\Q{in this font}). Open questions are points that are uns ettled in the mind of the author(s) of the specification; expect them (the quest ions, not the authors; precision is important in a specification) to be eliminat ed in the final specification. \Q{Should the text at the end of the previous bul let be rationale or commentary?} | 73 \item[Open questions] (\Q{in this font}). Open questions are points that are uns ettled in the mind of the author(s) of the specification; expect them (the quest ions, not the authors; precision is important in a specification) to be eliminat ed in the final specification. \Q{Should the text at the end of the previous bul let be rationale or commentary?} |
74 \end{itemize} | 74 \end{itemize} |
(...skipping 22 matching lines...) Expand all Loading... | |
97 (Some Grouped Things); | 97 (Some Grouped Things); |
98 \~{}NotAThing; | 98 \~{}NotAThing; |
99 A\_LEXICAL\_THING | 99 A\_LEXICAL\_THING |
100 . | 100 . |
101 } | 101 } |
102 \end{grammar} | 102 \end{grammar} |
103 | 103 |
104 % need a match anything or a production that does that, so we can correct bugs w rt use | 104 % need a match anything or a production that does that, so we can correct bugs w rt use |
105 % ~. ~ does not actually parse stuff - it just looks ahead and checks. To get th e effect of | 105 % ~. ~ does not actually parse stuff - it just looks ahead and checks. To get th e effect of |
106 % parsing anything but X, one needs ~X ANYTHING, not just ~X. There are bugs in the | 106 % parsing anything but X, one needs ~X ANYTHING, not just ~X. There are bugs in the |
107 % grammar related to this. | 107 % grammar related to this. |
108 % The alternative is to define ~X as anything but X, or to introduce an anthingB ut(X) | 108 % The alternative is to define ~X as anything but X, or to introduce an anthingB ut(X) |
109 % combinator, such as !X | 109 % combinator, such as !X |
110 | 110 |
111 \LMHash{} | 111 \LMHash{} |
112 Both syntactic and lexical productions are represented this way. Lexical product ions are distinguished by their names. The names of lexical productions consist exclusively of upper case characters and underscores. As always, within grammat ical productions, whitespace and comments between elements of the production are implicitly ignored unless stated otherwise. | 112 Both syntactic and lexical productions are represented this way. Lexical product ions are distinguished by their names. The names of lexical productions consist exclusively of upper case characters and underscores. As always, within grammat ical productions, whitespace and comments between elements of the production are implicitly ignored unless stated otherwise. |
113 Punctuation tokens appear in quotes. | 113 Punctuation tokens appear in quotes. |
114 | 114 |
115 \LMHash{} | 115 \LMHash{} |
116 Productions are embedded, as much as possible, in the discussion of the construc ts they represent. | 116 Productions are embedded, as much as possible, in the discussion of the construc ts they represent. |
117 | 117 |
118 \LMHash{} | 118 \LMHash{} |
119 A list $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. | 119 A list $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. |
120 | 120 |
121 \LMHash{} | 121 \LMHash{} |
122 The notation $[x_1, \ldots, x_n/y_1, \ldots, y_n]E$ denotes a copy of $E$ in whi ch all occurrences of $y_i, 1 \le i \le n$ have been replaced with $x_i$. | 122 The notation $[x_1, \ldots, x_n/y_1, \ldots, y_n]E$ denotes a copy of $E$ in whi ch all occurrences of $y_i, 1 \le i \le n$ have been replaced with $x_i$. |
123 | 123 |
124 \LMHash{} | 124 \LMHash{} |
125 We sometimes abuse list or map literal syntax, writing $[o_1, \ldots, o_n]$ (re spectively $\{k_1: o_1, \ldots, k_n: o_n\}$) where the $o_i$ and $k_i$ may be ob jects 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$). | 125 We sometimes abuse list or map literal syntax, writing $[o_1, \ldots, o_n]$ (re spectively $\{k_1: o_1, \ldots, k_n: o_n\}$) where the $o_i$ and $k_i$ may be ob jects 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$). |
126 | 126 |
127 \LMHash{} | 127 \LMHash{} |
128 The specifications of operators often involve statements such as $x$ $op$ $y$ is equivalent to the method invocation $x.op(y)$. Such specifications should be un derstood as a shorthand for: | 128 The specifications of operators often involve statements such as $x$ $op$ $y$ is equivalent to the method invocation $x.op(y)$. Such specifications should be un derstood as a shorthand for: |
129 \begin{itemize} | 129 \begin{itemize} |
130 \item | 130 \item |
131 $x$ $op$ $y$ is equivalent to the method invocation $x.op^\prime(y)$, assuming the class of $x$ actually declared a non-operator method named $op^\prime$ defin ing the same function as the operator $op$. | 131 $x$ $op$ $y$ is equivalent to the method invocation $x.op^\prime(y)$, assuming the class of $x$ actually declared a non-operator method named $op^\prime$ defin ing the same function as the operator $op$. |
132 \end{itemize} | 132 \end{itemize} |
133 | 133 |
134 \rationale{This circumlocution is required because x.op(y), where op is an oper ator, is not legal syntax. However, it is painfully verbose, and we prefer to st ate this rule once here, and use a concise and clear notation across the specifi cation. | 134 \rationale{This circumlocution is required because x.op(y), where op is an oper ator, is not legal syntax. However, it is painfully verbose, and we prefer to st ate this rule once here, and use a concise and clear notation across the specifi cation. |
135 } | 135 } |
136 | 136 |
137 \LMHash{} | 137 \LMHash{} |
138 When the specification refers to the order given in the program, it means the or der of the program source code text, scanning left-to-right and top-to-bottom. | 138 When the specification refers to the order given in the program, it means the or der of the program source code text, scanning left-to-right and top-to-bottom. |
139 | 139 |
140 \LMHash{} | 140 \LMHash{} |
141 References to otherwise unspecified names of program entities (such as classes o r functions) are interpreted as the names of members of the Dart core library. | 141 References to otherwise unspecified names of program entities (such as classes o r functions) are interpreted as the names of members of the Dart core library. |
142 | 142 |
143 \commentary{ | 143 \commentary{ |
144 Examples would be the classes \code{Object} and \code{Type} representing the roo t of the class hierarchy and the reification of runtime types respectively. | 144 Examples would be the classes \code{Object} and \code{Type} representing the roo t of the class hierarchy and the reification of runtime types respectively. |
145 } | 145 } |
146 | 146 |
147 \section{Overview} | 147 \section{Overview} |
148 \LMLabel{overview} | 148 \LMLabel{overview} |
149 | 149 |
150 \LMHash{} | 150 \LMHash{} |
151 Dart is a class-based, single-inheritance, pure object-oriented programming lang uage. 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 cl ass \code{Object}, the root of the Dart class hierarchy. | 151 Dart is a class-based, single-inheritance, pure object-oriented programming lang uage. 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 cl ass \code{Object}, the root of the Dart class hierarchy. |
152 | 152 |
153 \LMHash{} | 153 \LMHash{} |
154 Dart programs may be statically checked. The static checker will report some vio lations of the type rules, but such violations do not abort compilation or precl ude execution. | 154 Dart programs may be statically checked. The static checker will report some vio lations of the type rules, but such violations do not abort compilation or precl ude execution. |
155 | 155 |
156 \LMHash{} | 156 \LMHash{} |
157 Dart programs may be executed in one of two modes: production mode or checked mo de. In production mode, static type annotations (\ref{staticTypes}) have absolut ely no effect on execution with the exception of reflection and structural type tests. | 157 Dart programs may be executed in one of two modes: production mode or checked mo de. In production mode, static type annotations (\ref{staticTypes}) have absolut ely no effect on execution with the exception of reflection and structural type tests. |
158 | 158 |
159 \commentary{ | 159 \commentary{ |
160 Reflection, by definition, examines the program structure. If we provide reflect ive access to the type of a declaration, or to source code, it will inevitably p roduce results that depend on the types used in the underlying code. | 160 Reflection, by definition, examines the program structure. If we provide reflect ive access to the type of a declaration, or to source code, it will inevitably p roduce results that depend on the types used in the underlying code. |
161 | 161 |
162 Type tests also examine the types in a program explicitly. Nevertheless, in most cases, these will not depend on type annotations. The exceptions to this rule a re type tests involving function types. Function types are structural, and so de pend on the types declared for their parameters and on their return types. | 162 Type tests also examine the types in a program explicitly. Nevertheless, in most cases, these will not depend on type annotations. The exceptions to this rule a re type tests involving function types. Function types are structural, and so de pend on the types declared for their parameters and on their return types. |
163 } | 163 } |
164 | 164 |
165 \LMHash{} | 165 \LMHash{} |
166 In checked mode, assignments are dynamically checked, and certain violations of the type system raise exceptions at run time. | 166 In checked mode, assignments are dynamically checked, and certain violations of the type system raise exceptions at run time. |
167 | 167 |
168 \commentary{ | 168 \commentary{ |
169 The coexistence between optional typing and reification is based on the followin g: | 169 The coexistence between optional typing and reification is based on the followin g: |
170 \begin{enumerate} | 170 \begin{enumerate} |
171 \item Reified type information reflects the types of objects at runtime and may always be queried by dynamic typechecking constructs (the analogs of instanceOf, casts, typecase etc. in other languages). Reified type information includes cla ss declarations, the runtime type (aka class) of an object, and type arguments t o constructors. | 171 \item Reified type information reflects the types of objects at runtime and may always be queried by dynamic typechecking constructs (the analogs of instanceOf, casts, typecase etc. in other languages). Reified type information includes cla ss declarations, the runtime type (aka class) of an object, and type arguments t o constructors. |
172 \item Static type annotations determine the types of variables and function decl arations (including methods and constructors). | 172 \item Static type annotations determine the types of variables and function decl arations (including methods and constructors). |
173 \item Production mode respects optional typing. Static type annotations do not a ffect runtime behavior. | 173 \item Production mode respects optional typing. Static type annotations do not a ffect runtime behavior. |
174 \item Checked mode utilizes static type annotations and dynamic type information aggressively yet selectively to provide early error detection during developmen t. | 174 \item Checked mode utilizes static type annotations and dynamic type information aggressively yet selectively to provide early error detection during developmen t. |
175 \end{enumerate} | 175 \end{enumerate} |
176 } | 176 } |
177 | 177 |
178 \LMHash{} | 178 \LMHash{} |
179 Dart programs are organized in a modular fashion into units called {\em librarie s} (\ref{librariesAndScripts}). Libraries are units of encapsulation and may be mutually recursive. | 179 Dart programs are organized in a modular fashion into units called {\em librarie s} (\ref{librariesAndScripts}). Libraries are units of encapsulation and may be mutually recursive. |
180 | 180 |
181 \commentary{However they are not first class. To get multiple copies of a libra ry running simultaneously, one needs to spawn an isolate. | 181 \commentary{However they are not first class. To get multiple copies of a libra ry running simultaneously, one needs to spawn an isolate. |
182 } | 182 } |
183 | 183 |
184 \subsection{Scoping} | 184 \subsection{Scoping} |
185 \LMLabel{scoping} | 185 \LMLabel{scoping} |
186 | 186 |
187 \LMHash{} | 187 \LMHash{} |
188 A {\em namespace} is a mapping of names denoting declarations to actual declarat ions. Let $NS$ be a namespace. We say that a name $n$ {\em is in }$NS$ if $n$ i s a key of $NS$. We say a declaration $d$ {\em is in }$NS$ if a key of $NS$ maps to $d$. | 188 A {\em namespace} is a mapping of names denoting declarations to actual declarat ions. Let $NS$ be a namespace. We say that a name $n$ {\em is in }$NS$ if $n$ i s a key of $NS$. We say a declaration $d$ {\em is in }$NS$ if a key of $NS$ maps to $d$. |
189 | 189 |
190 \LMHash{} | 190 \LMHash{} |
191 A scope $S_0$ induces a namespace $NS_0$ that maps the simple name of each varia ble, type or function declaration $d$ declared in $S_0$ to $d$. Labels are not i ncluded in the induced namespace of a scope; instead they have their own dedicat ed namespace. | 191 A scope $S_0$ induces a namespace $NS_0$ that maps the simple name of each varia ble, type or function declaration $d$ declared in $S_0$ to $d$. Labels are not i ncluded in the induced namespace of a scope; instead they have their own dedicat ed namespace. |
192 | 192 |
193 \commentary{It is therefore impossible, e.g., to define a class that declares a method and a field with the same name in Dart. Similarly one cannot declare a t op-level function with the same name as a library variable or class. | 193 \commentary{It is therefore impossible, e.g., to define a class that declares a method and a field with the same name in Dart. Similarly one cannot declare a t op-level function with the same name as a library variable or class. |
194 } | 194 } |
195 | 195 |
196 \LMHash{} | 196 \LMHash{} |
197 It is a compile-time error if there is more than one entity with the same name d eclared in the same scope. | 197 It is a compile-time error if there is more than one entity with the same name d eclared in the same scope. |
198 | 198 |
199 \commentary{ | 199 \commentary{ |
200 In some cases, the name of the declaration differs from the identifier used to d eclare it. Setters have names that are distinct from the corresponding getters because they always have an = automatically added at the end, and unary minus ha s the special name unary-. | 200 In some cases, the name of the declaration differs from the identifier used to d eclare it. Setters have names that are distinct from the corresponding getters because they always have an = automatically added at the end, and unary minus ha s the special name unary-. |
201 } | 201 } |
202 | 202 |
203 \LMHash{} | 203 \LMHash{} |
204 Dart is lexically scoped. Scopes may nest. A name or declaration $d$ is {\em available in scope} $S$ if $d$ is in the namespace induced by $S$ or if $d$ is available in the lexically enclosing scope of $S$. We say that a name or declar ation $d$ is {\em in scope} if $d$ is available in the current scope. | 204 Dart is lexically scoped. Scopes may nest. A name or declaration $d$ is {\em available in scope} $S$ if $d$ is in the namespace induced by $S$ or if $d$ is available in the lexically enclosing scope of $S$. We say that a name or declar ation $d$ is {\em in scope} if $d$ is available in the current scope. |
205 | 205 |
206 | 206 |
207 \LMHash{} | 207 \LMHash{} |
208 If a declaration $d$ named $n$ is in the namespace induced by a scope $S$, then $d$ {\em hides} any declaration named $n$ that is available in the lexically en closing scope of $S$. | 208 If a declaration $d$ named $n$ is in the namespace induced by a scope $S$, then $d$ {\em hides} any declaration named $n$ that is available in the lexically en closing scope of $S$. |
209 | 209 |
210 \commentary { | 210 \commentary { |
211 A consequence of these rules is that it is possible to hide a type with a method or variable. | 211 A consequence of these rules is that it is possible to hide a type with a method or variable. |
212 Naming conventions usually prevent such abuses. Nevertheless,the following progr am is legal: | 212 Naming conventions usually prevent such abuses. Nevertheless,the following progr am is legal: |
213 } | 213 } |
214 | 214 |
215 \begin{dartCode} | 215 \begin{dartCode} |
216 \CLASS{} HighlyStrung \{ | 216 \CLASS{} HighlyStrung \{ |
217 String() $=>$ "?"; | 217 String() $=>$ "?"; |
218 \} | 218 \} |
(...skipping 25 matching lines...) Expand all Loading... | |
244 \CLASS{} S \{foo() =$>$ 91;\} | 244 \CLASS{} S \{foo() =$>$ 91;\} |
245 \end{dartCode} | 245 \end{dartCode} |
246 | 246 |
247 \rationale{ | 247 \rationale{ |
248 If inheritance took precedence over the lexical scope, the behavior of \code{C} would change in an unexpected way. Neither the author of \code{S} nor the author of \code{C} are necessarily aware of this. In Dart, if there is a lexically vis ible method \code{foo()}, it will always be called. | 248 If inheritance took precedence over the lexical scope, the behavior of \code{C} would change in an unexpected way. Neither the author of \code{S} nor the author of \code{C} are necessarily aware of this. In Dart, if there is a lexically vis ible method \code{foo()}, it will always be called. |
249 | 249 |
250 Now consider the opposite scenario. We start with a version of \code{S} that con tains \code{foo()}, but do not declare \code{foo()} in library \code{L2}. Again , there is a change in behavior - but the author of \code{L2} is the one who int roduced the discrepancy that effects their code, and the new code is lexically v isible. Both these factors make it more likely that the problem will be detected . | 250 Now consider the opposite scenario. We start with a version of \code{S} that con tains \code{foo()}, but do not declare \code{foo()} in library \code{L2}. Again , there is a change in behavior - but the author of \code{L2} is the one who int roduced the discrepancy that effects their code, and the new code is lexically v isible. Both these factors make it more likely that the problem will be detected . |
251 | 251 |
252 These considerations become even more important if one introduces constructs suc h as nested classes, which might be considered in future versions of the languag e. | 252 These considerations become even more important if one introduces constructs suc h as nested classes, which might be considered in future versions of the languag e. |
253 | 253 |
254 Good tooling should of course endeavor to inform programmers of such situations (discreetly). For example, an identifier that is both inherited and lexically vi sible could be highlighted (via underlining or colorization). Better yet, tight integration of source control with language aware tools would detect such change s when they occur. | 254 Good tooling should of course endeavor to inform programmers of such situations (discreetly). For example, an identifier that is both inherited and lexically vi sible could be highlighted (via underlining or colorization). Better yet, tight integration of source control with language aware tools would detect such change s when they occur. |
255 | 255 |
256 } | 256 } |
257 | 257 |
258 | 258 |
259 | 259 |
260 | 260 |
261 \subsection{Privacy} | 261 \subsection{Privacy} |
262 \LMLabel{privacy} | 262 \LMLabel{privacy} |
263 | 263 |
264 \LMHash{} | 264 \LMHash{} |
265 Dart supports two levels of privacy: {\em public} and {\em private}. A declarat ion is {\em private} iff its name is private, otherwise it is {\em public.} A name $q$ is private iff any one of the identifiers that comprise $q$ is private, otherwise it is {\em public.} An identifier is private iff it | 265 Dart supports two levels of privacy: {\em public} and {\em private}. A declarat ion is {\em private} iff its name is private, otherwise it is {\em public.} A name $q$ is private iff any one of the identifiers that comprise $q$ is private, otherwise it is {\em public.} An identifier is private iff it |
266 begins with an underscore (the \_ character) otherwise it is {\em public.} | 266 begins with an underscore (the \_ character) otherwise it is {\em public.} |
267 | 267 |
268 \LMHash{} | 268 \LMHash{} |
269 A declaration $m$ is {\em accessible to library $L$} if $m$ is declared in $L$ or if $m$ is public. | 269 A declaration $m$ is {\em accessible to library $L$} if $m$ is declared in $L$ or if $m$ is public. |
270 | 270 |
271 \commentary{ | 271 \commentary{ |
272 This means private declarations may only be accessed within the library in which they are declared. | 272 This means private declarations may only be accessed within the library in which they are declared. |
273 } | 273 } |
274 | 274 |
275 \LMHash{} | 275 \LMHash{} |
276 Privacy applies only to declarations within a library, not to library declaratio ns themselves. | 276 Privacy applies only to declarations within a library, not to library declaratio ns themselves. |
277 | 277 |
278 \rationale{Libraries do not reference each other by name and so the idea of a pr ivate library is meaningless. | 278 \rationale{Libraries do not reference each other by name and so the idea of a pr ivate library is meaningless. |
279 Thus, if the name of a library begins with an underscore, it has no effect on th e accessibility of the library or its members. | 279 Thus, if the name of a library begins with an underscore, it has no effect on th e accessibility of the library or its members. |
280 } | 280 } |
281 | 281 |
282 \rationale{Privacy is, at this point, a static notion tied to a particular piece of code (a library). It is designed to support software engineering concerns ra ther than security concerns. Untrusted code should always run in an another isol ate. It is possible that libraries will become first class objects and privacy will be a dynamic notion tied to a library instance. | 282 \rationale{Privacy is, at this point, a static notion tied to a particular piece of code (a library). It is designed to support software engineering concerns ra ther than security concerns. Untrusted code should always run in an another isol ate. It is possible that libraries will become first class objects and privacy will be a dynamic notion tied to a library instance. |
283 | 283 |
284 Privacy is indicated by the name of a declaration - hence privacy and naming are not orthogonal. This has the advantage that both humans and machines can recogn ize access to private declarations at the point of use without knowledge of the context from which the declaration is derived.} | 284 Privacy is indicated by the name of a declaration - hence privacy and naming are not orthogonal. This has the advantage that both humans and machines can recogn ize access to private declarations at the point of use without knowledge of the context from which the declaration is derived.} |
285 | 285 |
286 \subsection{Concurrency} | 286 \subsection{Concurrency} |
287 \LMLabel{concurrency} | 287 \LMLabel{concurrency} |
288 | 288 |
289 \LMHash{} | 289 \LMHash{} |
290 Dart code is always single threaded. There is no shared-state concurrency in Dar t. Concurrency is supported via actor-like entities called {\em isolates}. | 290 Dart code is always single threaded. There is no shared-state concurrency in Dar t. Concurrency is supported via actor-like entities called {\em isolates}. |
291 | 291 |
292 \LMHash{} | 292 \LMHash{} |
293 An isolate is a unit of concurrency. It has its own memory and its own thread of control. Isolates communicate by message passing (\ref{sendingMessages}). No st ate is ever shared between isolates. Isolates are created by spawning (\ref{spaw ningAnIsolate}). | 293 An isolate is a unit of concurrency. It has its own memory and its own thread of control. Isolates communicate by message passing (\ref{sendingMessages}). No st ate is ever shared between isolates. Isolates are created by spawning (\ref{spaw ningAnIsolate}). |
294 | 294 |
295 | 295 |
296 \section{Errors and Warnings} | 296 \section{Errors and Warnings} |
297 \LMLabel{errorsAndWarnings} | 297 \LMLabel{errorsAndWarnings} |
298 | 298 |
299 \LMHash{} | 299 \LMHash{} |
300 This specification distinguishes between several kinds of errors. | 300 This specification distinguishes between several kinds of errors. |
301 | 301 |
302 \LMHash{} | 302 \LMHash{} |
303 {\em Compile-time errors} are errors that preclude execution. A compile-time err or must be reported by a Dart compiler before the erroneous code is executed. | 303 {\em Compile-time errors} are errors that preclude execution. A compile-time err or must be reported by a Dart compiler before the erroneous code is executed. |
304 | 304 |
305 \rationale{A Dart implementation has considerable freedom as to when compilation takes place. Modern programming language implementations often interleave compi lation and execution, so that compilation of a method may be delayed, e.g., unt il it is first invoked. Consequently, compile-time errors in a method $m$ may be reported as late as the time of $m$'s first invocation. | 305 \rationale{A Dart implementation has considerable freedom as to when compilation takes place. Modern programming language implementations often interleave compi lation and execution, so that compilation of a method may be delayed, e.g., unt il it is first invoked. Consequently, compile-time errors in a method $m$ may be reported as late as the time of $m$'s first invocation. |
306 | 306 |
307 As a web language, Dart is often loaded directly from source, with no intermedia te binary representation. In the interests of rapid loading, Dart implementation s may choose to avoid full parsing of method bodies, for example. This can be do ne by tokenizing the input and checking for balanced curly braces on method body entry. In such an implementation, even syntax errors will be detected only when the method needs to be executed, at which time it will be compiled (JITed). | 307 As a web language, Dart is often loaded directly from source, with no intermedia te binary representation. In the interests of rapid loading, Dart implementation s may choose to avoid full parsing of method bodies, for example. This can be do ne by tokenizing the input and checking for balanced curly braces on method body entry. In such an implementation, even syntax errors will be detected only when the method needs to be executed, at which time it will be compiled (JITed). |
308 | 308 |
309 In a development environment a compiler should of course report compilation erro rs eagerly so as to best serve the programmer. | 309 In a development environment a compiler should of course report compilation erro rs eagerly so as to best serve the programmer. |
310 } | 310 } |
311 | 311 |
312 \LMHash{} | 312 \LMHash{} |
313 If an uncaught compile-time error occurs within the code of a running isolate $A $, $A$ is immediately suspended. The only circumstance where a compile-time err or could be caught would be via code run reflectively, where the mirror system c an catch it. | 313 If an uncaught compile-time error occurs within the code of a running isolate $A $, $A$ is immediately suspended. The only circumstance where a compile-time err or could be caught would be via code run reflectively, where the mirror system c an catch it. |
314 | 314 |
315 \rationale{Typically, once a compile-time error is thrown and $A$ is suspended, $A$ will then be terminated. However, this depends on the overall environment. | 315 \rationale{Typically, once a compile-time error is thrown and $A$ is suspended, $A$ will then be terminated. However, this depends on the overall environment. |
316 A Dart engine runs in the context of an {\em embedder}, | 316 A Dart engine runs in the context of an {\em embedder}, |
317 a program that interfaces between the engine and the surrounding computing envir onment. The embedder will often be a web browser, but need not be; it may be a C ++ program on the server for example. When an isolate fails with a compile-time error as described above, control returns to the embedder, along with an excepti on describing the problem. This is necessary so that the embedder can clean up resources etc. It is then the embedder's decision whether to terminate the isola te or not. | 317 a program that interfaces between the engine and the surrounding computing envir onment. The embedder will often be a web browser, but need not be; it may be a C ++ program on the server for example. When an isolate fails with a compile-time error as described above, control returns to the embedder, along with an excepti on describing the problem. This is necessary so that the embedder can clean up resources etc. It is then the embedder's decision whether to terminate the isola te or not. |
318 } | 318 } |
319 | 319 |
320 \LMHash{} | 320 \LMHash{} |
321 {\em Static warnings} are those errors reported by the static checker. They hav e no effect on execution. Many, but not all, static warnings relate to types, in which case they are known as {\em static type warnings.} Static warnings must b e provided by Dart compilers used during development such as those incorporated in IDEs or otherwise intended to be used by developers for developing code. Comp ilers that are part of runtime execution environments such as virtual machines s hould not issue static warnings. | 321 {\em Static warnings} are those errors reported by the static checker. They hav e no effect on execution. Many, but not all, static warnings relate to types, in which case they are known as {\em static type warnings.} Static warnings must b e provided by Dart compilers used during development such as those incorporated in IDEs or otherwise intended to be used by developers for developing code. Comp ilers that are part of runtime execution environments such as virtual machines s hould not issue static warnings. |
322 | 322 |
323 \LMHash{} | 323 \LMHash{} |
324 {\em Dynamic type errors} are type errors reported in checked mode. | 324 {\em Dynamic type errors} are type errors reported in checked mode. |
325 | 325 |
326 \LMHash{} | 326 \LMHash{} |
327 {\em Run-time errors} are exceptions raised during execution. Whenever we say th at an exception $ex$ is {\em raised} or {\em thrown}, we mean that a throw expre ssion (\ref{throw}) of the form: \code{\THROW{} $ex$;} was implicitly evaluated or that a rethrow statement (\ref{rethrow}) of the form \code{\RETHROW} was exe cuted. When we say that {\em a} $C$ {\em is thrown}, where $C$ is a class, we me an that an instance of class $C$ is thrown. | 327 {\em Run-time errors} are exceptions raised during execution. Whenever we say th at an exception $ex$ is {\em raised} or {\em thrown}, we mean that a throw expre ssion (\ref{throw}) of the form: \code{\THROW{} $ex$;} was implicitly evaluated or that a rethrow statement (\ref{rethrow}) of the form \code{\RETHROW} was exe cuted. When we say that {\em a} $C$ {\em is thrown}, where $C$ is a class, we me an that an instance of class $C$ is thrown. When we say that a stream raises an exception, we mean that an exception occurred while computing the value(s) of th e stream. |
328 | 328 |
329 \LMHash{} | 329 \LMHash{} |
330 If an uncaught exception is thrown by a running isolate $A$, $A$ is immediately suspended. | 330 If an uncaught exception is thrown by a running isolate $A$, $A$ is immediately suspended. |
331 | 331 |
332 | 332 |
333 \section{Variables} | 333 \section{Variables} |
334 \LMLabel{variables} | 334 \LMLabel{variables} |
335 | 335 |
336 \LMHash{} | 336 \LMHash{} |
337 Variables are storage locations in memory. | 337 Variables are storage locations in memory. |
338 | 338 |
339 \begin{grammar} | 339 \begin{grammar} |
340 {\bf variableDeclaration:} | 340 {\bf variableDeclaration:} |
341 declaredIdentifier (`,' identifier)* | 341 declaredIdentifier (`,' identifier)* |
342 . | 342 . |
343 | 343 |
344 {\bf declaredIdentifier:} | 344 {\bf declaredIdentifier:} |
345 metadata finalConstVarOrType identifier | 345 metadata finalConstVarOrType identifier |
346 . | 346 . |
347 | 347 |
348 {\bf finalConstVarOrType:}\FINAL{} type?; | 348 {\bf finalConstVarOrType:}\FINAL{} type?; |
349 \CONST{} type?; | 349 \CONST{} type?; |
350 varOrType | 350 varOrType |
351 . | 351 . |
352 | 352 |
353 {\bf varOrType:}\VAR{}; | 353 {\bf varOrType:}\VAR{}; |
354 type | 354 type |
355 . | 355 . |
356 | 356 |
357 {\bf initializedVariableDeclaration:} | 357 {\bf initializedVariableDeclaration:} |
358 declaredIdentifier (`=' expression)? (`,' initializedIdentifier)* % could do top level here | 358 declaredIdentifier (`=' expression)? (`,' initializedIdentifier)* % could do top level here |
359 . | 359 . |
360 | 360 |
361 {\bf initializedIdentifier:} | 361 {\bf initializedIdentifier:} |
362 identifier (`=' expression)? % could do top-level here | 362 identifier (`=' expression)? % could do top-level here |
363 . | 363 . |
364 | 364 |
365 {\bf initializedIdentifierList:} | 365 {\bf initializedIdentifierList:} |
366 initializedIdentifier (`,' initializedIdentifier)* | 366 initializedIdentifier (`,' initializedIdentifier)* |
367 . | 367 . |
368 | 368 |
369 | 369 |
370 | 370 |
371 | 371 |
372 \end{grammar} | 372 \end{grammar} |
373 | 373 |
374 \LMHash{} | 374 \LMHash{} |
375 A variable that has not been initialized has the initial value \NULL{} (\ref{nul l}). | 375 A variable that has not been initialized has the initial value \NULL{} (\ref{nul l}). |
376 | 376 |
377 \LMHash{} | 377 \LMHash{} |
378 A variable declared at the top-level of a library is referred to as either a {\e m library variable} or simply a top-level variable. | 378 A variable declared at the top-level of a library is referred to as either a {\e m library variable} or simply a top-level variable. |
379 | 379 |
380 \LMHash{} | 380 \LMHash{} |
381 A {\em static variable} is a variable that is not associated with a particular i nstance, but rather with an entire library or class. Static variables include l ibrary variables and class variables. Class variables are variables whose declar ation is immediately nested inside a class declaration and includes the modifier \STATIC{}. A library variable is implicitly static. It is a compile-time error to preface a top-level variable declaration with the built-in identifier (\ref{ identifierReference}) \STATIC{}. | 381 A {\em static variable} is a variable that is not associated with a particular i nstance, but rather with an entire library or class. Static variables include l ibrary variables and class variables. Class variables are variables whose declar ation is immediately nested inside a class declaration and includes the modifier \STATIC{}. A library variable is implicitly static. It is a compile-time error to preface a top-level variable declaration with the built-in identifier (\ref{ identifierReference}) \STATIC{}. |
382 | 382 |
383 \LMHash{} | 383 \LMHash{} |
384 Static variable declarations are initialized lazily. When a static variable $v$ is read, iff it has not yet been assigned, it is set to the result of evaluatin g its initializer. The precise rules are given in section \ref{evaluationOfImpli citVariableGetters}. | 384 Static variable declarations are initialized lazily. When a static variable $v$ is read, iff it has not yet been assigned, it is set to the result of evaluatin g its initializer. The precise rules are given in section \ref{evaluationOfImpli citVariableGetters}. |
385 | 385 |
386 \rationale{The lazy semantics are given because we do not want a language where one tends to define expensive initialization computations, causing long applicat ion startup times. This is especially crucial for Dart, which must support the c oding of client applications. | 386 \rationale{The lazy semantics are given because we do not want a language where one tends to define expensive initialization computations, causing long applicat ion startup times. This is especially crucial for Dart, which must support the c oding of client applications. |
387 } | 387 } |
388 | 388 |
389 \LMHash{} | 389 \LMHash{} |
390 A {\em final variable} is a variable whose binding is fixed upon initialization; a final variable $v$ will always refer to the same object after $v$ has been in itialized. The declaration of a final variable must include the modifier \FINAL {}. | 390 A {\em final variable} is a variable whose binding is fixed upon initialization; a final variable $v$ will always refer to the same object after $v$ has been in itialized. The declaration of a final variable must include the modifier \FINAL {}. |
391 | 391 |
392 \LMHash{} | 392 \LMHash{} |
393 It is a static warning if a final instance variable that has been initialized at its point of declaration is also initialized in a constructor. | 393 It is a static warning if a final instance variable that has been initialized at its point of declaration is also initialized in a constructor. |
394 % It is a static warning if a final instance variable that has been initialized by means of an initializing formal of a constructor is also initialized elsewhe re in the same constructor. | 394 % It is a static warning if a final instance variable that has been initialized by means of an initializing formal of a constructor is also initialized elsewhe re in the same constructor. |
395 It is a compile-time error if a local variable $v$ is final and $v$ is not initi alized at its point of declaration. | 395 It is a compile-time error if a local variable $v$ is final and $v$ is not initi alized at its point of declaration. |
396 | 396 |
397 \commentary{ | 397 \commentary{ |
398 | 398 |
399 A library or static variable is guaranteed to have an initializer at its declara tion by the grammar. | 399 A library or static variable is guaranteed to have an initializer at its declara tion by the grammar. |
400 | 400 |
401 Attempting to assign to a final variable anywhere except in its declaration or i n a constructor header will cause a runtime error to be thrown as discussed bel ow. The assignment will also give rise to a static warning. Any repeated assignm ent to a final variable will also lead to a runtime error. | 401 Attempting to assign to a final variable anywhere except in its declaration or i n a constructor header will cause a runtime error to be thrown as discussed bel ow. The assignment will also give rise to a static warning. Any repeated assignm ent to a final variable will also lead to a runtime error. |
402 | 402 |
403 Taken as a whole, the rules ensure that any attempt to execute multiple assignme nts to a final variable will yield static warnings and repeated assignments will fail dynamically. | 403 Taken as a whole, the rules ensure that any attempt to execute multiple assignme nts to a final variable will yield static warnings and repeated assignments will fail dynamically. |
404 } | 404 } |
405 | 405 |
406 \LMHash{} | 406 \LMHash{} |
407 A {\em constant variable} is a variable whose declaration includes the modifier \CONST{}. A constant variable is always implicitly final. A constant variable mu st be initialized to a compile-time constant (\ref{constants}) or a compile-time error occurs. | 407 A {\em constant variable} is a variable whose declaration includes the modifier \CONST{}. A constant variable is always implicitly final. A constant variable mu st be initialized to a compile-time constant (\ref{constants}) or a compile-time error occurs. |
408 | 408 |
409 \LMHash{} | 409 \LMHash{} |
410 We say that a variable $v$ is {\em potentially mutated} in some scope $s$ if $v$ is not final or constant and an assignment to $v$ occurs in $s$. | 410 We say that a variable $v$ is {\em potentially mutated} in some scope $s$ if $v$ is not final or constant and an assignment to $v$ occurs in $s$. |
411 | 411 |
412 \LMHash{} | 412 \LMHash{} |
413 If a variable declaration does not explicitly specify a type, the type of the de clared variable(s) is \DYNAMIC{}, the unknown type (\ref{typeDynamic}). | 413 If a variable declaration does not explicitly specify a type, the type of the de clared variable(s) is \DYNAMIC{}, the unknown type (\ref{typeDynamic}). |
414 | 414 |
415 \LMHash{} | 415 \LMHash{} |
416 A variable is {\em mutable} if it is not final. | 416 A variable is {\em mutable} if it is not final. |
417 Static and instance variable declarations always induce implicit getters. If the variable is mutable it also introduces an implicit setter. | 417 Static and instance variable declarations always induce implicit getters. If the variable is mutable it also introduces an implicit setter. |
418 The scope into which the implicit getters and setters are introduced depends on the kind of variable declaration involved. | 418 The scope into which the implicit getters and setters are introduced depends on the kind of variable declaration involved. |
419 | 419 |
420 \LMHash{} | 420 \LMHash{} |
421 A library variable introduces a getter into the top level scope of the enclosing library. A static class variable introduces a static getter into the immediatel y enclosing class. An instance variable introduces an instance getter into the i mmediately enclosing class. | 421 A library variable introduces a getter into the top level scope of the enclosing library. A static class variable introduces a static getter into the immediatel y enclosing class. An instance variable introduces an instance getter into the i mmediately enclosing class. |
422 | 422 |
423 \LMHash{} | 423 \LMHash{} |
424 A mutable library variable introduces a setter into the top level scope of the e nclosing library. A mutable static class variable introduces a static setter int o the immediately enclosing class. A mutable instance variable introduces an ins tance setter into the immediately enclosing class. | 424 A mutable library variable introduces a setter into the top level scope of the e nclosing library. A mutable static class variable introduces a static setter int o the immediately enclosing class. A mutable instance variable introduces an ins tance setter into the immediately enclosing class. |
425 | 425 |
426 \LMHash{} | 426 \LMHash{} |
427 Local variables are added to the innermost enclosing scope. They do not induce getters and setters. A local variable may only be referenced at a source code l ocation that is after its initializer, if any, is complete, or a compile-time er ror occurs. The error may be reported either at the point where the premature r eference occurs, or at the variable declaration. | 427 Local variables are added to the innermost enclosing scope. They do not induce getters and setters. A local variable may only be referenced at a source code l ocation that is after its initializer, if any, is complete, or a compile-time er ror occurs. The error may be reported either at the point where the premature r eference occurs, or at the variable declaration. |
428 | 428 |
429 \rationale { | 429 \rationale { |
430 We allow the error to be reported at the declaration to allow implementations to avoid an extra processing phase. | 430 We allow the error to be reported at the declaration to allow implementations to avoid an extra processing phase. |
431 } | 431 } |
432 | 432 |
433 \commentary{ | 433 \commentary{ |
434 The example below illustrates the expected behavior. A variable $x$ is declared at the library level, and another $x$ is declared inside the function $f$. | 434 The example below illustrates the expected behavior. A variable $x$ is declared at the library level, and another $x$ is declared inside the function $f$. |
435 } | 435 } |
436 | 436 |
437 \begin{dartCode} | 437 \begin{dartCode} |
438 \VAR{} x = 0; | 438 \VAR{} x = 0; |
439 | 439 |
440 f(y) \{ | 440 f(y) \{ |
441 \VAR{} z = x; // compile-time error | 441 \VAR{} z = x; // compile-time error |
442 if (y) \{ | 442 if (y) \{ |
443 x = x + 1; // two compile time errors | 443 x = x + 1; // two compile time errors |
444 print(x); // compile time error | 444 print(x); // compile time error |
445 \} | 445 \} |
446 \VAR{} x = x++; // compile time error | 446 \VAR{} x = x++; // compile time error |
447 print(x); | 447 print(x); |
448 \} | 448 \} |
449 \end{dartCode} | 449 \end{dartCode} |
450 | 450 |
451 \commentary{ | 451 \commentary{ |
452 The declaration inside $f$ hides the enclosing one. So all references to $x$ in side $f$ refer to the inner declaration of $x$. However, many of these reference s are illegal, because they appear before the declaration. The assignment to $z$ is one such case. The assignment to $x$ in the \IF{} statement suffers from mul tiple problems. The right hand side reads $x$ before its declaration, and the le ft hand side assigns to $x$ before its declaration. Each of these are, independe ntly, compile time errors. The print statement inside the \IF{} is also illegal . | 452 The declaration inside $f$ hides the enclosing one. So all references to $x$ in side $f$ refer to the inner declaration of $x$. However, many of these reference s are illegal, because they appear before the declaration. The assignment to $z$ is one such case. The assignment to $x$ in the \IF{} statement suffers from mul tiple problems. The right hand side reads $x$ before its declaration, and the le ft hand side assigns to $x$ before its declaration. Each of these are, independe ntly, compile time errors. The print statement inside the \IF{} is also illegal . |
453 | 453 |
454 The inner declaration of $x$ is itself erroneous because its right hand side att empts to read $x$ before the declaration has terminated. The left hand side is not, technically, a reference or an assignment but a declaration and so is legal . The last print statement is perfectly legal as well. | 454 The inner declaration of $x$ is itself erroneous because its right hand side att empts to read $x$ before the declaration has terminated. The left hand side is not, technically, a reference or an assignment but a declaration and so is legal . The last print statement is perfectly legal as well. |
455 } | 455 } |
456 | 456 |
457 \commentary { | 457 \commentary { |
458 As another example \code{\VAR{} x = 3, y = x;} is legal, because \code{x} is re ferenced after its initializer. | 458 As another example \code{\VAR{} x = 3, y = x;} is legal, because \code{x} is re ferenced after its initializer. |
459 | 459 |
460 A particularly perverse example involves a local variable name shadowing a type. This is possible because Dart has a single namespace for types, functions and v ariables. | 460 A particularly perverse example involves a local variable name shadowing a type. This is possible because Dart has a single namespace for types, functions and v ariables. |
461 } | 461 } |
462 | 462 |
463 \begin{dartCode} | 463 \begin{dartCode} |
464 \CLASS{} C \{\} | 464 \CLASS{} C \{\} |
465 perverse() \{ | 465 perverse() \{ |
466 \VAR{} v = \NEW{} C(); // compile-time error | 466 \VAR{} v = \NEW{} C(); // compile-time error |
467 C aC; // compile-time error | 467 C aC; // compile-time error |
468 \VAR{} C = 10; | 468 \VAR{} C = 10; |
469 \} | 469 \} |
470 | 470 |
471 \commentary { | 471 \commentary { |
472 Inside \cd{perverse()}, \cd{C} denotes a local variable. The type \cd{C} is hid den by the variable of the same name. The attempt to instantiate \cd{C} causes a compile-time error because it references a local variable prior to its declarat ion. Similarly, for the declaration of \cd{aC} (even though it is only a type an notation). | 472 Inside \cd{perverse()}, \cd{C} denotes a local variable. The type \cd{C} is hid den by the variable of the same name. The attempt to instantiate \cd{C} causes a compile-time error because it references a local variable prior to its declarat ion. Similarly, for the declaration of \cd{aC} (even though it is only a type an notation). |
473 } | 473 } |
474 | 474 |
475 \rationale{ | 475 \rationale{ |
476 As a rule, type annotations are ignored in production mode. However, we do | 476 As a rule, type annotations are ignored in production mode. However, we do |
477 not want to allow programs to compile legally in one mode and not another, and in this extremely odd situation, that consideration takes precedence. | 477 not want to allow programs to compile legally in one mode and not another, and in this extremely odd situation, that consideration takes precedence. |
478 } | 478 } |
479 | 479 |
480 \end{dartCode} | 480 \end{dartCode} |
481 | 481 |
482 % the grammar does not support local getters and setters. The local var discussi on does not seem to mention getters and setters based semantics. It simply discu sses the creation of the variable, not its access. Access is either assignment o r identifiers. Identifiers ignore the getter story. | 482 % the grammar does not support local getters and setters. The local var discussi on does not seem to mention getters and setters based semantics. It simply discu sses the creation of the variable, not its access. Access is either assignment o r identifiers. Identifiers ignore the getter story. |
483 | 483 |
484 \LMHash{} | 484 \LMHash{} |
485 The following rules apply to all static and instance variables. | 485 The following rules apply to all static and instance variables. |
486 | 486 |
487 \LMHash{} | 487 \LMHash{} |
488 A variable declaration of one of the forms \code{$T$ $v$;}, \code{$T$ $v$ = $ e$;} , \code{\CONST{} $T$ $v$ = $e$;}, \code{\FINAL{} $T$ $v$;} or \code{\FINA L{} $T$ $v$ = $e$;} always induces an implicit getter function (\ref{getters}) with signature | 488 A variable declaration of one of the forms \code{$T$ $v$;}, \code{$T$ $v$ = $ e$;} , \code{\CONST{} $T$ $v$ = $e$;}, \code{\FINAL{} $T$ $v$;} or \code{\FINA L{} $T$ $v$ = $e$;} always induces an implicit getter function (\ref{getters}) with signature |
489 | 489 |
490 $T$ \GET{} $v$ | 490 $T$ \GET{} $v$ |
491 | 491 |
492 whose invocation evaluates as described below (\ref{evaluationOfImplicitVariable Getters}). | 492 whose invocation evaluates as described below (\ref{evaluationOfImplicitVariable Getters}). |
493 | 493 |
494 | 494 |
495 \LMHash{} | 495 \LMHash{} |
496 A variable declaration of one of the forms \code{\VAR{} $v$;}, \code{\VAR{} $ v$ = $e$;} , \code{\CONST{} $v$ = $e$;}, \code{\FINAL{} $v$;} or \code{\FINAL{} $v$ = $e$;} always induces an implicit getter function with signature | 496 A variable declaration of one of the forms \code{\VAR{} $v$;}, \code{\VAR{} $ v$ = $e$;} , \code{\CONST{} $v$ = $e$;}, \code{\FINAL{} $v$;} or \code{\FINAL{} $v$ = $e$;} always induces an implicit getter function with signature |
497 | 497 |
498 \GET{} $v$ | 498 \GET{} $v$ |
499 | 499 |
500 whose invocation evaluates as described below (\ref{evaluationOfImplicitVariabl eGetters}). | 500 whose invocation evaluates as described below (\ref{evaluationOfImplicitVariabl eGetters}). |
501 | 501 |
502 \LMHash{} | 502 \LMHash{} |
503 A non-final variable declaration of the form \code{{} $T$ $v$;} or the form \ code{$T$ $v$ = $e$;} always induces an implicit setter function (\ref{setters }) with signature | 503 A non-final variable declaration of the form \code{{} $T$ $v$;} or the form \ code{$T$ $v$ = $e$;} always induces an implicit setter function (\ref{setters }) with signature |
504 | 504 |
505 \VOID{} \SET{} $v=(T$ $x)$ | 505 \VOID{} \SET{} $v=(T$ $x)$ |
506 | 506 |
507 whose execution sets the value of $v$ to the incoming argument $x$. | 507 whose execution sets the value of $v$ to the incoming argument $x$. |
508 | 508 |
509 \LMHash{} | 509 \LMHash{} |
510 A non-final variable declaration of the form \code{\VAR{} $v$;} or the form \ code{\VAR{} $v$ = $e$;} always induces an implicit setter function with signa ture | 510 A non-final variable declaration of the form \code{\VAR{} $v$;} or the form \ code{\VAR{} $v$ = $e$;} always induces an implicit setter function with signa ture |
511 | 511 |
512 \SET{} $v=(x)$ | 512 \SET{} $v=(x)$ |
513 | 513 |
514 whose execution sets the value of $v$ to the incoming argument $x$. | 514 whose execution sets the value of $v$ to the incoming argument $x$. |
515 | 515 |
516 | 516 |
517 \subsection{Evaluation of Implicit Variable Getters} | 517 \subsection{Evaluation of Implicit Variable Getters} |
518 \LMLabel{evaluationOfImplicitVariableGetters} | 518 \LMLabel{evaluationOfImplicitVariableGetters} |
519 | 519 |
520 \LMHash{} | 520 \LMHash{} |
521 Let $d$ be the declaration of a static or instance variable $v$. If $d$ is an i nstance variable, then the invocation of the implicit getter of $v$ evaluates t o the value stored in $v$. | 521 Let $d$ be the declaration of a static or instance variable $v$. If $d$ is an i nstance variable, then the invocation of the implicit getter of $v$ evaluates t o the value stored in $v$. |
522 If $d$ is a static or library variable then the implicit getter method of $v$ ex ecutes as follows: | 522 If $d$ is a static or library variable then the implicit getter method of $v$ ex ecutes as follows: |
523 \begin{itemize} | 523 \begin{itemize} |
524 \item {\bf Non-constant variable declaration with initializer}. If $d$ is of one of the forms \code{\VAR{} $v$ = $e$;} , \code{$T$ $v$ = $e$;} , \code{\FINAL {} $v$ = $e$;} , \code{\FINAL{} $T$ $v$ = $e$;}, \code{\STATIC{} $v$ = $e$; }, \code{\STATIC{} $T$ $v$ = $e$; }, \code{\STATIC{} \FINAL{} $v$ = $e$; } or \code {\STATIC{} \FINAL{} $T$ $v$ = $e$;} and no value has yet been stored into $v$ th en the initializer expression $e$ is evaluated. If, during the evaluation of $e$ , the getter for $v$ is invoked, a \code{CyclicInitializationError} is thrown. I f the evaluation succeeded yielding an object $o$, let $r = o$, otherwise let $r = \NULL{}$. In any case, $r$ is stored into $v$. The result of executing the ge tter is $r$. | 524 \item {\bf Non-constant variable declaration with initializer}. If $d$ is of one of the forms \code{\VAR{} $v$ = $e$;} , \code{$T$ $v$ = $e$;} , \code{\FINAL {} $v$ = $e$;} , \code{\FINAL{} $T$ $v$ = $e$;}, \code{\STATIC{} $v$ = $e$; }, \code{\STATIC{} $T$ $v$ = $e$; }, \code{\STATIC{} \FINAL{} $v$ = $e$; } or \code {\STATIC{} \FINAL{} $T$ $v$ = $e$;} and no value has yet been stored into $v$ th en the initializer expression $e$ is evaluated. If, during the evaluation of $e$ , the getter for $v$ is invoked, a \code{CyclicInitializationError} is thrown. I f the evaluation succeeded yielding an object $o$, let $r = o$, otherwise let $r = \NULL{}$. In any case, $r$ is stored into $v$. The result of executing the ge tter is $r$. |
525 \item {\bf Constant variable declaration}. If $d$ is of one of the forms \code{ \CONST{} $v$ = $e$; } , \code{\CONST{} $T$ $v$ = $e$; }, \code{\STATIC{} \CON ST{} $v$ = $e$; } or \code{\STATIC{} \CONST{} $T$ $v$ = $e$;} the result of the getter is the value of the compile time constant $e$. \commentary{Note that a c ompile time constant cannot depend on itself, so no cyclic references can occur. } | 525 \item {\bf Constant variable declaration}. If $d$ is of one of the forms \code{ \CONST{} $v$ = $e$; } , \code{\CONST{} $T$ $v$ = $e$; }, \code{\STATIC{} \CON ST{} $v$ = $e$; } or \code{\STATIC{} \CONST{} $T$ $v$ = $e$;} the result of the getter is the value of the compile time constant $e$. \commentary{Note that a c ompile time constant cannot depend on itself, so no cyclic references can occur. } |
526 Otherwise | 526 Otherwise |
527 \item {\bf Variable declaration without initializer}. The result of executing th e getter method is the value stored in $v$. | 527 \item {\bf Variable declaration without initializer}. The result of executing th e getter method is the value stored in $v$. |
528 \end{itemize} | 528 \end{itemize} |
529 | 529 |
530 | 530 |
531 | 531 |
532 | 532 |
533 | 533 |
534 \section{Functions} | 534 \section{Functions} |
535 \LMLabel{functions} | 535 \LMLabel{functions} |
536 | 536 |
537 \LMHash{} | 537 \LMHash{} |
538 Functions abstract over executable actions. | 538 Functions abstract over executable actions. |
539 | 539 |
540 \begin{grammar} | 540 \begin{grammar} |
541 {\bf functionSignature:} | 541 {\bf functionSignature:} |
542 metadata returnType? identifier formalParameterList | 542 metadata returnType? identifier formalParameterList |
543 . | 543 . |
544 | 544 |
545 {\bf returnType:} | 545 {\bf returnType:} |
546 \VOID{}; | 546 \VOID{}; |
547 type | 547 type |
548 . | 548 . |
549 | 549 |
550 {\bf functionBody:} \ASYNC{}? `={\escapegrammar \gt}' expression `{\escapegramm ar ;}'; | 550 {\bf functionBody:} \ASYNC{}? `={\escapegrammar \gt}' expression `{\escapegramm ar ;}'; |
551 (\ASYNC{} $|$ \ASYNC* $|$ \SYNC*)? block | 551 (\ASYNC{} $|$ \ASYNC* $|$ \SYNC*)? block |
552 . | 552 . |
553 | 553 |
554 {\bf block:} | 554 {\bf block:} |
555 `\{' statements `\}' | 555 `\{' statements `\}' |
556 . | 556 . |
557 | 557 |
558 \end{grammar} | 558 \end{grammar} |
559 | 559 |
560 \LMHash{} | 560 \LMHash{} |
561 Functions include function declarations (\ref{functionDeclarations}), methods ( \ref{instanceMethods}, \ref{staticMethods}), getters (\ref{getters}), setters (\ref{setters}), constructors (\ref{constructors}) and function literals (\re f{functionExpressions}). | 561 Functions include function declarations (\ref{functionDeclarations}), methods ( \ref{instanceMethods}, \ref{staticMethods}), getters (\ref{getters}), setters (\ref{setters}), constructors (\ref{constructors}) and function literals (\re f{functionExpressions}). |
562 | 562 |
563 \LMHash{} | 563 \LMHash{} |
564 All functions have a signature and a body. The signature describes the formal pa rameters of the function, and possibly its name and return type. A function bod y is either: | 564 All functions have a signature and a body. The signature describes the formal pa rameters of the function, and possibly its name and return type. A function bod y is either: |
565 \begin{itemize} | 565 \begin{itemize} |
566 \item A block statement (\ref{blocks}) containing the statements (\ref{stateme nts}) executed by the function, optionally marked with one of the modifiers: \AS YNC, \ASYNC* or \SYNC*. In this case, if the last statement of a function is not a return statement (\ref{return}), the statement \code{\RETURN{};} is implicitl y appended to the function body. | 566 \item A block statement (\ref{blocks}) containing the statements (\ref{stateme nts}) executed by the function, optionally marked with one of the modifiers: \AS YNC, \ASYNC* or \SYNC*. In this case, if the last statement of a function is not a return statement (\ref{return}), the statement \code{\RETURN{};} is implicitl y appended to the function body. |
567 | 567 |
568 \rationale{ | 568 \rationale{ |
569 Because Dart is optionally typed, we cannot guarantee that a function that does not return a value will not be used in the context of an expression. Therefore, every function must return a value. A \RETURN{} without an expression returns \N ULL{}. For generator functions, the situation is more subtle. See further discus sion in section \ref{return}. | 569 Because Dart is optionally typed, we cannot guarantee that a function that does not return a value will not be used in the context of an expression. Therefore, every function must return a value. A \RETURN{} without an expression returns \N ULL{}. For generator functions, the situation is more subtle. See further discus sion in section \ref{return}. |
570 } | 570 } |
571 | 571 |
572 OR | 572 OR |
573 \item of the form \code{=$>$ $e$} which is equivalent to a body of the form \c ode{\{\RETURN{} $e$;\}} or the form \code{\ASYNC{} =$>$ $e$} which is equivalent to a body of the form \code{\ASYNC{} \{\RETURN{} $e$;\}}. \rationale{The other modifiers do not apply here, because they apply only to generators, discussed be low, and generators do not allow the form \code{\RETURN{} $e$}; values are added to the generated stream or iterable using \YIELD{} instead.} | 573 \item of the form \code{=$>$ $e$} which is equivalent to a body of the form \c ode{\{\RETURN{} $e$;\}} or the form \code{\ASYNC{} =$>$ $e$} which is equivalent to a body of the form \code{\ASYNC{} \{\RETURN{} $e$;\}}. \rationale{The other modifiers do not apply here, because they apply only to generators, discussed be low, and generators do not allow the form \code{\RETURN{} $e$}; values are added to the generated stream or iterable using \YIELD{} instead.} |
574 | 574 |
575 \end{itemize} | 575 \end{itemize} |
576 | 576 |
577 \LMHash{} | 577 \LMHash{} |
578 A function is {\em asynchronous} if its body is marked with the \ASYNC{} or \ASY NC* modifier. Otherwise the function is {\em synchronous}. A function is a {\em generator} if its body is marked with the \SYNC* or \ASYNC* modifier. | 578 A function is {\em asynchronous} if its body is marked with the \ASYNC{} or \ASY NC* modifier. Otherwise the function is {\em synchronous}. A function is a {\em generator} if its body is marked with the \SYNC* or \ASYNC* modifier. |
579 | 579 |
580 \commentary{ | 580 \commentary{ |
581 Whether a function is synchronous or asynchronous is orthogonal to whether it is a generator or not. Generator functions are a sugar for functions that produce collections in a systematic way, by lazily applying a function that {\em generat es} individual elements of a collection. Dart provides such a sugar in both the synchronous case, where one returns an iterable, and in the asynchronous case, w here one returns a stream. Dart also allows both synchronous and asynchronous fu nctions that produce a single value. | 581 Whether a function is synchronous or asynchronous is orthogonal to whether it is a generator or not. Generator functions are a sugar for functions that produce collections in a systematic way, by lazily applying a function that {\em generat es} individual elements of a collection. Dart provides such a sugar in both the synchronous case, where one returns an iterable, and in the asynchronous case, w here one returns a stream. Dart also allows both synchronous and asynchronous fu nctions that produce a single value. |
582 } | 582 } |
583 | 583 |
584 \LMHash{} | 584 \LMHash{} |
585 It is a compile-time error if an \ASYNC, \ASYNC* or \SYNC* modifier is attached to the body of a setter or constructor. | 585 It is a compile-time error if an \ASYNC, \ASYNC* or \SYNC* modifier is attached to the body of a setter or constructor. |
586 | 586 |
587 \rationale{ | 587 \rationale{ |
588 An asynchronous setter would be of little use, since setters can only be used in the context of an assignment (\ref{assignment}), and an assignment expression a lways evaluates to the value of the assignment's right hand side. If the setter actually did its work asynchronously, one might imagine that one would return a future that resolved to the assignment's right hand side after the setter did it s work. However, this would require dynamic tests at every assignment, and so wo uld be prohibitively expensive. | 588 An asynchronous setter would be of little use, since setters can only be used in the context of an assignment (\ref{assignment}), and an assignment expression a lways evaluates to the value of the assignment's right hand side. If the setter actually did its work asynchronously, one might imagine that one would return a future that resolved to the assignment's right hand side after the setter did it s work. However, this would require dynamic tests at every assignment, and so wo uld be prohibitively expensive. |
589 | 589 |
590 An asynchronous constructor would, by definition, never return an instance of th e class it purports to construct, but instead return a future. Calling such a be ast via \NEW{} would be very confusing. If you need to produce an object asynchr onously, use a method. | 590 An asynchronous constructor would, by definition, never return an instance of th e class it purports to construct, but instead return a future. Calling such a be ast via \NEW{} would be very confusing. If you need to produce an object asynchr onously, use a method. |
591 | 591 |
592 One could allow modifiers for factories. A factory for \code{Future} could be mo dified by \ASYNC{}, a factory for \code{Stream} could be modified by \ASYNC* and a factory for \code{Iterable} could be modified by \SYNC*. No other scenario ma kes sense because the object returned by the factory would be of the wrong type. This situation is very unusual so it is not worth making an exception to the ge neral rule for constructors in order to allow it. | 592 One could allow modifiers for factories. A factory for \code{Future} could be mo dified by \ASYNC{}, a factory for \code{Stream} could be modified by \ASYNC* and a factory for \code{Iterable} could be modified by \SYNC*. No other scenario ma kes sense because the object returned by the factory would be of the wrong type. This situation is very unusual so it is not worth making an exception to the ge neral rule for constructors in order to allow it. |
593 } | 593 } |
594 \LMHash{} | 594 \LMHash{} |
595 It is a static warning if the declared return type of a function marked \ASYNC{} may not be assigned to \code{Future}. It is a static warning if the declared re turn type of a function marked \SYNC* may not be assigned to \code{Iterable}. It is a static warning if the declared return type of a function marked \ASYNC* m ay not be assigned to \code{Stream}. | 595 It is a static warning if the declared return type of a function marked \ASYNC{} may not be assigned to \code{Future}. It is a static warning if the declared re turn type of a function marked \SYNC* may not be assigned to \code{Iterable}. It is a static warning if the declared return type of a function marked \ASYNC* m ay not be assigned to \code{Stream}. |
596 | 596 |
597 \subsection{Function Declarations} | 597 \subsection{Function Declarations} |
598 \LMLabel{functionDeclarations} | 598 \LMLabel{functionDeclarations} |
599 | 599 |
600 \LMHash{} | 600 \LMHash{} |
601 A {\em function declaration} is a function that is neither a member of a class n or a function literal. Function declarations include {\em library functions}, wh ich are function declarations | 601 A {\em function declaration} is a function that is neither a member of a class n or a function literal. Function declarations include {\em library functions}, wh ich are function declarations |
602 %(including getters and setters) | 602 %(including getters and setters) |
603 at the top level of a library, and {\em local functions}, which are function dec larations declared inside other functions. Library functions are often referred to simply as top-level functions. | 603 at the top level of a library, and {\em local functions}, which are function dec larations declared inside other functions. Library functions are often referred to simply as top-level functions. |
604 | 604 |
605 \LMHash{} | 605 \LMHash{} |
606 A function declaration consists of an identifier indicating the function's name, possibly prefaced by a return type. The function name is followed by a signatur e and body. For getters, the signature is empty. The body is empty for function s that are external. | 606 A function declaration consists of an identifier indicating the function's name, possibly prefaced by a return type. The function name is followed by a signatur e and body. For getters, the signature is empty. The body is empty for function s that are external. |
607 | 607 |
608 \LMHash{} | 608 \LMHash{} |
609 The scope of a library function is the scope of the enclosing library. The scope of a local function is described in section \ref{localFunctionDeclaration}. In both cases, the name of the function is in scope in its formal parameter scope (\ref{formalParameters}). | 609 The scope of a library function is the scope of the enclosing library. The scope of a local function is described in section \ref{localFunctionDeclaration}. In both cases, the name of the function is in scope in its formal parameter scope (\ref{formalParameters}). |
610 | 610 |
611 %A function declaration of the form $T_0$ $id(T_1$ $a_1, \ldots, T_n$ $a_n, [T_ {n+1}$ $x_{n+1} = d_1, \ldots, T_{n+k}$ $x_{n+k} = d_k])\{s\}$ is equivalent to a variable declaration of the form \code{\FINAL{} $F$ $id$ = $(T_1$ $a_1, \ldots , T_n$ $a_n, [T_{n+1}$ $x_{n+1} = d_1, \ldots, T_{n+k}$ $x_{n+k}= d_k])\{s\}$}, where $F$ is the function type alias (\ref{typedef}) \code{\TYPEDEF{} $T_0$ $F(T _1$ $a_1, \ldots, T_n$ $a_n, [T_{n+1}$ $x_{n+1}, \ldots, T_{n+k}$ $x_{n+k}])$}. Likewise, a function declaration of the form $id(T_1$ $a_1, \ldots, T_n$ $a_n , [T_{n+1}$ $x_{n+1} = d_1, \ldots, T_{n+k}$ $x_{n+k} = d_k])\{s\}$ is equivalen t to a variable declaration of the form \code{\FINAL{} $F$ $id$ = $(T_1$ $a_1, \ ldots, T_n$ $a_n, [T_{n+1}$ $x_{n+1} = d_1, \ldots, T_{n+k}$ $x_{n+k} = d_k])\{s \}$}, where $F$ is the function type alias \code{\TYPEDEF{} $F(T_1$ $a_1, \ldot s, T_n$ $a_n, [T_{n+1}$ $x_{n+1}, \ldots, T_{n+k}$ $x_{n+k}])$}. | 611 %A function declaration of the form $T_0$ $id(T_1$ $a_1, \ldots, T_n$ $a_n, [T_ {n+1}$ $x_{n+1} = d_1, \ldots, T_{n+k}$ $x_{n+k} = d_k])\{s\}$ is equivalent to a variable declaration of the form \code{\FINAL{} $F$ $id$ = $(T_1$ $a_1, \ldots , T_n$ $a_n, [T_{n+1}$ $x_{n+1} = d_1, \ldots, T_{n+k}$ $x_{n+k}= d_k])\{s\}$}, where $F$ is the function type alias (\ref{typedef}) \code{\TYPEDEF{} $T_0$ $F(T _1$ $a_1, \ldots, T_n$ $a_n, [T_{n+1}$ $x_{n+1}, \ldots, T_{n+k}$ $x_{n+k}])$}. Likewise, a function declaration of the form $id(T_1$ $a_1, \ldots, T_n$ $a_n , [T_{n+1}$ $x_{n+1} = d_1, \ldots, T_{n+k}$ $x_{n+k} = d_k])\{s\}$ is equivalen t to a variable declaration of the form \code{\FINAL{} $F$ $id$ = $(T_1$ $a_1, \ ldots, T_n$ $a_n, [T_{n+1}$ $x_{n+1} = d_1, \ldots, T_{n+k}$ $x_{n+k} = d_k])\{s \}$}, where $F$ is the function type alias \code{\TYPEDEF{} $F(T_1$ $a_1, \ldot s, T_n$ $a_n, [T_{n+1}$ $x_{n+1}, \ldots, T_{n+k}$ $x_{n+k}])$}. |
612 | 612 |
613 %\Q{We need to cover library getters as well.} | 613 %\Q{We need to cover library getters as well.} |
614 | 614 |
615 %\Q{ The definition in terms of variables is untrue, because the code would be i llegal. The initializer cannot refer to the function name in this case. I belie ve the best fix is to relax this | 615 %\Q{ The definition in terms of variables is untrue, because the code would be i llegal. The initializer cannot refer to the function name in this case. I belie ve the best fix is to relax this |
616 %requirement in the case of closures. See bug 315. | 616 %requirement in the case of closures. See bug 315. |
617 %} | 617 %} |
618 | 618 |
619 %\commentary{ | 619 %\commentary{ |
620 %Some obvious conclusions: | 620 %Some obvious conclusions: |
621 | 621 |
(...skipping 17 matching lines...) Expand all Loading... | |
639 \LMHash{} | 639 \LMHash{} |
640 Every function includes a {\em formal parameter list}, which consists of a list of required positional parameters (\ref{requiredFormals}), followed by any optio nal parameters (\ref{optionalFormals}). The optional parameters may be specified either as a set of named parameters or as a list of positional parameters, but not both. | 640 Every function includes a {\em formal parameter list}, which consists of a list of required positional parameters (\ref{requiredFormals}), followed by any optio nal parameters (\ref{optionalFormals}). The optional parameters may be specified either as a set of named parameters or as a list of positional parameters, but not both. |
641 | 641 |
642 \LMHash{} | 642 \LMHash{} |
643 The formal parameter list of a function introduces a new scope known as the func tion's {\em formal parameter scope}. The formal parameter scope of a function $f $ is enclosed in the scope where $f$ is declared. Every formal parameter intr oduces a local variable into the formal parameter scope. However, the scope of a function's signature is the function's enclosing scope, not the formal paramete r scope. | 643 The formal parameter list of a function introduces a new scope known as the func tion's {\em formal parameter scope}. The formal parameter scope of a function $f $ is enclosed in the scope where $f$ is declared. Every formal parameter intr oduces a local variable into the formal parameter scope. However, the scope of a function's signature is the function's enclosing scope, not the formal paramete r scope. |
644 | 644 |
645 \LMHash{} | 645 \LMHash{} |
646 The body of a function introduces a new scope known as the function's {\em body scope}. The body scope of a function $f$ is enclosed in the scope introduced by the formal parameter scope of $f$. | 646 The body of a function introduces a new scope known as the function's {\em body scope}. The body scope of a function $f$ is enclosed in the scope introduced by the formal parameter scope of $f$. |
647 | 647 |
648 | 648 |
649 %The formal parameter scope of a function maps the name of each formal parameter $p$ to the value $p$ is bound to. | 649 %The formal parameter scope of a function maps the name of each formal parameter $p$ to the value $p$ is bound to. |
650 | 650 |
651 % The formal parameters of a function are processed in the enclosing scope of th e function. | 651 % The formal parameters of a function are processed in the enclosing scope of th e function. |
652 % \commentary{this means that the parameters themselves may not be referenced wi thin the formal parameter list.} | 652 % \commentary{this means that the parameters themselves may not be referenced wi thin the formal parameter list.} |
653 | 653 |
654 \LMHash{} | 654 \LMHash{} |
655 It is a compile-time error if a formal parameter is declared as a constant varia ble (\ref{variables}). | 655 It is a compile-time error if a formal parameter is declared as a constant varia ble (\ref{variables}). |
656 | 656 |
657 \begin{grammar} | 657 \begin{grammar} |
658 {\bf formalParameterList:}`(' `)'; | 658 {\bf formalParameterList:}`(' `)'; |
659 `(' normalFormalParameters ( `,' optionalFormalParameters)? `)'; | 659 `(' normalFormalParameters ( `,' optionalFormalParameters)? `)'; |
660 `(' optionalFormalParameters `)' | 660 `(' optionalFormalParameters `)' |
661 . | 661 . |
662 %\end{grammar} | 662 %\end{grammar} |
663 %} | 663 %} |
664 | 664 |
665 %\begin{grammar} | 665 %\begin{grammar} |
666 %formalParameterList: | 666 %formalParameterList: |
667 % '(' restFormalParameter? ')'; | 667 % '(' restFormalParameter? ')'; |
668 % '(' namedFormalParameters ')'; | 668 % '(' namedFormalParameters ')'; |
669 % '(' normalFormalParameters normalFormalParameterTail? ')' | 669 % '(' normalFormalParameters normalFormalParameterTail? ')' |
670 % . | 670 % . |
671 | 671 |
672 {\bf normalFormalParameters:} | 672 {\bf normalFormalParameters:} |
673 normalFormalParameter (`,' normalFormalParameter)* | 673 normalFormalParameter (`,' normalFormalParameter)* |
674 . | 674 . |
675 | 675 |
676 {\bf optionalFormalParameters:}optionalPositionalFormalParameters; | 676 {\bf optionalFormalParameters:}optionalPositionalFormalParameters; |
677 namedFormalParameters | 677 namedFormalParameters |
678 . | 678 . |
679 | 679 |
680 {\bf optionalPositionalFormalParameters:} | 680 {\bf optionalPositionalFormalParameters:} |
681 `[' defaultFormalParameter (`,' defaultFormalParameter)* `]' | 681 `[' defaultFormalParameter (`,' defaultFormalParameter)* `]' |
682 . | 682 . |
683 {\bf namedFormalParameters:} | 683 {\bf namedFormalParameters:} |
684 `\{' defaultNamedParameter (`,' defaultNamedParameter)* `\}' | 684 `\{' defaultNamedParameter (`,' defaultNamedParameter)* `\}' |
685 . | 685 . |
686 \end{grammar} | 686 \end{grammar} |
687 | 687 |
688 %Formal parameters are always \FINAL{}. | 688 %Formal parameters are always \FINAL{}. |
689 %\Q{We're awaiting some data on whether enforcing this would cause widespread pa in.} | 689 %\Q{We're awaiting some data on whether enforcing this would cause widespread pa in.} |
690 %A formal parameter is always considered to be initialized. \rationale{This is because it will always be initialized by the call - even if it is optional.} | 690 %A formal parameter is always considered to be initialized. \rationale{This is because it will always be initialized by the call - even if it is optional.} |
691 | 691 |
692 | 692 |
693 \subsubsection{Required Formals} | 693 \subsubsection{Required Formals} |
694 \LMLabel{requiredFormals} | 694 \LMLabel{requiredFormals} |
695 | 695 |
696 \LMHash{} | 696 \LMHash{} |
697 A {\em required formal parameter} may be specified in one of three ways: | 697 A {\em required formal parameter} may be specified in one of three ways: |
698 \begin{itemize} | 698 \begin{itemize} |
699 \item By means of a function signature that names the parameter and describes it s type as a function type (\ref{functionTypes}). It is a compile-time error if any default values are specified in the signature of such a function type.% expl ain what the type is in this case? Where is this described in general? | 699 \item By means of a function signature that names the parameter and describes it s type as a function type (\ref{functionTypes}). It is a compile-time error if any default values are specified in the signature of such a function type.% expl ain what the type is in this case? Where is this described in general? |
700 \item As an initializing formal, which is only valid as a parameter to a generat ive constructor (\ref{generativeConstructors}). % do we need to say this, or any thing more? | 700 \item As an initializing formal, which is only valid as a parameter to a generat ive constructor (\ref{generativeConstructors}). % do we need to say this, or any thing more? |
701 \item Via an ordinary variable declaration (\ref{variables}). | 701 \item Via an ordinary variable declaration (\ref{variables}). |
702 \end{itemize} | 702 \end{itemize} |
703 | 703 |
704 \begin{grammar} | 704 \begin{grammar} |
705 {\bf normalFormalParameter:}functionSignature; | 705 {\bf normalFormalParameter:}functionSignature; |
706 fieldFormalParameter; | 706 fieldFormalParameter; |
707 simpleFormalParameter | 707 simpleFormalParameter |
708 . | 708 . |
709 | 709 |
710 {\bf simpleFormalParameter:}declaredIdentifier; | 710 {\bf simpleFormalParameter:}declaredIdentifier; |
711 metadata identifier | 711 metadata identifier |
712 . | 712 . |
713 | 713 |
714 {\bf fieldFormalParameter:} | 714 {\bf fieldFormalParameter:} |
715 metadata finalConstVarOrType? \THIS{} `{\escapegrammar .}' identifier formalP arameterList? | 715 metadata finalConstVarOrType? \THIS{} `{\escapegrammar .}' identifier formalP arameterList? |
716 . | 716 . |
717 \end{grammar} | 717 \end{grammar} |
718 | 718 |
719 %\subsubsection{Rest Formals} | 719 %\subsubsection{Rest Formals} |
720 %\LMLabel{restFormals} | 720 %\LMLabel{restFormals} |
721 | 721 |
722 %A rest formal $R$ must be the last parameter in a formal parameter list. If a type $T$ is specified for $R$, it signifies that the type of $R$ is $T[]$. | 722 %A rest formal $R$ must be the last parameter in a formal parameter list. If a type $T$ is specified for $R$, it signifies that the type of $R$ is $T[]$. |
723 | 723 |
724 %\begin{grammar} | 724 %\begin{grammar} |
725 %restFormalParameter: | 725 %restFormalParameter: |
726 % finalConstVarOrType? '{\escapegrammar ...}' identifier | 726 % finalConstVarOrType? '{\escapegrammar ...}' identifier |
727 %\end{grammar} | 727 %\end{grammar} |
728 | 728 |
729 \subsubsection{Optional Formals} | 729 \subsubsection{Optional Formals} |
730 \LMLabel{optionalFormals} | 730 \LMLabel{optionalFormals} |
731 | 731 |
732 \LMHash{} | 732 \LMHash{} |
733 Optional parameters may be specified and provided with default values. | 733 Optional parameters may be specified and provided with default values. |
734 | 734 |
735 \begin{grammar} | 735 \begin{grammar} |
736 {\bf defaultFormalParameter:} | 736 {\bf defaultFormalParameter:} |
737 normalFormalParameter ('=' expression)? | 737 normalFormalParameter ('=' expression)? |
738 . | 738 . |
739 | 739 |
740 {\bf defaultNamedParameter:} | 740 {\bf defaultNamedParameter:} |
741 normalFormalParameter ( `{\escapegrammar :}' expression)? | 741 normalFormalParameter ( `{\escapegrammar :}' expression)? |
742 . | 742 . |
743 \end{grammar} | 743 \end{grammar} |
744 | 744 |
745 \LMHash{} | 745 \LMHash{} |
746 It is a compile-time error if the default value of an optional parameter is not a compile-time constant (\ref{constants}). If no default is explicitly specified for an optional parameter an implicit default of \NULL{} is provided. | 746 It is a compile-time error if the default value of an optional parameter is not a compile-time constant (\ref{constants}). If no default is explicitly specified for an optional parameter an implicit default of \NULL{} is provided. |
747 | 747 |
748 \LMHash{} | 748 \LMHash{} |
749 It is a compile-time error if the name of a named optional parameter begins with an `\_' character. | 749 It is a compile-time error if the name of a named optional parameter begins with an `\_' character. |
750 | 750 |
751 \rationale{ | 751 \rationale{ |
752 The need for this restriction is a direct consequence of the fact that naming a nd privacy are not orthogonal. | 752 The need for this restriction is a direct consequence of the fact that naming a nd privacy are not orthogonal. |
753 If we allowed named parameters to begin with an underscore, they would be consid ered private and inaccessible to callers from outside the library where it was d efined. If a method outside the library overrode a method with a private optiona l name, it would not be a subtype of the original method. The static checker wou ld of course flag such situations, but the consequence would be that adding a pr ivate named formal would break clients outside the library in a way they could n ot easily correct. | 753 If we allowed named parameters to begin with an underscore, they would be consid ered private and inaccessible to callers from outside the library where it was d efined. If a method outside the library overrode a method with a private optiona l name, it would not be a subtype of the original method. The static checker wou ld of course flag such situations, but the consequence would be that adding a pr ivate named formal would break clients outside the library in a way they could n ot easily correct. |
754 } | 754 } |
755 | 755 |
756 \subsection{Type of a Function} | 756 \subsection{Type of a Function} |
757 \LMLabel{typeOfAFunction} | 757 \LMLabel{typeOfAFunction} |
758 | 758 |
759 \LMHash{} | 759 \LMHash{} |
760 If a function does not declare a return type explicitly, its return type is \DYN AMIC{} (\ref{typeDynamic}), unless it is a constructor function, in which case i ts return type is the immediately enclosing class. | 760 If a function does not declare a return type explicitly, its return type is \DYN AMIC{} (\ref{typeDynamic}), unless it is a constructor function, in which case i ts return type is the immediately enclosing class. |
761 | 761 |
762 \LMHash{} | 762 \LMHash{} |
763 Let $F$ be a function with required formal parameters $T_1$ $p_1 \ldots, T_n$ $p _n$, return type $T_0$ and no optional parameters. Then the type of $F$ is $(T_1 ,\ldots, T_n) \rightarrow T_0$. | 763 Let $F$ be a function with required formal parameters $T_1$ $p_1 \ldots, T_n$ $p _n$, return type $T_0$ and no optional parameters. Then the type of $F$ is $(T_1 ,\ldots, T_n) \rightarrow T_0$. |
764 | 764 |
765 \LMHash{} | 765 \LMHash{} |
766 Let $F$ be a function with required formal parameters $T_1$ $p_1 \ldots, T_n$ $p _n$, return type $T_0$ and positional optional parameters $T_{n+1}$ $p_{n+1}, \l dots, T_{n+k}$ $ p_{n+k}$. Then the type of $F$ is $(T_1 ,\ldots, T_n, [T_{n+1}$ $p_{n+1}, \ldots, T_{n+k}$ $p_{n+k}]) \rightarrow T_0$. | 766 Let $F$ be a function with required formal parameters $T_1$ $p_1 \ldots, T_n$ $p _n$, return type $T_0$ and positional optional parameters $T_{n+1}$ $p_{n+1}, \l dots, T_{n+k}$ $ p_{n+k}$. Then the type of $F$ is $(T_1 ,\ldots, T_n, [T_{n+1}$ $p_{n+1}, \ldots, T_{n+k}$ $p_{n+k}]) \rightarrow T_0$. |
767 | 767 |
768 \LMHash{} | 768 \LMHash{} |
769 Let $F$ be a function with required formal parameters $T_1$ $p_1 \ldots, T_n$ $p _n$, return type $T_0$ and named optional parameters $T_{n+1}$ $p_{n+1}, \ldots, T_{n+k}$ $ p_{n+k}$. Then the type of $F$ is $(T_1 ,\ldots, T_n, \{T_{n+1}$ $p_ {n+1}, \ldots, T_{n+k}$ $p_{n+k}\}) \rightarrow T_0$. | 769 Let $F$ be a function with required formal parameters $T_1$ $p_1 \ldots, T_n$ $p _n$, return type $T_0$ and named optional parameters $T_{n+1}$ $p_{n+1}, \ldots, T_{n+k}$ $ p_{n+k}$. Then the type of $F$ is $(T_1 ,\ldots, T_n, \{T_{n+1}$ $p_ {n+1}, \ldots, T_{n+k}$ $p_{n+k}\}) \rightarrow T_0$. |
770 | 770 |
771 \LMHash{} | 771 \LMHash{} |
772 The run time type of a function object always implements the class \cd{Function} . | 772 The run time type of a function object always implements the class \cd{Function} . |
773 | 773 |
774 \commentary{ | 774 \commentary{ |
775 One cannot assume, based on the above, that given a function \cd{f}, \cd{f.runt imeType} will actually be \cd{Function}, or that any two distinct function objec ts necessarily have the same runtime type. | 775 One cannot assume, based on the above, that given a function \cd{f}, \cd{f.runt imeType} will actually be \cd{Function}, or that any two distinct function objec ts necessarily have the same runtime type. |
776 } | 776 } |
777 | 777 |
778 \rationale{ | 778 \rationale{ |
779 It is up to the implementation to choose an appropriate representation for funct ions. | 779 It is up to the implementation to choose an appropriate representation for funct ions. |
780 For example, consider that a closure produced via property extraction treats equ ality different from ordinary closures, and is therefore likely a different clas s. Implementations may also use different classes for functions based on arity a nd or type. Arity may be implicitly affected by whether a function is an instanc e method (with an implicit receiver parameter) or not. The variations are manifo ld, and so this specification only guarantees that function objects are instance s of some class that is considered to implement \cd{Function}. | 780 For example, consider that a closure produced via property extraction treats equ ality different from ordinary closures, and is therefore likely a different clas s. Implementations may also use different classes for functions based on arity a nd or type. Arity may be implicitly affected by whether a function is an instanc e method (with an implicit receiver parameter) or not. The variations are manifo ld, and so this specification only guarantees that function objects are instance s of some class that is considered to implement \cd{Function}. |
781 | 781 |
782 } | 782 } |
783 | 783 |
784 \subsection{External Functions} | 784 \subsection{External Functions} |
785 \LMLabel{externalFunctions} | 785 \LMLabel{externalFunctions} |
786 | 786 |
787 \LMHash{} | 787 \LMHash{} |
788 An {\em external function} is a function whose body is provided separately from its declaration. An external function may be a top-level function (\ref{librarie sAndScripts}), a method (\ref{instanceMethods}, \ref{staticMethods}), a getter ( \ref{getters}), a setter (\ref{setters}) or a non-redirecting constructor (\ref{ generativeConstructors}, \ref{factories}). External functions are introduced via the built-in identifier \EXTERNAL{} (\ref{identifierReference}) followed by th e function signature. | 788 An {\em external function} is a function whose body is provided separately from its declaration. An external function may be a top-level function (\ref{librarie sAndScripts}), a method (\ref{instanceMethods}, \ref{staticMethods}), a getter ( \ref{getters}), a setter (\ref{setters}) or a non-redirecting constructor (\ref{ generativeConstructors}, \ref{factories}). External functions are introduced via the built-in identifier \EXTERNAL{} (\ref{identifierReference}) followed by th e function signature. |
789 | 789 |
790 \rationale{ | 790 \rationale{ |
791 External functions allow us to introduce type information for code that is not statically known to the Dart compiler. | 791 External functions allow us to introduce type information for code that is not statically known to the Dart compiler. |
792 } | 792 } |
793 | 793 |
794 \commentary{ | 794 \commentary{ |
795 Examples of external functions might be foreign functions (defined in C, or Java script etc.), primitives of the implementation (as defined by the Dart runtime), or code that was dynamically generated but whose interface is statically known. However, an abstract method is different from an external function, as it has { \em no} body. | 795 Examples of external functions might be foreign functions (defined in C, or Java script etc.), primitives of the implementation (as defined by the Dart runtime), or code that was dynamically generated but whose interface is statically known. However, an abstract method is different from an external function, as it has { \em no} body. |
796 } | 796 } |
797 | 797 |
798 \LMHash{} | 798 \LMHash{} |
799 An external function is connected to its body by an implementation specific mech anism. Attempting to invoke an external function that has not been connected to its body will raise a \code{NoSuchMethodError} or some subclass thereof. | 799 An external function is connected to its body by an implementation specific mech anism. Attempting to invoke an external function that has not been connected to its body will raise a \code{NoSuchMethodError} or some subclass thereof. |
800 | 800 |
801 \LMHash{} | 801 \LMHash{} |
802 The actual syntax is given in sections \ref{classes} and \ref{librariesAndScript s} below. | 802 The actual syntax is given in sections \ref{classes} and \ref{librariesAndScript s} below. |
803 | 803 |
804 \section{Classes} | 804 \section{Classes} |
805 \LMLabel{classes} | 805 \LMLabel{classes} |
806 | 806 |
807 \LMHash{} | 807 \LMHash{} |
808 A {\em class} defines the form and behavior of a set of objects which are its {\ em instances}. Classes may be defined by class declarations as described below, or via mixin applications (\ref{mixinApplication}). | 808 A {\em class} defines the form and behavior of a set of objects which are its {\ em instances}. Classes may be defined by class declarations as described below, or via mixin applications (\ref{mixinApplication}). |
809 | 809 |
810 \begin{grammar} | 810 \begin{grammar} |
811 {\bf classDefinition:} | 811 {\bf classDefinition:} |
812 metadata \ABSTRACT{}? \CLASS{} identifier typeParameters? (superclass mixins?)? interfaces? \\ | 812 metadata \ABSTRACT{}? \CLASS{} identifier typeParameters? (superclass mixins?)? interfaces? \\ |
813 `\{' (metadata classMemberDefinition)* `\}'; | 813 `\{' (metadata classMemberDefinition)* `\}'; |
814 | 814 |
815 metadata \ABSTRACT{}? \CLASS{} mixinApplicationClass | 815 metadata \ABSTRACT{}? \CLASS{} mixinApplicationClass |
816 . | 816 . |
817 | 817 |
818 {\bf mixins:} | 818 {\bf mixins:} |
819 \WITH{} typeList | 819 \WITH{} typeList |
820 . | 820 . |
821 | 821 |
822 {\bf classMemberDefinition:}declaration `{\escapegrammar ;}' ; | 822 {\bf classMemberDefinition:}declaration `{\escapegrammar ;}' ; |
823 methodSignature functionBody | 823 methodSignature functionBody |
824 . | 824 . |
825 | 825 |
826 {\bf methodSignature:}constructorSignature initializers?; | 826 {\bf methodSignature:}constructorSignature initializers?; |
827 factoryConstructorSignature; | 827 factoryConstructorSignature; |
(...skipping 25 matching lines...) Expand all Loading... | |
853 identifier `=' expression | 853 identifier `=' expression |
854 . | 854 . |
855 | 855 |
856 \end{grammar} | 856 \end{grammar} |
857 | 857 |
858 \LMHash{} | 858 \LMHash{} |
859 A class has constructors, instance members and static members. The instance mem bers of a class are its instance methods, getters, setters and instance variable s. The static members of a class are its static methods, getters, setters and st atic variables. The members of a class are its static and instance members. | 859 A class has constructors, instance members and static members. The instance mem bers of a class are its instance methods, getters, setters and instance variable s. The static members of a class are its static methods, getters, setters and st atic variables. The members of a class are its static and instance members. |
860 | 860 |
861 A class has several scopes: | 861 A class has several scopes: |
862 \begin{itemize} | 862 \begin{itemize} |
863 \item A {\em type-parameter scope}, which is empty if the class is not generic ( \ref{generics}). The enclosing scope of the type-parameter scope of a class is the enclosing scope of the class declaration. | 863 \item A {\em type-parameter scope}, which is empty if the class is not generic ( \ref{generics}). The enclosing scope of the type-parameter scope of a class is the enclosing scope of the class declaration. |
864 \item A {\em static scope}. The enclosing scope of the static scope of a class is the type parameter scope (\ref{generics}) of the class. | 864 \item A {\em static scope}. The enclosing scope of the static scope of a class is the type parameter scope (\ref{generics}) of the class. |
865 \item An {\em instance scope}. | 865 \item An {\em instance scope}. |
866 The enclosing scope of a class' instance scope is the class' static scope. | 866 The enclosing scope of a class' instance scope is the class' static scope. |
867 \end{itemize} | 867 \end{itemize} |
868 | 868 |
869 The enclosing scope of an instance member declaration is the instance scope of t he class in which it is declared. | 869 The enclosing scope of an instance member declaration is the instance scope of t he class in which it is declared. |
870 | 870 |
871 The enclosing scope of a static member declaration is the static scope of the cl ass in which it is declared. | 871 The enclosing scope of a static member declaration is the static scope of the cl ass in which it is declared. |
872 | 872 |
873 | 873 |
874 \LMHash{} | 874 \LMHash{} |
875 Every class has a single superclass except class \code{Object} which has no sup erclass. A class may implement a number of interfaces | 875 Every class has a single superclass except class \code{Object} which has no sup erclass. A class may implement a number of interfaces |
876 %, either | 876 %, either |
877 by declaring them in its implements clause (\ref{superinterfaces}). | 877 by declaring them in its implements clause (\ref{superinterfaces}). |
878 % or via interface injection declarations (\ref{interfaceInjection}) outside the class declaration | 878 % or via interface injection declarations (\ref{interfaceInjection}) outside the class declaration |
879 | 879 |
880 | 880 |
881 \LMHash{} | 881 \LMHash{} |
882 An {\em abstract class} is | 882 An {\em abstract class} is |
883 %either | 883 %either |
884 a class that is explicitly declared with the \ABSTRACT{} modifier, either by m eans of a class declaration or via a type alias (\ref{typedef}) for a mixin appl ication (\ref{mixinApplication}). A {\em concrete class} is a class that is not abstract. | 884 a class that is explicitly declared with the \ABSTRACT{} modifier, either by m eans of a class declaration or via a type alias (\ref{typedef}) for a mixin appl ication (\ref{mixinApplication}). A {\em concrete class} is a class that is not abstract. |
885 %, or a class that declares at least one abstract method (\ref{abstractInstance Members}). | 885 %, or a class that declares at least one abstract method (\ref{abstractInstance Members}). |
886 | 886 |
887 \rationale{ | 887 \rationale{ |
888 %The abstract modifier for classes is intended to be used in scenarios where an abstract class $A$ inherits from another abstract class $B$. In such a situation , it may be that A$ $itself does not declare any abstract methods. In the absenc e of an abstract modifier on the class, the class would be interpreted as a conc rete class. However, w | 888 %The abstract modifier for classes is intended to be used in scenarios where an abstract class $A$ inherits from another abstract class $B$. In such a situation , it may be that A$ $itself does not declare any abstract methods. In the absenc e of an abstract modifier on the class, the class would be interpreted as a conc rete class. However, w |
889 We want different behavior for concrete classes and abstract classes. If $A$ is intended to be abstract, we want the static checker to warn about any attempt to instantiate $A$, and we do not want the checker to complain about unimplemented methods in $A$. In contrast, if $A$ is intended to be concrete, the checker sho uld warn about all unimplemented methods, but allow clients to instantiate it fr eely. | 889 We want different behavior for concrete classes and abstract classes. If $A$ is intended to be abstract, we want the static checker to warn about any attempt to instantiate $A$, and we do not want the checker to complain about unimplemented methods in $A$. In contrast, if $A$ is intended to be concrete, the checker sho uld warn about all unimplemented methods, but allow clients to instantiate it fr eely. |
890 } | 890 } |
891 | 891 |
892 \LMHash{} | 892 \LMHash{} |
893 The {\em interface of class $C$} is an implicit interface that declares instance members that correspond to the instance members declared by $C$, and whose dire ct superinterfaces are the direct superinterfaces of $C$ (\ref{superinterfaces}) . When a class name appears as a type, that name denotes the interface of the cl ass. | 893 The {\em interface of class $C$} is an implicit interface that declares instance members that correspond to the instance members declared by $C$, and whose dire ct superinterfaces are the direct superinterfaces of $C$ (\ref{superinterfaces}) . When a class name appears as a type, that name denotes the interface of the cl ass. |
894 | 894 |
895 % making an exception for the setters generated for final fields is tempting but problematic. | 895 % making an exception for the setters generated for final fields is tempting but problematic. |
896 % If a super type defines a setter, it will be overridden yet have no impact on the interface. | 896 % If a super type defines a setter, it will be overridden yet have no impact on the interface. |
897 % Maybe the final field hides the setter in scope? | 897 % Maybe the final field hides the setter in scope? |
898 % I think the original rules were best. | 898 % I think the original rules were best. |
899 | 899 |
900 \LMHash{} | 900 \LMHash{} |
901 It is a compile-time error if a class declares two members of the same name. | 901 It is a compile-time error if a class declares two members of the same name. |
902 %, except that a getter and a setter may be declared with the same name provide d both are instance members or both are static members. | 902 %, except that a getter and a setter may be declared with the same name provide d both are instance members or both are static members. |
903 It is a compile-time error if a class has an instance member and a static member with the same name. | 903 It is a compile-time error if a class has an instance member and a static member with the same name. |
904 % It is a compile-time error if a generic (\ref{generics}) class declares a memb er with the same name as one of its type parameters. | 904 % It is a compile-time error if a generic (\ref{generics}) class declares a memb er with the same name as one of its type parameters. |
905 | 905 |
906 \commentary{Here are simple examples, that illustrate the difference between ``h as a member'' and ``declares a member''. For example, \code{B} {\em declares} on e member named \code{f}, but {\em has} two such members. The rules of inheritanc e determine what members a class has. | 906 \commentary{Here are simple examples, that illustrate the difference between ``h as a member'' and ``declares a member''. For example, \code{B} {\em declares} on e member named \code{f}, but {\em has} two such members. The rules of inheritanc e determine what members a class has. |
907 } | 907 } |
908 | 908 |
909 \begin{dartCode} | 909 \begin{dartCode} |
910 \CLASS{} A \{ | 910 \CLASS{} A \{ |
911 \VAR{} i = 0; | 911 \VAR{} i = 0; |
912 \VAR{} j; | 912 \VAR{} j; |
913 f(x) =$>$ 3; | 913 f(x) =$>$ 3; |
914 \} | 914 \} |
915 | 915 |
916 \CLASS{} B \EXTENDS{} A \{ | 916 \CLASS{} B \EXTENDS{} A \{ |
917 int i = 1; // getter i and setter i= override versions from A | 917 int i = 1; // getter i and setter i= override versions from A |
918 \STATIC{} j; // compile-time error: static getter \& setter conflict with | 918 \STATIC{} j; // compile-time error: static getter \& setter conflict with |
919 //instance getter \& setter | 919 //instance getter \& setter |
920 | 920 |
921 /* compile-time error: static method conflicts with instance method */ | 921 /* compile-time error: static method conflicts with instance method */ |
922 \STATIC{} f(x) =$>$ 3; | 922 \STATIC{} f(x) =$>$ 3; |
923 \} | 923 \} |
924 \end{dartCode} | 924 \end{dartCode} |
925 | 925 |
926 \LMHash{} | 926 \LMHash{} |
927 It is a compile time error if a class $C$ declares a member with the same name a s $C$. It is a compile time error if a generic class declares a type variable wi th the same name as the class or any of its members or constructors. | 927 It is a compile time error if a class $C$ declares a member with the same name a s $C$. It is a compile time error if a generic class declares a type variable wi th the same name as the class or any of its members or constructors. |
928 | 928 |
929 \subsection{Instance Methods} | 929 \subsection{Instance Methods} |
930 \LMLabel{instanceMethods} | 930 \LMLabel{instanceMethods} |
931 | 931 |
932 \LMHash{} | 932 \LMHash{} |
933 Instance methods are functions (\ref{functions}) whose declarations are immediat ely contained within a class declaration and that are not declared \STATIC{}. Th e instance methods of a class $C$ are those instance methods declared by $C$ and the instance methods inherited by $C$ from its superclass. | 933 Instance methods are functions (\ref{functions}) whose declarations are immediat ely contained within a class declaration and that are not declared \STATIC{}. Th e instance methods of a class $C$ are those instance methods declared by $C$ and the instance methods inherited by $C$ from its superclass. |
934 | 934 |
935 %make these warnings if possible | 935 %make these warnings if possible |
936 | 936 |
937 \LMHash{} | 937 \LMHash{} |
938 It is a static warning if an instance method $m_1$ overrides (\ref{inheritanceA ndOverriding}) an instance member $m_2$ and $m_1$ has a greater number of requi red parameters than $m_2$. It is a static warning if an instance method $m_1$ ov errides an instance member $m_2$ and $m_1$ has fewer positional parameters tha n $m_2$. It is a static warning if an instance method $m_1$ overrides an insta nce member $m_2$ and $m_1$ does not declare all the named parameters declared b y $m_2$. | 938 It is a static warning if an instance method $m_1$ overrides (\ref{inheritanceA ndOverriding}) an instance member $m_2$ and $m_1$ has a greater number of requi red parameters than $m_2$. It is a static warning if an instance method $m_1$ ov errides an instance member $m_2$ and $m_1$ has fewer positional parameters tha n $m_2$. It is a static warning if an instance method $m_1$ overrides an insta nce member $m_2$ and $m_1$ does not declare all the named parameters declared b y $m_2$. |
939 | 939 |
940 % not quite right. It should be ok to override a method that requires N paramete rs with one that requires M < N but accepts the others as optional. | 940 % not quite right. It should be ok to override a method that requires N paramete rs with one that requires M < N but accepts the others as optional. |
941 | 941 |
942 \LMHash{} | 942 \LMHash{} |
943 It is a static warning if an instance method $m_1$ overrides an instance member $m_2$ and the type of $m_1$ is not a subtype of the type of $m_2$. It is a stati c warning if an instance method $m_1$ overrides an instance member $m_2$, the s ignature of $m_2$ explicitly specifies a default value for a formal parameter $p $ and the signature of $m_1$ implies a different default value for $p$. It is a static warning if a class $C$ declares an instance method named $n$ and has a se tter named $n=$. It is a static warning if a class $C$ declares an instance meth od named $n$ and an accessible static member named $n$ is declared in a supercla ss of $C$. | 943 It is a static warning if an instance method $m_1$ overrides an instance member $m_2$ and the type of $m_1$ is not a subtype of the type of $m_2$. It is a stati c warning if an instance method $m_1$ overrides an instance member $m_2$, the s ignature of $m_2$ explicitly specifies a default value for a formal parameter $p $ and the signature of $m_1$ implies a different default value for $p$. It is a static warning if a class $C$ declares an instance method named $n$ and has a se tter named $n=$. It is a static warning if a class $C$ declares an instance meth od named $n$ and an accessible static member named $n$ is declared in a supercla ss of $C$. |
944 | 944 |
945 % Works. If the name is public, no issue. If it's private, if a subclass has a c onflicting inst var, it either is in the same lib and will be flagged, or is in another and is not an issue. | 945 % Works. If the name is public, no issue. If it's private, if a subclass has a c onflicting inst var, it either is in the same lib and will be flagged, or is in another and is not an issue. |
946 | 946 |
947 | 947 |
948 \subsubsection{Operators} | 948 \subsubsection{Operators} |
949 \LMLabel{operators} | 949 \LMLabel{operators} |
950 | 950 |
951 \LMHash{} | 951 \LMHash{} |
952 {\em Operators} are instance methods with special names. | 952 {\em Operators} are instance methods with special names. |
953 | 953 |
954 \begin{grammar} | 954 \begin{grammar} |
955 {\bf operatorSignature:} | 955 {\bf operatorSignature:} |
956 returnType? \OPERATOR{} operator formalParameterList | 956 returnType? \OPERATOR{} operator formalParameterList |
957 . | 957 . |
958 | 958 |
959 {\bf operator:}`\~{}'; | 959 {\bf operator:}`\~{}'; |
960 binaryOperator; | 960 binaryOperator; |
961 `[' `]' ; | 961 `[' `]' ; |
962 `[' `]' `=' | 962 `[' `]' `=' |
963 . | 963 . |
964 | 964 |
965 {\bf binaryOperator:}multiplicativeOperator; | 965 {\bf binaryOperator:}multiplicativeOperator; |
966 additiveOperator; | 966 additiveOperator; |
967 shiftOperator; | 967 shiftOperator; |
968 relationalOperator; | 968 relationalOperator; |
969 `=='; | 969 `=='; |
970 bitwiseOperator | 970 bitwiseOperator |
971 . | 971 . |
972 \end{grammar} | 972 \end{grammar} |
973 | 973 |
974 \LMHash{} | 974 \LMHash{} |
975 An operator declaration is identified using the built-in identifier (\ref{identi fierReference}) \OPERATOR{}. | 975 An operator declaration is identified using the built-in identifier (\ref{identi fierReference}) \OPERATOR{}. |
976 | 976 |
977 \LMHash{} | 977 \LMHash{} |
978 The following names are allowed for user-defined operators: \code{$<$, $>$, $<$= , $>$=, ==, -, +, /, \~{}/, *, \%, $|$, \^{}, \&, $<<$, $>>$, []=, [], \~{}.} | 978 The following names are allowed for user-defined operators: \code{$<$, $>$, $<$= , $>$=, ==, -, +, /, \~{}/, *, \%, $|$, \^{}, \&, $<<$, $>>$, []=, [], \~{}.} |
979 | 979 |
980 | 980 |
981 \LMHash{} | 981 \LMHash{} |
982 It is a compile-time error if the arity of the user-declared operator \code{[]=} is not 2. It is a compile-time error if the arity of a user-declared operator w ith one of the names: \code{ $<$, $>$, $<$=, $>$=, ==, -, +, \~{}/, /, *, \%, $|$, \^{}, \&, $<<$, $>>$, []} is not 1. It is a compile-time error if the arity of the user-declared operator \code{-} is not 0 or 1. | 982 It is a compile-time error if the arity of the user-declared operator \code{[]=} is not 2. It is a compile-time error if the arity of a user-declared operator w ith one of the names: \code{ $<$, $>$, $<$=, $>$=, ==, -, +, \~{}/, /, *, \%, $|$, \^{}, \&, $<<$, $>>$, []} is not 1. It is a compile-time error if the arity of the user-declared operator \code{-} is not 0 or 1. |
983 | 983 |
984 \commentary{ | 984 \commentary{ |
985 The \code{-} operator is unique in that two overloaded versions are permitted. I f the operator has no arguments, it denotes unary minus. If it has an argument, it denotes binary subtraction. | 985 The \code{-} operator is unique in that two overloaded versions are permitted. I f the operator has no arguments, it denotes unary minus. If it has an argument, it denotes binary subtraction. |
986 } | 986 } |
987 | 987 |
988 \LMHash{} | 988 \LMHash{} |
989 The name of the unary operator \code{-} is \code{unary-}. | 989 The name of the unary operator \code{-} is \code{unary-}. |
990 | 990 |
991 \rationale{ | 991 \rationale{ |
992 This device allows the two methods to be distinguished for purposes of method lo okup, override and reflection. | 992 This device allows the two methods to be distinguished for purposes of method lo okup, override and reflection. |
993 } | 993 } |
994 | 994 |
995 \LMHash{} | 995 \LMHash{} |
996 It is a compile-time error if the arity of the user-declared operator \code{ \~ {}} is not 0. | 996 It is a compile-time error if the arity of the user-declared operator \code{ \~ {}} is not 0. |
997 | 997 |
998 \LMHash{} | 998 \LMHash{} |
999 It is a compile-time error to declare an optional parameter in an operator. | 999 It is a compile-time error to declare an optional parameter in an operator. |
1000 | 1000 |
1001 \LMHash{} | 1001 \LMHash{} |
1002 It is a static warning if the return type of the user-declared operator \code{[] =} is explicitly declared and not \VOID{}. | 1002 It is a static warning if the return type of the user-declared operator \code{[] =} is explicitly declared and not \VOID{}. |
1003 | 1003 |
1004 % add rationale: return in []= methods will have no effect, a the expression alw ays returns its second argument (the RHS of the assignment, for consistency with assignment in general). So it's best to enforce this by declaring the method to be void, even though the expression that uses it returns an object with the typ e of the RHS, as described in \ref{assignment}. | 1004 % add rationale: return in []= methods will have no effect, a the expression alw ays returns its second argument (the RHS of the assignment, for consistency with assignment in general). So it's best to enforce this by declaring the method to be void, even though the expression that uses it returns an object with the typ e of the RHS, as described in \ref{assignment}. |
1005 | 1005 |
1006 | 1006 |
1007 \subsection{Getters} | 1007 \subsection{Getters} |
1008 \LMLabel{getters} | 1008 \LMLabel{getters} |
1009 | 1009 |
1010 \LMHash{} | 1010 \LMHash{} |
1011 Getters are functions (\ref{functions}) that are used to retrieve the values of object properties. | 1011 Getters are functions (\ref{functions}) that are used to retrieve the values of object properties. |
1012 | 1012 |
1013 \begin{grammar} | 1013 \begin{grammar} |
1014 {\bf getterSignature:} | 1014 {\bf getterSignature:} |
1015 returnType? \GET{} identifier | 1015 returnType? \GET{} identifier |
1016 . | 1016 . |
1017 \end{grammar} | 1017 \end{grammar} |
1018 | 1018 |
1019 %\Q{Why does a getter have a formal parameter list at all?} | 1019 %\Q{Why does a getter have a formal parameter list at all?} |
1020 | 1020 |
1021 \LMHash{} | 1021 \LMHash{} |
1022 If no return type is specified, the return type of the getter is \DYNAMIC{}. | 1022 If no return type is specified, the return type of the getter is \DYNAMIC{}. |
1023 | 1023 |
1024 \LMHash{} | 1024 \LMHash{} |
1025 A getter definition that is prefixed with the \STATIC{} modifier defines a stati c getter. Otherwise, it defines an instance getter. The name of the getter is gi ven by the identifier in the definition. The effect of a static getter declarati on in class $C$ is to add an instance getter with the same name and signature to the \code{Type} object for class $C$ that forwards (\ref{functionDeclarations}) to the static getter. | 1025 A getter definition that is prefixed with the \STATIC{} modifier defines a stati c getter. Otherwise, it defines an instance getter. The name of the getter is gi ven by the identifier in the definition. The effect of a static getter declarati on in class $C$ is to add an instance getter with the same name and signature to the \code{Type} object for class $C$ that forwards (\ref{functionDeclarations}) to the static getter. |
1026 | 1026 |
1027 %It is a compile-time error if a getter`s formal parameter list is not empty. | 1027 %It is a compile-time error if a getter`s formal parameter list is not empty. |
1028 | 1028 |
1029 \LMHash{} | 1029 \LMHash{} |
1030 The instance getters of a class $C$ are those instance getters declared by $C$, either implicitly or explicitly, and the instance getters inherited by $C$ from its superclass. The static getters of a class $C$ are those static getters decla red by $C$. | 1030 The instance getters of a class $C$ are those instance getters declared by $C$, either implicitly or explicitly, and the instance getters inherited by $C$ from its superclass. The static getters of a class $C$ are those static getters decla red by $C$. |
1031 | 1031 |
1032 \LMHash{} | 1032 \LMHash{} |
1033 It is a compile-time error if a class has both a getter and a method with the sa me name. This restriction holds regardless of whether the getter is defined expl icitly or implicitly, or whether the getter or the method are inherited or not. | 1033 It is a compile-time error if a class has both a getter and a method with the sa me name. This restriction holds regardless of whether the getter is defined expl icitly or implicitly, or whether the getter or the method are inherited or not. |
1034 | 1034 |
1035 \commentary{ | 1035 \commentary{ |
1036 This implies that a getter can never override a method, and a method can never o verride a getter or field. | 1036 This implies that a getter can never override a method, and a method can never o verride a getter or field. |
1037 } | 1037 } |
1038 | 1038 |
1039 \LMHash{} | 1039 \LMHash{} |
1040 It is a static warning if the return type of a getter is \VOID. | 1040 It is a static warning if the return type of a getter is \VOID. |
1041 It is a static warning if a getter $m_1$ overrides (\ref{inheritanceAndOverridi ng}) a getter | 1041 It is a static warning if a getter $m_1$ overrides (\ref{inheritanceAndOverridi ng}) a getter |
1042 $m_2$ and the type of $m_1$ is not a subtype of the type of $m_2$. | 1042 $m_2$ and the type of $m_1$ is not a subtype of the type of $m_2$. |
1043 | 1043 |
1044 \LMHash{} | 1044 \LMHash{} |
1045 It is a static warning if a class declares a static getter named $v$ and also h as a non-static setter named $v=$. It is a static warning if a class $C$ declare s an instance getter named $v$ and an accessible static member named $v$ or $v=$ is declared in a superclass of $C$. These warnings must be issued regardless of whether the getters or setters are declared explicitly or implicitly. | 1045 It is a static warning if a class declares a static getter named $v$ and also h as a non-static setter named $v=$. It is a static warning if a class $C$ declare s an instance getter named $v$ and an accessible static member named $v$ or $v=$ is declared in a superclass of $C$. These warnings must be issued regardless of whether the getters or setters are declared explicitly or implicitly. |
1046 | 1046 |
1047 \subsection{Setters} | 1047 \subsection{Setters} |
1048 \LMLabel{setters} | 1048 \LMLabel{setters} |
1049 | 1049 |
1050 \LMHash{} | 1050 \LMHash{} |
1051 Setters are functions (\ref{functions}) that are used to set the values of objec t properties. | 1051 Setters are functions (\ref{functions}) that are used to set the values of objec t properties. |
1052 | 1052 |
(...skipping 16 matching lines...) Expand all Loading... | |
1069 \LMHash{} | 1069 \LMHash{} |
1070 The instance setters of a class $C$ are those instance setters declared by $C$ e ither implicitly or explicitly, and the instance setters inherited by $C$ from i ts superclass. The static setters of a class $C$ are those static setters declar ed by $C$. | 1070 The instance setters of a class $C$ are those instance setters declared by $C$ e ither implicitly or explicitly, and the instance setters inherited by $C$ from i ts superclass. The static setters of a class $C$ are those static setters declar ed by $C$. |
1071 | 1071 |
1072 \LMHash{} | 1072 \LMHash{} |
1073 It is a compile-time error if a setter's formal parameter list does not consist of exactly one required formal parameter $p$. \rationale{We could enforce this via the grammar, but we'd have to specify the evaluation rules in that case.} | 1073 It is a compile-time error if a setter's formal parameter list does not consist of exactly one required formal parameter $p$. \rationale{We could enforce this via the grammar, but we'd have to specify the evaluation rules in that case.} |
1074 | 1074 |
1075 %It is a compile-time error if a class has both a setter and a method with the s ame name. This restriction holds regardless of whether the setter is defined exp licitly or implicitly, or whether the setter or the method are inherited or not. | 1075 %It is a compile-time error if a class has both a setter and a method with the s ame name. This restriction holds regardless of whether the setter is defined exp licitly or implicitly, or whether the setter or the method are inherited or not. |
1076 | 1076 |
1077 \LMHash{} | 1077 \LMHash{} |
1078 It is a static warning if a setter declares a return type other than \VOID{}. | 1078 It is a static warning if a setter declares a return type other than \VOID{}. |
1079 It is a static warning if a setter $m_1$ overrides (\ref{inheritanceAndOverridi ng}) a setter $m_2$ and the type of $m_1$ is not a subtype of the type of $m_2$. It is a static warning if a class has a setter named $v=$ with argument type $T $ and a getter named $v$ with return type $S$, and $T$ may not be assigned to $S $. | 1079 It is a static warning if a setter $m_1$ overrides (\ref{inheritanceAndOverridi ng}) a setter $m_2$ and the type of $m_1$ is not a subtype of the type of $m_2$. It is a static warning if a class has a setter named $v=$ with argument type $T $ and a getter named $v$ with return type $S$, and $T$ may not be assigned to $S $. |
1080 | 1080 |
1081 \LMHash{} | 1081 \LMHash{} |
1082 It is a static warning if a class declares a static setter named $v=$ and also has a non-static member named $v$. It is a static warning if a class $C$ declare s an instance setter named $v=$ and an accessible static member named $v=$ or $v $ is declared in a superclass of $C$. | 1082 It is a static warning if a class declares a static setter named $v=$ and also has a non-static member named $v$. It is a static warning if a class $C$ declare s an instance setter named $v=$ and an accessible static member named $v=$ or $v $ is declared in a superclass of $C$. |
1083 | 1083 |
1084 \LMHash{} | 1084 \LMHash{} |
1085 These warnings must be issued regardless of whether the getters or setters are d eclared explicitly or implicitly. | 1085 These warnings must be issued regardless of whether the getters or setters are d eclared explicitly or implicitly. |
1086 | 1086 |
1087 \subsection{Abstract Instance Members} | 1087 \subsection{Abstract Instance Members} |
1088 \LMLabel{abstractInstanceMembers} | 1088 \LMLabel{abstractInstanceMembers} |
1089 | 1089 |
(...skipping 17 matching lines...) Expand all Loading... | |
1107 % But if we do override, method lookup rules break down. So several things need revisiting. | 1107 % But if we do override, method lookup rules break down. So several things need revisiting. |
1108 | 1108 |
1109 \rationale{ | 1109 \rationale{ |
1110 The purpose of an abstract method is to provide a declaration for purposes such as type checking and reflection. In classes used as mixins, it is often useful t o introduce such declarations for methods that the mixin expects will be provide d by the superclass the mixin is applied to. | 1110 The purpose of an abstract method is to provide a declaration for purposes such as type checking and reflection. In classes used as mixins, it is often useful t o introduce such declarations for methods that the mixin expects will be provide d by the superclass the mixin is applied to. |
1111 } | 1111 } |
1112 %always results in a run-time error. This must be \code{NoSuchMethodError} or an instance of a subclass of \code{NoSuchMethodError}, such as \code{AbstractMetho dError}. | 1112 %always results in a run-time error. This must be \code{NoSuchMethodError} or an instance of a subclass of \code{NoSuchMethodError}, such as \code{AbstractMetho dError}. |
1113 | 1113 |
1114 \LMHash{} | 1114 \LMHash{} |
1115 It is a static warning if an abstract member $m$ is declared or inherited in a c oncrete class $C$ unless: | 1115 It is a static warning if an abstract member $m$ is declared or inherited in a c oncrete class $C$ unless: |
1116 \begin{itemize} | 1116 \begin{itemize} |
1117 \item $m$ overrides a concrete member, or | 1117 \item $m$ overrides a concrete member, or |
1118 \item $C$ has a \cd{noSuchMethod()} method distinct from the one declared in cla ss \cd{Object}. | 1118 \item $C$ has a \cd{noSuchMethod()} method distinct from the one declared in cla ss \cd{Object}. |
1119 \end{itemize} | 1119 \end{itemize} |
1120 | 1120 |
1121 \rationale { | 1121 \rationale { |
1122 We wish to warn if one declares a concrete class with abstract members. However, code like the following should work without warnings: | 1122 We wish to warn if one declares a concrete class with abstract members. However, code like the following should work without warnings: |
1123 } | 1123 } |
1124 | 1124 |
1125 \begin{dartCode} | 1125 \begin{dartCode} |
1126 class Base \{ | 1126 class Base \{ |
1127 int get one =$>$ 1; | 1127 int get one =$>$ 1; |
(...skipping 15 matching lines...) Expand all Loading... | |
1143 \LMHash{} | 1143 \LMHash{} |
1144 Instance variables are variables whose declarations are immediately contained wi thin a class declaration and that are not declared \STATIC{}. The instance varia bles of a class $C$ are those instance variables declared by $C$ and the instanc e variables inherited by $C$ from its superclass. | 1144 Instance variables are variables whose declarations are immediately contained wi thin a class declaration and that are not declared \STATIC{}. The instance varia bles of a class $C$ are those instance variables declared by $C$ and the instanc e variables inherited by $C$ from its superclass. |
1145 | 1145 |
1146 \LMHash{} | 1146 \LMHash{} |
1147 It is a compile-time error if an instance variable is declared to be constant. | 1147 It is a compile-time error if an instance variable is declared to be constant. |
1148 | 1148 |
1149 \rationale{ | 1149 \rationale{ |
1150 The notion of a constant instance variable is subtle and confusing to programmer s. | 1150 The notion of a constant instance variable is subtle and confusing to programmer s. |
1151 An instance variable is intended to vary per instance. A constant instance varia ble would have the same value for all instances, and as such is already a dubiou s idea. | 1151 An instance variable is intended to vary per instance. A constant instance varia ble would have the same value for all instances, and as such is already a dubiou s idea. |
1152 | 1152 |
1153 The language could interpret const instance variable declarations as instance ge tters that return a constant. However, a constant instance variable could not b e treated as a true compile time constant, as its getter would be subject to ove rriding. | 1153 The language could interpret const instance variable declarations as instance ge tters that return a constant. However, a constant instance variable could not b e treated as a true compile time constant, as its getter would be subject to ove rriding. |
1154 | 1154 |
1155 Given that the value does not depend on the instance, it is better to use a sta tic class variable. | 1155 Given that the value does not depend on the instance, it is better to use a sta tic class variable. |
1156 An instance getter for it can always be defined manually if desired. | 1156 An instance getter for it can always be defined manually if desired. |
1157 } | 1157 } |
1158 | 1158 |
1159 | 1159 |
1160 %An instance variable declaration of one of the forms \code{$T$ $v$;}, \code{\FI NAL{} $T$ $v$;} , \code{$T$ $v$ = $e$;} , \code{\CONST{} $T$ $v$ = $e$;} or \c ode{\FINAL{} $T$ $v$ = $e$;} always induces an implicit getter function (\ref{g etters}) with signature | 1160 %An instance variable declaration of one of the forms \code{$T$ $v$;}, \code{\FI NAL{} $T$ $v$;} , \code{$T$ $v$ = $e$;} , \code{\CONST{} $T$ $v$ = $e$;} or \c ode{\FINAL{} $T$ $v$ = $e$;} always induces an implicit getter function (\ref{g etters}) with signature |
1161 | 1161 |
1162 %$T$ \GET{} $v$ | 1162 %$T$ \GET{} $v$ |
1163 | 1163 |
1164 %whose invocation evaluates to the value stored in $v$. | 1164 %whose invocation evaluates to the value stored in $v$. |
1165 | 1165 |
1166 %An instance variable declaration of one of the forms \code{\VAR{} $v$;}, \code {\FINAL{} $v$;}, \code{\VAR{} $v$ = $e$;} , \code{\CONST{} $v$ = $e$;} or \code {\FINAL{} $v$ = $e$;} always induces an implicit getter function with signatur e | 1166 %An instance variable declaration of one of the forms \code{\VAR{} $v$;}, \code {\FINAL{} $v$;}, \code{\VAR{} $v$ = $e$;} , \code{\CONST{} $v$ = $e$;} or \code {\FINAL{} $v$ = $e$;} always induces an implicit getter function with signatur e |
1167 | 1167 |
1168 %\GET{} $v$ | 1168 %\GET{} $v$ |
1169 | 1169 |
1170 %whose invocation evaluates to the value stored in $v$. | 1170 %whose invocation evaluates to the value stored in $v$. |
1171 | 1171 |
1172 %\commentary{Getters are introduced for all instance and static variables (\ref{ staticVariables}), regardless of whether they are const/final or not.} | 1172 %\commentary{Getters are introduced for all instance and static variables (\ref{ staticVariables}), regardless of whether they are const/final or not.} |
1173 | 1173 |
1174 %A non-final instance variable declaration of the form \code{$T$ $v$;} or the f orm \code{$T$ $v$ = $e$;} always induces an implicit setter function (\ref{se tters}) with signature | 1174 %A non-final instance variable declaration of the form \code{$T$ $v$;} or the f orm \code{$T$ $v$ = $e$;} always induces an implicit setter function (\ref{se tters}) with signature |
1175 | 1175 |
1176 %\VOID{} \SET{} $v=(T$ $x)$ | 1176 %\VOID{} \SET{} $v=(T$ $x)$ |
1177 | 1177 |
1178 %whose execution sets the value of $v$ to the incoming argument $x$. | 1178 %whose execution sets the value of $v$ to the incoming argument $x$. |
1179 | 1179 |
1180 %A non-final instance variable declaration of the form \code{\VAR{} $v$;} or th e form \code{\VAR{} $v$ = $e$;} always induces an implicit setter function wi th signature | 1180 %A non-final instance variable declaration of the form \code{\VAR{} $v$;} or th e form \code{\VAR{} $v$ = $e$;} always induces an implicit setter function wi th signature |
1181 | 1181 |
1182 %\SET{} $v=(x)$ | 1182 %\SET{} $v=(x)$ |
1183 | 1183 |
1184 %whose execution sets the value of $v$ to the incoming argument $x$. | 1184 %whose execution sets the value of $v$ to the incoming argument $x$. |
1185 | 1185 |
1186 % It is a compile-time error/warning if a class $C$ declares a final instance va riable $v$ and $C$ inherits a setter $v=$. | 1186 % It is a compile-time error/warning if a class $C$ declares a final instance va riable $v$ and $C$ inherits a setter $v=$. |
1187 | 1187 |
1188 | 1188 |
1189 \subsection{Constructors} | 1189 \subsection{Constructors} |
1190 \LMLabel{constructors} | 1190 \LMLabel{constructors} |
1191 | 1191 |
1192 \LMHash{} | 1192 \LMHash{} |
1193 A {\em constructor} is a special function that is used in instance creation expr essions (\ref{instanceCreation}) to produce objects. Constructors may be generat ive (\ref{generativeConstructors}) or they may be factories (\ref{factories}). | 1193 A {\em constructor} is a special function that is used in instance creation expr essions (\ref{instanceCreation}) to produce objects. Constructors may be generat ive (\ref{generativeConstructors}) or they may be factories (\ref{factories}). |
1194 | 1194 |
1195 \LMHash{} | 1195 \LMHash{} |
1196 A {\em constructor name} always begins with the name of its immediately enclosin g class, and may optionally be followed by a dot and an identifier $id$. It is a compile-time error if $id$ is the name of a member declared in the immediately enclosing class. It is a compile-time error if the name of a constructor is no t a constructor name. | 1196 A {\em constructor name} always begins with the name of its immediately enclosin g class, and may optionally be followed by a dot and an identifier $id$. It is a compile-time error if $id$ is the name of a member declared in the immediately enclosing class. It is a compile-time error if the name of a constructor is no t a constructor name. |
1197 | 1197 |
1198 | 1198 |
1199 % In what scope do constructors go? The simple names of named constructors go i n the static scope of the class. Unnamed ones go nowhere, but we use the class n ame to refer to them; the class name could also in the static scope of the class as well to prevent weird errors, or we could ban it explicitly and avoiding dup lication. Similarly, the instance scope could contain the constructor names and class name, or we could have special rules to prevent collisions between instanc e members and constructors or the class. | 1199 % In what scope do constructors go? The simple names of named constructors go i n the static scope of the class. Unnamed ones go nowhere, but we use the class n ame to refer to them; the class name could also in the static scope of the class as well to prevent weird errors, or we could ban it explicitly and avoiding dup lication. Similarly, the instance scope could contain the constructor names and class name, or we could have special rules to prevent collisions between instanc e members and constructors or the class. |
1200 | 1200 |
1201 % The enclosing scope of a generative constructor is the instance scope of the c lass in which it is declared (but what about redirecting?) | 1201 % The enclosing scope of a generative constructor is the instance scope of the c lass in which it is declared (but what about redirecting?) |
1202 | 1202 |
1203 \LMHash{} | 1203 \LMHash{} |
1204 Iff no constructor is specified for a class $C$, it implicitly has a default con structor \code{C() : \SUPER{}() \{\}}, unless $C$ is class \code{Object}. | 1204 Iff no constructor is specified for a class $C$, it implicitly has a default con structor \code{C() : \SUPER{}() \{\}}, unless $C$ is class \code{Object}. |
1205 | 1205 |
1206 \subsubsection{Generative Constructors} | 1206 \subsubsection{Generative Constructors} |
1207 \LMLabel{generativeConstructors} | 1207 \LMLabel{generativeConstructors} |
1208 | 1208 |
1209 \LMHash{} | 1209 \LMHash{} |
1210 A {\em generative constructor} consists of a constructor name, a constructor par ameter list, and either a redirect clause or an initializer list and an optiona l body. | 1210 A {\em generative constructor} consists of a constructor name, a constructor par ameter list, and either a redirect clause or an initializer list and an optiona l body. |
1211 | 1211 |
1212 \begin{grammar} | 1212 \begin{grammar} |
1213 {\bf constructorSignature:} | 1213 {\bf constructorSignature:} |
1214 identifier (`{\escapegrammar .}' identifier)? formalParameterList | 1214 identifier (`{\escapegrammar .}' identifier)? formalParameterList |
1215 . | 1215 . |
1216 \end{grammar} | 1216 \end{grammar} |
1217 | 1217 |
1218 \LMHash{} | 1218 \LMHash{} |
1219 A {\em constructor parameter list} is a parenthesized, comma-separated list of f ormal constructor parameters. A {\em formal constructor parameter} is either a f ormal parameter (\ref{formalParameters}) or an initializing formal. An {\em init ializing formal} has the form \code{\THIS{}.id}, where \code{id} is the name of an instance variable of the immediately enclosing class. It is a compile-time e rror if \code{id} is not an instance variable of the immediately enclosing class . It is a compile-time error if an initializing formal is used by a function oth er than a non-redirecting generative constructor. | 1219 A {\em constructor parameter list} is a parenthesized, comma-separated list of f ormal constructor parameters. A {\em formal constructor parameter} is either a f ormal parameter (\ref{formalParameters}) or an initializing formal. An {\em init ializing formal} has the form \code{\THIS{}.id}, where \code{id} is the name of an instance variable of the immediately enclosing class. It is a compile-time e rror if \code{id} is not an instance variable of the immediately enclosing class . It is a compile-time error if an initializing formal is used by a function oth er than a non-redirecting generative constructor. |
1220 | 1220 |
1221 \LMHash{} | 1221 \LMHash{} |
1222 If an explicit type is attached to the initializing formal, that is its static t ype. Otherwise, the type of an initializing formal named \code{id} is $T_{id}$, where $T_{id}$ is the type of the field named \code{id} in the immediately enclo sing class. It is a static warning if the static type of \code{id} is not assign able to $T_{id}$. | 1222 If an explicit type is attached to the initializing formal, that is its static t ype. Otherwise, the type of an initializing formal named \code{id} is $T_{id}$, where $T_{id}$ is the type of the field named \code{id} in the immediately enclo sing class. It is a static warning if the static type of \code{id} is not assign able to $T_{id}$. |
1223 | 1223 |
1224 \LMHash{} | 1224 \LMHash{} |
1225 Using an initializing formal \code{\THIS{}.id} in a formal parameter list does n ot introduce a formal parameter name into the scope of the constructor. However, the initializing formal does effect the type of the constructor function exactl y as if a formal parameter named \code{id} of the same type were introduced in the same position. | 1225 Using an initializing formal \code{\THIS{}.id} in a formal parameter list does n ot introduce a formal parameter name into the scope of the constructor. However, the initializing formal does effect the type of the constructor function exactl y as if a formal parameter named \code{id} of the same type were introduced in the same position. |
1226 | 1226 |
1227 \LMHash{} | 1227 \LMHash{} |
1228 Initializing formals are executed during the execution of generative constructor s detailed below. Executing an initializing formal \code{\THIS{}.id} causes the field \code{id} of the immediately surrounding class to be assigned the value o f the corresponding actual parameter, unless $id$ is a final variable that has a lready been initialized, in which case a runtime error occurs. | 1228 Initializing formals are executed during the execution of generative constructor s detailed below. Executing an initializing formal \code{\THIS{}.id} causes the field \code{id} of the immediately surrounding class to be assigned the value o f the corresponding actual parameter, unless $id$ is a final variable that has a lready been initialized, in which case a runtime error occurs. |
1229 | 1229 |
1230 | 1230 |
1231 \commentary{ | 1231 \commentary{ |
1232 The above rule allows initializing formals to be used as optional parameters: | 1232 The above rule allows initializing formals to be used as optional parameters: |
1233 } | 1233 } |
1234 | 1234 |
1235 \begin{dartCode} | 1235 \begin{dartCode} |
1236 class A \{ | 1236 class A \{ |
1237 int x; | 1237 int x; |
1238 A([this.x]); | 1238 A([this.x]); |
1239 \} | 1239 \} |
1240 \end{dartCode} | 1240 \end{dartCode} |
1241 | 1241 |
1242 \commentary{is legal, and has the same effect as} | 1242 \commentary{is legal, and has the same effect as} |
1243 | 1243 |
1244 \begin{dartCode} | 1244 \begin{dartCode} |
1245 class A \{ | 1245 class A \{ |
1246 int x; | 1246 int x; |
1247 A([int x]): this.x = x; | 1247 A([int x]): this.x = x; |
1248 \} | 1248 \} |
1249 \end{dartCode} | 1249 \end{dartCode} |
1250 | 1250 |
1251 \LMHash{} | 1251 \LMHash{} |
1252 A {\em fresh instance} is an instance whose identity is distinct from any previ ously allocated instance of its class. A generative constructor always operates on a fresh instance of its immediately enclosing class. | 1252 A {\em fresh instance} is an instance whose identity is distinct from any previ ously allocated instance of its class. A generative constructor always operates on a fresh instance of its immediately enclosing class. |
1253 | 1253 |
1254 \commentary{ | 1254 \commentary{ |
1255 The above holds if the constructor is actually run, as it is by \NEW{}. If a con structor $c$ is referenced by \CONST{}, $c$ may not be run; instead, a canonical object may be looked up. See the section on instance creation (\ref{instanceCre ation}). | 1255 The above holds if the constructor is actually run, as it is by \NEW{}. If a con structor $c$ is referenced by \CONST{}, $c$ may not be run; instead, a canonical object may be looked up. See the section on instance creation (\ref{instanceCre ation}). |
1256 } | 1256 } |
1257 | 1257 |
1258 \LMHash{} | 1258 \LMHash{} |
1259 If a generative constructor $c$ is not a redirecting constructor and no body is provided, then $c$ implicitly has an empty body \code{\{\}}. | 1259 If a generative constructor $c$ is not a redirecting constructor and no body is provided, then $c$ implicitly has an empty body \code{\{\}}. |
1260 | 1260 |
1261 | 1261 |
1262 \paragraph{Redirecting Constructors} | 1262 \paragraph{Redirecting Constructors} |
(...skipping 14 matching lines...) Expand all Loading... | |
1277 %\Q{We now have generative constructors with no bodies as well.} | 1277 %\Q{We now have generative constructors with no bodies as well.} |
1278 | 1278 |
1279 \paragraph{Initializer Lists} | 1279 \paragraph{Initializer Lists} |
1280 \LMLabel{initializerLists} | 1280 \LMLabel{initializerLists} |
1281 | 1281 |
1282 \LMHash{} | 1282 \LMHash{} |
1283 An initializer list begins with a colon, and consists of a comma-separated list of individual {\em initializers}. There are two kinds of initializers. | 1283 An initializer list begins with a colon, and consists of a comma-separated list of individual {\em initializers}. There are two kinds of initializers. |
1284 \begin{itemize} | 1284 \begin{itemize} |
1285 \item A {\em superinitializer} identifies a {\em superconstructor} - that is, a specific constructor of the superclass. Execution of the superinitializer caus es the initializer list of the superconstructor to be executed. | 1285 \item A {\em superinitializer} identifies a {\em superconstructor} - that is, a specific constructor of the superclass. Execution of the superinitializer caus es the initializer list of the superconstructor to be executed. |
1286 | 1286 |
1287 \item An {\em instance variable initializer} assigns a value to an individual in stance variable. | 1287 \item An {\em instance variable initializer} assigns a value to an individual in stance variable. |
1288 \end{itemize} | 1288 \end{itemize} |
1289 | 1289 |
1290 \begin{grammar} | 1290 \begin{grammar} |
1291 {\bf initializers:} | 1291 {\bf initializers:} |
1292 `{\escapegrammar :}' superCallOrFieldInitializer (`,' superCallOrFieldInit ializer)* | 1292 `{\escapegrammar :}' superCallOrFieldInitializer (`,' superCallOrFieldInit ializer)* |
1293 . | 1293 . |
1294 | 1294 |
1295 | 1295 |
1296 {\bf superCallOrFieldInitializer:}\SUPER{} arguments; | 1296 {\bf superCallOrFieldInitializer:}\SUPER{} arguments; |
1297 \SUPER{} `{\escapegrammar .}' identifier arguments; | 1297 \SUPER{} `{\escapegrammar .}' identifier arguments; |
1298 fieldInitializer | 1298 fieldInitializer |
1299 . | 1299 . |
1300 | 1300 |
1301 {\bf fieldInitializer:} | 1301 {\bf fieldInitializer:} |
1302 (\THIS{} `{\escapegrammar .}')? identifier `=' conditionalExpression casca deSection* | 1302 (\THIS{} `{\escapegrammar .}')? identifier `=' conditionalExpression casca deSection* |
1303 . | 1303 . |
1304 | 1304 |
1305 \end{grammar} | 1305 \end{grammar} |
1306 | 1306 |
1307 \LMHash{} | 1307 \LMHash{} |
1308 Let $k$ be a generative constructor. Then $k$ may include at most one superini tializer in its initializer list or a compile-time error occurs. If no superinit ializer is provided, an implicit superinitializer of the form \SUPER{}() is adde d at the end of $k$'s initializer list, unless the enclosing class is class \cod e{Object}. It is a compile-time error if more than one initializer corresponding to a given instance variable appears in $k$'s initializer list. It is a compile -time error if $k$'s initializer list contains an initializer for a variable tha t is initialized by means of an initializing formal of $k$. % It is a compile-ti me error if $k$'s initializer list contains an initializer for a final variable $f$ whose declaration includes an initialization expression. | 1308 Let $k$ be a generative constructor. Then $k$ may include at most one superini tializer in its initializer list or a compile-time error occurs. If no superinit ializer is provided, an implicit superinitializer of the form \SUPER{}() is adde d at the end of $k$'s initializer list, unless the enclosing class is class \cod e{Object}. It is a compile-time error if more than one initializer corresponding to a given instance variable appears in $k$'s initializer list. It is a compile -time error if $k$'s initializer list contains an initializer for a variable tha t is initialized by means of an initializing formal of $k$. % It is a compile-ti me error if $k$'s initializer list contains an initializer for a final variable $f$ whose declaration includes an initialization expression. |
1309 | 1309 |
1310 \LMHash{} | 1310 \LMHash{} |
1311 Each final instance variable $f$ declared in the immediately enclosing class mus t have an initializer in $k$'s initializer list unless it has already been initi alized by one of the following means: | 1311 Each final instance variable $f$ declared in the immediately enclosing class mus t have an initializer in $k$'s initializer list unless it has already been initi alized by one of the following means: |
1312 \begin{itemize} | 1312 \begin{itemize} |
1313 \item Initialization at the declaration of $f$. | 1313 \item Initialization at the declaration of $f$. |
1314 \item Initialization by means of an initializing formal of $k$. | 1314 \item Initialization by means of an initializing formal of $k$. |
1315 \end{itemize} | 1315 \end{itemize} |
1316 | 1316 |
1317 or a static warning occurs. It is a compile-time error if $k$'s initializer list contains an initializer for a variable that is not an instance variable declare d in the immediately surrounding class. | 1317 or a static warning occurs. It is a compile-time error if $k$'s initializer list contains an initializer for a variable that is not an instance variable declare d in the immediately surrounding class. |
1318 | 1318 |
1319 | 1319 |
1320 \commentary{The initializer list may of course contain an initializer for any instance variable declared by the immediately surrounding class, even if it is n ot final. | 1320 \commentary{The initializer list may of course contain an initializer for any instance variable declared by the immediately surrounding class, even if it is n ot final. |
1321 } | 1321 } |
1322 | 1322 |
1323 \LMHash{} | 1323 \LMHash{} |
1324 It is a compile-time error if a generative constructor of class \code{Object} includes a superinitializer. | 1324 It is a compile-time error if a generative constructor of class \code{Object} includes a superinitializer. |
1325 | 1325 |
1326 \LMHash{} | 1326 \LMHash{} |
1327 Execution of a generative constructor $k$ is always done with respect to a set o f bindings for its formal parameters and with \THIS{} bound to a fresh instance $i$ and the type parameters of the immediately enclosing class bound to a set o f actual type arguments $V_1, \ldots , V_m$. | 1327 Execution of a generative constructor $k$ is always done with respect to a set o f bindings for its formal parameters and with \THIS{} bound to a fresh instance $i$ and the type parameters of the immediately enclosing class bound to a set o f actual type arguments $V_1, \ldots , V_m$. |
1328 | 1328 |
1329 \commentary{These bindings are usually determined by the instance creation expre ssion that invoked the constructor (directly or indirectly). However, they may a lso be determined by a reflective call,. | 1329 \commentary{These bindings are usually determined by the instance creation expre ssion that invoked the constructor (directly or indirectly). However, they may a lso be determined by a reflective call,. |
1330 } | 1330 } |
1331 | 1331 |
1332 \LMHash{} | 1332 \LMHash{} |
1333 If $k$ is redirecting then its redirect clause has the form | 1333 If $k$ is redirecting then its redirect clause has the form |
1334 | 1334 |
1335 \THIS{}$.g(a_1, \ldots , a_n, x_{n+1}: a_{n+1}, \ldots , x_{n+k}: a_{n+k})$ | 1335 \THIS{}$.g(a_1, \ldots , a_n, x_{n+1}: a_{n+1}, \ldots , x_{n+k}: a_{n+k})$ |
1336 | 1336 |
1337 where $g$ identifies another generative constructor of the immediately surround ing class. Then execution of $k$ proceeds by evaluating the argument list $(a_1, \ldots , a_n, x_{n+1}: a_{n+1}, \ldots , x_{n+k}: a_{n+k})$, and then executing $g$ with respect to the bindings resulting from the evaluation of $(a_1, \ldots , a_n, x_{n+1}: a_{n+1}, \ldots , x_{n+k}: a_{n+k})$ and with \THIS{} bound to $i$ and the type parameters of the immediately enclosing class bound to $V_1, \ ldots , V_m$. | 1337 where $g$ identifies another generative constructor of the immediately surround ing class. Then execution of $k$ proceeds by evaluating the argument list $(a_1, \ldots , a_n, x_{n+1}: a_{n+1}, \ldots , x_{n+k}: a_{n+k})$, and then executing $g$ with respect to the bindings resulting from the evaluation of $(a_1, \ldots , a_n, x_{n+1}: a_{n+1}, \ldots , x_{n+k}: a_{n+k})$ and with \THIS{} bound to $i$ and the type parameters of the immediately enclosing class bound to $V_1, \ ldots , V_m$. |
1338 | 1338 |
1339 \LMHash{} | 1339 \LMHash{} |
1340 Otherwise, execution proceeds as follows: | 1340 Otherwise, execution proceeds as follows: |
1341 | 1341 |
1342 \LMHash{} | 1342 \LMHash{} |
1343 %First, a fresh instance (\ref{generativeConstructors}) $i$ of the immediately e nclosing class is allocated. Next, the instance variable declarations of the im mediately enclosing class are visited in the order they appear in the program te xt. For each such declaration $d$, if $d$ has the form \code{$finalConstVarOrTy pe$ $v$ = $e$; } then the instance variable $v$ of $i$ is bound to the value of $e$ (which is necessarily a compile-time constant). | 1343 %First, a fresh instance (\ref{generativeConstructors}) $i$ of the immediately e nclosing class is allocated. Next, the instance variable declarations of the im mediately enclosing class are visited in the order they appear in the program te xt. For each such declaration $d$, if $d$ has the form \code{$finalConstVarOrTy pe$ $v$ = $e$; } then the instance variable $v$ of $i$ is bound to the value of $e$ (which is necessarily a compile-time constant). |
1344 %Next, a | 1344 %Next, a |
1345 Any initializing formals declared in $k$'s parameter list are executed in the or der they appear in the program text. | 1345 Any initializing formals declared in $k$'s parameter list are executed in the or der they appear in the program text. |
1346 % In fact, this order is unobservable; this could be done any time prior to runn ing the body, since | 1346 % In fact, this order is unobservable; this could be done any time prior to runn ing the body, since |
1347 % these only effect \THIS{}. | 1347 % these only effect \THIS{}. |
1348 Then, $k$'s initializers are executed in the order they appear in the program. | 1348 Then, $k$'s initializers are executed in the order they appear in the program. |
1349 | 1349 |
1350 \rationale {We could observe the order by side effecting external routines call ed. So we need to specify the order.} | 1350 \rationale {We could observe the order by side effecting external routines call ed. So we need to specify the order.} |
1351 | 1351 |
1352 \LMHash{} | 1352 \LMHash{} |
1353 After all the initializers have completed, the body of $k$ is executed in a sc ope where \THIS{} is bound to $i$. Execution of the body begins with execution o f the body of the superconstructor with \THIS{} bound to $i$, the type paramete rs of the immediately enclosing class bound to a set of actual type arguments $V _1, \ldots , V_m$ and the formal parameters bindings determined by the argument list of the superinitializer of $k$. | 1353 After all the initializers have completed, the body of $k$ is executed in a sc ope where \THIS{} is bound to $i$. Execution of the body begins with execution o f the body of the superconstructor with \THIS{} bound to $i$, the type paramete rs of the immediately enclosing class bound to a set of actual type arguments $V _1, \ldots , V_m$ and the formal parameters bindings determined by the argument list of the superinitializer of $k$. |
1354 | 1354 |
1355 \rationale{ | 1355 \rationale{ |
1356 This process ensures that no uninitialized final field is ever seen by code. Not e that \THIS{} is not in scope on the right hand side of an initializer (see \re f{this}) so no instance method can execute during initialization: an instance me thod cannot be directly invoked, nor can \THIS{} be passed into any other code being invoked in the initializer. | 1356 This process ensures that no uninitialized final field is ever seen by code. Not e that \THIS{} is not in scope on the right hand side of an initializer (see \re f{this}) so no instance method can execute during initialization: an instance me thod cannot be directly invoked, nor can \THIS{} be passed into any other code being invoked in the initializer. |
1357 } | 1357 } |
1358 | 1358 |
1359 \LMHash{} | 1359 \LMHash{} |
1360 Execution of an initializer of the form \code{\THIS{}.$v$ = $e$} proceeds as fol lows: | 1360 Execution of an initializer of the form \code{\THIS{}.$v$ = $e$} proceeds as fol lows: |
1361 | 1361 |
1362 \LMHash{} | 1362 \LMHash{} |
1363 First, the expression $e$ is evaluated to an object $o$. Then, the instance vari able $v$ of the object denoted by \THIS{} is bound to $o$, unless $v$ is a final variable that has already been initialized, in which case a runtime error occur s. In checked mode, it is a dynamic type error if $o$ is not \NULL{} and the int erface of the class of $o$ is not a subtype of the actual type of the field $v$. | 1363 First, the expression $e$ is evaluated to an object $o$. Then, the instance vari able $v$ of the object denoted by \THIS{} is bound to $o$, unless $v$ is a final variable that has already been initialized, in which case a runtime error occur s. In checked mode, it is a dynamic type error if $o$ is not \NULL{} and the int erface of the class of $o$ is not a subtype of the actual type of the field $v$. |
1364 | 1364 |
1365 \LMHash{} | 1365 \LMHash{} |
1366 An initializer of the form \code{$v$ = $e$} is equivalent to an initializer of t he form \code{\THIS{}.$v$ = $e$}. | 1366 An initializer of the form \code{$v$ = $e$} is equivalent to an initializer of t he form \code{\THIS{}.$v$ = $e$}. |
1367 | 1367 |
1368 \LMHash{} | 1368 \LMHash{} |
1369 Execution of a superinitializer of the form | 1369 Execution of a superinitializer of the form |
1370 | 1370 |
1371 \SUPER{}$(a_1, \ldots, a_n, x_{n+1}: a_{n+1}, \ldots, x_{n+k}: a_{n+k})$ | 1371 \SUPER{}$(a_1, \ldots, a_n, x_{n+1}: a_{n+1}, \ldots, x_{n+k}: a_{n+k})$ |
1372 | 1372 |
1373 (respectively \SUPER{}$.id(a_1, \ldots, a_n, x_{n+1}: a_{n+1}, \ldots, x_{n+k}: a_{n+k})$ | 1373 (respectively \SUPER{}$.id(a_1, \ldots, a_n, x_{n+1}: a_{n+1}, \ldots, x_{n+k}: a_{n+k})$ |
1374 | 1374 |
1375 proceeds as follows: | 1375 proceeds as follows: |
1376 | 1376 |
1377 \LMHash{} | 1377 \LMHash{} |
1378 First, the argument list $(a_1, \ldots, a_n, x_{n+1}: a_{n+1}, \ldots, x_{n+k}: a_{n+k})$ is evaluated. | 1378 First, the argument list $(a_1, \ldots, a_n, x_{n+1}: a_{n+1}, \ldots, x_{n+k}: a_{n+k})$ is evaluated. |
1379 | 1379 |
1380 \LMHash{} | 1380 \LMHash{} |
1381 Let $C$ be the class in which the superinitializer appears and let $S$ be the su perclass of $C$. If $S$ is generic (\ref{generics}), let $U_1, , \ldots, U_m$ b e the actual type arguments passed to $S$ in the superclass clause of $C$. | 1381 Let $C$ be the class in which the superinitializer appears and let $S$ be the su perclass of $C$. If $S$ is generic (\ref{generics}), let $U_1, , \ldots, U_m$ b e the actual type arguments passed to $S$ in the superclass clause of $C$. |
1382 | 1382 |
1383 \LMHash{} | 1383 \LMHash{} |
1384 Then, the initializer list of the constructor $S$ (respectively $S.id$) is execu ted with respect to the bindings that resulted from the evaluation of the argume nt list, with \THIS{} bound to the current binding of \THIS{}, and the type pa rameters (if any) of class $S$ bound to the current bindings of $U_1, , \ldots, U_m$. | 1384 Then, the initializer list of the constructor $S$ (respectively $S.id$) is execu ted with respect to the bindings that resulted from the evaluation of the argume nt list, with \THIS{} bound to the current binding of \THIS{}, and the type pa rameters (if any) of class $S$ bound to the current bindings of $U_1, , \ldots, U_m$. |
1385 | 1385 |
1386 \LMHash{} | 1386 \LMHash{} |
1387 It is a compile-time error if class $S$ does not declare a generative constructo r named $S$ (respectively $S.id$). | 1387 It is a compile-time error if class $S$ does not declare a generative constructo r named $S$ (respectively $S.id$). |
1388 | 1388 |
1389 \subsubsection{Factories} | 1389 \subsubsection{Factories} |
1390 \LMLabel{factories} | 1390 \LMLabel{factories} |
1391 | 1391 |
1392 \LMHash{} | 1392 \LMHash{} |
1393 A {\em factory} is a constructor prefaced by the built-in identifier (\ref{iden tifierReference}) \FACTORY{}. | 1393 A {\em factory} is a constructor prefaced by the built-in identifier (\ref{iden tifierReference}) \FACTORY{}. |
1394 | 1394 |
1395 \begin{grammar} | 1395 \begin{grammar} |
1396 {\bf factoryConstructorSignature:} | 1396 {\bf factoryConstructorSignature:} |
1397 \FACTORY{} identifier (`{\escapegrammar .}' identifier)? formalParameter List | 1397 \FACTORY{} identifier (`{\escapegrammar .}' identifier)? formalParameter List |
1398 . | 1398 . |
1399 \end{grammar} | 1399 \end{grammar} |
1400 | 1400 |
1401 | 1401 |
1402 %The enclosing scope of a factory constructor is the static scope \ref{} of the class in which it is declared. | 1402 %The enclosing scope of a factory constructor is the static scope \ref{} of the class in which it is declared. |
1403 | 1403 |
1404 \LMHash{} | 1404 \LMHash{} |
1405 The {\em return type} of a factory whose signature is of the form \FACTORY{} $M$ or the form \FACTORY{} $M.id$ is $M$ if $M$ is not a generic type; otherwise th e return type is $M <T_1, \ldots, T_n>$ where $T_1, \ldots, T_n$ are the type p arameters of the enclosing class | 1405 The {\em return type} of a factory whose signature is of the form \FACTORY{} $M$ or the form \FACTORY{} $M.id$ is $M$ if $M$ is not a generic type; otherwise th e return type is $M <T_1, \ldots, T_n>$ where $T_1, \ldots, T_n$ are the type p arameters of the enclosing class |
1406 | 1406 |
1407 \LMHash{} | 1407 \LMHash{} |
1408 It is a compile-time error if $M$ is not the name of the immediately enclosing c lass. | 1408 It is a compile-time error if $M$ is not the name of the immediately enclosing c lass. |
1409 | 1409 |
1410 \LMHash{} | 1410 \LMHash{} |
1411 In checked mode, it is a dynamic type error if a factory returns a non-null obje ct whose type is not a subtype of its actual (\ref{actualTypeOfADeclaration}) re turn type. | 1411 In checked mode, it is a dynamic type error if a factory returns a non-null obje ct whose type is not a subtype of its actual (\ref{actualTypeOfADeclaration}) re turn type. |
1412 | 1412 |
1413 \rationale{It seems useless to allow a factory to return null. But it is more un iform to allow it, as the rules currently do.} | 1413 \rationale{It seems useless to allow a factory to return null. But it is more un iform to allow it, as the rules currently do.} |
1414 | 1414 |
1415 \rationale{Factories address classic weaknesses associated with constructors in other languages. | 1415 \rationale{Factories address classic weaknesses associated with constructors in other languages. |
1416 Factories can produce instances that are not freshly allocated: they can come fr om a cache. Likewise, factories can return instances of different classes. | 1416 Factories can produce instances that are not freshly allocated: they can come fr om a cache. Likewise, factories can return instances of different classes. |
1417 | 1417 |
1418 } | 1418 } |
1419 | 1419 |
1420 \paragraph{Redirecting Factory Constructors} | 1420 \paragraph{Redirecting Factory Constructors} |
1421 \LMLabel{redirectingFactoryConstructors} | 1421 \LMLabel{redirectingFactoryConstructors} |
1422 | 1422 |
1423 \LMHash{} | 1423 \LMHash{} |
1424 A {\em redirecting factory constructor} specifies a call to a constructor of ano ther class that is to be used whenever the redirecting constructor is called. | 1424 A {\em redirecting factory constructor} specifies a call to a constructor of ano ther class that is to be used whenever the redirecting constructor is called. |
1425 | 1425 |
1426 \begin{grammar} | 1426 \begin{grammar} |
1427 {\bf redirectingFactoryConstructorSignature:} | 1427 {\bf redirectingFactoryConstructorSignature:} |
1428 \CONST{}? \FACTORY{} identifier (`{\escapegrammar .}' identifier)? formalP arameterList `=' type (`{\escapegrammar .}' identifier)? | 1428 \CONST{}? \FACTORY{} identifier (`{\escapegrammar .}' identifier)? formalP arameterList `=' type (`{\escapegrammar .}' identifier)? |
1429 . | 1429 . |
1430 \end{grammar} | 1430 \end{grammar} |
1431 | 1431 |
1432 \LMHash{} | 1432 \LMHash{} |
1433 Calling a redirecting factory constructor $k$ causes the constructor $k^\prime$ denoted by $type$ (respectively, $type.identifier$) to be called with the actual arguments passed to $k$, and returns the result of $k^\prime$ as the result of $k$. The resulting constructor call is governed by the same rules as an instanc e creation expression using \NEW{} (\ref{instanceCreation}). | 1433 Calling a redirecting factory constructor $k$ causes the constructor $k^\prime$ denoted by $type$ (respectively, $type.identifier$) to be called with the actual arguments passed to $k$, and returns the result of $k^\prime$ as the result of $k$. The resulting constructor call is governed by the same rules as an instanc e creation expression using \NEW{} (\ref{instanceCreation}). |
1434 | 1434 |
1435 \commentary{ | 1435 \commentary{ |
1436 It follows that if $type$ or $type.id$ are not defined, or do not refer to a cla ss or constructor, a dynamic error occurs, as with any other undefined construct or call. The same holds if $k$ is called with fewer required parameters or more positional parameters than $k^\prime$ expects, or if $k$ is called with a named parameter that is not declared by $k^\prime$. | 1436 It follows that if $type$ or $type.id$ are not defined, or do not refer to a cla ss or constructor, a dynamic error occurs, as with any other undefined construct or call. The same holds if $k$ is called with fewer required parameters or more positional parameters than $k^\prime$ expects, or if $k$ is called with a named parameter that is not declared by $k^\prime$. |
1437 } | 1437 } |
1438 | 1438 |
1439 \LMHash{} | 1439 \LMHash{} |
1440 It is a compile-time error if $k$ explicitly specifies a default value for an op tional parameter.\commentary{ | 1440 It is a compile-time error if $k$ explicitly specifies a default value for an op tional parameter.\commentary{ |
1441 Default values specified in $k$ would be ignored, since it is the {\em actual} p arameters that are passed to $k^\prime$. Hence, default values are disallowed. | 1441 Default values specified in $k$ would be ignored, since it is the {\em actual} p arameters that are passed to $k^\prime$. Hence, default values are disallowed. |
1442 } | 1442 } |
1443 | 1443 |
1444 \LMHash{} | 1444 \LMHash{} |
1445 It is a run-time error if a redirecting factory constructor redirects to itself, either directly or indirectly via a sequence of redirections. %does not redirec t to a non-redirecting factory constructor or to a generative constructor in a f inite number of steps. | 1445 It is a run-time error if a redirecting factory constructor redirects to itself, either directly or indirectly via a sequence of redirections. %does not redirec t to a non-redirecting factory constructor or to a generative constructor in a f inite number of steps. |
1446 | 1446 |
1447 % Make this a runtime error so deferred loading works | 1447 % Make this a runtime error so deferred loading works |
1448 | 1448 |
1449 \rationale{ | 1449 \rationale{ |
1450 If a redirecting factory $F_1$ redirects to another redirecting factory $F_2$ an d $F_2$ then redirects to $F_1$, then both $F_1$ and $F_2$ are ill-defined. Such cycles are therefore illegal. | 1450 If a redirecting factory $F_1$ redirects to another redirecting factory $F_2$ an d $F_2$ then redirects to $F_1$, then both $F_1$ and $F_2$ are ill-defined. Such cycles are therefore illegal. |
1451 } | 1451 } |
1452 | 1452 |
1453 | 1453 |
1454 \LMHash{} | 1454 \LMHash{} |
1455 It is a static warning if $type$ does not denote a class accessible in the curre nt scope; if $type$ does denote such a class $C$ it is a static warning if the r eferenced constructor (be it $type$ or $type.id$) is not a constructor of $C$. | 1455 It is a static warning if $type$ does not denote a class accessible in the curre nt scope; if $type$ does denote such a class $C$ it is a static warning if the r eferenced constructor (be it $type$ or $type.id$) is not a constructor of $C$. |
1456 | 1456 |
1457 \commentary{ | 1457 \commentary{ |
1458 Note that it is not possible to modify the arguments being passed to $k'$. | 1458 Note that it is not possible to modify the arguments being passed to $k'$. |
1459 } | 1459 } |
1460 % but we have the same issue with other redirecting constructors, no?) | 1460 % but we have the same issue with other redirecting constructors, no?) |
1461 \rationale{ | 1461 \rationale{ |
1462 At first glance, one might think that ordinary factory constructors could simply create instances of other classes and return them, and that redirecting factori es are unnecessary. However, redirecting factories have several advantages: | 1462 At first glance, one might think that ordinary factory constructors could simply create instances of other classes and return them, and that redirecting factori es are unnecessary. However, redirecting factories have several advantages: |
1463 \begin{itemize} | 1463 \begin{itemize} |
1464 \item An abstract class may provide a constant constructor that utilizes the con stant constructor of another class. | 1464 \item An abstract class may provide a constant constructor that utilizes the con stant constructor of another class. |
1465 \item A redirecting factory constructors avoids the need for forwarders to repea t the default values for formal parameters in their signatures. | 1465 \item A redirecting factory constructors avoids the need for forwarders to repea t the default values for formal parameters in their signatures. |
1466 %\item A generic factory class that aggregates factory constructors for types it does not implement can still have its type arguments passed correctly. | 1466 %\item A generic factory class that aggregates factory constructors for types it does not implement can still have its type arguments passed correctly. |
1467 \end{itemize} | 1467 \end{itemize} |
1468 | 1468 |
1469 %An example of the latter point: | 1469 %An example of the latter point: |
1470 %} | 1470 %} |
1471 | 1471 |
1472 | 1472 |
1473 %\begin{dartCode} | 1473 %\begin{dartCode} |
1474 %\CLASS{} W$<$T$>$ \IMPLEMENTS{} A$<$T$>$ { W(w) {...} ...} | 1474 %\CLASS{} W$<$T$>$ \IMPLEMENTS{} A$<$T$>$ { W(w) {...} ...} |
1475 %\CLASS{} X$<$T$>$ \IMPLEMENTS{} A$<$T$>$ { X(x) {...} ...} | 1475 %\CLASS{} X$<$T$>$ \IMPLEMENTS{} A$<$T$>$ { X(x) {...} ...} |
1476 %\CLASS{} Y$<$T$>$ \IMPLEMENTS{} A$<$T$>$ { Y(y) {...} ...} | 1476 %\CLASS{} Y$<$T$>$ \IMPLEMENTS{} A$<$T$>$ { Y(y) {...} ...} |
1477 %\CLASS{} Z$<$T$>$ \IMPLEMENTS{} A$<$T$>$ { Z(z) {...} ...} | 1477 %\CLASS{} Z$<$T$>$ \IMPLEMENTS{} A$<$T$>$ { Z(z) {...} ...} |
1478 | 1478 |
1479 | 1479 |
1480 %\CLASS{} F$<$T$>$ { // note that F does not implement A | 1480 %\CLASS{} F$<$T$>$ { // note that F does not implement A |
1481 % \STATIC{} F$<$T$>$ idw(w) $=>$ \NEW{} W$<$T$>$(w); // illegal - T not in sco pe in idw | 1481 % \STATIC{} F$<$T$>$ idw(w) $=>$ \NEW{} W$<$T$>$(w); // illegal - T not in sco pe in idw |
1482 % \FACTORY{} F.idx(x) $=>$ \NEW{} X$<$T$>$(x); | 1482 % \FACTORY{} F.idx(x) $=>$ \NEW{} X$<$T$>$(x); |
1483 % \FACTORY{} F.idy(y) $=>$ \NEW{} Y$<$T$>$(y); | 1483 % \FACTORY{} F.idy(y) $=>$ \NEW{} Y$<$T$>$(y); |
1484 % \STATIC{} F idz(z) $=>$ \NEW{} Z(z); // does not capture the type argument | 1484 % \STATIC{} F idz(z) $=>$ \NEW{} Z(z); // does not capture the type argument |
1485 %} | 1485 %} |
1486 | 1486 |
1487 %\CLASS{} A$<$T$>${ | 1487 %\CLASS{} A$<$T$>${ |
1488 % \FACTORY{} A.idw(w) $=>$ F$<$T$>$.idw(w); | 1488 % \FACTORY{} A.idw(w) $=>$ F$<$T$>$.idw(w); |
1489 %// illegal - cannot pass type parameter to static method | 1489 %// illegal - cannot pass type parameter to static method |
1490 % \FACTORY{} A.idx(x) $=> \NEW{} $F$<$T$>$.idx(x); // works, but allocates a gr atuitous instance of F | 1490 % \FACTORY{} A.idx(x) $=> \NEW{} $F$<$T$>$.idx(x); // works, but allocates a gr atuitous instance of F |
1491 % \FACTORY{} A.idy(y) = Y$<$T$>$; // works | 1491 % \FACTORY{} A.idy(y) = Y$<$T$>$; // works |
1492 % \FACTORY{} A.idz(z) $=>$ F.idz(z); // wrong - returns Z$<$Dynamic$>$; no way to pass type argument | 1492 % \FACTORY{} A.idz(z) $=>$ F.idz(z); // wrong - returns Z$<$Dynamic$>$; no way to pass type argument |
1493 } | 1493 } |
1494 %\end{dartCode} | 1494 %\end{dartCode} |
1495 | 1495 |
1496 \LMHash{} | 1496 \LMHash{} |
1497 It is a compile-time error if $k$ is prefixed with the \CONST{} modifier but $k^ \prime$ is not a constant constructor (\ref{constantConstructors}). | 1497 It is a compile-time error if $k$ is prefixed with the \CONST{} modifier but $k^ \prime$ is not a constant constructor (\ref{constantConstructors}). |
1498 | 1498 |
1499 \LMHash{} | 1499 \LMHash{} |
1500 It is a static warning if the function type of $k^\prime$ is not a subtype of th e type of $k$. | 1500 It is a static warning if the function type of $k^\prime$ is not a subtype of th e type of $k$. |
1501 | 1501 |
1502 \commentary{ | 1502 \commentary{ |
1503 This implies that the resulting object conforms to the interface of the immedia tely enclosing class of $k$. | 1503 This implies that the resulting object conforms to the interface of the immedia tely enclosing class of $k$. |
1504 } | 1504 } |
1505 | 1505 |
1506 \LMHash{} | 1506 \LMHash{} |
1507 It is a static type warning if any of the type arguments to $k^\prime$ are not s ubtypes of the bounds of the corresponding formal type parameters of $type$. | 1507 It is a static type warning if any of the type arguments to $k^\prime$ are not s ubtypes of the bounds of the corresponding formal type parameters of $type$. |
1508 | 1508 |
1509 | 1509 |
1510 \subsubsection{Constant Constructors} | 1510 \subsubsection{Constant Constructors} |
1511 \LMLabel{constantConstructors} | 1511 \LMLabel{constantConstructors} |
1512 | 1512 |
1513 \LMHash{} | 1513 \LMHash{} |
1514 A {\em constant constructor} may be used to create compile-time constant (\ref{ constants}) objects. A constant constructor is prefixed by the reserved word \CO NST{}. | 1514 A {\em constant constructor} may be used to create compile-time constant (\ref{ constants}) objects. A constant constructor is prefixed by the reserved word \CO NST{}. |
1515 | 1515 |
1516 \begin{grammar} | 1516 \begin{grammar} |
1517 {\bf constantConstructorSignature:} | 1517 {\bf constantConstructorSignature:} |
1518 \CONST{} qualified formalParameterList | 1518 \CONST{} qualified formalParameterList |
1519 . | 1519 . |
1520 \end{grammar} | 1520 \end{grammar} |
1521 | 1521 |
1522 | 1522 |
1523 %\commentary{Spell out subtleties: a constant constructor call within the initia lizer of a constant constructor is treated as a ordinary constructor call (a ne w), because the arguments cannot be assumed constant anymore. In practice, this means two versions are compiled and analyzed. One for new and one for const.} | 1523 %\commentary{Spell out subtleties: a constant constructor call within the initia lizer of a constant constructor is treated as a ordinary constructor call (a ne w), because the arguments cannot be assumed constant anymore. In practice, this means two versions are compiled and analyzed. One for new and one for const.} |
1524 | 1524 |
1525 % \Q{How to specify?} | 1525 % \Q{How to specify?} |
1526 | 1526 |
1527 \commentary{All the work of a constant constructor must be handled via its initi alizers.} | 1527 \commentary{All the work of a constant constructor must be handled via its initi alizers.} |
1528 | 1528 |
1529 \LMHash{} | 1529 \LMHash{} |
1530 It is a compile-time error if a constant constructor is declared by a class that has a non-final instance variable. | 1530 It is a compile-time error if a constant constructor is declared by a class that has a non-final instance variable. |
1531 | 1531 |
1532 \commentary{ | 1532 \commentary{ |
1533 The above refers to both locally declared and inherited instance variables. | 1533 The above refers to both locally declared and inherited instance variables. |
1534 } | 1534 } |
1535 | 1535 |
1536 \LMHash{} | 1536 \LMHash{} |
1537 It is a compile-time error if a constant constructor is declared by a class $C$ if any instance variable declared in $C$ is initialized with an expression that is not a constant expression. | 1537 It is a compile-time error if a constant constructor is declared by a class $C$ if any instance variable declared in $C$ is initialized with an expression that is not a constant expression. |
1538 | 1538 |
1539 \commentary { | 1539 \commentary { |
1540 A superclass of $C$ cannot declare such an initializer either, because it must n ecessarily declare constant constructor as well (unless it is \code{Object}, whi ch declares no instance variables). | 1540 A superclass of $C$ cannot declare such an initializer either, because it must n ecessarily declare constant constructor as well (unless it is \code{Object}, whi ch declares no instance variables). |
1541 } | 1541 } |
1542 | 1542 |
1543 \LMHash{} | 1543 \LMHash{} |
1544 The superinitializer that appears, explicitly or implicitly, in the initializer list of a constant constructor must specify a constant constructor of the superc lass of the immediately enclosing class or a compile-time error occurs. | 1544 The superinitializer that appears, explicitly or implicitly, in the initializer list of a constant constructor must specify a constant constructor of the superc lass of the immediately enclosing class or a compile-time error occurs. |
1545 | 1545 |
1546 \LMHash{} | 1546 \LMHash{} |
1547 Any expression that appears within the initializer list of a constant constructo r must be a potentially constant expression, or a compile-time error occurs. | 1547 Any expression that appears within the initializer list of a constant constructo r must be a potentially constant expression, or a compile-time error occurs. |
1548 | 1548 |
1549 \LMHash{} | 1549 \LMHash{} |
1550 A {\em potentially constant expression} is an expression $e$ that would be a val id constant expression if all formal parameters of $e$'s immediately enclosing c onstant constructor were treated as compile-time constants that were guaranteed to evaluate to an integer, boolean or string value as required by their immediat ely enclosing superexpression, <em>and</em> where $e$ is also a valid expression if all the formal parameters are treated as non-constant variables. | 1550 A {\em potentially constant expression} is an expression $e$ that would be a val id constant expression if all formal parameters of $e$'s immediately enclosing c onstant constructor were treated as compile-time constants that were guaranteed to evaluate to an integer, boolean or string value as required by their immediat ely enclosing superexpression, <em>and</em> where $e$ is also a valid expression if all the formal parameters are treated as non-constant variables. |
1551 | 1551 |
1552 \commentary{ | 1552 \commentary{ |
1553 Note that a parameter that is not used in a superexpression that is restricted t o certain types can be a constant of any type. For example} | 1553 Note that a parameter that is not used in a superexpression that is restricted t o certain types can be a constant of any type. For example} |
1554 | 1554 |
1555 \begin{dartCode} | 1555 \begin{dartCode} |
1556 \CLASS{} A \{ | 1556 \CLASS{} A \{ |
1557 \FINAL{} m; | 1557 \FINAL{} m; |
1558 \CONST{} A(this.m); | 1558 \CONST{} A(this.m); |
1559 \} | 1559 \} |
1560 \end{dartCode} | 1560 \end{dartCode} |
1561 | 1561 |
1562 \commentary{can be instantiated via \cd{\CONST{} A(\CONST []);}} | 1562 \commentary{can be instantiated via \cd{\CONST{} A(\CONST []);}} |
1563 | 1563 |
1564 | 1564 |
1565 | 1565 |
1566 \commentary{ | 1566 \commentary{ |
1567 The difference between a potentially constant expression and a compile-time cons tant expression (\ref{const}) deserves some explanation. | 1567 The difference between a potentially constant expression and a compile-time cons tant expression (\ref{const}) deserves some explanation. |
1568 | 1568 |
1569 The key issue is whether one treats the formal parameters of a constructor as co mpile-time constants. | 1569 The key issue is whether one treats the formal parameters of a constructor as co mpile-time constants. |
1570 | 1570 |
1571 If a constant constructor is invoked from a constant object expression, the actu al arguments will be required to be compile-time constants. Therefore, if we wer e assured that constant constructors were always invoked from constant object ex pressions, we could assume that the formal parameters of a constructor were comp ile-time constants. | 1571 If a constant constructor is invoked from a constant object expression, the actu al arguments will be required to be compile-time constants. Therefore, if we wer e assured that constant constructors were always invoked from constant object ex pressions, we could assume that the formal parameters of a constructor were comp ile-time constants. |
1572 | 1572 |
1573 However, constant constructors can also be invoked from ordinary instance creati on expressions (\ref{new}), and so the above assumption is not generally valid. | 1573 However, constant constructors can also be invoked from ordinary instance creati on expressions (\ref{new}), and so the above assumption is not generally valid. |
1574 | 1574 |
1575 Nevertheless, the use of the formal parameters of a constant constructor within the constructor is of considerable utility. The concept of potentially constant expressions is introduced to facilitate limited use of such formal parameters. S pecifically, we allow the usage of the formal parameters of a constant construct or for expressions that involve built-in operators, but not for constant objects , lists and maps. This allows for constructors such as: | 1575 Nevertheless, the use of the formal parameters of a constant constructor within the constructor is of considerable utility. The concept of potentially constant expressions is introduced to facilitate limited use of such formal parameters. S pecifically, we allow the usage of the formal parameters of a constant construct or for expressions that involve built-in operators, but not for constant objects , lists and maps. This allows for constructors such as: |
1576 } | 1576 } |
1577 | 1577 |
1578 \begin{dartCode} | 1578 \begin{dartCode} |
1579 \CLASS{} C \{ | 1579 \CLASS{} C \{ |
1580 \FINAL{} x; \FINAL{} y; \FINAL{} z; | 1580 \FINAL{} x; \FINAL{} y; \FINAL{} z; |
1581 \CONST{} C(p, q): x = q, y = p + 100, z = p + q; | 1581 \CONST{} C(p, q): x = q, y = p + 100, z = p + q; |
1582 % what about | 1582 % what about |
1583 % \CONST{} C(p, q): x = q, y = p + 100, z = p + 'foo'; | 1583 % \CONST{} C(p, q): x = q, y = p + 100, z = p + 'foo'; |
1584 % perhaps moot. Current spec says that would be ok; type checker can worry, as can execution, which is at compile time anyway | 1584 % perhaps moot. Current spec says that would be ok; type checker can worry, as can execution, which is at compile time anyway |
1585 \} | 1585 \} |
1586 \end{dartCode} | 1586 \end{dartCode} |
1587 | 1587 |
1588 \commentary{ | 1588 \commentary{ |
1589 The assignment to \code{x} is allowed under the assumption that \code{q} is a co mpile-time constant (even though \code{q} is not, in general a compile-time cons tant). The assignment to \code{y} is similar, but raises additional questions. In this case, the superexpression of \code{p} is \code{p + 100}, and it requires that \code{p} be a numeric compile-time constant for the entire expression to b e considered constant. The wording of the specification allows us to assume tha t \code{p} evaluates to an integer. A similar argument holds for \code{p} and \c ode{q} in the assignment to \code{z}. | 1589 The assignment to \code{x} is allowed under the assumption that \code{q} is a co mpile-time constant (even though \code{q} is not, in general a compile-time cons tant). The assignment to \code{y} is similar, but raises additional questions. In this case, the superexpression of \code{p} is \code{p + 100}, and it requires that \code{p} be a numeric compile-time constant for the entire expression to b e considered constant. The wording of the specification allows us to assume tha t \code{p} evaluates to an integer. A similar argument holds for \code{p} and \c ode{q} in the assignment to \code{z}. |
1590 | 1590 |
1591 However, the following constructors are disallowed: | 1591 However, the following constructors are disallowed: |
1592 } | 1592 } |
(...skipping 27 matching lines...) Expand all Loading... | |
1620 | 1620 |
1621 \LMHash{} | 1621 \LMHash{} |
1622 {\em Static methods} are functions, other than getters or setters, whose declara tions are immediately contained within a class declaration and that are declared \STATIC{}. The static methods of a class $C$ are those static methods declared by $C$. | 1622 {\em Static methods} are functions, other than getters or setters, whose declara tions are immediately contained within a class declaration and that are declared \STATIC{}. The static methods of a class $C$ are those static methods declared by $C$. |
1623 | 1623 |
1624 \LMHash{} | 1624 \LMHash{} |
1625 The effect of a static method declaration in class $C$ is to add an instance met hod with the same name and signature to the \code{Type} object for class $C$ tha t forwards (\ref{functionDeclarations}) to the static method. | 1625 The effect of a static method declaration in class $C$ is to add an instance met hod with the same name and signature to the \code{Type} object for class $C$ tha t forwards (\ref{functionDeclarations}) to the static method. |
1626 | 1626 |
1627 \rationale{ | 1627 \rationale{ |
1628 Inheritance of static methods has little utility in Dart. Static methods cannot be overridden. Any required static function can be obtained from its declaring l ibrary, and there is no need to bring it into scope via inheritance. Experience shows that developers are confused by the idea of inherited methods that are not instance methods. | 1628 Inheritance of static methods has little utility in Dart. Static methods cannot be overridden. Any required static function can be obtained from its declaring l ibrary, and there is no need to bring it into scope via inheritance. Experience shows that developers are confused by the idea of inherited methods that are not instance methods. |
1629 | 1629 |
1630 Of course, the entire notion of static methods is debatable, but it is retained here because so many programmers are familiar with it. Dart static methods may b e seen as functions of the enclosing library. | 1630 Of course, the entire notion of static methods is debatable, but it is retained here because so many programmers are familiar with it. Dart static methods may b e seen as functions of the enclosing library. |
1631 } | 1631 } |
1632 | 1632 |
1633 \LMHash{} | 1633 \LMHash{} |
1634 It is a static warning if a class $C$ declares a static method named $n$ and has a setter named $n=$. | 1634 It is a static warning if a class $C$ declares a static method named $n$ and has a setter named $n=$. |
1635 %It is a static warning if a class has a static method with the same name as a s tatic member of one of its superclasses. | 1635 %It is a static warning if a class has a static method with the same name as a s tatic member of one of its superclasses. |
1636 | 1636 |
1637 %\rationale{ | 1637 %\rationale{ |
1638 %This last restriction makes classes more brittle with respect to changes in the class hierarchy. It stems from a general observation that shadowing of names in the same scope is questionable and should elicit a warning. | 1638 %This last restriction makes classes more brittle with respect to changes in the class hierarchy. It stems from a general observation that shadowing of names in the same scope is questionable and should elicit a warning. |
1639 %} | 1639 %} |
1640 %\commentary{ | 1640 %\commentary{ |
1641 %There is no hiding of static methods, or of static variables. | 1641 %There is no hiding of static methods, or of static variables. |
1642 %} | 1642 %} |
1643 | 1643 |
1644 | 1644 |
1645 \subsection{Static Variables} | 1645 \subsection{Static Variables} |
1646 \LMLabel{staticVariables} | 1646 \LMLabel{staticVariables} |
1647 | 1647 |
1648 \LMHash{} | 1648 \LMHash{} |
1649 {\em Static variables} are variables whose declarations are immediately containe d within a class declaration and that are declared \STATIC{}. The static variabl es of a class $C$ are those static variables declared by $C$. | 1649 {\em Static variables} are variables whose declarations are immediately containe d within a class declaration and that are declared \STATIC{}. The static variabl es of a class $C$ are those static variables declared by $C$. |
1650 | 1650 |
1651 %A static variable declaration of one of the forms \code{\STATIC{} $T$ $v$;}, \code{\STATIC{} $T$ $v$ = $e$;} , \code{\STATIC{} \CONST{} $T$ $v$ = $e$;} or \code{\STATIC{} \FINAL{} $T$ $v$ = $e$;} always induces an implicit static gette r function (\ref{getters}) with signature | 1651 %A static variable declaration of one of the forms \code{\STATIC{} $T$ $v$;}, \code{\STATIC{} $T$ $v$ = $e$;} , \code{\STATIC{} \CONST{} $T$ $v$ = $e$;} or \code{\STATIC{} \FINAL{} $T$ $v$ = $e$;} always induces an implicit static gette r function (\ref{getters}) with signature |
1652 | 1652 |
1653 %\STATIC{} $T$ \GET{} $v$ | 1653 %\STATIC{} $T$ \GET{} $v$ |
1654 | 1654 |
1655 %whose invocation evaluates as described below (\ref{evaluationOfStaticVariableG etters}).%to the value stored in $v$. | 1655 %whose invocation evaluates as described below (\ref{evaluationOfStaticVariableG etters}).%to the value stored in $v$. |
1656 | 1656 |
1657 | 1657 |
1658 %A static variable declaration of one of the forms \code{\STATIC{} \VAR{} $v$;} , \code{\STATIC{} \VAR{} $v$ = $e$;} , \code{\STATIC{} \CONST{} $v$ = $e$;} or \code{\STATIC{} \FINAL{} $v$ = $e$;} always induces an implicit static getter function with signature | 1658 %A static variable declaration of one of the forms \code{\STATIC{} \VAR{} $v$;} , \code{\STATIC{} \VAR{} $v$ = $e$;} , \code{\STATIC{} \CONST{} $v$ = $e$;} or \code{\STATIC{} \FINAL{} $v$ = $e$;} always induces an implicit static getter function with signature |
1659 | 1659 |
1660 %\STATIC{} \GET{} $v$ | 1660 %\STATIC{} \GET{} $v$ |
1661 | 1661 |
1662 %whose invocation evaluates as described below (\ref{evaluationOfStaticVariable Getters}).%to the value stored in $v$. | 1662 %whose invocation evaluates as described below (\ref{evaluationOfStaticVariable Getters}).%to the value stored in $v$. |
1663 | 1663 |
1664 %A non-final static variable declaration of the form \code{\STATIC{} $T$ $v$;} or the form \code{\STATIC{} $T$ $v$ = $e$;} always induces an implicit static setter function (\ref{setters}) with signature | 1664 %A non-final static variable declaration of the form \code{\STATIC{} $T$ $v$;} or the form \code{\STATIC{} $T$ $v$ = $e$;} always induces an implicit static setter function (\ref{setters}) with signature |
1665 | 1665 |
1666 %\STATIC{} \VOID{} \SET{} $v=(T$ $x)$ | 1666 %\STATIC{} \VOID{} \SET{} $v=(T$ $x)$ |
1667 | 1667 |
1668 %whose execution sets the value of $v$ to the incoming argument $x$. | 1668 %whose execution sets the value of $v$ to the incoming argument $x$. |
1669 | 1669 |
1670 %A static variable declaration of the form \code{\STATIC{} \VAR{} $v$;} or the form \code{\STATIC{} \VAR{} $v$ = $e$;} always induces an implicit static set ter function with signature | 1670 %A static variable declaration of the form \code{\STATIC{} \VAR{} $v$;} or the form \code{\STATIC{} \VAR{} $v$ = $e$;} always induces an implicit static set ter function with signature |
1671 | 1671 |
1672 %\STATIC{} \SET{} $v=(x)$ | 1672 %\STATIC{} \SET{} $v=(x)$ |
1673 | 1673 |
1674 %whose execution sets the value of $v$ to the incoming argument $x$. | 1674 %whose execution sets the value of $v$ to the incoming argument $x$. |
1675 | 1675 |
1676 %Extrernal static functions, getters, setters | 1676 %Extrernal static functions, getters, setters |
1677 | 1677 |
1678 %\subsubsection{Evaluation of Implicit Static Variable Getters} | 1678 %\subsubsection{Evaluation of Implicit Static Variable Getters} |
1679 %\LMLabel{evaluationOfStaticVariableGetters} | 1679 %\LMLabel{evaluationOfStaticVariableGetters} |
1680 | 1680 |
1681 %Let $d$ be the declaration of a static variable $v$. The implicit getter method of $v$ executes as follows: | 1681 %Let $d$ be the declaration of a static variable $v$. The implicit getter method of $v$ executes as follows: |
1682 %\begin{itemize} | 1682 %\begin{itemize} |
1683 %\item If $d$ is of one of the forms \code{\STATIC{} \VAR{} $v$ = $e$;} , \code{ \STATIC{} $T$ $v$ = $e$; }, \code{\STATIC{} \FINAL{} $v$ = $e$; } or \code{\STAT IC{} \FINAL{} $T$ $v$ = $e$;} and no value has yet been stored into $v$ then the initializer expression $e$ is evaluated. If, during the evaluation of $e$, the getter for $v$ is referenced, a \code{CyclicInitializationError} is thrown. If t he evaluation succeeded yielding an object $o$, let $r = o$, otherwise let $r = \NULL{}$. In any case, $r$ is stored into $v$. The result of executing the gette r is $r$. | 1683 %\item If $d$ is of one of the forms \code{\STATIC{} \VAR{} $v$ = $e$;} , \code{ \STATIC{} $T$ $v$ = $e$; }, \code{\STATIC{} \FINAL{} $v$ = $e$; } or \code{\STAT IC{} \FINAL{} $T$ $v$ = $e$;} and no value has yet been stored into $v$ then the initializer expression $e$ is evaluated. If, during the evaluation of $e$, the getter for $v$ is referenced, a \code{CyclicInitializationError} is thrown. If t he evaluation succeeded yielding an object $o$, let $r = o$, otherwise let $r = \NULL{}$. In any case, $r$ is stored into $v$. The result of executing the gette r is $r$. |
1684 %\item If $d$ is of one of the forms \code{\STATIC{} \CONST{} $v$ = $e$; } or \ code{\STATIC{} \CONST{} $T$ $v$ = $e$;} the result of the getter is the value of the compile time constant $e$. | 1684 %\item If $d$ is of one of the forms \code{\STATIC{} \CONST{} $v$ = $e$; } or \ code{\STATIC{} \CONST{} $T$ $v$ = $e$;} the result of the getter is the value of the compile time constant $e$. |
1685 %Otherwise | 1685 %Otherwise |
1686 %\item The result of executing the getter method is the value stored in $v$. | 1686 %\item The result of executing the getter method is the value stored in $v$. |
1687 %\end{itemize} | 1687 %\end{itemize} |
1688 | 1688 |
1689 | 1689 |
1690 | 1690 |
1691 \subsection{Superclasses} | 1691 \subsection{Superclasses} |
1692 \LMLabel{superclasses} | 1692 \LMLabel{superclasses} |
1693 | 1693 |
1694 \LMHash{} | 1694 \LMHash{} |
1695 The superclass of a class $C$ that has a with clause \code{\WITH{} $M_1, \ldots, M_k$} and an extends clause \code{\EXTENDS{} S} is the application of mixin (\r ef{mixins}) $M_k* \cdots * M_1$ to S. If no \WITH{} clause is specified then the \EXTENDS{} clause of a class $C$ specifies its superclass. If no \EXTENDS{} clause is specified, then either: | 1695 The superclass of a class $C$ that has a with clause \code{\WITH{} $M_1, \ldots, M_k$} and an extends clause \code{\EXTENDS{} S} is the application of mixin (\r ef{mixins}) $M_k* \cdots * M_1$ to S. If no \WITH{} clause is specified then the \EXTENDS{} clause of a class $C$ specifies its superclass. If no \EXTENDS{} clause is specified, then either: |
1696 \begin{itemize} | 1696 \begin{itemize} |
1697 \item $C$ is \code{Object}, which has no superclass. OR | 1697 \item $C$ is \code{Object}, which has no superclass. OR |
1698 \item Class $C$ is deemed to have an \EXTENDS{} clause of the form \code{\EXTEN DS{} Object}, and the rules above apply. | 1698 \item Class $C$ is deemed to have an \EXTENDS{} clause of the form \code{\EXTEN DS{} Object}, and the rules above apply. |
1699 \end{itemize} | 1699 \end{itemize} |
1700 | 1700 |
1701 \LMHash{} | 1701 \LMHash{} |
1702 It is a compile-time error to specify an \EXTENDS{} clause for class \code{Objec t}. | 1702 It is a compile-time error to specify an \EXTENDS{} clause for class \code{Objec t}. |
1703 | 1703 |
1704 \begin{grammar} | 1704 \begin{grammar} |
1705 {\bf superclass:} | 1705 {\bf superclass:} |
1706 \EXTENDS{} type | 1706 \EXTENDS{} type |
1707 . | 1707 . |
1708 \end{grammar} | 1708 \end{grammar} |
1709 | 1709 |
1710 %The superclass clause of a class C is processed within the enclosing scope of t he static scope of C. | 1710 %The superclass clause of a class C is processed within the enclosing scope of t he static scope of C. |
1711 %\commentary{ | 1711 %\commentary{ |
1712 %This means that in a generic class, the type parameters of the generic are avai lable in the superclass clause. | 1712 %This means that in a generic class, the type parameters of the generic are avai lable in the superclass clause. |
1713 %} | 1713 %} |
1714 | 1714 |
1715 \LMHash{} | 1715 \LMHash{} |
1716 The scope of the \EXTENDS{} and \WITH{} clauses of a class $C$ is the type-param eter scope of $C$. | 1716 The scope of the \EXTENDS{} and \WITH{} clauses of a class $C$ is the type-param eter scope of $C$. |
1717 | 1717 |
1718 \LMHash{} | 1718 \LMHash{} |
1719 %It is a compile-time error if the \EXTENDS{} clause of a class $C$ includes a type expression that does not denote a class available in the lexical scope of $ C$. | 1719 %It is a compile-time error if the \EXTENDS{} clause of a class $C$ includes a type expression that does not denote a class available in the lexical scope of $ C$. |
1720 It is a compile-time error if the \EXTENDS{} clause of a class $C$ specifies an enumerated type (\ref{enums}), a malformed type or a deferred type (\ref{stati cTypes}) as a superclass. | 1720 It is a compile-time error if the \EXTENDS{} clause of a class $C$ specifies an enumerated type (\ref{enums}), a malformed type or a deferred type (\ref{stati cTypes}) as a superclass. |
1721 % too strict? Do we e want extends List<Undeclared> to work as List<dynamic>? | 1721 % too strict? Do we e want extends List<Undeclared> to work as List<dynamic>? |
1722 | 1722 |
1723 \commentary{ The type parameters of a generic class are available in the lexical scope of the superclass clause, potentially shadowing classes in the surroundin g scope. The following code is therefore illegal and should cause a compile-time error: | 1723 \commentary{ The type parameters of a generic class are available in the lexical scope of the superclass clause, potentially shadowing classes in the surroundin g scope. The following code is therefore illegal and should cause a compile-time error: |
1724 } | 1724 } |
1725 | 1725 |
1726 \begin{dartCode} | 1726 \begin{dartCode} |
1727 class T \{\} | 1727 class T \{\} |
1728 | 1728 |
1729 /* Compilation error: Attempt to subclass a type parameter */ | 1729 /* Compilation error: Attempt to subclass a type parameter */ |
1730 class G$<$T$>$ extends T \{\} | 1730 class G$<$T$>$ extends T \{\} |
1731 | 1731 |
1732 \end{dartCode} | 1732 \end{dartCode} |
1733 | 1733 |
1734 | 1734 |
1735 \LMHash{} | 1735 \LMHash{} |
1736 A class $S$ is {\em a superclass} of a class $C$ iff either: | 1736 A class $S$ is {\em a superclass} of a class $C$ iff either: |
1737 \begin{itemize} | 1737 \begin{itemize} |
1738 \item $S$ is the superclass of $C$, or | 1738 \item $S$ is the superclass of $C$, or |
1739 \item $S$ is a superclass of a class $S^{\prime}$ and $S^{\prime}$ is a supercla ss of $C$. | 1739 \item $S$ is a superclass of a class $S^{\prime}$ and $S^{\prime}$ is a supercla ss of $C$. |
1740 \end{itemize} | 1740 \end{itemize} |
1741 | 1741 |
1742 \LMHash{} | 1742 \LMHash{} |
1743 It is a compile-time error if a class $C$ is a superclass of itself. | 1743 It is a compile-time error if a class $C$ is a superclass of itself. |
1744 | 1744 |
1745 | 1745 |
1746 | 1746 |
1747 | 1747 |
1748 \subsubsection{Inheritance and Overriding} | 1748 \subsubsection{Inheritance and Overriding} |
1749 \LMLabel{inheritanceAndOverriding} | 1749 \LMLabel{inheritanceAndOverriding} |
1750 | 1750 |
1751 | 1751 |
1752 %A class $C$ {\em inherits} any accessible instance members of its superclass t hat are not overridden by members declared in $C$. | 1752 %A class $C$ {\em inherits} any accessible instance members of its superclass t hat are not overridden by members declared in $C$. |
1753 | 1753 |
1754 \LMHash{} | 1754 \LMHash{} |
1755 Let $C$ be a class, let $A$ be a superclass of $C$, and let $S_1 \ldots S_k$ b e superclasses of $C$ that are also subclasses of $A$. $C$ {\em inherits} all ac cessible instance members of $A$ that have not been overridden by a declaratio n in $C$ or in at least one of $S_1 \ldots S_k$. | 1755 Let $C$ be a class, let $A$ be a superclass of $C$, and let $S_1 \ldots S_k$ b e superclasses of $C$ that are also subclasses of $A$. $C$ {\em inherits} all ac cessible instance members of $A$ that have not been overridden by a declaratio n in $C$ or in at least one of $S_1 \ldots S_k$. |
1756 | 1756 |
1757 \rationale { | 1757 \rationale { |
1758 It would be more attractive to give a purely local definition of inheritance, t hat depended only on the members of the direct superclass $S$. However, a class $C$ can inherit a member $m$ that is not a member of its superclass $S$. This can occur when the member $m$ is private | 1758 It would be more attractive to give a purely local definition of inheritance, t hat depended only on the members of the direct superclass $S$. However, a class $C$ can inherit a member $m$ that is not a member of its superclass $S$. This can occur when the member $m$ is private |
1759 to the library $L_1$ of $C$, whereas $S$ comes from a different library $L_2$, b ut | 1759 to the library $L_1$ of $C$, whereas $S$ comes from a different library $L_2$, b ut |
1760 the superclass chain of $S$ includes a class declared in $L_1$. | 1760 the superclass chain of $S$ includes a class declared in $L_1$. |
1761 } | 1761 } |
1762 | 1762 |
1763 \LMHash{} | 1763 \LMHash{} |
1764 A class may override instance members that would otherwise have been inherited f rom its superclass. | 1764 A class may override instance members that would otherwise have been inherited f rom its superclass. |
1765 | 1765 |
1766 \LMHash{} | 1766 \LMHash{} |
1767 Let $C = S_0$ be a class declared in library $L$, and let $\{S_1 \ldots S_k\}$ b e the set of all superclasses of $C$, where $S_i$ is the superclass of $S_{i-1}$ for $i \in 1 .. k$. Let $C$ declare a member $m$, and let $m^\prime$ be a memb er of $S_j, j \in 1 .. k$, that has the same name as $m$, such that $m^\prime$ is accessible to $L$. Then $m$ overrides $m^\prime$ if $m^\prime$ is not alrea dy overridden by a member of at least one of $S_1 \ldots S_{j-1}$ and neither $m $ nor $m^\prime$ are fields. | 1767 Let $C = S_0$ be a class declared in library $L$, and let $\{S_1 \ldots S_k\}$ b e the set of all superclasses of $C$, where $S_i$ is the superclass of $S_{i-1}$ for $i \in 1 .. k$. Let $C$ declare a member $m$, and let $m^\prime$ be a memb er of $S_j, j \in 1 .. k$, that has the same name as $m$, such that $m^\prime$ is accessible to $L$. Then $m$ overrides $m^\prime$ if $m^\prime$ is not alrea dy overridden by a member of at least one of $S_1 \ldots S_{j-1}$ and neither $m $ nor $m^\prime$ are fields. |
1768 | 1768 |
1769 %Let $C$ be a class declared in library $L$, with superclass $S$ and let $C$ dec lare an instance member $m$, and assume $S$ declares an instance member $m^\pri me$ with the same name as $m$. Then $m$ {\em overrides} $m^\prime$ iff $m^\prime $ is accessible (\ref{privacy}) to $L$, $m$ has the same name as $m^\prime$ an d neither $m$ nor $m^\prime$ are fields. | 1769 %Let $C$ be a class declared in library $L$, with superclass $S$ and let $C$ dec lare an instance member $m$, and assume $S$ declares an instance member $m^\pri me$ with the same name as $m$. Then $m$ {\em overrides} $m^\prime$ iff $m^\prime $ is accessible (\ref{privacy}) to $L$, $m$ has the same name as $m^\prime$ an d neither $m$ nor $m^\prime$ are fields. |
1770 | 1770 |
1771 \commentary{Fields never override each other. The getters and setters induced by fields do.} | 1771 \commentary{Fields never override each other. The getters and setters induced by fields do.} |
1772 | 1772 |
1773 \rationale{Again, a local definition of overriding would be preferable, but fail s to account for library privacy. | 1773 \rationale{Again, a local definition of overriding would be preferable, but fail s to account for library privacy. |
1774 } | 1774 } |
1775 | 1775 |
1776 \LMHash{} | 1776 \LMHash{} |
1777 Whether an override is legal or not is described elsewhere in this specification (see \ref{instanceMethods}, \ref{getters} and \ref{setters}). | 1777 Whether an override is legal or not is described elsewhere in this specification (see \ref{instanceMethods}, \ref{getters} and \ref{setters}). |
1778 | 1778 |
1779 \commentary{For example getters may not legally override methods and vice versa. Setters never override methods or getters, and vice versa, because their names always differ. | 1779 \commentary{For example getters may not legally override methods and vice versa. Setters never override methods or getters, and vice versa, because their names always differ. |
1780 } | 1780 } |
1781 | 1781 |
1782 \rationale{ | 1782 \rationale{ |
1783 It is nevertheless convenient to define the override relation between members in this way, so that we can concisely describe the illegal cases. | 1783 It is nevertheless convenient to define the override relation between members in this way, so that we can concisely describe the illegal cases. |
1784 } | 1784 } |
1785 | 1785 |
1786 \commentary{ | 1786 \commentary{ |
1787 Note that instance variables do not participate in the override relation, but th e getters and setters they induce do. Also, getters don't override setters and v ice versa. Finally, static members never override anything. | 1787 Note that instance variables do not participate in the override relation, but th e getters and setters they induce do. Also, getters don't override setters and v ice versa. Finally, static members never override anything. |
1788 } | 1788 } |
1789 | 1789 |
1790 \LMHash{} | 1790 \LMHash{} |
1791 It is a static warning if a non-abstract class inherits an abstract method. | 1791 It is a static warning if a non-abstract class inherits an abstract method. |
1792 | 1792 |
1793 \commentary { | 1793 \commentary { |
1794 For convenience, here is a summary of the relevant rules. Remember that this is not normative. The controlling language is in the relevant sections of the speci fication. | 1794 For convenience, here is a summary of the relevant rules. Remember that this is not normative. The controlling language is in the relevant sections of the speci fication. |
1795 | 1795 |
1796 \begin{enumerate} | 1796 \begin{enumerate} |
1797 | 1797 |
1798 \item There is only one namespace for getters, setters, methods and constructors (\ref{scoping}). A field $f$ introduces a getter $f$ and a non-final field $f$ also introduces a setter $f=$ (\ref{instanceVariables}, \ref{staticVariables}). When we speak of members here, we mean accessible fields, getters, setters and m ethods (\ref{classes}). | 1798 \item There is only one namespace for getters, setters, methods and constructors (\ref{scoping}). A field $f$ introduces a getter $f$ and a non-final field $f$ also introduces a setter $f=$ (\ref{instanceVariables}, \ref{staticVariables}). When we speak of members here, we mean accessible fields, getters, setters and m ethods (\ref{classes}). |
1799 \item You cannot have two members with the same name in the same class - be the y declared or inherited (\ref{scoping}, \ref{classes}). | 1799 \item You cannot have two members with the same name in the same class - be the y declared or inherited (\ref{scoping}, \ref{classes}). |
1800 \item Static members are never inherited. | 1800 \item Static members are never inherited. |
1801 \item It is a warning if you have an static member named $m$ in your class or a ny superclass (even though it is not inherited) and an instance member of the s ame name (\ref{instanceMethods}, \ref{getters}, \ref{setters}). | 1801 \item It is a warning if you have an static member named $m$ in your class or a ny superclass (even though it is not inherited) and an instance member of the s ame name (\ref{instanceMethods}, \ref{getters}, \ref{setters}). |
1802 \item It is a warning if you have a static setter $v=$, and an instance member $ v$ (\ref{setters}). | 1802 \item It is a warning if you have a static setter $v=$, and an instance member $ v$ (\ref{setters}). |
1803 \item It is a warning if you have a static getter $v$ and an instance setter $v= $ (\ref{getters}). | 1803 \item It is a warning if you have a static getter $v$ and an instance setter $v= $ (\ref{getters}). |
1804 \item If you define an instance member named $m$, and your superclass has an in stance member of the same name, they override each other. This may or may not be legal. | 1804 \item If you define an instance member named $m$, and your superclass has an in stance member of the same name, they override each other. This may or may not be legal. |
1805 \item \label{typeSigAssignable} | 1805 \item \label{typeSigAssignable} |
1806 If two members override each other, it is a static warning if their type signatu res are not assignable to each other (\ref{instanceMethods}, \ref{getters}, \ref {setters}) (and since these are function types, this means the same as "subtype s of each other"). | 1806 If two members override each other, it is a static warning if their type signatu res are not assignable to each other (\ref{instanceMethods}, \ref{getters}, \ref {setters}) (and since these are function types, this means the same as "subtype s of each other"). |
1807 \item \label{requiredParams} | 1807 \item \label{requiredParams} |
1808 If two members override each other, it is a static warning if the overriding mem ber has more required parameters than the overridden one (\ref{instanceMethods} ). | 1808 If two members override each other, it is a static warning if the overriding mem ber has more required parameters than the overridden one (\ref{instanceMethods} ). |
1809 \item \label{optionalPositionals} | 1809 \item \label{optionalPositionals} |
1810 If two members override each other, it is a static warning if the overriding mem ber has fewer positional parameters than the overridden one (\ref{instanceMetho ds}). | 1810 If two members override each other, it is a static warning if the overriding mem ber has fewer positional parameters than the overridden one (\ref{instanceMetho ds}). |
1811 \item \label{namedParams} | 1811 \item \label{namedParams} |
1812 If two members override each other, it is a static warning if the overriding mem ber does not have all the named parameters that the overridden one has (\ref{ins tanceMethods}). | 1812 If two members override each other, it is a static warning if the overriding mem ber does not have all the named parameters that the overridden one has (\ref{ins tanceMethods}). |
1813 \item Setters, getters and operators never have optional parameters of any kind; it's a compile-time error (\ref{operators}, \ref{getters}, \ref{setters}). | 1813 \item Setters, getters and operators never have optional parameters of any kind; it's a compile-time error (\ref{operators}, \ref{getters}, \ref{setters}). |
1814 \item It is a compile-time error if a member has the same name as its enclosing class (\ref{classes}). | 1814 \item It is a compile-time error if a member has the same name as its enclosing class (\ref{classes}). |
1815 \item A class has an implicit interface (\ref{classes}). | 1815 \item A class has an implicit interface (\ref{classes}). |
1816 \item Superinterface members are not inherited by a class, but are inherited by its implicit interface. Interfaces have their own inheritance rules (\ref{interf aceInheritanceAndOverriding}). | 1816 \item Superinterface members are not inherited by a class, but are inherited by its implicit interface. Interfaces have their own inheritance rules (\ref{interf aceInheritanceAndOverriding}). |
1817 \item A member is abstract if it has no body and is not labeled \EXTERNAL{} (\re f{abstractInstanceMembers}, \ref{externalFunctions}). | 1817 \item A member is abstract if it has no body and is not labeled \EXTERNAL{} (\re f{abstractInstanceMembers}, \ref{externalFunctions}). |
1818 \item A class is abstract iff it is explicitly labeled \ABSTRACT{}.% or if it de clares (not just inherits) an abstract member (\ref{classes}). | 1818 \item A class is abstract iff it is explicitly labeled \ABSTRACT{}.% or if it de clares (not just inherits) an abstract member (\ref{classes}). |
1819 \item It is a static warning if a concrete class has an abstract member (declare d or inherited). | 1819 \item It is a static warning if a concrete class has an abstract member (declare d or inherited). |
1820 \item It is a static warning and a dynamic error to call a non-factory construct or of an abstract class (\ref{new}). | 1820 \item It is a static warning and a dynamic error to call a non-factory construct or of an abstract class (\ref{new}). |
1821 \item If a class defines an instance member named $m$, and any of its superinter faces have a member named $m$, the interface of the class overrides $m$. | 1821 \item If a class defines an instance member named $m$, and any of its superinter faces have a member named $m$, the interface of the class overrides $m$. |
1822 \item An interface inherits all members of its superinterfaces that are not ov erridden and not members of multiple superinterfaces. | 1822 \item An interface inherits all members of its superinterfaces that are not ov erridden and not members of multiple superinterfaces. |
1823 \item If multiple superinterfaces of an interface define a member with the same name $m$, then at most one member is inherited. That member (if it exists) is t he one whose type is a subtype of all the others. If there is no such member, th en: | 1823 \item If multiple superinterfaces of an interface define a member with the same name $m$, then at most one member is inherited. That member (if it exists) is t he one whose type is a subtype of all the others. If there is no such member, th en: |
1824 \begin{itemize} | 1824 \begin{itemize} |
1825 \item A static warning is given. | 1825 \item A static warning is given. |
1826 \item If possible the interface gets a member named $m$ that has the minimum number of required parameters among all the members in the superinterfaces, the maximal number of positionals, and the superset of named parameters. The typ es of these are all \DYNAMIC{}. If this is impossible then no member $m$ appears in the interface. | 1826 \item If possible the interface gets a member named $m$ that has the minimum number of required parameters among all the members in the superinterfaces, the maximal number of positionals, and the superset of named parameters. The typ es of these are all \DYNAMIC{}. If this is impossible then no member $m$ appears in the interface. |
1827 \end{itemize} (\ref{interfaceInheritanceAndOverriding}) | 1827 \end{itemize} (\ref{interfaceInheritanceAndOverriding}) |
1828 \item Rule \ref{typeSigAssignable} applies to interfaces as well as classes (\ ref{interfaceInheritanceAndOverriding}). | 1828 \item Rule \ref{typeSigAssignable} applies to interfaces as well as classes (\ ref{interfaceInheritanceAndOverriding}). |
1829 \item It is a static warning if a concrete class does not have an implementatio n for a method in any of its superinterfaces unless it has a \cd{noSuchMethod} method (\ref{superinterfaces}). | 1829 \item It is a static warning if a concrete class does not have an implementatio n for a method in any of its superinterfaces unless it has a \cd{noSuchMethod} method (\ref{superinterfaces}). |
1830 \item The identifier of a named constructor cannot be the same as the name of a member declared (as opposed to inherited) in the same class (\ref{constructors}) . | 1830 \item The identifier of a named constructor cannot be the same as the name of a member declared (as opposed to inherited) in the same class (\ref{constructors}) . |
1831 \end{enumerate} | 1831 \end{enumerate} |
1832 } | 1832 } |
1833 | 1833 |
1834 | 1834 |
1835 %Can we have abstract getters and setters? | 1835 %Can we have abstract getters and setters? |
1836 | 1836 |
1837 \subsection{ Superinterfaces} | 1837 \subsection{ Superinterfaces} |
1838 \LMLabel{superinterfaces} | 1838 \LMLabel{superinterfaces} |
1839 % what about rules about classes that fail to implement their interfaces? | 1839 % what about rules about classes that fail to implement their interfaces? |
1840 | 1840 |
1841 \LMHash{} | 1841 \LMHash{} |
1842 A class has a set of direct superinterfaces. This set includes the interface of its superclass and the interfaces specified in the \IMPLEMENTS{} clause of the class. | 1842 A class has a set of direct superinterfaces. This set includes the interface of its superclass and the interfaces specified in the \IMPLEMENTS{} clause of the class. |
1843 % and any superinterfaces specified by interface injection (\ref{interfaceInject ion}). \Q{The latter needs to be worded carefully - when do interface injection clauses execute and in what scope?} | 1843 % and any superinterfaces specified by interface injection (\ref{interfaceInject ion}). \Q{The latter needs to be worded carefully - when do interface injection clauses execute and in what scope?} |
1844 | 1844 |
1845 \begin{grammar} | 1845 \begin{grammar} |
1846 {\bf interfaces:} | 1846 {\bf interfaces:} |
1847 \IMPLEMENTS{} typeList | 1847 \IMPLEMENTS{} typeList |
1848 . | 1848 . |
1849 \end{grammar} | 1849 \end{grammar} |
1850 | 1850 |
1851 \LMHash{} | 1851 \LMHash{} |
1852 The scope of the \IMPLEMENTS{} clause of a class $C$ is the type-parameter scope of $C$. | 1852 The scope of the \IMPLEMENTS{} clause of a class $C$ is the type-parameter scope of $C$. |
1853 | 1853 |
1854 \LMHash{} | 1854 \LMHash{} |
1855 It is a compile-time error if the \IMPLEMENTS{} clause of a class $C$ specifie s a type variable as a superinterface. It is a compile-time error if the \IMPL EMENTS{} clause of a class $C$ specifies an enumerated type (\ref{enums}), a ma lformed type or deferred type (\ref{staticTypes}) as a superinterface. It is a compile-time error if the \IMPLEMENTS{} clause of a class $C$ specifies type \DY NAMIC{} as a superinterface. It is a compile-time error if the \IMPLEMENTS{} c lause of a class $C$ specifies a type $T$ as a superinterface more than once. | 1855 It is a compile-time error if the \IMPLEMENTS{} clause of a class $C$ specifie s a type variable as a superinterface. It is a compile-time error if the \IMPL EMENTS{} clause of a class $C$ specifies an enumerated type (\ref{enums}), a ma lformed type or deferred type (\ref{staticTypes}) as a superinterface. It is a compile-time error if the \IMPLEMENTS{} clause of a class $C$ specifies type \DY NAMIC{} as a superinterface. It is a compile-time error if the \IMPLEMENTS{} c lause of a class $C$ specifies a type $T$ as a superinterface more than once. |
1856 It is a compile-time error if the superclass of a class $C$ is specified as a su perinterface of $C$. | 1856 It is a compile-time error if the superclass of a class $C$ is specified as a su perinterface of $C$. |
1857 | 1857 |
1858 \rationale{ | 1858 \rationale{ |
1859 One might argue that it is harmless to repeat a type in the superinterface list, so why make it an error? The issue is not so much that the situation described in program source is erroneous, but that it is pointless. As such, it is an indi cation that the programmer may very well have meant to say something else - and that is a mistake that should be called to her or his attention. Nevertheless, we could simply issue a warning; and perhaps we should and will. That said, prob lems like these are local and easily corrected on the spot, so we feel justified in taking a harder line. | 1859 One might argue that it is harmless to repeat a type in the superinterface list, so why make it an error? The issue is not so much that the situation described in program source is erroneous, but that it is pointless. As such, it is an indi cation that the programmer may very well have meant to say something else - and that is a mistake that should be called to her or his attention. Nevertheless, we could simply issue a warning; and perhaps we should and will. That said, prob lems like these are local and easily corrected on the spot, so we feel justified in taking a harder line. |
1860 } | 1860 } |
1861 | 1861 |
1862 \LMHash{} | 1862 \LMHash{} |
1863 It is a compile-time error if the interface of a class $C$ is a superinterface o f itself. | 1863 It is a compile-time error if the interface of a class $C$ is a superinterface o f itself. |
1864 | 1864 |
1865 \LMHash{} | 1865 \LMHash{} |
1866 Let $C$ be a concrete class that does not have a \code{noSuchMethod()} method di stinct from the one declared in class \cd{Object}. | 1866 Let $C$ be a concrete class that does not have a \code{noSuchMethod()} method di stinct from the one declared in class \cd{Object}. |
1867 It is a static warning if the implicit interface of $C$ includes an instance me mber $m$ of type $F$ and $C$ does not declare or inherit a corresponding non-abs tract instance member $m$ of type $F'$ such that $F' <: F$. | 1867 It is a static warning if the implicit interface of $C$ includes an instance me mber $m$ of type $F$ and $C$ does not declare or inherit a corresponding non-abs tract instance member $m$ of type $F'$ such that $F' <: F$. |
1868 | 1868 |
1869 \commentary{A class does not inherit members from its superinterfaces. However, its implicit interface does. | 1869 \commentary{A class does not inherit members from its superinterfaces. However, its implicit interface does. |
1870 } | 1870 } |
1871 | 1871 |
1872 | 1872 |
1873 \rationale { | 1873 \rationale { |
1874 We choose to issue these warnings only for concrete classes; an abstract class m ight legitimately be designed with the expectation that concrete subclasses will implement part of the interface. | 1874 We choose to issue these warnings only for concrete classes; an abstract class m ight legitimately be designed with the expectation that concrete subclasses will implement part of the interface. |
1875 We also disable these warnings if a \code{noSuchMethod()} declaration is present or inherited from any class other than \cd{Object}. In such cases, the supporte d interface is going to be implemented via \code{noSuchMethod()} and no actual d eclarations of the implemented interface's members are needed. This allows proxy classes for specific types to be implemented without provoking type warnings. | 1875 We also disable these warnings if a \code{noSuchMethod()} declaration is present or inherited from any class other than \cd{Object}. In such cases, the supporte d interface is going to be implemented via \code{noSuchMethod()} and no actual d eclarations of the implemented interface's members are needed. This allows proxy classes for specific types to be implemented without provoking type warnings. |
1876 } | 1876 } |
1877 | 1877 |
1878 | 1878 |
1879 \LMHash{} | 1879 \LMHash{} |
1880 It is a static warning if the implicit interface of a class $C$ includes an ins tance member $m$ of type $F$ and $C$ declares or inherits a corresponding instan ce member $m$ of type $F'$ if $F'$ is not a subtype of $F$. | 1880 It is a static warning if the implicit interface of a class $C$ includes an ins tance member $m$ of type $F$ and $C$ declares or inherits a corresponding instan ce member $m$ of type $F'$ if $F'$ is not a subtype of $F$. |
1881 | 1881 |
1882 \rationale{ | 1882 \rationale{ |
1883 However, if a class does explicitly declare a member that conflicts with its sup erinterface, this always yields a static warning. | 1883 However, if a class does explicitly declare a member that conflicts with its sup erinterface, this always yields a static warning. |
1884 | 1884 |
1885 } | 1885 } |
1886 %It is a static warning if an imported superinterface of a class $C$ declares pr ivate members. | 1886 %It is a static warning if an imported superinterface of a class $C$ declares pr ivate members. |
1887 | 1887 |
1888 % Should we ignore unimplemented private members? | 1888 % Should we ignore unimplemented private members? |
1889 | 1889 |
1890 %\rationale{This last rule is problematic. As code evolves in one library ($L_1$ ) it may add private members to a class $I_1$ implemented or inherited in anothe r library $L_2$ breaking $L_1$. This is a direct result of coupling an interfa ce based type system with library based privacy. We are considering alternative semantics that might help resolve this issue. | 1890 %\rationale{This last rule is problematic. As code evolves in one library ($L_1$ ) it may add private members to a class $I_1$ implemented or inherited in anothe r library $L_2$ breaking $L_1$. This is a direct result of coupling an interfa ce based type system with library based privacy. We are considering alternative semantics that might help resolve this issue. |
1891 %} | 1891 %} |
1892 | 1892 |
1893 %\commentary{However, it is perfectly acceptable if a type mentioned in the impl ements clause is mentioned as a superinterface in an interface injection clause. | 1893 %\commentary{However, it is perfectly acceptable if a type mentioned in the impl ements clause is mentioned as a superinterface in an interface injection clause. |
1894 %} | 1894 %} |
1895 | 1895 |
1896 %\rationale{We disallow repetition of a type in a given implements clause, as th at is a localized mistake. However, separate clauses (that is the original class and various injections) may evolve separately over time, and we don't want to c ause breakage. For example | 1896 %\rationale{We disallow repetition of a type in a given implements clause, as th at is a localized mistake. However, separate clauses (that is the original class and various injections) may evolve separately over time, and we don't want to c ause breakage. For example |
1897 | 1897 |
1898 %class C implements I1 {...}; // class declaration | 1898 %class C implements I1 {...}; // class declaration |
1899 | 1899 |
1900 | 1900 |
1901 %somewhere someone realizes that C could implement I2 class C implements I2; // injection | 1901 %somewhere someone realizes that C could implement I2 class C implements I2; // injection |
1902 | 1902 |
1903 %later, the author of C decides to support I2 | 1903 %later, the author of C decides to support I2 |
1904 | 1904 |
1905 %class C implements I1, I2 {...}; // class declaration | 1905 %class C implements I1, I2 {...}; // class declaration |
1906 | 1906 |
1907 %this should not cause breakage. | 1907 %this should not cause breakage. |
1908 %} | 1908 %} |
1909 | 1909 |
1910 % \rationale{This avoids the issues with so-called miranda methods etc. } | 1910 % \rationale{This avoids the issues with so-called miranda methods etc. } |
1911 | 1911 |
1912 | 1912 |
1913 \section{Interfaces} | 1913 \section{Interfaces} |
1914 \LMLabel{interfaces} | 1914 \LMLabel{interfaces} |
1915 | 1915 |
1916 \LMHash{} | 1916 \LMHash{} |
1917 An {\em interface} defines how one may interact with an object. An interface has methods, getters and setters and a set of superinterfaces. | 1917 An {\em interface} defines how one may interact with an object. An interface has methods, getters and setters and a set of superinterfaces. |
1918 | 1918 |
1919 \subsection{Superinterfaces} | 1919 \subsection{Superinterfaces} |
1920 \LMLabel{interfaceSuperinterfaces} | 1920 \LMLabel{interfaceSuperinterfaces} |
1921 | 1921 |
1922 \LMHash{} | 1922 \LMHash{} |
1923 An interface has a set of direct superinterfaces. | 1923 An interface has a set of direct superinterfaces. |
1924 | 1924 |
1925 \LMHash{} | 1925 \LMHash{} |
1926 An interface $J$ is a superinterface of an interface $I$ iff either $J$ is a dir ect superinterface of $I$ or $J$ is a superinterface of a direct superinterface of $I$. | 1926 An interface $J$ is a superinterface of an interface $I$ iff either $J$ is a dir ect superinterface of $I$ or $J$ is a superinterface of a direct superinterface of $I$. |
1927 | 1927 |
1928 | 1928 |
1929 | 1929 |
1930 | 1930 |
1931 \subsubsection{Inheritance and Overriding} | 1931 \subsubsection{Inheritance and Overriding} |
1932 \LMLabel{interfaceInheritanceAndOverriding} | 1932 \LMLabel{interfaceInheritanceAndOverriding} |
1933 | 1933 |
1934 \LMHash{} | 1934 \LMHash{} |
1935 Let $J$ be an interface and $K$ be a library. We define $inherited(J, K)$ to be the set of members $m$ such that all of the following hold: | 1935 Let $J$ be an interface and $K$ be a library. We define $inherited(J, K)$ to be the set of members $m$ such that all of the following hold: |
1936 \begin{itemize} | 1936 \begin{itemize} |
1937 \item $m$ is accessible to $K$ and | 1937 \item $m$ is accessible to $K$ and |
1938 \item $A$ is a direct superinterface of $J$ and either | 1938 \item $A$ is a direct superinterface of $J$ and either |
1939 \begin{itemize} | 1939 \begin{itemize} |
1940 \item $A$ declares a member $m$ or | 1940 \item $A$ declares a member $m$ or |
1941 \item $m$ is a member of $inherited(A, K)$. | 1941 \item $m$ is a member of $inherited(A, K)$. |
1942 \end{itemize} | 1942 \end{itemize} |
1943 \item $m$ is not overridden by $J$. | 1943 \item $m$ is not overridden by $J$. |
1944 \end{itemize} | 1944 \end{itemize} |
1945 | 1945 |
1946 \LMHash{} | 1946 \LMHash{} |
1947 Furthermore, we define $overrides(J, K)$ to be the set of members $m^\prime$ su ch that all of the following hold: | 1947 Furthermore, we define $overrides(J, K)$ to be the set of members $m^\prime$ su ch that all of the following hold: |
1948 \begin{itemize} | 1948 \begin{itemize} |
1949 \item $J$ is the implicit interface of a class $C$. | 1949 \item $J$ is the implicit interface of a class $C$. |
1950 \item $C$ declares a member $m$. | 1950 \item $C$ declares a member $m$. |
1951 \item $m^\prime$ has the same name as $m$. | 1951 \item $m^\prime$ has the same name as $m$. |
1952 \item $m^\prime$ is accessible to $K$. | 1952 \item $m^\prime$ is accessible to $K$. |
1953 \item $A$ is a direct superinterface of $J$ and either | 1953 \item $A$ is a direct superinterface of $J$ and either |
1954 \begin{itemize} | 1954 \begin{itemize} |
1955 \item $A$ declares a member $m^\prime$ or | 1955 \item $A$ declares a member $m^\prime$ or |
1956 \item $m^\prime$ is a member of $inherited(A, K)$. | 1956 \item $m^\prime$ is a member of $inherited(A, K)$. |
1957 \end{itemize} | 1957 \end{itemize} |
1958 \end{itemize} | 1958 \end{itemize} |
1959 | 1959 |
1960 | 1960 |
1961 \LMHash{} | 1961 \LMHash{} |
1962 Let $I$ be the implicit interface of a class $C$ declared in library $L$. $I$ { \em inherits} all members of $inherited(I, L)$ and $I$ {\em overrides} $m^\prime $ if $m^\prime \in overrides(I, L)$. | 1962 Let $I$ be the implicit interface of a class $C$ declared in library $L$. $I$ { \em inherits} all members of $inherited(I, L)$ and $I$ {\em overrides} $m^\prime $ if $m^\prime \in overrides(I, L)$. |
1963 | 1963 |
1964 \LMHash{} | 1964 \LMHash{} |
1965 All the static warnings pertaining to the overriding of instance members given i n section \ref{classes} above hold for overriding between interfaces as well. | 1965 All the static warnings pertaining to the overriding of instance members given i n section \ref{classes} above hold for overriding between interfaces as well. |
1966 | 1966 |
1967 \LMHash{} | 1967 \LMHash{} |
1968 It is a static warning if $m$ is a method and $m^\prime$ is a getter, or if $m$ is a getter and $m^\prime$ is a method. | 1968 It is a static warning if $m$ is a method and $m^\prime$ is a getter, or if $m$ is a getter and $m^\prime$ is a method. |
1969 | 1969 |
1970 | 1970 |
1971 | 1971 |
1972 %Let $I = S_0$ be the implicit interface of a class $C$ declared in library $L$, and let $\{S_1 \ldots S_k\}$ be the set of all superinterfaces of $I$. | 1972 %Let $I = S_0$ be the implicit interface of a class $C$ declared in library $L$, and let $\{S_1 \ldots S_k\}$ be the set of all superinterfaces of $I$. |
1973 | 1973 |
1974 %Let $I$ be the implicit interface of a class $C$. $I$ inherits any instance me mbers of its superinterfaces that are not overridden by members declared in $C$. | 1974 %Let $I$ be the implicit interface of a class $C$. $I$ inherits any instance me mbers of its superinterfaces that are not overridden by members declared in $C$. |
1975 | 1975 |
1976 % tighten definition? do we need chain as for classes? Definition for interface override? | 1976 % tighten definition? do we need chain as for classes? Definition for interface override? |
1977 | 1977 |
1978 \LMHash{} | 1978 \LMHash{} |
1979 However, if the above rules would cause multiple members $m_1, \ldots, m_k$ wit h the same name $n$ to be inherited (because identically named members existed i n several superinterfaces) then at most one member is inherited. | 1979 However, if the above rules would cause multiple members $m_1, \ldots, m_k$ wit h the same name $n$ to be inherited (because identically named members existed i n several superinterfaces) then at most one member is inherited. |
1980 | 1980 |
1981 \LMHash{} | 1981 \LMHash{} |
1982 If some but not all of the $m_i, 1 \le i \le k$ are getters none of the $m_i$ ar e inherited, and a static warning is issued. | 1982 If some but not all of the $m_i, 1 \le i \le k$ are getters none of the $m_i$ ar e inherited, and a static warning is issued. |
1983 | 1983 |
1984 \LMHash{} | 1984 \LMHash{} |
1985 Otherwise, if the static types $T_1, \ldots, T_k$ of the members $m_1, \ldots, m_k$ are not identical, then there must be a member $m_x$ such that $T_x <: T_ i, 1 \le x \le k$ for all $i \in 1..k$, or a static type warning occurs. The m ember that is inherited is $m_x$, if it exists; otherwise: | 1985 Otherwise, if the static types $T_1, \ldots, T_k$ of the members $m_1, \ldots, m_k$ are not identical, then there must be a member $m_x$ such that $T_x <: T_ i, 1 \le x \le k$ for all $i \in 1..k$, or a static type warning occurs. The m ember that is inherited is $m_x$, if it exists; otherwise: |
1986 let $numberOfPositionals(f)$ denote the number of positional parameters of a fu nction $f$, and let $numberOfRequiredParams(f)$ denote the number of required pa rameters of a function $f$. Furthermore, let $s$ denote the set of all named par ameters of the $m_1, \ldots, m_k$. Then let | 1986 let $numberOfPositionals(f)$ denote the number of positional parameters of a fu nction $f$, and let $numberOfRequiredParams(f)$ denote the number of required pa rameters of a function $f$. Furthermore, let $s$ denote the set of all named par ameters of the $m_1, \ldots, m_k$. Then let |
1987 | 1987 |
1988 $h = max(numberOfPositionals(m_i)), $ | 1988 $h = max(numberOfPositionals(m_i)), $ |
1989 | 1989 |
1990 $r = min(numberOfRequiredParams(m_i)), i \in 1..k$. | 1990 $r = min(numberOfRequiredParams(m_i)), i \in 1..k$. |
1991 | 1991 |
1992 \LMHash{} | 1992 \LMHash{} |
1993 Then $I$ has a method named $n$, with $r$ required parameters of type \DYNAMIC{} , $h$ positional parameters of type \DYNAMIC{}, named parameters $s$ of type \ DYNAMIC{} and return type \DYNAMIC{}. | 1993 Then $I$ has a method named $n$, with $r$ required parameters of type \DYNAMIC{} , $h$ positional parameters of type \DYNAMIC{}, named parameters $s$ of type \ DYNAMIC{} and return type \DYNAMIC{}. |
1994 | 1994 |
1995 | 1995 |
1996 | 1996 |
1997 \commentary{The only situation where the runtime would be concerned with this wo uld be during reflection, if a mirror attempted to obtain the signature of an in terface member. | 1997 \commentary{The only situation where the runtime would be concerned with this wo uld be during reflection, if a mirror attempted to obtain the signature of an in terface member. |
1998 } | 1998 } |
1999 | 1999 |
2000 \rationale{ | 2000 \rationale{ |
2001 The current solution is a tad complex, but is robust in the face of type annotat ion changes. Alternatives: (a) No member is inherited in case of conflict. (b) The first m is selected (based on order of superinterface list) (c) Inherited me mber chosen at random. | 2001 The current solution is a tad complex, but is robust in the face of type annotat ion changes. Alternatives: (a) No member is inherited in case of conflict. (b) The first m is selected (based on order of superinterface list) (c) Inherited me mber chosen at random. |
2002 | 2002 |
2003 (a) means that the presence of an inherited member of an interface varies depend ing on type signatures. (b) is sensitive to irrelevant details of the declarati on and (c) is liable to give unpredictable results between implementations or ev en between different compilation sessions. | 2003 (a) means that the presence of an inherited member of an interface varies depend ing on type signatures. (b) is sensitive to irrelevant details of the declarati on and (c) is liable to give unpredictable results between implementations or ev en between different compilation sessions. |
2004 } | 2004 } |
2005 | 2005 |
2006 % Need warnings if overrider conflicts with overriddee either because signatures are incompatible or because done is a method and one is a getter or setter. | 2006 % Need warnings if overrider conflicts with overriddee either because signatures are incompatible or because done is a method and one is a getter or setter. |
2007 | 2007 |
2008 \section{Mixins} | 2008 \section{Mixins} |
2009 \LMLabel{mixins} | 2009 \LMLabel{mixins} |
2010 | 2010 |
2011 | 2011 |
2012 \LMHash{} | 2012 \LMHash{} |
2013 A mixin describes the difference between a class and its superclass. A mixin is always derived from an existing class declaration. | 2013 A mixin describes the difference between a class and its superclass. A mixin is always derived from an existing class declaration. |
2014 | 2014 |
2015 \LMHash{} | 2015 \LMHash{} |
2016 It is a compile-time error if a declared or derived mixin explicitly declares a constructor. | 2016 It is a compile-time error if a declared or derived mixin explicitly declares a constructor which is not a factory constructor. |
2017 | 2017 |
2018 \rationale{ | 2018 \rationale{ |
2019 This restriction is temporary. We expect to remove it in later versions of Dart . | 2019 This restriction is temporary. We expect to remove it in later versions of Dart . |
2020 | 2020 |
2021 The restriction on constructors simplifies the construction of mixin application s because the process of creating instances is simpler. | 2021 The restriction on constructors simplifies the construction of mixin application s because the process of creating instances is simpler. |
2022 } | 2022 } |
2023 | 2023 |
2024 \subsection{Mixin Application} | 2024 \subsection{Mixin Application} |
2025 \LMLabel{mixinApplication} | 2025 \LMLabel{mixinApplication} |
2026 | 2026 |
2027 \LMHash{} | 2027 \LMHash{} |
2028 A mixin may be applied to a superclass, yielding a new class. Mixin application occurs when a mixin is mixed into a class declaration via its \WITH{} clause. T he mixin application may be used to extend a class per section (\ref{classes}); alternately, a class may be defined as a mixin application as described in this section. It is a compile-time error if the \WITH{} clause of a mixin applicati on $C$ includes a deferred type expression. | 2028 A mixin may be applied to a superclass, yielding a new class. Mixin application occurs when a mixin is mixed into a class declaration via its \WITH{} clause. T he mixin application may be used to extend a class per section (\ref{classes}); alternately, a class may be defined as a mixin application as described in this section. It is a compile-time error if the \WITH{} clause of a mixin applicati on $C$ includes a deferred type expression. |
2029 | 2029 |
2030 | 2030 |
2031 \begin{grammar} | 2031 \begin{grammar} |
2032 {\bf mixinApplicationClass:} | 2032 {\bf mixinApplicationClass:} |
2033 identifier typeParameters? `=' mixinApplication `{\escapegrammar ;}' . | 2033 identifier typeParameters? `=' mixinApplication `{\escapegrammar ;}' . |
2034 » | 2034 |
2035 {\bf mixinApplication:} | 2035 {\bf mixinApplication:} |
2036 type mixins interfaces? | 2036 type mixins interfaces? |
2037 . | 2037 . |
2038 \end{grammar} | 2038 \end{grammar} |
2039 | 2039 |
2040 \LMHash{} | 2040 \LMHash{} |
2041 A mixin application of the form \code{$S$ \WITH{} $M$;} defines a class $C$ w ith superclass $S$. | 2041 A mixin application of the form \code{$S$ \WITH{} $M$;} defines a class $C$ w ith superclass $S$. |
2042 | 2042 |
2043 \LMHash{} | 2043 \LMHash{} |
2044 A mixin application of the form \code{$S$ \WITH{} $M_1, \ldots, M_k$;} defines a class $C$ whose superclass is the application of the mixin composition (\ref {mixinComposition}) $M_{k-1} * \ldots * M_1$ to $S$. | 2044 A mixin application of the form \code{$S$ \WITH{} $M_1, \ldots, M_k$;} defines a class $C$ whose superclass is the application of the mixin composition (\ref {mixinComposition}) $M_{k-1} * \ldots * M_1$ to $S$. |
2045 | 2045 |
2046 \LMHash{} | 2046 \LMHash{} |
2047 In both cases above, $C$ declares the same instance members as $M$ (respectively , $M_k$). If any of the instance fields of $M$ (respectively, $M_k$) have initia lizers, they are executed in the scope of $M$ (respectively, $M_k$) to initializ e the corresponding fields of $C$. | 2047 In both cases above, $C$ declares the same instance members as $M$ (respectively , $M_k$). If any of the instance fields of $M$ (respectively, $M_k$) have initia lizers, they are executed in the scope of $M$ (respectively, $M_k$) to initializ e the corresponding fields of $C$. |
2048 | 2048 |
2049 \LMHash{} | 2049 \LMHash{} |
2050 Let $L_M$ be the library in which $M$ is declared. | 2050 Let $L_M$ be the library in which $M$ is declared. |
2051 For each generative constructor named $q_i(T_{i1}$ $ a_{i1}, \ldots , T_{ik_i}$ $ a_{ik_i}), i \in 1..n$ of $S$ that is accessible to $L_M$, $C$ has an implicit ly declared constructor named | 2051 For each generative constructor named $q_i(T_{i1}$ $ a_{i1}, \ldots , T_{ik_i}$ $ a_{ik_i}), i \in 1..n$ of $S$ that is accessible to $L_M$, $C$ has an implicit ly declared constructor named |
2052 $q'_i = [C/S]q_i$ of the form | 2052 $q'_i = [C/S]q_i$ of the form |
2053 | 2053 |
2054 $q'_i(a_{i1}, \ldots , a_{ik_i}):\SUPER(a_{i1}, \ldots , a_{ik_i});$. | 2054 $q'_i(a_{i1}, \ldots , a_{ik_i}):\SUPER(a_{i1}, \ldots , a_{ik_i});$. |
2055 | 2055 |
2056 %super.id | 2056 %super.id |
2057 | 2057 |
2058 \LMHash{} | 2058 \LMHash{} |
2059 If the mixin application declares support for interfaces, the resulting class im plements those interfaces. | 2059 If the mixin application declares support for interfaces, the resulting class im plements those interfaces. |
2060 | 2060 |
2061 \LMHash{} | 2061 \LMHash{} |
2062 It is a compile-time error if $S$ is an enumerated type (\ref{enums}) or a malfo rmed type. It is a compile-time error if $M$ (respectively, any of $M_1, \ldots, M_k$) is an enumerated type (\ref{enums}) or a malformed type. It is a compile time error if a well formed mixin cannot be derived from $M$ (respectively, from each of $M_1, \ldots, M_k$). | 2062 It is a compile-time error if $S$ is an enumerated type (\ref{enums}) or a malfo rmed type. It is a compile-time error if $M$ (respectively, any of $M_1, \ldots, M_k$) is an enumerated type (\ref{enums}) or a malformed type. It is a compile time error if a well formed mixin cannot be derived from $M$ (respectively, from each of $M_1, \ldots, M_k$). |
2063 | 2063 |
2064 \LMHash{} | 2064 \LMHash{} |
2065 Let $K$ be a class declaration with the same constructors, superclass and inter faces as $C$, and the instance members declared by $M$ (respectively $M_1, \ldo ts, M_k$). It is a static warning if the declaration of $K$ would cause a static warning. It is a compile-time error if the declaration of $K$ would cause a co mpile-time error. | 2065 Let $K$ be a class declaration with the same constructors, superclass and inter faces as $C$, and the instance members declared by $M$ (respectively $M_1, \ldo ts, M_k$). It is a static warning if the declaration of $K$ would cause a static warning. It is a compile-time error if the declaration of $K$ would cause a co mpile-time error. |
2066 | 2066 |
2067 \commentary{ | 2067 \commentary{ |
2068 If, for example, $M$ declares an instance member $im$ whose type is at odds with the type of a member of the same name in $S$, this will result in a static warn ing just as if we had defined $K$ by means of an ordinary class declaration exte nding $S$, with a body that included $im$. | 2068 If, for example, $M$ declares an instance member $im$ whose type is at odds with the type of a member of the same name in $S$, this will result in a static warn ing just as if we had defined $K$ by means of an ordinary class declaration exte nding $S$, with a body that included $im$. |
2069 | 2069 |
2070 } | 2070 } |
2071 | 2071 |
2072 \LMHash{} | 2072 \LMHash{} |
2073 The effect of a class definition of the form \code{\CLASS{} $C$ = $M$; } or the form | 2073 The effect of a class definition of the form \code{\CLASS{} $C$ = $M$; } or the form |
2074 \code{\CLASS{} $C<T_1, \ldots, T_n>$ = $M$; } in library $L$ is to introduce t he name $C$ into the scope of $L$, bound to the class (\ref{classes}) defined by the mixin application $M$. The name of the class is also set to $C$. Iff the c lass is prefixed by the built-in identifier \ABSTRACT{}, the class being defined is an abstract class. | 2074 \code{\CLASS{} $C<T_1, \ldots, T_n>$ = $M$; } in library $L$ is to introduce t he name $C$ into the scope of $L$, bound to the class (\ref{classes}) defined by the mixin application $M$. The name of the class is also set to $C$. Iff the c lass is prefixed by the built-in identifier \ABSTRACT{}, the class being defined is an abstract class. |
2075 | 2075 |
2076 Let $M_A$ be a mixin derived from a class $M$ with direct superclass $S_{static }$. | 2076 Let $M_A$ be a mixin derived from a class $M$ with direct superclass $S_{static }$. |
2077 | 2077 |
2078 Let $A$ be an application of $M_A$. It is a static warning if the superclass of $A$ is not a subtype of $S_{static}$. | 2078 Let $A$ be an application of $M_A$. It is a static warning if the superclass of $A$ is not a subtype of $S_{static}$. |
2079 | 2079 |
2080 Let $C$ be a class declaration that includes $M_A$ in a with clause. It is a sta tic warning if $C$ does not implement, directly or indirectly, all the direct su perinterfaces of $M$. | 2080 Let $C$ be a class declaration that includes $M_A$ in a with clause. It is a sta tic warning if $C$ does not implement, directly or indirectly, all the direct su perinterfaces of $M$. |
2081 | 2081 |
2082 | 2082 |
2083 \subsection{Mixin Composition} | 2083 \subsection{Mixin Composition} |
2084 \LMLabel{mixinComposition} | 2084 \LMLabel{mixinComposition} |
2085 | 2085 |
2086 \rationale{ | 2086 \rationale{ |
2087 Dart does not directly support mixin composition, but the concept is useful when defining how the superclass of a class with a mixin clause is created. | 2087 Dart does not directly support mixin composition, but the concept is useful when defining how the superclass of a class with a mixin clause is created. |
2088 } | 2088 } |
2089 | 2089 |
2090 \LMHash{} | 2090 \LMHash{} |
2091 The {\em composition of two mixins}, $M_1<T_1 \ldots T_{k_{M_1}}>$ and $M_2<U_1 \ldots U_{k_{M_2}}>$, written $M_1<T_1 \ldots T_{k_{M_1}}> * M_2<U_1 \ldots U_ {k_{M_2}}>$ defines an anonymous mixin such that for any class $S<V_1 \ldots V_{ k_S}>$, the application of | 2091 The {\em composition of two mixins}, $M_1<T_1 \ldots T_{k_{M_1}}>$ and $M_2<U_1 \ldots U_{k_{M_2}}>$, written $M_1<T_1 \ldots T_{k_{M_1}}> * M_2<U_1 \ldots U_ {k_{M_2}}>$ defines an anonymous mixin such that for any class $S<V_1 \ldots V_{ k_S}>$, the application of |
2092 | 2092 |
2093 $M_1<T_1 \ldots T_{k_{M_1}}> * M_2<U_1 \ldots U_{k_{M_2}}>$ | 2093 $M_1<T_1 \ldots T_{k_{M_1}}> * M_2<U_1 \ldots U_{k_{M_2}}>$ |
2094 | 2094 |
2095 to $S<V_1 \ldots V_{k_S}>$ is equivalent to | 2095 to $S<V_1 \ldots V_{k_S}>$ is equivalent to |
2096 | 2096 |
2097 \begin{dartCode} | 2097 \begin{dartCode} |
2098 \ABSTRACT{} \CLASS{} $Id_1<T_1 \ldots T_{k_{M_1}}, U_1 \ldots U_{k_{M_2}}, V_1 \ldots V_{k_S}> = $ | 2098 \ABSTRACT{} \CLASS{} $Id_1<T_1 \ldots T_{k_{M_1}}, U_1 \ldots U_{k_{M_2}}, V_1 \ldots V_{k_S}> = $ |
2099 $Id_2<U_1 \ldots U_{k_{M_2}}, V_1 \ldots V_{k_S}>$ \WITH{} $M_1 <T_1 \l dots T_{k_{M_1}}>$; | 2099 $Id_2<U_1 \ldots U_{k_{M_2}}, V_1 \ldots V_{k_S}>$ \WITH{} $M_1 <T_1 \l dots T_{k_{M_1}}>$; |
2100 \end{dartCode} | 2100 \end{dartCode} |
2101 | 2101 |
2102 where $Id_2$ denotes | 2102 where $Id_2$ denotes |
2103 | 2103 |
2104 \begin{dartCode} | 2104 \begin{dartCode} |
2105 \ABSTRACT{} \CLASS{} $Id_2<U_1 \ldots U_{k_{M_2}}, V_1 \ldots V_{k_S}> =$ | 2105 \ABSTRACT{} \CLASS{} $Id_2<U_1 \ldots U_{k_{M_2}}, V_1 \ldots V_{k_S}> =$ |
2106 $S<V_1 \ldots V_{k_S}>$ \WITH{} $M_2<U_1 \ldots U_{k_{ M_2}}>$; | 2106 $S<V_1 \ldots V_{k_S}>$ \WITH{} $M_2<U_1 \ldots U_{k_{ M_2}}>$; |
2107 \end{dartCode} | 2107 \end{dartCode} |
2108 | 2108 |
2109 and $Id_1$ and $Id_2$ are unique identifiers that do not exist anywhere in the p rogram. | 2109 and $Id_1$ and $Id_2$ are unique identifiers that do not exist anywhere in the p rogram. |
2110 | 2110 |
2111 \rationale{ | 2111 \rationale{ |
2112 The classes produced by mixin composition are regarded as abstract because they cannot be instantiated independently. They are only introduced as anonymous supe rclasses of ordinary class declarations and mixin applications. Consequently, no warning is given if a mixin composition includes abstract members, or incomplet ely implements an interface. | 2112 The classes produced by mixin composition are regarded as abstract because they cannot be instantiated independently. They are only introduced as anonymous supe rclasses of ordinary class declarations and mixin applications. Consequently, no warning is given if a mixin composition includes abstract members, or incomplet ely implements an interface. |
2113 } | 2113 } |
2114 | 2114 |
2115 \LMHash{} | 2115 \LMHash{} |
2116 Mixin composition is associative. | 2116 Mixin composition is associative. |
2117 | 2117 |
2118 | 2118 |
2119 \commentary{ | 2119 \commentary{ |
(...skipping 30 matching lines...) Expand all Loading... | |
2150 \end{dartCode} | 2150 \end{dartCode} |
2151 | 2151 |
2152 \commentary { | 2152 \commentary { |
2153 It is also a compile-time error to subclass, mix-in or implement an enum or to e xplicitly instantiate an enum. These restrictions are given in normative form i n sections \ref{superclasses}, \ref{superinterfaces}, \ref{mixinApplication} and \ref{instanceCreation} as appropriate. | 2153 It is also a compile-time error to subclass, mix-in or implement an enum or to e xplicitly instantiate an enum. These restrictions are given in normative form i n sections \ref{superclasses}, \ref{superinterfaces}, \ref{mixinApplication} and \ref{instanceCreation} as appropriate. |
2154 } | 2154 } |
2155 | 2155 |
2156 \section{Generics} | 2156 \section{Generics} |
2157 \LMLabel{generics} | 2157 \LMLabel{generics} |
2158 | 2158 |
2159 \LMHash{} | 2159 \LMHash{} |
2160 A class declaration (\ref{classes}) or type alias (\ref{typedef}) | 2160 A class declaration (\ref{classes}) or type alias (\ref{typedef}) |
2161 $G$ may be {\em generic}, that is, $G$ may have formal type parameters declared. A generic declaration induces a family of declarations, one for each set of act ual type parameters provided in the program. | 2161 $G$ may be {\em generic}, that is, $G$ may have formal type parameters declared. A generic declaration induces a family of declarations, one for each set of act ual type parameters provided in the program. |
2162 | 2162 |
2163 \begin{grammar} | 2163 \begin{grammar} |
2164 {\bf typeParameter:} | 2164 {\bf typeParameter:} |
2165 metadata identifier (\EXTENDS{} type)? | 2165 metadata identifier (\EXTENDS{} type)? |
2166 . | 2166 . |
2167 {\bf typeParameters:} | 2167 {\bf typeParameters:} |
2168 `<' typeParameter (`,' typeParameter)* `>' | 2168 `<' typeParameter (`,' typeParameter)* `>' |
2169 . | 2169 . |
2170 \end{grammar} | 2170 \end{grammar} |
2171 | 2171 |
2172 \LMHash{} | 2172 \LMHash{} |
2173 A type parameter $T$ may be suffixed with an \EXTENDS{} clause that specifies th e {\em upper bound} for $T$. If no \EXTENDS{} clause is present, the upper boun d is \code{Object}. It is a static type warning if a type parameter is a supert ype of its upper bound. The bounds of type variables are a form of type annotati on and have no effect on execution in production mode. | 2173 A type parameter $T$ may be suffixed with an \EXTENDS{} clause that specifies th e {\em upper bound} for $T$. If no \EXTENDS{} clause is present, the upper boun d is \code{Object}. It is a static type warning if a type parameter is a supert ype of its upper bound. The bounds of type variables are a form of type annotati on and have no effect on execution in production mode. |
2174 | 2174 |
2175 \LMHash{} | 2175 \LMHash{} |
2176 Type parameters are declared in the type-parameter scope of a class. | 2176 Type parameters are declared in the type-parameter scope of a class. |
2177 The type parameters of a generic $G$ are in scope in the bounds of all of the ty pe parameters of $G$. The type parameters of a generic class declaration $G$ are also in scope in the \EXTENDS{} and \IMPLEMENTS{} clauses of $G$ (if these exis t) and in the body of $G$. However, a type parameter is considered to be a mal formed type when referenced by a static member. | 2177 The type parameters of a generic $G$ are in scope in the bounds of all of the ty pe parameters of $G$. The type parameters of a generic class declaration $G$ are also in scope in the \EXTENDS{} and \IMPLEMENTS{} clauses of $G$ (if these exis t) and in the body of $G$. However, a type parameter is considered to be a mal formed type when referenced by a static member. |
2178 | 2178 |
2179 \rationale{ | 2179 \rationale{ |
2180 The restriction is necessary since a type variable has no meaning in the context of a static member, because statics are shared among all instantiations of a ge neric. However, a type variable may be referenced from an instance initializer, even though \THIS{} is not available. | 2180 The restriction is necessary since a type variable has no meaning in the context of a static member, because statics are shared among all instantiations of a ge neric. However, a type variable may be referenced from an instance initializer, even though \THIS{} is not available. |
2181 } | 2181 } |
2182 | 2182 |
2183 \commentary{ | 2183 \commentary{ |
2184 Because type parameters are in scope in their bounds, we support F-bounded quant ification (if you don't know what that is, don't ask). This enables typechecking code such as: | 2184 Because type parameters are in scope in their bounds, we support F-bounded quant ification (if you don't know what that is, don't ask). This enables typechecking code such as: |
2185 } | 2185 } |
2186 | 2186 |
2187 \begin{dartCode} | 2187 \begin{dartCode} |
2188 \INTERFACE{} Ordered$<$T$>$ \{ | 2188 \INTERFACE{} Ordered$<$T$>$ \{ |
2189 operator $>$ (T x); | 2189 operator $>$ (T x); |
2190 \} | 2190 \} |
2191 | 2191 |
2192 \CLASS{} Sorter$<$T \EXTENDS{} Ordered$<$T$>>$ \{ | 2192 \CLASS{} Sorter$<$T \EXTENDS{} Ordered$<$T$>>$ \{ |
2193 sort(List$<$T$>$ l) {... l[n] $<$ l[n+1] ...} | 2193 sort(List$<$T$>$ l) {... l[n] $<$ l[n+1] ...} |
2194 \} | 2194 \} |
2195 | 2195 |
2196 \end{dartCode} | 2196 \end{dartCode} |
2197 | 2197 |
2198 \commentary{ | 2198 \commentary{ |
2199 Even where type parameters are in scope there are numerous restrictions at this time: | 2199 Even where type parameters are in scope there are numerous restrictions at this time: |
2200 \begin{itemize} | 2200 \begin{itemize} |
2201 \item A type parameter cannot be used to name a constructor in an instance creat ion expression (\ref{instanceCreation}). | 2201 \item A type parameter cannot be used to name a constructor in an instance creat ion expression (\ref{instanceCreation}). |
2202 \item A type parameter cannot be used as a superclass or superinterface (\ref{su perclasses}, \ref{superinterfaces}, \ref{interfaceSuperinterfaces}). | 2202 \item A type parameter cannot be used as a superclass or superinterface (\ref{su perclasses}, \ref{superinterfaces}, \ref{interfaceSuperinterfaces}). |
2203 \item A type parameter cannot be used as a generic type. | 2203 \item A type parameter cannot be used as a generic type. |
2204 \end{itemize} | 2204 \end{itemize} |
2205 | 2205 |
2206 The normative versions of these are given in the appropriate sections of this s pecification. Some of these restrictions may be lifted in the future. | 2206 The normative versions of these are given in the appropriate sections of this s pecification. Some of these restrictions may be lifted in the future. |
2207 } | 2207 } |
2208 | 2208 |
2209 %The {\em induced type set}, $S$, of a parameterized type $T$ is the set consist ing of | 2209 %The {\em induced type set}, $S$, of a parameterized type $T$ is the set consist ing of |
2210 %\begin{itemize} | 2210 %\begin{itemize} |
2211 %\item The supertypes of any type in $S$. | 2211 %\item The supertypes of any type in $S$. |
2212 %\item The type arguments of any parameterized type in $S$. | 2212 %\item The type arguments of any parameterized type in $S$. |
2213 %\end{itemize} | 2213 %\end{itemize} |
2214 | 2214 |
2215 %Let $P$ be the instantiation of a generic type with its own type parameters. It is a compile-time error if the induced type set of $P$ is not finite. | 2215 %Let $P$ be the instantiation of a generic type with its own type parameters. It is a compile-time error if the induced type set of $P$ is not finite. |
2216 | 2216 |
2217 %\rationale {A typical recursive type declaration such as} | 2217 %\rationale {A typical recursive type declaration such as} |
2218 | 2218 |
2219 %\begin{dartCode} | 2219 %\begin{dartCode} |
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
2257 %classInterfaceInjection: | 2257 %classInterfaceInjection: |
2258 %class qualified typeParameters? interfaces '{\escapegrammar ;}' | 2258 %class qualified typeParameters? interfaces '{\escapegrammar ;}' |
2259 % . | 2259 % . |
2260 | 2260 |
2261 | 2261 |
2262 %interfaceInterfaceInjection: | 2262 %interfaceInterfaceInjection: |
2263 %interface qualified typeParameters? superinterfaces '{\escapegrammar ;}' | 2263 %interface qualified typeParameters? superinterfaces '{\escapegrammar ;}' |
2264 %. | 2264 %. |
2265 %\end{grammar} | 2265 %\end{grammar} |
2266 | 2266 |
2267 %\rationale{Since subinterface relations can be tested dynamically via \IS{}, in terface injection is not just a directive to the static checker. The dynamic rel ations implied must hold regardless of whether a static typecheck has succeeded , or has been performed at all. This makes sense from the perspective of preserv ing programmer intent. The injection describes a nominal type relation that the programmer wishes to hold. Just as a supertype mentioned within a class declarat ion is considered a supertype even though type errors might arise among (say) ov erridden and overriding methods, so it must be that the relation implied by an i njection holds regardless of type errors. | 2267 %\rationale{Since subinterface relations can be tested dynamically via \IS{}, in terface injection is not just a directive to the static checker. The dynamic rel ations implied must hold regardless of whether a static typecheck has succeeded , or has been performed at all. This makes sense from the perspective of preserv ing programmer intent. The injection describes a nominal type relation that the programmer wishes to hold. Just as a supertype mentioned within a class declarat ion is considered a supertype even though type errors might arise among (say) ov erridden and overriding methods, so it must be that the relation implied by an i njection holds regardless of type errors. |
2268 %In addition, this decision helps to produce meaningful and localized error mess ages. Any errors are reported at the point of injection rather than at program p oints that rely on the relation (a well known problem with structural subtyping in OO systems). | 2268 %In addition, this decision helps to produce meaningful and localized error mess ages. Any errors are reported at the point of injection rather than at program p oints that rely on the relation (a well known problem with structural subtyping in OO systems). |
2269 %} | 2269 %} |
2270 | 2270 |
2271 %\Q{When does an interface injection take effect? When the containing library is loaded? | 2271 %\Q{When does an interface injection take effect? When the containing library is loaded? |
2272 %What is the scope of such a declaration? Is it global, or only in the scope of the containing library? The scope of such a declaration is global. | 2272 %What is the scope of such a declaration? Is it global, or only in the scope of the containing library? The scope of such a declaration is global. |
2273 %An injection must be at top level. Who has the right to inject an interface $I$ into another class $C$? Anybody? But since this affects dynamic behavior, is th is a weird security issue? | 2273 %An injection must be at top level. Who has the right to inject an interface $I$ into another class $C$? Anybody? But since this affects dynamic behavior, is th is a weird security issue? |
2274 %The current theory is that there is no security within an isolate, and one can never refer to a type from another isolate, so supposedly not an issue. This ass umption (no mutually suspicious code in the same isolate) is suspect but it seem s there is nothing to be done at this point. | 2274 %The current theory is that there is no security within an isolate, and one can never refer to a type from another isolate, so supposedly not an issue. This ass umption (no mutually suspicious code in the same isolate) is suspect but it seem s there is nothing to be done at this point. |
2275 %If libs are first class, they get created dynamically in order, and new libs mi ght modify the type relations among other libs types - but then it is clear when that happened and order is ok. | 2275 %If libs are first class, they get created dynamically in order, and new libs mi ght modify the type relations among other libs types - but then it is clear when that happened and order is ok. |
2276 %} | 2276 %} |
2277 | 2277 |
2278 %It is a compile-time error if a type $T$ appears more than once in the implemen ts or eextends clause of an interface injection. | 2278 %It is a compile-time error if a type $T$ appears more than once in the implemen ts or eextends clause of an interface injection. |
2279 | 2279 |
2280 | 2280 |
2281 \section{Metadata} | 2281 \section{Metadata} |
2282 \LMLabel{metadata} | 2282 \LMLabel{metadata} |
2283 | 2283 |
2284 \LMHash{} | 2284 \LMHash{} |
2285 Dart supports metadata which is used to attach user defined annotations to progr am structures. | 2285 Dart supports metadata which is used to attach user defined annotations to progr am structures. |
2286 | 2286 |
2287 \begin{grammar} | 2287 \begin{grammar} |
2288 {\bf metadata:} | 2288 {\bf metadata:} |
2289 (`@' qualified ({\escapegrammar `.'} identifier)? (arguments)?)* | 2289 (`@' qualified ({\escapegrammar `.'} identifier)? (arguments)?)* |
2290 . | 2290 . |
2291 \end{grammar} | 2291 \end{grammar} |
2292 | 2292 |
2293 \LMHash{} | 2293 \LMHash{} |
2294 Metadata consists of a series of annotations, each of which begin with the chara cter @, followed by a constant expression that starts with an identifier. It is a compile time error if the expression is not one of the following: | 2294 Metadata consists of a series of annotations, each of which begin with the chara cter @, followed by a constant expression that starts with an identifier. It is a compile time error if the expression is not one of the following: |
2295 \begin{itemize} | 2295 \begin{itemize} |
(...skipping 13 matching lines...) Expand all Loading... | |
2309 } | 2309 } |
2310 | 2310 |
2311 \commentary{ | 2311 \commentary{ |
2312 It is possible to associate metadata with constructs that may not be accessible via reflection, such as local variables (though it is conceivable that in the fu ture, richer reflective libraries might provide access to these as well). This is not as useless as it might seem. As noted above, the data can be retrieved st atically if source code is available. | 2312 It is possible to associate metadata with constructs that may not be accessible via reflection, such as local variables (though it is conceivable that in the fu ture, richer reflective libraries might provide access to these as well). This is not as useless as it might seem. As noted above, the data can be retrieved st atically if source code is available. |
2313 } | 2313 } |
2314 | 2314 |
2315 \LMHash{} | 2315 \LMHash{} |
2316 Metadata can appear before a library, part header, class, typedef, type paramete r, constructor, factory, function, field, parameter, or variable declaration and before an import, export or part directive. | 2316 Metadata can appear before a library, part header, class, typedef, type paramete r, constructor, factory, function, field, parameter, or variable declaration and before an import, export or part directive. |
2317 | 2317 |
2318 \LMHash{} | 2318 \LMHash{} |
2319 The constant expression given in an annotation is type checked and evaluated in the scope surrounding the declaration being annotated. | 2319 The constant expression given in an annotation is type checked and evaluated in the scope surrounding the declaration being annotated. |
2320 | 2320 |
2321 | 2321 |
2322 \section{Expressions} | 2322 \section{Expressions} |
2323 \LMLabel{expressions} | 2323 \LMLabel{expressions} |
2324 | 2324 |
2325 \LMHash{} | 2325 \LMHash{} |
2326 An {\em expression} is a fragment of Dart code that can be evaluated at run time to yield a {\em value}, which is always an object. Every expression has an asso ciated static type (\ref{staticTypes}). Every value has an associated dynamic ty pe (\ref{dynamicTypeSystem}). | 2326 An {\em expression} is a fragment of Dart code that can be evaluated at run time to yield a {\em value}, which is always an object. Every expression has an asso ciated static type (\ref{staticTypes}). Every value has an associated dynamic ty pe (\ref{dynamicTypeSystem}). |
2327 | 2327 |
2328 | 2328 |
2329 \begin{grammar} | 2329 \begin{grammar} |
2330 | 2330 |
2331 {\bf expression:}assignableExpression assignmentOperator expression; | 2331 {\bf expression:}assignableExpression assignmentOperator expression; |
2332 conditionalExpression cascadeSection*; | 2332 conditionalExpression cascadeSection*; |
2333 throwExpression | 2333 throwExpression |
2334 . | 2334 . |
2335 | 2335 |
2336 | 2336 |
2337 {\bf expressionWithoutCascade:}assignableExpression assignmentOperator expressio nWithoutCascade; | 2337 {\bf expressionWithoutCascade:}assignableExpression assignmentOperator expressio nWithoutCascade; |
2338 conditionalExpression; | 2338 conditionalExpression; |
2339 throwExpressionWithoutCascade | 2339 throwExpressionWithoutCascade |
2340 . | 2340 . |
2341 | 2341 |
2342 {\bf expressionList:} | 2342 {\bf expressionList:} |
2343 expression (`,' expression)* %should these be top level expressions? | 2343 expression (`,' expression)* %should these be top level expressions? |
2344 . | 2344 . |
2345 \end{grammar} | 2345 \end{grammar} |
2346 | 2346 |
2347 \begin{grammar} | 2347 \begin{grammar} |
2348 {\bf primary:}thisExpression; | 2348 {\bf primary:}thisExpression; |
2349 \SUPER{} unconditionalAssignableSelector; | 2349 \SUPER{} unconditionalAssignableSelector; |
2350 functionExpression; | 2350 functionExpression; |
2351 literal; | 2351 literal; |
2352 identifier; | 2352 identifier; |
2353 newExpression; | 2353 newExpression; |
2354 \NEW{} type `\#' (`{\escapegrammar .}' identifier)?; | 2354 \NEW{} type `\#' (`{\escapegrammar .}' identifier)?; |
2355 constObjectExpression; | 2355 constObjectExpression; |
2356 `(' expression `)' | 2356 `(' expression `)' |
2357 . | 2357 . |
2358 | 2358 |
2359 \end{grammar} | 2359 \end{grammar} |
2360 | 2360 |
2361 \LMHash{} | 2361 \LMHash{} |
2362 An expression $e$ may always be enclosed in parentheses, but this never has any semantic effect on $e$. | 2362 An expression $e$ may always be enclosed in parentheses, but this never has any semantic effect on $e$. |
2363 | 2363 |
2364 \commentary{ | 2364 \commentary{ |
2365 Sadly, it may have an effect on the surrounding expression. Given a class $C$ wi th static method $m => 42$, $C.m()$ returns 42, but $(C).m()$ produces a \code{N oSuchMethodError}. This anomaly can be corrected by removing the restrictions o n calling the members of instances of \code{Type}. This issue may be addressed i n future versions of Dart. | 2365 Sadly, it may have an effect on the surrounding expression. Given a class $C$ wi th static method $m => 42$, $C.m()$ returns 42, but $(C).m()$ produces a \code{N oSuchMethodError}. This anomaly can be corrected by removing the restrictions o n calling the members of instances of \code{Type}. This issue may be addressed i n future versions of Dart. |
2366 } | 2366 } |
2367 | 2367 |
2368 \subsubsection{Object Identity} | 2368 \subsubsection{Object Identity} |
2369 \LMLabel{objectIdentity} | 2369 \LMLabel{objectIdentity} |
2370 | 2370 |
2371 \LMHash{} | 2371 \LMHash{} |
2372 The predefined Dart function \cd{identical()} is defined such that \code{identic al($c_1$, $c_2$)} iff: | 2372 The predefined Dart function \cd{identical()} is defined such that \code{identic al($c_1$, $c_2$)} iff: |
2373 \begin{itemize} | 2373 \begin{itemize} |
2374 \item $c_1$ evaluates to either \NULL{} or an instance of \code{bool} and \co de{$c_1$ == $c_2$}, OR | 2374 \item $c_1$ evaluates to either \NULL{} or an instance of \code{bool} and \co de{$c_1$ == $c_2$}, OR |
2375 \item $c_1$ and $c_2$ are instances of \code{int} and \code{$c_1$ == $c_2$}, OR | 2375 \item $c_1$ and $c_2$ are instances of \code{int} and \code{$c_1$ == $c_2$}, OR |
2376 \item $c_1$ and $c_2$ are constant strings and \code{$c_1$ == $c_2$}, OR | 2376 \item $c_1$ and $c_2$ are constant strings and \code{$c_1$ == $c_2$}, OR |
2377 \item $c_1$ and $c_2$ are instances of \cd{double} and one of the following holds: | 2377 \item $c_1$ and $c_2$ are instances of \cd{double} and one of the following holds: |
2378 \begin{itemize} | 2378 \begin{itemize} |
2379 \item $c_1$ and $c_2$ are non-zero and \code{$c_1$ == $c_2$}. | 2379 \item $c_1$ and $c_2$ are non-zero and \code{$c_1$ == $c_2$}. |
2380 \item Both $c_1$ and $c_2$ are $+0.0$. | 2380 \item Both $c_1$ and $c_2$ are $+0.0$. |
2381 \item Both $c_1$ and $c_2$ are $-0.0$. | 2381 \item Both $c_1$ and $c_2$ are $-0.0$. |
2382 \item Both $c_1$ and $c_2$ represent a NaN value with the same underlying bit pattern. | 2382 \item Both $c_1$ and $c_2$ represent a NaN value with the same underlying bit pattern. |
2383 \end{itemize} | 2383 \end{itemize} |
2384 OR | 2384 OR |
2385 \item $c_1$ and $c_2$ are constant lists that are defined to be identical in th e specification of literal list expressions (\ref{lists}), OR | 2385 \item $c_1$ and $c_2$ are constant lists that are defined to be identical in th e specification of literal list expressions (\ref{lists}), OR |
2386 \item $c_1$ and $c_2$ are constant maps that are defined to be identical in the specification of literal map expressions (\ref{maps}), OR | 2386 \item $c_1$ and $c_2$ are constant maps that are defined to be identical in the specification of literal map expressions (\ref{maps}), OR |
2387 \item $c_1$ and $c_2$ are constant objects of the same class $C$ and each membe r field of $c_1$ is identical to the corresponding field of $c_2$. OR | 2387 \item $c_1$ and $c_2$ are constant objects of the same class $C$ and each membe r field of $c_1$ is identical to the corresponding field of $c_2$. OR |
2388 \item $c_1$ and $c_2$ are the same object. | 2388 \item $c_1$ and $c_2$ are the same object. |
2389 \end{itemize} | 2389 \end{itemize} |
2390 | 2390 |
2391 \commentary{ | 2391 \commentary{ |
2392 The definition of \cd{identity} for doubles differs from that of equality in tha t a NaN is identical to itself, and that negative and positive zero are distinct . | 2392 The definition of \cd{identity} for doubles differs from that of equality in tha t a NaN is identical to itself, and that negative and positive zero are distinct . |
2393 } | 2393 } |
2394 | 2394 |
2395 \rationale{ | 2395 \rationale{ |
2396 The definition of equality for doubles is dictated by the IEEE 754 standard, whi ch posits that NaNs do not obey the law of reflexivity. Given that hardware imp lements these rules, it is necessary to support them for reasons of efficiency. | 2396 The definition of equality for doubles is dictated by the IEEE 754 standard, whi ch posits that NaNs do not obey the law of reflexivity. Given that hardware imp lements these rules, it is necessary to support them for reasons of efficiency. |
2397 | 2397 |
2398 The definition of identity is not constrained in the same way. Instead, it assum es that bit-identical doubles are identical. | 2398 The definition of identity is not constrained in the same way. Instead, it assum es that bit-identical doubles are identical. |
2399 | 2399 |
2400 The rules for identity make it impossible for a Dart programmer to observe wheth er a boolean or numerical value is boxed or unboxed. | 2400 The rules for identity make it impossible for a Dart programmer to observe wheth er a boolean or numerical value is boxed or unboxed. |
2401 } | 2401 } |
2402 | 2402 |
2403 | 2403 |
2404 \subsection{Constants} | 2404 \subsection{Constants} |
2405 \LMLabel{constants} | 2405 \LMLabel{constants} |
2406 | 2406 |
2407 \LMHash{} | 2407 \LMHash{} |
2408 A {\em constant expression} is an expression whose value can never change, and t hat can be evaluated entirely at compile time. | 2408 A {\em constant expression} is an expression whose value can never change, and t hat can be evaluated entirely at compile time. |
2409 | 2409 |
2410 \LMHash{} | 2410 \LMHash{} |
2411 A constant expression is one of the following: | 2411 A constant expression is one of the following: |
2412 \begin{itemize} | 2412 \begin{itemize} |
2413 \item A literal number (\ref{numbers}). | 2413 \item A literal number (\ref{numbers}). |
2414 \item A literal boolean (\ref{booleans}). | 2414 \item A literal boolean (\ref{booleans}). |
2415 \item A literal string (\ref{strings}) where any interpolated expression (\ref{ stringInterpolation}) is a compile-time constant that evaluates to a numeric, st ring or boolean value or to \NULL{}. | 2415 \item A literal string (\ref{strings}) where any interpolated expression (\ref{ stringInterpolation}) is a compile-time constant that evaluates to a numeric, st ring or boolean value or to \NULL{}. |
2416 \rationale{It would be tempting to allow string interpolation where the interpol ated value is any compile-time constant. However, this would require running th e \code{toString()} method for constant objects, which could contain arbitrary c ode.} | 2416 \rationale{It would be tempting to allow string interpolation where the interpol ated value is any compile-time constant. However, this would require running th e \code{toString()} method for constant objects, which could contain arbitrary c ode.} |
2417 \item A literal symbol (\ref{symbols}). | 2417 \item A literal symbol (\ref{symbols}). |
2418 \item \NULL{} (\ref{null}). | 2418 \item \NULL{} (\ref{null}). |
2419 \item A qualified reference to a static constant variable (\ref{variables}) that is not qualified by a deferred prefix. | 2419 \item A qualified reference to a static constant variable (\ref{variables}) that is not qualified by a deferred prefix. |
2420 \commentary {For example, If class C declares a constant static variable v, C.v is a constant. The same is true if C is accessed via a prefix p; p.C.v is a cons tant unless p is a deferred prefix. | 2420 \commentary {For example, If class C declares a constant static variable v, C.v is a constant. The same is true if C is accessed via a prefix p; p.C.v is a cons tant unless p is a deferred prefix. |
2421 } | 2421 } |
2422 \item An identifier expression that denotes a constant variable. | 2422 \item An identifier expression that denotes a constant variable. |
2423 \item A simple or qualified identifier denoting a class or type alias that is no t qualified by a deferred prefix. | 2423 \item A simple or qualified identifier denoting a class or type alias that is no t qualified by a deferred prefix. |
2424 \commentary {For example, If C is a class or typedef, C is a constant, and if C is imported with a prefix p, p.C is a constant unless p is a deferred prefix. | 2424 \commentary {For example, If C is a class or typedef, C is a constant, and if C is imported with a prefix p, p.C is a constant unless p is a deferred prefix. |
2425 } | 2425 } |
2426 \item A constant constructor invocation (\ref{const}) that is not qualified by a deferred prefix. | 2426 \item A constant constructor invocation (\ref{const}) that is not qualified by a deferred prefix. |
2427 \item A constant list literal (\ref{lists}). | 2427 \item A constant list literal (\ref{lists}). |
2428 \item A constant map literal (\ref{maps}). | 2428 \item A constant map literal (\ref{maps}). |
2429 \item A simple or qualified identifier denoting a top-level function (\ref{funct ions}) or a static method (\ref{staticMethods}) that is not qualified by a defer red prefix. | 2429 \item A simple or qualified identifier denoting a top-level function (\ref{funct ions}) or a static method (\ref{staticMethods}) that is not qualified by a defer red prefix. |
2430 \item A parenthesized expression \code{($e$)} where $e$ is a constant expression . | 2430 \item A parenthesized expression \code{($e$)} where $e$ is a constant expression . |
2431 \item An expression of the form \code{identical($e_1$, $e_2$)} where $e_1$ and $ e_2$ are constant expressions and \code{identical()} is statically bound to the predefined dart function \code{identical()} discussed above (\ref{objectIdent ity}). | 2431 \item An expression of the form \code{identical($e_1$, $e_2$)} where $e_1$ and $ e_2$ are constant expressions and \code{identical()} is statically bound to the predefined dart function \code{identical()} discussed above (\ref{objectIdent ity}). |
2432 \item An expression of one of the forms \code{$e_1$ == $e_2$} or \code{$e_1$ ! = $e_2$} where $e_1$ and $e_2$ are constant expressions that evaluate to a numer ic, string or boolean value or to \NULL{}. | 2432 \item An expression of one of the forms \code{$e_1$ == $e_2$} or \code{$e_1$ ! = $e_2$} where $e_1$ and $e_2$ are constant expressions that evaluate to a numer ic, string or boolean value or to \NULL{}. |
2433 \item An expression of one of the forms \code{!$e$}, \code{$e_1$ \&\& $e_2$} or \code{$e_1 || e_2$}, where $e$, $e_1$ and $e_2$ are constant expressions that e valuate to a boolean value. | 2433 \item An expression of one of the forms \code{!$e$}, \code{$e_1$ \&\& $e_2$} or \code{$e_1 || e_2$}, where $e$, $e_1$ and $e_2$ are constant expressions that e valuate to a boolean value. |
2434 \item An expression of one of the forms \~{}$e$, $e_1$ \^{} $e_2$, \code{$e_1$ \ & $e_2$}, $e_1 | e_2$, $e_1 >> e_2$ or $e_1 << e_2$, where $e$, $e_1$ and $e_2 $ are constant expressions that evaluate to an integer value or to \NULL{}. | 2434 \item An expression of one of the forms \~{}$e$, $e_1$ \^{} $e_2$, \code{$e_1$ \ & $e_2$}, $e_1 | e_2$, $e_1 >> e_2$ or $e_1 << e_2$, where $e$, $e_1$ and $e_2 $ are constant expressions that evaluate to an integer value or to \NULL{}. |
2435 \item An expression of the form \code{$e_1 + e_2$} where $e_1$ and $e_2$ are con stant expressions that evaluate to a numeric or string value or to \NULL{}. | 2435 \item An expression of the form \code{$e_1 + e_2$} where $e_1$ and $e_2$ are con stant expressions that evaluate to a numeric or string value or to \NULL{}. |
2436 \item An expression of one of the forms \code{$-e$}, \code{$e_1$ - $e_2$}, \code {$e_1$ * $e_2$}, \code{$e_1$ / $e_2$,} \code{$e_1$ \~{}/ $e_2$}, \code{$e_1 > e_2$}, \code{$e_1 < e_2$}, \code{$e_1$ $>$= $e_2$}, \code{$e_1$ $<$= $e_2$} o r \code{$e_1$ \% $e_2$}, where $e$, $e_1$ and $e_2$ are constant expressions th at evaluate to a numeric value or to \NULL{}. | 2436 \item An expression of one of the forms \code{$-e$}, \code{$e_1$ - $e_2$}, \code {$e_1$ * $e_2$}, \code{$e_1$ / $e_2$,} \code{$e_1$ \~{}/ $e_2$}, \code{$e_1 > e_2$}, \code{$e_1 < e_2$}, \code{$e_1$ $>$= $e_2$}, \code{$e_1$ $<$= $e_2$} o r \code{$e_1$ \% $e_2$}, where $e$, $e_1$ and $e_2$ are constant expressions th at evaluate to a numeric value or to \NULL{}. |
2437 \item An expression of the form \code{$e_1$?$e_2$:$e3$} where $e_1$, $e_2$ and $ e_3$ are constant expressions and $e_1$ evaluates to a boolean value. | 2437 \item An expression of the form \code{$e_1$?$e_2$:$e3$} where $e_1$, $e_2$ and $ e_3$ are constant expressions and $e_1$ evaluates to a boolean value. |
2438 \item An expression of the form \code{$e_1 ?? e_2$} where $e_1$ and $e_2$ are co nstant expressions. | 2438 \item An expression of the form \code{$e_1 ?? e_2$} where $e_1$ and $e_2$ are co nstant expressions. |
2439 \item An expression of the form \code{$e$.length} where $e$ is a constant expres sion that evaluates to a string value. | 2439 \item An expression of the form \code{$e$.length} where $e$ is a constant expres sion that evaluates to a string value. |
2440 \end{itemize} | 2440 \end{itemize} |
2441 | 2441 |
2442 % null in all the expressions | 2442 % null in all the expressions |
2443 | 2443 |
2444 % designed so constants do not depend on check diode being on or not. | 2444 % designed so constants do not depend on check diode being on or not. |
2445 | 2445 |
2446 \LMHash{} | 2446 \LMHash{} |
2447 It is a compile-time error if an expression is required to be a constant express ion but its evaluation would raise an exception. | 2447 It is a compile-time error if an expression is required to be a constant express ion but its evaluation would raise an exception. |
2448 | 2448 |
2449 % so, checked mode? analyzers? editor/development compilers? | 2449 % so, checked mode? analyzers? editor/development compilers? |
2450 \commentary{ | 2450 \commentary{ |
2451 Note that there is no requirement that every constant expression evaluate correc tly. Only when a constant expression is required (e.g., to initialize a constant variable, or as a default value of a formal parameter, or as metadata) do we in sist that a constant expression actually be evaluated successfully at compile ti me. | 2451 Note that there is no requirement that every constant expression evaluate correc tly. Only when a constant expression is required (e.g., to initialize a constant variable, or as a default value of a formal parameter, or as metadata) do we in sist that a constant expression actually be evaluated successfully at compile ti me. |
2452 | 2452 |
2453 The above is not dependent on program control-flow. The mere presence of a requi red compile time constant whose evaluation would fail within a program is an err or. This also holds recursively: since compound constants are composed out of c onstants, if any subpart of a constant would raise an exception when evaluated, that is an error. | 2453 The above is not dependent on program control-flow. The mere presence of a requi red compile time constant whose evaluation would fail within a program is an err or. This also holds recursively: since compound constants are composed out of c onstants, if any subpart of a constant would raise an exception when evaluated, that is an error. |
2454 | 2454 |
2455 On the other hand, since implementations are free to compile code late, some com pile-time errors may manifest quite late. | 2455 On the other hand, since implementations are free to compile code late, some com pile-time errors may manifest quite late. |
2456 } | 2456 } |
2457 | 2457 |
2458 \begin{dartCode} | 2458 \begin{dartCode} |
2459 \CONST{} x = 1/0; | 2459 \CONST{} x = 1/0; |
2460 \FINAL{} y = 1/0; | 2460 \FINAL{} y = 1/0; |
2461 | 2461 |
2462 \CLASS{} K \{ | 2462 \CLASS{} K \{ |
2463 m1() \{ | 2463 m1() \{ |
2464 \VAR{} z = \FALSE{}; | 2464 \VAR{} z = \FALSE{}; |
2465 \IF{} (z) \{\RETURN{} x; \} | 2465 \IF{} (z) \{\RETURN{} x; \} |
2466 \ELSE{} \{ \RETURN{} 2;\} | 2466 \ELSE{} \{ \RETURN{} 2;\} |
2467 \} | 2467 \} |
2468 | 2468 |
2469 m2() \{ | 2469 m2() \{ |
2470 \IF{} (\TRUE{}) \{\RETURN{} y; \} | 2470 \IF{} (\TRUE{}) \{\RETURN{} y; \} |
2471 \ELSE{} \{ \RETURN{} 3;\} | 2471 \ELSE{} \{ \RETURN{} 3;\} |
2472 \} | 2472 \} |
2473 \} | 2473 \} |
2474 \end{dartCode} | 2474 \end{dartCode} |
2475 | 2475 |
2476 \commentary{An implementation is free to immediately issue a compilation error f or \code{x}, but it is not required to do so. It could defer errors if it does not immediately compile the declarations that reference \code{x}. For example, it could delay giving a compilation error about the method \code{m1} until the f irst invocation of \code{m1}. However, it could not choose to execute \code{m1}, see that the branch that refers to \code{x} is not taken and return 2 successf ully. | 2476 \commentary{An implementation is free to immediately issue a compilation error f or \code{x}, but it is not required to do so. It could defer errors if it does not immediately compile the declarations that reference \code{x}. For example, it could delay giving a compilation error about the method \code{m1} until the f irst invocation of \code{m1}. However, it could not choose to execute \code{m1}, see that the branch that refers to \code{x} is not taken and return 2 successf ully. |
2477 | 2477 |
2478 The situation with respect to an invocation \code{m2} is different. Because \cod e{y} is not a compile-time constant (even though its value is), one need not giv e a compile-time error upon compiling \code{m2}. An implementation may run the c ode, which will cause the getter for \code{y} to be invoked. At that point, the initialization of \code{y} must take place, which requires the initializer to b e compiled, which will cause a compilation error. | 2478 The situation with respect to an invocation \code{m2} is different. Because \cod e{y} is not a compile-time constant (even though its value is), one need not giv e a compile-time error upon compiling \code{m2}. An implementation may run the c ode, which will cause the getter for \code{y} to be invoked. At that point, the initialization of \code{y} must take place, which requires the initializer to b e compiled, which will cause a compilation error. |
2479 } | 2479 } |
2480 | 2480 |
2481 \rationale{ | 2481 \rationale{ |
2482 The treatment of \NULL{} merits some discussion. Consider \code{\NULL{} + 2}. T his expression always causes an error. We could have chosen not to treat it as a constant expression (and in general, not to allow \NULL{} as a subexpression of numeric or boolean constant expressions). There are two arguments for includin g it: | 2482 The treatment of \NULL{} merits some discussion. Consider \code{\NULL{} + 2}. T his expression always causes an error. We could have chosen not to treat it as a constant expression (and in general, not to allow \NULL{} as a subexpression of numeric or boolean constant expressions). There are two arguments for includin g it: |
2483 \begin{enumerate} | 2483 \begin{enumerate} |
2484 \item It is constant. We can evaluate it at compile-time. | 2484 \item It is constant. We can evaluate it at compile-time. |
2485 \item It seems more useful to give the error stemming from the evaluation explic itly. | 2485 \item It seems more useful to give the error stemming from the evaluation explic itly. |
2486 \end{enumerate} | 2486 \end{enumerate} |
2487 } | 2487 } |
2488 | 2488 |
2489 \rationale { | |
2490 One might reasonably ask why $e_1? e_1: e_3$ and $e_1?? e_2$ have constant forms . For example, if $e_1$ is known statically, why do we need to test it?. | |
2491 The answer is that there are contexts where $e_1$ is a variable. In particular, constant constructor initializers such as | |
floitsch
2016/06/22 14:57:17
This sentence feels incomplete.
| |
2492 | |
2493 \code{\CONST{} C(foo) : \THIS.foo = foo ?? someDefaultValue;} | |
2494 } | |
2495 | |
2496 | |
2489 \LMHash{} | 2497 \LMHash{} |
2490 It is a compile-time error if the value of a compile-time constant expression de pends on itself. | 2498 It is a compile-time error if the value of a compile-time constant expression de pends on itself. |
2491 | 2499 |
2492 \commentary{ | 2500 \commentary{ |
2493 As an example, consider: | 2501 As an example, consider: |
2494 } | 2502 } |
2495 | 2503 |
2496 \begin{dartCode} | 2504 \begin{dartCode} |
2497 \CLASS{} CircularConsts\{ | 2505 \CLASS{} CircularConsts\{ |
2498 // Illegal program - mutually recursive compile-time constants | 2506 // Illegal program - mutually recursive compile-time constants |
2499 \STATIC{} \CONST{} i = j; // a compile-time constant | 2507 \STATIC{} \CONST{} i = j; // a compile-time constant |
2500 \STATIC{} \CONST{} j = i; // a compile-time constant | 2508 \STATIC{} \CONST{} j = i; // a compile-time constant |
2501 \} | 2509 \} |
2502 \end{dartCode} | 2510 \end{dartCode} |
2503 | 2511 |
2504 | 2512 |
2505 \begin{grammar} | 2513 \begin{grammar} |
2506 {\bf literal:}nullLiteral; | 2514 {\bf literal:}nullLiteral; |
2507 booleanLiteral; | 2515 booleanLiteral; |
(...skipping 14 matching lines...) Expand all Loading... | |
2522 The reserved word \NULL{} denotes the {\em null object}. | 2530 The reserved word \NULL{} denotes the {\em null object}. |
2523 %\Q{Any methods, such as \code{isNull}?} | 2531 %\Q{Any methods, such as \code{isNull}?} |
2524 | 2532 |
2525 \begin{grammar} | 2533 \begin{grammar} |
2526 {\bf nullLiteral:} | 2534 {\bf nullLiteral:} |
2527 \NULL{} | 2535 \NULL{} |
2528 . | 2536 . |
2529 \end{grammar} | 2537 \end{grammar} |
2530 | 2538 |
2531 \LMHash{} | 2539 \LMHash{} |
2532 The null object is the sole instance of the built-in class \code{Null}. Attempti ng to instantiate \code{Null} causes a run-time error. It is a compile-time erro r for a class to attempt to extend, mix in or implement \code{Null}. | 2540 The null object is the sole instance of the built-in class \code{Null}. Attempti ng to instantiate \code{Null} causes a run-time error. It is a compile-time erro r for a class to attempt to extend, mix in or implement \code{Null}. |
2533 Invoking a method on \NULL{} yields a \code{NoSuchMethodError} unless the metho d is explicitly implemented by class \code{Null}. | 2541 Invoking a method on \NULL{} yields a \code{NoSuchMethodError} unless the metho d is explicitly implemented by class \code{Null}. |
2534 | 2542 |
2535 \LMHash{} | 2543 \LMHash{} |
2536 The static type of \NULL{} is $\bot$. | 2544 The static type of \NULL{} is $\bot$. |
2537 | 2545 |
2538 \rationale{The decision to use $\bot$ instead of \code{Null} allows \NULL{} to b e be assigned everywhere without complaint by the static checker. | 2546 \rationale{The decision to use $\bot$ instead of \code{Null} allows \NULL{} to b e be assigned everywhere without complaint by the static checker. |
2539 } | 2547 } |
2540 | 2548 |
2541 | 2549 |
2542 \subsection{Numbers} | 2550 \subsection{Numbers} |
2543 \LMLabel{numbers} | 2551 \LMLabel{numbers} |
2544 | 2552 |
2545 \LMHash{} | 2553 \LMHash{} |
2546 A {\em numeric literal} is either a decimal or hexadecimal integer of arbitrary size, or a decimal double. | 2554 A {\em numeric literal} is either a decimal or hexadecimal integer of arbitrary size, or a decimal double. |
2547 | 2555 |
2548 \begin{grammar} | 2556 \begin{grammar} |
2549 {\bf numericLiteral:}NUMBER; | 2557 {\bf numericLiteral:}NUMBER; |
2550 HEX\_NUMBER | 2558 HEX\_NUMBER |
2551 . | 2559 . |
2552 | 2560 |
2553 {\bf NUMBER:} DIGIT+ (`{\escapegrammar.}' DIGIT+)? EXPONENT?; | 2561 {\bf NUMBER:} DIGIT+ (`{\escapegrammar.}' DIGIT+)? EXPONENT?; |
2554 {`\escapegrammar .}' DIGIT+ EXPONENT? | 2562 {`\escapegrammar .}' DIGIT+ EXPONENT? |
2555 . | 2563 . |
2556 | 2564 |
2557 {\bf EXPONENT:} | 2565 {\bf EXPONENT:} |
2558 (`e' $|$ `E') ('+' $|$ `-`)? DIGIT+ | 2566 (`e' $|$ `E') ('+' $|$ `-`)? DIGIT+ |
2559 . | 2567 . |
2560 | 2568 |
2561 {\bf HEX\_NUMBER:}`0x' HEX\_DIGIT+; | 2569 {\bf HEX\_NUMBER:}`0x' HEX\_DIGIT+; |
2562 `0X' HEX\_DIGIT+ | 2570 `0X' HEX\_DIGIT+ |
2563 . | 2571 . |
2564 | 2572 |
2565 {\bf HEX\_DIGIT:}`a'{\escapegrammar ..}'f'; | 2573 {\bf HEX\_DIGIT:}`a'{\escapegrammar ..}'f'; |
2566 `A'{\escapegrammar ..}'F'; | 2574 `A'{\escapegrammar ..}'F'; |
2567 DIGIT | 2575 DIGIT |
2568 . | 2576 . |
2569 \end{grammar} | 2577 \end{grammar} |
2570 | 2578 |
2571 \LMHash{} | 2579 \LMHash{} |
2572 If a numeric literal begins with the prefix `0x' or `0X', it denotes the hexadec imal integer represented by the part of the literal following `0x' (respectively `0X'). Otherwise, if the numeric literal does not include a decimal point it d enotes a decimal integer. Otherwise, the numeric literal denotes a 64 bit doub le precision floating point number as specified by the IEEE 754 standard. | 2580 If a numeric literal begins with the prefix `0x' or `0X', it denotes the hexadec imal integer represented by the part of the literal following `0x' (respectively `0X'). Otherwise, if the numeric literal does not include a decimal point it d enotes a decimal integer. Otherwise, the numeric literal denotes a 64 bit doub le precision floating point number as specified by the IEEE 754 standard. |
2573 | 2581 |
2574 \LMHash{} | 2582 \LMHash{} |
2575 In principle, the range of integers supported by a Dart implementations is unlim ited. In practice, it is limited by available memory. Implementations may also b e limited by other considerations. | 2583 In principle, the range of integers supported by a Dart implementations is unlim ited. In practice, it is limited by available memory. Implementations may also b e limited by other considerations. |
2576 | 2584 |
2577 \commentary{ | 2585 \commentary{ |
2578 For example, implementations may choose to limit the range to facilitate efficie nt compilation to Javascript. These limitations should be relaxed as soon as tec hnologically feasible. | 2586 For example, implementations may choose to limit the range to facilitate efficie nt compilation to Javascript. These limitations should be relaxed as soon as tec hnologically feasible. |
2579 } | 2587 } |
2580 | 2588 |
2581 \LMHash{} | 2589 \LMHash{} |
2582 It is a compile-time error for a class to attempt to extend, mix in or implement \code{int}. It is a compile-time error for a class to attempt to extend, mix in or implement \code{double}. It is a compile-time error for any type other than the types \code{int} and \code{double} to attempt to extend, mix in or implement \code{num}. | 2590 It is a compile-time error for a class to attempt to extend, mix in or implement \code{int}. It is a compile-time error for a class to attempt to extend, mix in or implement \code{double}. It is a compile-time error for any type other than the types \code{int} and \code{double} to attempt to extend, mix in or implement \code{num}. |
2583 | 2591 |
2584 \LMHash{} | 2592 \LMHash{} |
2585 An {\em integer literal} is either a hexadecimal integer literal or a decimal i nteger literal. Invoking the getter \code{runtimeType} on an integer literal ret urns the \code{Type} object that is the value of the expression \code{int}. The static type of an integer literal is \code{int}. | 2593 An {\em integer literal} is either a hexadecimal integer literal or a decimal i nteger literal. Invoking the getter \code{runtimeType} on an integer literal ret urns the \code{Type} object that is the value of the expression \code{int}. The static type of an integer literal is \code{int}. |
2586 | 2594 |
2587 \LMHash{} | 2595 \LMHash{} |
2588 A {\em literal double} is a numeric literal that is not an integer literal. Invo king the getter \code{runtimeType} on a literal double returns the \code{Type} o bject that is the value of the expression \code{double}. | 2596 A {\em literal double} is a numeric literal that is not an integer literal. Invo king the getter \code{runtimeType} on a literal double returns the \code{Type} o bject that is the value of the expression \code{double}. |
2589 The static type of a literal double is \code{double}. | 2597 The static type of a literal double is \code{double}. |
2590 | 2598 |
2591 \subsection{Booleans} | 2599 \subsection{Booleans} |
2592 \LMLabel{booleans} | 2600 \LMLabel{booleans} |
2593 | 2601 |
2594 \LMHash{} | 2602 \LMHash{} |
2595 The reserved words \TRUE{} and \FALSE{} denote objects that represent the boolea n values true and false respectively. They are the {\em boolean literals}. | 2603 The reserved words \TRUE{} and \FALSE{} denote objects that represent the boolea n values true and false respectively. They are the {\em boolean literals}. |
2596 | 2604 |
2597 \begin{grammar} | 2605 \begin{grammar} |
2598 {\bf booleanLiteral:}\TRUE{}; | 2606 {\bf booleanLiteral:}\TRUE{}; |
2599 \FALSE{} | 2607 \FALSE{} |
2600 . | 2608 . |
2601 \end{grammar} | 2609 \end{grammar} |
2602 | 2610 |
2603 \LMHash{} | 2611 \LMHash{} |
2604 Both \TRUE{} and \FALSE{} implement the built-in class \code{bool}. It is a co mpile-time error for a class to attempt to extend, mix in or implement\code{ boo l}. | 2612 Both \TRUE{} and \FALSE{} implement the built-in class \code{bool}. It is a co mpile-time error for a class to attempt to extend, mix in or implement\code{ boo l}. |
2605 | 2613 |
2606 \commentary{ | 2614 \commentary{ |
2607 It follows that the two boolean literals are the only two instances of \code{boo l}. | 2615 It follows that the two boolean literals are the only two instances of \code{boo l}. |
2608 } | 2616 } |
2609 | 2617 |
2610 \LMHash{} | 2618 \LMHash{} |
2611 Invoking the getter \code{runtimeType} on a boolean literal returns the \code{Ty pe} object that is the value of the expression \code{bool}. The static type of a boolean literal is \code{bool}. | 2619 Invoking the getter \code{runtimeType} on a boolean literal returns the \code{Ty pe} object that is the value of the expression \code{bool}. The static type of a boolean literal is \code{bool}. |
2612 | 2620 |
2613 \subsubsection{Boolean Conversion} | 2621 \subsubsection{Boolean Conversion} |
2614 \LMLabel{booleanConversion} | 2622 \LMLabel{booleanConversion} |
2615 | 2623 |
2616 \LMHash{} | 2624 \LMHash{} |
2617 {\em Boolean conversion} maps any object $o$ into a boolean. Boolean conversion is defined by the function application | 2625 {\em Boolean conversion} maps any object $o$ into a boolean. Boolean conversion is defined by the function application |
2618 | 2626 |
2619 \begin{dartCode} | 2627 \begin{dartCode} |
2620 (bool v)\{ | 2628 (bool v)\{ |
2621 \ASSERT{}(v != \NULL{}); | 2629 \ASSERT{}(v != \NULL{}); |
2622 % \IF{} (\NULL{} == v) \{ \THROW{} \NEW{} AssertionError('null is not a bo ol')\}; | 2630 % \IF{} (\NULL{} == v) \{ \THROW{} \NEW{} AssertionError('null is not a bo ol')\}; |
2623 \RETURN{} identical(v, \TRUE{}); | 2631 \RETURN{} identical(v, \TRUE{}); |
2624 \}(o) | 2632 \}(o) |
2625 \end{dartCode} | 2633 \end{dartCode} |
2626 | 2634 |
2627 \rationale{ | 2635 \rationale{ |
2628 Boolean conversion is used as part of control-flow constructs and boolean expres sions. Ideally, one would simply insist that control-flow decisions be based ex clusively on booleans. This is straightforward in a statically typed setting. I n a dynamically typed language, it requires a dynamic check. Sophisticated virtu al machines can minimize the penalty involved. Alas, Dart must be compiled into Javascript. Boolean conversion allows this to be done efficiently. | 2636 Boolean conversion is used as part of control-flow constructs and boolean expres sions. Ideally, one would simply insist that control-flow decisions be based ex clusively on booleans. This is straightforward in a statically typed setting. I n a dynamically typed language, it requires a dynamic check. Sophisticated virtu al machines can minimize the penalty involved. Alas, Dart must be compiled into Javascript. Boolean conversion allows this to be done efficiently. |
2629 | 2637 |
2630 At the same time, this formulation differs radically from Javascript, where most numbers and objects are interpreted as \TRUE{}. Dart's approach prevents usage s such \code{\IF{} (a-b) ... ; }because it does not agree with the low level con ventions whereby non-null objects or non-zero numbers are treated as \TRUE{}. In deed, there is no way to derive \TRUE{} from a non-boolean object via boolean co nversion, so this kind of low level hackery is nipped in the bud. | 2638 At the same time, this formulation differs radically from Javascript, where most numbers and objects are interpreted as \TRUE{}. Dart's approach prevents usage s such \code{\IF{} (a-b) ... ; }because it does not agree with the low level con ventions whereby non-null objects or non-zero numbers are treated as \TRUE{}. In deed, there is no way to derive \TRUE{} from a non-boolean object via boolean co nversion, so this kind of low level hackery is nipped in the bud. |
2631 | 2639 |
2632 Dart also avoids the strange behaviors that can arise due to the interaction of boolean conversion with autoboxing in Javascript. A notorious example is the sit uation where \FALSE{} can be interpreted as \TRUE{}. In Javascript, booleans are not objects, and instead are autoboxed into objects where ``needed''. If \FALS E{} gets autoboxed into an object, that object can be coerced into \TRUE{} (as i t is a non-null object). | 2640 Dart also avoids the strange behaviors that can arise due to the interaction of boolean conversion with autoboxing in Javascript. A notorious example is the sit uation where \FALSE{} can be interpreted as \TRUE{}. In Javascript, booleans are not objects, and instead are autoboxed into objects where ``needed''. If \FALS E{} gets autoboxed into an object, that object can be coerced into \TRUE{} (as i t is a non-null object). |
2633 } | 2641 } |
2634 | 2642 |
2635 \commentary{Because boolean conversion requires its parameter to be a boolean, a ny construct that makes use of boolean conversion will cause a dynamic type erro r in checked mode if the value to be converted is not a boolean. | 2643 \commentary{Because boolean conversion requires its parameter to be a boolean, a ny construct that makes use of boolean conversion will cause a dynamic type erro r in checked mode if the value to be converted is not a boolean. |
2636 } | 2644 } |
2637 | 2645 |
2638 \subsection{Strings} | 2646 \subsection{Strings} |
2639 \LMLabel{strings} | 2647 \LMLabel{strings} |
2640 | 2648 |
2641 \LMHash{} | 2649 \LMHash{} |
2642 A {\em string} is a sequence of UTF-16 code units. | 2650 A {\em string} is a sequence of UTF-16 code units. |
2643 | 2651 |
2644 \rationale{ | 2652 \rationale{ |
2645 This decision was made for compatibility with web browsers and Javascript. Earli er versions of the specification required a string to be a sequence of valid Uni code code points. Programmers should not depend on this distinction. | 2653 This decision was made for compatibility with web browsers and Javascript. Earli er versions of the specification required a string to be a sequence of valid Uni code code points. Programmers should not depend on this distinction. |
2646 } | 2654 } |
2647 | 2655 |
2648 \begin{grammar} | 2656 \begin{grammar} |
2649 {\bf stringLiteral:}(multilineString $|$ singleLineString)+ | 2657 {\bf stringLiteral:}(multilineString $|$ singleLineString)+ |
2650 . | 2658 . |
2651 \end{grammar} | 2659 \end{grammar} |
2652 | 2660 |
2653 \LMHash{} | 2661 \LMHash{} |
2654 A string can be either a sequence of single line strings or a multiline string. | 2662 A string can be either a sequence of single line strings or a multiline string. |
2655 | 2663 |
2656 \begin{grammar} | 2664 \begin{grammar} |
2657 {\bf singleLineString:}`{\escapegrammar \code{"}}' stringContentDQ* `{\escapegr ammar \code{"}}'; | 2665 {\bf singleLineString:}`{\escapegrammar \code{"}}' stringContentDQ* `{\escapegr ammar \code{"}}'; |
2658 `{\escapegrammar \code{'}}' stringContentSQ* `{\escapegrammar \code{'}}'; | 2666 `{\escapegrammar \code{'}}' stringContentSQ* `{\escapegrammar \code{'}}'; |
2659 `r' `{\escapegrammar \code{'}}' (\~{}( `{\escapegrammar \code{'}}' $|$ NEW LINE ))* `{\escapegrammar \code{'}}'; | 2667 `r' `{\escapegrammar \code{'}}' (\~{}( `{\escapegrammar \code{'}}' $|$ NEW LINE ))* `{\escapegrammar \code{'}}'; |
2660 `r' `{\escapegrammar \code{"}}' (\~{}( `{\escapegrammar \code{"}}' $|$ NEW LINE ))* `{\escapegrammar \code{"}}' | 2668 `r' `{\escapegrammar \code{"}}' (\~{}( `{\escapegrammar \code{"}}' $|$ NEW LINE ))* `{\escapegrammar \code{"}}' |
2661 . | 2669 . |
2662 \end{grammar} | 2670 \end{grammar} |
2663 | 2671 |
2664 \LMHash{} | 2672 \LMHash{} |
2665 A single line string is delimited by either matching single quotes or matching d ouble quotes. | 2673 A single line string is delimited by either matching single quotes or matching d ouble quotes. |
2666 | 2674 |
2667 \commentary{ | 2675 \commentary{ |
2668 Hence, `abc' and ``abc'' are both legal strings, as are `He said ``To be or not to be'' did he not?' and ``He said `To be or not to be' didn't he''. However ` `This ` is not a valid string, nor is `this''. | 2676 Hence, `abc' and ``abc'' are both legal strings, as are `He said ``To be or not to be'' did he not?' and ``He said `To be or not to be' didn't he''. However ` `This ` is not a valid string, nor is `this''. |
2669 } | 2677 } |
2670 | 2678 |
2671 \commentary{The grammar ensures that a single line string cannot span more than one line of source code, unless it includes an interpolated expression that span s multiple lines. | 2679 \commentary{The grammar ensures that a single line string cannot span more than one line of source code, unless it includes an interpolated expression that span s multiple lines. |
2672 } | 2680 } |
2673 | 2681 |
2674 \LMHash{} | 2682 \LMHash{} |
2675 Adjacent | 2683 Adjacent |
2676 %single line | 2684 %single line |
2677 strings are implicitly concatenated to form a single string literal. | 2685 strings are implicitly concatenated to form a single string literal. |
2678 %, and so are adjacent multiline strings, but the two forms may not be mixed. | 2686 %, and so are adjacent multiline strings, but the two forms may not be mixed. |
2679 | 2687 |
2680 | 2688 |
2681 \commentary{Here is an example} | 2689 \commentary{Here is an example} |
2682 | 2690 |
2683 \begin{dartCode} | 2691 \begin{dartCode} |
2684 print("A string" "and then another"); // prints: A stringand then another | 2692 print("A string" "and then another"); // prints: A stringand then another |
2685 \end{dartCode} | 2693 \end{dartCode} |
2686 | 2694 |
2687 \rationale{Dart also supports the operator + for string concatenation. | 2695 \rationale{Dart also supports the operator + for string concatenation. |
2688 | 2696 |
2689 The + operator on Strings requires a String argument. It does not coerce its arg ument into a string. This helps avoid puzzlers such as | 2697 The + operator on Strings requires a String argument. It does not coerce its arg ument into a string. This helps avoid puzzlers such as |
2690 } | 2698 } |
2691 | 2699 |
2692 \begin{dartCode} | 2700 \begin{dartCode} |
2693 print("A simple sum: 2 + 2 = " + | 2701 print("A simple sum: 2 + 2 = " + |
2694 2 + 2); | 2702 2 + 2); |
2695 \end{dartCode} | 2703 \end{dartCode} |
2696 | 2704 |
2697 \rationale{ which this prints 'A simple sum: 2 + 2 = 22' rather than 'A simple sum: 2 + 2 = 4'. | 2705 \rationale{ which this prints 'A simple sum: 2 + 2 = 22' rather than 'A simple sum: 2 + 2 = 4'. |
(...skipping 20 matching lines...) Expand all Loading... | |
2718 | 2726 |
2719 | 2727 |
2720 | 2728 |
2721 | 2729 |
2722 \begin{grammar} | 2730 \begin{grammar} |
2723 {\bf multilineString:}`{\escapegrammar \texttt{"""}}' stringContentTDQ* `{\es capegrammar \texttt{"""}}'; | 2731 {\bf multilineString:}`{\escapegrammar \texttt{"""}}' stringContentTDQ* `{\es capegrammar \texttt{"""}}'; |
2724 `{\escapegrammar \code{'}\code{'}\code{'}}' stringContentTSQ* `{\escapegra mmar \code{'}\code{'}\code{'}}'; | 2732 `{\escapegrammar \code{'}\code{'}\code{'}}' stringContentTSQ* `{\escapegra mmar \code{'}\code{'}\code{'}}'; |
2725 `r' `{\escapegrammar \texttt{"""}}' (\~{} `{\escapegrammar \texttt{"""}}' )* `{\escapegrammar \texttt{"""}}'; | 2733 `r' `{\escapegrammar \texttt{"""}}' (\~{} `{\escapegrammar \texttt{"""}}' )* `{\escapegrammar \texttt{"""}}'; |
2726 `r' `{\escapegrammar \code{'}\code{'}\code{'}}' (\~{} `{\escapegrammar \co de{'}\code{'}\code{'}}')* `{\escapegrammar \code{'}\code{'}\code{'}}' | 2734 `r' `{\escapegrammar \code{'}\code{'}\code{'}}' (\~{} `{\escapegrammar \co de{'}\code{'}\code{'}}')* `{\escapegrammar \code{'}\code{'}\code{'}}' |
2727 . | 2735 . |
2728 | 2736 |
2729 | 2737 |
2730 {\bf ESCAPE\_SEQUENCE:} `$\backslash$ n'; | 2738 {\bf ESCAPE\_SEQUENCE:} `$\backslash$ n'; |
2731 `$\backslash$ r'; | 2739 `$\backslash$ r'; |
2732 `$\backslash$ f'; | 2740 `$\backslash$ f'; |
2733 `$\backslash$ b'; | 2741 `$\backslash$ b'; |
2734 `$\backslash$ t'; | 2742 `$\backslash$ t'; |
2735 `$\backslash$ v'; | 2743 `$\backslash$ v'; |
2736 `$\backslash$ x' HEX\_DIGIT HEX\_DIGIT; | 2744 `$\backslash$ x' HEX\_DIGIT HEX\_DIGIT; |
2737 `$\backslash$ u' HEX\_DIGIT HEX\_DIGIT HEX\_DIGIT HEX\_DIGIT; | 2745 `$\backslash$ u' HEX\_DIGIT HEX\_DIGIT HEX\_DIGIT HEX\_DIGIT; |
2738 `$\backslash$ u\{' HEX\_DIGIT\_SEQUENCE `\}' | 2746 `$\backslash$ u\{' HEX\_DIGIT\_SEQUENCE `\}' |
2739 . | 2747 . |
2740 | 2748 |
2741 {\bf HEX\_DIGIT\_SEQUENCE:} | 2749 {\bf HEX\_DIGIT\_SEQUENCE:} |
2742 HEX\_DIGIT HEX\_DIGIT? HEX\_DIGIT? HEX\_DIGIT? HEX\_DIGIT? HEX\_DIGIT? | 2750 HEX\_DIGIT HEX\_DIGIT? HEX\_DIGIT? HEX\_DIGIT? HEX\_DIGIT? HEX\_DIGIT? |
2743 . | 2751 . |
2744 | 2752 |
2745 \end{grammar} | 2753 \end{grammar} |
2746 | 2754 |
2747 \LMHash{} | 2755 \LMHash{} |
2748 Multiline strings are delimited by either matching triples of single quotes or m atching triples of double quotes. If the first line of a multiline string consis ts solely of the whitespace characters defined by the production {\em WHITESPACE } \ref{lexicalRules}), possibly prefixed by $\backslash$, then that line is ign ored, including the new line at its end. | 2756 Multiline strings are delimited by either matching triples of single quotes or m atching triples of double quotes. If the first line of a multiline string consis ts solely of the whitespace characters defined by the production {\em WHITESPACE } \ref{lexicalRules}), possibly prefixed by $\backslash$, then that line is ign ored, including the new line at its end. |
2749 | 2757 |
2750 | 2758 |
2751 \rationale{ | 2759 \rationale{ |
2752 The idea is to ignore whitespace, where whitespace is defined as tabs, spaces a nd newlines. These can be represented directly, but since for most characters pr efixing by backslash is an identity, we allow those forms as well. | 2760 The idea is to ignore whitespace, where whitespace is defined as tabs, spaces a nd newlines. These can be represented directly, but since for most characters pr efixing by backslash is an identity, we allow those forms as well. |
2753 } | 2761 } |
2754 | 2762 |
2755 % could be clearer. Is the first line in """\t | 2763 % could be clearer. Is the first line in """\t |
2756 % """ ignored not. It depends if we mean whitespace before escapes are inter preted, | 2764 % """ ignored not. It depends if we mean whitespace before escapes are inter preted, |
2757 % or after, or both. See https://code.google.com/p/dart/issues/detail?id=23020 | 2765 % or after, or both. See https://code.google.com/p/dart/issues/detail?id=23020 |
2758 | 2766 |
2759 \LMHash{} | 2767 \LMHash{} |
2760 Strings support escape sequences for special characters. The escapes are: | 2768 Strings support escape sequences for special characters. The escapes are: |
2761 \begin{itemize} | 2769 \begin{itemize} |
2762 \item $\backslash$n for newline, equivalent to $\backslash$x0A. | 2770 \item $\backslash$n for newline, equivalent to $\backslash$x0A. |
2763 \item $\backslash$r for carriage return, equivalent to $\backslash$x0D. | 2771 \item $\backslash$r for carriage return, equivalent to $\backslash$x0D. |
2764 \item $\backslash$f for form feed, equivalent to $\backslash$x0C. | 2772 \item $\backslash$f for form feed, equivalent to $\backslash$x0C. |
2765 \item $\backslash$b for backspace, equivalent to $\backslash$x08. | 2773 \item $\backslash$b for backspace, equivalent to $\backslash$x08. |
2766 \item $\backslash$t for tab, equivalent to $\backslash$x09. | 2774 \item $\backslash$t for tab, equivalent to $\backslash$x09. |
2767 \item $\backslash$v for vertical tab, equivalent to $\backslash$x0B | 2775 \item $\backslash$v for vertical tab, equivalent to $\backslash$x0B |
2768 \item $\backslash$x $HEX\_DIGIT_1$ $HEX\_DIGIT_2$, equivalent to | 2776 \item $\backslash$x $HEX\_DIGIT_1$ $HEX\_DIGIT_2$, equivalent to |
2769 | 2777 |
2770 $\backslash$u\{$HEX\_DIGIT_1$ $HEX\_DIGIT_2$\}. | 2778 $\backslash$u\{$HEX\_DIGIT_1$ $HEX\_DIGIT_2$\}. |
2771 \item $\backslash$u $HEX\_DIGIT_1$ $HEX\_DIGIT_2$ $HEX\_DIGIT_3$ $HEX\_DIGIT_4$, equivalent to $\backslash$u\{$HEX\_DIGIT_1$ $HEX\_DIGIT_2$ $HEX\_DIGIT_3$ $HEX\ _DIGIT_4$\}. | 2779 \item $\backslash$u $HEX\_DIGIT_1$ $HEX\_DIGIT_2$ $HEX\_DIGIT_3$ $HEX\_DIGIT_4$, equivalent to $\backslash$u\{$HEX\_DIGIT_1$ $HEX\_DIGIT_2$ $HEX\_DIGIT_3$ $HEX\ _DIGIT_4$\}. |
2772 \item $\backslash$u\{$HEX\_DIGIT\_SEQUENCE$\} is the unicode scalar value repres ented by the $HEX\_DIGIT\_SEQUENCE$. It is a compile-time error if the value of the $HEX\_DIGIT\_SEQUENCE$ is not a valid unicode scalar value. | 2780 \item $\backslash$u\{$HEX\_DIGIT\_SEQUENCE$\} is the unicode scalar value repres ented by the $HEX\_DIGIT\_SEQUENCE$. It is a compile-time error if the value of the $HEX\_DIGIT\_SEQUENCE$ is not a valid unicode scalar value. |
2773 \item \$ indicating the beginning of an interpolated expression. | 2781 \item \$ indicating the beginning of an interpolated expression. |
2774 \item Otherwise, $\backslash k$ indicates the character $k$ for any $k$ not in $ \{n, r, f, b, t, v, x, u\}$. | 2782 \item Otherwise, $\backslash k$ indicates the character $k$ for any $k$ not in $ \{n, r, f, b, t, v, x, u\}$. |
2775 \end{itemize} | 2783 \end{itemize} |
2776 | 2784 |
2777 \LMHash{} | 2785 \LMHash{} |
2778 Any string may be prefixed with the character `r', indicating that it is a {\em raw string}, in which case no escapes or interpolations are recognized. | 2786 Any string may be prefixed with the character `r', indicating that it is a {\em raw string}, in which case no escapes or interpolations are recognized. |
2779 | 2787 |
2780 \LMHash{} | 2788 \LMHash{} |
2781 It is a compile-time error if a non-raw string literal contains a character sequ ence of the form $\backslash$x that is not followed by a sequence of two hexadec imal digits. It is a compile-time error if a non-raw string literal contains a character sequence of the form $\backslash$u that is not followed by either a se quence of four hexadecimal digits, or by curly brace delimited sequence of hexad ecimal digits. | 2789 It is a compile-time error if a non-raw string literal contains a character sequ ence of the form $\backslash$x that is not followed by a sequence of two hexadec imal digits. It is a compile-time error if a non-raw string literal contains a character sequence of the form $\backslash$u that is not followed by either a se quence of four hexadecimal digits, or by curly brace delimited sequence of hexad ecimal digits. |
2782 | 2790 |
2783 | 2791 |
2784 | 2792 |
2785 \begin{grammar} | 2793 \begin{grammar} |
2786 {\bf stringContentDQ:}\~{}( `$\backslash$' $|$ `{\escapegrammar \texttt{"}}' $| $ `\$' $|$ NEWLINE ); | 2794 {\bf stringContentDQ:}\~{}( `$\backslash$' $|$ `{\escapegrammar \texttt{"}}' $| $ `\$' $|$ NEWLINE ); |
2787 `$\backslash$' \~{}( NEWLINE ); | 2795 `$\backslash$' \~{}( NEWLINE ); |
2788 stringInterpolation | 2796 stringInterpolation |
2789 . | 2797 . |
2790 | 2798 |
2791 {\bf stringContentSQ:}\~{}( `$\backslash$' $|$ `{\escapegrammar \texttt{'}}' $| $ `\$' $|$ NEWLINE ); | 2799 {\bf stringContentSQ:}\~{}( `$\backslash$' $|$ `{\escapegrammar \texttt{'}}' $| $ `\$' $|$ NEWLINE ); |
2792 `$\backslash$' \~{}( NEWLINE ); | 2800 `$\backslash$' \~{}( NEWLINE ); |
2793 stringInterpolation | 2801 stringInterpolation |
2794 . | 2802 . |
2795 | 2803 |
2796 | 2804 |
2797 {\bf stringContentTDQ:}\~{}( `$\backslash$' $|$ `{\escapegrammar \texttt{"""}} ' $|$ `\$'); | 2805 {\bf stringContentTDQ:}\~{}( `$\backslash$' $|$ `{\escapegrammar \texttt{"""}} ' $|$ `\$'); |
2798 stringInterpolation | 2806 stringInterpolation |
2799 . | 2807 . |
2800 | 2808 |
2801 {\bf stringContentTSQ:}\~{}( `$\backslash$' $|$ `{\escapegrammar \code{'}\code{ '}\code{'}}' $|$ `\$'); | 2809 {\bf stringContentTSQ:}\~{}( `$\backslash$' $|$ `{\escapegrammar \code{'}\code{ '}\code{'}}' $|$ `\$'); |
2802 stringInterpolation | 2810 stringInterpolation |
2803 . | 2811 . |
2804 | 2812 |
2805 {\bf NEWLINE:}$\backslash$ n; | 2813 {\bf NEWLINE:}$\backslash$ n; |
2806 $\backslash$ r | 2814 $\backslash$ r |
2807 . | 2815 . |
2808 | 2816 |
2809 \end{grammar} | 2817 \end{grammar} |
2810 | 2818 |
2811 \LMHash{} | 2819 \LMHash{} |
2812 All string literals implement the built-in class \code{String}. It is a compile- time error for a class to attempt to extend, mix in or implement \code{String}. Invoking the getter \code{runtimeType} on a string literal returns the \code{Typ e} object that is the value of the expression \code{String}. The static type of a string literal is \code{String}. | 2820 All string literals implement the built-in class \code{String}. It is a compile- time error for a class to attempt to extend, mix in or implement \code{String}. Invoking the getter \code{runtimeType} on a string literal returns the \code{Typ e} object that is the value of the expression \code{String}. The static type of a string literal is \code{String}. |
2813 | 2821 |
2814 \subsubsection{String Interpolation} | 2822 \subsubsection{String Interpolation} |
2815 \LMLabel{stringInterpolation} | 2823 \LMLabel{stringInterpolation} |
2816 | 2824 |
2817 \LMHash{} | 2825 \LMHash{} |
2818 It is possible to embed expressions within non-raw string literals, such that th ese expressions are evaluated, and the resulting values are converted into strin gs and concatenated with the enclosing string. This process is known as {\em str ing interpolation}. | 2826 It is possible to embed expressions within non-raw string literals, such that th ese expressions are evaluated, and the resulting values are converted into strin gs and concatenated with the enclosing string. This process is known as {\em str ing interpolation}. |
2819 | 2827 |
2820 \begin{grammar} | 2828 \begin{grammar} |
2821 {\bf stringInterpolation:}`\$' IDENTIFIER\_NO\_DOLLAR; | 2829 {\bf stringInterpolation:}`\$' IDENTIFIER\_NO\_DOLLAR; |
2822 `\$' `\{' expression `\}' % could be top level expression, no? | 2830 `\$' `\{' expression `\}' % could be top level expression, no? |
2823 . | 2831 . |
2824 \end{grammar} | 2832 \end{grammar} |
2825 | 2833 |
2826 \commentary{The reader will note that the expression inside the interpolation co uld itself include strings, which could again be interpolated recursively. | 2834 \commentary{The reader will note that the expression inside the interpolation co uld itself include strings, which could again be interpolated recursively. |
2827 } | 2835 } |
2828 | 2836 |
2829 \LMHash{} | 2837 \LMHash{} |
2830 An unescaped \$ character in a string signifies the beginning of an interpolated expression. The \$ sign may be followed by either: | 2838 An unescaped \$ character in a string signifies the beginning of an interpolated expression. The \$ sign may be followed by either: |
2831 \begin{itemize} | 2839 \begin{itemize} |
2832 \item A single identifier $id$ that must not contain the \$ character. | 2840 \item A single identifier $id$ that must not contain the \$ character. |
2833 \item An expression $e$ delimited by curly braces. | 2841 \item An expression $e$ delimited by curly braces. |
2834 \end{itemize} | 2842 \end{itemize} |
2835 | 2843 |
2836 \LMHash{} | 2844 \LMHash{} |
2837 The form \code{\$id} is equivalent to the form \code{\$\{id\}}. An interpolated string \code{`$s_1$\$\{$e$\}$s_2$'} is equivalent to the concatenation of the strings \code{`$s_1$'}, \code{$e$.toString()} and \code{$`s_2$'}. Likewise an interpolated string \code{``$s_1$\$\{e\}$s_2$''} is equivalent to the concatena tion of the strings \code{``$s_1$''}, \code{$e$.toString()} and \code{``$s_2$'' }. | 2845 The form \code{\$id} is equivalent to the form \code{\$\{id\}}. An interpolated string \code{`$s_1$\$\{$e$\}$s_2$'} is equivalent to the concatenation of the strings \code{`$s_1$'}, \code{$e$.toString()} and \code{$`s_2$'}. Likewise an interpolated string \code{``$s_1$\$\{e\}$s_2$''} is equivalent to the concatena tion of the strings \code{``$s_1$''}, \code{$e$.toString()} and \code{``$s_2$'' }. |
2838 | 2846 |
2839 \subsection{Symbols} | 2847 \subsection{Symbols} |
2840 \LMLabel{symbols} | 2848 \LMLabel{symbols} |
2841 | 2849 |
2842 \LMHash{} | 2850 \LMHash{} |
2843 A {\em symbol literal} denotes the name of a declaration in a Dart program. | 2851 A {\em symbol literal} denotes the name of a declaration in a Dart program. |
2844 | 2852 |
2845 \begin{grammar} | 2853 \begin{grammar} |
2846 {\bf symbolLiteral:} | 2854 {\bf symbolLiteral:} |
2847 `\#' (operator $|$ (identifier (`{\escapegrammar .}' identifier)*)) . | 2855 `\#' (operator $|$ (identifier (`{\escapegrammar .}' identifier)*)) . |
2848 \end{grammar} | 2856 \end{grammar} |
2849 | 2857 |
2850 \LMHash{} | 2858 \LMHash{} |
2851 A symbol literal \code{\#id} where \code{id} does not begin with an underscore ( '\code{\_}') is equivalent to the expression \code{\CONST{} Symbol('id')}. | 2859 A symbol literal \code{\#id} where \code{id} does not begin with an underscore ( '\code{\_}') is equivalent to the expression \code{\CONST{} Symbol('id')}. |
2852 | 2860 |
2853 \LMHash{} | 2861 \LMHash{} |
2854 A symbol literal \code{\#\_id} evaluates to the object that would be returned by the call \code{mirror.getPrivateSymbol('id')} where mirror is an instance of th e class \code{LibraryMirror} defined in the library \code{dart:mirrors}, reflect ing the current library. | 2862 A symbol literal \code{\#\_id} evaluates to the object that would be returned by the call \code{mirror.getPrivateSymbol('id')} where mirror is an instance of th e class \code{LibraryMirror} defined in the library \code{dart:mirrors}, reflect ing the current library. |
2855 | 2863 |
2856 \rationale{ | 2864 \rationale{ |
2857 One may well ask what is the motivation for introducing literal symbols? In some languages, symbols are canonicalized whereas strings are not. However literal s trings are already canonicalized in Dart. Symbols are slightly easier to type c ompared to strings and their use can become strangely addictive, but this is not nearly sufficient justification for adding a literal form to the language. The primary motivation is related to the use of reflection and a web specific practi ce known as minification. | 2865 One may well ask what is the motivation for introducing literal symbols? In some languages, symbols are canonicalized whereas strings are not. However literal s trings are already canonicalized in Dart. Symbols are slightly easier to type c ompared to strings and their use can become strangely addictive, but this is not nearly sufficient justification for adding a literal form to the language. The primary motivation is related to the use of reflection and a web specific practi ce known as minification. |
2858 | 2866 |
2859 Minification compresses identifiers consistently throughout a program in order t o reduce download size. This practice poses difficulties for reflective program s that refer to program declarations via strings. A string will refer to an iden tifier in the source, but the identifier will no longer be used in the minified code, and reflective code using these would fail. Therefore, Dart reflection us es objects of type \code{Symbol} rather than strings. Instances of \code{Symbol } are guaranteed to be stable with repeat to minification. Providing a literal f orm for symbols makes reflective code easier to read and write. The fact that sy mbols are easy to type and can often act as convenient substitutes for enums are secondary benefits. | 2867 Minification compresses identifiers consistently throughout a program in order t o reduce download size. This practice poses difficulties for reflective program s that refer to program declarations via strings. A string will refer to an iden tifier in the source, but the identifier will no longer be used in the minified code, and reflective code using these would fail. Therefore, Dart reflection us es objects of type \code{Symbol} rather than strings. Instances of \code{Symbol } are guaranteed to be stable with repeat to minification. Providing a literal f orm for symbols makes reflective code easier to read and write. The fact that sy mbols are easy to type and can often act as convenient substitutes for enums are secondary benefits. |
2860 } | 2868 } |
2861 | 2869 |
2862 \LMHash{} | 2870 \LMHash{} |
2863 The static type of a symbol literal is \code{Symbol}. | 2871 The static type of a symbol literal is \code{Symbol}. |
2864 | 2872 |
2865 \subsection{Lists} | 2873 \subsection{Lists} |
2866 \LMLabel{lists} | 2874 \LMLabel{lists} |
2867 | 2875 |
2868 \LMHash{} | 2876 \LMHash{} |
2869 A {\em list literal} denotes a list, which is an integer indexed collection of o bjects. | 2877 A {\em list literal} denotes a list, which is an integer indexed collection of o bjects. |
2870 | 2878 |
2871 \begin{grammar} | 2879 \begin{grammar} |
2872 {\bf listLiteral:} | 2880 {\bf listLiteral:} |
2873 \CONST{}? typeArguments? `[' (expressionList `,'?)? `]' | 2881 \CONST{}? typeArguments? `[' (expressionList `,'?)? `]' |
2874 . | 2882 . |
2875 \end{grammar} | 2883 \end{grammar} |
2876 | 2884 |
2877 \LMHash{} | 2885 \LMHash{} |
2878 A list may contain zero or more objects. The number of elements in a list is its size. A list has an associated set of indices. An empty list has an empty set of indices. A non-empty list has the index set $\{0 \ldots n -1\}$ where $n$ is the size of the list. It is a runtime error to attempt to access a list using an index that is not a member of its set of indices. | 2886 A list may contain zero or more objects. The number of elements in a list is its size. A list has an associated set of indices. An empty list has an empty set of indices. A non-empty list has the index set $\{0 \ldots n -1\}$ where $n$ is the size of the list. It is a runtime error to attempt to access a list using an index that is not a member of its set of indices. |
2879 | 2887 |
2880 | 2888 |
2881 \LMHash{} | 2889 \LMHash{} |
2882 If a list literal begins with the reserved word \CONST{}, it is a {\em constant list literal} which is a compile-time constant (\ref{constants}) and therefore e valuated at compile-time. Otherwise, it is a {\em run-time list literal} and it is evaluated at run-time. Only run-time list literals can be mutated | 2890 If a list literal begins with the reserved word \CONST{}, it is a {\em constant list literal} which is a compile-time constant (\ref{constants}) and therefore e valuated at compile-time. Otherwise, it is a {\em run-time list literal} and it is evaluated at run-time. Only run-time list literals can be mutated |
2883 after they are created. Attempting to mutate a constant list literal will result in a dynamic error. | 2891 after they are created. Attempting to mutate a constant list literal will result in a dynamic error. |
2884 | 2892 |
2885 \LMHash{} | 2893 \LMHash{} |
2886 It is a compile-time error if an element of a constant list literal is not a com pile-time constant. It is a compile-time error if the type argument of a constan t list literal includes a type parameter. | 2894 It is a compile-time error if an element of a constant list literal is not a com pile-time constant. It is a compile-time error if the type argument of a constan t list literal includes a type parameter. |
2887 \rationale{The binding of a type parameter is not known at compile-time, so we c annot use type parameters inside compile-time constants.} | 2895 \rationale{The binding of a type parameter is not known at compile-time, so we c annot use type parameters inside compile-time constants.} |
2888 | 2896 |
2889 \LMHash{} | 2897 \LMHash{} |
2890 The value of a constant list literal \CONST{} $<E>[e_1\ldots e_n]$ is an object $a$ whose class implements the built-in class $List<E>$. The $i$th element of $ a$ is $v_{i+1}$, where $v_i$ is the value of the compile-time expression $e_i$. The value of a constant list literal \CONST{} $[e_1 \ldots e_n]$ is defined as the value of the constant list literal \CONST{}$ < \DYNAMIC{}>[e_1\ldots e_n]$. | 2898 The value of a constant list literal \CONST{} $<E>[e_1\ldots e_n]$ is an object $a$ whose class implements the built-in class $List<E>$. The $i$th element of $ a$ is $v_{i+1}$, where $v_i$ is the value of the compile-time expression $e_i$. The value of a constant list literal \CONST{} $[e_1 \ldots e_n]$ is defined as the value of the constant list literal \CONST{}$ < \DYNAMIC{}>[e_1\ldots e_n]$. |
2891 | 2899 |
2892 \LMHash{} | 2900 \LMHash{} |
2893 Let $list_1 =$ \CONST{} $<V>[e_{11} \ldots e_{1n}]$ and $list_2 =$ \CONST{} $<U >[e_{21} \ldots e_{2n}]$ be two constant list literals and let the elements of $list_1$ and $list_2$ evaluate to $o_{11} \ldots o_{1n}$ and $o_{21} \ldots o_ {2n}$ respectively. Iff \code{identical($o_{1i}$, $o_{2i}$)} for $i \in 1.. n$ a nd $V = U$ then \code{identical($list_1$, $list_2$)}. | 2901 Let $list_1 =$ \CONST{} $<V>[e_{11} \ldots e_{1n}]$ and $list_2 =$ \CONST{} $<U >[e_{21} \ldots e_{2n}]$ be two constant list literals and let the elements of $list_1$ and $list_2$ evaluate to $o_{11} \ldots o_{1n}$ and $o_{21} \ldots o_ {2n}$ respectively. Iff \code{identical($o_{1i}$, $o_{2i}$)} for $i \in 1.. n$ a nd $V = U$ then \code{identical($list_1$, $list_2$)}. |
2894 | 2902 |
2895 \commentary{In other words, constant list literals are canonicalized.} | 2903 \commentary{In other words, constant list literals are canonicalized.} |
2896 | 2904 |
2897 \LMHash{} | 2905 \LMHash{} |
2898 A run-time list literal $<E>[e_1 \ldots e_n]$ is evaluated as follows: | 2906 A run-time list literal $<E>[e_1 \ldots e_n]$ is evaluated as follows: |
2899 \begin{itemize} | 2907 \begin{itemize} |
2900 \item | 2908 \item |
2901 First, the expressions $e_1 \ldots e_n$ are evaluated in order they appear in th e program, yielding objects $o_1 \ldots o_n$. | 2909 First, the expressions $e_1 \ldots e_n$ are evaluated in order they appear in th e program, yielding objects $o_1 \ldots o_n$. |
2902 \item A fresh instance (\ref{generativeConstructors}) $a$, of size $n$, whose class implements the built-in class $List<E>$ is allocated. | 2910 \item A fresh instance (\ref{generativeConstructors}) $a$, of size $n$, whose class implements the built-in class $List<E>$ is allocated. |
2903 \item | 2911 \item |
2904 The operator \code{[]=} is invoked on $a$ with first argument $i$ and second a rgument | 2912 The operator \code{[]=} is invoked on $a$ with first argument $i$ and second a rgument |
2905 %The $i$th element of $a$ is set to | 2913 %The $i$th element of $a$ is set to |
2906 $o_{i+1}, 0 \le i < n$. | 2914 $o_{i+1}, 0 \le i < n$. |
2907 \item | 2915 \item |
2908 The result of the evaluation is $a$. | 2916 The result of the evaluation is $a$. |
2909 \end{itemize} | 2917 \end{itemize} |
2910 | 2918 |
2911 | 2919 |
2912 \commentary{ | 2920 \commentary{ |
2913 Note that this document does not specify an order in which the elements are set. This allows for parallel assignments into the list if an implementation so desi res. The order can only be observed in checked mode (and may not be relied upon ): if element $i$ is not a subtype of the element type of the list, a dynamic ty pe error will occur when $a[i]$ is assigned $o_{i-1}$. | 2921 Note that this document does not specify an order in which the elements are set. This allows for parallel assignments into the list if an implementation so desi res. The order can only be observed in checked mode (and may not be relied upon ): if element $i$ is not a subtype of the element type of the list, a dynamic ty pe error will occur when $a[i]$ is assigned $o_{i-1}$. |
2914 } | 2922 } |
2915 | 2923 |
2916 \LMHash{} | 2924 \LMHash{} |
2917 A runtime list literal $[e_1 \ldots e_n]$ is evaluated as $< \DYNAMIC{}>[e_1\l dots e_n]$. | 2925 A runtime list literal $[e_1 \ldots e_n]$ is evaluated as $< \DYNAMIC{}>[e_1\l dots e_n]$. |
2918 | 2926 |
2919 | 2927 |
2920 \commentary{ | 2928 \commentary{ |
2921 There is no restriction precluding nesting of list literals. It follows from the rules above that | 2929 There is no restriction precluding nesting of list literals. It follows from the rules above that |
2922 $<List<int>>[[1, 2, 3], [4, 5, 6]]$ is a list with type parameter $List<int>$, c ontaining two lists with type parameter \DYNAMIC{}. | 2930 $<List<int>>[[1, 2, 3], [4, 5, 6]]$ is a list with type parameter $List<int>$, c ontaining two lists with type parameter \DYNAMIC{}. |
2923 } | 2931 } |
2924 | 2932 |
2925 \LMHash{} | 2933 \LMHash{} |
2926 The static type of a list literal of the form \CONST{}$ <E>[e_1\ldots e_n]$ or the form $<E>[e_1 \ldots e_n]$ is $List<E>$. The static type a list literal of the form \CONST{} $[e_1 \ldots e_n$] or the form $[e_1\ldots e_n$] is $List< \ DYNAMIC{}>$. | 2934 The static type of a list literal of the form \CONST{}$ <E>[e_1\ldots e_n]$ or the form $<E>[e_1 \ldots e_n]$ is $List<E>$. The static type a list literal of the form \CONST{} $[e_1 \ldots e_n$] or the form $[e_1\ldots e_n$] is $List< \ DYNAMIC{}>$. |
2927 | 2935 |
2928 \rationale{ | 2936 \rationale{ |
2929 It is tempting to assume that the type of the list literal would be computed bas ed on the types of its elements. However, for mutable lists this may be unwarran ted. Even for constant lists, we found this behavior to be problematic. Since co mpile-time is often actually runtime, the runtime system must be able to perform a complex least upper bound computation to determine a reasonably precise type. It is better to leave this task to a tool in the IDE. It is also much more unif orm (and therefore predictable and understandable) to insist that whenever types are unspecified they are assumed to be the unknown type \DYNAMIC{}. | 2937 It is tempting to assume that the type of the list literal would be computed bas ed on the types of its elements. However, for mutable lists this may be unwarran ted. Even for constant lists, we found this behavior to be problematic. Since co mpile-time is often actually runtime, the runtime system must be able to perform a complex least upper bound computation to determine a reasonably precise type. It is better to leave this task to a tool in the IDE. It is also much more unif orm (and therefore predictable and understandable) to insist that whenever types are unspecified they are assumed to be the unknown type \DYNAMIC{}. |
2930 } | 2938 } |
2931 | 2939 |
2932 %Invoking the getter \code{runtimeType} on a list literal returns the \code{Type } object that is the value of the expression \code{List}. The static type of a l ist literal is \code{List}. | 2940 %Invoking the getter \code{runtimeType} on a list literal returns the \code{Type } object that is the value of the expression \code{List}. The static type of a l ist literal is \code{List}. |
2933 % what about generics? | 2941 % what about generics? |
2934 | 2942 |
2935 \subsection{Maps} | 2943 \subsection{Maps} |
2936 \LMLabel{maps} | 2944 \LMLabel{maps} |
2937 | 2945 |
2938 \LMHash{} | 2946 \LMHash{} |
2939 A {\em map literal} denotes a map object. | 2947 A {\em map literal} denotes a map object. |
2940 | 2948 |
2941 \begin{grammar} | 2949 \begin{grammar} |
2942 {\bf mapLiteral:} | 2950 {\bf mapLiteral:} |
2943 \CONST{}? typeArguments? `\{' (mapLiteralEntry (`,' mapLiteralEntry)* `,' ?)? `\}' | 2951 \CONST{}? typeArguments? `\{' (mapLiteralEntry (`,' mapLiteralEntry)* `,' ?)? `\}' |
2944 . | 2952 . |
2945 | 2953 |
2946 {\bf mapLiteralEntry:} | 2954 {\bf mapLiteralEntry:} |
2947 % identifier `{\escapegrammar :}' expression; | 2955 % identifier `{\escapegrammar :}' expression; |
2948 » expression `{\escapegrammar :}' expression | 2956 » expression `{\escapegrammar :}' expression |
2949 . | 2957 . |
2950 \end{grammar} | 2958 \end{grammar} |
2951 | 2959 |
2952 \LMHash{} | 2960 \LMHash{} |
2953 A {\em map literal} consists of zero or more entries. Each entry has a {\em key} and a {\em value}. Each key and each value is denoted by an expression. | 2961 A {\em map literal} consists of zero or more entries. Each entry has a {\em key} and a {\em value}. Each key and each value is denoted by an expression. |
2954 | 2962 |
2955 \LMHash{} | 2963 \LMHash{} |
2956 If a map literal begins with the reserved word \CONST{}, it is a {\em constant m ap literal} which is a compile-time constant (\ref{constants}) and therefore eva luated at compile-time. Otherwise, it is a {\em run-time map literal} and it is evaluated at run-time. Only run-time map literals can be mutated | 2964 If a map literal begins with the reserved word \CONST{}, it is a {\em constant m ap literal} which is a compile-time constant (\ref{constants}) and therefore eva luated at compile-time. Otherwise, it is a {\em run-time map literal} and it is evaluated at run-time. Only run-time map literals can be mutated |
2957 after they are created. Attempting to mutate a constant map literal will result in a dynamic error. | 2965 after they are created. Attempting to mutate a constant map literal will result in a dynamic error. |
2958 | 2966 |
2959 \LMHash{} | 2967 \LMHash{} |
2960 It is a compile-time error if either a key or a value of an entry in a constant map literal is not a compile-time constant. It is a compile-time error if the ke y of an entry in a constant map literal is an instance of a class that implement s the operator $==$ unless the key is a | 2968 It is a compile-time error if either a key or a value of an entry in a constant map literal is not a compile-time constant. It is a compile-time error if the ke y of an entry in a constant map literal is an instance of a class that implement s the operator $==$ unless the key is a |
2961 %symbol, | 2969 %symbol, |
2962 string, an integer, a literal symbol or the result of invoking a constant constr uctor of class \cd{Symbol}. | 2970 string, an integer, a literal symbol or the result of invoking a constant constr uctor of class \cd{Symbol}. |
2963 It is a compile-time error if the type arguments of a constant map literal inclu de a type parameter. | 2971 It is a compile-time error if the type arguments of a constant map literal inclu de a type parameter. |
2964 | 2972 |
2965 \LMHash{} | 2973 \LMHash{} |
2966 The value of a constant map literal \CONST{}$ <K, V>\{k_1:e_1\ldots k_n :e_n\}$ is an object $m$ whose class implements the built-in class $Map<K, V>$. The ent ries of $m$ are $u_i:v_i, i \in 1 .. n$, where $u_i$ is the value of the compile -time expression $k_i$ and $v_i$ is the value of the compile-time expression $e_ i$. The value of a constant map literal \CONST{} $\{k_1:e_1\ldots k_n :e_n\}$ is defined as the value of a constant map literal \CONST{} $<\DYNAMIC{}, \DYNAMI C{}>\{k_1:e_1\ldots k_n :e_n\}$. | 2974 The value of a constant map literal \CONST{}$ <K, V>\{k_1:e_1\ldots k_n :e_n\}$ is an object $m$ whose class implements the built-in class $Map<K, V>$. The ent ries of $m$ are $u_i:v_i, i \in 1 .. n$, where $u_i$ is the value of the compile -time expression $k_i$ and $v_i$ is the value of the compile-time expression $e_ i$. The value of a constant map literal \CONST{} $\{k_1:e_1\ldots k_n :e_n\}$ is defined as the value of a constant map literal \CONST{} $<\DYNAMIC{}, \DYNAMI C{}>\{k_1:e_1\ldots k_n :e_n\}$. |
2967 | 2975 |
2968 \LMHash{} | 2976 \LMHash{} |
2969 Let $map_1 =$ \CONST{}$ <K, V>\{k_{11}:e_{11} \ldots k_{1n} :e_{1n}\}$ and $map _2 =$ \CONST{}$ <J, U>\{k_{21}:e_{21} \ldots k_{2n} :e_{2n}\}$ be two constant map literals. Let the keys of $map_1$ and $map_2$ evaluate to $s_{11} \ldots s _{1n}$ and $s_{21} \ldots s_{2n}$ respectively, and let the elements of $map _1$ and $map_2$ evaluate to $o_{11} \ldots o_{1n}$ and $o_{21} \ldots o_{2n}$ respectively. Iff \code{identical($o_{1i}$, $o_{2i}$)} and \code{identical($s_{ 1i}$, $s_{2i}$)} for $i \in 1.. n$, and $K = J, V = U$ then \code{identical($map _1$, $map_2$)}. | 2977 Let $map_1 =$ \CONST{}$ <K, V>\{k_{11}:e_{11} \ldots k_{1n} :e_{1n}\}$ and $map _2 =$ \CONST{}$ <J, U>\{k_{21}:e_{21} \ldots k_{2n} :e_{2n}\}$ be two constant map literals. Let the keys of $map_1$ and $map_2$ evaluate to $s_{11} \ldots s _{1n}$ and $s_{21} \ldots s_{2n}$ respectively, and let the elements of $map _1$ and $map_2$ evaluate to $o_{11} \ldots o_{1n}$ and $o_{21} \ldots o_{2n}$ respectively. Iff \code{identical($o_{1i}$, $o_{2i}$)} and \code{identical($s_{ 1i}$, $s_{2i}$)} for $i \in 1.. n$, and $K = J, V = U$ then \code{identical($map _1$, $map_2$)}. |
2970 | 2978 |
2971 \commentary{In other words, constant map literals are canonicalized.} | 2979 \commentary{In other words, constant map literals are canonicalized.} |
2972 | 2980 |
2973 \LMHash{} | 2981 \LMHash{} |
2974 A runtime map literal $<K, V>\{k_1:e_1\ldots k_n :e_n\}$ is evaluated as follow s: | 2982 A runtime map literal $<K, V>\{k_1:e_1\ldots k_n :e_n\}$ is evaluated as follow s: |
2975 \begin{itemize} | 2983 \begin{itemize} |
2976 \item | 2984 \item |
2977 First, the expression $k_i$ is evaluated yielding object $u_i$, the $e_i$ is vau lted yielding object $o_i$, for $i \in 1..n$ in left to right order, yielding ob jects $u_1, o_1\ldots u_n, o_n$. | 2985 First, the expression $k_i$ is evaluated yielding object $u_i$, the $e_i$ is vau lted yielding object $o_i$, for $i \in 1..n$ in left to right order, yielding ob jects $u_1, o_1\ldots u_n, o_n$. |
2978 \item A fresh instance (\ref{generativeConstructors}) $m$ whose class implement s the built-in class | 2986 \item A fresh instance (\ref{generativeConstructors}) $m$ whose class implement s the built-in class |
2979 | 2987 |
2980 $Map<K, V>$ is allocated. | 2988 $Map<K, V>$ is allocated. |
2981 \item | 2989 \item |
2982 The operator \code{[]=} is invoked on $m$ with first argument $u_i$ and second argument $o_i, i \in 1.. n$. | 2990 The operator \code{[]=} is invoked on $m$ with first argument $u_i$ and second argument $o_i, i \in 1.. n$. |
2983 \item | 2991 \item |
2984 The result of the evaluation is $m$. | 2992 The result of the evaluation is $m$. |
2985 \end{itemize} | 2993 \end{itemize} |
2986 | 2994 |
2987 | 2995 |
2988 \LMHash{} | 2996 \LMHash{} |
2989 A runtime map literal $\{k_1:e_1\ldots k_n :e_n\}$ is evaluated as | 2997 A runtime map literal $\{k_1:e_1\ldots k_n :e_n\}$ is evaluated as |
2990 | 2998 |
2991 $<\DYNAMIC{}, \DYNAMIC{}>\{k_1:e_1\ldots k_n :e_n\}$. | 2999 $<\DYNAMIC{}, \DYNAMIC{}>\{k_1:e_1\ldots k_n :e_n\}$. |
2992 | 3000 |
2993 \LMHash{} | 3001 \LMHash{} |
2994 Iff all the keys in a map literal are compile-time constants, it is a static war ning if the values of any two keys in a map literal are equal. | 3002 Iff all the keys in a map literal are compile-time constants, it is a static war ning if the values of any two keys in a map literal are equal. |
2995 | 3003 |
2996 \LMHash{} | 3004 \LMHash{} |
2997 A map literal is ordered: iterating over the keys and/or values of the maps alwa ys happens in the | 3005 A map literal is ordered: iterating over the keys and/or values of the maps alwa ys happens in the |
2998 order the keys appeared in the source code. | 3006 order the keys appeared in the source code. |
2999 | 3007 |
3000 \commentary{ | 3008 \commentary{ |
3001 Of course, if a key repeats, the order is defined by first occurrence, but the v alue is defined by the last. | 3009 Of course, if a key repeats, the order is defined by first occurrence, but the v alue is defined by the last. |
3002 } | 3010 } |
3003 | 3011 |
3004 \LMHash{} | 3012 \LMHash{} |
3005 The static type of a map literal of the form \CONST{}$ <K, V>\{k_1:e_1\ldots k_ n :e_n\}$ or the form $<K, V>\{k_1:e_1\ldots k_n :e_n\}$ is $Map<K, V>$. The sta tic type a map literal of the form \CONST{}$\{k_1:e_1\ldots k_n :e_n\}$ or the form $\{k_1:e_1\ldots k_n :e_n\}$ is $Map<\DYNAMIC{}, \DYNAMIC{}>$. | 3013 The static type of a map literal of the form \CONST{}$ <K, V>\{k_1:e_1\ldots k_ n :e_n\}$ or the form $<K, V>\{k_1:e_1\ldots k_n :e_n\}$ is $Map<K, V>$. The sta tic type a map literal of the form \CONST{}$\{k_1:e_1\ldots k_n :e_n\}$ or the form $\{k_1:e_1\ldots k_n :e_n\}$ is $Map<\DYNAMIC{}, \DYNAMIC{}>$. |
3006 | 3014 |
3007 | 3015 |
3008 \subsection{Throw} | 3016 \subsection{Throw} |
3009 \LMLabel{throw} | 3017 \LMLabel{throw} |
3010 | 3018 |
3011 \LMHash{} | 3019 \LMHash{} |
3012 The {\em throw expression} is used to raise an exception. | 3020 The {\em throw expression} is used to raise an exception. |
3013 | 3021 |
3014 \begin{grammar} | 3022 \begin{grammar} |
3015 {\bf throwExpression:} | 3023 {\bf throwExpression:} |
3016 \THROW{} expression | 3024 \THROW{} expression |
3017 . | 3025 . |
3018 | 3026 |
3019 {\bf throwExpressionWithoutCascade:} | 3027 {\bf throwExpressionWithoutCascade:} |
3020 \THROW{} expressionWithoutCascade | 3028 \THROW{} expressionWithoutCascade |
3021 . | 3029 . |
3022 | 3030 |
3023 \end{grammar} | 3031 \end{grammar} |
3024 | 3032 |
3025 \LMHash{} | 3033 \LMHash{} |
3026 The {\em current exception} is the last exception raised and not subsequently c aught at a given moment during runtime. | 3034 The {\em current exception} is the last exception raised and not subsequently c aught at a given moment during runtime. |
3027 | 3035 |
3028 \LMHash{} | 3036 \LMHash{} |
3029 Evaluation of a throw expression of the form \code{\THROW{} $e$;} proceeds as follows: | 3037 Evaluation of a throw expression of the form \code{\THROW{} $e$;} proceeds as follows: |
3030 | 3038 |
3031 \LMHash{} | 3039 \LMHash{} |
3032 The expression $e$ is evaluated yielding a value $v$. | 3040 The expression $e$ is evaluated yielding a value $v$. |
3033 | 3041 |
3034 \commentary{ | 3042 \commentary{ |
3035 There is no requirement that the expression $e$ evaluate to a special kind of ex ception or error object. | 3043 There is no requirement that the expression $e$ evaluate to a special kind of ex ception or error object. |
3036 } | 3044 } |
3037 | 3045 |
3038 \LMHash{} | 3046 \LMHash{} |
3039 If $e$ evaluates to \NULL{} (\ref{null}), then a \code{NullThrownError} is throw n. Otherwise the current exception is set to $v$ and the current return value (\ ref{return}) becomes undefined. | 3047 If $e$ evaluates to \NULL{} (\ref{null}), then a \code{NullThrownError} is throw n. Otherwise the current exception is set to $v$ and the current return value (\ ref{return}) becomes undefined. |
3040 | 3048 |
3041 \rationale{The current exception and the current return value must never be simu ltaneously defined, as they represent mutually exclusive options for exiting the current function. | 3049 \rationale{The current exception and the current return value must never be simu ltaneously defined, as they represent mutually exclusive options for exiting the current function. |
3042 } | 3050 } |
3043 | 3051 |
3044 \LMHash{} | 3052 \LMHash{} |
3045 Let $f$ be the immediately enclosing function. | 3053 Let $f$ be the immediately enclosing function. |
3046 | 3054 |
3047 \LMHash{} | 3055 \LMHash{} |
3048 If $f$ is synchronous (\ref{functions}), control is transferred to the nearest d ynamically enclosing exception handler. | 3056 If $f$ is synchronous (\ref{functions}), control is transferred to the nearest d ynamically enclosing exception handler. |
3049 | 3057 |
3050 \commentary{ | 3058 \commentary{ |
3051 If $f$ is marked \SYNC* then a dynamically enclosing exception handler encloses the call to \code{moveNext()} that initiated the evaluation of the throw express ion. | 3059 If $f$ is marked \SYNC* then a dynamically enclosing exception handler encloses the call to \code{moveNext()} that initiated the evaluation of the throw express ion. |
3052 } | 3060 } |
3053 | 3061 |
3054 \LMHash{} | 3062 \LMHash{} |
3055 If $f$ is asynchronous then if there is a dynamically enclosing exception handl er $h$ (\ref{try}) introduced by the current activation, control is transferred to $h$, otherwise $f$ terminates. | 3063 If $f$ is asynchronous then if there is a dynamically enclosing exception handl er $h$ (\ref{try}) introduced by the current activation, control is transferred to $h$, otherwise $f$ terminates. |
3056 | 3064 |
3057 \rationale{ | 3065 \rationale{ |
3058 The rules for where a thrown exception will be handled must necessarily differ b etween the synchronous and asynchronous cases. Asynchronous functions cannot tra nsfer control to an exception handler defined outside themselves. Asynchronous generators post exceptions to their stream. Other asynchronous functions report exceptions via their future. | 3066 The rules for where a thrown exception will be handled must necessarily differ b etween the synchronous and asynchronous cases. Asynchronous functions cannot tra nsfer control to an exception handler defined outside themselves. Asynchronous generators post exceptions to their stream. Other asynchronous functions report exceptions via their future. |
3059 } | 3067 } |
3060 | 3068 |
3061 \LMHash{} | 3069 \LMHash{} |
3062 If the object being thrown is an instance of class \code{Error} or a subclass th ereof, its \code{stackTrace} getter will return the stack trace current at the p oint where the object was first thrown. | 3070 If the object being thrown is an instance of class \code{Error} or a subclass th ereof, its \code{stackTrace} getter will return the stack trace current at the p oint where the object was first thrown. |
3063 | 3071 |
3064 \LMHash{} | 3072 \LMHash{} |
3065 The static type of a throw expression is $\bot$. | 3073 The static type of a throw expression is $\bot$. |
3066 | 3074 |
3067 | 3075 |
3068 \subsection{ Function Expressions} | 3076 \subsection{ Function Expressions} |
3069 \LMLabel{functionExpressions} | 3077 \LMLabel{functionExpressions} |
3070 | 3078 |
3071 \LMHash{} | 3079 \LMHash{} |
3072 A {\em function literal} is an object that encapsulates an executable unit of co de. | 3080 A {\em function literal} is an object that encapsulates an executable unit of co de. |
3073 | 3081 |
3074 \begin{grammar} | 3082 \begin{grammar} |
3075 {\bf functionExpression:} | 3083 {\bf functionExpression:} |
3076 formalParameterList functionBody | 3084 formalParameterList functionBody |
3077 . | 3085 . |
3078 \end{grammar} | 3086 \end{grammar} |
3079 | 3087 |
3080 \LMHash{} | 3088 \LMHash{} |
3081 The class of a function literal implements the built-in class \code{Function}. | 3089 The class of a function literal implements the built-in class \code{Function}. |
3082 %Invoking the getter \code{runtimeType} on a function literal returns the \code{ Type} object that is the value of the expression \code{Function}. | 3090 %Invoking the getter \code{runtimeType} on a function literal returns the \code{ Type} object that is the value of the expression \code{Function}. |
3083 % not necessarily | 3091 % not necessarily |
3084 | 3092 |
3085 | 3093 |
3086 %Q{Can anyone implement it? Then we should define things via call} | 3094 %Q{Can anyone implement it? Then we should define things via call} |
3087 | 3095 |
3088 \LMHash{} | 3096 \LMHash{} |
3089 The static type of a function literal of the form | 3097 The static type of a function literal of the form |
3090 | 3098 |
3091 $(T_1$ $a_1, \ldots, T_n$ $a_n, [T_{n+1}$ $x_{n+1} = d_1, \ldots, T_{n+k}$ $x_{ n+k} = d_k]) => e$ | 3099 $(T_1$ $a_1, \ldots, T_n$ $a_n, [T_{n+1}$ $x_{n+1} = d_1, \ldots, T_{n+k}$ $x_{ n+k} = d_k]) => e$ |
3092 is | 3100 is |
3093 | 3101 |
3094 $(T_1 \ldots, T_n, [T_{n+1}$ $x_{n+1}, \ldots, T_{n+k}$ $x_{n+k}]) \rightarrow T _0$, where $T_0$ is the static type of $e$. | 3102 $(T_1 \ldots, T_n, [T_{n+1}$ $x_{n+1}, \ldots, T_{n+k}$ $x_{n+k}]) \rightarrow T _0$, where $T_0$ is the static type of $e$. |
3095 | 3103 |
3096 \LMHash{} | 3104 \LMHash{} |
3097 The static type of a function literal of the form | 3105 The static type of a function literal of the form |
3098 | 3106 |
3099 $(T_1$ $a_1, \ldots, T_n$ $a_n, [T_{n+1}$ $x_{n+1} = d_1, \ldots, T_{n+k}$ $x_{ n+k} = d_k])$ \ASYNC{} $=> e$ | 3107 $(T_1$ $a_1, \ldots, T_n$ $a_n, [T_{n+1}$ $x_{n+1} = d_1, \ldots, T_{n+k}$ $x_{ n+k} = d_k])$ \ASYNC{} $=> e$ |
3100 is $(T_1 \ldots, T_n, [T_{n+1}$ $x_{n+1}, \ldots, T_{n+k}$ $x_{n+k}]) \rightarro w Future<flatten(T_0)>$, where $T_0$ is the static type of $e$ and $flatten(T)$ is defined as follows: | 3108 is $(T_1 \ldots, T_n, [T_{n+1}$ $x_{n+1}, \ldots, T_{n+k}$ $x_{n+k}]) \rightarro w Future<flatten(T_0)>$, where $T_0$ is the static type of $e$ and $flatten(T)$ is defined as follows: |
3101 | 3109 |
3102 If $T = Future<S>$ then $flatten(T) = flatten(S)$. | 3110 If $T = Future<S>$ then $flatten(T) = flatten(S)$. |
3103 | 3111 |
3104 Otherwise if $T <: Future$ then let $S$ be a type such that $T << Future<S>$ an d for all $R$, if $T << Future<R>$ then $S << R$. | 3112 Otherwise if $T <: Future$ then let $S$ be a type such that $T << Future<S>$ an d for all $R$, if $T << Future<R>$ then $S << R$. |
3105 | 3113 |
3106 \rationale{ | 3114 \rationale{ |
3107 This ensures that $Future<S>$ is the most specific instantiation of \cd{Future} that is a super type of $T$. | 3115 This ensures that $Future<S>$ is the most specific instantiation of \cd{Future} that is a super type of $T$. |
3108 } | 3116 } |
3109 | 3117 |
3110 Then $flatten(T) = S$. | 3118 Then $flatten(T) = S$. |
3111 | 3119 |
3112 In any other circumstance, $flatten(T) = T$. | 3120 In any other circumstance, $flatten(T) = T$. |
3113 | 3121 |
3114 | 3122 |
3115 | 3123 |
3116 \rationale{ | 3124 \rationale{ |
3117 We collapse multiple layers of futures into one. If $e$ evaluates to a future $f $, the future will not invoke its \code{then()} callback until f completes to a non-future value, and so the result of an await is never a future, and the resul t of an async function will never have type \code{Future$<X>$} where $X$ itself is an invocation of \code{Future}. | 3125 We collapse multiple layers of futures into one. If $e$ evaluates to a future $f $, the future will not invoke its \code{then()} callback until f completes to a non-future value, and so the result of an await is never a future, and the resul t of an async function will never have type \code{Future$<X>$} where $X$ itself is an invocation of \code{Future}. |
3118 | 3126 |
3119 The exception to that would be a type $X$ that extended or implemented \code{Fu ture}. In that case, only one unwrapping takes place. As an example of why this is done, consider | 3127 The exception to that would be a type $X$ that extended or implemented \code{Fu ture}. In that case, only one unwrapping takes place. As an example of why this is done, consider |
3120 | 3128 |
3121 \cd{\CLASS{} C$<$T$>$ \IMPLEMENTS{} Future$<$C$<$C$<$T$>>>$ \ldots } | 3129 \cd{\CLASS{} C$<$T$>$ \IMPLEMENTS{} Future$<$C$<$C$<$T$>>>$ \ldots } |
3122 | 3130 |
3123 Here, a naive definition of $flatten$ diverges; there is not even a fixed point. A more sophisticated definition of $flatten$ is possible, but the existing rule deals with most realistic examples while remaining relatively simple to underst and. | 3131 Here, a naive definition of $flatten$ diverges; there is not even a fixed point. A more sophisticated definition of $flatten$ is possible, but the existing rule deals with most realistic examples while remaining relatively simple to underst and. |
3124 | 3132 |
3125 } | 3133 } |
3126 | 3134 |
3127 | 3135 |
3128 \LMHash{} | 3136 \LMHash{} |
3129 The static type of a function literal of the form | 3137 The static type of a function literal of the form |
3130 | 3138 |
3131 $(T_1$ $a_1, \ldots, T_n$ $a_n, \{T_{n+1}$ $x_{n+1} : d_1, \ldots, T_{n+k}$ $x_ {n+k} : d_k\}) => e$ | 3139 $(T_1$ $a_1, \ldots, T_n$ $a_n, \{T_{n+1}$ $x_{n+1} : d_1, \ldots, T_{n+k}$ $x_ {n+k} : d_k\}) => e$ |
3132 is | 3140 is |
3133 | 3141 |
3134 $(T_1 \ldots, T_n, \{T_{n+1}$ $x_{n+1}, \ldots, T_{n+k}$ $x_{n+k}\}) \rightarrow T_0$, where $T_0$ is the static type of $e$. | 3142 $(T_1 \ldots, T_n, \{T_{n+1}$ $x_{n+1}, \ldots, T_{n+k}$ $x_{n+k}\}) \rightarrow T_0$, where $T_0$ is the static type of $e$. |
3135 | 3143 |
3136 \LMHash{} | 3144 \LMHash{} |
3137 The static type of a function literal of the form | 3145 The static type of a function literal of the form |
3138 | 3146 |
3139 $(T_1$ $a_1, \ldots, T_n$ $a_n, \{T_{n+1}$ $x_{n+1} : d_1, \ldots, T_{n+k}$ $x_ {n+k} : d_k\})$ \ASYNC{} $=> e$ | 3147 $(T_1$ $a_1, \ldots, T_n$ $a_n, \{T_{n+1}$ $x_{n+1} : d_1, \ldots, T_{n+k}$ $x_ {n+k} : d_k\})$ \ASYNC{} $=> e$ |
3140 | 3148 |
3141 is $(T_1 \ldots, T_n, \{T_{n+1}$ $x_{n+1}, \ldots, T_{n+k}$ $x_{n+k}\}) \rightar row Future<flatten(T_0)>$, where $T_0$ is the static type of $e$. | 3149 is $(T_1 \ldots, T_n, \{T_{n+1}$ $x_{n+1}, \ldots, T_{n+k}$ $x_{n+k}\}) \rightar row Future<flatten(T_0)>$, where $T_0$ is the static type of $e$. |
3142 | 3150 |
3143 \LMHash{} | 3151 \LMHash{} |
3144 The static type of a function literal of the form | 3152 The static type of a function literal of the form |
3145 | 3153 |
3146 $(T_1$ $a_1, \ldots, T_n$ $a_n, [T_{n+1}$ $x_{n+1} = d_1, \ldots, T_{n+k}$ $x_{ n+k}= d_k])\{s\}$ | 3154 $(T_1$ $a_1, \ldots, T_n$ $a_n, [T_{n+1}$ $x_{n+1} = d_1, \ldots, T_{n+k}$ $x_{ n+k}= d_k])\{s\}$ |
3147 | 3155 |
3148 is $(T_1 \ldots, T_n, [T_{n+1}$ $x_{n+1}, \ldots, T_{n+k}$ $x_{n+k}]) \rightarro w \DYNAMIC{}$. | 3156 is $(T_1 \ldots, T_n, [T_{n+1}$ $x_{n+1}, \ldots, T_{n+k}$ $x_{n+k}]) \rightarro w \DYNAMIC{}$. |
3149 | 3157 |
3150 \LMHash{} | 3158 \LMHash{} |
3151 The static type of a function literal of the form | 3159 The static type of a function literal of the form |
3152 | 3160 |
3153 $(T_1$ $a_1, \ldots, T_n$ $a_n, [T_{n+1}$ $x_{n+1} = d_1, \ldots, T_{n+k}$ $x_{ n+k}= d_k])$ $ \ASYNC{}$ $\{s\}$ | 3161 $(T_1$ $a_1, \ldots, T_n$ $a_n, [T_{n+1}$ $x_{n+1} = d_1, \ldots, T_{n+k}$ $x_{ n+k}= d_k])$ $ \ASYNC{}$ $\{s\}$ |
3154 is $(T_1 \ldots, T_n, [T_{n+1}$ $x_{n+1}, \ldots, T_{n+k}$ $x_{n+k}]) \rightarro w Future$. | 3162 is $(T_1 \ldots, T_n, [T_{n+1}$ $x_{n+1}, \ldots, T_{n+k}$ $x_{n+k}]) \rightarro w Future$. |
3155 | 3163 |
3156 \LMHash{} | 3164 \LMHash{} |
3157 The static type of a function literal of the form | 3165 The static type of a function literal of the form |
3158 | 3166 |
3159 $(T_1$ $a_1, \ldots, T_n$ $a_n, [T_{n+1}$ $x_{n+1} = d_1, \ldots, T_{n+k}$ $x_{ n+k}= d_k])$ $ \ASYNC*{}$ $\{s\}$ | 3167 $(T_1$ $a_1, \ldots, T_n$ $a_n, [T_{n+1}$ $x_{n+1} = d_1, \ldots, T_{n+k}$ $x_{ n+k}= d_k])$ $ \ASYNC*{}$ $\{s\}$ |
3160 is $(T_1 \ldots, T_n, [T_{n+1}$ $x_{n+1}, \ldots, T_{n+k}$ $x_{n+k}]) \rightarro w Stream$. | 3168 is $(T_1 \ldots, T_n, [T_{n+1}$ $x_{n+1}, \ldots, T_{n+k}$ $x_{n+k}]) \rightarro w Stream$. |
3161 | 3169 |
3162 \LMHash{} | 3170 \LMHash{} |
3163 The static type of a function literal of the form | 3171 The static type of a function literal of the form |
3164 | 3172 |
3165 $(T_1$ $a_1, \ldots, T_n$ $a_n, [T_{n+1}$ $x_{n+1} = d_1, \ldots, T_{n+k}$ $x_{ n+k}= d_k])$ $ \SYNC*{}$ $\{s\}$ | 3173 $(T_1$ $a_1, \ldots, T_n$ $a_n, [T_{n+1}$ $x_{n+1} = d_1, \ldots, T_{n+k}$ $x_{ n+k}= d_k])$ $ \SYNC*{}$ $\{s\}$ |
3166 is $(T_1 \ldots, T_n, [T_{n+1}$ $x_{n+1}, \ldots, T_{n+k}$ $x_{n+k}]) \rightarro w Iterable$. | 3174 is $(T_1 \ldots, T_n, [T_{n+1}$ $x_{n+1}, \ldots, T_{n+k}$ $x_{n+k}]) \rightarro w Iterable$. |
3167 | 3175 |
3168 | 3176 |
3169 \LMHash{} | 3177 \LMHash{} |
3170 The static type of a function literal of the form | 3178 The static type of a function literal of the form |
3171 | 3179 |
3172 $(T_1$ $a_1, \ldots, T_n$ $a_n, [T_{n+1}$ $x_{n+1} = d_1, \ldots, T_{n+k}$ $x_{ n+k}= d_k])\{s\}$ | 3180 $(T_1$ $a_1, \ldots, T_n$ $a_n, [T_{n+1}$ $x_{n+1} = d_1, \ldots, T_{n+k}$ $x_{ n+k}= d_k])\{s\}$ |
3173 | 3181 |
3174 is $(T_1 \ldots, T_n, [T_{n+1}$ $x_{n+1}, \ldots, T_{n+k}$ $x_{n+k}]) \rightarro w \DYNAMIC{}$. | 3182 is $(T_1 \ldots, T_n, [T_{n+1}$ $x_{n+1}, \ldots, T_{n+k}$ $x_{n+k}]) \rightarro w \DYNAMIC{}$. |
3175 | 3183 |
3176 | 3184 |
3177 \LMHash{} | 3185 \LMHash{} |
3178 The static type of a function literal of the form | 3186 The static type of a function literal of the form |
3179 | 3187 |
3180 $(T_1$ $a_1, \ldots, T_n$ $a_n, \{T_{n+1}$ $x_{n+1} : d_1, \ldots, T_{n+k}$ $x_ {n+k} : d_k\})$ $\ASYNC{}$ $\{s\}$ | 3188 $(T_1$ $a_1, \ldots, T_n$ $a_n, \{T_{n+1}$ $x_{n+1} : d_1, \ldots, T_{n+k}$ $x_ {n+k} : d_k\})$ $\ASYNC{}$ $\{s\}$ |
3181 | 3189 |
3182 is $(T_1 \ldots, T_n, \{T_{n+1}$ $x_{n+1}, \ldots, T_{n+k}$ $x_{n+k}\}) \rightar row Future{}$. | 3190 is $(T_1 \ldots, T_n, \{T_{n+1}$ $x_{n+1}, \ldots, T_{n+k}$ $x_{n+k}\}) \rightar row Future{}$. |
3183 | 3191 |
3184 \LMHash{} | 3192 \LMHash{} |
3185 The static type of a function literal of the form | 3193 The static type of a function literal of the form |
3186 | 3194 |
3187 $(T_1$ $a_1, \ldots, T_n$ $a_n, \{T_{n+1}$ $x_{n+1} : d_1, \ldots, T_{n+k}$ $x_ {n+k} : d_k\})$ $\ASYNC*{}$ $\{s\}$ | 3195 $(T_1$ $a_1, \ldots, T_n$ $a_n, \{T_{n+1}$ $x_{n+1} : d_1, \ldots, T_{n+k}$ $x_ {n+k} : d_k\})$ $\ASYNC*{}$ $\{s\}$ |
3188 | 3196 |
3189 is $(T_1 \ldots, T_n, \{T_{n+1}$ $x_{n+1}, \ldots, T_{n+k}$ $x_{n+k}\}) \rightar row Stream{}$. | 3197 is $(T_1 \ldots, T_n, \{T_{n+1}$ $x_{n+1}, \ldots, T_{n+k}$ $x_{n+k}\}) \rightar row Stream{}$. |
3190 | 3198 |
3191 \LMHash{} | 3199 \LMHash{} |
3192 The static type of a function literal of the form | 3200 The static type of a function literal of the form |
3193 | 3201 |
3194 $(T_1$ $a_1, \ldots, T_n$ $a_n, \{T_{n+1}$ $x_{n+1} : d_1, \ldots, T_{n+k}$ $x_ {n+k} : d_k\})$ $\SYNC*{}$ $\{s\}$ | 3202 $(T_1$ $a_1, \ldots, T_n$ $a_n, \{T_{n+1}$ $x_{n+1} : d_1, \ldots, T_{n+k}$ $x_ {n+k} : d_k\})$ $\SYNC*{}$ $\{s\}$ |
3195 | 3203 |
3196 is $(T_1 \ldots, T_n, \{T_{n+1}$ $x_{n+1}, \ldots, T_{n+k}$ $x_{n+k}\}) \rightar row Iterable{}$. | 3204 is $(T_1 \ldots, T_n, \{T_{n+1}$ $x_{n+1}, \ldots, T_{n+k}$ $x_{n+k}\}) \rightar row Iterable{}$. |
3197 | 3205 |
3198 \LMHash{} | 3206 \LMHash{} |
3199 In all of the above cases, whenever $T_i, 1 \le i \le n+k$, is not specified, it is considered to have been specified as \DYNAMIC{}. | 3207 In all of the above cases, whenever $T_i, 1 \le i \le n+k$, is not specified, it is considered to have been specified as \DYNAMIC{}. |
3200 | 3208 |
3201 | 3209 |
3202 \subsection{ This} | 3210 \subsection{ This} |
3203 \LMLabel{this} | 3211 \LMLabel{this} |
3204 | 3212 |
3205 \LMHash{} | 3213 \LMHash{} |
3206 The reserved word \THIS{} denotes the target of the current instance member invo cation. | 3214 The reserved word \THIS{} denotes the target of the current instance member invo cation. |
3207 | 3215 |
3208 \begin{grammar} | 3216 \begin{grammar} |
3209 {\bf thisExpression:} | 3217 {\bf thisExpression:} |
3210 \THIS{} | 3218 \THIS{} |
3211 . | 3219 . |
3212 \end{grammar} | 3220 \end{grammar} |
3213 | 3221 |
3214 \LMHash{} | 3222 \LMHash{} |
3215 The static type of \THIS{} is the interface of the immediately enclosing class. | 3223 The static type of \THIS{} is the interface of the immediately enclosing class. |
3216 | 3224 |
3217 \commentary{ | 3225 \commentary{ |
3218 We do not support self-types at this point. | 3226 We do not support self-types at this point. |
3219 } | 3227 } |
3220 | 3228 |
3221 \LMHash{} | 3229 \LMHash{} |
3222 It is a compile-time error if \THIS{} appears, implicitly or explicitly, in a t op-level function or variable initializer, in a factory constructor, or in a st atic method or variable initializer, or in the initializer of an instance variab le. | 3230 It is a compile-time error if \THIS{} appears, implicitly or explicitly, in a t op-level function or variable initializer, in a factory constructor, or in a st atic method or variable initializer, or in the initializer of an instance variab le. |
3223 | 3231 |
3224 \subsection{ Instance Creation} | 3232 \subsection{ Instance Creation} |
3225 \LMLabel{instanceCreation} | 3233 \LMLabel{instanceCreation} |
3226 | 3234 |
3227 \LMHash{} | 3235 \LMHash{} |
3228 Instance creation expressions invoke constructors to produce instances. | 3236 Instance creation expressions invoke constructors to produce instances. |
3229 | 3237 |
3230 %It is a compile-time error if any of the type arguments to a constructor of a g eneric type invoked by a new expression or a constant object expression do not d enote types in the enclosing lexical scope. | 3238 %It is a compile-time error if any of the type arguments to a constructor of a g eneric type invoked by a new expression or a constant object expression do not d enote types in the enclosing lexical scope. |
3231 | 3239 |
3232 %It is a compile-time error if a constructor of a non-generic type invoked by a new expression or a constant object expression is passed any type arguments. It is a compile-time error if a constructor of a generic type with $n$ type paramet ers invoked by a new expression or a constant object expression is passed $m$ ty pe arguments where $m \ne n$, or if any of its type arguments is misconstructed (\ref{parameterizedTypes}). | 3240 %It is a compile-time error if a constructor of a non-generic type invoked by a new expression or a constant object expression is passed any type arguments. It is a compile-time error if a constructor of a generic type with $n$ type paramet ers invoked by a new expression or a constant object expression is passed $m$ ty pe arguments where $m \ne n$, or if any of its type arguments is misconstructed (\ref{parameterizedTypes}). |
3233 | 3241 |
3234 \LMHash{} | 3242 \LMHash{} |
3235 It is a static type warning if | 3243 It is a static type warning if |
3236 the type $T$ in an instance creation expression of one of the forms | 3244 the type $T$ in an instance creation expression of one of the forms |
3237 | 3245 |
3238 \NEW{} $T.id(a_1, \ldots , a_n, x_{n+1}: a_{n+1}, \ldots , x_{n+k}: a_{n+k})$, | 3246 \NEW{} $T.id(a_1, \ldots , a_n, x_{n+1}: a_{n+1}, \ldots , x_{n+k}: a_{n+k})$, |
3239 | 3247 |
3240 \NEW{} $T(a_1, \ldots , a_n, x_{n+1}: a_{n+1}, \ldots , x_{n+k}: a_{n+k})$, | 3248 \NEW{} $T(a_1, \ldots , a_n, x_{n+1}: a_{n+1}, \ldots , x_{n+k}: a_{n+k})$, |
3241 | 3249 |
3242 \CONST{} $T.id(a_1, \ldots , a_n, x_{n+1}: a_{n+1}, \ldots , x_{n+k}: a_{n+k})$, | 3250 \CONST{} $T.id(a_1, \ldots , a_n, x_{n+1}: a_{n+1}, \ldots , x_{n+k}: a_{n+k})$, |
3243 | 3251 |
3244 \CONST{} $T(a_1, \ldots , a_n, x_{n+1}: a_{n+1}, \ldots , x_{n+k}: a_{n+k})$ is malformed (\ref{dynamicTypeSystem}) or malbounded (\ref{parameterizedTypes}). | 3252 \CONST{} $T(a_1, \ldots , a_n, x_{n+1}: a_{n+1}, \ldots , x_{n+k}: a_{n+k})$ is malformed (\ref{dynamicTypeSystem}) or malbounded (\ref{parameterizedTypes}). |
3245 | 3253 |
3246 \LMHash{} | 3254 \LMHash{} |
3247 It is a compile-time error if the type $T$ in an instance creation expression of one of the forms | 3255 It is a compile-time error if the type $T$ in an instance creation expression of one of the forms |
3248 | 3256 |
3249 \NEW{} $T.id(a_1, \ldots , a_n, x_{n+1}: a_{n+1}, \ldots , x_{n+k}: a_{n+k})$, | 3257 \NEW{} $T.id(a_1, \ldots , a_n, x_{n+1}: a_{n+1}, \ldots , x_{n+k}: a_{n+k})$, |
3250 | 3258 |
3251 \NEW{} $T(a_1, \ldots , a_n, x_{n+1}: a_{n+1}, \ldots , x_{n+k}: a_{n+k})$, | 3259 \NEW{} $T(a_1, \ldots , a_n, x_{n+1}: a_{n+1}, \ldots , x_{n+k}: a_{n+k})$, |
3252 | 3260 |
3253 \CONST{} $T.id(a_1, \ldots , a_n, x_{n+1}: a_{n+1}, \ldots , x_{n+k}: a_{n+k})$, | 3261 \CONST{} $T.id(a_1, \ldots , a_n, x_{n+1}: a_{n+1}, \ldots , x_{n+k}: a_{n+k})$, |
3254 | 3262 |
3255 \CONST{} $T(a_1, \ldots , a_n, x_{n+1}: a_{n+1}, \ldots , x_{n+k}: a_{n+k})$ | 3263 \CONST{} $T(a_1, \ldots , a_n, x_{n+1}: a_{n+1}, \ldots , x_{n+k}: a_{n+k})$ |
3256 | 3264 |
3257 is an enumerated type (\ref{enums}). | 3265 is an enumerated type (\ref{enums}). |
3258 %any of the type arguments to a constructor of a generic type $G$ invoked by a n ew expression or a constant object expression are not subtypes of the bounds of the corresponding formal type parameters of $G$. | 3266 %any of the type arguments to a constructor of a generic type $G$ invoked by a n ew expression or a constant object expression are not subtypes of the bounds of the corresponding formal type parameters of $G$. |
3259 | 3267 |
3260 | 3268 |
3261 \subsubsection{ New} | 3269 \subsubsection{ New} |
3262 \LMLabel{new} | 3270 \LMLabel{new} |
3263 | 3271 |
3264 \LMHash{} | 3272 \LMHash{} |
3265 The {\em new expression} invokes a constructor (\ref{constructors}). | 3273 The {\em new expression} invokes a constructor (\ref{constructors}). |
3266 | 3274 |
3267 \begin{grammar} | 3275 \begin{grammar} |
3268 {\bf newExpression:} | 3276 {\bf newExpression:} |
3269 \NEW{} type (`{\escapegrammar .}' identifier)? arguments | 3277 \NEW{} type (`{\escapegrammar .}' identifier)? arguments |
3270 . | 3278 . |
3271 \end{grammar} | 3279 \end{grammar} |
3272 | 3280 |
3273 \LMHash{} | 3281 \LMHash{} |
3274 Let $e$ be a new expression of the form | 3282 Let $e$ be a new expression of the form |
3275 | 3283 |
3276 \NEW{} $T.id(a_1, \ldots , a_n, x_{n+1}: a_{n+1}, \ldots , x_{n+k}: a_{n+k})$ or the form | 3284 \NEW{} $T.id(a_1, \ldots , a_n, x_{n+1}: a_{n+1}, \ldots , x_{n+k}: a_{n+k})$ or the form |
3277 | 3285 |
3278 \NEW{} $T(a_1, \ldots , a_n, x_{n+1}: a_{n+1}, \ldots , x_{n+k}: a_{n+k})$. | 3286 \NEW{} $T(a_1, \ldots , a_n, x_{n+1}: a_{n+1}, \ldots , x_{n+k}: a_{n+k})$. |
3279 | 3287 |
3280 %It is a runtime type error if | 3288 %It is a runtime type error if |
3281 %the type $T$ is malformed. | 3289 %the type $T$ is malformed. |
3282 %It is a static warning if $T$ is a malformed type. | 3290 %It is a static warning if $T$ is a malformed type. |
3283 | 3291 |
3284 %not a class accessible in the current scope, optionally followed by type argum ents. | 3292 %not a class accessible in the current scope, optionally followed by type argum ents. |
3285 | 3293 |
3286 \LMHash{} | 3294 \LMHash{} |
3287 If $T$ is a class or parameterized type accessible in the current scope then: | 3295 If $T$ is a class or parameterized type accessible in the current scope then: |
3288 \begin{itemize} | 3296 \begin{itemize} |
3289 \item | 3297 \item |
3290 If $e$ is of the form \NEW{} $T.id(a_1, \ldots , a_n, x_{n+1}: a_{n+1}, \ldots , x_{n+k}: a_{n+k})$ it is a static warning if $T.id$ is not the name of a constr uctor declared by the type $T$. If $e$ is of the form \NEW{} $T(a_1, \ldots , a _n, x_{n+1}: a_{n+1}, \ldots , x_{n+k}: a_{n+k})$ it is a static warning if the type $T$ does not declare a constructor with the same name as the declaration of $T$. | 3298 If $e$ is of the form \NEW{} $T.id(a_1, \ldots , a_n, x_{n+1}: a_{n+1}, \ldots , x_{n+k}: a_{n+k})$ it is a static warning if $T.id$ is not the name of a constr uctor declared by the type $T$. If $e$ is of the form \NEW{} $T(a_1, \ldots , a _n, x_{n+1}: a_{n+1}, \ldots , x_{n+k}: a_{n+k})$ it is a static warning if the type $T$ does not declare a constructor with the same name as the declaration of $T$. |
3291 \end{itemize} | 3299 \end{itemize} |
3292 | 3300 |
3293 \LMHash{} | 3301 \LMHash{} |
3294 If $T$ is a parameterized type (\ref{parameterizedTypes}) $S<U_1, \ldots, U_m>$ , let $R = S$. | 3302 If $T$ is a parameterized type (\ref{parameterizedTypes}) $S<U_1, \ldots, U_m>$ , let $R = S$. |
3295 %It is a | 3303 %It is a |
3296 %compile-time CHANGED | 3304 %compile-time CHANGED |
3297 %runtime type | 3305 %runtime type |
3298 %error if $S$ is not a generic (\ref{generics}) type with $m$ type parameters. | 3306 %error if $S$ is not a generic (\ref{generics}) type with $m$ type parameters. |
3299 If $T$ is not a parameterized type, let $R = T$. | 3307 If $T$ is not a parameterized type, let $R = T$. |
3300 Furthermore, if $e$ is of the form \NEW{} $T.id(a_1, \ldots , a_n, x_{n+1}: a_{n +1}, \ldots , x_{n+k}: a_{n+k})$ then let $q$ be the constructor $T.id$, other wise let $q$ be the constructor $T$. | 3308 Furthermore, if $e$ is of the form \NEW{} $T.id(a_1, \ldots , a_n, x_{n+1}: a_{n +1}, \ldots , x_{n+k}: a_{n+k})$ then let $q$ be the constructor $T.id$, other wise let $q$ be the constructor $T$. |
3301 | 3309 |
3302 \LMHash{} | 3310 \LMHash{} |
3303 If $R$ is a generic with $l = m$ type parameters then | 3311 If $R$ is a generic with $l = m$ type parameters then |
3304 \begin{itemize} | 3312 \begin{itemize} |
3305 \item If $T$ is not a parameterized type, then for $ i \in 1 .. l$, let $V_i = \DYNAMIC{}$. | 3313 \item If $T$ is not a parameterized type, then for $ i \in 1 .. l$, let $V_i = \DYNAMIC{}$. |
3306 \item If $T$ is a parameterized type then let $V_i = U_i$ for $ i \in 1 .. m$. | 3314 \item If $T$ is a parameterized type then let $V_i = U_i$ for $ i \in 1 .. m$. |
3307 \end{itemize} | 3315 \end{itemize} |
3308 | 3316 |
3309 \LMHash{} | 3317 \LMHash{} |
3310 If $R$ is a generic with $l \ne m$ type parameters then for $ i \in 1 .. l$, let $V_i = \DYNAMIC{}$. In any other case, let $V_i = U_i$ for $ i \in 1 .. m$. | 3318 If $R$ is a generic with $l \ne m$ type parameters then for $ i \in 1 .. l$, let $V_i = \DYNAMIC{}$. In any other case, let $V_i = U_i$ for $ i \in 1 .. m$. |
3311 | 3319 |
3312 \LMHash{} | 3320 \LMHash{} |
3313 Evaluation of $e$ proceeds as follows: | 3321 Evaluation of $e$ proceeds as follows: |
3314 | 3322 |
3315 \LMHash{} | 3323 \LMHash{} |
3316 First, the argument list $(a_1, \ldots , a_n, x_{n+1}: a_{n+1}, \ldots , x_{n+k} : a_{n+k})$ is evaluated. | 3324 First, the argument list $(a_1, \ldots , a_n, x_{n+1}: a_{n+1}, \ldots , x_{n+k} : a_{n+k})$ is evaluated. |
3317 | 3325 |
3318 \LMHash{} | 3326 \LMHash{} |
3319 If $T$ is a deferred type with prefix $p$, then if $p$ has not been successfully loaded, a dynamic error occurs. | 3327 If $T$ is a deferred type with prefix $p$, then if $p$ has not been successfully loaded, a dynamic error occurs. |
3320 | 3328 |
3321 \LMHash{} | 3329 \LMHash{} |
3322 Then, if $q$ is a non-factory constructor of an abstract class then an \code{Abs tractClassInstantiationError} is thrown. | 3330 Then, if $q$ is a non-factory constructor of an abstract class then an \code{Abs tractClassInstantiationError} is thrown. |
3323 | 3331 |
3324 \LMHash{} | 3332 \LMHash{} |
3325 If $T$ is malformed or if $T$ is a type variable a dynamic error occurs. In che cked mode, if $T$ or any of its superclasses is malbounded a dynamic error occur s. | 3333 If $T$ is malformed or if $T$ is a type variable a dynamic error occurs. In che cked mode, if $T$ or any of its superclasses is malbounded a dynamic error occur s. |
3326 Otherwise, if $q$ is not defined or not accessible, a \code{NoSuchMethodError} is thrown. If $q$ has less than $n$ positional parameters or more than $n$ req uired parameters, or if $q$ lacks any of the keyword parameters $\{ x_{n+1}, \ld ots, x_{n+k}\}$ a \code{NoSuchMethodError} is thrown. | 3334 Otherwise, if $q$ is not defined or not accessible, a \code{NoSuchMethodError} is thrown. If $q$ has less than $n$ positional parameters or more than $n$ req uired parameters, or if $q$ lacks any of the keyword parameters $\{ x_{n+1}, \ld ots, x_{n+k}\}$ a \code{NoSuchMethodError} is thrown. |
(...skipping 10 matching lines...) Expand all Loading... | |
3337 Observe that \THIS{} is not in scope in $e_f$. Hence, the initialization cannot depend on other properties of the object being instantiated. | 3345 Observe that \THIS{} is not in scope in $e_f$. Hence, the initialization cannot depend on other properties of the object being instantiated. |
3338 } | 3346 } |
3339 | 3347 |
3340 \LMHash{} | 3348 \LMHash{} |
3341 Next, $q$ is executed with \THIS{} bound to $i$, the type parameters (if any) of $R$ bound to the actual type arguments $V_1, \ldots, V_l$ and the formal par ameter bindings that resulted from the evaluation of the argument list. The resu lt of the evaluation of $e$ is $i$. | 3349 Next, $q$ is executed with \THIS{} bound to $i$, the type parameters (if any) of $R$ bound to the actual type arguments $V_1, \ldots, V_l$ and the formal par ameter bindings that resulted from the evaluation of the argument list. The resu lt of the evaluation of $e$ is $i$. |
3342 | 3350 |
3343 \LMHash{} | 3351 \LMHash{} |
3344 Otherwise, $q$ is a factory constructor (\ref{factories}). Then: | 3352 Otherwise, $q$ is a factory constructor (\ref{factories}). Then: |
3345 | 3353 |
3346 \LMHash{} | 3354 \LMHash{} |
3347 If $q$ is a redirecting factory constructor of the form $T(p_1, \ldots, p_{n+k}) = c;$ or of the form $T.id(p_1, \ldots, p_{n+k}) = c;$ then the result of the evaluation of $e$ is equivalent to evaluating the expression | 3355 If $q$ is a redirecting factory constructor of the form $T(p_1, \ldots, p_{n+k}) = c;$ or of the form $T.id(p_1, \ldots, p_{n+k}) = c;$ then the result of the evaluation of $e$ is equivalent to evaluating the expression |
3348 | 3356 |
3349 $[V_1, \ldots, V_m/T_1, \ldots, T_m]($\code{\NEW{} $c(a_1, \ldots, a_n, x_{n+1 }: a_{n+1}, \ldots, x_{n+k}: a_{n+k}))$}. If evaluation of $q$ causes $q$ to be re-evaluated cyclically, a runtime error occurs. | 3357 $[V_1, \ldots, V_m/T_1, \ldots, T_m]($\code{\NEW{} $c(a_1, \ldots, a_n, x_{n+1 }: a_{n+1}, \ldots, x_{n+k}: a_{n+k}))$}. If evaluation of $q$ causes $q$ to be re-evaluated cyclically, a runtime error occurs. |
3350 | 3358 |
3351 | 3359 |
3352 \LMHash{} | 3360 \LMHash{} |
3353 Otherwise, the body of $q$ is executed with respect to the bindings that resulte d from the evaluation of the argument list and the type parameters (if any) of $ q$ bound to the actual type arguments $V_1, \ldots, V_l$ resulting in an object $i$. The result of the evaluation of $e$ is $i$. | 3361 Otherwise, the body of $q$ is executed with respect to the bindings that resulte d from the evaluation of the argument list and the type parameters (if any) of $ q$ bound to the actual type arguments $V_1, \ldots, V_l$ resulting in an object $i$. The result of the evaluation of $e$ is $i$. |
3354 | 3362 |
3355 \LMHash{} | 3363 \LMHash{} |
3356 It is a static warning if $q$ is a constructor of an abstract class and $q$ is n ot a factory constructor. | 3364 It is a static warning if $q$ is a constructor of an abstract class and $q$ is n ot a factory constructor. |
3357 | 3365 |
3358 \commentary{The above gives precise meaning to the idea that instantiating an ab stract class leads to a warning. | 3366 \commentary{The above gives precise meaning to the idea that instantiating an ab stract class leads to a warning. |
3359 A similar clause applies to constant object creation in the next section. | 3367 A similar clause applies to constant object creation in the next section. |
3360 } | 3368 } |
3361 | 3369 |
3362 \rationale{In particular, a factory constructor can be declared in an abstract c lass and used safely, as it will either produce a valid instance or lead to a wa rning inside its own declaration. | 3370 \rationale{In particular, a factory constructor can be declared in an abstract c lass and used safely, as it will either produce a valid instance or lead to a wa rning inside its own declaration. |
3363 } | 3371 } |
3364 | 3372 |
3365 \LMHash{} | 3373 \LMHash{} |
3366 The static type of an instance creation expression of either the form | 3374 The static type of an instance creation expression of either the form |
3367 | 3375 |
3368 \NEW{} $T.id(a_1, \ldots , a_n, x_{n+1}: a_{n+1}, \ldots , x_{n+k}: a_{n+k})$ | 3376 \NEW{} $T.id(a_1, \ldots , a_n, x_{n+1}: a_{n+1}, \ldots , x_{n+k}: a_{n+k})$ |
3369 | 3377 |
3370 or the form | 3378 or the form |
3371 | 3379 |
3372 \NEW{} $T(a_1, \ldots , a_n, x_{n+1}: a_{n+1}, \ldots , x_{n+k}: a_{n+k})$ | 3380 \NEW{} $T(a_1, \ldots , a_n, x_{n+1}: a_{n+1}, \ldots , x_{n+k}: a_{n+k})$ |
3373 | 3381 |
3374 is $T$. | 3382 is $T$. |
3375 It is a static warning if the static type of $a_i, 1 \le i \le n+ k$ may not be assigned to the type of the corresponding formal parameter of the constructor $T .id$ (respectively $T$). | 3383 It is a static warning if the static type of $a_i, 1 \le i \le n+ k$ may not be assigned to the type of the corresponding formal parameter of the constructor $T .id$ (respectively $T$). |
3376 | 3384 |
3377 | 3385 |
3378 | 3386 |
3379 \subsubsection{ Const} | 3387 \subsubsection{ Const} |
3380 \LMLabel{const} | 3388 \LMLabel{const} |
3381 | 3389 |
3382 \LMHash{} | 3390 \LMHash{} |
3383 A {\em constant object expression} invokes a constant constructor (\ref{constant Constructors}). | 3391 A {\em constant object expression} invokes a constant constructor (\ref{constant Constructors}). |
3384 | 3392 |
3385 \begin{grammar} | 3393 \begin{grammar} |
3386 {\bf constObjectExpression:} | 3394 {\bf constObjectExpression:} |
3387 \CONST{} type ('{\escapegrammar .}' identifier)? arguments | 3395 \CONST{} type ('{\escapegrammar .}' identifier)? arguments |
3388 . | 3396 . |
3389 \end{grammar} | 3397 \end{grammar} |
3390 | 3398 |
3391 \LMHash{} | 3399 \LMHash{} |
3392 Let $e$ be a constant object expression of the form | 3400 Let $e$ be a constant object expression of the form |
3393 | 3401 |
3394 \CONST{} $T.id(a_1, \ldots , a_n, x_{n+1}: a_{n+1}, \ldots , x_{n+k}: a_{n+k})$ | 3402 \CONST{} $T.id(a_1, \ldots , a_n, x_{n+1}: a_{n+1}, \ldots , x_{n+k}: a_{n+k})$ |
3395 | 3403 |
3396 or the form \CONST{} $T(a_1, \ldots , a_n, x_{n+1}: a_{n+1}, \ldots , x_{n+k}: a_{n+k})$. It is a compile-time error if $T$ does not denote a class accessible in the current scope. It is a compile-time error if $T$ is a deferred type (\re f{staticTypes}). | 3404 or the form \CONST{} $T(a_1, \ldots , a_n, x_{n+1}: a_{n+1}, \ldots , x_{n+k}: a_{n+k})$. It is a compile-time error if $T$ does not denote a class accessible in the current scope. It is a compile-time error if $T$ is a deferred type (\re f{staticTypes}). |
3397 | 3405 |
3398 \commentary{In particular, $T$ may not be a type variable.} | 3406 \commentary{In particular, $T$ may not be a type variable.} |
3399 | 3407 |
3400 \LMHash{} | 3408 \LMHash{} |
3401 If $T$ is a parameterized type, it is a compile-time error if $T$ includes a typ e variable among its type arguments. | 3409 If $T$ is a parameterized type, it is a compile-time error if $T$ includes a typ e variable among its type arguments. |
3402 | 3410 |
3403 \LMHash{} | 3411 \LMHash{} |
3404 If $e$ is of the form \CONST{} $T.id(a_1, \ldots , a_n, x_{n+1}: a_{n+1}, \ldots , x_{n+k}: a_{n+k})$ it is a compile-time error if $T.id$ is not the name of a constant constructor declared by the type $T$. If $e$ is of the form \CONST{} $ T(a_1, \ldots , a_n, x_{n+1}: a_{n+1}, \ldots , x_{n+k}: a_{n+k})$ it is a compi le-time error if the type $T$ does not declare a constant constructor with the s ame name as the declaration of $T$. | 3412 If $e$ is of the form \CONST{} $T.id(a_1, \ldots , a_n, x_{n+1}: a_{n+1}, \ldots , x_{n+k}: a_{n+k})$ it is a compile-time error if $T.id$ is not the name of a constant constructor declared by the type $T$. If $e$ is of the form \CONST{} $ T(a_1, \ldots , a_n, x_{n+1}: a_{n+1}, \ldots , x_{n+k}: a_{n+k})$ it is a compi le-time error if the type $T$ does not declare a constant constructor with the s ame name as the declaration of $T$. |
3405 | 3413 |
3406 \LMHash{} | 3414 \LMHash{} |
3407 In all of the above cases, it is a compile-time error if $a_i, i\in 1 .. n + k$ , is not a compile-time constant expression. | 3415 In all of the above cases, it is a compile-time error if $a_i, i\in 1 .. n + k$ , is not a compile-time constant expression. |
3408 | 3416 |
3409 %If $T$ is a parameterized type (\ref{parameterizedTypes}) $S<U_1, \ldots, U_m> $, let $R = S$. It is a compile-time error if $T$ is is malformed. If $T$ is no t a parameterized type, let $R = T$. | 3417 %If $T$ is a parameterized type (\ref{parameterizedTypes}) $S<U_1, \ldots, U_m> $, let $R = S$. It is a compile-time error if $T$ is is malformed. If $T$ is no t a parameterized type, let $R = T$. |
3410 %Finally, | 3418 %Finally, |
3411 % If $T$ is a generic with $l$ retype parameters, then for all $ i \in 1 .. l$, let $V_i = \DYNAMIC{}$. | 3419 % If $T$ is a generic with $l$ retype parameters, then for all $ i \in 1 .. l$, let $V_i = \DYNAMIC{}$. |
3412 | 3420 |
3413 \LMHash{} | 3421 \LMHash{} |
3414 Evaluation of $e$ proceeds as follows: | 3422 Evaluation of $e$ proceeds as follows: |
3415 | 3423 |
3416 \LMHash{} | 3424 \LMHash{} |
3417 First, if $e$ is of the form | 3425 First, if $e$ is of the form |
3418 | 3426 |
3419 \CONST{} $T.id(a_1, \ldots , a_n, x_{n+1}: a_{n+1}, \ldots , x_{n+k}: a_{n+k})$ | 3427 \CONST{} $T.id(a_1, \ldots , a_n, x_{n+1}: a_{n+1}, \ldots , x_{n+k}: a_{n+k})$ |
3420 | 3428 |
3421 then let $i$ be the value of the expression | 3429 then let $i$ be the value of the expression |
3422 | 3430 |
3423 \NEW{} $T.id(a_1, \ldots , a_n, x_{n+1}: a_{n+1}, \ldots , x_{n+k}: a_{n+k})$. | 3431 \NEW{} $T.id(a_1, \ldots , a_n, x_{n+1}: a_{n+1}, \ldots , x_{n+k}: a_{n+k})$. |
3424 | 3432 |
3425 \LMHash{} | 3433 \LMHash{} |
3426 Otherwise, $e$ must be of the form | 3434 Otherwise, $e$ must be of the form |
3427 | 3435 |
3428 \CONST{} $T(a_1, \ldots , a_n, x_{n+1}: a_{n+1}, \ldots , x_{n+k}: a_{n+k})$, | 3436 \CONST{} $T(a_1, \ldots , a_n, x_{n+1}: a_{n+1}, \ldots , x_{n+k}: a_{n+k})$, |
3429 | 3437 |
3430 in which case let $i$ be the result of evaluating | 3438 in which case let $i$ be the result of evaluating |
3431 | 3439 |
3432 \NEW{} $T(a_1, \ldots , a_n, x_{n+1}: a_{n+1}, \ldots , x_{n+k}: a_{n+k})$. | 3440 \NEW{} $T(a_1, \ldots , a_n, x_{n+1}: a_{n+1}, \ldots , x_{n+k}: a_{n+k})$. |
3433 | 3441 |
3434 \LMHash{} | 3442 \LMHash{} |
3435 Then: | 3443 Then: |
3436 \begin{itemize} | 3444 \begin{itemize} |
3437 \item If during execution of the program, a constant object expression has alrea dy evaluated to an instance $j$ of class $R$ with type arguments $V_i, 1 \le i \ le m$, then: | 3445 \item If during execution of the program, a constant object expression has alrea dy evaluated to an instance $j$ of class $R$ with type arguments $V_i, 1 \le i \ le m$, then: |
3438 \begin{itemize} | 3446 \begin{itemize} |
3439 \item For each instance variable $f$ of $i$, let $v_{if}$ be the value of the fi eld $f$ in $i$, and let $v_{jf}$ be the value of the field $f$ in $j$. If \code {identical($v_{if}$, $v_{jf}$)} for all fields $f$ in $i$, then the value of $e$ is $j$, otherwise the value of $e$ is $i$. | 3447 \item For each instance variable $f$ of $i$, let $v_{if}$ be the value of the fi eld $f$ in $i$, and let $v_{jf}$ be the value of the field $f$ in $j$. If \code {identical($v_{if}$, $v_{jf}$)} for all fields $f$ in $i$, then the value of $e$ is $j$, otherwise the value of $e$ is $i$. |
3440 \end{itemize} | 3448 \end{itemize} |
3441 \item Otherwise the value of $e$ is $i$. | 3449 \item Otherwise the value of $e$ is $i$. |
3442 \end{itemize} | 3450 \end{itemize} |
3443 | 3451 |
3444 \commentary{ | 3452 \commentary{ |
3445 In other words, constant objects are canonicalized. In order to determine if an object is actually new, one has to compute it; then it can be compared to any c ached instances. If an equivalent object exists in the cache, we throw away the newly created object and use the cached one. Objects are equivalent if they have identical fields and identical type arguments. Since the constructor cannot ind uce any side effects, the execution of the constructor is unobservable. The con structor need only be executed once per call site, at compile-time. | 3453 In other words, constant objects are canonicalized. In order to determine if an object is actually new, one has to compute it; then it can be compared to any c ached instances. If an equivalent object exists in the cache, we throw away the newly created object and use the cached one. Objects are equivalent if they have identical fields and identical type arguments. Since the constructor cannot ind uce any side effects, the execution of the constructor is unobservable. The con structor need only be executed once per call site, at compile-time. |
3446 } | 3454 } |
3447 | 3455 |
3448 \LMHash{} | 3456 \LMHash{} |
3449 The static type of a constant object expression of either the form | 3457 The static type of a constant object expression of either the form |
3450 | 3458 |
3451 \CONST{} $T.id(a_1, \ldots , a_n, x_{n+1}: a_{n+1}, \ldots , x_{n+k}: a_{n+k})$ | 3459 \CONST{} $T.id(a_1, \ldots , a_n, x_{n+1}: a_{n+1}, \ldots , x_{n+k}: a_{n+k})$ |
3452 | 3460 |
3453 or the form | 3461 or the form |
3454 | 3462 |
3455 \CONST{} $T(a_1, \ldots , a_n, x_{n+1}: a_{n+1}, \ldots , x_{n+k}: a_{n+k})$ | 3463 \CONST{} $T(a_1, \ldots , a_n, x_{n+1}: a_{n+1}, \ldots , x_{n+k}: a_{n+k})$ |
3456 | 3464 |
3457 is $T$. It is a static warning if the static type of $a_i, 1 \le i \le n+ k$ may not be assigned to the type of the corresponding formal parameter of the constr uctor $T.id$ (respectively $T$). | 3465 is $T$. It is a static warning if the static type of $a_i, 1 \le i \le n+ k$ may not be assigned to the type of the corresponding formal parameter of the constr uctor $T.id$ (respectively $T$). |
3458 | 3466 |
3459 \LMHash{} | 3467 \LMHash{} |
3460 It is a compile-time error if evaluation of a constant object results in an unca ught exception being thrown. | 3468 It is a compile-time error if evaluation of a constant object results in an unca ught exception being thrown. |
3461 | 3469 |
3462 \commentary{ | 3470 \commentary{ |
3463 To see how such situations might arise, consider the following examples: | 3471 To see how such situations might arise, consider the following examples: |
3464 } | 3472 } |
3465 | 3473 |
(...skipping 11 matching lines...) Expand all Loading... | |
3477 \CONST{} IntPair(\THIS{}.x, \THIS{}.y); | 3485 \CONST{} IntPair(\THIS{}.x, \THIS{}.y); |
3478 \FINAL{} int x; | 3486 \FINAL{} int x; |
3479 \FINAL{} int y; | 3487 \FINAL{} int y; |
3480 \OPERATOR *(v) $=>$ \NEW{} IntPair(x*v, y*v); | 3488 \OPERATOR *(v) $=>$ \NEW{} IntPair(x*v, y*v); |
3481 \} | 3489 \} |
3482 | 3490 |
3483 \CONST{} A(\CONST{} IntPair(1,2)); // compile-time error: illegal in a subtler w ay | 3491 \CONST{} A(\CONST{} IntPair(1,2)); // compile-time error: illegal in a subtler w ay |
3484 \end{dartCode} | 3492 \end{dartCode} |
3485 | 3493 |
3486 \commentary{ | 3494 \commentary{ |
3487 Due to the rules governing constant constructors, evaluating the constructor \co de{A()} with the argument \code{''x''} or the argument \code{\CONST{} IntPair(1, 2)} would cause it to throw an exception, resulting in a compile-time error. | 3495 Due to the rules governing constant constructors, evaluating the constructor \co de{A()} with the argument \code{"x"} or the argument \code{\CONST{} IntPair(1, 2 )} would cause it to throw an exception, resulting in a compile-time error. |
3488 } | 3496 } |
3489 | 3497 |
3490 | 3498 |
3491 \LMHash{} | 3499 \LMHash{} |
3492 Given an instance creation expression of the form \CONST{} $q(a_1, \ldots , a_n) $ it is a static warning if $q$ is a constructor of an abstract class (\ref{abs tractInstanceMembers}) but $q$ is not a factory constructor. | 3500 Given an instance creation expression of the form \CONST{} $q(a_1, \ldots , a_n) $ it is a static warning if $q$ is a constructor of an abstract class (\ref{abs tractInstanceMembers}) but $q$ is not a factory constructor. |
3493 | 3501 |
3494 | 3502 |
3495 \subsection{ Spawning an Isolate} | 3503 \subsection{ Spawning an Isolate} |
3496 \LMLabel{spawningAnIsolate} | 3504 \LMLabel{spawningAnIsolate} |
3497 | 3505 |
3498 \LMHash{} | 3506 \LMHash{} |
3499 Spawning an isolate is accomplished via what is syntactically an ordinary librar y call, invoking one of the functions \code{spawnUri()} or \code{spawn()} define d in the \code{dart:isolate} library. However, such calls have the semantic ef fect of creating a new isolate with its own memory and thread of control. | 3507 Spawning an isolate is accomplished via what is syntactically an ordinary librar y call, invoking one of the functions \code{spawnUri()} or \code{spawn()} define d in the \code{dart:isolate} library. However, such calls have the semantic ef fect of creating a new isolate with its own memory and thread of control. |
3500 | 3508 |
3501 \LMHash{} | 3509 \LMHash{} |
3502 An isolate's memory is finite, as is the space available to its thread's call st ack. It is possible for a running isolate to exhaust its memory or stack, result ing in a run-time error that cannot be effectively caught, which will force the isolate to be suspended. | 3510 An isolate's memory is finite, as is the space available to its thread's call st ack. It is possible for a running isolate to exhaust its memory or stack, result ing in a run-time error that cannot be effectively caught, which will force the isolate to be suspended. |
3503 | 3511 |
3504 \commentary{ | 3512 \commentary{ |
3505 As discussed in section \ref{errorsAndWarnings}, the handling of a suspended iso late is the responsibility of the embedder. | 3513 As discussed in section \ref{errorsAndWarnings}, the handling of a suspended iso late is the responsibility of the embedder. |
3506 } | 3514 } |
3507 | 3515 |
3508 | 3516 |
3509 | 3517 |
3510 \subsection{ Function Invocation} | 3518 \subsection{ Function Invocation} |
3511 \LMLabel{functionInvocation} | 3519 \LMLabel{functionInvocation} |
3512 | |
3513 \LMHash{} | |
3514 Function invocation occurs in the following cases: when a function expression ( \ref{functionExpressions}) is invoked (\ref{functionExpressionInvocation}), when a method (\ref{methodInvocation}), getter (\ref{topLevelGetterInvocation}, \ref {propertyExtraction}) or setter (\ref{assignment}) is invoked or when a construc tor is invoked (either via instance creation (\ref{instanceCreation}), construct or redirection (\ref{redirectingConstructors}) or super initialization). The var ious kinds of function invocation differ as to how the function to be invoked, $ f$, is determined, as well as whether \THIS{} (\ref{this}) is bound. Once $f$ h as been determined, the formal parameters of $f$ are bound to corresponding actu al arguments. When the body of $f$ is executed it will be executed with the afor ementioned bindings. | |
3515 | 3520 |
3516 \LMHash{} | 3521 \LMHash{} |
3517 If $f$ is marked \ASYNC{} (\ref{functions}), then a fresh instance (\ref{generat iveConstructors}) $o$ implementing the built-in class \code{Future} is associate d with the invocation and immediately returned to the caller. The body of $f$ is scheduled for execution at some future time. The future $o$ will complete when $f$ terminates. The value used to complete $o$ is the current return value (\ref {return}), if it is defined, and the current exception (\ref{throw}) otherwise. | 3522 Function invocation occurs in the following cases: when a function expression ( \ref{functionExpressions}) is invoked (\ref{functionExpressionInvocation}), when a method (\ref{methodInvocation}), getter (\ref{topLevelGetterInvocation}, \ref {propertyExtraction}) or setter (\ref{assignment}) is invoked or when a construc tor is invoked (either via instance creation (\ref{instanceCreation}), construct or redirection (\ref{redirectingConstructors}) or super initialization). The var ious kinds of function invocation differ as to how the function to be invoked, $ f$, is determined, as well as whether \THIS{} (\ref{this}) is bound. Once $f$ h as been determined, the formal parameters of $f$ are bound to corresponding actu al arguments. When the body of $f$ is executed it will be executed with the afor ementioned bindings. |
3523 | |
3524 \LMHash{} | |
3525 If $f$ is marked \ASYNC{} (\ref{functions}), then a fresh instance (\ref{generat iveConstructors}) $o$ implementing the built-in class \code{Future} is associate d with the invocation and immediately returned to the caller. The body of $f$ is scheduled for execution at some future time. The future $o$ will complete when $f$ terminates. The value used to complete $o$ is the current return value (\ref {return}), if it is defined, and the current exception (\ref{throw}) otherwise. | |
3518 | 3526 |
3519 \LMHash{} | 3527 \LMHash{} |
3520 If $f$ is marked \ASYNC* (\ref{functions}), then a fresh instance $s$ implementi ng the built-in class \code{Stream} is associated with the invocation and immedi ately returned. When $s$ is listened to, execution of the body of $f$ will begin . When $f$ terminates: | 3528 If $f$ is marked \ASYNC* (\ref{functions}), then a fresh instance $s$ implementi ng the built-in class \code{Stream} is associated with the invocation and immedi ately returned. When $s$ is listened to, execution of the body of $f$ will begin . When $f$ terminates: |
3521 \begin{itemize} | 3529 \begin{itemize} |
3522 \item If the current return value is defined then, if $s$ has been canceled then its cancellation future is completed with \NULL{} (\ref{null}). | 3530 \item If the current return value is defined then, if $s$ has been canceled then its cancellation future is completed with \NULL{} (\ref{null}). |
3523 \item If the current exception $x$ is defined: | 3531 \item If the current exception $x$ is defined: |
3524 \begin{itemize} | 3532 \begin{itemize} |
3525 \item $x$ is added to $s$. | 3533 \item $x$ is added to $s$. |
3526 \item If $s$ has been canceled then its cancellation future is completed with $x$ as an error. | 3534 \item If $s$ has been canceled then its cancellation future is completed with $x$ as an error. |
3527 \end{itemize} | 3535 \end{itemize} |
3528 \item $s$ is closed. | 3536 \item $s$ is closed. |
3529 \end{itemize} | 3537 \end{itemize} |
3530 | 3538 |
3531 \rationale{ | 3539 \rationale{ |
3532 When an asynchronous generator's stream has been canceled, cleanup will occur in the \FINALLY{} clauses (\ref{try}) inside the generator. We choose to direct an y exceptions that occur at this time to the cancellation future rather than have them be lost. | 3540 When an asynchronous generator's stream has been canceled, cleanup will occur in the \FINALLY{} clauses (\ref{try}) inside the generator. We choose to direct an y exceptions that occur at this time to the cancellation future rather than have them be lost. |
3533 } | 3541 } |
3534 | 3542 |
3535 \LMHash{} | 3543 \LMHash{} |
3536 If $f$ is asynchronous then, when $f$ terminates, any open stream subscriptions associated with any asynchronous for loops (\ref{asynchronousFor-in}) or yield- each statements (\ref{yieldEach}) executing within $f$ are canceled, in the ord er of their nesting, innermost first. | 3544 If $f$ is asynchronous then, when $f$ terminates, any open stream subscriptions associated with any asynchronous for loops (\ref{asynchronousFor-in}) or yield- each statements (\ref{yieldEach}) executing within $f$ are canceled, in the ord er of their nesting, innermost first. |
3537 | 3545 |
3538 \rationale{Such streams may be left open by for loops that were escaped when an exception was thrown within them for example. | 3546 \rationale{Such streams may be left open by for loops that were escaped when an exception was thrown within them for example. |
3539 } | 3547 } |
3540 | 3548 |
3541 %\LMHash{} | 3549 %\LMHash{} |
3542 %When a stream is canceled, the implementation must wait for the cancelation fut ure returned by \cd{cancell()} to complete before proceeding. | 3550 %When a stream is canceled, the implementation must wait for the cancelation fut ure returned by \cd{cancell()} to complete before proceeding. |
3543 | 3551 |
3544 \LMHash{} | 3552 \LMHash{} |
3545 If $f$ is marked \SYNC* (\ref{functions}), then a fresh instance $i$ implementin g the built-in class \code{Iterable} is associated with the invocation and immed iately returned. | 3553 If $f$ is marked \SYNC* (\ref{functions}), then a fresh instance $i$ implementin g the built-in class \code{Iterable} is associated with the invocation and immed iately returned. |
3546 | 3554 |
3547 | 3555 |
3548 \commentary{ | 3556 \commentary{ |
3549 A Dart implementation will need to provide a specific implementation of \code{It erable} that will be returned by \SYNC* methods. A typical strategy would be to produce an instance of a subclass of class \code{IterableBase} defined in \code{ dart:core}. The only method that needs to be added by the Dart implementation in that case is \code{iterator}. | 3557 A Dart implementation will need to provide a specific implementation of \code{It erable} that will be returned by \SYNC* methods. A typical strategy would be to produce an instance of a subclass of class \code{IterableBase} defined in \code{ dart:core}. The only method that needs to be added by the Dart implementation in that case is \code{iterator}. |
3550 } | 3558 } |
3551 | 3559 |
3552 \LMHash{} | 3560 \LMHash{} |
3553 The iterable implementation must comply with the contract of \code{Iterable} and should not take any steps identified as exceptionally efficient in that contrac t. | 3561 The iterable implementation must comply with the contract of \code{Iterable} and should not take any steps identified as exceptionally efficient in that contrac t. |
3554 | 3562 |
3555 \commentary { | 3563 \commentary { |
3556 The contract explicitly mentions a number of situations where certain iterables could be more efficient than normal. For example, by precomputing their length. Normal iterables must iterate over their elements to determine their length. Thi s is certainly true in the case of a synchronous generator, where each element i s computed by a function. It would not be acceptable to pre-compute the results of the generator and cache them, for example. | 3564 The contract explicitly mentions a number of situations where certain iterables could be more efficient than normal. For example, by precomputing their length. Normal iterables must iterate over their elements to determine their length. Thi s is certainly true in the case of a synchronous generator, where each element i s computed by a function. It would not be acceptable to pre-compute the results of the generator and cache them, for example. |
3557 } | 3565 } |
3558 | 3566 |
3559 \LMHash{} | 3567 \LMHash{} |
3560 When iteration over the iterable is started, by getting an iterator $j$ from the iterable and calling \code{moveNext()}, execution of the body of $f$ will begin . When $f$ terminates, $j$ is positioned after its last element, so that its cur rent value is \NULL{} and the current call to \code{moveNext()} on $j$ returns f alse, as will all further calls. | 3568 When iteration over the iterable is started, by getting an iterator $j$ from the iterable and calling \code{moveNext()}, execution of the body of $f$ will begin . When $f$ terminates, $j$ is positioned after its last element, so that its cur rent value is \NULL{} and the current call to \code{moveNext()} on $j$ returns f alse, as will all further calls. |
3561 | 3569 |
3562 Each iterator starts a separate computation. If the \SYNC* function is impure, t he sequence of values yielded by each iterator may differ. | 3570 Each iterator starts a separate computation. If the \SYNC* function is impure, t he sequence of values yielded by each iterator may differ. |
3563 | 3571 |
3564 \commentary{ | 3572 \commentary{ |
3565 One can derive more than one iterator from a given iterable. Note that operati ons on the iterable itself can create distinct iterators. An example would be \c ode{length}. It is conceivable that different iterators might yield sequences o f different length. The same care needs to be taken when writing \SYNC* function s as when | 3573 One can derive more than one iterator from a given iterable. Note that operati ons on the iterable itself can create distinct iterators. An example would be \c ode{length}. It is conceivable that different iterators might yield sequences o f different length. The same care needs to be taken when writing \SYNC* function s as when |
3566 writing an \code{Iterator} class. In particular, it should handle multiple | 3574 writing an \code{Iterator} class. In particular, it should handle multiple |
3567 simultaneous iterators gracefully. If the iterator depends on external state | 3575 simultaneous iterators gracefully. If the iterator depends on external state |
3568 that might change, it should check that the state is still valid after every | 3576 that might change, it should check that the state is still valid after every |
3569 yield (and maybe throw a \code{ConcurrentModificationError} if it isn't). | 3577 yield (and maybe throw a \code{ConcurrentModificationError} if it isn't). |
3570 } | 3578 } |
3571 | 3579 |
3572 \LMHash{} | 3580 \LMHash{} |
3573 Each iterator runs with its own shallow copies of all local variables; in partic ular, each iterator has the same initial arguments, even if their bindings are m odified by the function. | 3581 Each iterator runs with its own shallow copies of all local variables; in partic ular, each iterator has the same initial arguments, even if their bindings are m odified by the function. |
3574 \commentary{ | 3582 \commentary{ |
3575 Two executions of an iterator interact only via state outside the function. | 3583 Two executions of an iterator interact only via state outside the function. |
3576 } | 3584 } |
3577 % The alternative would be to cache the results of an iterator in the iterable, and check the cache at each \YIELD{}. This would have strange issues as well. T he yielded value might differ from the expression in the yield. And it is a pote ntial memory leak as the cache is kept alive by any iterator. | 3585 % The alternative would be to cache the results of an iterator in the iterable, and check the cache at each \YIELD{}. This would have strange issues as well. T he yielded value might differ from the expression in the yield. And it is a pote ntial memory leak as the cache is kept alive by any iterator. |
3578 | 3586 |
3579 | 3587 |
3580 \LMHash{} | 3588 \LMHash{} |
3581 If $f$ is synchronous and is not a generator (\ref{functions}) then execution of the body of $f$ begins immediately. When $f$ terminates the current return val ue is returned to the caller. | 3589 If $f$ is synchronous and is not a generator (\ref{functions}) then execution of the body of $f$ begins immediately. When $f$ terminates the current return val ue is returned to the caller. |
3582 | 3590 |
3583 | 3591 |
3584 \LMHash{} | 3592 \LMHash{} |
3585 Execution of $f$ terminates when the first of the following occurs: | 3593 Execution of $f$ terminates when the first of the following occurs: |
3586 \begin{itemize} | 3594 \begin{itemize} |
3587 \item An exception is thrown and not caught within the current function activati on. | 3595 \item An exception is thrown and not caught within the current function activati on. |
3588 \item A return statement (\ref{return}) immediately nested in the body of $f$ is executed and not intercepted in a \FINALLY{} (\ref{try}) clause. | 3596 \item A return statement (\ref{return}) immediately nested in the body of $f$ is executed and not intercepted in a \FINALLY{} (\ref{try}) clause. |
3589 \item The last statement of the body completes execution. | 3597 \item The last statement of the body completes execution. |
3590 \end{itemize} | 3598 \end{itemize} |
3591 | 3599 |
3592 | 3600 |
3593 | 3601 |
3594 | 3602 |
3595 \subsubsection{ Actual Argument List Evaluation} | 3603 \subsubsection{ Actual Argument List Evaluation} |
3596 \LMLabel{actualArguments} | 3604 \LMLabel{actualArguments} |
3597 | 3605 |
(...skipping 10 matching lines...) Expand all Loading... | |
3608 expressionList (`,' namedArgument)* | 3616 expressionList (`,' namedArgument)* |
3609 % spreadArgument | 3617 % spreadArgument |
3610 . | 3618 . |
3611 | 3619 |
3612 {\bf namedArgument:} | 3620 {\bf namedArgument:} |
3613 label expression % could be top level expression? | 3621 label expression % could be top level expression? |
3614 . | 3622 . |
3615 \end{grammar} | 3623 \end{grammar} |
3616 | 3624 |
3617 \LMHash{} | 3625 \LMHash{} |
3618 Evaluation of an actual argument list of the form | 3626 Evaluation of an actual argument list of the form |
3619 | 3627 |
3620 $(a_1, \ldots, a_m, q_1: a_{m+1}, \ldots, q_l: a_{m+l})$ | 3628 $(a_1, \ldots, a_m, q_1: a_{m+1}, \ldots, q_l: a_{m+l})$ |
3621 | 3629 |
3622 proceeds as follows: | 3630 proceeds as follows: |
3623 | 3631 |
3624 \LMHash{} | 3632 \LMHash{} |
3625 The arguments $a_1, \ldots, a_{m+l}$ are evaluated in the order they appear in t he program, yielding objects $o_1, \ldots, o_{m+l}$. | 3633 The arguments $a_1, \ldots, a_{m+l}$ are evaluated in the order they appear in t he program, yielding objects $o_1, \ldots, o_{m+l}$. |
3626 | 3634 |
3627 \commentary{Simply stated, an argument list consisting of $m$ positional argumen ts and $l$ named arguments is evaluated from left to right. | 3635 \commentary{Simply stated, an argument list consisting of $m$ positional argumen ts and $l$ named arguments is evaluated from left to right. |
3628 } | 3636 } |
3629 | 3637 |
3630 | 3638 |
3631 \subsubsection{ Binding Actuals to Formals} | 3639 \subsubsection{ Binding Actuals to Formals} |
3632 \LMLabel{bindingActualsToFormals} | 3640 \LMLabel{bindingActualsToFormals} |
3633 | 3641 |
3634 \LMHash{} | 3642 \LMHash{} |
3635 Let $f$ be a function with $h$ required parameters, let $p_1 \ldots p_n$ be the positional parameters of $f$ and let $p_{h+1}, \ldots, p_{h+k}$ be the optional parameters declared by $f$. | 3643 Let $f$ be a function with $h$ required parameters, let $p_1 \ldots p_n$ be the positional parameters of $f$ and let $p_{h+1}, \ldots, p_{h+k}$ be the optional parameters declared by $f$. |
3636 | 3644 |
3637 \LMHash{} | 3645 \LMHash{} |
3638 An evaluated actual argument list $o_1 \ldots o_{m+l}$ derived from an actual ar gument list of the form $(a_1, \ldots, a_m, q_1: a_{m+1}, \ldots, q_l: a_{m+l})$ is bound to the formal parameters of $f$ as follows: | 3646 An evaluated actual argument list $o_1 \ldots o_{m+l}$ derived from an actual ar gument list of the form $(a_1, \ldots, a_m, q_1: a_{m+1}, \ldots, q_l: a_{m+l})$ is bound to the formal parameters of $f$ as follows: |
3639 | 3647 |
3640 \commentary{ | 3648 \commentary{ |
3641 We have an argument list consisting of $m$ positional arguments and $l$ named ar guments. We have a function with $h$ required parameters and $k$ optional parame ters. The number of positional arguments must be at least as large as the number of required parameters, and no larger than the number of positional parameters. All named arguments must have a corresponding named parameter. You may not prov ide a given named argument more than once. If an optional parameter has no corr esponding argument, it gets its default value. In checked mode, all arguments mu st belong to subtypes of the type of their corresponding formal. | 3649 We have an argument list consisting of $m$ positional arguments and $l$ named ar guments. We have a function with $h$ required parameters and $k$ optional parame ters. The number of positional arguments must be at least as large as the number of required parameters, and no larger than the number of positional parameters. All named arguments must have a corresponding named parameter. You may not prov ide a given named argument more than once. If an optional parameter has no corr esponding argument, it gets its default value. In checked mode, all arguments mu st belong to subtypes of the type of their corresponding formal. |
3642 } | 3650 } |
3643 | 3651 |
3644 \commentary{ | 3652 \commentary{ |
3645 If $l > 0$, then it is necessarily the case that $n = h$, because a method canno t have both optional positional parameters and named parameters. | 3653 If $l > 0$, then it is necessarily the case that $n = h$, because a method canno t have both optional positional parameters and named parameters. |
3646 } | 3654 } |
3647 | 3655 |
3648 | 3656 |
3649 \LMHash{} | 3657 \LMHash{} |
3650 If $m < h$, or $m > n$, a \cd{NoSuchMethodError} is thrown. Furthermore, each $ q_i, 1 \le i \le l$, must have a corresponding named parameter in the set $\{p_ {n+1}, \ldots, p_{n +k}\}$ or a \cd{NoSuchMethodError} is thrown. Then $p_i$ is bound to $o_i, i \in 1.. m$, and $q_j$ is bound to $o_{m+j}, j \in 1.. l$. All remaining formal parameters of $f$ are bound to their default values. | 3658 If $m < h$, or $m > n$, a \cd{NoSuchMethodError} is thrown. Furthermore, each $ q_i, 1 \le i \le l$, must have a corresponding named parameter in the set $\{p_ {n+1}, \ldots, p_{n +k}\}$ or a \cd{NoSuchMethodError} is thrown. Then $p_i$ is bound to $o_i, i \in 1.. m$, and $q_j$ is bound to $o_{m+j}, j \in 1.. l$. All remaining formal parameters of $f$ are bound to their default values. |
3651 | 3659 |
3652 \commentary{All of these remaining parameters are necessarily optional and thus have default values.} | 3660 \commentary{All of these remaining parameters are necessarily optional and thus have default values.} |
3653 | 3661 |
3654 \LMHash{} | 3662 \LMHash{} |
3655 In checked mode, it is a dynamic type error if $o_i$ is not \NULL{} and the act ual type (\ref{actualTypeOfADeclaration}) of $p_i$ is not a supertype of the ty pe of $o_i, i \in 1.. m$. In checked mode, it is a dynamic type error if $o_{m+ j}$ is not \NULL{} and the actual type (\ref{actualTypeOfADeclaration}) of $q_j $ is not a supertype of the type of $o_{m+j}, j \in 1.. l$. | 3663 In checked mode, it is a dynamic type error if $o_i$ is not \NULL{} and the act ual type (\ref{actualTypeOfADeclaration}) of $p_i$ is not a supertype of the ty pe of $o_i, i \in 1.. m$. In checked mode, it is a dynamic type error if $o_{m+ j}$ is not \NULL{} and the actual type (\ref{actualTypeOfADeclaration}) of $q_j $ is not a supertype of the type of $o_{m+j}, j \in 1.. l$. |
3656 | 3664 |
3657 \LMHash{} | 3665 \LMHash{} |
3658 It is a compile-time error if $q_i = q_j$ for any $i \ne j$. | 3666 It is a compile-time error if $q_i = q_j$ for any $i \ne j$. |
3659 | 3667 |
3660 \LMHash{} | 3668 \LMHash{} |
3661 Let $T_i$ be the static type of $a_i$, let $S_i$ be the type of $p_i, i \in 1 .. h+k$ and let $S_q$ be the type of the named parameter $q$ of $f$. It is a stat ic warning if $T_j$ may not be assigned to $S_j, j \in 1..m$. It is a static wa rning if $m < h$ or if $m > n$. Furthermore, each $q_i, 1 \le i \le l$, must ha ve a corresponding named parameter in the set $\{p_{n+1}, \ldots, p_{n +k}\}$ or a static warning occurs. It is a static warning if $T_{m+j}$ may not be assign ed to $S_{q_j}, j \in 1 .. l$. | 3669 Let $T_i$ be the static type of $a_i$, let $S_i$ be the type of $p_i, i \in 1 .. h+k$ and let $S_q$ be the type of the named parameter $q$ of $f$. It is a stat ic warning if $T_j$ may not be assigned to $S_j, j \in 1..m$. It is a static wa rning if $m < h$ or if $m > n$. Furthermore, each $q_i, 1 \le i \le l$, must ha ve a corresponding named parameter in the set $\{p_{n+1}, \ldots, p_{n +k}\}$ or a static warning occurs. It is a static warning if $T_{m+j}$ may not be assign ed to $S_{q_j}, j \in 1 .. l$. |
3662 | 3670 |
3663 \subsubsection{ Unqualified Invocation} | 3671 \subsubsection{ Unqualified Invocation} |
3664 \LMLabel{unqualifiedInvocation} | 3672 \LMLabel{unqualifiedInvocation} |
3665 | 3673 |
3666 \LMHash{} | 3674 \LMHash{} |
3667 An unqualified function invocation $i$ has the form | 3675 An unqualified function invocation $i$ has the form |
3668 | 3676 |
3669 $id(a_1, \ldots, a_n, x_{n+1}: a_{n+1}, \ldots, x_{n+k}: a_{n+k})$, | 3677 $id(a_1, \ldots, a_n, x_{n+1}: a_{n+1}, \ldots, x_{n+k}: a_{n+k})$, |
3670 | 3678 |
3671 where $id$ is an identifier. | 3679 where $id$ is an identifier. |
3672 | 3680 |
3673 \LMHash{} | 3681 \LMHash{} |
3674 If there exists a lexically visible declaration named $id$, let $f_{id}$ be the innermost such declaration. Then: | 3682 If there exists a lexically visible declaration named $id$, let $f_{id}$ be the innermost such declaration. Then: |
3675 \begin{itemize} | 3683 \begin{itemize} |
3676 \item | 3684 \item |
3677 If $f_{id}$ is a prefix object, a compile-time error occurs. | 3685 If $f_{id}$ is a prefix object, a compile-time error occurs. |
3678 \item | 3686 \item |
3679 If $f_{id}$ is a local function, a library function, a library or static getter or a variable then $i$ is interpreted as a function expression invocation (\ref {functionExpressionInvocation}). | 3687 If $f_{id}$ is a local function, a library function, a library or static getter or a variable then $i$ is interpreted as a function expression invocation (\ref {functionExpressionInvocation}). |
3680 \item | 3688 \item |
3681 Otherwise, if $f_{id}$ is a static method of the enclosing class $C$, $i$ is equ ivalent to $C.id(a_1, \ldots , a_n, x_{n+1}: a_{n+1}, \ldots , x_{n+k}: a_{n+k}) $. | 3689 Otherwise, if $f_{id}$ is a static method of the enclosing class $C$, $i$ is equ ivalent to $C.id(a_1, \ldots , a_n, x_{n+1}: a_{n+1}, \ldots , x_{n+k}: a_{n+k}) $. |
3682 \item Otherwise, $f_{id}$ is considered equivalent to the ordinary method invoca tion $\THIS{}.id(a_1, \ldots , a_n, x_{n+1}: a_{n+1}, \ldots , x_{n+k}: a_{n+k}) $. | 3690 \item Otherwise, $f_{id}$ is considered equivalent to the ordinary method invoca tion $\THIS{}.id(a_1, \ldots , a_n, x_{n+1}: a_{n+1}, \ldots , x_{n+k}: a_{n+k}) $. |
3683 \end{itemize} | 3691 \end{itemize} |
3684 | 3692 |
3685 \LMHash{} | 3693 \LMHash{} |
3686 Otherwise, if $i$ occurs inside a top level or static function (be it function, method, getter, or setter) or variable initializer, evaluation of $i$ causes a \cd{NoSuchMethodError} to be thrown. | 3694 Otherwise, if $i$ occurs inside a top level or static function (be it function, method, getter, or setter) or variable initializer, evaluation of $i$ causes a \cd{NoSuchMethodError} to be thrown. |
3687 | 3695 |
3688 \LMHash{} | 3696 \LMHash{} |
3689 If $i$ does not occur inside a top level or static function, $i$ is equivalent t o $\THIS{}.id(a_1, \ldots , a_n, x_{n+1}: a_{n+1}, \ldots , x_{n+k}: a_{n+k})$. | 3697 If $i$ does not occur inside a top level or static function, $i$ is equivalent t o $\THIS{}.id(a_1, \ldots , a_n, x_{n+1}: a_{n+1}, \ldots , x_{n+k}: a_{n+k})$. |
3690 | 3698 |
3691 | 3699 |
3692 % Should also say: | 3700 % Should also say: |
3693 % It is a static warning if $i$ occurs inside a top level or static function (b e it function, method, getter, or setter) or variable initializer and there is no lexically visible declaration named $id$ in scope. | 3701 % It is a static warning if $i$ occurs inside a top level or static function (b e it function, method, getter, or setter) or variable initializer and there is no lexically visible declaration named $id$ in scope. |
3694 | 3702 |
3695 | 3703 |
3696 | 3704 |
3697 | 3705 |
3698 | 3706 |
3699 \subsubsection{ Function Expression Invocation} | 3707 \subsubsection{ Function Expression Invocation} |
3700 \LMLabel{functionExpressionInvocation} | 3708 \LMLabel{functionExpressionInvocation} |
3701 | 3709 |
3702 \LMHash{} | 3710 \LMHash{} |
3703 A function expression invocation $i$ has the form | 3711 A function expression invocation $i$ has the form |
3704 | 3712 |
3705 $e_f(a_1, \ldots , a_n, x_{n+1}: a_{n+1}, \ldots , x_{n+k}: a_{n+k})$, | 3713 $e_f(a_1, \ldots , a_n, x_{n+1}: a_{n+1}, \ldots , x_{n+k}: a_{n+k})$, |
3706 | 3714 |
3707 where $e_f$ is an expression. If $e_f$ is an identifier $id$, then $id$ must nec essarily denote a local function, a library function, a library or static getter or a variable as described above, or $i$ is not considered a function expressio n invocation. If $e_f$ is a property extraction expression (\ref{propertyExtract ion}), then $i$ is is not a function expression invocation and is instead recogn ized as an ordinary method invocation (\ref{ordinaryInvocation}). | 3715 where $e_f$ is an expression. If $e_f$ is an identifier $id$, then $id$ must nec essarily denote a local function, a library function, a library or static getter or a variable as described above, or $i$ is not considered a function expressio n invocation. If $e_f$ is a property extraction expression (\ref{propertyExtract ion}), then $i$ is is not a function expression invocation and is instead recogn ized as an ordinary method invocation (\ref{ordinaryInvocation}). |
3708 | 3716 |
3709 \commentary{ | 3717 \commentary{ |
3710 \code{$a.b(x)$} is parsed as a method invocation of method \code{$b()$} on objec t \code{$a$}, not as an invocation of getter \code{$b$} on \code{$a$} followed b y a function call \code{$(a.b)(x)$}. If a method or getter \code{$b$} exists, t he two will be equivalent. However, if \code{$b$} is not defined on \code{$a$}, the resulting invocation of \code{noSuchMethod()} would differ. The \code{Invoc ation} passed to \code{noSuchMethod()} would describe a call to a method \code{$ b$} with argument \code{$x$} in the former case, and a call to a getter \code{$b $} (with no arguments) in the latter. | 3718 \code{$a.b(x)$} is parsed as a method invocation of method \code{$b()$} on objec t \code{$a$}, not as an invocation of getter \code{$b$} on \code{$a$} followed b y a function call \code{$(a.b)(x)$}. If a method or getter \code{$b$} exists, t he two will be equivalent. However, if \code{$b$} is not defined on \code{$a$}, the resulting invocation of \code{noSuchMethod()} would differ. The \code{Invoc ation} passed to \code{noSuchMethod()} would describe a call to a method \code{$ b$} with argument \code{$x$} in the former case, and a call to a getter \code{$b $} (with no arguments) in the latter. |
3711 } | 3719 } |
3712 | 3720 |
3713 \LMHash{} | 3721 \LMHash{} |
3714 Otherwise: | 3722 Otherwise: |
3715 | 3723 |
3716 A function expression invocation $e_f(a_1, \ldots , a_n, x_{n+1}: a_{n+1}, \ldot s , x_{n+k}: a_{n+k})$ is equivalent to $e_f.call(a_1, \ldots , a_n, x_{n+1}: a_ {n+1}, \ldots , x_{n+k}: a_{n+k})$. | 3724 A function expression invocation $e_f(a_1, \ldots , a_n, x_{n+1}: a_{n+1}, \ldot s , x_{n+k}: a_{n+k})$ is equivalent to $e_f.call(a_1, \ldots , a_n, x_{n+1}: a_ {n+1}, \ldots , x_{n+k}: a_{n+k})$. |
3717 | 3725 |
3718 \commentary{ | 3726 \commentary{ |
3719 The implication of this definition, and the other definitions involving the meth od \code{call()}, is that user defined types can be used as function values prov ided they define a \CALL{} method. The method \CALL{} is special in this regard. The signature of the \CALL{} method determines the signature used when using th e object via the built-in invocation syntax. | 3727 The implication of this definition, and the other definitions involving the meth od \code{call()}, is that user defined types can be used as function values prov ided they define a \CALL{} method. The method \CALL{} is special in this regard. The signature of the \CALL{} method determines the signature used when using th e object via the built-in invocation syntax. |
3720 } | 3728 } |
3721 | 3729 |
3722 \LMHash{} | 3730 \LMHash{} |
3723 It is a static warning if the static type $F$ of $e_f$ may not be assigned to a function type. If $F$ is not a function type, the static type of $i$ is \DYNAMI C{}. Otherwise | 3731 It is a static warning if the static type $F$ of $e_f$ may not be assigned to a function type. If $F$ is not a function type, the static type of $i$ is \DYNAMI C{}. Otherwise |
3724 the static type of $i$ is the declared return type of $F$. | 3732 the static type of $i$ is the declared return type of $F$. |
3725 %\item Let $T_i$ be the static type of $a_i, i \in 1 .. n+k$. It is a static war ning if $F$ is not a supertype of $(T_1, \ldots, T_n, [T_{n+1}$ $x_{n+1}, \ldot s, T_{n+k}$ $x_{n+k}]) \to \bot$. | 3733 %\item Let $T_i$ be the static type of $a_i, i \in 1 .. n+k$. It is a static war ning if $F$ is not a supertype of $(T_1, \ldots, T_n, [T_{n+1}$ $x_{n+1}, \ldot s, T_{n+k}$ $x_{n+k}]) \to \bot$. |
3726 %\end{itemize} | 3734 %\end{itemize} |
3727 | 3735 |
3728 \subsection{ Lookup} | 3736 \subsection{ Lookup} |
3729 \LMLabel{lookup} | 3737 \LMLabel{lookup} |
3730 | 3738 |
3731 \subsubsection{Method Lookup} | 3739 \subsubsection{Method Lookup} |
3732 \LMLabel{methodLookup} | 3740 \LMLabel{methodLookup} |
3733 | 3741 |
3734 \LMHash{} | 3742 \LMHash{} |
3735 The result of a lookup of a method $m$ in object $o$ with respect to library $L$ is the result of a lookup of method $m$ in class $C$ with respect to library $ L$, where $C$ is the class of $o$. | 3743 The result of a lookup of a method $m$ in object $o$ with respect to library $L$ is the result of a lookup of method $m$ in class $C$ with respect to library $ L$, where $C$ is the class of $o$. |
3736 | 3744 |
3737 \LMHash{} | 3745 \LMHash{} |
3738 The result of a lookup of method $m$ in class $C$ with respect to library $L$ i s: | 3746 The result of a lookup of method $m$ in class $C$ with respect to library $L$ i s: |
3739 If $C$ declares a concrete instance method named $m$ that is accessible to $L$, then that method is the result of the lookup, and we say that the method was {\ em looked up in $C$}. Otherwise, if $C$ has a superclass $S$, then the result of the lookup is the result of looking up $m$ in $S$ with respect to $L$. Otherwi se, we say that the method lookup has failed. | 3747 If $C$ declares a concrete instance method named $m$ that is accessible to $L$, then that method is the result of the lookup, and we say that the method was {\ em looked up in $C$}. Otherwise, if $C$ has a superclass $S$, then the result of the lookup is the result of looking up $m$ in $S$ with respect to $L$. Otherwi se, we say that the method lookup has failed. |
3740 | 3748 |
3741 \rationale { | 3749 \rationale { |
3742 The motivation for skipping abstract members during lookup is largely to allow s moother mixin composition. | 3750 The motivation for skipping abstract members during lookup is largely to allow s moother mixin composition. |
3743 } | 3751 } |
3744 | 3752 |
3745 | 3753 |
3746 \subsubsection{ Getter and Setter Lookup} | 3754 \subsubsection{ Getter and Setter Lookup} |
3747 \LMLabel{getterAndSetterLookup} | 3755 \LMLabel{getterAndSetterLookup} |
3748 | 3756 |
3749 \LMHash{} | 3757 \LMHash{} |
3750 The result of a lookup of a getter (respectively setter) $m$ in object $o$ with respect to library $L$ is the result of looking up getter (respectively sette r) $m$ in class $C$ with respect to $L$, where $C$ is the class of $o$. | 3758 The result of a lookup of a getter (respectively setter) $m$ in object $o$ with respect to library $L$ is the result of looking up getter (respectively sette r) $m$ in class $C$ with respect to $L$, where $C$ is the class of $o$. |
3751 | 3759 |
3752 \LMHash{} | 3760 \LMHash{} |
3753 The result of a lookup of a getter (respectively setter) $m$ in class $C$ with respect to library $L$ is: | 3761 The result of a lookup of a getter (respectively setter) $m$ in class $C$ with respect to library $L$ is: |
3754 If $C$ declares a concrete instance getter (respectively setter) named $m$ that is accessible to $L$, then that getter (respectively setter) is the result of the lookup, and we say that the getter (respectively setter) was {\em looked up in $C$}. Otherwise, if $C$ has a superclass $S$, then the result of the lookup i s the result of looking up getter (respectively setter) $m$ in $S$ with respect to $L$. Otherwise, we say that the lookup has failed. | 3762 If $C$ declares a concrete instance getter (respectively setter) named $m$ that is accessible to $L$, then that getter (respectively setter) is the result of the lookup, and we say that the getter (respectively setter) was {\em looked up in $C$}. Otherwise, if $C$ has a superclass $S$, then the result of the lookup i s the result of looking up getter (respectively setter) $m$ in $S$ with respect to $L$. Otherwise, we say that the lookup has failed. |
3755 | 3763 |
3756 \rationale { | 3764 \rationale { |
3757 The motivation for skipping abstract members during lookup is largely to allow s moother mixin composition. | 3765 The motivation for skipping abstract members during lookup is largely to allow s moother mixin composition. |
3758 } | 3766 } |
3759 | 3767 |
3760 | 3768 |
3761 \subsection{ Top level Getter Invocation} | 3769 \subsection{ Top level Getter Invocation} |
3762 \LMLabel{topLevelGetterInvocation} | 3770 \LMLabel{topLevelGetterInvocation} |
3763 | 3771 |
3764 \LMHash{} | 3772 \LMHash{} |
3765 Evaluation of a top-level getter invocation $i$ of the form $m$, where $m$ is an identifier, proceeds as follows: | 3773 Evaluation of a top-level getter invocation $i$ of the form $m$, where $m$ is an identifier, proceeds as follows: |
3766 | 3774 |
3767 \LMHash{} | 3775 \LMHash{} |
3768 The getter function $m$ is invoked. The value of $i$ is the result returned by t he call to the getter function. | 3776 The getter function $m$ is invoked. The value of $i$ is the result returned by t he call to the getter function. |
3769 \commentary{ | 3777 \commentary{ |
3770 Note that the invocation is always defined. Per the rules for identifier referen ces, an identifier will not be treated as a top-level getter invocation unless t he getter $i$ is defined. | 3778 Note that the invocation is always defined. Per the rules for identifier referen ces, an identifier will not be treated as a top-level getter invocation unless t he getter $i$ is defined. |
3771 } | 3779 } |
3772 | 3780 |
3773 \LMHash{} | 3781 \LMHash{} |
3774 The static type of $i$ is the declared return type of $m$. | 3782 The static type of $i$ is the declared return type of $m$. |
3775 | 3783 |
3776 \subsection{ Method Invocation} | 3784 \subsection{ Method Invocation} |
3777 \LMLabel{methodInvocation} | 3785 \LMLabel{methodInvocation} |
3778 | 3786 |
3779 \LMHash{} | 3787 \LMHash{} |
3780 Method invocation can take several forms as specified below. | 3788 Method invocation can take several forms as specified below. |
3781 | 3789 |
3782 \subsubsection{Ordinary Invocation} | 3790 \subsubsection{Ordinary Invocation} |
3783 \LMLabel{ordinaryInvocation} | 3791 \LMLabel{ordinaryInvocation} |
3784 | 3792 |
3785 \LMHash{} | 3793 \LMHash{} |
3786 An ordinary method invocation can be {\em conditional} or {\em unconditional}. | 3794 An ordinary method invocation can be {\em conditional} or {\em unconditional}. |
3787 | 3795 |
3788 \LMHash{} | 3796 \LMHash{} |
3789 Evaluation of a {\em conditional ordinary method invocation} $e$ of the form | 3797 Evaluation of a {\em conditional ordinary method invocation} $e$ of the form |
3790 | 3798 |
3791 \LMHash{} | 3799 \LMHash{} |
3792 $o?.m(a_1, \ldots , a_n, x_{n+1}: a_{n+1}, \ldots , x_{n+k}: a_{n+k})$ | 3800 $o?.m(a_1, \ldots , a_n, x_{n+1}: a_{n+1}, \ldots , x_{n+k}: a_{n+k})$ |
3793 | 3801 |
3794 \LMHash{} | 3802 \LMHash{} |
3795 is equivalent to the evaluation of the expression | 3803 is equivalent to the evaluation of the expression |
3796 | 3804 |
3797 \LMHash{} | 3805 \LMHash{} |
3798 $((x) => x == \NULL ? \NULL : x.m(a_1, \ldots , a_n, x_{n+1}: a_{n+1}, \ldots , x_{n+k}: a_{n+k}))(o)$. | 3806 $((x) => x == \NULL ? \NULL : x.m(a_1, \ldots , a_n, x_{n+1}: a_{n+1}, \ldots , x_{n+k}: a_{n+k}))(o)$. |
3799 | 3807 |
3800 unless $o$ is a type literal, in which case it is equivalent to $o.m(a_1, \ldot s , a_n, x_{n+1}: a_{n+1}, \ldots , x_{n+k}: a_{n+k})$. | 3808 unless $o$ is a type literal, in which case it is equivalent to $o.m(a_1, \ldot s , a_n, x_{n+1}: a_{n+1}, \ldots , x_{n+k}: a_{n+k})$. |
3801 | 3809 |
3802 \LMHash{} | 3810 \LMHash{} |
3803 The static type of $e$ is the same as the static type of $o.m(a_1, \ldots , a_n, x_{n+1}: a_{n+1}, \ldots , x_{n+k}: a_{n+k})$. Exactly the same static warnings that would be caused by $o.m(a_1, \ldots , a_n, x_{n+1}: a_{n+1}, \ldots , x_{n +k}: a_{n+k})$ are also generated in the case of $o?.m(a_1, \ldots , a_n, x_{n+1 }: a_{n+1}, \ldots , x_{n+k}: a_{n+k})$. | 3811 The static type of $e$ is the same as the static type of $o.m(a_1, \ldots , a_n, x_{n+1}: a_{n+1}, \ldots , x_{n+k}: a_{n+k})$. Exactly the same static warnings that would be caused by $o.m(a_1, \ldots , a_n, x_{n+1}: a_{n+1}, \ldots , x_{n +k}: a_{n+k})$ are also generated in the case of $o?.m(a_1, \ldots , a_n, x_{n+1 }: a_{n+1}, \ldots , x_{n+k}: a_{n+k})$. |
3804 | 3812 |
3805 \LMHash{} | 3813 \LMHash{} |
3806 An {\em unconditional ordinary method invocation} $i$ has the form | 3814 An {\em unconditional ordinary method invocation} $i$ has the form |
3807 | 3815 |
3808 $o.m(a_1, \ldots , a_n, x_{n+1}: a_{n+1}, \ldots , x_{n+k}: a_{n+k})$. | 3816 $o.m(a_1, \ldots , a_n, x_{n+1}: a_{n+1}, \ldots , x_{n+k}: a_{n+k})$. |
3809 | 3817 |
3810 \LMHash{} | 3818 \LMHash{} |
3811 Evaluation of an unconditional ordinary method invocation $i$ of the form | 3819 Evaluation of an unconditional ordinary method invocation $i$ of the form |
3812 | 3820 |
3813 $o.m(a_1, \ldots , a_n, x_{n+1}: a_{n+1}, \ldots , x_{n+k}: a_{n+k})$ | 3821 $o.m(a_1, \ldots , a_n, x_{n+1}: a_{n+1}, \ldots , x_{n+k}: a_{n+k})$ |
3814 | 3822 |
3815 proceeds as follows: | 3823 proceeds as follows: |
3816 | 3824 |
3817 \LMHash{} | 3825 \LMHash{} |
3818 First, the expression $o$ is evaluated to a value $v_o$. Next, the argument list $(a_1, \ldots , a_n, x_{n+1}: a_{n+1}, \ldots , x_{n+k}: a_{n+k})$ is evaluated yielding actual argument objects $o_1, \ldots , o_{n+k}$. Let $f$ be the result of looking up (\ref{methodLookup}) method $m$ in $v_o$ with respect to the cur rent library $L$. | 3826 First, the expression $o$ is evaluated to a value $v_o$. Next, the argument list $(a_1, \ldots , a_n, x_{n+1}: a_{n+1}, \ldots , x_{n+k}: a_{n+k})$ is evaluated yielding actual argument objects $o_1, \ldots , o_{n+k}$. Let $f$ be the result of looking up (\ref{methodLookup}) method $m$ in $v_o$ with respect to the cur rent library $L$. |
3819 | 3827 |
3820 \LMHash{} | 3828 \LMHash{} |
3821 Let $p_1 \ldots p_h$ be the required parameters of $f$, let $p_1 \ldots p_m$ be the positional parameters of $f$ and let $p_{h+1}, \ldots, p_{h+l}$ be the opti onal parameters declared by $f$. | 3829 Let $p_1 \ldots p_h$ be the required parameters of $f$, let $p_1 \ldots p_m$ be the positional parameters of $f$ and let $p_{h+1}, \ldots, p_{h+l}$ be the opti onal parameters declared by $f$. |
3822 | 3830 |
3823 \commentary{ | 3831 \commentary{ |
3824 We have an argument list consisting of $n$ positional arguments and $k$ named ar guments. We have a function with $h$ required parameters and $l$ optional parame ters. The number of positional arguments must be at least as large as the number of required parameters, and no larger than the number of positional parameters. All named arguments must have a corresponding named parameter. | 3832 We have an argument list consisting of $n$ positional arguments and $k$ named ar guments. We have a function with $h$ required parameters and $l$ optional parame ters. The number of positional arguments must be at least as large as the number of required parameters, and no larger than the number of positional parameters. All named arguments must have a corresponding named parameter. |
3825 } | 3833 } |
3826 | 3834 |
3827 \LMHash{} | 3835 \LMHash{} |
3828 If $n < h$, or $n > m$, the method lookup has failed. Furthermore, each $x_i, n +1 \le i \le n+k$, must have a corresponding named parameter in the set $\{p_{m +1}, \ldots, p_{h+l}\}$ or the method lookup also fails. If $v_o$ is an instanc e of \code{Type} but $o$ is not a constant type literal, then if $m$ is a method that forwards (\ref{functionDeclarations}) to a static method, method lookup fa ils. Otherwise method lookup has succeeded. | 3836 If $n < h$, or $n > m$, the method lookup has failed. Furthermore, each $x_i, n +1 \le i \le n+k$, must have a corresponding named parameter in the set $\{p_{m +1}, \ldots, p_{h+l}\}$ or the method lookup also fails. If $v_o$ is an instanc e of \code{Type} but $o$ is not a constant type literal, then if $m$ is a method that forwards (\ref{functionDeclarations}) to a static method, method lookup fa ils. Otherwise method lookup has succeeded. |
3829 | 3837 |
3830 \LMHash{} | 3838 \LMHash{} |
3831 If the method lookup succeeded, the body of $f$ is executed with respect to the bindings that resulted from the evaluation of the argument list, and with \THIS{ } bound to $v_o$. The value of $i$ is the value returned after $f$ is executed. | 3839 If the method lookup succeeded, the body of $f$ is executed with respect to the bindings that resulted from the evaluation of the argument list, and with \THIS{ } bound to $v_o$. The value of $i$ is the value returned after $f$ is executed. |
3832 | 3840 |
3833 \LMHash{} | 3841 \LMHash{} |
3834 If the method lookup has failed, then let $g$ be the result of looking up getter (\ref{getterAndSetterLookup}) $m$ in $v_o$ with respect to $L$. | 3842 If the method lookup has failed, then let $g$ be the result of looking up getter (\ref{getterAndSetterLookup}) $m$ in $v_o$ with respect to $L$. |
3835 If $v_o$ is an instance of \code{Type} but $o$ is not a constant type literal, t hen if $g$ is a getter that forwards to a static getter, getter lookup fails. | 3843 If $v_o$ is an instance of \code{Type} but $o$ is not a constant type literal, t hen if $g$ is a getter that forwards to a static getter, getter lookup fails. |
3836 If the getter lookup succeeded, let $v_g$ be the value of the getter invocation $o.m$. Then the value of $i$ is the result of invoking | 3844 If the getter lookup succeeded, let $v_g$ be the value of the getter invocation $o.m$. Then the value of $i$ is the result of invoking |
3837 the static method \code{Function.apply()} with arguments $v.g, [o_1, \ldots , o_ n], \{x_{n+1}: o_{n+1}, \ldots , x_{n+k}: o_{n+k}\}$. | 3845 the static method \code{Function.apply()} with arguments $v.g, [o_1, \ldots , o_ n], \{x_{n+1}: o_{n+1}, \ldots , x_{n+k}: o_{n+k}\}$. |
3838 | 3846 |
3839 \LMHash{} | 3847 \LMHash{} |
3840 If getter lookup has also failed, then a new instance $im$ of the predefined c lass \code{Invocation} is created, such that : | 3848 If getter lookup has also failed, then a new instance $im$ of the predefined c lass \code{Invocation} is created, such that : |
3841 \begin{itemize} | 3849 \begin{itemize} |
3842 \item \code{im.isMethod} evaluates to \code{\TRUE{}}. | 3850 \item \code{im.isMethod} evaluates to \code{\TRUE{}}. |
3843 \item \code{im.memberName} evaluates to the symbol \code{m}. | 3851 \item \code{im.memberName} evaluates to the symbol \code{m}. |
3844 \item \code{im.positionalArguments} evaluates to an immutable list with the same values as \code{[$o_1, \ldots, o_n$]}. | 3852 \item \code{im.positionalArguments} evaluates to an immutable list with the same values as \code{[$o_1, \ldots, o_n$]}. |
3845 \item \code{im.namedArguments} evaluates to an immutable map with the same keys and values as \code{\{$x_{n+1}: o_{n+1}, \ldots, x_{n+k} : o_{n+k}$\}}. | 3853 \item \code{im.namedArguments} evaluates to an immutable map with the same keys and values as \code{\{$x_{n+1}: o_{n+1}, \ldots, x_{n+k} : o_{n+k}$\}}. |
3846 \end{itemize} | 3854 \end{itemize} |
(...skipping 10 matching lines...) Expand all Loading... | |
3857 and the result of the latter invocation is the result of evaluating $i$. | 3865 and the result of the latter invocation is the result of evaluating $i$. |
3858 | 3866 |
3859 \rationale { | 3867 \rationale { |
3860 It is possible to bring about such a situation by overriding \code{noSuchMethod( )} with the wrong number of arguments:} | 3868 It is possible to bring about such a situation by overriding \code{noSuchMethod( )} with the wrong number of arguments:} |
3861 | 3869 |
3862 \begin{code} | 3870 \begin{code} |
3863 \CLASS{} Perverse \{ | 3871 \CLASS{} Perverse \{ |
3864 noSuchMethod(x,y) =$>$ x + y; | 3872 noSuchMethod(x,y) =$>$ x + y; |
3865 \} | 3873 \} |
3866 | 3874 |
3867 \NEW{} Perverse.unknownMethod(); | 3875 \NEW{} Perverse.unknownMethod(); |
3868 \end{code} | 3876 \end{code} |
3869 | 3877 |
3870 \commentary{Notice that the wording carefully avoids re-evaluating the receiver $o$ and the arguments $a_i$. } | 3878 \commentary{Notice that the wording carefully avoids re-evaluating the receiver $o$ and the arguments $a_i$. } |
3871 | 3879 |
3872 \LMHash{} | 3880 \LMHash{} |
3873 Let $T$ be the static type of $o$. It is a static type warning if $T$ does not have an accessible (\ref{privacy}) instance member named $m$ unless either: | 3881 Let $T$ be the static type of $o$. It is a static type warning if $T$ does not have an accessible (\ref{privacy}) instance member named $m$ unless either: |
3874 \begin{itemize} | 3882 \begin{itemize} |
3875 \item | 3883 \item |
3876 $T$ or a superinterface of $T$ is annotated with an annotation denoting a consta nt identical to the constant \code{@proxy} defined in \code{dart:core}. Or | 3884 $T$ or a superinterface of $T$ is annotated with an annotation denoting a consta nt identical to the constant \code{@proxy} defined in \code{dart:core}. Or |
3877 \item $T$ is \code{Type}, $e$ is a constant type literal and the class correspo nding to $e$ has a static getter named $m$. | 3885 \item $T$ is \code{Type}, $e$ is a constant type literal and the class correspo nding to $e$ has a static getter named $m$. |
3878 \item $T$ is \code{Function} and $m$ is \CALL. \rationale {The type \code{Functi on} is treated as if it has a \code{call} method for any possible signature of \ CALL. The expectation is that any concrete subclass of \code{Function} will impl ement \CALL. Note that a warning will be issue if this is not the case. Furtherm ore, any use of \CALL{} on a subclass of \code{Function} that fails to implement \CALL{} will also provoke a a warning, as this exemption is limited to type \co de{Function}, and does not apply to its subtypes. | 3886 \item $T$ is \code{Function} and $m$ is \CALL. \rationale {The type \code{Functi on} is treated as if it has a \code{call} method for any possible signature of \ CALL. The expectation is that any concrete subclass of \code{Function} will impl ement \CALL. Note that a warning will be issue if this is not the case. Furtherm ore, any use of \CALL{} on a subclass of \code{Function} that fails to implement \CALL{} will also provoke a warning, as this exemption is limited to type \code {Function}, and does not apply to its subtypes. |
3879 } | 3887 } |
3880 \end{itemize} | 3888 \end{itemize} |
3881 | 3889 |
3882 \LMHash{} | 3890 \LMHash{} |
3883 If $T.m$ exists, it is a static type warning if the type $F$ of $T.m$ may not b e assigned to a function type. If $T.m$ does not exist, or if $F$ is not a funct ion type, the static type of $i$ is \DYNAMIC{}; otherwise the static type of $i$ is the declared return type of $F$. | 3891 If $T.m$ exists, it is a static type warning if the type $F$ of $T.m$ may not b e assigned to a function type. If $T.m$ does not exist, or if $F$ is not a funct ion type, the static type of $i$ is \DYNAMIC{}; otherwise the static type of $i$ is the declared return type of $F$. |
3884 | 3892 |
3885 \LMHash{} | 3893 \LMHash{} |
3886 It is a compile-time error to invoke any of the methods of class \cd{Object} on a prefix object (\ref{imports}) or on a constant type literal that is immediate ly followed by the token `.'. | 3894 It is a compile-time error to invoke any of the methods of class \cd{Object} on a prefix object (\ref{imports}) or on a constant type literal that is immediate ly followed by the token `.'. |
3887 | 3895 |
3888 | 3896 |
3889 \subsubsection{Cascaded Invocations} | 3897 \subsubsection{Cascaded Invocations} |
3890 \LMLabel{cascadedInvocations} | 3898 \LMLabel{cascadedInvocations} |
3891 | 3899 |
3892 \LMHash{} | 3900 \LMHash{} |
3893 A {\em cascaded method invocation} has the form {\em e..suffix} | 3901 A {\em cascaded method invocation} has the form {\em e..suffix} |
3894 where $e$ is an expression and {\em suffix} is a sequence of operator, method, g etter or setter invocations. | 3902 where $e$ is an expression and {\em suffix} is a sequence of operator, method, g etter or setter invocations. |
3895 | 3903 |
3896 \begin{grammar} | 3904 \begin{grammar} |
3897 {\bf cascadeSection:} | 3905 {\bf cascadeSection:} |
3898 `{\escapegrammar ..}' (cascadeSelector arguments*) (assignableSelector arg uments*)* (assignmentOperator expressionWithoutCascade)? | 3906 `{\escapegrammar ..}' (cascadeSelector arguments*) (assignableSelector arg uments*)* (assignmentOperator expressionWithoutCascade)? |
3899 . | 3907 . |
3900 | 3908 |
3901 {\bf cascadeSelector:}`[' expression `]'; | 3909 {\bf cascadeSelector:}`[' expression `]'; |
3902 identifier | 3910 identifier |
3903 . | 3911 . |
3904 \end{grammar} | 3912 \end{grammar} |
3905 | 3913 |
3906 \LMHash{} | 3914 \LMHash{} |
3907 A cascaded method invocation expression of the form {\em e..suffix} is equivalen t to the expression \code{(t)\{t.{\em suffix}; \RETURN{} t;\}($e$)}. | 3915 A cascaded method invocation expression of the form {\em e..suffix} is equivalen t to the expression \code{(t)\{t.{\em suffix}; \RETURN{} t;\}($e$)}. |
3908 | 3916 |
3909 \rationale{ | 3917 \rationale{ |
3910 With the introduction of null-aware conditional assignable expressions (\ref{ass ignableExpressions}), it would make sense to extend cascades with a null-aware c onditional form as well. One might define {\em e?..suffix} to be equivalent to the expression \code{(t)\{t?.{\em suffix}; \RETURN{} t;\}($e$)}. | 3918 With the introduction of null-aware conditional assignable expressions (\ref{ass ignableExpressions}), it would make sense to extend cascades with a null-aware c onditional form as well. One might define {\em e?..suffix} to be equivalent to the expression \code{(t)\{t?.{\em suffix}; \RETURN{} t;\}($e$)}. |
3911 | 3919 |
3912 The present specification has not added such a construct, in the interests of si mplicity and rapid language evolution. However, Dart implementations may experim ent with such constructs, as noted in section \ref{ecmaConformance}. | 3920 The present specification has not added such a construct, in the interests of si mplicity and rapid language evolution. However, Dart implementations may experim ent with such constructs, as noted in section \ref{ecmaConformance}. |
3913 } | 3921 } |
3914 | 3922 |
3915 \subsubsection{Super Invocation} | 3923 \subsubsection{Super Invocation} |
3916 \LMLabel{superInvocation} | 3924 \LMLabel{superInvocation} |
3917 | 3925 |
3918 \LMHash{} | 3926 \LMHash{} |
3919 A super method invocation $i$ has the form | 3927 A super method invocation $i$ has the form |
3920 | 3928 |
3921 $\SUPER{}.m(a_1, \ldots , a_n, x_{n+1}: a_{n+1}, \ldots , x_{n+k}: a_{n+k})$. | 3929 $\SUPER{}.m(a_1, \ldots , a_n, x_{n+1}: a_{n+1}, \ldots , x_{n+k}: a_{n+k})$. |
3922 | 3930 |
3923 \LMHash{} | 3931 \LMHash{} |
3924 Evaluation of $i$ proceeds as follows: | 3932 Evaluation of $i$ proceeds as follows: |
3925 | 3933 |
3926 \LMHash{} | 3934 \LMHash{} |
3927 First, the argument list $(a_1, \ldots , a_n, x_{n+1}: a_{n+1}, \ldots , x_{n+k} : a_{n+k})$ is evaluated yielding actual argument objects $o_1, \ldots , o_{n+k }$. Let $g$ be the method currently executing, and let $C$ be the class in which $g$ was looked up (\ref{methodLookup}). Let $S_{dynamic}$ be the superclass of $C$, and let $f$ be the result of looking up method (\ref{methodLookup}) $m$ in $S_{dynamic}$ with respect to the current library $L$. | 3935 First, the argument list $(a_1, \ldots , a_n, x_{n+1}: a_{n+1}, \ldots , x_{n+k} : a_{n+k})$ is evaluated yielding actual argument objects $o_1, \ldots , o_{n+k }$. Let $g$ be the method currently executing, and let $C$ be the class in which $g$ was looked up (\ref{methodLookup}). Let $S_{dynamic}$ be the superclass of $C$, and let $f$ be the result of looking up method (\ref{methodLookup}) $m$ in $S_{dynamic}$ with respect to the current library $L$. |
3928 Let $p_1 \ldots p_h$ be the required parameters of $f$, let $p_1 \ldots p_m$ be the positional parameters of $f$ and let $p_{h+1}, \ldots, p_{h+l}$ be the opti onal parameters declared by $f$. | 3936 Let $p_1 \ldots p_h$ be the required parameters of $f$, let $p_1 \ldots p_m$ be the positional parameters of $f$ and let $p_{h+1}, \ldots, p_{h+l}$ be the opti onal parameters declared by $f$. |
3929 | 3937 |
3930 \LMHash{} | 3938 \LMHash{} |
3931 If $n < h$, or $n > m$, the method lookup has failed. Furthermore, each $x_i, n +1 \le i \le n+k$, must have a corresponding named parameter in the set $\{p_{m +1}, \ldots, p_{h+l}\}$ or the method lookup also fails. Otherwise method looku p has succeeded. | 3939 If $n < h$, or $n > m$, the method lookup has failed. Furthermore, each $x_i, n +1 \le i \le n+k$, must have a corresponding named parameter in the set $\{p_{m +1}, \ldots, p_{h+l}\}$ or the method lookup also fails. Otherwise method looku p has succeeded. |
3932 | 3940 |
3933 \LMHash{} | 3941 \LMHash{} |
3934 If the method lookup succeeded, the body of $f$ is executed with respect to the bindings that resulted from the evaluation of the argument list, and with \THIS{ } bound to the current value of \THIS{}. The value of $i$ is the value returned after $f$ is executed. | 3942 If the method lookup succeeded, the body of $f$ is executed with respect to the bindings that resulted from the evaluation of the argument list, and with \THIS{ } bound to the current value of \THIS{}. The value of $i$ is the value returned after $f$ is executed. |
3935 | 3943 |
3936 \LMHash{} | 3944 \LMHash{} |
3937 If the method lookup has failed, then let $g$ be the result of looking up getter (\ref{getterAndSetterLookup}) $m$ in $S_{dynamic}$ with respect to $L$. If the getter lookup succeeded, let $v_g$ be the value of the getter invocation $\SUPER {}.m$. Then the value of $i$ is the result of invoking | 3945 If the method lookup has failed, then let $g$ be the result of looking up getter (\ref{getterAndSetterLookup}) $m$ in $S_{dynamic}$ with respect to $L$. If the getter lookup succeeded, let $v_g$ be the value of the getter invocation $\SUPER {}.m$. Then the value of $i$ is the result of invoking |
3938 the static method \code{Function.apply()} with arguments $v_g, [o_1, \ldots , o_ n], \{x_{n+1}: o_{n+1}, \ldots , x_{n+k}: o_{n+k}\}$. | 3946 the static method \code{Function.apply()} with arguments $v_g, [o_1, \ldots , o_ n], \{x_{n+1}: o_{n+1}, \ldots , x_{n+k}: o_{n+k}\}$. |
3939 | 3947 |
3940 \LMHash{} | 3948 \LMHash{} |
3941 If getter lookup has also failed, then a new instance $im$ of the predefined c lass \code{Invocation} is created, such that : | 3949 If getter lookup has also failed, then a new instance $im$ of the predefined c lass \code{Invocation} is created, such that : |
3942 \begin{itemize} | 3950 \begin{itemize} |
3943 \item \code{im.isMethod} evaluates to \code{\TRUE{}}. | 3951 \item \code{im.isMethod} evaluates to \code{\TRUE{}}. |
3944 \item \code{im.memberName} evaluates to the symbol \code{m}. | 3952 \item \code{im.memberName} evaluates to the symbol \code{m}. |
3945 \item \code{im.positionalArguments} evaluates to an immutable list with the same values as \code{[$o_1, \ldots, o_n$]}. | 3953 \item \code{im.positionalArguments} evaluates to an immutable list with the same values as \code{[$o_1, \ldots, o_n$]}. |
3946 \item \code{im.namedArguments} evaluates to an immutable map with the same keys and values as \code{\{$x_{n+1}: o_{n+1}, \ldots, x_{n+k} : o_{n+k}$\}}. | 3954 \item \code{im.namedArguments} evaluates to an immutable map with the same keys and values as \code{\{$x_{n+1}: o_{n+1}, \ldots, x_{n+k} : o_{n+k}$\}}. |
3947 \end{itemize} | 3955 \end{itemize} |
3948 Then the method \code{noSuchMethod()} is looked up in $S_{dynamic}$ and invoked on \THIS{} with argument $im$, and the result of this invocation is the result o f evaluating $i$. However, if the implementation found cannot be invoked with a single positional argument, the implementation of \code{noSuchMethod()} in clas s \code{Object} is invoked on \THIS{} with argument $im'$, where $im'$ is an ins tance of \code{Invocation} such that : | 3956 Then the method \code{noSuchMethod()} is looked up in $S_{dynamic}$ and invoked on \THIS{} with argument $im$, and the result of this invocation is the result o f evaluating $i$. However, if the implementation found cannot be invoked with a single positional argument, the implementation of \code{noSuchMethod()} in clas s \code{Object} is invoked on \THIS{} with argument $im'$, where $im'$ is an ins tance of \code{Invocation} such that : |
3949 \begin{itemize} | 3957 \begin{itemize} |
3950 \item \code{im'.isMethod} evaluates to \code{\TRUE{}}. | 3958 \item \code{im'.isMethod} evaluates to \code{\TRUE{}}. |
3951 \item \code{im'.memberName} evaluates to \code{\#noSuchMethod}. | 3959 \item \code{im'.memberName} evaluates to \code{\#noSuchMethod}. |
3952 \item \code{im'.positionalArguments} evaluates to an immutable list whose sole e lement is $im$. | 3960 \item \code{im'.positionalArguments} evaluates to an immutable list whose sole e lement is $im$. |
3953 \item \code{im'.namedArguments} evaluates to the value of \code{\CONST{} \{\}}. | 3961 \item \code{im'.namedArguments} evaluates to the value of \code{\CONST{} \{\}}. |
3954 \end{itemize} | 3962 \end{itemize} |
3955 | 3963 |
3956 and the result of this latter invocation is the result of evaluating $i$. | 3964 and the result of this latter invocation is the result of evaluating $i$. |
3957 | 3965 |
3958 | 3966 |
3959 \LMHash{} | 3967 \LMHash{} |
3960 It is a compile-time error if a super method invocation occurs in a top-level fu nction or variable initializer, in an instance variable initializer or initializ er list, in class \code{Object}, in a factory constructor or in a static method or variable initializer. | 3968 It is a compile-time error if a super method invocation occurs in a top-level fu nction or variable initializer, in an instance variable initializer or initializ er list, in class \code{Object}, in a factory constructor or in a static method or variable initializer. |
3961 | 3969 |
3962 \LMHash{} | 3970 \LMHash{} |
3963 Let $S_{static}$ be the superclass of the immediately enclosing class. It is a s tatic type warning if $S_{static}$ does not have an accessible (\ref{privacy}) i nstance member named $m$ unless $S_{static}$ or a superinterface of $S_{static}$ is annotated with an annotation denoting a constant identical to the constant \ code{@proxy} defined in \code{dart:core}. If $S_{static}.m$ exists, it is a sta tic type warning if the type $F$ of $S_{static}.m$ may not be assigned to a func tion type. If $S_{static}.m$ does not exist, or if $F$ is not a function type, t he static type of $i$ is \DYNAMIC{}; otherwise the static type of $i$ is the dec lared return type of $F$. | 3971 Let $S_{static}$ be the superclass of the immediately enclosing class. It is a s tatic type warning if $S_{static}$ does not have an accessible (\ref{privacy}) i nstance member named $m$ unless $S_{static}$ or a superinterface of $S_{static}$ is annotated with an annotation denoting a constant identical to the constant \ code{@proxy} defined in \code{dart:core}. If $S_{static}.m$ exists, it is a sta tic type warning if the type $F$ of $S_{static}.m$ may not be assigned to a func tion type. If $S_{static}.m$ does not exist, or if $F$ is not a function type, t he static type of $i$ is \DYNAMIC{}; otherwise the static type of $i$ is the dec lared return type of $F$. |
3964 % The following is not needed because it is specified in 'Binding Actuals to For mals" | 3972 % The following is not needed because it is specified in 'Binding Actuals to For mals" |
3965 %Let $T_i$ be the static type of $a_i, i \in 1 .. n+k$. It is a static warning i f $F$ is not a supertype of $(T_1, \ldots, t_n, \{T_{n+1}$ $x_{n+1}, \ldots, T_ {n+k}$ $x_{n+k}\}) \to \bot$. | 3973 %Let $T_i$ be the static type of $a_i, i \in 1 .. n+k$. It is a static warning i f $F$ is not a supertype of $(T_1, \ldots, t_n, \{T_{n+1}$ $x_{n+1}, \ldots, T_ {n+k}$ $x_{n+k}\}) \to \bot$. |
3966 | 3974 |
3967 | 3975 |
3968 | 3976 |
3969 | 3977 |
3970 \subsubsection{Sending Messages} | 3978 \subsubsection{Sending Messages} |
3971 \LMLabel{sendingMessages} | 3979 \LMLabel{sendingMessages} |
3972 | 3980 |
3973 \LMHash{} | 3981 \LMHash{} |
3974 Messages are the sole means of communication among isolates. Messages are sent b y invoking specific methods in the Dart libraries; there is no specific syntax for sending a message. | 3982 Messages are the sole means of communication among isolates. Messages are sent b y invoking specific methods in the Dart libraries; there is no specific syntax for sending a message. |
3975 | 3983 |
3976 \commentary{In other words, the methods supporting sending messages embody primi tives of Dart that are not accessible to ordinary code, much like the methods th at spawn isolates. | 3984 \commentary{In other words, the methods supporting sending messages embody primi tives of Dart that are not accessible to ordinary code, much like the methods th at spawn isolates. |
3977 } | 3985 } |
3978 | 3986 |
3979 | 3987 |
3980 | 3988 |
3981 \subsection{ Property Extraction} | 3989 \subsection{ Property Extraction} |
3982 \LMLabel{propertyExtraction} | 3990 \LMLabel{propertyExtraction} |
3983 | 3991 |
3984 \LMHash{} | 3992 \LMHash{} |
3985 {\em Property extraction} allows for a member or constructor to be accessed as a property rather than a function. | 3993 {\em Property extraction} allows for a member or constructor to be accessed as a property rather than a function. |
3986 A property extraction can be either: | 3994 A property extraction can be either: |
3987 \begin{enumerate} | 3995 \begin{enumerate} |
3988 \item A {\em closurization} which converts a method or constructor into a closur e. Or | 3996 \item A {\em closurization} which converts a method or constructor into a closur e. Or |
3989 \item A {\em getter invocation} which returns the result of invoking of a getter method. | 3997 \item A {\em getter invocation} which returns the result of invoking of a getter method. |
3990 \end{enumerate} | 3998 \end{enumerate} |
3991 | 3999 |
3992 | 4000 |
3993 \commentary{Closures derived from members via closurization are colloquially kno wn as tear-offs} | 4001 \commentary{Closures derived from members via closurization are colloquially kno wn as tear-offs} |
3994 | 4002 |
3995 Property extraction can be either {\em conditional} or {\em unconditional}. | 4003 Property extraction can be either {\em conditional} or {\em unconditional}. |
3996 | 4004 |
3997 \rationale { | 4005 \rationale { |
3998 Tear-offs using the \cd{ x\#id} syntax cannot be conditional at this time; this is inconsistent, and is likely to be addressed in the near future, perhaps via notation such as \cd{ x?\#id} . As indicated in section \ref{ecmaConformance}, experimentation in this area is allowed. | 4006 Tear-offs using the \cd{ x\#id} syntax cannot be conditional at this time; this is inconsistent, and is likely to be addressed in the near future, perhaps via notation such as \cd{ x?\#id} . As indicated in section \ref{ecmaConformance}, experimentation in this area is allowed. |
3999 } | 4007 } |
4000 | 4008 |
4001 Evaluation of a {\em conditional property extraction expression} $e$ of the form $e_1?.id$ is equivalent to the evaluation of the expression $((x) => x == \NU LL ? \NULL : x.id)(e_1)$. | 4009 Evaluation of a {\em conditional property extraction expression} $e$ of the form $e_1?.id$ is equivalent to the evaluation of the expression $((x) => x == \NU LL ? \NULL : x.id)(e_1)$. |
4002 unless $e_1$ is a type literal, in which case it is equivalent to $e_1.m$. | 4010 unless $e_1$ is a type literal, in which case it is equivalent to $e_1.m$. |
4003 | 4011 |
4004 The static type of $e$ is the same as the static type of $e_1.id$. Let $T$ be th e static type of $e_1$ and let $y$ be a fresh variable of type $T$. Exactly the same static warnings that would be caused by $y.id$ are also generated in the ca se of $e_1?.id$. | 4012 The static type of $e$ is the same as the static type of $e_1.id$. Let $T$ be th e static type of $e_1$ and let $y$ be a fresh variable of type $T$. Exactly the same static warnings that would be caused by $y.id$ are also generated in the ca se of $e_1?.id$. |
4005 | 4013 |
4006 \LMHash{} | 4014 \LMHash{} |
4007 Unconditional property extraction takes several syntactic forms: $e.m$ (\ref{get terAccessAndMethodExtraction}), $\SUPER.m$ (\ref{superGetterAccessAndMethodClosu rization}), $e\#m$ (\ref{generalClosurization}), $\NEW{}$ $T\#m$ (\ref{namedCons tructorExtraction}), $\NEW{}$ $T\#$ (\ref{anonymousConstructorExtraction}) and $ \SUPER\#m$ (\ref{generalSuperPropertyExtraction}), where $e$ is an expression, $ m$ is an identifier optionally followed by an equal sign and $T$ is a type. | 4015 Unconditional property extraction takes several syntactic forms: $e.m$ (\ref{get terAccessAndMethodExtraction}), $\SUPER.m$ (\ref{superGetterAccessAndMethodClosu rization}), $e\#m$ (\ref{generalClosurization}), $\NEW{}$ $T\#m$ (\ref{namedCons tructorExtraction}), $\NEW{}$ $T\#$ (\ref{anonymousConstructorExtraction}) and $ \SUPER\#m$ (\ref{generalSuperPropertyExtraction}), where $e$ is an expression, $ m$ is an identifier optionally followed by an equal sign and $T$ is a type. |
4008 | 4016 |
4009 \subsubsection{Getter Access and Method Extraction} | 4017 \subsubsection{Getter Access and Method Extraction} |
4010 \LMLabel{getterAccessAndMethodExtraction} | 4018 \LMLabel{getterAccessAndMethodExtraction} |
4011 | 4019 |
4012 \LMHash{} | 4020 \LMHash{} |
4013 Evaluation of a property extraction $i$ of the form $e.m$ proceeds as follows: | 4021 Evaluation of a property extraction $i$ of the form $e.m$ proceeds as follows: |
4014 | 4022 |
4015 \LMHash{} | 4023 \LMHash{} |
4016 First, the expression $e$ is evaluated to an object $o$. Let $f$ be the result o f looking up (\ref{methodLookup}) method (\ref{instanceMethods}) $m$ in $o$ wit h respect to the current library $L$. If $o$ is an instance of \code{Type} but $e$ is not a constant type literal, then if $f$ is a method that forwards (\ref{ functionDeclarations}) to a static method, method lookup fails. If method looku p succeeds then $i$ evaluates to the closurization of method $f$ on object $o$ ( \ref{ordinaryMemberClosurization}). | 4024 First, the expression $e$ is evaluated to an object $o$. Let $f$ be the result o f looking up (\ref{methodLookup}) method (\ref{instanceMethods}) $m$ in $o$ wit h respect to the current library $L$. If $o$ is an instance of \code{Type} but $e$ is not a constant type literal, then if $f$ is a method that forwards (\ref{ functionDeclarations}) to a static method, method lookup fails. If method looku p succeeds then $i$ evaluates to the closurization of method $f$ on object $o$ ( \ref{ordinaryMemberClosurization}). |
4017 | 4025 |
4018 \commentary { | 4026 \commentary { |
4019 Note that $f$ is never an abstract method, because method lookup skips abstract methods. Hence, if $m$ refers to an abstract method, we will continue to the nex t step. However, since methods and getters never override each other, getter loo kup will necessarily fail as well, and \cd{noSuchMethod()} will ultimately be in voked. The regrettable implication is that the error will refer to a missing get ter rather than an attempt to closurize an abstract method. | 4027 Note that $f$ is never an abstract method, because method lookup skips abstract methods. Hence, if $m$ refers to an abstract method, we will continue to the nex t step. However, since methods and getters never override each other, getter loo kup will necessarily fail as well, and \cd{noSuchMethod()} will ultimately be in voked. The regrettable implication is that the error will refer to a missing get ter rather than an attempt to closurize an abstract method. |
4020 } | 4028 } |
4021 | 4029 |
4022 \LMHash{} | 4030 \LMHash{} |
4023 Otherwise, $i$ is a getter invocation. Let $f$ be the result of looking up | 4031 Otherwise, $i$ is a getter invocation. Let $f$ be the result of looking up |
4024 (\ref{getterAndSetterLookup}) getter (\ref{getters}) $m$ in $o$ with respect to $L$. If $o$ is an instance of \code{Type} but $e$ is not a constant type litera l, then if $f$ is a getter that forwards to a static getter, getter lookup fai ls. Otherwise, the body of $f$ is executed with \THIS{} bound to $o$. The value of $i$ is the result returned by the call to the getter function. | 4032 (\ref{getterAndSetterLookup}) getter (\ref{getters}) $m$ in $o$ with respect to $L$. If $o$ is an instance of \code{Type} but $e$ is not a constant type litera l, then if $f$ is a getter that forwards to a static getter, getter lookup fai ls. Otherwise, the body of $f$ is executed with \THIS{} bound to $o$. The value of $i$ is the result returned by the call to the getter function. |
4025 | 4033 |
4026 \LMHash{} | 4034 \LMHash{} |
4027 If the getter lookup has failed, then a new instance $im$ of the predefined cla ss \code{Invocation} is created, such that : | 4035 If the getter lookup has failed, then a new instance $im$ of the predefined cla ss \code{Invocation} is created, such that : |
4028 \begin{itemize} | 4036 \begin{itemize} |
4029 \item \code{im.isGetter} evaluates to \code{\TRUE{}}. | 4037 \item \code{im.isGetter} evaluates to \code{\TRUE{}}. |
4030 \item \code{im.memberName} evaluates to the symbol \code{m}. | 4038 \item \code{im.memberName} evaluates to the symbol \code{m}. |
4031 \item \code{im.positionalArguments} evaluates to the value of \code{\CONST{} []} . | 4039 \item \code{im.positionalArguments} evaluates to the value of \code{\CONST{} []} . |
4032 \item \code{im.namedArguments} evaluates to the value of \code{\CONST{} \{\}}. | 4040 \item \code{im.namedArguments} evaluates to the value of \code{\CONST{} \{\}}. |
4033 \end{itemize} | 4041 \end{itemize} |
4034 Then the method \code{noSuchMethod()} is looked up in $o$ and invoked with argu ment $im$, and the result of this invocation is the result of evaluating $i$. Ho wever, if the implementation found cannot be invoked with a single positional ar gument, the implementation of \code{noSuchMethod()} in class \code{Object} is i nvoked on $o$ with argument $im'$, where $im'$ is an instance of \code{Invocatio n} such that : | 4042 Then the method \code{noSuchMethod()} is looked up in $o$ and invoked with argu ment $im$, and the result of this invocation is the result of evaluating $i$. Ho wever, if the implementation found cannot be invoked with a single positional ar gument, the implementation of \code{noSuchMethod()} in class \code{Object} is i nvoked on $o$ with argument $im'$, where $im'$ is an instance of \code{Invocatio n} such that : |
(...skipping 21 matching lines...) Expand all Loading... | |
4056 \item $T$ is \code{Type}, $e$ is a constant type literal and the class correspo nding to $e$ has a static method or getter named $m$. | 4064 \item $T$ is \code{Type}, $e$ is a constant type literal and the class correspo nding to $e$ has a static method or getter named $m$. |
4057 \end{itemize} | 4065 \end{itemize} |
4058 | 4066 |
4059 \LMHash{} | 4067 \LMHash{} |
4060 The static type of $i$ is: | 4068 The static type of $i$ is: |
4061 \begin{itemize} | 4069 \begin{itemize} |
4062 \item The declared return type of $T.m$, if $T$ has an accessible instance gett er named $m$. | 4070 \item The declared return type of $T.m$, if $T$ has an accessible instance gett er named $m$. |
4063 \item The declared return type of $m$, if $T$ is \code{Type}, $e$ is a constant type literal and the class corresponding to $e$ declares an accessible static g etter named $m$. | 4071 \item The declared return type of $m$, if $T$ is \code{Type}, $e$ is a constant type literal and the class corresponding to $e$ declares an accessible static g etter named $m$. |
4064 \item The static type of function $T.m$ if $T$ has an accessible instance method named $m$. | 4072 \item The static type of function $T.m$ if $T$ has an accessible instance method named $m$. |
4065 \item The static type of function $m$, if $T$ is \code{Type}, $e$ is a constant type literal and the class corresponding to $e$ declares an accessible static m ethod named $m$. | 4073 \item The static type of function $m$, if $T$ is \code{Type}, $e$ is a constant type literal and the class corresponding to $e$ declares an accessible static m ethod named $m$. |
4066 \item The type \DYNAMIC{} otherwise. | 4074 \item The type \DYNAMIC{} otherwise. |
4067 \end{itemize} | 4075 \end{itemize} |
4068 | 4076 |
4069 | 4077 |
4070 \subsubsection{Super Getter Access and Method Closurization} | 4078 \subsubsection{Super Getter Access and Method Closurization} |
4071 \LMLabel{superGetterAccessAndMethodClosurization} | 4079 \LMLabel{superGetterAccessAndMethodClosurization} |
4072 | 4080 |
4073 \LMHash{} | 4081 \LMHash{} |
4074 Evaluation of a property extraction $i$ of the form $\SUPER.m$ proceeds as follo ws: | 4082 Evaluation of a property extraction $i$ of the form $\SUPER.m$ proceeds as follo ws: |
4075 | 4083 |
4076 \LMHash{} | 4084 \LMHash{} |
4077 Let $g$ be the method currently executing, and let $C$ be the class in which $g$ was looked up. Let $S_{dynamic}$ be the superclass of $C$. Let $f$ be the resu lt of looking up method $m$ in $S_{dynamic}$ with respect to the current library $L$. If method lookup succeeds then $i$ evaluates to the closurization of meth od $f$ with respect to superclass $S_{dynamic}$ (\ref{superClosurization}). | 4085 Let $g$ be the method currently executing, and let $C$ be the class in which $g$ was looked up. Let $S_{dynamic}$ be the superclass of $C$. Let $f$ be the resu lt of looking up method $m$ in $S_{dynamic}$ with respect to the current library $L$. If method lookup succeeds then $i$ evaluates to the closurization of meth od $f$ with respect to superclass $S_{dynamic}$ (\ref{superClosurization}). |
4078 | 4086 |
4079 \LMHash{} | 4087 \LMHash{} |
4080 Otherwise, $i$ is a getter invocation. Let $f$ be the result of looking up ge tter $m$ in $S_{dynamic}$ with respect to $L$. The body of $f$ is executed wi th \THIS{} bound to the current value of \THIS{}. The value of $i$ is the resu lt returned by the call to the getter function. | 4088 Otherwise, $i$ is a getter invocation. Let $f$ be the result of looking up ge tter $m$ in $S_{dynamic}$ with respect to $L$. The body of $f$ is executed wi th \THIS{} bound to the current value of \THIS{}. The value of $i$ is the resu lt returned by the call to the getter function. |
4081 | 4089 |
4082 \LMHash{} | 4090 \LMHash{} |
4083 If the getter lookup has failed, then a new instance $im$ of the predefined cla ss \code{Invocation} is created, such that : | 4091 If the getter lookup has failed, then a new instance $im$ of the predefined cla ss \code{Invocation} is created, such that : |
4084 \begin{itemize} | 4092 \begin{itemize} |
4085 \item \code{im.isGetter} evaluates to \code{\TRUE{}}. | 4093 \item \code{im.isGetter} evaluates to \code{\TRUE{}}. |
4086 \item \code{im.memberName} evaluates to the symbol \code{m}. | 4094 \item \code{im.memberName} evaluates to the symbol \code{m}. |
4087 \item \code{im.positionalArguments} evaluates to the value of \code{\CONST{} []} . | 4095 \item \code{im.positionalArguments} evaluates to the value of \code{\CONST{} []} . |
4088 \item \code{im.namedArguments} evaluates to the value of \code{\CONST{} \{\}}. | 4096 \item \code{im.namedArguments} evaluates to the value of \code{\CONST{} \{\}}. |
4089 \end{itemize} | 4097 \end{itemize} |
4090 Then the method \code{noSuchMethod()} is looked up in $S_{dynamic}$ and invoked with argument $im$, and the result of this invocation is the result of evaluati ng $i$. However, if the implementation found cannot be invoked with a single pos itional argument, the implementation of \code{noSuchMethod()} in class \code{Ob ject} is invoked on \THIS{} with argument $im'$, where $im'$ is an instance of \ code{Invocation} such that : | 4098 Then the method \code{noSuchMethod()} is looked up in $S_{dynamic}$ and invoked with argument $im$, and the result of this invocation is the result of evaluati ng $i$. However, if the implementation found cannot be invoked with a single pos itional argument, the implementation of \code{noSuchMethod()} in class \code{Ob ject} is invoked on \THIS{} with argument $im'$, where $im'$ is an instance of \ code{Invocation} such that : |
4091 \begin{itemize} | 4099 \begin{itemize} |
4092 \item \code{im'.isMethod} evaluates to \code{\TRUE{}}. | 4100 \item \code{im'.isMethod} evaluates to \code{\TRUE{}}. |
4093 \item \code{im'.memberName} evaluates to \code{\#noSuchMethod}. | 4101 \item \code{im'.memberName} evaluates to \code{\#noSuchMethod}. |
4094 \item \code{im'.positionalArguments} evaluates to an immutable list whose sole e lement is $im$. | 4102 \item \code{im'.positionalArguments} evaluates to an immutable list whose sole e lement is $im$. |
4095 \item \code{im'.namedArguments} evaluates to the value of \code{\CONST{} \{\}}. | 4103 \item \code{im'.namedArguments} evaluates to the value of \code{\CONST{} \{\}}. |
4096 \end{itemize} | 4104 \end{itemize} |
4097 and the result of this latter invocation is the result of evaluating $i$. | 4105 and the result of this latter invocation is the result of evaluating $i$. |
4098 | 4106 |
4099 \LMHash{} | 4107 \LMHash{} |
4100 Let $S_{static}$ be the superclass of the immediately enclosing class. It is a s tatic type warning if $S_{static}$ does not have an accessible instance method o r getter named $m$. | 4108 Let $S_{static}$ be the superclass of the immediately enclosing class. It is a s tatic type warning if $S_{static}$ does not have an accessible instance method o r getter named $m$. |
4101 | 4109 |
4102 The static type of $i$ is: | 4110 The static type of $i$ is: |
4103 \begin{itemize} | 4111 \begin{itemize} |
4104 \item The declared return type of $S_{static}.m$, if $S_{static}$ has an accessi ble instance getter named $m$. | 4112 \item The declared return type of $S_{static}.m$, if $S_{static}$ has an accessi ble instance getter named $m$. |
4105 \item The static type of function $S_{static}.m$ if $S_{static}$ has an accessib le instance method named $m$. | 4113 \item The static type of function $S_{static}.m$ if $S_{static}$ has an accessib le instance method named $m$. |
4106 \item The type \DYNAMIC{} otherwise. | 4114 \item The type \DYNAMIC{} otherwise. |
4107 \end{itemize} | 4115 \end{itemize} |
4108 | 4116 |
4109 | 4117 |
4110 \subsubsection{General Closurization} | 4118 \subsubsection{General Closurization} |
4111 \LMLabel{generalClosurization} | 4119 \LMLabel{generalClosurization} |
4112 | 4120 |
4113 \LMHash{} | 4121 \LMHash{} |
4114 Evaluation of a property extraction $i$ of the form $e\#m$ proceeds as follows: | 4122 Evaluation of a property extraction $i$ of the form $e\#m$ proceeds as follows: |
4115 | 4123 |
4116 \LMHash{} | 4124 \LMHash{} |
4117 First, the expression $e$ is evaluated to an object $o$. Then: | 4125 First, the expression $e$ is evaluated to an object $o$. Then: |
4118 | 4126 |
4119 \LMHash{} | 4127 \LMHash{} |
4120 if $m$ is a setter name, let $f$ be the result of looking up setter $m$ in $o$ with respect to the current library $L$. If $o$ is an instance of \cd{Type} bu t $e$ is not a constant type literal, then if $f$ is a method that forwards to a static setter, setter lookup fails. If setter lookup succeeds then $i$ evaluate s to the closurization of setter $f$ on object $o$ (\ref{ordinaryMemberClosuriza tion}). | 4128 if $m$ is a setter name, let $f$ be the result of looking up setter $m$ in $o$ with respect to the current library $L$. If $o$ is an instance of \cd{Type} bu t $e$ is not a constant type literal, then if $f$ is a method that forwards to a static setter, setter lookup fails. If setter lookup succeeds then $i$ evaluate s to the closurization of setter $f$ on object $o$ (\ref{ordinaryMemberClosuriza tion}). |
4121 If setter lookup failed, a \cd{NoSuchMethodError} is thrown. | 4129 If setter lookup failed, a \cd{NoSuchMethodError} is thrown. |
4122 | 4130 |
4123 \rationale { | 4131 \rationale { |
4124 It would be more in keeping with the rules of Dart to invoke \cd{noSuchMethod} i n this and similar cases below. However, current implementations of \cd{noSuchM ethod} cannot distinguish between an invocation of a closurization and an actual call. It is likely that future versions of Dart will provide a mechanism to de tect whether \cd{noSuchMethod} is invoked in response to a closurization, say by means of a getter like \cd{isTearOff}. By being conservative at this stage and insisting on failure, we can ensure that no functioning code will break when/if this functionality is introduced. | 4132 It would be more in keeping with the rules of Dart to invoke \cd{noSuchMethod} i n this and similar cases below. However, current implementations of \cd{noSuchM ethod} cannot distinguish between an invocation of a closurization and an actual call. It is likely that future versions of Dart will provide a mechanism to de tect whether \cd{noSuchMethod} is invoked in response to a closurization, say by means of a getter like \cd{isTearOff}. By being conservative at this stage and insisting on failure, we can ensure that no functioning code will break when/if this functionality is introduced. |
4125 } | 4133 } |
4126 | 4134 |
4127 | 4135 |
4128 \LMHash{} | 4136 \LMHash{} |
4129 If $m$ is not a setter name, let $f$ be the result of looking up method $m$ in $ o$ with respect to the current library $L$. If $o$ is an instance of \cd{Type} but $e$ is not a constant type literal, then if $f$ is a method that forwards t o a static method, method lookup fails. If method lookup succeeds then $i$ evalu ates to the closurization of method $f$ on object $o$ (\ref{ordinaryMemberClosur ization}). | 4137 If $m$ is not a setter name, let $f$ be the result of looking up method $m$ in $ o$ with respect to the current library $L$. If $o$ is an instance of \cd{Type} but $e$ is not a constant type literal, then if $f$ is a method that forwards t o a static method, method lookup fails. If method lookup succeeds then $i$ evalu ates to the closurization of method $f$ on object $o$ (\ref{ordinaryMemberClosur ization}). |
4130 | 4138 |
4131 \LMHash{} | 4139 \LMHash{} |
4132 If method lookup failed, let $f$ be the result of looking up getter $m$ in $o$ w ith respect to the current library $L$. If $o$ is an instance of \cd{Type} but $e$ is not a constant type literal, then if $f$ is a method that forwards to a static getter, getter lookup fails. If getter lookup succeeds then $i$ evaluates to the closurization of getter $f$ on object $o$ (\ref{ordinaryMemberClosurizat ion}). | 4140 If method lookup failed, let $f$ be the result of looking up getter $m$ in $o$ w ith respect to the current library $L$. If $o$ is an instance of \cd{Type} but $e$ is not a constant type literal, then if $f$ is a method that forwards to a static getter, getter lookup fails. If getter lookup succeeds then $i$ evaluates to the closurization of getter $f$ on object $o$ (\ref{ordinaryMemberClosurizat ion}). |
4133 If getter lookup failed, a \cd{NoSuchMethodError} is thrown. | 4141 If getter lookup failed, a \cd{NoSuchMethodError} is thrown. |
4134 | 4142 |
4135 | 4143 |
4136 | 4144 |
4137 | 4145 |
4138 %\LMHash{} | 4146 %\LMHash{} |
4139 %Otherwise, a new instance $im$ of the predefined class \code{Invocation} is created, such that : | 4147 %Otherwise, a new instance $im$ of the predefined class \code{Invocation} is created, such that : |
4140 %\begin{itemize} | 4148 %\begin{itemize} |
4141 %\item If $m$ is a setter name, \code{im.isSetter} evaluates to \code{\TRUE{}}; otherwise \code{im.isMethod} evaluates to \code{\TRUE{}} | 4149 %\item If $m$ is a setter name, \code{im.isSetter} evaluates to \code{\TRUE{}}; otherwise \code{im.isMethod} evaluates to \code{\TRUE{}} |
4142 %\item \code{im.memberName} evaluates to the symbol \code{m}. | 4150 %\item \code{im.memberName} evaluates to the symbol \code{m}. |
4143 %\item \code{im.positionalArguments} evaluates to the value of \code{\CONST{} [] }. | 4151 %\item \code{im.positionalArguments} evaluates to the value of \code{\CONST{} [] }. |
4144 %\item \code{im.namedArguments} evaluates to the value of \code{\CONST{} \{\}}. | 4152 %\item \code{im.namedArguments} evaluates to the value of \code{\CONST{} \{\}}. |
4145 %\end{itemize} | 4153 %\end{itemize} |
4146 %Then the method \code{noSuchMethod()} is looked up in $o$ and invoked with arg ument $im$, and the result of this invocation is the result of evaluating $i$. H owever, if the implementation found cannot be invoked with a single positional a rgument, the implementation of \code{noSuchMethod()} in class \code{Object} is invoked on $o$ with argument $im'$, where $im'$ is an instance of \code{Invocati on} such that : | 4154 %Then the method \code{noSuchMethod()} is looked up in $o$ and invoked with arg ument $im$, and the result of this invocation is the result of evaluating $i$. H owever, if the implementation found cannot be invoked with a single positional a rgument, the implementation of \code{noSuchMethod()} in class \code{Object} is invoked on $o$ with argument $im'$, where $im'$ is an instance of \code{Invocati on} such that : |
4147 %\begin{itemize} | 4155 %\begin{itemize} |
4148 %\item \code{im'.isMethod} evaluates to \code{\TRUE{}}. | 4156 %\item \code{im'.isMethod} evaluates to \code{\TRUE{}}. |
4149 %\item \code{im'.memberName} evaluates to \code{\#noSuchMethod}. | 4157 %\item \code{im'.memberName} evaluates to \code{\#noSuchMethod}. |
4150 %\item \code{im'.positionalArguments} evaluates to an immutable list whose sole element is $im$. | 4158 %\item \code{im'.positionalArguments} evaluates to an immutable list whose sole element is $im$. |
4151 %\item \code{im'.namedArguments} evaluates to the value of \code{\CONST{} \{\}}. | 4159 %\item \code{im'.namedArguments} evaluates to the value of \code{\CONST{} \{\}}. |
4152 %\end{itemize} | 4160 %\end{itemize} |
4153 %and the result of this latter invocation is the result of evaluating $i$. | 4161 %and the result of this latter invocation is the result of evaluating $i$. |
4154 | 4162 |
4155 \LMHash{} | 4163 \LMHash{} |
4156 It is a compile-time error if $e$ is a prefix object (\ref{imports}) and $m$ ref ers to a type or a member of class \cd{Object}. | 4164 It is a compile-time error if $e$ is a prefix object, $p$, (\ref{imports}) and $ m$ refers to a type accessible via $p$ or to a member of class \cd{Object}. |
4157 | 4165 |
4158 \commentary{ | 4166 \commentary{ |
4159 This restriction is in line with other limitations on the use of prefixes as obj ects. The only permitted uses of $p\#m$ are closurizing top level methods and ge tters imported via the prefix $p$. Top level methods are directly available by t heir qualified names: $p.m$. However, getters and setters are not, and allowing their closurization is the whole point of the $e\#m$ syntax. | 4167 This restriction is in line with other limitations on the use of prefixes as obj ects. The only permitted uses of $p\#m$ are closurizing top level methods and ge tters imported via the prefix $p$. Top level methods are directly available by t heir qualified names: $p.m$. However, getters and setters are not, and allowing their closurization is the whole point of the $e\#m$ syntax. |
4160 } | 4168 } |
4161 | 4169 |
4162 \LMHash{} | 4170 \LMHash{} |
4163 Let $T$ be the static type of $e$. It is a static type warning if $T$ does not h ave an accessible instance method or getter named $m$ unless either: | 4171 Let $T$ be the static type of $e$. It is a static type warning if $T$ does not h ave an accessible instance method or getter named $m$ unless either: |
4164 \begin{itemize} | 4172 \begin{itemize} |
4165 \item $T$ or a superinterface of $T$ is annotated with an annotation denoting a constant identical to the constant \code{@proxy} defined in \cd{dart:core}. Or | 4173 \item $T$ or a superinterface of $T$ is annotated with an annotation denoting a constant identical to the constant \code{@proxy} defined in \cd{dart:core}. Or |
4166 \item $T$ is \cd{Type}, $e$ is a constant type literal and the class correspondi ng to $e$ declares an accessible static method or getter named $m$. | 4174 \item $T$ is \cd{Type}, $e$ is a constant type literal and the class correspondi ng to $e$ declares an accessible static method or getter named $m$. |
4167 \item $T$ is \code{Function} and $m$ is \CALL. | 4175 \item $T$ is \code{Function} and $m$ is \CALL. |
4168 \end{itemize} | 4176 \end{itemize} |
4169 | 4177 |
4170 The static type of $i$ is: | 4178 The static type of $i$ is: |
4171 \begin{itemize} | 4179 \begin{itemize} |
4172 \item The static type of function $T.m$, if $T$ has an accessible instance membe r named $m$. | 4180 \item The static type of function $T.m$, if $T$ has an accessible instance membe r named $m$. |
4173 \item The static type of function $T.m$, if $T$ is \cd{Type}, $e$ is a constant type literal and the class corresponding to $e$ declares an accessible static me mber or constructor named $m$. | 4181 \item The static type of function $T.m$, if $T$ is \cd{Type}, $e$ is a constant type literal and the class corresponding to $e$ declares an accessible static me mber or constructor named $m$. |
4174 \item \code{Function} if $T$ is \code{Function} and $m$ is \CALL. | 4182 \item \code{Function} if $T$ is \code{Function} and $m$ is \CALL. |
4175 \item The type \DYNAMIC{} otherwise. | 4183 \item The type \DYNAMIC{} otherwise. |
4176 \end{itemize} | 4184 \end{itemize} |
4177 | 4185 |
4178 \subsubsection{Named Constructor Extraction} | 4186 \subsubsection{Named Constructor Extraction} |
4179 \LMLabel{namedConstructorExtraction} | 4187 \LMLabel{namedConstructorExtraction} |
4180 | 4188 |
4181 \LMHash{} | 4189 \LMHash{} |
4182 Evaluation of a property extraction $i$ of the form \NEW{} $T\#m$ proceeds as fo llows: | 4190 Evaluation of a property extraction $i$ of the form \NEW{} $T\#m$ proceeds as fo llows: |
4183 | 4191 |
4184 \LMHash{} | 4192 \LMHash{} |
4185 If $T$ is a malformed type (\ref{staticTypes}), a dynamic error occurs. If $T$ i s a deferred type with prefix $p$, then if $p$ has not been successfully loaded, a dynamic error occurs. If $T$ does not denote a class, a dynamic error occurs. In checked mode, if $T$ or any of its superclasses is malbounded a dynamic erro r occurs. Otherwise, if the type $T$ does not declare an accessible named constr uctor $f$ with name $m$, a \cd{NoSuchMethodError} is thrown. Otherwise, $i$ eval uates to the closurization of constructor $f$ of type $T$ (\ref{namedConstructor Closurization}). | 4193 If $T$ is a malformed type (\ref{staticTypes}), a dynamic error occurs. If $T$ i s a deferred type with prefix $p$, then if $p$ has not been successfully loaded, a dynamic error occurs. If $T$ does not denote a class, a dynamic error occurs. In checked mode, if $T$ or any of its superclasses is malbounded a dynamic erro r occurs. Otherwise, if the type $T$ does not declare an accessible named constr uctor $f$ with name $m$, a \cd{NoSuchMethodError} is thrown. Otherwise, $i$ eval uates to the closurization of constructor $f$ of type $T$ (\ref{namedConstructor Closurization}). |
4186 | 4194 |
4187 \commentary{Note that if $T$ is malformed or malbounded, a static warning occurs , as always.} | 4195 \commentary{Note that if $T$ is malformed or malbounded, a static warning occurs , as always.} |
4188 | 4196 |
4189 \LMHash{} | 4197 \LMHash{} |
4190 The static type of $i$ is the type of the constructor function, if $T$ denotes a class in the surrounding scope with an accessible constructor $f$ named $m$. Ot herwise the static type of $i$ is \DYNAMIC{}. | 4198 The static type of $i$ is the type of the constructor function, if $T$ denotes a class in the surrounding scope with an accessible constructor $f$ named $m$. Ot herwise the static type of $i$ is \DYNAMIC{}. |
4191 | 4199 |
4200 It is a compile-time error if $T$ is an enumerated type (\ref{enums}). | |
4201 | |
4192 \subsubsection{Anonymous Constructor Extraction} | 4202 \subsubsection{Anonymous Constructor Extraction} |
4193 \LMLabel{anonymousConstructorExtraction} | 4203 \LMLabel{anonymousConstructorExtraction} |
4194 | 4204 |
4195 \LMHash{} | 4205 \LMHash{} |
4196 Evaluation of a property extraction $i$ of the form \NEW{} $T\#$ proceeds as fol lows: | 4206 Evaluation of a property extraction $i$ of the form \NEW{} $T\#$ proceeds as fol lows: |
4197 | 4207 |
4198 \LMHash{} | 4208 \LMHash{} |
4199 If $T$ is a malformed type (\ref{staticTypes}), a dynamic error occurs. If $T$ i s a deferred type with prefix $p$, then if $p$ has not been successfully loaded, a dynamic error occurs. If $T$ does not denote a class, a dynamic error occurs. In checked mode, if $T$ or any of its superclasses is malbounded a dynamic erro r occurs. Otherwise, if the type $T$ does not declare an accessible anonymous co nstructor, a \cd{NoSuchMethodError} is thrown. Otherwise, $i$ evaluates to the c losurization of the anonymous constructor of type $T$ (\ref{anonymousConstructor Closurization}). | 4209 If $T$ is a malformed type (\ref{staticTypes}), a dynamic error occurs. If $T$ i s a deferred type with prefix $p$, then if $p$ has not been successfully loaded, a dynamic error occurs. If $T$ does not denote a class, a dynamic error occurs. In checked mode, if $T$ or any of its superclasses is malbounded a dynamic erro r occurs. Otherwise, if the type $T$ does not declare an accessible anonymous co nstructor, a \cd{NoSuchMethodError} is thrown. Otherwise, $i$ evaluates to the c losurization of the anonymous constructor of type $T$ (\ref{anonymousConstructor Closurization}). |
4200 | 4210 |
4201 \commentary{Again, note that if $T$ is malformed or malbounded, existing rules e nsure that a static warning occurs. This also means that $x\#$ where $x$ is not a type will always give a static warning.} | 4211 \commentary{Again, note that if $T$ is malformed or malbounded, existing rules e nsure that a static warning occurs. This also means that $x\#$ where $x$ is not a type will always give a static warning.} |
4202 | 4212 |
4203 \LMHash{} | 4213 \LMHash{} |
4204 The static type of $i$ is the type of the constructor function $T()$, if $T$ den otes a class in the surrounding scope with an anonymous constructor $T()$. Other wise the static type of $i$ is \DYNAMIC{}. | 4214 The static type of $i$ is the type of the constructor function $T()$, if $T$ den otes a class in the surrounding scope with an anonymous constructor $T()$. Other wise the static type of $i$ is \DYNAMIC{}. |
4205 | 4215 |
4216 It is a compile-time error if $T$ is an enumerated type (\ref{enums}). | |
4217 | |
4218 | |
4206 \subsubsection{General Super Property Extraction} | 4219 \subsubsection{General Super Property Extraction} |
4207 \LMLabel{generalSuperPropertyExtraction} | 4220 \LMLabel{generalSuperPropertyExtraction} |
4208 | 4221 |
4209 | 4222 |
4210 \LMHash{} | 4223 \LMHash{} |
4211 Evaluation of a property extraction $i$ of the form \SUPER$\#m$ proceeds as foll ows: | 4224 Evaluation of a property extraction $i$ of the form \SUPER$\#m$ proceeds as foll ows: |
4212 | 4225 |
4213 \LMHash{} | 4226 \LMHash{} |
4214 Let $g$ be the method currently executing, and let $C$ be the class in which $g$ was looked up. Let $S_{dynamic}$ be the superclass of $C$. | 4227 Let $g$ be the method currently executing, and let $C$ be the class in which $g$ was looked up. Let $S_{dynamic}$ be the superclass of $C$. |
4215 | 4228 |
4216 \LMHash{} | 4229 \LMHash{} |
4217 If $m$ is a setter name, let $f$ be the result of looking up setter $m$ in $S_{d ynamic}$ with respect to the current library $L$. If setter lookup succeeds then $i$ evaluates to the closurization of setter $f$ with respect to superclass $S _{dynamic}$ (\ref{superClosurization}). If setter lookup failed, a \cd{NoSuchM ethodError} is thrown. | 4230 If $m$ is a setter name, let $f$ be the result of looking up setter $m$ in $S_{d ynamic}$ with respect to the current library $L$. If setter lookup succeeds then $i$ evaluates to the closurization of setter $f$ with respect to superclass $S _{dynamic}$ (\ref{superClosurization}). If setter lookup failed, a \cd{NoSuchM ethodError} is thrown. |
4218 | 4231 |
4219 If $m$ is not a setter name, let $f$ be the result of looking up method $m$ in $ S_{dynamic}$ with respect to the current library $L$. If method lookup succeeds then $i$ evaluates to the closurization of method $m$ with respect to superclass $S_{dynamic}$ (\ref{superClosurization}). | 4232 If $m$ is not a setter name, let $f$ be the result of looking up method $m$ in $ S_{dynamic}$ with respect to the current library $L$. If method lookup succeeds then $i$ evaluates to the closurization of method $m$ with respect to superclass $S_{dynamic}$ (\ref{superClosurization}). |
4220 | 4233 |
4221 \LMHash{} | 4234 \LMHash{} |
4222 Otherwise, let $f$ be the result of looking up getter $m$ in $S_{dynamic}$ with respect to the current library $L$. If getter lookup succeeds then $i$ evaluat es to the closurization of getter $f$ with respect to superclass $S_{dynamic}$ ( \ref{superClosurization}). If getter lookup failed, a \cd{NoSuchMethodError} i s thrown. | 4235 Otherwise, let $f$ be the result of looking up getter $m$ in $S_{dynamic}$ with respect to the current library $L$. If getter lookup succeeds then $i$ evaluat es to the closurization of getter $f$ with respect to superclass $S_{dynamic}$ ( \ref{superClosurization}). If getter lookup failed, a \cd{NoSuchMethodError} i s thrown. |
4223 | 4236 |
4224 \LMHash{} | 4237 \LMHash{} |
4225 Let $S_{static}$ be the superclass of the immediately enclosing class.It is a st atic type warning if $S_{static}$ does not have an accessible instance member na med $m$. | 4238 Let $S_{static}$ be the superclass of the immediately enclosing class.It is a st atic type warning if $S_{static}$ does not have an accessible instance member na med $m$. |
4226 | 4239 |
4227 \LMHash{} | 4240 \LMHash{} |
4228 The static type of $i$ is the static type of the function $S_{static}.m$, if $S _{static}$ has an accessible instance member named $m$. Otherwise the static typ e of $i$ is \DYNAMIC{}. | 4241 The static type of $i$ is the static type of the function $S_{static}.m$, if $S _{static}$ has an accessible instance member named $m$. Otherwise the static typ e of $i$ is \DYNAMIC{}. |
4229 | 4242 |
4230 | 4243 |
4231 | 4244 |
4232 \subsubsection{Ordinary Member Closurization} | 4245 \subsubsection{Ordinary Member Closurization} |
4233 \LMLabel{ordinaryMemberClosurization} | 4246 \LMLabel{ordinaryMemberClosurization} |
4234 | 4247 |
4235 | 4248 |
4236 \LMHash{} | 4249 \LMHash{} |
4237 Let $o$ be an object, and let $u$ be a fresh final variable bound to $o$. | 4250 Let $o$ be an object, and let $u$ be a fresh final variable bound to $o$. |
4238 The {\em closurization of method $f$ on object $o$} is defined to be equivalent to: | 4251 The {\em closurization of method $f$ on object $o$} is defined to be equivalent to: |
4239 \begin{itemize} | 4252 \begin{itemize} |
4240 \item $(a) \{\RETURN{}$ $u$ $op$ $a;$\} if $f$ is named $op$ and $op$ is one of \code{$<$, $>$, $<$=, $>$=, ==, -, +, /, \~{}/, *, \%, $|$, \^{}, \&, $<<$, $> >$} (this precludes closurization of unary -). | 4253 \item $(a) \{\RETURN{}$ $u$ $op$ $a;$\} if $f$ is named $op$ and $op$ is one of \code{$<$, $>$, $<$=, $>$=, ==, -, +, /, \~{}/, *, \%, $|$, \^{}, \&, $<<$, $> >$} (this precludes closurization of unary -). |
4241 \item $() \{\RETURN{}$ \~{} $u;$\} if $f$ is named \~{}. | 4254 \item $() \{\RETURN{}$ \~{} $u;$\} if $f$ is named \~{}. |
4242 \item $(a) \{\RETURN{}$ $u[a];$\} if $f$ is named $[]$. | 4255 \item $(a) \{\RETURN{}$ $u[a];$\} if $f$ is named $[]$. |
4243 \item $(a, b) \{\RETURN{}$ $u[a] = b;$\} if $f$ is named $[]=$. | 4256 \item $(a, b) \{\RETURN{}$ $u[a] = b;$\} if $f$ is named $[]=$. |
4244 \item | 4257 \item |
4245 \begin{dartCode} | 4258 \begin{dartCode} |
4246 $(r_1, \ldots, r_n, \{p_1 : d_1, \ldots , p_k : d_k\})$ \{ | 4259 $(r_1, \ldots, r_n, \{p_1 : d_1, \ldots , p_k : d_k\})$ \{ |
4247 \RETURN{} $ u.m(r_1, \ldots, r_n, p_1: p_1, \ldots, p_k: p_k);$ | 4260 \RETURN{} $ u.m(r_1, \ldots, r_n, p_1: p_1, \ldots, p_k: p_k);$ |
4248 \} | 4261 \} |
4249 \end{dartCode} | 4262 \end{dartCode} |
4250 if $f$ is named $m$ and has required parameters $r_1, \ldots, r_n$, and named pa rameters $p_1, \ldots, p_k$ with defaults $d_1, \ldots, d_k$. | 4263 if $f$ is named $m$ and has required parameters $r_1, \ldots, r_n$, and named pa rameters $p_1, \ldots, p_k$ with defaults $d_1, \ldots, d_k$. |
4251 \item | 4264 \item |
4252 \begin{dartCode} | 4265 \begin{dartCode} |
4253 $(r_1, \ldots, r_n, [p_1 = d_1, \ldots , p_k = d_k])$\{ | 4266 $(r_1, \ldots, r_n, [p_1 = d_1, \ldots , p_k = d_k])$\{ |
4254 \RETURN{} $u.m(r_1, \ldots, r_n, p_1, \ldots, p_k)$; | 4267 \RETURN{} $u.m(r_1, \ldots, r_n, p_1, \ldots, p_k)$; |
4255 \} | 4268 \} |
4256 \end{dartCode} | 4269 \end{dartCode} |
4257 | 4270 |
4258 if $f$ is named $m$ and has required parameters $r_1, \ldots, r_n$, and optional positional parameters $p_1, \ldots, p_k$ with defaults $d_1, \ldots, d_k$. | 4271 if $f$ is named $m$ and has required parameters $r_1, \ldots, r_n$, and optional positional parameters $p_1, \ldots, p_k$ with defaults $d_1, \ldots, d_k$. |
4259 \end{itemize} | 4272 \end{itemize} |
4260 | 4273 |
4261 \LMHash{} | 4274 \LMHash{} |
(...skipping 22 matching lines...) Expand all Loading... | |
4284 } | 4297 } |
4285 | 4298 |
4286 | 4299 |
4287 | 4300 |
4288 \subsubsection{Named Constructor Closurization} | 4301 \subsubsection{Named Constructor Closurization} |
4289 \LMLabel{namedConstructorClosurization} | 4302 \LMLabel{namedConstructorClosurization} |
4290 | 4303 |
4291 \LMHash{} | 4304 \LMHash{} |
4292 The {\em closurization of constructor $f$ of type $T$} is defined to be equivale nt to: | 4305 The {\em closurization of constructor $f$ of type $T$} is defined to be equivale nt to: |
4293 \begin{itemize} | 4306 \begin{itemize} |
4294 \item | 4307 \item |
4295 \begin{dartCode} | 4308 \begin{dartCode} |
4296 $(r_1, \ldots, r_n, \{p_1 : d_1, \ldots , p_k : d_k\})$ \{ | 4309 $(r_1, \ldots, r_n, \{p_1 : d_1, \ldots , p_k : d_k\})$ \{ |
4297 \RETURN{} \NEW{} $T.m(r_1, \ldots, r_n, p_1: p_1, \ldots, p_k: p_k);$ | 4310 \RETURN{} \NEW{} $T.m(r_1, \ldots, r_n, p_1: p_1, \ldots, p_k: p_k);$ |
4298 \} | 4311 \} |
4299 \end{dartCode} | 4312 \end{dartCode} |
4300 | 4313 |
4301 if $f$ is a named constructor with name $m$ that has required parameters $r_1, \ ldots, r_n$, and named parameters $p_1, \ldots, p_k$ with defaults $d_1, \ldots, d_k$. | 4314 if $f$ is a named constructor with name $m$ that has required parameters $r_1, \ ldots, r_n$, and named parameters $p_1, \ldots, p_k$ with defaults $d_1, \ldots, d_k$. |
4302 \item | 4315 \item |
4303 \begin{dartCode} | 4316 \begin{dartCode} |
4304 $(r_1, \ldots, r_n, [p_1 = d_1, \ldots , p_k = d_k])$\{ | 4317 $(r_1, \ldots, r_n, [p_1 = d_1, \ldots , p_k = d_k])$\{ |
4305 \RETURN{} \NEW{} $T.m(r_1, \ldots, r_n, p_1, \ldots, p_k)$; | 4318 \RETURN{} \NEW{} $T.m(r_1, \ldots, r_n, p_1, \ldots, p_k)$; |
4306 \} | 4319 \} |
4307 \end{dartCode} | 4320 \end{dartCode} |
4308 | 4321 |
4309 if $f$ is a named constructor with name $m$ that has required parameters $r_1, \ ldots, r_n$, and optional positional parameters $p_1, \ldots, p_k$ with defaults $d_1, \ldots, d_k$. | 4322 if $f$ is a named constructor with name $m$ that has required parameters $r_1, \ ldots, r_n$, and optional positional parameters $p_1, \ldots, p_k$ with defaults $d_1, \ldots, d_k$. |
4310 \end{itemize} | 4323 \end{itemize} |
4311 | 4324 |
4312 \LMHash{} | 4325 \LMHash{} |
4313 Except that iff \code{identical($T_1, T_2$)} then \cd{\NEW{} $T_1\#m$ == \NEW {} $T_2\#m$}. | 4326 Except that iff \code{identical($T_1, T_2$)} then \cd{\NEW{} $T_1\#m$ == \NEW {} $T_2\#m$}. |
4314 | 4327 |
4315 \commentary{ | 4328 \commentary{ |
4316 The above implies that for non-parameterized types, one can rely on the equality of closures resulting from closurization on the ``same'' type. For parameterize d types, one cannot, since there is no requirement to canonicalize them. | 4329 The above implies that for non-parameterized types, one can rely on the equality of closures resulting from closurization on the ``same'' type. For parameterize d types, one cannot, since there is no requirement to canonicalize them. |
4317 } | 4330 } |
4318 | 4331 |
4319 \subsubsection{Anonymous Constructor Closurization} | 4332 \subsubsection{Anonymous Constructor Closurization} |
4320 \LMLabel{anonymousConstructorClosurization} | 4333 \LMLabel{anonymousConstructorClosurization} |
4321 | 4334 |
4322 \LMHash{} | 4335 \LMHash{} |
4323 The {\em closurization of anonymous constructor $f$ of type $T$} is defined to b e equivalent to: | 4336 The {\em closurization of anonymous constructor $f$ of type $T$} is defined to b e equivalent to: |
4324 \begin{itemize} | 4337 \begin{itemize} |
4325 \item | 4338 \item |
4326 \begin{dartCode} | 4339 \begin{dartCode} |
4327 $(r_1, \ldots, r_n, \{p_1 : d_1, \ldots , p_k : d_k\})$ \{ | 4340 $(r_1, \ldots, r_n, \{p_1 : d_1, \ldots , p_k : d_k\})$ \{ |
4328 \RETURN{} \NEW{} $T(r_1, \ldots, r_n, p_1: p_1, \ldots, p_k: p_k);$ | 4341 \RETURN{} \NEW{} $T(r_1, \ldots, r_n, p_1: p_1, \ldots, p_k: p_k);$ |
4329 \} | 4342 \} |
4330 \end{dartCode} | 4343 \end{dartCode} |
4331 | 4344 |
4332 if $f$ is an anonymous constructor that has required parameters $r_1, \ldots, r_ n$, and named parameters $p_1, \ldots, p_k$ with defaults $d_1, \ldots, d_k$. | 4345 if $f$ is an anonymous constructor that has required parameters $r_1, \ldots, r_ n$, and named parameters $p_1, \ldots, p_k$ with defaults $d_1, \ldots, d_k$. |
4333 \item | 4346 \item |
4334 \begin{dartCode} | 4347 \begin{dartCode} |
4335 $(r_1, \ldots, r_n, [p_1 = d_1, \ldots , p_k = d_k])$\{ | 4348 $(r_1, \ldots, r_n, [p_1 = d_1, \ldots , p_k = d_k])$\{ |
4336 \RETURN{} \NEW{} $T(r_1, \ldots, r_n, p_1, \ldots, p_k)$; | 4349 \RETURN{} \NEW{} $T(r_1, \ldots, r_n, p_1, \ldots, p_k)$; |
4337 \} | 4350 \} |
4338 \end{dartCode} | 4351 \end{dartCode} |
4339 | 4352 |
4340 if $f$ is an anonymous constructor that has required parameters $r_1, \ldots, r_ n$, and optional positional parameters $p_1, \ldots, p_k$ with defaults $d_1, \l dots, d_k$. | 4353 if $f$ is an anonymous constructor that has required parameters $r_1, \ldots, r_ n$, and optional positional parameters $p_1, \ldots, p_k$ with defaults $d_1, \l dots, d_k$. |
4341 \end{itemize} | 4354 \end{itemize} |
4342 | 4355 |
4343 \LMHash{} | 4356 \LMHash{} |
4344 Except that iff \code{identical($T_1, T_2$)} then \cd{\NEW{} $T_1\#$ == \NEW{ } $T_2\#$}. | 4357 Except that iff \code{identical($T_1, T_2$)} then \cd{\NEW{} $T_1\#$ == \NEW{ } $T_2\#$}. |
4345 | 4358 |
4346 | 4359 |
4347 \subsubsection{Super Closurization} | 4360 \subsubsection{Super Closurization} |
4348 \LMLabel{superClosurization} | 4361 \LMLabel{superClosurization} |
4349 | 4362 |
4350 \LMHash{} | 4363 \LMHash{} |
4351 The {\em closurization of method $f$ with respect to superclass $S$} is defined to be equivalent to: | 4364 The {\em closurization of method $f$ with respect to superclass $S$} is defined to be equivalent to: |
4352 | 4365 |
4353 \LMHash{} | 4366 \LMHash{} |
4354 \begin{itemize} | 4367 \begin{itemize} |
4355 \item $(a) \{\RETURN{}$ \SUPER{} $op$ $a;$\} if $f$ is named $op$ and $op$ is on e of \code{$<$, $>$, $<$=, $>$=, ==, -, +, /, \~{}/, *, \%, $|$, \^{}, \&, $<< $, $>>$}. | 4368 \item $(a) \{\RETURN{}$ \SUPER{} $op$ $a;$\} if $f$ is named $op$ and $op$ is on e of \code{$<$, $>$, $<$=, $>$=, ==, -, +, /, \~{}/, *, \%, $|$, \^{}, \&, $<< $, $>>$}. |
4356 \item $() \{\RETURN{}$ \~{}\SUPER;\} if $f$ is named \~{}. | 4369 \item $() \{\RETURN{}$ \~{}\SUPER;\} if $f$ is named \~{}. |
4357 \item $(a) \{\RETURN{}$ $\SUPER[a];$\} if $f$ is named $[]$. | 4370 \item $(a) \{\RETURN{}$ $\SUPER[a];$\} if $f$ is named $[]$. |
4358 \item $(a, b) \{\RETURN{}$ $\SUPER[a] = b;$\} if $f$ is named $[]=$. | 4371 \item $(a, b) \{\RETURN{}$ $\SUPER[a] = b;$\} if $f$ is named $[]=$. |
4359 \item | 4372 \item |
4360 \begin{dartCode} | 4373 \begin{dartCode} |
4361 $(r_1, \ldots, r_n, \{p_1 : d_1, \ldots , p_k : d_k\})$ \{ | 4374 $(r_1, \ldots, r_n, \{p_1 : d_1, \ldots , p_k : d_k\})$ \{ |
4362 \RETURN{} \SUPER$.m(r_1, \ldots, r_n, p_1: p_1, \ldots, p_k: p_k);$ | 4375 \RETURN{} \SUPER$.m(r_1, \ldots, r_n, p_1: p_1, \ldots, p_k: p_k);$ |
4363 \} | 4376 \} |
4364 \end{dartCode} | 4377 \end{dartCode} |
4365 if $f$ is named $m$ and has required parameters $r_1, \ldots, r_n$, and named pa rameters $p_1, \ldots, p_k$ with defaults $d_1, \ldots, d_k$. | 4378 if $f$ is named $m$ and has required parameters $r_1, \ldots, r_n$, and named pa rameters $p_1, \ldots, p_k$ with defaults $d_1, \ldots, d_k$. |
4366 \item | 4379 \item |
4367 \begin{dartCode} | 4380 \begin{dartCode} |
4368 $(r_1, \ldots, r_n, [p_1 = d_1, \ldots , p_k = d_k])$\{ | 4381 $(r_1, \ldots, r_n, [p_1 = d_1, \ldots , p_k = d_k])$\{ |
4369 \RETURN{} \SUPER$.m(r_1, \ldots, r_n, p_1, \ldots, p_k)$; | 4382 \RETURN{} \SUPER$.m(r_1, \ldots, r_n, p_1, \ldots, p_k)$; |
4370 \} | 4383 \} |
4371 \end{dartCode} | 4384 \end{dartCode} |
4372 | 4385 |
4373 if $f$ is named $m$ and has required parameters $r_1, \ldots, r_n$, and optional positional parameters $p_1, \ldots, p_k$ with defaults $d_1, \ldots, d_k$. | 4386 if $f$ is named $m$ and has required parameters $r_1, \ldots, r_n$, and optional positional parameters $p_1, \ldots, p_k$ with defaults $d_1, \ldots, d_k$. |
4374 \end{itemize} | 4387 \end{itemize} |
4375 | 4388 |
4376 \LMHash{} | 4389 \LMHash{} |
(...skipping 19 matching lines...) Expand all Loading... | |
4396 compoundAssignmentOperator | 4409 compoundAssignmentOperator |
4397 . | 4410 . |
4398 \end{grammar} | 4411 \end{grammar} |
4399 | 4412 |
4400 \LMHash{} | 4413 \LMHash{} |
4401 Evaluation of an assignment $a$ of the form $v$ \code{=} $e$ proceeds as follows : | 4414 Evaluation of an assignment $a$ of the form $v$ \code{=} $e$ proceeds as follows : |
4402 | 4415 |
4403 | 4416 |
4404 %If there is neither a local variable declaration with name $v$ nor a setter dec laration with name $v=$ in the lexical scope enclosing $a$, then: | 4417 %If there is neither a local variable declaration with name $v$ nor a setter dec laration with name $v=$ in the lexical scope enclosing $a$, then: |
4405 %\begin{itemize} | 4418 %\begin{itemize} |
4406 % \item If $a$ occurs inside a top level or static function (be it function, me thod, getter, or setter) or variable initializer, evaluation of $a$ causes $e$ to be evaluated, after which a \code{NoSuchMethodError} is thrown. | 4419 % \item If $a$ occurs inside a top level or static function (be it function, me thod, getter, or setter) or variable initializer, evaluation of $a$ causes $e$ to be evaluated, after which a \code{NoSuchMethodError} is thrown. |
4407 % \item Otherwise, the assignment is equivalent to the assignment \code{ \THIS{} .$v$ = $e$}. | 4420 % \item Otherwise, the assignment is equivalent to the assignment \code{ \THIS{} .$v$ = $e$}. |
4408 % \end{itemize} | 4421 % \end{itemize} |
4409 | 4422 |
4410 %Otherwise | 4423 %Otherwise |
4411 | 4424 |
4412 \LMHash{} | 4425 \LMHash{} |
4413 Let $d$ be the innermost declaration whose name is $v$ or $v=$, if it exists. | 4426 Let $d$ be the innermost declaration whose name is $v$ or $v=$, if it exists. |
4414 It is a compile-time error if $d$ denotes a prefix object. | 4427 It is a compile-time error if $d$ denotes a prefix object. |
4415 | 4428 |
4416 \LMHash{} | 4429 \LMHash{} |
4417 If $d$ is the declaration of a local variable, the expression $e$ is evaluated t o an object $o$. Then, the variable $v$ is bound to $o$ unless $v$ is \FINAL{} o r \CONST{}, in which case a dynamic error occurs. | 4430 If $d$ is the declaration of a local variable, the expression $e$ is evaluated t o an object $o$. Then, the variable $v$ is bound to $o$ unless $v$ is \FINAL{} o r \CONST{}, in which case a dynamic error occurs. |
4418 If no error occurs, the value of the assignment expression is $o$. | 4431 If no error occurs, the value of the assignment expression is $o$. |
4419 | 4432 |
4420 % add local functions per bug 23218 | 4433 % add local functions per bug 23218 |
4421 | 4434 |
4422 \LMHash{} | 4435 \LMHash{} |
4423 If $d$ is the declaration of a library variable, top level getter or top level s etter, the expression $e$ is evaluated to an object $o$. Then the setter $v=$ is invoked with its formal parameter bound to $o$. The value of the assignment exp ression is $o$. | 4436 If $d$ is the declaration of a library variable, top level getter or top level s etter, the expression $e$ is evaluated to an object $o$. Then the setter $v=$ is invoked with its formal parameter bound to $o$. The value of the assignment exp ression is $o$. |
4424 | 4437 |
4425 \LMHash{} | 4438 \LMHash{} |
4426 Otherwise, if $d$ is the declaration of a static variable, static getter or stat ic setter in class $C$, then the assignment is equivalent to the assignment \cod e{$C.v$ = $e$}. | 4439 Otherwise, if $d$ is the declaration of a static variable, static getter or stat ic setter in class $C$, then the assignment is equivalent to the assignment \cod e{$C.v$ = $e$}. |
4427 | 4440 |
4428 \LMHash{} | 4441 \LMHash{} |
4429 Otherwise, If $a$ occurs inside a top level or static function (be it function, method, getter, or setter) or variable initializer, evaluation of $a$ causes $ e$ to be evaluated, after which a \code{NoSuchMethodError} is thrown. | 4442 Otherwise, If $a$ occurs inside a top level or static function (be it function, method, getter, or setter) or variable initializer, evaluation of $a$ causes $ e$ to be evaluated, after which a \code{NoSuchMethodError} is thrown. |
4430 | 4443 |
4431 \LMHash{} | 4444 \LMHash{} |
4432 Otherwise, the assignment is equivalent to the assignment \code{ \THIS{}.$v$ = $ e$}. | 4445 Otherwise, the assignment is equivalent to the assignment \code{ \THIS{}.$v$ = $ e$}. |
4433 | 4446 |
4434 \LMHash{} | 4447 \LMHash{} |
4435 In checked mode, it is a dynamic type error if $o$ is not \NULL{} and the interf ace of the class of $o$ is not a subtype of the actual type (\ref{actualTypeOfAD eclaration}) of $v$. | 4448 In checked mode, it is a dynamic type error if $o$ is not \NULL{} and the interf ace of the class of $o$ is not a subtype of the actual type (\ref{actualTypeOfAD eclaration}) of $v$. |
4436 | 4449 |
4437 \LMHash{} | 4450 \LMHash{} |
4438 It is a static type warning if the static type of $e$ may not be assigned to the static type of $v$. The static type of the expression $v$ \code{=} $e$ is the s tatic type of $e$. | 4451 It is a static type warning if the static type of $e$ may not be assigned to the static type of $v$. The static type of the expression $v$ \code{=} $e$ is the s tatic type of $e$. |
4439 | 4452 |
4440 \LMHash{} | 4453 \LMHash{} |
4441 Evaluation of an assignment $a$ of the form $e_1?.v$ \code{=} $e_2$ is equivalen t to the evaluation of the expression $((x) => x == \NULL? \NULL: x.v = e_2)(e_1 )$ | 4454 Evaluation of an assignment $a$ of the form $e_1?.v$ \code{=} $e_2$ is equivalen t to the evaluation of the expression $((x) => x == \NULL? \NULL: x.v = e_2)(e_1 )$ |
4442 unless $e_1$ is a type literal, in which case it is equivalent to $e_1.v$ \cod e{=} $e_2$. | 4455 unless $e_1$ is a type literal, in which case it is equivalent to $e_1.v$ \cod e{=} $e_2$. |
4443 . The static type of $a$ is the static type of $e_2$. Let $T$ be the static type of $e_1$ and let $y$ be a fresh variable of type $T$. Exactly the same static w arnings that would be caused by $y.v = e_2$ are also generated in the case of $e _1?.v$ \code{=} $e_2$. | 4456 . The static type of $a$ is the static type of $e_2$. Let $T$ be the static type of $e_1$ and let $y$ be a fresh variable of type $T$. Exactly the same static w arnings that would be caused by $y.v = e_2$ are also generated in the case of $e _1?.v$ \code{=} $e_2$. |
4444 | 4457 |
4445 \LMHash{} | 4458 \LMHash{} |
4446 Evaluation of an assignment of the form $e_1.v$ \code{=} $e_2$ proceeds as follo ws: | 4459 Evaluation of an assignment of the form $e_1.v$ \code{=} $e_2$ proceeds as follo ws: |
4447 | 4460 |
4448 \LMHash{} | 4461 \LMHash{} |
4449 The expression $e_1$ is evaluated to an object $o_1$. Then, the expression $e_2$ is evaluated to an object $o_2$. Then, the setter $v=$ is looked up (\ref{gett erAndSetterLookup}) in $o_1$ with respect to the current library. If $o_1$ is a n instance of \code{Type} but $e_1$ is not a constant type literal, then if $v=$ is a setter that forwards (\ref{functionDeclarations}) to a static setter, sett er lookup fails. Otherwise, the body of $v=$ is executed with its formal parame ter bound to $o_2$ and \THIS{} bound to $o_1$. | 4462 The expression $e_1$ is evaluated to an object $o_1$. Then, the expression $e_2$ is evaluated to an object $o_2$. Then, the setter $v=$ is looked up (\ref{gett erAndSetterLookup}) in $o_1$ with respect to the current library. If $o_1$ is a n instance of \code{Type} but $e_1$ is not a constant type literal, then if $v=$ is a setter that forwards (\ref{functionDeclarations}) to a static setter, sett er lookup fails. Otherwise, the body of $v=$ is executed with its formal parame ter bound to $o_2$ and \THIS{} bound to $o_1$. |
4450 | 4463 |
4451 \LMHash{} | 4464 \LMHash{} |
4452 If the setter lookup has failed, then a new instance $im$ of the predefined cla ss \code{Invocation} is created, such that : | 4465 If the setter lookup has failed, then a new instance $im$ of the predefined cla ss \code{Invocation} is created, such that : |
4453 \begin{itemize} | 4466 \begin{itemize} |
4454 \item \code{im.isSetter} evaluates to \code{\TRUE{}}. | 4467 \item \code{im.isSetter} evaluates to \code{\TRUE{}}. |
4455 \item \code{im.memberName} evaluates to the symbol \code{v=}. | 4468 \item \code{im.memberName} evaluates to the symbol \code{v=}. |
4456 \item \code{im.positionalArguments} evaluates to an immutable list with the same values as \code{[$o_2$]}. | 4469 \item \code{im.positionalArguments} evaluates to an immutable list with the same values as \code{[$o_2$]}. |
4457 \item \code{im.namedArguments} evaluates to the value of \code{\CONST{} \{\}}. | 4470 \item \code{im.namedArguments} evaluates to the value of \code{\CONST{} \{\}}. |
4458 \end{itemize} | 4471 \end{itemize} |
4459 | 4472 |
4460 \LMHash{} | 4473 \LMHash{} |
4461 Then the method \code{noSuchMethod()} is looked up in $o_1$ and invoked with ar gument $im$. | 4474 Then the method \code{noSuchMethod()} is looked up in $o_1$ and invoked with ar gument $im$. |
4462 However, if the implementation found cannot be invoked with a single positional argument, the implementation of \code{noSuchMethod()} in class \code{Object} is invoked on $o_1$ with argument $im'$, where $im'$ is an instance of \code{Invoc ation} such that : | 4475 However, if the implementation found cannot be invoked with a single positional argument, the implementation of \code{noSuchMethod()} in class \code{Object} is invoked on $o_1$ with argument $im'$, where $im'$ is an instance of \code{Invoc ation} such that : |
4463 \begin{itemize} | 4476 \begin{itemize} |
4464 \item \code{im'.isMethod} evaluates to \code{\TRUE{}}. | 4477 \item \code{im'.isMethod} evaluates to \code{\TRUE{}}. |
4465 \item \code{im'.memberName} evaluates to \code{\#noSuchMethod}. | 4478 \item \code{im'.memberName} evaluates to \code{\#noSuchMethod}. |
4466 \item \code{im'.positionalArguments} evaluates to an immutable list whose sole e lement is $im$. | 4479 \item \code{im'.positionalArguments} evaluates to an immutable list whose sole e lement is $im$. |
4467 \item \code{im'.namedArguments} evaluates to the value of \code{\CONST{} \{\}}. | 4480 \item \code{im'.namedArguments} evaluates to the value of \code{\CONST{} \{\}}. |
4468 \end{itemize} | 4481 \end{itemize} |
4469 | 4482 |
4470 \LMHash{} | 4483 \LMHash{} |
4471 The value of the assignment expression is $o_2$ irrespective of whether setter l ookup has failed or succeeded. | 4484 The value of the assignment expression is $o_2$ irrespective of whether setter l ookup has failed or succeeded. |
4472 | 4485 |
4473 \LMHash{} | 4486 \LMHash{} |
4474 In checked mode, it is a dynamic type error if $o_2$ is not \NULL{} and the inte rface of the class of $o_2$ is not a subtype of the actual type of $e_1.v$. | 4487 In checked mode, it is a dynamic type error if $o_2$ is not \NULL{} and the inte rface of the class of $o_2$ is not a subtype of the actual type of $e_1.v$. |
4475 | 4488 |
4476 \LMHash{} | 4489 \LMHash{} |
4477 Let $T$ be the static type of $e_1$. It is a static type warning if $T$ does not have an accessible instance setter named $v=$ unless either: | 4490 Let $T$ be the static type of $e_1$. It is a static type warning if $T$ does not have an accessible instance setter named $v=$ unless either: |
4478 \begin{itemize} | 4491 \begin{itemize} |
4479 \item $T$ or a superinterface of $T$ is annotated with an annotation denoting a constant identical to the constant \code{@proxy} defined in \code{dart:core}. Or | 4492 \item $T$ or a superinterface of $T$ is annotated with an annotation denoting a constant identical to the constant \code{@proxy} defined in \code{dart:core}. Or |
4480 \item $T$ is \code{Type}, $e_1$ is a constant type literal and the class corresp onding to $e_1$ has a static setter named $v=$. | 4493 \item $T$ is \code{Type}, $e_1$ is a constant type literal and the class corresp onding to $e_1$ has a static setter named $v=$. |
4481 \end{itemize} | 4494 \end{itemize} |
4482 | 4495 |
4483 | 4496 |
4484 | 4497 |
4485 \LMHash{} | 4498 \LMHash{} |
4486 It is a static type warning if the static type of $e_2$ may not be assigned to t he static type of the formal parameter of the setter $v=$. The static type of the expression $e_1.v$ \code{=} $e_2$ is the static type of $e_2$. | 4499 It is a static type warning if the static type of $e_2$ may not be assigned to t he static type of the formal parameter of the setter $v=$. The static type of the expression $e_1.v$ \code{=} $e_2$ is the static type of $e_2$. |
4487 | 4500 |
4488 \LMHash{} | 4501 \LMHash{} |
4489 Evaluation of an assignment of the form $\SUPER.v$ \code{=} $e$ proceeds as foll ows: | 4502 Evaluation of an assignment of the form $\SUPER.v$ \code{=} $e$ proceeds as foll ows: |
4490 | 4503 |
4491 \LMHash{} | 4504 \LMHash{} |
4492 Let $g$ be the method currently executing, and let $C$ be the class in which $g$ was looked up. Let $S_{dynamic}$ be the superclass of $C$. | 4505 Let $g$ be the method currently executing, and let $C$ be the class in which $g$ was looked up. Let $S_{dynamic}$ be the superclass of $C$. |
4493 The expression $e$ is evaluated to an object $o$. Then, the setter $v=$ is look ed up (\ref{getterAndSetterLookup}) in $S_{dynamic}$ with respect to the current library. The body of $v=$ is executed with its formal parameter bound to $o$ and \THIS{} bound to \THIS{}. | 4506 The expression $e$ is evaluated to an object $o$. Then, the setter $v=$ is look ed up (\ref{getterAndSetterLookup}) in $S_{dynamic}$ with respect to the current library. The body of $v=$ is executed with its formal parameter bound to $o$ and \THIS{} bound to \THIS{}. |
4494 | 4507 |
4495 \LMHash{} | 4508 \LMHash{} |
4496 If the setter lookup has failed, then a new instance $im$ of the predefined cla ss \code{Invocation} is created, such that : | 4509 If the setter lookup has failed, then a new instance $im$ of the predefined cla ss \code{Invocation} is created, such that : |
4497 \begin{itemize} | 4510 \begin{itemize} |
4498 \item \code{im.isSetter} evaluates to \code{\TRUE{}}. | 4511 \item \code{im.isSetter} evaluates to \code{\TRUE{}}. |
4499 \item \code{im.memberName} evaluates to the symbol \code{v=}. | 4512 \item \code{im.memberName} evaluates to the symbol \code{v=}. |
4500 \item \code{im.positionalArguments} evaluates to an immutable list with the same values as \code{[$o$]}. | 4513 \item \code{im.positionalArguments} evaluates to an immutable list with the same values as \code{[$o$]}. |
4501 \item \code{im.namedArguments} evaluates to the value of \code{\CONST{} \{\}}. | 4514 \item \code{im.namedArguments} evaluates to the value of \code{\CONST{} \{\}}. |
4502 \end{itemize} | 4515 \end{itemize} |
4503 | 4516 |
4504 \LMHash{} | 4517 \LMHash{} |
4505 Then the method \code{noSuchMethod()} is looked up in $S_{dynamic}$ and invoked with argument $im$. | 4518 Then the method \code{noSuchMethod()} is looked up in $S_{dynamic}$ and invoked with argument $im$. |
4506 However, if the implementation found cannot be invoked with a single positional argument, the implementation of \code{noSuchMethod()} in class \code{Object} is invoked on \THIS{} with argument $im'$, where $im'$ is an instance of \code{Inv ocation} such that : | 4519 However, if the implementation found cannot be invoked with a single positional argument, the implementation of \code{noSuchMethod()} in class \code{Object} is invoked on \THIS{} with argument $im'$, where $im'$ is an instance of \code{Inv ocation} such that : |
4507 \begin{itemize} | 4520 \begin{itemize} |
4508 \item \code{im'.isMethod} evaluates to \code{\TRUE{}}. | 4521 \item \code{im'.isMethod} evaluates to \code{\TRUE{}}. |
4509 \item \code{im'.memberName} evaluates to \code{\#noSuchMethod}. | 4522 \item \code{im'.memberName} evaluates to \code{\#noSuchMethod}. |
4510 \item \code{im'.positionalArguments} evaluates to an immutable list whose sole e lement is $im$. | 4523 \item \code{im'.positionalArguments} evaluates to an immutable list whose sole e lement is $im$. |
4511 \item \code{im'.namedArguments} evaluates to the value of \code{\CONST{} \{\}}. | 4524 \item \code{im'.namedArguments} evaluates to the value of \code{\CONST{} \{\}}. |
4512 \end{itemize} | 4525 \end{itemize} |
4513 | 4526 |
4514 \LMHash{} | 4527 \LMHash{} |
4515 The value of the assignment expression is $o$ irrespective of whether setter loo kup has failed or succeeded. | 4528 The value of the assignment expression is $o$ irrespective of whether setter loo kup has failed or succeeded. |
4516 | 4529 |
4517 \LMHash{} | 4530 \LMHash{} |
4518 In checked mode, it is a dynamic type error if $o$ is not \NULL{} and the interf ace of the class of $o$ is not a subtype of the actual type of $S.v$. | 4531 In checked mode, it is a dynamic type error if $o$ is not \NULL{} and the interf ace of the class of $o$ is not a subtype of the actual type of $S.v$. |
4519 | 4532 |
4520 \LMHash{} | 4533 \LMHash{} |
4521 Let $S_{static}$ be the superclass of the immediately enclosing class. It is a s tatic type warning if $S_{static}$ does not have an accessible instance setter n amed $v=$ unless $S_{static}$ or a superinterface of $S_{static}$ is annotated w ith an annotation denoting a constant identical to the constant \code{@proxy} de fined in \code{dart:core}. | 4534 Let $S_{static}$ be the superclass of the immediately enclosing class. It is a s tatic type warning if $S_{static}$ does not have an accessible instance setter n amed $v=$ unless $S_{static}$ or a superinterface of $S_{static}$ is annotated w ith an annotation denoting a constant identical to the constant \code{@proxy} de fined in \code{dart:core}. |
4522 | 4535 |
4523 \LMHash{} | 4536 \LMHash{} |
4524 It is a static type warning if the static type of $e$ may not be assigned to the static type of the formal parameter of the setter $v=$. The static type of th e expression $\SUPER.v$ \code{=} $e$ is the static type of $e$. | 4537 It is a static type warning if the static type of $e$ may not be assigned to the static type of the formal parameter of the setter $v=$. The static type of th e expression $\SUPER.v$ \code{=} $e$ is the static type of $e$. |
4525 | 4538 |
4526 | 4539 |
4527 | 4540 |
4528 | 4541 |
4529 | 4542 |
4530 | 4543 |
4531 \LMHash{} | 4544 \LMHash{} |
(...skipping 10 matching lines...) Expand all Loading... | |
4542 | 4555 |
4543 \LMHash{} | 4556 \LMHash{} |
4544 It is a compile-time error to invoke any of the setters of class \cd{Object} on a prefix object (\ref{imports}) or on a constant type literal that is immediate ly followed by the token `.'. | 4557 It is a compile-time error to invoke any of the setters of class \cd{Object} on a prefix object (\ref{imports}) or on a constant type literal that is immediate ly followed by the token `.'. |
4545 | 4558 |
4546 | 4559 |
4547 | 4560 |
4548 \subsubsection{Compound Assignment} | 4561 \subsubsection{Compound Assignment} |
4549 \LMLabel{compoundAssignment} | 4562 \LMLabel{compoundAssignment} |
4550 | 4563 |
4551 \LMHash{} | 4564 \LMHash{} |
4552 Evaluation of a compound assignment of the form $v$ {\em ??=} $e$ is equivalent to the evaluation of the expression $((x) => x == \NULL{}$ ? $v=e : x)(v)$ whe re $x$ is a fresh variable that is not used in $e$. | 4565 Evaluation of a compound assignment of the form $v$ {\em ??=} $e$ is equivalent to the evaluation of the expression $((x) => x == \NULL{}$ ? $v=e : x)(v)$ whe re $x$ is a fresh variable that is not used in $e$. |
4553 | 4566 |
4554 \LMHash{} | 4567 \LMHash{} |
4555 Evaluation of a compound assignment of the form $C.v$ {\em ??=} $e$, where $C$ i s a type literal, is equivalent to the evaluation of the expression $((x) => x == \NULL{}$? $C.v=e: x)(C.v)$ where $x$ is a fresh variable that is not used in $e$. | 4568 Evaluation of a compound assignment of the form $C.v$ {\em ??=} $e$, where $C$ i s a type literal, is equivalent to the evaluation of the expression $((x) => x == \NULL{}$? $C.v=e: x)(C.v)$ where $x$ is a fresh variable that is not used in $e$. |
4556 | 4569 |
4557 \commentary { | 4570 \commentary { |
4558 The two rules above also apply when the variable v or the type C is prefixed. | 4571 The two rules above also apply when the variable v or the type C is prefixed. |
4559 } | 4572 } |
4560 | 4573 |
4561 \LMHash{} | 4574 \LMHash{} |
4562 Evaluation of a compound assignment of the form $e_1.v$ {\em ??=} $e_2$ is equiv alent to the evaluation of the expression $((x) =>((y) => y == \NULL{}$ ? $ x.v = e_2: y)(x.v))(e_1)$ where $x$ and $y$ are distinct fresh variables that are n ot used in $e_2$. | 4575 Evaluation of a compound assignment of the form $e_1.v$ {\em ??=} $e_2$ is equiv alent to the evaluation of the expression $((x) =>((y) => y == \NULL{}$ ? $ x.v = e_2: y)(x.v))(e_1)$ where $x$ and $y$ are distinct fresh variables that are n ot used in $e_2$. |
4563 | 4576 |
4564 \LMHash{} | 4577 \LMHash{} |
4565 Evaluation of a compound assignment of the form $e_1[e_2]$ {\em ??=} $e_3$ is equivalent to the evaluation of the expression | 4578 Evaluation of a compound assignment of the form $e_1[e_2]$ {\em ??=} $e_3$ is equivalent to the evaluation of the expression |
4566 $((a, i) => ((x) => x == \NULL{}$ ? $a[i] = e_3: x)(a[i]))(e_1, e_2)$ where $x$ , $a$ and $i$ are distinct fresh variables that are not used in $e_3$. | 4579 $((a, i) => ((x) => x == \NULL{}$ ? $a[i] = e_3: x)(a[i]))(e_1, e_2)$ where $x$ , $a$ and $i$ are distinct fresh variables that are not used in $e_3$. |
4567 | 4580 |
4568 \LMHash{} | 4581 \LMHash{} |
4569 Evaluation of a compound assignment of the form $\SUPER.v$ {\em ??=} $e$ is equ ivalent to the evaluation of the expression $((x) => x == \NULL{}$ ? $\SUPER.v = e: x)(\SUPER.v)$ where $x$ is a fresh variable that is not used in $e$. | 4582 Evaluation of a compound assignment of the form $\SUPER.v$ {\em ??=} $e$ is equ ivalent to the evaluation of the expression $((x) => x == \NULL{}$ ? $\SUPER.v = e: x)(\SUPER.v)$ where $x$ is a fresh variable that is not used in $e$. |
4570 | 4583 |
4571 \LMHash{} | 4584 \LMHash{} |
4572 Evaluation of a compound assignment of the form $e_1?.v$ {\em ??=} $e_2$ is equ ivalent to the evaluation of the expression \code{((x) $=>$ x == \NULL{} ? \NUL L: $x.v ??= e_2$)($e_1$)} where $x$ is a variable that is not used in $e_2$. | 4585 Evaluation of a compound assignment of the form $e_1?.v$ {\em ??=} $e_2$ is equ ivalent to the evaluation of the expression \code{((x) $=>$ x == \NULL{} ? \NUL L: $x.v ??= e_2$)($e_1$)} where $x$ is a variable that is not used in $e_2$. |
4573 % But what about C?.v ??= e | 4586 % But what about C?.v ??= e |
4574 | 4587 |
4575 \LMHash{} | 4588 \LMHash{} |
4576 A compound assignment of the form $C?.v$ {\em ??=} $e_2$ is equivalent to the e xpression $C.v$ {\em ??=} $e$. | 4589 A compound assignment of the form $C?.v$ {\em ??=} $e_2$ is equivalent to the e xpression $C.v$ {\em ??=} $e$. |
4577 | 4590 |
4578 \LMHash{} | 4591 \LMHash{} |
4579 The static type of a compound assignment of the form $v$ {\em ??=} $e$ is the le ast upper bound of the static type of $v$ and the static type of $e$. Exactly t he same static warnings that would be caused by $v = e$ are also generated in th e case of $v$ {\em ??=} $e$. | 4592 The static type of a compound assignment of the form $v$ {\em ??=} $e$ is the le ast upper bound of the static type of $v$ and the static type of $e$. Exactly t he same static warnings that would be caused by $v = e$ are also generated in th e case of $v$ {\em ??=} $e$. |
4580 | 4593 |
4581 | 4594 |
4582 \LMHash{} | 4595 \LMHash{} |
4583 The static type of a compound assignment of the form $C.v$ {\em ??=} $e$ is th e least upper bound of the static type of $C.v$ and the static type of $e$. Exa ctly the same static warnings that would be caused by $C.v = e$ are also generat ed in the case of $C.v$ {\em ??=} $e$. | 4596 The static type of a compound assignment of the form $C.v$ {\em ??=} $e$ is th e least upper bound of the static type of $C.v$ and the static type of $e$. Exa ctly the same static warnings that would be caused by $C.v = e$ are also generat ed in the case of $C.v$ {\em ??=} $e$. |
4584 | 4597 |
4585 \LMHash{} | 4598 \LMHash{} |
4586 The static type of a compound assignment of the form $e_1.v$ {\em ??=} $e_2$ is the least upper bound of the static type of $e_1.v$ and the static type of $e_2 $. Let $T$ be the static type of $e_1$ and let $z$ be a fresh variable of type $ T$. Exactly the same static warnings that would be caused by $z.v = e_2$ are als o generated in the case of $e_1.v$ {\em ??=} $e_2$. | 4599 The static type of a compound assignment of the form $e_1.v$ {\em ??=} $e_2$ is the least upper bound of the static type of $e_1.v$ and the static type of $e_2 $. Let $T$ be the static type of $e_1$ and let $z$ be a fresh variable of type $ T$. Exactly the same static warnings that would be caused by $z.v = e_2$ are als o generated in the case of $e_1.v$ {\em ??=} $e_2$. |
4587 | 4600 |
4588 \LMHash{} | 4601 \LMHash{} |
4589 The static type of a compound assignment of the form $e_1[e_2]$ {\em ??=} $e_3$ is the least upper bound of the static type of $e_1[e_2]$ and the static type of $e_3$. Exactly the same static warnings that would be caused by $e_1[e_2] = e _3$ are also generated in the case of $e_1[e_2]$ {\em ??=} $e_3$. | 4602 The static type of a compound assignment of the form $e_1[e_2]$ {\em ??=} $e_3$ is the least upper bound of the static type of $e_1[e_2]$ and the static type of $e_3$. Exactly the same static warnings that would be caused by $e_1[e_2] = e _3$ are also generated in the case of $e_1[e_2]$ {\em ??=} $e_3$. |
4590 | 4603 |
4591 \LMHash{} | 4604 \LMHash{} |
4592 The static type of a compound assignment of the form $\SUPER.v$ {\em ??=} $e$ is the least upper bound of the static type of $\SUPER.v$ and the static type of $e$. Exactly the same static warnings that would be caused by $\SUPER.v = e$ ar e also generated in the case of $\SUPER.v$ {\em ??=} $e$. | 4605 The static type of a compound assignment of the form $\SUPER.v$ {\em ??=} $e$ is the least upper bound of the static type of $\SUPER.v$ and the static type of $e$. Exactly the same static warnings that would be caused by $\SUPER.v = e$ ar e also generated in the case of $\SUPER.v$ {\em ??=} $e$. |
4593 | 4606 |
4594 \LMHash{} | 4607 \LMHash{} |
4595 For any other valid operator $op$, a compound assignment of the form $v$ $op\cod e{=} e$ is equivalent to $v \code{=} v$ $op$ $e$. A compound assignment of the f orm $C.v$ $op \code{=} e$ is equivalent to $C.v \code{=} C.v$ $op$ $e$. A compou nd assignment of the form $e_1.v$ $op = e_2$ is equivalent to \code{((x) $=>$ x. v = x.v $op$ $e_2$)($e_1$)} where $x$ is a variable that is not used in $e_2$. A compound assignment of the form $e_1[e_2]$ $op\code{=} e_3$ is equivalent to | 4608 For any other valid operator $op$, a compound assignment of the form $v$ $op\cod e{=} e$ is equivalent to $v \code{=} v$ $op$ $e$. A compound assignment of the f orm $C.v$ $op \code{=} e$ is equivalent to $C.v \code{=} C.v$ $op$ $e$. A compou nd assignment of the form $e_1.v$ $op = e_2$ is equivalent to \code{((x) $=>$ x. v = x.v $op$ $e_2$)($e_1$)} where $x$ is a variable that is not used in $e_2$. A compound assignment of the form $e_1[e_2]$ $op\code{=} e_3$ is equivalent to |
4596 \code{((a, i) $=>$ a[i] = a[i] $op$ $e_3$)($e_1, e_2$)} where $a$ and $i$ are a variables that are not used in $e_3$. | 4609 \code{((a, i) $=>$ a[i] = a[i] $op$ $e_3$)($e_1, e_2$)} where $a$ and $i$ are a variables that are not used in $e_3$. |
4597 | 4610 |
4598 \LMHash{} | 4611 \LMHash{} |
4599 Evaluation of a compound assignment of the form $e_1?.v$ $op = e_2$ is equivalen t to \code{((x) $=>$ x?.v = x.v $op$ $e_2$)($e_1$)} where $x$ is a variable that is not used in $e_2$. The static type of $e_1?.v$ $op = e_2$ is the static type of $e_1.v$ $op$ $e_2$. Exactly the same static warnings that would be caused by $e_1.v$ $op = e_2$ are also generated in the case of $e_1?.v$ $op = e_2$. | 4612 Evaluation of a compound assignment of the form $e_1?.v$ $op = e_2$ is equivalen t to \code{((x) $=>$ x?.v = x.v $op$ $e_2$)($e_1$)} where $x$ is a variable that is not used in $e_2$. The static type of $e_1?.v$ $op = e_2$ is the static type of $e_1.v$ $op$ $e_2$. Exactly the same static warnings that would be caused by $e_1.v$ $op = e_2$ are also generated in the case of $e_1?.v$ $op = e_2$. |
4600 | 4613 |
4601 \LMHash{} | 4614 \LMHash{} |
4602 A compound assignment of the form $C?.v$ $op = e_2$ is equivalent to the express ion | 4615 A compound assignment of the form $C?.v$ $op = e_2$ is equivalent to the express ion |
4603 $C.v$ $op = e_2$. | 4616 $C.v$ $op = e_2$. |
4604 | 4617 |
4605 \begin{grammar} | 4618 \begin{grammar} |
4606 {\bf compoundAssignmentOperator:}`*='; | 4619 {\bf compoundAssignmentOperator:}`*='; |
4607 `/='; | 4620 `/='; |
4608 `\~{}/='; | 4621 `\~{}/='; |
4609 `\%='; | 4622 `\%='; |
4610 `+='; | 4623 `+='; |
4611 `-='; | 4624 `-='; |
4612 `{\escapegrammar \lt \lt}='; | 4625 `{\escapegrammar \lt \lt}='; |
4613 `{\escapegrammar \gt \gt}='; | 4626 `{\escapegrammar \gt \gt}='; |
4614 `\&='; | 4627 `\&='; |
4615 `\^{}='; | 4628 `\^{}='; |
4616 `$|$='; | 4629 `$|$='; |
4617 `??='; | 4630 `??='; |
4618 . | 4631 . |
4619 \end{grammar} | 4632 \end{grammar} |
4620 | 4633 |
4621 | 4634 |
4622 \subsection{ Conditional} | 4635 \subsection{ Conditional} |
4623 \LMLabel{conditional} | 4636 \LMLabel{conditional} |
4624 | 4637 |
4625 \LMHash{} | 4638 \LMHash{} |
4626 A {\em conditional expression} evaluates one of two expressions based on a boole an condition. | 4639 A {\em conditional expression} evaluates one of two expressions based on a boole an condition. |
4627 | 4640 |
4628 \begin{grammar} | 4641 \begin{grammar} |
4629 {\bf conditionalExpression:} | 4642 {\bf conditionalExpression:} |
4630 ifNullExpression (`?' expressionWithoutCascade `{\escapegrammar :}' express ionWithoutCascade)? | 4643 ifNullExpression (`?' expressionWithoutCascade `{\escapegrammar :}' express ionWithoutCascade)? |
4631 . % the first branches could top level expressions, it seems, but certainl y NOT the second | 4644 . % the first branches could top level expressions, it seems, but certainl y NOT the second |
4632 \end{grammar} | 4645 \end{grammar} |
4633 | 4646 |
4634 \LMHash{} | 4647 \LMHash{} |
4635 Evaluation of a conditional expression $c$ of the form $e_1 ? e_2 : e_3$ proceed s as follows: | 4648 Evaluation of a conditional expression $c$ of the form $e_1 ? e_2 : e_3$ proceed s as follows: |
4636 | 4649 |
4637 \LMHash{} | 4650 \LMHash{} |
4638 First, $e_1$ is evaluated to an object $o_1$. Then, $o_1$ is subjected to bool ean conversion (\ref{booleanConversion}) producing an object $r$. If $r$ is \TR UE, then the value of $c$ is the result of evaluating the expression $e_2$. Othe rwise the value of $c$ is the result of evaluating the expression $e_3$. | 4651 First, $e_1$ is evaluated to an object $o_1$. Then, $o_1$ is subjected to bool ean conversion (\ref{booleanConversion}) producing an object $r$. If $r$ is \TR UE, then the value of $c$ is the result of evaluating the expression $e_2$. Othe rwise the value of $c$ is the result of evaluating the expression $e_3$. |
4639 | 4652 |
4640 \LMHash{} | 4653 \LMHash{} |
4641 If all of the following hold: | 4654 If all of the following hold: |
4642 \begin{itemize} | 4655 \begin{itemize} |
4643 \item $e_1$ shows that a variable $v$ has type $T$. | 4656 \item $e_1$ shows that a variable $v$ has type $T$. |
4644 \item $v$ is not potentially mutated in $e_2$ or within a closure. | 4657 \item $v$ is not potentially mutated in $e_2$ or within a closure. |
4645 \item If the variable $v$ is accessed by a closure in $e_2$ then the variable $v $ is not potentially mutated anywhere in the scope of $v$. | 4658 \item If the variable $v$ is accessed by a closure in $e_2$ then the variable $v $ is not potentially mutated anywhere in the scope of $v$. |
4646 \end{itemize} | 4659 \end{itemize} |
4647 | 4660 |
4648 then the type of $v$ is known to be $T$ in $e_2$. | 4661 then the type of $v$ is known to be $T$ in $e_2$. |
4649 | 4662 |
4650 | 4663 |
4651 \LMHash{} | 4664 \LMHash{} |
4652 It is a static type warning if the static type of $e_1$ may not be assigned to \code{bool}. The static type of $c$ is the least upper bound (\ref{leastUpperBo unds}) of the static type of $e_2$ and the static type of $e_3$. | 4665 It is a static type warning if the static type of $e_1$ may not be assigned to \code{bool}. The static type of $c$ is the least upper bound (\ref{leastUpperBo unds}) of the static type of $e_2$ and the static type of $e_3$. |
4653 | 4666 |
4654 | 4667 |
4655 \subsection{If-null Expressions} | 4668 \subsection{If-null Expressions} |
4656 \label{ifNull} | 4669 \label{ifNull} |
4657 | 4670 |
4658 \LMHash{} | 4671 \LMHash{} |
4659 An {\em if-null expression}evaluates an expression and if the result is \NULL, evaluates another. | 4672 An {\em if-null expression}evaluates an expression and if the result is \NULL, evaluates another. |
4660 | 4673 |
4661 \begin{grammar} | 4674 \begin{grammar} |
4662 {\bf ifNullExpression:} | 4675 {\bf ifNullExpression:} |
4663 logicalOrExpression (`??' logicalOrExpression)* | 4676 logicalOrExpression (`??' logicalOrExpression)* |
4664 \end{grammar} | 4677 \end{grammar} |
4665 | 4678 |
4666 \LMHash{} | 4679 \LMHash{} |
4667 Evaluation of an if-null expression $e$ of the form $e_1??e_2 $ is equivalent to the evaluation of the expression $((x) => x == \NULL? e_2: x)(e_1)$. The static type of $e$ is least upper bound (\ref{leastUpperBounds}) of the static type of $e_1$ and the static type of $e_2$. | 4680 Evaluation of an if-null expression $e$ of the form $e_1??e_2 $ is equivalent to the evaluation of the expression $((x) => x == \NULL? e_2: x)(e_1)$. The static type of $e$ is least upper bound (\ref{leastUpperBounds}) of the static type of $e_1$ and the static type of $e_2$. |
4668 | 4681 |
4669 | 4682 |
4670 \subsection{ Logical Boolean Expressions} | 4683 \subsection{ Logical Boolean Expressions} |
4671 \LMLabel{logicalBooleanExpressions} | 4684 \LMLabel{logicalBooleanExpressions} |
4672 | 4685 |
4673 \LMHash{} | 4686 \LMHash{} |
4674 The logical boolean expressions combine boolean objects using the boolean conjun ction and disjunction operators. | 4687 The logical boolean expressions combine boolean objects using the boolean conjun ction and disjunction operators. |
4675 | 4688 |
4676 \begin{grammar} | 4689 \begin{grammar} |
4677 {\bf logicalOrExpression:} | 4690 {\bf logicalOrExpression:} |
4678 logicalAndExpression (`$||$' logicalAndExpression)* | 4691 logicalAndExpression (`$||$' logicalAndExpression)* |
4679 . | 4692 . |
4680 | 4693 |
4681 | 4694 |
4682 {\bf logicalAndExpression:} | 4695 {\bf logicalAndExpression:} |
4683 equalityExpression (`\&\&' equalityExpression)* | 4696 equalityExpression (`\&\&' equalityExpression)* |
4684 % bitwiseOrExpression (`\&\&' bitwiseOrExpression)* | 4697 % bitwiseOrExpression (`\&\&' bitwiseOrExpression)* |
4685 . | 4698 . |
4686 \end{grammar} | 4699 \end{grammar} |
4687 | 4700 |
4688 \LMHash{} | 4701 \LMHash{} |
4689 A {\em logical boolean expression} is either an equality expression (\ref{equali ty}), or an invocation of a logical boolean operator on an expression $e_1$ with argument $e_2$. | 4702 A {\em logical boolean expression} is either an equality expression (\ref{equali ty}), or an invocation of a logical boolean operator on an expression $e_1$ with argument $e_2$. |
4690 | |
4691 \LMHash{} | |
4692 Evaluation of a logical boolean expression $b$ of the form $e_1 || e_2$ causes t he evaluation of $e_1$ which is then subjected to boolean conversion, yielding an object $o_1$; if $o_1$ is \TRUE, the result of evaluating $b$ is \TRUE, other wise $e_2$ is evaluated to an object $o_2$, which is then subjected to boolean c onversion (\ref{booleanConversion}) producing an object $r$, which is the value of $b$. | |
4693 | 4703 |
4694 \LMHash{} | 4704 \LMHash{} |
4695 Evaluation of a logical boolean expression $b$ of the form $e_1 \&\& e_2$ causes the evaluation of $e_1$ which is then subjected to boolean conversion, yielding an object $o_1$; if $o_1$ is not \TRUE, the result of evaluating $b$ is \FALSE , otherwise $e_2$ is evaluated to an object $o_2$, which is then subjected to bo olean conversion producing an object $r$, which is the value of $b$. | 4705 Evaluation of a logical boolean expression $b$ of the form $e_1 || e_2$ causes t he evaluation of $e_1$ which is then subjected to boolean conversion, yielding an object $o_1$; if $o_1$ is \TRUE, the result of evaluating $b$ is \TRUE, other wise $e_2$ is evaluated to an object $o_2$, which is then subjected to boolean c onversion (\ref{booleanConversion}) producing an object $r$, which is the value of $b$. |
4696 | 4706 |
4697 \LMHash{} | 4707 \LMHash{} |
4698 A logical boolean expression $b$ of the form $e_1 \&\& e_2$ shows that a variabl e $v$ has type | 4708 Evaluation of a logical boolean expression $b$ of the form $e_1 \&\& e_2$ causes the evaluation of $e_1$ which is then subjected to boolean conversion, yielding an object $o_1$; if $o_1$ is not \TRUE, the result of evaluating $b$ is \FALSE , otherwise $e_2$ is evaluated to an object $o_2$, which is then subjected to bo olean conversion producing an object $r$, which is the value of $b$. |
4709 | |
4710 \LMHash{} | |
4711 A logical boolean expression $b$ of the form $e_1 \&\& e_2$ shows that a variabl e $v$ has type | |
4699 $T$ if all of the following conditions hold: | 4712 $T$ if all of the following conditions hold: |
4700 \begin{itemize} | 4713 \begin{itemize} |
4701 \item Either $e_1$ shows that $v$ has type $T$ or $e_2$ shows that $v$ has type $T$. | 4714 \item Either $e_1$ shows that $v$ has type $T$ or $e_2$ shows that $v$ has type $T$. |
4702 \item $v$ is a local variable or formal parameter. | 4715 \item $v$ is a local variable or formal parameter. |
4703 \item The variable $v$ is not mutated in $e_2$ or within a closure. | 4716 \item The variable $v$ is not mutated in $e_2$ or within a closure. |
4704 \end{itemize} | 4717 \end{itemize} |
4705 | 4718 |
4706 \LMHash{} | 4719 \LMHash{} |
4707 Furthermore, if all of the following hold: | 4720 Furthermore, if all of the following hold: |
4708 \begin{itemize} | 4721 \begin{itemize} |
4709 \item $e_1$ shows that $v$ has type $T$. | 4722 \item $e_1$ shows that $v$ has type $T$. |
4710 \item $v$ is not mutated in either $e_1$, $e_2$ or within a closure. | 4723 \item $v$ is not mutated in either $e_1$, $e_2$ or within a closure. |
4711 \item If the variable $v$ is accessed by a closure in $e_2$ then the variable $v $ is not potentially mutated anywhere in the scope of $v$. | 4724 \item If the variable $v$ is accessed by a closure in $e_2$ then the variable $v $ is not potentially mutated anywhere in the scope of $v$. |
4712 \end{itemize} | 4725 \end{itemize} |
4713 then the type of $v$ is known to be $T$ in $e_2$. | 4726 then the type of $v$ is known to be $T$ in $e_2$. |
4714 | 4727 |
4715 \LMHash{} | 4728 \LMHash{} |
4716 It is a static warning if the static type of $e_1$ may not be assigned to \cd{bo ol} or if the static type of $e_2$ may not be assigned to \cd{bool}. The static type of a logical boolean expression is \code{bool}. | 4729 It is a static warning if the static type of $e_1$ may not be assigned to \cd{bo ol} or if the static type of $e_2$ may not be assigned to \cd{bool}. The static type of a logical boolean expression is \code{bool}. |
4717 | 4730 |
4718 | 4731 |
4719 \subsection{ Equality} | 4732 \subsection{ Equality} |
4720 \LMLabel{equality} | 4733 \LMLabel{equality} |
4721 | 4734 |
4722 \LMHash{} | 4735 \LMHash{} |
4723 Equality expressions test objects for equality. | 4736 Equality expressions test objects for equality. |
4724 | 4737 |
4725 \begin{grammar} | 4738 \begin{grammar} |
4726 {\bf equalityExpression:}relationalExpression (equalityOperator relationalExpres sion)?; | 4739 {\bf equalityExpression:}relationalExpression (equalityOperator relationalExpres sion)?; |
4727 \SUPER{} equalityOperator relationalExpression | 4740 \SUPER{} equalityOperator relationalExpression |
4728 . | 4741 . |
4729 | 4742 |
4730 {\bf equalityOperator:}`=='; | 4743 {\bf equalityOperator:}`=='; |
4731 `!=' | 4744 `!=' |
4732 . | 4745 . |
4733 \end{grammar} | 4746 \end{grammar} |
4734 | 4747 |
4735 \LMHash{} | 4748 \LMHash{} |
4736 An {\em equality expression} is either a relational expression (\ref{relationalE xpressions}), or an invocation of an equality operator on either \SUPER{} or an expression $e_1$, with argument $e_2$. | 4749 An {\em equality expression} is either a relational expression (\ref{relationalE xpressions}), or an invocation of an equality operator on either \SUPER{} or an expression $e_1$, with argument $e_2$. |
4737 | 4750 |
4738 | 4751 |
4739 \LMHash{} | 4752 \LMHash{} |
4740 Evaluation of an equality expression $ee$ of the form \code{$e_1$ == $e_2$} proc eeds as follows: | 4753 Evaluation of an equality expression $ee$ of the form \code{$e_1$ == $e_2$} proc eeds as follows: |
4741 \begin{itemize} | 4754 \begin{itemize} |
4742 \item The expression $e_1$ is evaluated to an object $o_1$. | 4755 \item The expression $e_1$ is evaluated to an object $o_1$. |
4743 \item The expression $e_2$ is evaluated to an object $o_2$. | 4756 \item The expression $e_2$ is evaluated to an object $o_2$. |
4744 \item If either $o_1$ or $o_2$ is \NULL{}, then $ee$ evaluates to \TRUE{} if bot h $o_1$ and $o_2$ are \NULL{} and to \FALSE{} otherwise. Otherwise, | 4757 \item If either $o_1$ or $o_2$ is \NULL{}, then $ee$ evaluates to \TRUE{} if bot h $o_1$ and $o_2$ are \NULL{} and to \FALSE{} otherwise. Otherwise, |
4745 \item $ee$ is equivalent to the method invocation \code{$o_1$.==($o_2$)}. | 4758 \item $ee$ is equivalent to the method invocation \code{$o_1$.==($o_2$)}. |
4746 \end{itemize} | 4759 \end{itemize} |
4747 | 4760 |
4748 | 4761 |
4749 \LMHash{} | 4762 \LMHash{} |
4750 Evaluation of an equality expression $ee$ of the form \code{\SUPER{} == $e$} pro ceeds as follows: | 4763 Evaluation of an equality expression $ee$ of the form \code{\SUPER{} == $e$} pro ceeds as follows: |
4751 \begin{itemize} | 4764 \begin{itemize} |
4752 \item The expression $e$ is evaluated to an object $o$. | 4765 \item The expression $e$ is evaluated to an object $o$. |
4753 \item If either \THIS{} or $o$ is \NULL{}, then $ee$ evaluates to evaluates to \ TRUE{} if both \THIS{} and $o$ are \NULL{} and to \FALSE{} otherwise. Otherwise, | 4766 \item If either \THIS{} or $o$ is \NULL{}, then $ee$ evaluates to evaluates to \ TRUE{} if both \THIS{} and $o$ are \NULL{} and to \FALSE{} otherwise. Otherwise, |
4754 \item $ee$ is equivalent to the method invocation \code{\SUPER{}.==($o$)}. | 4767 \item $ee$ is equivalent to the method invocation \code{\SUPER{}.==($o$)}. |
4755 \end{itemize} | 4768 \end{itemize} |
4756 | 4769 |
4757 \commentary{As a result of the above definition, user defined \code{==} methods can assume that their argument is non-null, and avoid the standard boiler-plate prelude: | 4770 \commentary{As a result of the above definition, user defined \code{==} methods can assume that their argument is non-null, and avoid the standard boiler-plate prelude: |
4758 | 4771 |
4759 \code{if (identical(\NULL{}, arg)) return \FALSE{};} | 4772 \code{if (identical(\NULL{}, arg)) return \FALSE{};} |
4760 | 4773 |
4761 Another implication is that there is never a need to use \code{identical()} to t est against \NULL{}, nor should anyone ever worry about whether to write \NULL{} == $e$ or $e$ == \NULL{}. | 4774 Another implication is that there is never a need to use \code{identical()} to t est against \NULL{}, nor should anyone ever worry about whether to write \NULL{} == $e$ or $e$ == \NULL{}. |
4762 } | 4775 } |
4763 | 4776 |
4764 \LMHash{} | 4777 \LMHash{} |
4765 An equality expression of the form \code{$e_1$ != $e_2$} is equivalent to the e xpression \code{!($e_1$ == $e_2$)}. An equality expression of the form \code{\SU PER{} != $e$} is equivalent to the expression \code{!(\SUPER{} == $e$)}. | 4778 An equality expression of the form \code{$e_1$ != $e_2$} is equivalent to the e xpression \code{!($e_1$ == $e_2$)}. An equality expression of the form \code{\SU PER{} != $e$} is equivalent to the expression \code{!(\SUPER{} == $e$)}. |
4766 | 4779 |
4767 | 4780 |
4768 | 4781 |
4769 %The expression $e_1$ is evaluated to an object $o_1$; then the expression $e_2 $ is evaluated to an object $o_2$. Next, if $o_1$ and $o_2$ are the same object , then $ee$ evaluates to \TRUE{}, otherwise $ee$ evaluates to \FALSE{}. | 4782 %The expression $e_1$ is evaluated to an object $o_1$; then the expression $e_2 $ is evaluated to an object $o_2$. Next, if $o_1$ and $o_2$ are the same object , then $ee$ evaluates to \TRUE{}, otherwise $ee$ evaluates to \FALSE{}. |
4770 | 4783 |
4771 | 4784 |
4772 \LMHash{} | 4785 \LMHash{} |
4773 The static type of an equality expression is \code{bool}. | 4786 The static type of an equality expression is \code{bool}. |
4774 | 4787 |
4775 | 4788 |
4776 \subsection{ Relational Expressions} | 4789 \subsection{ Relational Expressions} |
4777 \LMLabel{relationalExpressions} | 4790 \LMLabel{relationalExpressions} |
4778 | 4791 |
4779 \LMHash{} | 4792 \LMHash{} |
4780 Relational expressions invoke the relational operators on objects. | 4793 Relational expressions invoke the relational operators on objects. |
4781 | 4794 |
4782 \begin{grammar} | 4795 \begin{grammar} |
4783 {\bf relationalExpression:}bitwiseOrExpression (typeTest $|$ typeCast $|$ relat ionalOperator bitwiseOrExpression)?; | 4796 {\bf relationalExpression:}bitwiseOrExpression (typeTest $|$ typeCast $|$ relat ionalOperator bitwiseOrExpression)?; |
4784 \SUPER{} relationalOperator bitwiseOrExpression | 4797 \SUPER{} relationalOperator bitwiseOrExpression |
4785 . | 4798 . |
4786 | 4799 |
4787 | 4800 |
4788 {\bf relationalOperator:}`{\escapegrammar \gt=}'; | 4801 {\bf relationalOperator:}`{\escapegrammar \gt=}'; |
4789 `{\escapegrammar \gt}'; | 4802 `{\escapegrammar \gt}'; |
4790 `{\escapegrammar \lt}='; | 4803 `{\escapegrammar \lt}='; |
4791 `{\escapegrammar \lt}' | 4804 `{\escapegrammar \lt}' |
4792 . | 4805 . |
4793 \end{grammar} | 4806 \end{grammar} |
4794 | 4807 |
4795 \LMHash{} | 4808 \LMHash{} |
4796 A {\em relational expression} is either a bitwise expression (\ref{bitwiseExpres sions}), or an invocation of a relational operator on either \SUPER{} or an expr ession $e_1$, with argument $e_2$. | 4809 A {\em relational expression} is either a bitwise expression (\ref{bitwiseExpres sions}), or an invocation of a relational operator on either \SUPER{} or an expr ession $e_1$, with argument $e_2$. |
4797 | 4810 |
4798 \LMHash{} | 4811 \LMHash{} |
4799 A relational expression of the form $e_1$ $op$ $e_2$ is equivalent to the metho d invocation \code{$e_1$.$op$($e_2$)}. A relational expression of the form \SUP ER{} $op$ $e_2$ is equivalent to the method invocation \code{\SUPER{}.$op$($e_2$ )}. | 4812 A relational expression of the form $e_1$ $op$ $e_2$ is equivalent to the metho d invocation \code{$e_1$.$op$($e_2$)}. A relational expression of the form \SUP ER{} $op$ $e_2$ is equivalent to the method invocation \code{\SUPER{}.$op$($e_2$ )}. |
4800 | 4813 |
4801 \subsection{ Bitwise Expressions} | 4814 \subsection{ Bitwise Expressions} |
4802 \LMLabel{bitwiseExpressions} | 4815 \LMLabel{bitwiseExpressions} |
4803 | 4816 |
4804 \LMHash{} | 4817 \LMHash{} |
4805 Bitwise expressions invoke the bitwise operators on objects. | 4818 Bitwise expressions invoke the bitwise operators on objects. |
4806 | 4819 |
4807 \begin{grammar} | 4820 \begin{grammar} |
4808 {\bf bitwiseOrExpression:}bitwiseXorExpression (`$|$' bitwiseXorExpression)*; | 4821 {\bf bitwiseOrExpression:}bitwiseXorExpression (`$|$' bitwiseXorExpression)*; |
4809 \SUPER{} (`$|$' bitwiseXorExpression)+ | 4822 \SUPER{} (`$|$' bitwiseXorExpression)+ |
4810 . | 4823 . |
4811 | 4824 |
4812 {\bf bitwiseXorExpression:}bitwiseAndExpression (`\^{}' bitwiseAndExpression)*; | 4825 {\bf bitwiseXorExpression:}bitwiseAndExpression (`\^{}' bitwiseAndExpression)*; |
4813 \SUPER{} (`\^{}' bitwiseAndExpression)+ | 4826 \SUPER{} (`\^{}' bitwiseAndExpression)+ |
4814 . | 4827 . |
4815 | 4828 |
4816 {\bf bitwiseAndExpression:}shiftExpression (`\&' shiftExpression)*; | 4829 {\bf bitwiseAndExpression:}shiftExpression (`\&' shiftExpression)*; |
4817 \SUPER{} (`\&' shiftExpression)+ | 4830 \SUPER{} (`\&' shiftExpression)+ |
4818 . | 4831 . |
4819 | 4832 |
4820 {\bf bitwiseOperator:}`\&'; | 4833 {\bf bitwiseOperator:}`\&'; |
4821 `\^{}'; | 4834 `\^{}'; |
4822 `$|$' | 4835 `$|$' |
4823 . | 4836 . |
4824 \end{grammar} | 4837 \end{grammar} |
4825 | 4838 |
4826 \LMHash{} | 4839 \LMHash{} |
4827 A {\em bitwise expression} is either a shift expression (\ref{shift}), or an inv ocation of a bitwise operator on either \SUPER{} or an expression $e_1$, with ar gument $e_2$. | 4840 A {\em bitwise expression} is either a shift expression (\ref{shift}), or an inv ocation of a bitwise operator on either \SUPER{} or an expression $e_1$, with ar gument $e_2$. |
4828 | 4841 |
4829 \LMHash{} | 4842 \LMHash{} |
4830 A bitwise expression of the form $e_1$ $op$ $e_2$ is equivalent to the method invocation $e_1.op(e_2)$. | 4843 A bitwise expression of the form $e_1$ $op$ $e_2$ is equivalent to the method invocation $e_1.op(e_2)$. |
4831 A bitwise expression of the form \code{\SUPER{} $op$ $e_2$} is equivalent to th e method invocation \code{\SUPER{}.op($e_2$)}. | 4844 A bitwise expression of the form \code{\SUPER{} $op$ $e_2$} is equivalent to th e method invocation \code{\SUPER{}.op($e_2$)}. |
4832 | 4845 |
4833 \commentary{ | 4846 \commentary{ |
4834 It should be obvious that the static type rules for these expressions are define d by the equivalence above - ergo, by the type rules for method invocation and t he signatures of the operators on the type $e_1$. The same holds in similar situ ations throughout this specification. | 4847 It should be obvious that the static type rules for these expressions are define d by the equivalence above - ergo, by the type rules for method invocation and t he signatures of the operators on the type $e_1$. The same holds in similar situ ations throughout this specification. |
4835 } | 4848 } |
4836 | 4849 |
4837 | 4850 |
4838 \subsection{ Shift} | 4851 \subsection{ Shift} |
4839 \LMLabel{shift} | 4852 \LMLabel{shift} |
4840 | 4853 |
4841 \LMHash{} | 4854 \LMHash{} |
4842 Shift expressions invoke the shift operators on objects. | 4855 Shift expressions invoke the shift operators on objects. |
4843 | 4856 |
4844 \begin{grammar} | 4857 \begin{grammar} |
4845 {\bf shiftExpression:}additiveExpression (shiftOperator additiveExpression)*; | 4858 {\bf shiftExpression:}additiveExpression (shiftOperator additiveExpression)*; |
4846 \SUPER{} (shiftOperator additiveExpression)+ | 4859 \SUPER{} (shiftOperator additiveExpression)+ |
4847 . | 4860 . |
4848 | 4861 |
4849 {\bf shiftOperator:}`{\escapegrammar \lt\lt'}; | 4862 {\bf shiftOperator:}`{\escapegrammar \lt\lt'}; |
4850 `{\escapegrammar \gt \gt}' | 4863 `{\escapegrammar \gt \gt}' |
4851 . | 4864 . |
4852 \end{grammar} | 4865 \end{grammar} |
4853 | 4866 |
4854 \LMHash{} | 4867 \LMHash{} |
4855 A {\em shift expression} is either an additive expression (\ref{additiveExpressi ons}), or an invocation of a shift operator on either \SUPER{} or an expression $e_1$, with argument $e_2$. | 4868 A {\em shift expression} is either an additive expression (\ref{additiveExpressi ons}), or an invocation of a shift operator on either \SUPER{} or an expression $e_1$, with argument $e_2$. |
4856 | 4869 |
4857 \LMHash{} | 4870 \LMHash{} |
4858 A shift expression of the form $e_1$ $op$ $e_2$ is equivalent to the method in vocation \code{$e_1$.$op$($e_2$)}. A shift expression of the form \SUPER{} $op$ $e_2$ is equivalent to the method invocation \code{\SUPER{}.$op$($e_2$)}. | 4871 A shift expression of the form $e_1$ $op$ $e_2$ is equivalent to the method in vocation \code{$e_1$.$op$($e_2$)}. A shift expression of the form \SUPER{} $op$ $e_2$ is equivalent to the method invocation \code{\SUPER{}.$op$($e_2$)}. |
4859 | 4872 |
4860 \commentary{ | 4873 \commentary{ |
4861 Note that this definition implies left-to-right evaluation order among shift exp ressions: | 4874 Note that this definition implies left-to-right evaluation order among shift exp ressions: |
4862 | 4875 |
4863 $e_1 << e_2 << e_3$ | 4876 $e_1 << e_2 << e_3$ |
4864 | 4877 |
4865 is evaluated as $(e_1 << e_2 ).<< (e_3)$ which is equivalent to $(e_1 << e_2) << e_3$. | 4878 is evaluated as $(e_1 << e_2 ).<< (e_3)$ which is equivalent to $(e_1 << e_2) << e_3$. |
4866 The same holds for additive and multiplicative expressions. | 4879 The same holds for additive and multiplicative expressions. |
4867 } | 4880 } |
4868 | 4881 |
4869 \subsection{ Additive Expressions} | 4882 \subsection{ Additive Expressions} |
4870 \LMLabel{additiveExpressions} | 4883 \LMLabel{additiveExpressions} |
4871 | 4884 |
4872 \LMHash{} | 4885 \LMHash{} |
4873 Additive expressions invoke the addition operators on objects. | 4886 Additive expressions invoke the addition operators on objects. |
4874 | 4887 |
4875 \begin{grammar} | 4888 \begin{grammar} |
4876 {\bf additiveExpression:}multiplicativeExpression (additiveOperator multiplicati veExpression)*; | 4889 {\bf additiveExpression:}multiplicativeExpression (additiveOperator multiplicati veExpression)*; |
4877 \SUPER{} (additiveOperator multiplicativeExpression)+ | 4890 \SUPER{} (additiveOperator multiplicativeExpression)+ |
4878 . | 4891 . |
4879 | 4892 |
4880 {\bf additiveOperator:}`+'; | 4893 {\bf additiveOperator:}`+'; |
4881 `-' | 4894 `-' |
4882 . | 4895 . |
4883 \end{grammar} | 4896 \end{grammar} |
4884 | 4897 |
4885 \LMHash{} | 4898 \LMHash{} |
4886 An {\em additive expression} is either a multiplicative expression (\ref{multipl icativeExpressions}), or an invocation of an additive operator on either \SUPER{ } or an expression $e_1$, with argument $e_2$. | 4899 An {\em additive expression} is either a multiplicative expression (\ref{multipl icativeExpressions}), or an invocation of an additive operator on either \SUPER{ } or an expression $e_1$, with argument $e_2$. |
4887 | 4900 |
4888 \LMHash{} | 4901 \LMHash{} |
4889 An additive expression of the form $e_1$ $op$ $e_2$ is equivalent to the method invocation \code{$e_1$.$op$($e_2$)}. An additive expression of the form \SUPER {} $op$ $e_2$ is equivalent to the method invocation \code{\SUPER{}.$op$($e_2$)} . | 4902 An additive expression of the form $e_1$ $op$ $e_2$ is equivalent to the method invocation \code{$e_1$.$op$($e_2$)}. An additive expression of the form \SUPER {} $op$ $e_2$ is equivalent to the method invocation \code{\SUPER{}.$op$($e_2$)} . |
4890 | 4903 |
4891 \LMHash{} | 4904 \LMHash{} |
4892 The static type of an additive expression is usually determined by the signature given in the declaration of the operator used. However, invocations of the oper ators \cd{+} and \cd{-} of class \cd{int} are treated specially by the typechec ker. The static type of an expression $e_1 + e_2$ where $e_1$ has static type \c d{int} is \cd{int} if the static type of $e_2$ is \cd{int}, and \cd{double} if t he static type of $e_2$ is \cd{double}. The static type of an expression $e_1 - e_2$ where $e_1$ has static type \cd{int} is \cd{int} if the static type of $e_2 $ is \cd{int}, and \cd{double} if the static type of $e_2$ is \cd{double}. | 4905 The static type of an additive expression is usually determined by the signature given in the declaration of the operator used. However, invocations of the oper ators \cd{+} and \cd{-} of class \cd{int} are treated specially by the typechec ker. The static type of an expression $e_1 + e_2$ where $e_1$ has static type \c d{int} is \cd{int} if the static type of $e_2$ is \cd{int}, and \cd{double} if t he static type of $e_2$ is \cd{double}. The static type of an expression $e_1 - e_2$ where $e_1$ has static type \cd{int} is \cd{int} if the static type of $e_2 $ is \cd{int}, and \cd{double} if the static type of $e_2$ is \cd{double}. |
4893 | 4906 |
4894 | 4907 |
4895 \subsection{ Multiplicative Expressions} | 4908 \subsection{ Multiplicative Expressions} |
4896 \LMLabel{multiplicativeExpressions} | 4909 \LMLabel{multiplicativeExpressions} |
4897 | 4910 |
4898 \LMHash{} | 4911 \LMHash{} |
4899 Multiplicative expressions invoke the multiplication operators on objects. | 4912 Multiplicative expressions invoke the multiplication operators on objects. |
4900 | 4913 |
4901 \begin{grammar} | 4914 \begin{grammar} |
4902 {\bf multiplicativeExpression:}unaryExpression (multiplicativeOperator unaryExpr ession)*; | 4915 {\bf multiplicativeExpression:}unaryExpression (multiplicativeOperator unaryExpr ession)*; |
4903 \SUPER{} (multiplicativeOperator unaryExpression)+ | 4916 \SUPER{} (multiplicativeOperator unaryExpression)+ |
4904 . | 4917 . |
4905 | 4918 |
4906 {\bf multiplicativeOperator:}`*'; | 4919 {\bf multiplicativeOperator:}`*'; |
4907 `/'; | 4920 `/'; |
4908 `\%'; | 4921 `\%'; |
4909 `\~{}/' | 4922 `\~{}/' |
4910 . | 4923 . |
4911 | 4924 |
4912 \end{grammar} | 4925 \end{grammar} |
4913 | 4926 |
4914 \LMHash{} | 4927 \LMHash{} |
4915 A {\em multiplicative expression} is either a unary expression (\ref{unaryExpre ssions}), or an invocation of a multiplicative operator on either \SUPER{} or an expression $e_1$, with argument $e_2$. | 4928 A {\em multiplicative expression} is either a unary expression (\ref{unaryExpre ssions}), or an invocation of a multiplicative operator on either \SUPER{} or an expression $e_1$, with argument $e_2$. |
4916 | 4929 |
4917 \LMHash{} | 4930 \LMHash{} |
4918 A multiplicative expression of the form $e_1$ $op$ $e_2$ is equivalent to the method invocation \code{$e_1$.$op$($e_2$)}. A multiplicative expression of the f orm \SUPER{} $op$ $e_2$ is equivalent to the method invocation \code{\SUPER{}.$ op$($e_2$)}. | 4931 A multiplicative expression of the form $e_1$ $op$ $e_2$ is equivalent to the method invocation \code{$e_1$.$op$($e_2$)}. A multiplicative expression of the f orm \SUPER{} $op$ $e_2$ is equivalent to the method invocation \code{\SUPER{}.$ op$($e_2$)}. |
4919 | 4932 |
4920 \LMHash{} | 4933 \LMHash{} |
4921 The static type of an multiplicative expression is usually determined by the sig nature given in the declaration of the operator used. However, invocations of th e operators \cd{*}, \cd{\%} and \cd{\~{}/} of class \cd{int} are treated specia lly by the typechecker. The static type of an expression $e_1 * e_2$ where $e_1$ has static type \cd{int} is \cd{int} if the static type of $e_2$ is \cd{int}, a nd \cd{double} if the static type of $e_2$ is \cd{double}. The static type of an expression $e_1 \% e_2$ where $e_1$ has static type \cd{int} is \cd{int} if the static type of $e_2$ is \cd{int}, and \cd{double} if the static type of $e_2$ i s \cd{double}. The static type of an expression \cd{$e_1$ \~{}/ $e_2$} where $e _1$ has static type \cd{int} is \cd{int} if the static type of $e_2$ is \cd{int} . | 4934 The static type of an multiplicative expression is usually determined by the sig nature given in the declaration of the operator used. However, invocations of th e operators \cd{*}, \cd{\%} and \cd{\~{}/} of class \cd{int} are treated specia lly by the typechecker. The static type of an expression $e_1 * e_2$ where $e_1$ has static type \cd{int} is \cd{int} if the static type of $e_2$ is \cd{int}, a nd \cd{double} if the static type of $e_2$ is \cd{double}. The static type of an expression $e_1 \% e_2$ where $e_1$ has static type \cd{int} is \cd{int} if the static type of $e_2$ is \cd{int}, and \cd{double} if the static type of $e_2$ i s \cd{double}. The static type of an expression \cd{$e_1$ \~{}/ $e_2$} where $e _1$ has static type \cd{int} is \cd{int} if the static type of $e_2$ is \cd{int} . |
4922 | 4935 |
4923 \subsection{ Unary Expressions} | 4936 \subsection{ Unary Expressions} |
4924 \LMLabel{unaryExpressions} | 4937 \LMLabel{unaryExpressions} |
4925 | 4938 |
4926 \LMHash{} | 4939 \LMHash{} |
4927 Unary expressions invoke unary operators on objects. | 4940 Unary expressions invoke unary operators on objects. |
4928 | 4941 |
4929 \begin{grammar} | 4942 \begin{grammar} |
4930 {\bf unaryExpression:}prefixOperator unaryExpression; | 4943 {\bf unaryExpression:}prefixOperator unaryExpression; |
4931 awaitExpression; | 4944 awaitExpression; |
4932 postfixExpression; | 4945 postfixExpression; |
4933 (minusOperator $|$ tildeOperator) \SUPER{}; | 4946 (minusOperator $|$ tildeOperator) \SUPER{}; |
4934 incrementOperator assignableExpression | 4947 incrementOperator assignableExpression |
4935 . | 4948 . |
4936 | 4949 |
4937 {\bf prefixOperator:}minusOperator; | 4950 {\bf prefixOperator:}minusOperator; |
4938 negationOperator; | 4951 negationOperator; |
4939 tildeOperator | 4952 tildeOperator |
4940 . | 4953 . |
4941 | 4954 |
4942 | 4955 |
4943 {\bf minusOperator:}`-'; . | 4956 {\bf minusOperator:}`-'; . |
4944 | 4957 |
4945 | 4958 |
4946 {\bf negationOperator:}`!' ; | 4959 {\bf negationOperator:}`!' ; |
4947 . | 4960 . |
4948 | 4961 |
4949 {\bf tildeOperator:} `\~{}' | 4962 {\bf tildeOperator:} `\~{}' |
4950 . | 4963 . |
4951 | 4964 |
4952 | 4965 |
4953 \end{grammar} | 4966 \end{grammar} |
4954 | 4967 |
4955 \LMHash{} | 4968 \LMHash{} |
4956 A {\em unary expression} is either a postfix expression (\ref{postfixExpression s}), an await expression (\ref{awaitExpressions}) or an invocation of a prefix o perator on an expression or an invocation of a unary operator on either \SUPER{} or an expression $e$. | 4969 A {\em unary expression} is either a postfix expression (\ref{postfixExpression s}), an await expression (\ref{awaitExpressions}) or an invocation of a prefix o perator on an expression or an invocation of a unary operator on either \SUPER{} or an expression $e$. |
4957 | 4970 |
4958 \LMHash{} | 4971 \LMHash{} |
4959 The expression $!e$ is equivalent to the expression $e?$ $ \FALSE{} :\TRUE{}$. | 4972 The expression $!e$ is equivalent to the expression $e?$ $ \FALSE{} :\TRUE{}$. |
4960 | 4973 |
4961 \LMHash{} | 4974 \LMHash{} |
4962 Evaluation of an expression of the form \code{++$e$} is equivalent to \code{$e$ += 1}. Evaluation of an expression of the form \code{-{}-$e$} is equivalent to \code{$e$ -= 1}. | 4975 Evaluation of an expression of the form \code{++$e$} is equivalent to \code{$e$ += 1}. Evaluation of an expression of the form \code{-{}-$e$} is equivalent to \code{$e$ -= 1}. |
4963 | 4976 |
4964 %The expression $-e$ is equivalent to the method invocation \code{$e$.-()}. The expression \code{-\SUPER{}} is equivalent to the method invocation \code{\SUPE R{}.-()}. | 4977 %The expression $-e$ is equivalent to the method invocation \code{$e$.-()}. The expression \code{-\SUPER{}} is equivalent to the method invocation \code{\SUPE R{}.-()}. |
4965 | 4978 |
4966 \LMHash{} | 4979 \LMHash{} |
4967 An expression of the form \code{$op$ $e$} is equivalent to the method invocation \code{$e.op()$}. An expression of the form \code{$op$ \SUPER{}} is equivalent t o the method invocation (\ref{superInvocation}) \code{\SUPER{}.$op()$}. | 4980 An expression of the form \code{$op$ $e$} is equivalent to the method invocation \code{$e.op()$}. An expression of the form \code{$op$ \SUPER{}} is equivalent t o the method invocation (\ref{superInvocation}) \code{\SUPER{}.$op()$}. |
4968 | 4981 |
4969 \subsection{ Await Expressions} | 4982 \subsection{ Await Expressions} |
4970 \LMLabel{awaitExpressions} | 4983 \LMLabel{awaitExpressions} |
4971 | 4984 |
4972 \LMHash{} | 4985 \LMHash{} |
4973 An {\em await expression} allows code to yield control until an asynchronous ope ration (\ref{functions}) completes. | 4986 An {\em await expression} allows code to yield control until an asynchronous ope ration (\ref{functions}) completes. |
4974 | 4987 |
4975 \begin{grammar} | 4988 \begin{grammar} |
4976 {\bf awaitExpression:} | 4989 {\bf awaitExpression:} |
4977 \AWAIT{} unaryExpression | 4990 \AWAIT{} unaryExpression |
4978 \end{grammar} | 4991 \end{grammar} |
4979 | 4992 |
4980 \LMHash{} | 4993 \LMHash{} |
4981 Evaluation of an await expression $a$ of the form \AWAIT{} $e$ proceeds as follo ws: | 4994 Evaluation of an await expression $a$ of the form \AWAIT{} $e$ proceeds as follo ws: |
4982 First, the expression $e$ is evaluated. Next: | 4995 First, the expression $e$ is evaluated. Next: |
4983 | 4996 |
4984 \LMHash{} | 4997 \LMHash{} |
4985 If $e$ raises an exception $x$, then an instance $f$ of class \code{Future} is a llocated and later completed with $x$. Otherwise, if $e$ evaluates to an object $o$ that is not an instance of \code{Future}, then let $f$ be the result of call ing \code{Future.value()} with $o$ as its argument; otherwise let $f$ be the res ult of evaluating $e$. | 4998 If $e$ raises an exception $x$, then an instance $f$ of class \code{Future} is a llocated and later completed with $x$. Otherwise, if $e$ evaluates to an object $o$ that is not an instance of \code{Future}, then let $f$ be the result of call ing \code{Future.value()} with $o$ as its argument; otherwise let $f$ be the res ult of evaluating $e$. |
4986 | 4999 |
4987 \LMHash{} | 5000 \LMHash{} |
4988 Next, execution of the function $m$ immediately enclosing $a$ is suspended unti l after $f$ completes. The stream associated with the innermost enclosing asynch ronous for loop (\ref{asynchronousFor-in}), if any, is paused. At some time afte r $f$ is completed, control returns to the current invocation. The stream associ ated with the innermost enclosing asynchronous for loop (\ref{asynchronousFor-i n}), if any, is resumed. If $f$ has completed with an exception $x$, $a$ raises $x$. If $f$ completes with a value $v$, $a$ evaluates to $v$. | 5001 Next, execution of the function $m$ immediately enclosing $a$ is suspended unti l after $f$ completes. The stream associated with the innermost enclosing asynch ronous for loop (\ref{asynchronousFor-in}), if any, is paused. At some time afte r $f$ is completed, control returns to the current invocation. The stream associ ated with the innermost enclosing asynchronous for loop (\ref{asynchronousFor-i n}), if any, is resumed. If $f$ has completed with an exception $x$, $a$ raises $x$. If $f$ completes with a value $v$, $a$ evaluates to $v$. |
4989 | 5002 |
4990 %Otherwise, the value of $a$ is the value of $e$. If evaluation of $e$ raises an exception $x$, $a$ raises $x$. | 5003 %Otherwise, the value of $a$ is the value of $e$. If evaluation of $e$ raises an exception $x$, $a$ raises $x$. |
4991 | 5004 |
4992 \commentary{ | 5005 \commentary{ |
4993 It is a compile-time error if the function immediately enclosing $a$ is not declared asynchronous. However, this error is simply a syntax error, because in the context of a normal function, \AWAIT{} has no special meaning. | 5006 It is a compile-time error if the function immediately enclosing $a$ is not declared asynchronous. However, this error is simply a syntax error, because in the context of a normal function, \AWAIT{} has no special meaning. |
4994 } | 5007 } |
4995 | 5008 |
4996 \rationale{ | 5009 \rationale{ |
4997 An await expression has no meaning in a synchronous function. If such a function were to suspend waiting for a future, it would no longer be synchronous. | 5010 An await expression has no meaning in a synchronous function. If such a function were to suspend waiting for a future, it would no longer be synchronous. |
4998 } | 5011 } |
4999 | 5012 |
5000 \commentary{ | 5013 \commentary{ |
5001 It is not a static warning if the type of $e$ is not a subtype of \code{Future}. Tools may choose to give a hint in such cases. | 5014 It is not a static warning if the type of $e$ is not a subtype of \code{Future}. Tools may choose to give a hint in such cases. |
5002 } | 5015 } |
5003 | 5016 |
5004 \LMHash{} | 5017 \LMHash{} |
5005 The static type of $a$ is $flatten(T)$ (the $flatten$ function is defined in sec tion \ref{functionExpressions}) where $T$ is the static type of $e$. | 5018 The static type of $a$ is $flatten(T)$ (the $flatten$ function is defined in sec tion \ref{functionExpressions}) where $T$ is the static type of $e$. |
5006 | 5019 |
5007 | 5020 |
5008 | 5021 |
5009 \subsection{ Postfix Expressions} | 5022 \subsection{ Postfix Expressions} |
5010 \LMLabel{postfixExpressions} | 5023 \LMLabel{postfixExpressions} |
5011 | 5024 |
5012 \LMHash{} | 5025 \LMHash{} |
5013 Postfix expressions invoke the postfix operators on objects. | 5026 Postfix expressions invoke the postfix operators on objects. |
5014 | 5027 |
5015 \begin{grammar} | 5028 \begin{grammar} |
5016 {\bf postfixExpression:}assignableExpression postfixOperator; | 5029 {\bf postfixExpression:}assignableExpression postfixOperator; |
5017 primary (selector* $|$ ( `\#' ( (identifier `='?) $|$ operator))) | 5030 primary (selector* $|$ ( `\#' ( (identifier `='?) $|$ operator))) |
5018 . | 5031 . |
5019 | 5032 |
5020 {\bf postfixOperator:} | 5033 {\bf postfixOperator:} |
5021 incrementOperator | 5034 incrementOperator |
5022 . | 5035 . |
5023 | 5036 |
5024 {\bf selector:}assignableSelector; | 5037 {\bf selector:}assignableSelector; |
5025 arguments | 5038 arguments |
5026 . | 5039 . |
5027 | 5040 |
5028 {\bf incrementOperator:}`++'; | 5041 {\bf incrementOperator:}`++'; |
5029 `-{}-' | 5042 `-{}-' |
5030 . | 5043 . |
5031 | 5044 |
5032 \end{grammar} | 5045 \end{grammar} |
5033 | 5046 |
5034 \LMHash{} | 5047 \LMHash{} |
5035 A {\em postfix expression} is either a primary expression, a function, method o r getter invocation, or an invocation of a postfix operator on an expression $e$ . | 5048 A {\em postfix expression} is either a primary expression, a function, method o r getter invocation, or an invocation of a postfix operator on an expression $e$ . |
5036 | 5049 |
5037 \LMHash{} | 5050 \LMHash{} |
5038 Execution of a postfix expression of the form \code{$v$++}, where $v$ is an iden tifier, is equivalent to executing \code{()\{\VAR{} r = $v$; $v$ = r + 1; \RETUR N{} r\}()}. | 5051 Execution of a postfix expression of the form \code{$v$++}, where $v$ is an iden tifier, is equivalent to executing \code{()\{\VAR{} r = $v$; $v$ = r + 1; \RETUR N{} r\}()}. |
5039 | 5052 |
5040 \LMHash{} | 5053 \LMHash{} |
5041 The static type of such an expression is the static type of $v$. | 5054 The static type of such an expression is the static type of $v$. |
5042 | 5055 |
5043 | 5056 |
5044 \rationale{The above ensures that if $v$ is a field, the getter gets called exac tly once. Likewise in the cases below. | 5057 \rationale{The above ensures that if $v$ is a field, the getter gets called exac tly once. Likewise in the cases below. |
5045 } | 5058 } |
5046 | 5059 |
5047 \LMHash{} | 5060 \LMHash{} |
5048 Execution of a postfix expression of the form \code{$C.v$ ++} is equivalent to e xecuting | 5061 Execution of a postfix expression of the form \code{$C.v$ ++} is equivalent to e xecuting |
5049 | 5062 |
5050 \code{()\{\VAR{} r = $C.v$; $C.v$ = r + 1; \RETURN{} r\}()}. | 5063 \code{()\{\VAR{} r = $C.v$; $C.v$ = r + 1; \RETURN{} r\}()}. |
5051 | 5064 |
5052 \LMHash{} | 5065 \LMHash{} |
5053 The static type of such an expression is the static type of $C.v$. | 5066 The static type of such an expression is the static type of $C.v$. |
5054 | 5067 |
5055 | 5068 |
5056 \LMHash{} | 5069 \LMHash{} |
5057 Execution of a postfix expression of the form \code{$e_1.v$++} is equivalent to executing | 5070 Execution of a postfix expression of the form \code{$e_1.v$++} is equivalent to executing |
5058 | 5071 |
5059 \code{(x)\{\VAR{} r = x.v; x.v = r + 1; \RETURN{} r\}($e_1$)}. | 5072 \code{(x)\{\VAR{} r = x.v; x.v = r + 1; \RETURN{} r\}($e_1$)}. |
5060 | 5073 |
5061 \LMHash{} | 5074 \LMHash{} |
5062 The static type of such an expression is the static type of $e_1.v$. | 5075 The static type of such an expression is the static type of $e_1.v$. |
5063 | 5076 |
5064 | 5077 |
5065 \LMHash{} | 5078 \LMHash{} |
5066 Execution of a postfix expression of the form \code{$e_1[e_2]$++}, is equivalen t to executing | 5079 Execution of a postfix expression of the form \code{$e_1[e_2]$++}, is equivalen t to executing |
5067 | 5080 |
5068 \code{(a, i)\{\VAR{} r = a[i]; a[i] = r + 1; \RETURN{} r\}($e_1$, $e_2$)}. | 5081 \code{(a, i)\{\VAR{} r = a[i]; a[i] = r + 1; \RETURN{} r\}($e_1$, $e_2$)}. |
5069 | 5082 |
5070 \LMHash{} | 5083 \LMHash{} |
5071 The static type of such an expression is the static type of $e_1[e_2]$. | 5084 The static type of such an expression is the static type of $e_1[e_2]$. |
5072 | 5085 |
5073 | 5086 |
5074 \LMHash{} | 5087 \LMHash{} |
5075 Execution of a postfix expression of the form \code{$v$-{}-}, where $v$ is an id entifier, is equivalent to executing | 5088 Execution of a postfix expression of the form \code{$v$-{}-}, where $v$ is an id entifier, is equivalent to executing |
5076 | 5089 |
5077 \code{()\{\VAR{} r = $v$; $v$ = r - 1; \RETURN{} r\}()}. | 5090 \code{()\{\VAR{} r = $v$; $v$ = r - 1; \RETURN{} r\}()}. |
5078 | 5091 |
5079 \LMHash{} | 5092 \LMHash{} |
5080 The static type of such an expression is the static type of $v$. | 5093 The static type of such an expression is the static type of $v$. |
5081 | 5094 |
5082 | 5095 |
5083 \LMHash{} | 5096 \LMHash{} |
5084 Execution of a postfix expression of the form \code{$C.v$-{}-} is equivalent to executing | 5097 Execution of a postfix expression of the form \code{$C.v$-{}-} is equivalent to executing |
5085 | 5098 |
5086 \code{()\{\VAR{} r = $C.v$; $C.v$ = r - 1; \RETURN{} r\}()}. | 5099 \code{()\{\VAR{} r = $C.v$; $C.v$ = r - 1; \RETURN{} r\}()}. |
5087 | 5100 |
5088 \LMHash{} | 5101 \LMHash{} |
5089 The static type of such an expression is the static type of $C.v$. | 5102 The static type of such an expression is the static type of $C.v$. |
5090 | 5103 |
5091 | 5104 |
5092 \LMHash{} | 5105 \LMHash{} |
5093 Execution of a postfix expression of the form \code{$e_1.v$-{}-} is equivalent t o executing | 5106 Execution of a postfix expression of the form \code{$e_1.v$-{}-} is equivalent t o executing |
5094 | 5107 |
5095 \code{(x)\{\VAR{} r = x.v; x.v = r - 1; \RETURN{} r\}($e_1$)}. | 5108 \code{(x)\{\VAR{} r = x.v; x.v = r - 1; \RETURN{} r\}($e_1$)}. |
5096 | 5109 |
5097 \LMHash{} | 5110 \LMHash{} |
5098 The static type of such an expression is the static type of $e_1.v$. | 5111 The static type of such an expression is the static type of $e_1.v$. |
5099 | 5112 |
5100 | 5113 |
5101 \LMHash{} | 5114 \LMHash{} |
5102 Execution of a postfix expression of the form \code{$e_1[e_2]$-{}-}, is equival ent to executing | 5115 Execution of a postfix expression of the form \code{$e_1[e_2]$-{}-}, is equival ent to executing |
5103 | 5116 |
5104 \code{(a, i)\{\VAR{} r = a[i]; a[i] = r - 1; \RETURN{} r\}($e_1$, $e_2$)}. | 5117 \code{(a, i)\{\VAR{} r = a[i]; a[i] = r - 1; \RETURN{} r\}($e_1$, $e_2$)}. |
5105 | 5118 |
5106 \LMHash{} | 5119 \LMHash{} |
5107 The static type of such an expression is the static type of $e_1[e_2]$. | 5120 The static type of such an expression is the static type of $e_1[e_2]$. |
5108 | 5121 |
5109 \LMHash{} | 5122 \LMHash{} |
5110 Execution of a postfix expression of the form \code{$e_1?.v$++} is equivalent to executing | 5123 Execution of a postfix expression of the form \code{$e_1?.v$++} is equivalent to executing |
5111 | 5124 |
5112 \code{((x) =$>$ x == \NULL? \NULL : x.v++)($e_1$)} | 5125 \code{((x) =$>$ x == \NULL? \NULL : x.v++)($e_1$)} |
5113 unless $e_1$ is a type literal, in which case it is equivalent to \code{$e_1.v$+ +} | 5126 unless $e_1$ is a type literal, in which case it is equivalent to \code{$e_1.v$+ +} |
5114 . | 5127 . |
5115 | 5128 |
5116 \LMHash{} | 5129 \LMHash{} |
5117 The static type of such an expression is the static type of $e_1.v$. | 5130 The static type of such an expression is the static type of $e_1.v$. |
5118 | 5131 |
5119 \LMHash{} | 5132 \LMHash{} |
5120 Execution of a postfix expression of the form \code{$e_1?.v$-{}-} is equivalent to executing | 5133 Execution of a postfix expression of the form \code{$e_1?.v$-{}-} is equivalent to executing |
5121 | 5134 |
5122 \code{((x) =$>$ x == \NULL? \NULL : x.v-{}-)($e_1$)} | 5135 \code{((x) =$>$ x == \NULL? \NULL : x.v-{}-)($e_1$)} |
5123 unless $e_1$ is a type literal, in which case it is equivalent to \code{$e_1.v$- {}-} | 5136 unless $e_1$ is a type literal, in which case it is equivalent to \code{$e_1.v$- {}-} |
5124 . | 5137 . |
5125 | 5138 |
5126 \LMHash{} | 5139 \LMHash{} |
5127 The static type of such an expression is the static type of $e_1.v$. | 5140 The static type of such an expression is the static type of $e_1.v$. |
5128 | 5141 |
5129 | 5142 |
5130 \subsection{ Assignable Expressions} | 5143 \subsection{ Assignable Expressions} |
5131 \LMLabel{assignableExpressions} | 5144 \LMLabel{assignableExpressions} |
5132 | 5145 |
5133 \LMHash{} | 5146 \LMHash{} |
5134 Assignable expressions are expressions that can appear on the left hand side of an assignment. | 5147 Assignable expressions are expressions that can appear on the left hand side of an assignment. |
5135 This section describes how to evaluate these expressions when they do not consti tute the complete left hand side of an assignment. | 5148 This section describes how to evaluate these expressions when they do not consti tute the complete left hand side of an assignment. |
5136 | 5149 |
5137 \rationale{ | 5150 \rationale{ |
5138 Of course, if assignable expressions always appeared {\em as} the left hand side , one would have no need for their value, and the rules for evaluating them woul d be unnecessary. However, assignable expressions can be subexpressions of othe r expressions and therefore must be evaluated. | 5151 Of course, if assignable expressions always appeared {\em as} the left hand side , one would have no need for their value, and the rules for evaluating them woul d be unnecessary. However, assignable expressions can be subexpressions of othe r expressions and therefore must be evaluated. |
5139 } | 5152 } |
5140 | 5153 |
5141 | 5154 |
5142 | 5155 |
5143 \begin{grammar} | 5156 \begin{grammar} |
5144 | 5157 |
5145 {\bf assignableExpression:}primary (arguments* assignableSelector)+; | 5158 {\bf assignableExpression:}primary (arguments* assignableSelector)+; |
5146 \SUPER{} unconditionalAssignableSelector; | 5159 \SUPER{} unconditionalAssignableSelector; |
5147 identifier | 5160 identifier |
5148 . | 5161 . |
5149 | 5162 |
5150 {\bf unconditionalAssignableSelector:}`[' expression `]'; % again, could be top level | 5163 {\bf unconditionalAssignableSelector:}`[' expression `]'; % again, could be top level |
5151 `{\escapegrammar .}' identifier | 5164 `{\escapegrammar .}' identifier |
5152 . | 5165 . |
5153 | 5166 |
5154 {\bf assignableSelector:} | 5167 {\bf assignableSelector:} |
5155 unconditionalAssignableSelector; | 5168 unconditionalAssignableSelector; |
5156 `{\escapegrammar ?.}' identifier | 5169 `{\escapegrammar ?.}' identifier |
5157 . | 5170 . |
5158 | 5171 |
5159 \end{grammar} | 5172 \end{grammar} |
5160 | 5173 |
5161 | 5174 |
5162 \LMHash{} | 5175 \LMHash{} |
5163 An {\em assignable expression} is either: | 5176 An {\em assignable expression} is either: |
5164 \begin{itemize} | 5177 \begin{itemize} |
5165 \item An identifier. | 5178 \item An identifier. |
5166 \item An invocation (possibly conditional) of a getter (\ref{getters}) or list a ccess operator on an expression $e$. | 5179 \item An invocation (possibly conditional) of a getter (\ref{getters}) or list a ccess operator on an expression $e$. |
5167 \item An invocation of a getter or list access operator on \SUPER{}. | 5180 \item An invocation of a getter or list access operator on \SUPER{}. |
5168 \end{itemize} | 5181 \end{itemize} |
5169 | 5182 |
5170 | 5183 |
5171 \LMHash{} | 5184 \LMHash{} |
5172 An assignable expression of the form $id$ is evaluated as an identifier expressi on (\ref{identifierReference}). | 5185 An assignable expression of the form $id$ is evaluated as an identifier expressi on (\ref{identifierReference}). |
5173 | 5186 |
5174 %An assignable expression of the form $e.id(a_1, \ldots, a_n)$ is evaluated as a method invocation (\ref{methodInvocation}). | 5187 %An assignable expression of the form $e.id(a_1, \ldots, a_n)$ is evaluated as a method invocation (\ref{methodInvocation}). |
5175 | 5188 |
(...skipping 12 matching lines...) Expand all Loading... | |
5188 \subsection{ Identifier Reference} | 5201 \subsection{ Identifier Reference} |
5189 \LMLabel{identifierReference} | 5202 \LMLabel{identifierReference} |
5190 | 5203 |
5191 \LMHash{} | 5204 \LMHash{} |
5192 An {\em identifier expression} consists of a single identifier; it provides acce ss to an object via an unqualified name. | 5205 An {\em identifier expression} consists of a single identifier; it provides acce ss to an object via an unqualified name. |
5193 | 5206 |
5194 \begin{grammar} | 5207 \begin{grammar} |
5195 {\bf identifier:} | 5208 {\bf identifier:} |
5196 IDENTIFIER | 5209 IDENTIFIER |
5197 . | 5210 . |
5198 | 5211 |
5199 | 5212 |
5200 {\bf IDENTIFIER\_NO\_DOLLAR:} | 5213 {\bf IDENTIFIER\_NO\_DOLLAR:} |
5201 IDENTIFIER\_START\_NO\_DOLLAR IDENTIFIER\_PART\_NO\_DOLLAR* | 5214 IDENTIFIER\_START\_NO\_DOLLAR IDENTIFIER\_PART\_NO\_DOLLAR* |
5202 . | 5215 . |
5203 | 5216 |
5204 {\bf IDENTIFIER:} | 5217 {\bf IDENTIFIER:} |
5205 IDENTIFIER\_START IDENTIFIER\_PART* | 5218 IDENTIFIER\_START IDENTIFIER\_PART* |
5206 . | 5219 . |
5207 | 5220 |
5208 {\bf BUILT\_IN\_IDENTIFIER:} \ABSTRACT{}; | 5221 {\bf BUILT\_IN\_IDENTIFIER:} \ABSTRACT{}; |
5209 \AS{}; | 5222 \AS{}; |
(...skipping 26 matching lines...) Expand all Loading... | |
5236 . | 5249 . |
5237 | 5250 |
5238 | 5251 |
5239 {\bf IDENTIFIER\_PART:}IDENTIFIER\_START; | 5252 {\bf IDENTIFIER\_PART:}IDENTIFIER\_START; |
5240 DIGIT | 5253 DIGIT |
5241 . | 5254 . |
5242 | 5255 |
5243 | 5256 |
5244 | 5257 |
5245 {\bf qualified:} | 5258 {\bf qualified:} |
5246 identifier (`{\escapegrammar .}' identifier)? | 5259 identifier (`{\escapegrammar .}' identifier)? |
5247 . | 5260 . |
5248 \end{grammar} | 5261 \end{grammar} |
5249 | 5262 |
5250 \LMHash{} | 5263 \LMHash{} |
5251 A built-in identifier is one of the identifiers produced by the production {\em BUILT\_IN\_IDENTIFIER}. It is a compile-time error if a built-in identifier is u sed as the declared name of a prefix, class, type parameter or type alias. It is a compile-time error to use a built-in identifier other than \DYNAMIC{} as a ty pe annotation or type parameter. | 5264 A built-in identifier is one of the identifiers produced by the production {\em BUILT\_IN\_IDENTIFIER}. It is a compile-time error if a built-in identifier is u sed as the declared name of a prefix, class, type parameter or type alias. It is a compile-time error to use a built-in identifier other than \DYNAMIC{} as a ty pe annotation or type parameter. |
5252 | 5265 |
5253 \rationale{ | 5266 \rationale{ |
5254 Built-in identifiers are identifiers that are used as keywords in Dart, but are not reserved words in Javascript. To minimize incompatibilities when porting Jav ascript code to Dart, we do not make these into reserved words. A built-in ident ifier may not be used to name a class or type. In other words, they are treated as reserved words when used as types. This eliminates many confusing situations without causing compatibility problems. After all, a Javascript program has no type declarations or annotations so no clash can occur. Furthermore, types shou ld begin with an uppercase letter (see the appendix) and so no clash should occu r in any Dart user program anyway. | 5267 Built-in identifiers are identifiers that are used as keywords in Dart, but are not reserved words in Javascript. To minimize incompatibilities when porting Jav ascript code to Dart, we do not make these into reserved words. A built-in ident ifier may not be used to name a class or type. In other words, they are treated as reserved words when used as types. This eliminates many confusing situations without causing compatibility problems. After all, a Javascript program has no type declarations or annotations so no clash can occur. Furthermore, types shou ld begin with an uppercase letter (see the appendix) and so no clash should occu r in any Dart user program anyway. |
5255 } | 5268 } |
5256 | 5269 |
5257 \LMHash{} | 5270 \LMHash{} |
5258 It is a compile-time error if any of the identifiers \ASYNC, \AWAIT{} or \YIELD{ } is used as an identifier in a function body marked with either \ASYNC{}, \ASYN C* or \SYNC*. | 5271 It is a compile-time error if any of the identifiers \ASYNC, \AWAIT{} or \YIELD{ } is used as an identifier in a function body marked with either \ASYNC{}, \ASYN C* or \SYNC*. |
5259 | 5272 |
5260 \rationale{ | 5273 \rationale{ |
5261 For compatibility reasons, new constructs cannot rely upon new reserved words o r even built-in identifiers. However, the constructs above are only usable in co ntexts that require special markers introduced concurrently with these construct s, so no old code could use them. Hence the restriction, which treats these name s as reserved words in a limited context. | 5274 For compatibility reasons, new constructs cannot rely upon new reserved words o r even built-in identifiers. However, the constructs above are only usable in co ntexts that require special markers introduced concurrently with these construct s, so no old code could use them. Hence the restriction, which treats these name s as reserved words in a limited context. |
5262 } | 5275 } |
5263 | 5276 |
5264 \LMHash{} | 5277 \LMHash{} |
5265 Evaluation of an identifier expression $e$ of the form $id$ proceeds as follows: | 5278 Evaluation of an identifier expression $e$ of the form $id$ proceeds as follows: |
5266 | 5279 |
5267 | 5280 |
5268 \LMHash{} | 5281 \LMHash{} |
5269 Let $d$ be the innermost declaration in the enclosing lexical scope whose name i s $id$ or $id=$. If no such declaration exists in the lexical scope, let $d$ be the declaration of the inherited member named $id$ if it exists. | 5282 Let $d$ be the innermost declaration in the enclosing lexical scope whose name i s $id$ or $id=$. If no such declaration exists in the lexical scope, let $d$ be the declaration of the inherited member named $id$ if it exists. |
5270 %If no such member exists, let $d$ be the declaration of the static member name $id$ declared in a superclass of the current class, if it exists. | 5283 %If no such member exists, let $d$ be the declaration of the static member name $id$ declared in a superclass of the current class, if it exists. |
5271 | 5284 |
5272 \begin{itemize} | 5285 \begin{itemize} |
5273 \item if $d$ is a prefix $p$, a compile-time error occurs unless the token immed iately following $d$ is \code{'.'}. | 5286 \item if $d$ is a prefix $p$, a compile-time error occurs unless the token immed iately following $d$ is \code{'.'} or \code{'\#'}. |
5274 \item If $d$ is a class or type alias $T$, the value of $e$ is an instance of c lass \code{Type} (or a subclass thereof) reifying $T$. | 5287 \item If $d$ is a class or type alias $T$, the value of $e$ is an instance of c lass \code{Type} (or a subclass thereof) reifying $T$. |
5275 \item If $d$ is a type parameter $T$, then the value of $e$ is the value of the actual type argument corresponding to $T$ that was passed to the generative con structor that created the current binding of \THIS{}. If, however, $e$ occurs in side a static member, a compile-time error occurs. | 5288 \item If $d$ is a type parameter $T$, then the value of $e$ is the value of the actual type argument corresponding to $T$ that was passed to the generative con structor that created the current binding of \THIS{}. If, however, $e$ occurs in side a static member, a compile-time error occurs. |
5276 | 5289 |
5277 %\commentary{ We are assured that \THIS{} is well defined, because if we were in a static member the reference to $T$ is a compile-time error (\ref{generics}.)} | 5290 %\commentary{ We are assured that \THIS{} is well defined, because if we were in a static member the reference to $T$ is a compile-time error (\ref{generics}.)} |
5278 %\item If $d$ is a library variable then: | 5291 %\item If $d$ is a library variable then: |
5279 % \begin{itemize} | 5292 % \begin{itemize} |
5280 % \item If $d$ is of one of the forms \code{\VAR{} $v$ = $e_i$;} , \code{$T$ $v $ = $e_i$;} , \code{\FINAL{} $v$ = $e_i$;} or \code{\FINAL{} $T$ $v$ = $e_i$;} and no value has yet been stored into $v$ then the initializer expression $e_i$ is evaluated. If, during the evaluation of $e_i$, the getter for $v$ is referenc ed, a \code{CyclicInitializationError} is thrown. If the evaluation succeeded yi elding an object $o$, let $r = o$, otherwise let $r = \NULL{}$. In any case, $r$ is stored into $v$. The value of $e$ is $r$. | 5293 % \item If $d$ is of one of the forms \code{\VAR{} $v$ = $e_i$;} , \code{$T$ $v $ = $e_i$;} , \code{\FINAL{} $v$ = $e_i$;} or \code{\FINAL{} $T$ $v$ = $e_i$;} and no value has yet been stored into $v$ then the initializer expression $e_i$ is evaluated. If, during the evaluation of $e_i$, the getter for $v$ is referenc ed, a \code{CyclicInitializationError} is thrown. If the evaluation succeeded yi elding an object $o$, let $r = o$, otherwise let $r = \NULL{}$. In any case, $r$ is stored into $v$. The value of $e$ is $r$. |
5281 \item If $d$ is a constant variable of one of the forms \code{\CONST{} $v$ = $e$;} or \code{\CONST{} $T$ $v$ = $e$;} then the value $id$ is the value of the compile-time constant $e$. | 5294 \item If $d$ is a constant variable of one of the forms \code{\CONST{} $v$ = $e$;} or \code{\CONST{} $T$ $v$ = $e$;} then the value $id$ is the value of the compile-time constant $e$. |
5282 % Otherwise | 5295 % Otherwise |
5283 % \item $e$ evaluates to the current binding of $id$. | 5296 % \item $e$ evaluates to the current binding of $id$. |
5284 % \end{itemize} | 5297 % \end{itemize} |
5285 \item If $d$ is a local variable or formal parameter then $e$ evaluates to the c urrent binding of $id$. | 5298 \item If $d$ is a local variable or formal parameter then $e$ evaluates to the c urrent binding of $id$. |
5286 %\item If $d$ is a library variable, local variable, or formal parameter, then $ e$ evaluates to the current binding of $id$. \commentary{This case also applies if d is a library or local function declaration, as these are equivalent to func tion-valued variable declarations.} | 5299 %\item If $d$ is a library variable, local variable, or formal parameter, then $ e$ evaluates to the current binding of $id$. \commentary{This case also applies if d is a library or local function declaration, as these are equivalent to func tion-valued variable declarations.} |
5287 \item If $d$ is a static method, top-level function or local function then $e$ e valuates to the function defined by $d$. | 5300 \item If $d$ is a static method, top-level function or local function then $e$ e valuates to the function defined by $d$. |
5288 \item If $d$ is the declaration of a static variable, static getter or static se tter declared in class $C$, then $e$ is equivalent to the property extraction (\ ref{propertyExtraction}) $C.id$. | 5301 \item If $d$ is the declaration of a static variable, static getter or static se tter declared in class $C$, then $e$ is equivalent to the property extraction (\ ref{propertyExtraction}) $C.id$. |
5289 \item If $d$ is the declaration of a library variable, top-level getter or top-l evel setter, then $e$ is equivalent to the top level getter invocation (\ref{top LevelGetterInvocation}) $id$. | 5302 \item If $d$ is the declaration of a library variable, top-level getter or top-l evel setter, then $e$ is equivalent to the top level getter invocation (\ref{top LevelGetterInvocation}) $id$. |
5290 \item Otherwise, if $e$ occurs inside a top level or static function (be it func tion, method, getter, or setter) or variable initializer, evaluation of $e$ cau ses a \code{NoSuchMethod} to be thrown. | 5303 \item Otherwise, if $e$ occurs inside a top level or static function (be it func tion, method, getter, or setter) or variable initializer, evaluation of $e$ cau ses a \code{NoSuchMethod} to be thrown. |
5291 \item Otherwise, $e$ is equivalent to the property extraction (\ref{propertyExtr action}) \THIS{}.$id$. | 5304 \item Otherwise, $e$ is equivalent to the property extraction (\ref{propertyExtr action}) \THIS{}.$id$. |
5292 % This implies that referring to an undefined static getter by simple name is an error, whereas doing so by qualified name is only a warning. Same with assignme nts. Revise? | 5305 % This implies that referring to an undefined static getter by simple name is an error, whereas doing so by qualified name is only a warning. Same with assignme nts. Revise? |
5293 \end{itemize} | 5306 \end{itemize} |
5294 | 5307 |
5295 \LMHash{} | 5308 \LMHash{} |
5296 The static type of $e$ is determined as follows: | 5309 The static type of $e$ is determined as follows: |
5297 | 5310 |
5298 \begin{itemize} | 5311 \begin{itemize} |
5299 \item If $d$ is a class, type alias or type parameter the static type of $e$ is \code{Type}. | 5312 \item If $d$ is a class, type alias or type parameter the static type of $e$ is \code{Type}. |
5300 \item If $d$ is a local variable or formal parameter the static type of $e$ is t he type of the variable $id$, unless $id$ is known to have some type $T$, in whi ch case the static type of $e$ is $T$, provided that $T$ is more specific than a ny other type $S$ such that $v$ is known to have type $S$. | 5313 \item If $d$ is a local variable or formal parameter the static type of $e$ is t he type of the variable $id$, unless $id$ is known to have some type $T$, in whi ch case the static type of $e$ is $T$, provided that $T$ is more specific than a ny other type $S$ such that $v$ is known to have type $S$. |
5301 \item If $d$ is a static method, top-level function or local function the static type of $e$ is the function type defined by $d$. | 5314 \item If $d$ is a static method, top-level function or local function the static type of $e$ is the function type defined by $d$. |
5302 \item If $d$ is the declaration of a static variable, static getter or static se tter declared in class $C$, the static type of $e$ is the static type of the get ter invocation (\ref{propertyExtraction}) $C.id$. | 5315 \item If $d$ is the declaration of a static variable, static getter or static se tter declared in class $C$, the static type of $e$ is the static type of the get ter invocation (\ref{propertyExtraction}) $C.id$. |
5303 \item If $d$ is the declaration of a library variable, top-level getter or top-l evel setter, the static type of $e$ is the static type of the top level getter invocation $id$. | 5316 \item If $d$ is the declaration of a library variable, top-level getter or top-l evel setter, the static type of $e$ is the static type of the top level getter invocation $id$. |
5304 \item Otherwise, if $e$ occurs inside a top level or static function (be it func tion, method, getter, or setter) or variable initializer, the static type of $e $ is \DYNAMIC{}. | 5317 \item Otherwise, if $e$ occurs inside a top level or static function (be it func tion, method, getter, or setter) or variable initializer, the static type of $e $ is \DYNAMIC{}. |
5305 \item Otherwise, the static type of $e$ is the type of the property extraction ( \ref{propertyExtraction}) \THIS{}.$id$. | 5318 \item Otherwise, the static type of $e$ is the type of the property extraction ( \ref{propertyExtraction}) \THIS{}.$id$. |
5306 \end{itemize} | 5319 \end{itemize} |
5307 | 5320 |
5308 \commentary{Note that if one declares a setter, we bind to the corresponding ge tter even if it does not exist.} | 5321 \commentary{Note that if one declares a setter, we bind to the corresponding ge tter even if it does not exist.} |
5309 | 5322 |
5310 \rationale{ | 5323 \rationale{ |
5311 This prevents situations where one uses uncorrelated setters and getters. The i ntent is to prevent errors when a getter in a surrounding scope is used acciden tally. | 5324 This prevents situations where one uses uncorrelated setters and getters. The i ntent is to prevent errors when a getter in a surrounding scope is used acciden tally. |
5312 } | 5325 } |
5313 | 5326 |
5314 \LMHash{} | 5327 \LMHash{} |
5315 It is a static warning if an identifier expression $id$ occurs inside a top leve l or static function (be it function, method, getter, or setter) or variable ini tializer and there is no declaration $d$ with name $id$ in the lexical scope enc losing the expression. | 5328 It is a static warning if an identifier expression $id$ occurs inside a top leve l or static function (be it function, method, getter, or setter) or variable ini tializer and there is no declaration $d$ with name $id$ in the lexical scope enc losing the expression. |
5316 | 5329 |
5317 \subsection{ Type Test} | 5330 \subsection{ Type Test} |
5318 \LMLabel{typeTest} | 5331 \LMLabel{typeTest} |
5319 | 5332 |
5320 \LMHash{} | 5333 \LMHash{} |
5321 The {\em is-expression} tests if an object is a member of a type. | 5334 The {\em is-expression} tests if an object is a member of a type. |
5322 | 5335 |
5323 \begin{grammar} | 5336 \begin{grammar} |
5324 {\bf typeTest:} | 5337 {\bf typeTest:} |
5325 isOperator type | 5338 isOperator type |
5326 . | 5339 . |
5327 | 5340 |
5328 | 5341 |
5329 {\bf isOperator:} | 5342 {\bf isOperator:} |
5330 \IS{} `!'? | 5343 \IS{} `!'? |
5331 . | 5344 . |
5332 \end{grammar} | 5345 \end{grammar} |
5333 | 5346 |
5334 \LMHash{} | 5347 \LMHash{} |
5335 Evaluation of the is-expression \code{$e$ \IS{} $T$} proceeds as follows: | 5348 Evaluation of the is-expression \code{$e$ \IS{} $T$} proceeds as follows: |
5336 | 5349 |
5337 \LMHash{} | 5350 \LMHash{} |
5338 The expression $e$ is evaluated to a value $v$. Then, if $T$ is a malformed or d eferred type (\ref{staticTypes}), a dynamic error occurs. Otherwise, if the inte rface of the class of $v$ is a subtype of $T$, the is-expression evaluates to \T RUE. Otherwise it evaluates to \FALSE. | 5351 The expression $e$ is evaluated to a value $v$. Then, if $T$ is a malformed or d eferred type (\ref{staticTypes}), a dynamic error occurs. Otherwise, if the inte rface of the class of $v$ is a subtype of $T$, the is-expression evaluates to \T RUE. Otherwise it evaluates to \FALSE. |
5339 | 5352 |
5340 \commentary{It follows that \code{$e$ \IS{} Object} is always true. This makes s ense in a language where everything is an object. | 5353 \commentary{It follows that \code{$e$ \IS{} Object} is always true. This makes s ense in a language where everything is an object. |
5341 | 5354 |
5342 Also note that \code{\NULL{} \IS{} $T$} is false unless $T = \code{Object}$, $T = \code{\DYNAMIC{}}$ or $T = \code{Null}$. The former two are useless, as is an ything of the form \code{$e$ \IS{} Object} or \code{$e$ \IS{} \DYNAMIC{}}. User s should test for a null value directly rather than via type tests. | 5355 Also note that \code{\NULL{} \IS{} $T$} is false unless $T = \code{Object}$, $T = \code{\DYNAMIC{}}$ or $T = \code{Null}$. The former two are useless, as is an ything of the form \code{$e$ \IS{} Object} or \code{$e$ \IS{} \DYNAMIC{}}. User s should test for a null value directly rather than via type tests. |
5343 } | 5356 } |
5344 | 5357 |
5345 \LMHash{} | 5358 \LMHash{} |
5346 The is-expression \code{$e$ \IS{}! $T$} is equivalent to \code{!($e$ \IS{} $T$)} . | 5359 The is-expression \code{$e$ \IS{}! $T$} is equivalent to \code{!($e$ \IS{} $T$)} . |
5347 | 5360 |
5348 % Add flow dependent types | 5361 % Add flow dependent types |
5349 | 5362 |
5350 | 5363 |
5351 \LMHash{} | 5364 \LMHash{} |
5352 Let $v$ be a local variable or a formal parameter. An is-expression of the form \code{$v$ \IS{} $T$} shows that $v$ has type $T$ iff $T$ is more specific than the type $S$ of the expression $v$ and both $T \ne \DYNAMIC{}$ and $S \ne \DYN AMIC{}$. | 5365 Let $v$ be a local variable or a formal parameter. An is-expression of the form \code{$v$ \IS{} $T$} shows that $v$ has type $T$ iff $T$ is more specific than the type $S$ of the expression $v$ and both $T \ne \DYNAMIC{}$ and $S \ne \DYN AMIC{}$. |
5353 | 5366 |
5354 \rationale{ | 5367 \rationale{ |
5355 The motivation for the ``shows that v has type T" relation is to reduce spurious warnings thereby enabling a more natural coding style. The rules in the current specification are deliberately kept simple. It would be upwardly compatible to refine these rules in the future; such a refinement would accept more code witho ut warning, but not reject any code now warning-free. | 5368 The motivation for the ``shows that v has type T" relation is to reduce spurious warnings thereby enabling a more natural coding style. The rules in the current specification are deliberately kept simple. It would be upwardly compatible to refine these rules in the future; such a refinement would accept more code witho ut warning, but not reject any code now warning-free. |
5356 | 5369 |
5357 The rule only applies to locals and parameters, as fields could be modified via side-effecting functions or methods that are not accessible to a local analysis. | 5370 The rule only applies to locals and parameters, as fields could be modified via side-effecting functions or methods that are not accessible to a local analysis. |
5358 | 5371 |
5359 It is pointless to deduce a weaker type than what is already known. Furthermore, this would lead to a situation where multiple types are associated with a varia ble at a given point, which complicates the specification. Hence the requirement that $T << S$ (we use $<<$ rather than subtyping because subtyping is not a par tial order). | 5372 It is pointless to deduce a weaker type than what is already known. Furthermore, this would lead to a situation where multiple types are associated with a varia ble at a given point, which complicates the specification. Hence the requirement that $T << S$ (we use $<<$ rather than subtyping because subtyping is not a par tial order). |
5360 | 5373 |
5361 We do not want to refine the type of a variable of type \DYNAMIC{}, as this coul d lead to more warnings rather than less. The opposite requirement, that $T \ne \DYNAMIC{}$ is a safeguard lest $S$ ever be $\bot$. | 5374 We do not want to refine the type of a variable of type \DYNAMIC{}, as this coul d lead to more warnings rather than less. The opposite requirement, that $T \ne \DYNAMIC{}$ is a safeguard lest $S$ ever be $\bot$. |
5362 } | 5375 } |
5363 | 5376 |
5364 \LMHash{} | 5377 \LMHash{} |
5365 The static type of an is-expression is \code{bool}. | 5378 The static type of an is-expression is \code{bool}. |
5366 | 5379 |
5367 | 5380 |
5368 \subsection{ Type Cast} | 5381 \subsection{ Type Cast} |
5369 \LMLabel{typeCast} | 5382 \LMLabel{typeCast} |
5370 | 5383 |
5371 \LMHash{} | 5384 \LMHash{} |
5372 The {\em cast expression} ensures that an object is a member of a type. | 5385 The {\em cast expression} ensures that an object is a member of a type. |
5373 | 5386 |
5374 \begin{grammar} | 5387 \begin{grammar} |
5375 {\bf typeCast:} | 5388 {\bf typeCast:} |
5376 asOperator type | 5389 asOperator type |
5377 . | 5390 . |
5378 | 5391 |
5379 | 5392 |
5380 {\bf asOperator:} | 5393 {\bf asOperator:} |
5381 \AS{} | 5394 \AS{} |
5382 . | 5395 . |
5383 \end{grammar} | 5396 \end{grammar} |
5384 | 5397 |
5385 \LMHash{} | 5398 \LMHash{} |
5386 Evaluation of the cast expression \code{$e$ \AS{} $T$} proceeds as follows: | 5399 Evaluation of the cast expression \code{$e$ \AS{} $T$} proceeds as follows: |
5387 | 5400 |
5388 \LMHash{} | 5401 \LMHash{} |
5389 The expression $e$ is evaluated to a value $v$. Then, if $T$ is a malformed or d eferred type (\ref{staticTypes}), a dynamic error occurs. Otherwise, if the inte rface of the class of $v$ is a subtype of $T$, the cast expression evaluates to $v$. Otherwise, if $v$ is \NULL{}, the cast expression evaluates to $v$. | 5402 The expression $e$ is evaluated to a value $v$. Then, if $T$ is a malformed or d eferred type (\ref{staticTypes}), a dynamic error occurs. Otherwise, if the inte rface of the class of $v$ is a subtype of $T$, the cast expression evaluates to $v$. Otherwise, if $v$ is \NULL{}, the cast expression evaluates to $v$. |
5390 In all other cases, a \code{CastError} is thrown. | 5403 In all other cases, a \code{CastError} is thrown. |
5391 | 5404 |
5392 \LMHash{} | 5405 \LMHash{} |
5393 The static type of a cast expression \code{$e$ \AS{} $T$} is $T$. | 5406 The static type of a cast expression \code{$e$ \AS{} $T$} is $T$. |
5394 | 5407 |
5395 | 5408 |
5396 \section{Statements} | 5409 \section{Statements} |
5397 \LMLabel{statements} | 5410 \LMLabel{statements} |
5398 | 5411 |
5399 \begin{grammar} | 5412 \begin{grammar} |
5400 {\bf statements:} | 5413 {\bf statements:} |
5401 statement* | 5414 statement* |
5402 . | 5415 . |
5403 | 5416 |
5404 | 5417 |
5405 {\bf statement:} | 5418 {\bf statement:} |
5406 label* nonLabelledStatement | 5419 label* nonLabelledStatement |
5407 . | 5420 . |
5408 | 5421 |
5409 {\bf nonLabelledStatement:}block; | 5422 {\bf nonLabelledStatement:}block; |
5410 localVariableDeclaration; | 5423 localVariableDeclaration; |
5411 forStatement; | 5424 forStatement; |
5412 whileStatement; | 5425 whileStatement; |
5413 doStatement; | 5426 doStatement; |
5414 switchStatement; | 5427 switchStatement; |
5415 ifStatement; | 5428 ifStatement; |
5416 rethrowStatement; | 5429 rethrowStatement; |
5417 tryStatement; | 5430 tryStatement; |
5418 breakStatement; | 5431 breakStatement; |
5419 continueStatement; | 5432 continueStatement; |
5420 returnStatement; | 5433 returnStatement; |
5421 yieldStatement; | 5434 yieldStatement; |
5422 yieldEachStatement; | 5435 yieldEachStatement; |
5423 expressionStatement; | 5436 expressionStatement; |
5424 assertStatement; | 5437 assertStatement; |
5425 localFunctionDeclaration | 5438 localFunctionDeclaration |
5426 . | 5439 . |
5427 \end{grammar} | 5440 \end{grammar} |
5428 | 5441 |
5429 \subsection{Blocks} | 5442 \subsection{Blocks} |
5430 \LMLabel{blocks} | 5443 \LMLabel{blocks} |
5431 | 5444 |
5432 \LMHash{} | 5445 \LMHash{} |
5433 A {\em block statement} supports sequencing of code. | 5446 A {\em block statement} supports sequencing of code. |
5434 | 5447 |
5435 \LMHash{} | 5448 \LMHash{} |
5436 Execution of a block statement $\{s_1, \ldots, s_n\}$ proceeds as follows: | 5449 Execution of a block statement $\{s_1, \ldots, s_n\}$ proceeds as follows: |
5437 | 5450 |
5438 \LMHash{} | 5451 \LMHash{} |
5439 For $i \in 1 .. n, s_i$ is executed. | 5452 For $i \in 1 .. n, s_i$ is executed. |
5440 | 5453 |
5441 \LMHash{} | 5454 \LMHash{} |
5442 A block statement introduces a new scope, which is nested in the lexically enclo sing scope in which the block statement appears. | 5455 A block statement introduces a new scope, which is nested in the lexically enclo sing scope in which the block statement appears. |
5443 | 5456 |
5444 | 5457 |
5445 | 5458 |
5446 \subsection{Expression Statements} | 5459 \subsection{Expression Statements} |
5447 \LMLabel{expressionStatements} | 5460 \LMLabel{expressionStatements} |
5448 | 5461 |
5449 \LMHash{} | 5462 \LMHash{} |
5450 An {\em expression statement} consists of an expression other than a non-constan t map literal (\ref{maps}) that has no explicit type arguments. | 5463 An {\em expression statement} consists of an expression other than a non-constan t map literal (\ref{maps}) that has no explicit type arguments. |
5451 | 5464 |
5452 \rationale{ | 5465 \rationale{ |
5453 The restriction on maps is designed to resolve an ambiguity in the grammar, whe n a statement begins with \{. | 5466 The restriction on maps is designed to resolve an ambiguity in the grammar, whe n a statement begins with \{. |
5454 } | 5467 } |
5455 | 5468 |
5456 \begin{grammar} | 5469 \begin{grammar} |
5457 {\bf expressionStatement:} | 5470 {\bf expressionStatement:} |
5458 expression? `{\escapegrammar ;}' | 5471 expression? `{\escapegrammar ;}' |
5459 . | 5472 . |
5460 \end{grammar} | 5473 \end{grammar} |
5461 | 5474 |
5462 \LMHash{} | 5475 \LMHash{} |
5463 Execution of an expression statement \code{$e$;} proceeds by evaluating $e$. | 5476 Execution of an expression statement \code{$e$;} proceeds by evaluating $e$. |
5464 | 5477 |
5465 \LMHash{} | 5478 \LMHash{} |
5466 It is a compile-time error if a non-constant map literal that has no explicit ty pe arguments appears in a place where a statement is expected. | 5479 It is a compile-time error if a non-constant map literal that has no explicit ty pe arguments appears in a place where a statement is expected. |
5467 | 5480 |
5468 \subsection{Local Variable Declaration} | 5481 \subsection{Local Variable Declaration} |
5469 \LMLabel{localVariableDeclaration} | 5482 \LMLabel{localVariableDeclaration} |
5470 | 5483 |
5471 | 5484 |
5472 \LMHash{} | 5485 \LMHash{} |
5473 A {\em variable declaration statement }declares a new local variable. | 5486 A {\em variable declaration statement }declares a new local variable. |
5474 | 5487 |
5475 \begin{grammar} | 5488 \begin{grammar} |
5476 {\bf localVariableDeclaration:} | 5489 {\bf localVariableDeclaration:} |
5477 initializedVariableDeclaration {\escapegrammar';'} | 5490 initializedVariableDeclaration {\escapegrammar';'} |
5478 . | 5491 . |
5479 \end{grammar} | 5492 \end{grammar} |
5480 | 5493 |
5481 \LMHash{} | 5494 \LMHash{} |
5482 Executing a variable declaration statement of one of the forms \VAR{} $v = e;$ , $T$ $v = e; $, \CONST{} $v = e;$, \CONST{} $T$ $v = e;$, \FINAL{} $v = e;$ o r \FINAL{} $T$ $v = e;$ proceeds as follows: | 5495 Executing a variable declaration statement of one of the forms \VAR{} $v = e;$ , $T$ $v = e; $, \CONST{} $v = e;$, \CONST{} $T$ $v = e;$, \FINAL{} $v = e;$ o r \FINAL{} $T$ $v = e;$ proceeds as follows: |
5483 | 5496 |
5484 \LMHash{} | 5497 \LMHash{} |
5485 The expression $e$ is evaluated to an object $o$. Then, the variable $v$ is set to $o$. | 5498 The expression $e$ is evaluated to an object $o$. Then, the variable $v$ is set to $o$. |
5486 | 5499 |
5487 \LMHash{} | 5500 \LMHash{} |
5488 A variable declaration statement of the form \VAR{} $v;$ is equivalent to \VAR{ } $v = \NULL{};$. A variable declaration statement of the form $T$ $v;$ is equiv alent to $T$ $v = \NULL{};$. | 5501 A variable declaration statement of the form \VAR{} $v;$ is equivalent to \VAR{ } $v = \NULL{};$. A variable declaration statement of the form $T$ $v;$ is equiv alent to $T$ $v = \NULL{};$. |
5489 | 5502 |
5490 \commentary{ | 5503 \commentary{ |
5491 This holds regardless of the type $T$. For example, \code{int i;} does not cause \code{i} to be initialized to zero. Instead, \code{i} is initialized to \NULL{} , just as if we had written \VAR{} \code{i;} or \code{Object i;} or \code{Collec tion$<$String$>$ i;}. | 5504 This holds regardless of the type $T$. For example, \code{int i;} does not cause \code{i} to be initialized to zero. Instead, \code{i} is initialized to \NULL{} , just as if we had written \VAR{} \code{i;} or \code{Object i;} or \code{Collec tion$<$String$>$ i;}. |
5492 } | 5505 } |
5493 | 5506 |
5494 \rationale{ | 5507 \rationale{ |
5495 To do otherwise would undermine the optionally typed nature of Dart, causing typ e annotations to modify program behavior. | 5508 To do otherwise would undermine the optionally typed nature of Dart, causing typ e annotations to modify program behavior. |
5496 } | 5509 } |
5497 | 5510 |
5498 %A variable declaration statement of one of the forms $T$ $v;$, $T$ $v = e;$, \C ONST{} $T$ $v = e;$, or \FINAL{} $T$ $v = e;$ causes a new getter named $v$ wit h static return type $T$ to be added to the innermost enclosing scope at the poi nt following the variable declaration statement. The result of executing this ge tter is the value stored in $v$. | 5511 %A variable declaration statement of one of the forms $T$ $v;$, $T$ $v = e;$, \C ONST{} $T$ $v = e;$, or \FINAL{} $T$ $v = e;$ causes a new getter named $v$ wit h static return type $T$ to be added to the innermost enclosing scope at the poi nt following the variable declaration statement. The result of executing this ge tter is the value stored in $v$. |
5499 | 5512 |
5500 %A variable declaration statement \VAR{} $v;$, \VAR{} $v = e;$, \CONST{} $v = e ;$ or \FINAL{} $v = e;$ causes a new getter named $v$ with static return type \DYNAMIC{} to be added to the innermost enclosing scope at the point following the variable declaration statement. The result of executing this getter is the value stored in $v$. | 5513 %A variable declaration statement \VAR{} $v;$, \VAR{} $v = e;$, \CONST{} $v = e ;$ or \FINAL{} $v = e;$ causes a new getter named $v$ with static return type \DYNAMIC{} to be added to the innermost enclosing scope at the point following the variable declaration statement. The result of executing this getter is the value stored in $v$. |
5501 | 5514 |
5502 %A variable declaration statement of one of the forms $T$ $v;$, or $T$ $v = e;$ causes a new setter named $v=$ with argument type $T$ to be added to the innermo st enclosing scope at the point following the variable declaration statement. Th e effect of executing this setter is to store its argument in $v$. | 5515 %A variable declaration statement of one of the forms $T$ $v;$, or $T$ $v = e;$ causes a new setter named $v=$ with argument type $T$ to be added to the innermo st enclosing scope at the point following the variable declaration statement. Th e effect of executing this setter is to store its argument in $v$. |
5503 | 5516 |
5504 %A variable declaration statement \VAR{} $v;$, \VAR{} $v = e;$, \CONST{} $v = e ;$ or \FINAL{} $v = e;$ causes a new setter named $v=$ with argument type \D YNAMIC{} to be added to the innermost enclosing scope at the point following the variable declaration statement. The effect of executing this setter is to stor e its argument in $v$. | 5517 %A variable declaration statement \VAR{} $v;$, \VAR{} $v = e;$, \CONST{} $v = e ;$ or \FINAL{} $v = e;$ causes a new setter named $v=$ with argument type \D YNAMIC{} to be added to the innermost enclosing scope at the point following the variable declaration statement. The effect of executing this setter is to stor e its argument in $v$. |
5505 | 5518 |
5506 %\rationale{ | 5519 %\rationale{ |
5507 %The use of getters and setters here is a device to help make the specification more uniform. Introducing getters and setters for local variables has no perfor mance consequences, since they can never be overridden, and so can always be opt imized away. It is not possible to declare a local getter or setter explicitly, since there is little reason to ever do so. | 5520 %The use of getters and setters here is a device to help make the specification more uniform. Introducing getters and setters for local variables has no perfor mance consequences, since they can never be overridden, and so can always be opt imized away. It is not possible to declare a local getter or setter explicitly, since there is little reason to ever do so. |
5508 %} | 5521 %} |
5509 | 5522 |
5510 | 5523 |
5511 \subsection{Local Function Declaration} | 5524 \subsection{Local Function Declaration} |
5512 \LMLabel{localFunctionDeclaration} | 5525 \LMLabel{localFunctionDeclaration} |
5513 | 5526 |
5514 \LMHash{} | 5527 \LMHash{} |
5515 A function declaration statement declares a new local function (\ref{functionDec larations}). | 5528 A function declaration statement declares a new local function (\ref{functionDec larations}). |
5516 | 5529 |
5517 \begin{grammar} | 5530 \begin{grammar} |
5518 {\bf localFunctionDeclaration:} | 5531 {\bf localFunctionDeclaration:} |
5519 functionSignature functionBody | 5532 functionSignature functionBody |
5520 . | 5533 . |
5521 \end{grammar} | 5534 \end{grammar} |
5522 | 5535 |
5523 \LMHash{} | 5536 \LMHash{} |
5524 A function declaration statement of one of the forms $id$ $signature$ $\{ statem ents \}$ or $T$ $id$ $signature$ $\{ statements \}$ causes a new function named $id$ to be added to the innermost enclosing scope. It is a compile-time error to reference a local function before its declaration. | 5537 A function declaration statement of one of the forms $id$ $signature$ $\{ statem ents \}$ or $T$ $id$ $signature$ $\{ statements \}$ causes a new function named $id$ to be added to the innermost enclosing scope. It is a compile-time error to reference a local function before its declaration. |
5525 | 5538 |
5526 | 5539 |
5527 \commentary{ This implies that local functions can be directly recursive, but no t mutually recursive. Consider these examples: | 5540 \commentary{ This implies that local functions can be directly recursive, but no t mutually recursive. Consider these examples: |
5528 } | 5541 } |
5529 | 5542 |
5530 \begin{dartCode} | 5543 \begin{dartCode} |
5531 f(x) =$>$ x++; // a top level function | 5544 f(x) =$>$ x++; // a top level function |
5532 top() \{ // another top level function | 5545 top() \{ // another top level function |
5533 f(3); // illegal | 5546 f(3); // illegal |
5534 f(x) $=>$ x $>$ 0? x*f(x-1): 1; // recursion is legal | 5547 f(x) $=>$ x $>$ 0? x*f(x-1): 1; // recursion is legal |
5535 g1(x) $=>$ h(x, 1); // error: h is not declared yet | 5548 g1(x) $=>$ h(x, 1); // error: h is not declared yet |
5536 h(x, n) $=>$ x $>$ 1? h(x-1, n*x): n; // again, recursion is fine | 5549 h(x, n) $=>$ x $>$ 1? h(x-1, n*x): n; // again, recursion is fine |
5537 g2(x) $=>$ h(x, 1); // legal | 5550 g2(x) $=>$ h(x, 1); // legal |
5538 | 5551 |
5539 p1(x) $=>$ q(x,x); // illegal | 5552 p1(x) $=>$ q(x,x); // illegal |
5540 q1(a, b)$ =>$ a $>$ 0 ? p1(a-1): b; // fine | 5553 q1(a, b)$ =>$ a $>$ 0 ? p1(a-1): b; // fine |
5541 | 5554 |
5542 q2(a, b) $=>$ a $>$ 0 ? p2(a-1): b; // illegal | 5555 q2(a, b) $=>$ a $>$ 0 ? p2(a-1): b; // illegal |
5543 p1(x) $=>$ q2(x,x); // fine | 5556 p1(x) $=>$ q2(x,x); // fine |
5544 \} | 5557 \} |
5545 \end{dartCode} | 5558 \end{dartCode} |
5546 | 5559 |
5547 \commentary{ | 5560 \commentary{ |
5548 There is no way to write a pair of mutually recursive local functions, because o ne always has to come before the other is declared. These cases are quite rare, and can always be managed by defining a pair of variables first, then assigning them appropriate closures: | 5561 There is no way to write a pair of mutually recursive local functions, because o ne always has to come before the other is declared. These cases are quite rare, and can always be managed by defining a pair of variables first, then assigning them appropriate closures: |
5549 } | 5562 } |
5550 | 5563 |
5551 \begin{dartCode} | 5564 \begin{dartCode} |
5552 top2() \{ // a top level function | 5565 top2() \{ // a top level function |
5553 \VAR{} p, q; | 5566 \VAR{} p, q; |
5554 p = (x) $=>$ q(x,x); | 5567 p = (x) $=>$ q(x,x); |
5555 q = (a, b) $=>$ a $>$ 0 ? p(a-1): b; | 5568 q = (a, b) $=>$ a $>$ 0 ? p(a-1): b; |
5556 | 5569 |
5557 \} | 5570 \} |
5558 \end{dartCode} | 5571 \end{dartCode} |
5559 | 5572 |
5560 \rationale{ | 5573 \rationale{ |
5561 The rules for local functions differ slightly from those for local variables in that a function can be accessed within its declaration but a variable can only be accessed after its declaration. This is because recursive functions are usefu l whereas recursively defined variables are almost always errors. It therefore makes sense to harmonize the rules for local functions with those for functions in general rather than with the rules for local variables. | 5574 The rules for local functions differ slightly from those for local variables in that a function can be accessed within its declaration but a variable can only be accessed after its declaration. This is because recursive functions are usefu l whereas recursively defined variables are almost always errors. It therefore makes sense to harmonize the rules for local functions with those for functions in general rather than with the rules for local variables. |
5562 } | 5575 } |
5563 | 5576 |
5564 % elaborate on function identity and equality, runtime type. Likewsie in functio n expressions (closures) and declarations | 5577 % elaborate on function identity and equality, runtime type. Likewsie in functio n expressions (closures) and declarations |
5565 | 5578 |
5566 \subsection{If} | 5579 \subsection{If} |
5567 \LMLabel{if} | 5580 \LMLabel{if} |
5568 | 5581 |
5569 \LMHash{} | 5582 \LMHash{} |
5570 The {\em if statement} allows for conditional execution of statements. | 5583 The {\em if statement} allows for conditional execution of statements. |
5571 | 5584 |
5572 \begin{grammar} | 5585 \begin{grammar} |
5573 {\bf ifStatement:} | 5586 {\bf ifStatement:} |
5574 \IF{} `(' expression `)' statement ( \ELSE{} statement)? % we could allow top level expression | 5587 \IF{} `(' expression `)' statement ( \ELSE{} statement)? % we could allow top level expression |
5575 . | 5588 . |
5576 \end{grammar} | 5589 \end{grammar} |
5577 | 5590 |
5578 Execution of an if statement of the form \code {\IF{} (}$b$\code{)}$s_1$ \code{ \ELSE{} } $s_2$ proceeds as follows: | 5591 Execution of an if statement of the form \code {\IF{} (}$b$\code{)}$s_1$ \code{ \ELSE{} } $s_2$ proceeds as follows: |
5579 | 5592 |
5580 \LMHash{} | 5593 \LMHash{} |
5581 First, the expression $b$ is evaluated to an object $o$. Then, $o$ is subjecte d to boolean conversion (\ref{booleanConversion}), producing an object $r$. If $ r$ is \TRUE{}, then the statement $\{s_1\}$ is executed, otherwise statement $\{ s_2\}$ is executed. | 5594 First, the expression $b$ is evaluated to an object $o$. Then, $o$ is subjecte d to boolean conversion (\ref{booleanConversion}), producing an object $r$. If $ r$ is \TRUE{}, then the statement $\{s_1\}$ is executed, otherwise statement $\{ s_2\}$ is executed. |
5582 | 5595 |
5583 | 5596 |
5584 \commentary { | 5597 \commentary { |
5585 Put another way, \code {\IF{} (}$b$\code{)}$s_1$ \code{\ELSE{} } $s_2$ is equiv alent to | 5598 Put another way, \code {\IF{} (}$b$\code{)}$s_1$ \code{\ELSE{} } $s_2$ is equiv alent to |
5586 \code {\IF{} (}$b$\code{)}$\{s_1\}$ \code{\ELSE{} } $\{s_2\}$ | 5599 \code {\IF{} (}$b$\code{)}$\{s_1\}$ \code{\ELSE{} } $\{s_2\}$ |
5587 } | 5600 } |
5588 | 5601 |
5589 \rationale { | 5602 \rationale { |
5590 The reason for this equivalence is to catch errors such as | 5603 The reason for this equivalence is to catch errors such as |
5591 } | 5604 } |
5592 \begin{dartCode} | 5605 \begin{dartCode} |
5593 \VOID{} main() \{ | 5606 \VOID{} main() \{ |
5594 \IF{} (somePredicate) | 5607 \IF{} (somePredicate) |
5595 \VAR{} v = 2; | 5608 \VAR{} v = 2; |
5596 print(v); | 5609 print(v); |
5597 \} | 5610 \} |
5598 \end{dartCode} | 5611 \end{dartCode} |
5599 | 5612 |
5600 \rationale { | 5613 \rationale { |
5601 Under reasonable scope rules such code is problematic. If we assume that \code{ v} is declared in the scope of the method \code{main()}, then when \code{somePre dicate} is false, \code{v} will be uninitialized when accessed. The cleanest ap proach would be to require a block following the test, rather than an arbitrary statement. However, this goes against long standing custom, undermining Dart's g oal of familiarity. Instead, we choose to insert a block, introducing a scope, around the statement following the predicate (and similarly for \ELSE{} and loo ps). This will cause both a warning and a runtime error in the case above. Of c ourse, if there is a declaration of \code{v} in the surrounding scope, programme rs might still be surprised. We expect tools to highlight cases of shadowing to help avoid such situations. | 5614 Under reasonable scope rules such code is problematic. If we assume that \code{ v} is declared in the scope of the method \code{main()}, then when \code{somePre dicate} is false, \code{v} will be uninitialized when accessed. The cleanest ap proach would be to require a block following the test, rather than an arbitrary statement. However, this goes against long standing custom, undermining Dart's g oal of familiarity. Instead, we choose to insert a block, introducing a scope, around the statement following the predicate (and similarly for \ELSE{} and loo ps). This will cause both a warning and a runtime error in the case above. Of c ourse, if there is a declaration of \code{v} in the surrounding scope, programme rs might still be surprised. We expect tools to highlight cases of shadowing to help avoid such situations. |
5602 } | 5615 } |
5603 | 5616 |
5604 \LMHash{} | 5617 \LMHash{} |
5605 It is a static type warning if the type of the expression $b$ may not be assig ned to \code{bool}. | 5618 It is a static type warning if the type of the expression $b$ may not be assig ned to \code{bool}. |
5606 | 5619 |
5607 \LMHash{} | 5620 \LMHash{} |
5608 If: | 5621 If: |
5609 \begin{itemize} | 5622 \begin{itemize} |
5610 \item $b$ shows that a variable $v$ has type $T$. | 5623 \item $b$ shows that a variable $v$ has type $T$. |
5611 \item $v$ is not potentially mutated in $s_1$ or within a closure. | 5624 \item $v$ is not potentially mutated in $s_1$ or within a closure. |
5612 \item If the variable $v$ is accessed by a closure in $s_1$ then the variable $v $ is not potentially mutated anywhere in the scope of $v$. | 5625 \item If the variable $v$ is accessed by a closure in $s_1$ then the variable $v $ is not potentially mutated anywhere in the scope of $v$. |
5613 \end{itemize} | 5626 \end{itemize} |
5614 then the type of $v$ is known to be $T$ in $s_1$. | 5627 then the type of $v$ is known to be $T$ in $s_1$. |
5615 | 5628 |
5616 \LMHash{} | 5629 \LMHash{} |
5617 An if statement of the form \code {\IF{} (}$b$\code{)}$s_1$ is equivalent to t he if statement | 5630 An if statement of the form \code {\IF{} (}$b$\code{)}$s_1$ is equivalent to t he if statement |
5618 | 5631 |
5619 \code {\IF{} (}$b$\code{)}$s_1$ \code{\ELSE{} \{\}}. | 5632 \code {\IF{} (}$b$\code{)}$s_1$ \code{\ELSE{} \{\}}. |
5620 | |
5621 | 5633 |
5622 | 5634 |
5635 | |
5623 \subsection{For} | 5636 \subsection{For} |
5624 \LMLabel{for} | 5637 \LMLabel{for} |
5625 | 5638 |
5626 \LMHash{} | 5639 \LMHash{} |
5627 The {\em for statement} supports iteration. | 5640 The {\em for statement} supports iteration. |
5628 | 5641 |
5629 \begin{grammar} | 5642 \begin{grammar} |
5630 {\bf forStatement:} | 5643 {\bf forStatement:} |
5631 \AWAIT? \FOR{} `(' forLoopParts `)' statement | 5644 \AWAIT? \FOR{} `(' forLoopParts `)' statement |
5632 . | 5645 . |
5633 | 5646 |
5634 {\bf forLoopParts:}forInitializerStatement expression? `{\escapegrammar ;}' expr essionList?; | 5647 {\bf forLoopParts:}forInitializerStatement expression? `{\escapegrammar ;}' expr essionList?; |
5635 declaredIdentifier \IN{} expression; | 5648 declaredIdentifier \IN{} expression; |
5636 identifier \IN{} expression | 5649 identifier \IN{} expression |
5637 . | 5650 . |
5638 | 5651 |
5639 {\bf forInitializerStatement:}localVariableDeclaration; | 5652 {\bf forInitializerStatement:}localVariableDeclaration; |
5640 expression? `{\escapegrammar ;}' | 5653 expression? `{\escapegrammar ;}' |
5641 . | 5654 . |
5642 \end{grammar} | 5655 \end{grammar} |
5643 | 5656 |
5644 \LMHash{} | 5657 \LMHash{} |
5645 The for statement has three forms - the traditional for loop and two forms of t he for-in statement - synchronous and asynchronous. | 5658 The for statement has three forms - the traditional for loop and two forms of t he for-in statement - synchronous and asynchronous. |
5646 | 5659 |
5647 \subsubsection{For Loop} | 5660 \subsubsection{For Loop} |
5648 \LMLabel{forLoop} | 5661 \LMLabel{forLoop} |
5649 | 5662 |
5650 | 5663 |
5651 \LMHash{} | 5664 \LMHash{} |
5652 Execution of a for statement of the form \code{ \FOR{} (\VAR{} $v = e_0$ ; $c$ ; $e$) $s$} proceeds as follows: | 5665 Execution of a for statement of the form \code{ \FOR{} (\VAR{} $v = e_0$ ; $c$ ; $e$) $s$} proceeds as follows: |
5653 | 5666 |
5654 \LMHash{} | 5667 \LMHash{} |
5655 If $c$ is empty then let $c^\prime$ be \TRUE{} otherwise let $c^\prime$ be $c$. | 5668 If $c$ is empty then let $c^\prime$ be \TRUE{} otherwise let $c^\prime$ be $c$. |
5656 | 5669 |
5657 \LMHash{} | 5670 \LMHash{} |
5658 First the variable declaration statement \VAR{} $v = e_0$ is executed. Then: | 5671 First the variable declaration statement \VAR{} $v = e_0$ is executed. Then: |
5659 \begin{enumerate} | 5672 \begin{enumerate} |
5660 \item | 5673 \item |
5661 \label{beginFor} | 5674 \label{beginFor} |
5662 If this is the first iteration of the for loop, let $v^\prime$ be $v$. Otherwise , let $v^\prime$ be the variable $v^{\prime\prime}$ created in the previous exe cution of step \ref{allocateFreshVar}. | 5675 If this is the first iteration of the for loop, let $v^\prime$ be $v$. Otherwise , let $v^\prime$ be the variable $v^{\prime\prime}$ created in the previous exe cution of step \ref{allocateFreshVar}. |
5663 \item | 5676 \item |
5664 The expression $[v^\prime/v]c$ is evaluated and subjected to boolean conversion (\ref{booleans}). If the result is \FALSE{}, the for loop completes. Otherwise, execution continues at step | 5677 The expression $[v^\prime/v]c$ is evaluated and subjected to boolean conversion (\ref{booleans}). If the result is \FALSE{}, the for loop completes. Otherwise, execution continues at step |
5665 \ref{beginIteration}. | 5678 \ref{beginIteration}. |
5666 \item | 5679 \item |
5667 \label{beginIteration} | 5680 \label{beginIteration} |
5668 The statement $[v^\prime/v]\{s\}$ is executed. | 5681 The statement $[v^\prime/v]\{s\}$ is executed. |
5669 \item | 5682 \item |
5670 \label{allocateFreshVar} | 5683 \label{allocateFreshVar} |
5671 Let $v^{\prime\prime}$ be a fresh variable. $v^{\prime\prime}$ is bound to the value of $v^\prime$. | 5684 Let $v^{\prime\prime}$ be a fresh variable. $v^{\prime\prime}$ is bound to the value of $v^\prime$. |
5672 \item | 5685 \item |
5673 The expression $[v^{\prime\prime}/v]e$ is evaluated, and the process recurses at step | 5686 The expression $[v^{\prime\prime}/v]e$ is evaluated, and the process recurses at step |
5674 \ref{beginFor}. | 5687 \ref{beginFor}. |
(...skipping 17 matching lines...) Expand all Loading... | |
5692 % $e$; | 5705 % $e$; |
5693 %\}\} | 5706 %\}\} |
5694 %} | 5707 %} |
5695 | 5708 |
5696 %If $c$ is empty, it is interpreted as \TRUE{}. | 5709 %If $c$ is empty, it is interpreted as \TRUE{}. |
5697 | 5710 |
5698 \subsubsection{For-in} | 5711 \subsubsection{For-in} |
5699 \LMLabel{for-in} | 5712 \LMLabel{for-in} |
5700 | 5713 |
5701 \LMHash{} | 5714 \LMHash{} |
5702 A for statement of the form \code{ \FOR{} ($finalConstVarOrType?$ id \IN{} $e$) $s$} is equivalent to the following code: | 5715 A for statement of the form \code{ \FOR{} ($finalConstVarOrType?$ id \IN{} $e$) $s$} is equivalent to the following code: |
5703 | 5716 |
5704 \begin{dartCode} | 5717 \begin{dartCode} |
5705 var n0 = $e$.iterator; | 5718 var n0 = $e$.iterator; |
5706 \WHILE{} (n0.moveNext()) \{ | 5719 \WHILE{} (n0.moveNext()) \{ |
5707 $finalConstVarOrType?$ id = n0.current; | 5720 $finalConstVarOrType?$ id = n0.current; |
5708 $s$ | 5721 $s$ |
5709 \} | 5722 \} |
5710 \end{dartCode} | 5723 \end{dartCode} |
5711 where \code{n0} is an identifier that does not occur anywhere in the program, ex cept that for purposes of static typechecking, it is checked under the assumptio n that $n0$ is declared to be of type $T$, where $T$ is the static type of $e.it erator$. | 5724 where \code{n0} is an identifier that does not occur anywhere in the program, ex cept that for purposes of static typechecking, it is checked under the assumptio n that $n0$ is declared to be of type $T$, where $T$ is the static type of $e.it erator$. |
5712 | 5725 |
5713 | 5726 |
5714 | 5727 |
5715 \subsubsection{Asynchronous For-in} | 5728 \subsubsection{Asynchronous For-in} |
5716 \LMLabel{asynchronousFor-in} | 5729 \LMLabel{asynchronousFor-in} |
5717 | 5730 |
5718 \LMHash{} | 5731 \LMHash{} |
5719 A for-in statement may be asynchronous. The asynchronous form is designed to ite rate over streams. An asynchronous for loop is distinguished by the keyword \AWA IT{} immediately preceding the keyword \FOR. | 5732 A for-in statement may be asynchronous. The asynchronous form is designed to ite rate over streams. An asynchronous for loop is distinguished by the keyword \AWA IT{} immediately preceding the keyword \FOR. |
5720 | 5733 |
5721 \LMHash{} | 5734 \LMHash{} |
5722 Execution of a for-in statement of the form \code{\AWAIT{} \FOR{} (finalConstVa rOrType? id \IN{} $e$) $s$} proceeds as follows: | 5735 Execution of a for-in statement of the form \code{\AWAIT{} \FOR{} (finalConstVa rOrType? id \IN{} $e$) $s$} proceeds as follows: |
5723 | 5736 |
5724 \LMHash{} | 5737 \LMHash{} |
5725 The expression $e$ is evaluated to an object $o$. It is a dynamic error if $o$ i s not an instance of a class that implements \code{Stream}. Otherwise, the expre ssion \code{\AWAIT{} $v_f$} (\ref{awaitExpressions}) is evaluated, where $v_f$ is a fresh variable whose value is a fresh instance (\ref{generativeConstructors }) $f$ implementing the built-in class \code{Future}. | 5738 The expression $e$ is evaluated to an object $o$. It is a dynamic error if $o$ i s not an instance of a class that implements \code{Stream}. Otherwise, the expre ssion \code{\AWAIT{} $v_f$} (\ref{awaitExpressions}) is evaluated, where $v_f$ is a fresh variable whose value is a fresh instance (\ref{generativeConstructors }) $f$ implementing the built-in class \code{Future}. |
5726 | 5739 |
5727 \LMHash{} | 5740 \LMHash{} |
5728 The stream $o$ is listened to, and on each data event in $o$ the statement $s$ is executed with \code{id} bound to the value of the current element of the stre am. If $s$ raises an exception, or if $o$ raises an exception, then $f$ is compl eted with that exception. Otherwise, when all events in the stream $o$ have been processed, $f$ is completed with \NULL{} (\ref{null}). | 5741 The stream $o$ is listened to, and on each data event in $o$ the statement $s$ is executed with \code{id} bound to the value of the current element of the stre am. If $s$ raises an exception, or if $o$ raises an exception, then $f$ is compl eted with that exception. Otherwise, when all events in the stream $o$ have been processed, $f$ is completed with \NULL{} (\ref{null}). |
5729 | 5742 |
5730 \LMHash{} | 5743 \LMHash{} |
5731 Let $u$ be the stream associated with the immediately enclosing asynchronous for loop or generator function (\ref{functions}), if any. If another event $e_u$ of $u$ occurs before execution of $s$ is complete, handling of $e_u$ must wait unt il $s$ is complete. | 5744 Let $u$ be the stream associated with the immediately enclosing asynchronous for loop or generator function (\ref{functions}), if any. If another event $e_u$ of $u$ occurs before execution of $s$ is complete, handling of $e_u$ must wait unt il $s$ is complete. |
5732 | 5745 |
5733 \rationale{ | 5746 \rationale{ |
5734 The future $f$ and the corresponding \AWAIT{} expression ensure that execution s uspends as an asynchronous for loop begins and resumes after the \FOR{} statemen t when it ends. They also ensure that the stream of any enclosing asynchronous \ FOR{} loop is paused for the duration of this loop. | 5747 The future $f$ and the corresponding \AWAIT{} expression ensure that execution s uspends as an asynchronous for loop begins and resumes after the \FOR{} statemen t when it ends. They also ensure that the stream of any enclosing asynchronous \ FOR{} loop is paused for the duration of this loop. |
5735 } | 5748 } |
5736 | 5749 |
5737 \LMHash{} | 5750 \LMHash{} |
5738 It is a compile-time error if an asynchronous for-in statement appears inside a synchronous function (\ref{functions}). It is a compile-time error if a traditio nal for loop (\ref{forLoop}) is prefixed by the \AWAIT{} keyword. | 5751 It is a compile-time error if an asynchronous for-in statement appears inside a synchronous function (\ref{functions}). It is a compile-time error if a traditio nal for loop (\ref{forLoop}) is prefixed by the \AWAIT{} keyword. |
5739 | 5752 |
5740 \rationale{An asynchronous loop would make no sense within a synchronous functio n, for the same reasons that an await expression makes no sense in a synchronous function.} | 5753 \rationale{An asynchronous loop would make no sense within a synchronous functio n, for the same reasons that an await expression makes no sense in a synchronous function.} |
5741 | 5754 |
5742 | 5755 |
5743 \subsection{While} | 5756 \subsection{While} |
5744 \LMLabel{while} | 5757 \LMLabel{while} |
5745 | 5758 |
5746 \LMHash{} | 5759 \LMHash{} |
5747 The while statement supports conditional iteration, where the condition is evalu ated prior to the loop. | 5760 The while statement supports conditional iteration, where the condition is evalu ated prior to the loop. |
5748 | 5761 |
5749 \begin{grammar} | 5762 \begin{grammar} |
5750 {\bf whileStatement:} | 5763 {\bf whileStatement:} |
5751 \WHILE{} `(' expression `)' statement % could do top level here, and in f or | 5764 \WHILE{} `(' expression `)' statement % could do top level here, and in f or |
5752 . | 5765 . |
5753 \end{grammar} | 5766 \end{grammar} |
5754 | 5767 |
5755 \LMHash{} | 5768 \LMHash{} |
5756 Execution of a while statement of the form \code{\WHILE{} ($e$) $s$;} proceeds as follows: | 5769 Execution of a while statement of the form \code{\WHILE{} ($e$) $s$;} proceeds as follows: |
5757 | 5770 |
5758 \LMHash{} | 5771 \LMHash{} |
5759 The expression $e$ is evaluated to an object $o$. Then, $o$ is subjected to boo lean conversion (\ref{booleanConversion}), producing an object $r$. If $r$ is \ TRUE{}, then the statement $\{s\}$ is executed and then the while statement is r e-executed recursively. If $r$ is \FALSE{}, execution of the while statement is complete. | 5772 The expression $e$ is evaluated to an object $o$. Then, $o$ is subjected to boo lean conversion (\ref{booleanConversion}), producing an object $r$. If $r$ is \ TRUE{}, then the statement $\{s\}$ is executed and then the while statement is r e-executed recursively. If $r$ is \FALSE{}, execution of the while statement is complete. |
5760 | 5773 |
5761 \LMHash{} | 5774 \LMHash{} |
5762 It is a static type warning if the static type of $e$ may not be assigned to \co de{bool}. | 5775 It is a static type warning if the static type of $e$ may not be assigned to \co de{bool}. |
5763 | 5776 |
5764 | 5777 |
5765 \subsection{Do} | 5778 \subsection{Do} |
5766 \LMLabel{do} | 5779 \LMLabel{do} |
5767 | 5780 |
5768 \LMHash{} | 5781 \LMHash{} |
5769 The do statement supports conditional iteration, where the condition is evaluate d after the loop. | 5782 The do statement supports conditional iteration, where the condition is evaluate d after the loop. |
5770 | 5783 |
5771 \begin{grammar} | 5784 \begin{grammar} |
5772 {\bf doStatement:} | 5785 {\bf doStatement:} |
5773 \DO{} statement \WHILE{} `(' expression `)' `{\escapegrammar ;}'% could do t op level here | 5786 \DO{} statement \WHILE{} `(' expression `)' `{\escapegrammar ;}'% could do t op level here |
5774 . | 5787 . |
5775 \end{grammar} | 5788 \end{grammar} |
5776 | 5789 |
5777 | |
5778 \LMHash{} | |
5779 Execution of a do statement of the form \code{\DO{} $s$ \WHILE{} ($e$);} proceed s as follows: | |
5780 | 5790 |
5781 \LMHash{} | 5791 \LMHash{} |
5782 The statement $\{s\}$ is executed. Then, the expression $e$ is evaluated to an o bject $o$. Then, $o$ is subjected to boolean conversion (\ref{booleanConversion }), producing an object $r$. If $r$ is \FALSE{}, execution of the do statement i s complete. If $r$ is \TRUE{}, then the do statement is re-executed recursively. | 5792 Execution of a do statement of the form \code{\DO{} $s$ \WHILE{} ($e$);} proceed s as follows: |
5783 | 5793 |
5784 \LMHash{} | 5794 \LMHash{} |
5785 It is a static type warning if the static type of $e$ may not be assigned to \co de{bool}. | 5795 The statement $\{s\}$ is executed. Then, the expression $e$ is evaluated to an o bject $o$. Then, $o$ is subjected to boolean conversion (\ref{booleanConversion }), producing an object $r$. If $r$ is \FALSE{}, execution of the do statement i s complete. If $r$ is \TRUE{}, then the do statement is re-executed recursively. |
5796 | |
5797 \LMHash{} | |
5798 It is a static type warning if the static type of $e$ may not be assigned to \co de{bool}. | |
5786 | 5799 |
5787 \subsection{Switch} | 5800 \subsection{Switch} |
5788 \LMLabel{switch} | 5801 \LMLabel{switch} |
5789 | 5802 |
5790 \LMHash{} | 5803 \LMHash{} |
5791 The {\em switch statement} supports dispatching control among a large number of cases. | 5804 The {\em switch statement} supports dispatching control among a large number of cases. |
5792 | 5805 |
5793 \begin{grammar} | 5806 \begin{grammar} |
5794 {\bf switchStatement:} | 5807 {\bf switchStatement:} |
5795 \SWITCH{} `(' expression `)' `\{' switchCase* defaultCase? `\}'% could do top level here and in cases | 5808 \SWITCH{} `(' expression `)' `\{' switchCase* defaultCase? `\}'% could do top level here and in cases |
5796 . | 5809 . |
5797 | 5810 |
5798 | 5811 |
5799 {\bf switchCase:} | 5812 {\bf switchCase:} |
5800 label* \CASE{} expression `{\escapegrammar :}' statements | 5813 label* \CASE{} expression `{\escapegrammar :}' statements |
5801 . | 5814 . |
5802 | 5815 |
5803 {\bf defaultCase:} | 5816 {\bf defaultCase:} |
5804 label* \DEFAULT{} `{\escapegrammar :}' statements | 5817 label* \DEFAULT{} `{\escapegrammar :}' statements |
5805 . | 5818 . |
5806 \end{grammar} | 5819 \end{grammar} |
5807 | 5820 |
5808 \LMHash{} | 5821 \LMHash{} |
5809 Given a switch statement of the form | 5822 Given a switch statement of the form |
5810 | 5823 |
5811 \begin{dartCode} | 5824 \begin{dartCode} |
5812 \SWITCH{} ($e$) \{ | 5825 \SWITCH{} ($e$) \{ |
5813 $label_{11} \ldots label_{1j_1}$ \CASE{} $e_1: s_1$ | 5826 $label_{11} \ldots label_{1j_1}$ \CASE{} $e_1: s_1$ |
5814 $\ldots$ | 5827 $\ldots$ |
5815 $label_{n1} \ldots label_{nj_n}$ \CASE{} $e_n: s_n$ | 5828 $label_{n1} \ldots label_{nj_n}$ \CASE{} $e_n: s_n$ |
5816 $label_{(n+1)1} \ldots label_{(n+1)j_{n+1}}$ \DEFAULT{}: $s_{n+1}$ | 5829 $label_{(n+1)1} \ldots label_{(n+1)j_{n+1}}$ \DEFAULT{}: $s_{n+1}$ |
5817 \} | 5830 \} |
5818 \end{dartCode} | 5831 \end{dartCode} |
5819 | 5832 |
5820 or the form | 5833 or the form |
5821 | 5834 |
5822 \begin{dartCode} | 5835 \begin{dartCode} |
5823 \SWITCH{} ($e$) \{ | 5836 \SWITCH{} ($e$) \{ |
5824 $label_{11} \ldots label_{1j_1}$ \CASE{} $e_1: s_1$ | 5837 $label_{11} \ldots label_{1j_1}$ \CASE{} $e_1: s_1$ |
5825 $\ldots$ | 5838 $\ldots$ |
5826 $label_{n1} \ldots label_{nj_n}$ \CASE{} $e_n: s_n$ | 5839 $label_{n1} \ldots label_{nj_n}$ \CASE{} $e_n: s_n$ |
5827 \} | 5840 \} |
5828 \end{dartCode} | 5841 \end{dartCode} |
5829 | 5842 |
5830 it is a compile-time error if the expressions $e_k$ are not compile-time consta nts for all $k \in 1..n$. It is a compile-time error if the values of the expr essions $e_k$ are not either: | 5843 it is a compile-time error if the expressions $e_k$ are not compile-time consta nts for all $k \in 1..n$. It is a compile-time error if the values of the expr essions $e_k$ are not either: |
5831 \begin{itemize} | 5844 \begin{itemize} |
5832 \item instances of the same class $C$, for all $k \in 1..n$, or | 5845 \item instances of the same class $C$, for all $k \in 1..n$, or |
5833 \item instances of a class that implements \cd{int}, for all $k \in 1..n$, or | 5846 \item instances of a class that implements \cd{int}, for all $k \in 1..n$, or |
5834 \item instances of a class that implements \cd{String}, for all $k \in 1..n$. | 5847 \item instances of a class that implements \cd{String}, for all $k \in 1..n$. |
5835 \end{itemize} | 5848 \end{itemize} |
5836 | 5849 |
5837 \commentary{In other words, all the expressions in the cases evaluate to consta nts of the exact same user defined class or are of certain known types. Note th at the values of the expressions are known at compile-time, and are independent of any static type annotations. | 5850 \commentary{In other words, all the expressions in the cases evaluate to consta nts of the exact same user defined class or are of certain known types. Note th at the values of the expressions are known at compile-time, and are independent of any static type annotations. |
5838 } | 5851 } |
5839 | 5852 |
5840 \LMHash{} | 5853 \LMHash{} |
5841 It is a compile-time error if the class $C$ has an implementation of the operato r $==$ other than the one inherited from \code{Object} unless the value of the e xpression is a string, an integer, literal symbol or the result of invoking a co nstant constructor of class \cd{Symbol}. | 5854 It is a compile-time error if the class $C$ has an implementation of the operato r $==$ other than the one inherited from \code{Object} unless the value of the e xpression is a string, an integer, literal symbol or the result of invoking a co nstant constructor of class \cd{Symbol}. |
5842 | 5855 |
5843 \rationale{ | 5856 \rationale{ |
5844 The prohibition on user defined equality allows us to implement the switch effi ciently for user defined types. We could formulate matching in terms of identity instead with the same efficiency. However, if a type defines an equality operat or, programmers would find it quite surprising that equal objects did not match. | 5857 The prohibition on user defined equality allows us to implement the switch effi ciently for user defined types. We could formulate matching in terms of identity instead with the same efficiency. However, if a type defines an equality operat or, programmers would find it quite surprising that equal objects did not match. |
5845 | 5858 |
5846 } | 5859 } |
5847 | 5860 |
5848 \commentary{ | 5861 \commentary{ |
5849 The \SWITCH{} statement should only be used in very limited situations (e.g., i nterpreters or scanners). | 5862 The \SWITCH{} statement should only be used in very limited situations (e.g., i nterpreters or scanners). |
5850 } | 5863 } |
5851 | 5864 |
5852 \LMHash{} | 5865 \LMHash{} |
5853 Execution of a switch statement of the form | 5866 Execution of a switch statement of the form |
5854 | 5867 |
5855 \begin{dartCode} | 5868 \begin{dartCode} |
5856 \SWITCH{} ($e$) \{ | 5869 \SWITCH{} ($e$) \{ |
5857 $label_{11} \ldots label_{1j_1}$ \CASE{} $e_1: s_1$ | 5870 $label_{11} \ldots label_{1j_1}$ \CASE{} $e_1: s_1$ |
5858 $\ldots$ | 5871 $\ldots$ |
5859 $label_{n1} \ldots label_{nj_n}$ \CASE{} $e_n: s_n$ | 5872 $label_{n1} \ldots label_{nj_n}$ \CASE{} $e_n: s_n$ |
5860 $label_{(n+1)1} \ldots label_{(n+1)j_{n+1}}$ \DEFAULT{}: $s_{n+1}$ | 5873 $label_{(n+1)1} \ldots label_{(n+1)j_{n+1}}$ \DEFAULT{}: $s_{n+1}$ |
5861 \} | 5874 \} |
5862 \end{dartCode} | 5875 \end{dartCode} |
5863 | 5876 |
5864 or the form | 5877 or the form |
5865 | 5878 |
5866 \begin{dartCode} | 5879 \begin{dartCode} |
5867 \SWITCH{} ($e$) \{ | 5880 \SWITCH{} ($e$) \{ |
5868 $label_{11} \ldots label_{1j_1}$ \CASE{} $e_1: s_1$ | 5881 $label_{11} \ldots label_{1j_1}$ \CASE{} $e_1: s_1$ |
5869 $\ldots$ | 5882 $\ldots$ |
5870 $label_{n1} \ldots label_{nj_n}$ \CASE{} $e_n: s_n$ | 5883 $label_{n1} \ldots label_{nj_n}$ \CASE{} $e_n: s_n$ |
5871 \} | 5884 \} |
5872 \end{dartCode} | 5885 \end{dartCode} |
5873 | 5886 |
5874 proceeds as follows: | 5887 proceeds as follows: |
5875 | 5888 |
5876 \LMHash{} | 5889 \LMHash{} |
5877 The statement \code{\VAR{} id = $e$;} is evaluated, where \code{id} is a variabl e whose name is distinct from any other variable in the program. In checked mode , it is a run time error if the value of $e$ is not an instance of the same clas s as the constants $e_1 \ldots e_n$. | 5890 The statement \code{\VAR{} id = $e$;} is evaluated, where \code{id} is a variabl e whose name is distinct from any other variable in the program. In checked mode , it is a run time error if the value of $e$ is not an instance of the same clas s as the constants $e_1 \ldots e_n$. |
5878 | 5891 |
5879 \commentary{Note that if there are no case clauses ($n = 0$), the type of $e$ do es not matter.} | 5892 \commentary{Note that if there are no case clauses ($n = 0$), the type of $e$ do es not matter.} |
5880 | 5893 |
5881 \LMHash{} | 5894 \LMHash{} |
5882 Next, the case clause \CASE{} $e_{1}: s_{1}$ is executed if it exists. If \CASE{ } $e_{1}: s_{1}$ does not exist, then if there is a \DEFAULT{} clause it is exe cuted by executing $s_{n+1}$. | 5895 Next, the case clause \CASE{} $e_{1}: s_{1}$ is executed if it exists. If \CASE{ } $e_{1}: s_{1}$ does not exist, then if there is a \DEFAULT{} clause it is exe cuted by executing $s_{n+1}$. |
5883 | 5896 |
5884 \LMHash{} | 5897 \LMHash{} |
5885 A case clause introduces a new scope, nested in the lexically surrounding scope. The scope of a case clause ends immediately after the case clause's statement l ist. | 5898 A case clause introduces a new scope, nested in the lexically surrounding scope. The scope of a case clause ends immediately after the case clause's statement l ist. |
5886 | 5899 |
5887 \LMHash{} | 5900 \LMHash{} |
5888 Execution of a \CASE{} clause \CASE{} $e_{k}: s_{k}$ of a switch statement | 5901 Execution of a \CASE{} clause \CASE{} $e_{k}: s_{k}$ of a switch statement |
5889 | 5902 |
5890 \begin{dartCode} | 5903 \begin{dartCode} |
5891 \SWITCH{} ($e$) \{ | 5904 \SWITCH{} ($e$) \{ |
5892 $label_{11} \ldots label_{1j_1}$ \CASE{} $e_1: s_1$ | 5905 $label_{11} \ldots label_{1j_1}$ \CASE{} $e_1: s_1$ |
5893 $\ldots$ | 5906 $\ldots$ |
5894 $label_{n1} \ldots label_{nj_n}$ \CASE{} $e_n: s_n$ | 5907 $label_{n1} \ldots label_{nj_n}$ \CASE{} $e_n: s_n$ |
5895 $label_{(n+1)1} \ldots label_{(n+1)j_{n+1}}$ \DEFAULT{}: $s_{n+1}$ | 5908 $label_{(n+1)1} \ldots label_{(n+1)j_{n+1}}$ \DEFAULT{}: $s_{n+1}$ |
5896 \} | 5909 \} |
5897 \end{dartCode} | 5910 \end{dartCode} |
5898 | 5911 |
5899 proceeds as follows: | 5912 proceeds as follows: |
5900 | 5913 |
5901 \LMHash{} | 5914 \LMHash{} |
5902 The expression \code{$e_k$ == id} is evaluated to an object $o$ which is then su bjected to boolean conversion yielding a value $v$. | 5915 The expression \code{$e_k$ == id} is evaluated to an object $o$ which is then su bjected to boolean conversion yielding a value $v$. |
5903 If $v$ is not \TRUE{} the following case, \CASE{} $e_{k+1}: s_{k+1}$ is execut ed if it exists. If \CASE{} $e_{k+1}: s_{k+1}$ does not exist, then the \DEFAUL T{} clause is executed by executing $s_{n+1}$. | 5916 If $v$ is not \TRUE{} the following case, \CASE{} $e_{k+1}: s_{k+1}$ is execut ed if it exists. If \CASE{} $e_{k+1}: s_{k+1}$ does not exist, then the \DEFAUL T{} clause is executed by executing $s_{n+1}$. |
5904 If $v$ is \TRUE{}, let $h$ be the smallest number such that $h \ge k$ and $s_h $ is non-empty. If no such $h$ exists, let $h = n + 1$. The sequence of stateme nts $s_h$ is then executed. | 5917 If $v$ is \TRUE{}, let $h$ be the smallest number such that $h \ge k$ and $s_h $ is non-empty. If no such $h$ exists, let $h = n + 1$. The sequence of stateme nts $s_h$ is then executed. |
5905 If execution reaches the point after $s_h$ then a runtime error occurs, unless $h = n+1$. | 5918 If execution reaches the point after $s_h$ then a runtime error occurs, unless $h = n+1$. |
5906 | 5919 |
5907 \LMHash{} | 5920 \LMHash{} |
5908 Execution of a \CASE{} clause \CASE{} $e_{k}: s_{k}$ of a switch statement | 5921 Execution of a \CASE{} clause \CASE{} $e_{k}: s_{k}$ of a switch statement |
5909 | 5922 |
5910 \begin{dartCode} | 5923 \begin{dartCode} |
5911 \SWITCH{} ($e$) \{ | 5924 \SWITCH{} ($e$) \{ |
5912 $label_{11} \ldots label_{1j_1}$ \CASE{} $e_1: s_1$ | 5925 $label_{11} \ldots label_{1j_1}$ \CASE{} $e_1: s_1$ |
5913 $\ldots$ | 5926 $\ldots$ |
5914 $label_{n1} \ldots label_{nj_n}$ \CASE{} $e_n: s_n$ | 5927 $label_{n1} \ldots label_{nj_n}$ \CASE{} $e_n: s_n$ |
5915 \} | 5928 \} |
5916 \end{dartCode} | 5929 \end{dartCode} |
5917 | 5930 |
5918 proceeds as follows: | 5931 proceeds as follows: |
5919 | 5932 |
5920 \LMHash{} | 5933 \LMHash{} |
5921 The expression \code{$e_k$ == id} is evaluated to an object $o$ which is then su bjected to boolean conversion yielding a value $v$. | 5934 The expression \code{$e_k$ == id} is evaluated to an object $o$ which is then su bjected to boolean conversion yielding a value $v$. |
5922 If $v$ is not \TRUE{} the following case, \CASE{} $e_{k+1}: s_{k+1}$ is execut ed if it exists. | 5935 If $v$ is not \TRUE{} the following case, \CASE{} $e_{k+1}: s_{k+1}$ is execut ed if it exists. |
5923 If $v$ is \TRUE{}, let $h$ be the smallest integer such that $h \ge k$ and $s_ h$ is non-empty. The sequence of statements $s_h$ is executed if it exists. | 5936 If $v$ is \TRUE{}, let $h$ be the smallest integer such that $h \ge k$ and $s_ h$ is non-empty. The sequence of statements $s_h$ is executed if it exists. |
5924 If execution reaches the point after $s_h$ then a runtime error occurs, unless $h = n$. | 5937 If execution reaches the point after $s_h$ then a runtime error occurs, unless $h = n$. |
5925 | 5938 |
5926 | 5939 |
5927 \commentary{ | 5940 \commentary{ |
5928 In other words, there is no implicit fall-through between non-empty cases. The l ast case in a switch (default or otherwise) can `fall-through' to the end of the statement. | 5941 In other words, there is no implicit fall-through between non-empty cases. The l ast case in a switch (default or otherwise) can `fall-through' to the end of the statement. |
5929 } | 5942 } |
5930 | 5943 |
5931 \LMHash{} | 5944 \LMHash{} |
5932 It is a static warning if the type of $e$ may not be assigned to the type of $e_ k$. It is a static warning if the last statement of the statement sequence $s_k$ is not a \BREAK{}, \CONTINUE{}, \RETURN{} or \THROW{} statement. | 5945 It is a static warning if the type of $e$ may not be assigned to the type of $e_ k$. It is a static warning if the last statement of the statement sequence $s_k$ is not a \BREAK{}, \CONTINUE{}, \RETURN{} or \THROW{} statement. |
5933 | 5946 |
5934 \rationale{ | 5947 \rationale{ |
5935 The behavior of switch cases intentionally differs from the C tradition. Implic it fall through is a known cause of programming errors and therefore disallowed. Why not simply break the flow implicitly at the end of every case, rather than requiring explicit code to do so? This would indeed be cleaner. It would also be cleaner to insist that each case have a single (possibly compound) statement . We have chosen not to do so in order to facilitate porting of switch statemen ts from other languages. Implicitly breaking the control flow at the end of a c ase would silently alter the meaning of ported code that relied on fall-through, potentially forcing the programmer to deal with subtle bugs. Our design ensures that the difference is immediately brought to the coder's attention. The progr ammer will be notified at compile-time if they forget to end a case with a state ment that terminates the straight-line control flow. We could make this warning a compile-time error, but refrain from doing so because do not wish to force the programmer to deal with this issue immediately while porting code. If develope rs ignore the warning and run their code, a run time error will prevent the prog ram from misbehaving in hard-to-debug ways (at least with respect to this issue) . | 5948 The behavior of switch cases intentionally differs from the C tradition. Implic it fall through is a known cause of programming errors and therefore disallowed. Why not simply break the flow implicitly at the end of every case, rather than requiring explicit code to do so? This would indeed be cleaner. It would also be cleaner to insist that each case have a single (possibly compound) statement . We have chosen not to do so in order to facilitate porting of switch statemen ts from other languages. Implicitly breaking the control flow at the end of a c ase would silently alter the meaning of ported code that relied on fall-through, potentially forcing the programmer to deal with subtle bugs. Our design ensures that the difference is immediately brought to the coder's attention. The progr ammer will be notified at compile-time if they forget to end a case with a state ment that terminates the straight-line control flow. We could make this warning a compile-time error, but refrain from doing so because do not wish to force the programmer to deal with this issue immediately while porting code. If develope rs ignore the warning and run their code, a run time error will prevent the prog ram from misbehaving in hard-to-debug ways (at least with respect to this issue) . |
5936 | 5949 |
5937 The sophistication of the analysis of fall-through is another issue. For now, we have opted for a very straightforward syntactic requirement. There are obviousl y situations where code does not fall through, and yet does not conform to these simple rules, e.g.: | 5950 The sophistication of the analysis of fall-through is another issue. For now, we have opted for a very straightforward syntactic requirement. There are obviousl y situations where code does not fall through, and yet does not conform to these simple rules, e.g.: |
5938 } | 5951 } |
5939 | 5952 |
5940 \begin{dartCode} | 5953 \begin{dartCode} |
5941 \SWITCH{} (x) \{ | 5954 \SWITCH{} (x) \{ |
5942 \CASE{} 1: \TRY{} \{ $\ldots$ \RETURN{};\} \FINALLY{} \{ $\ldots$ \RETURN{};\} | 5955 \CASE{} 1: \TRY{} \{ $\ldots$ \RETURN{};\} \FINALLY{} \{ $\ldots$ \RETURN{};\} |
5943 \} | 5956 \} |
5944 \end{dartCode} | 5957 \end{dartCode} |
5945 | 5958 |
5946 \rationale{ | 5959 \rationale{ |
5947 Very elaborate code in a case clause is probably bad style in any case, and su ch code can always be refactored. | 5960 Very elaborate code in a case clause is probably bad style in any case, and su ch code can always be refactored. |
5948 } | 5961 } |
5949 | 5962 |
5950 \LMHash{} | 5963 \LMHash{} |
5951 It is a static warning if all of the following conditions hold: | 5964 It is a static warning if all of the following conditions hold: |
5952 \begin{itemize} | 5965 \begin{itemize} |
5953 \item The switch statement does not have a default clause. | 5966 \item The switch statement does not have a default clause. |
5954 \item The static type of $e$ is an enumerated typed with elements $id_1, \ldots , id_n$. | 5967 \item The static type of $e$ is an enumerated typed with elements $id_1, \ldots , id_n$. |
5955 \item The sets $\{e_1, \ldots, e_k\} $ and $\{id_1, \ldots, id_n\}$ are not the same. | 5968 \item The sets $\{e_1, \ldots, e_k\} $ and $\{id_1, \ldots, id_n\}$ are not the same. |
5956 \end{itemize} | 5969 \end{itemize} |
5957 | 5970 |
5958 \commentary{ | 5971 \commentary{ |
5959 In other words, a warning will be issued if a switch statement over an enum is n ot exhaustive. | 5972 In other words, a warning will be issued if a switch statement over an enum is n ot exhaustive. |
5960 } | 5973 } |
5961 | 5974 |
5962 | 5975 |
5963 \subsection{ Rethrow} | 5976 \subsection{ Rethrow} |
5964 \LMLabel{rethrow} | 5977 \LMLabel{rethrow} |
5965 | 5978 |
5966 | 5979 |
5967 \LMHash{} | 5980 \LMHash{} |
5968 The {\em rethrow statement} is used to re-raise an exception. | 5981 The {\em rethrow statement} is used to re-raise an exception. |
5969 | 5982 |
5970 \begin{grammar} | 5983 \begin{grammar} |
5971 {\bf rethrowStatement:} | 5984 {\bf rethrowStatement:} |
5972 \RETHROW{} `{\escapegrammar ;}' | 5985 \RETHROW{} `{\escapegrammar ;}' |
5973 . | 5986 . |
5974 \end{grammar} | 5987 \end{grammar} |
5975 | 5988 |
5976 \LMHash{} | 5989 \LMHash{} |
5977 Execution of a \code{\RETHROW{}} statement proceeds as follows: | 5990 Execution of a \code{\RETHROW{}} statement proceeds as follows: |
5978 | 5991 |
5979 \LMHash{} | 5992 \LMHash{} |
5980 Let $f$ be the immediately enclosing function, and let \code{\ON{} $T$ \CATCH{} ($p_1$, $p_2$)} be the immediately enclosing catch clause (\ref{try}). | 5993 Let $f$ be the immediately enclosing function, and let \code{\ON{} $T$ \CATCH{} ($p_1$, $p_2$)} be the immediately enclosing catch clause (\ref{try}). |
5981 | 5994 |
5982 \rationale{ | 5995 \rationale{ |
5983 A \RETHROW{} statement always appears inside a \CATCH{} clause, and any \CATCH{} clause is semantically equivalent to some \CATCH{} clause of the form \code{\ON {} $T$ \CATCH{} (p1, p2)}. So we can assume that the \RETHROW{} is enclosed in a \CATCH{} clause of that form. | 5996 A \RETHROW{} statement always appears inside a \CATCH{} clause, and any \CATCH{} clause is semantically equivalent to some \CATCH{} clause of the form \code{\ON {} $T$ \CATCH{} (p1, p2)}. So we can assume that the \RETHROW{} is enclosed in a \CATCH{} clause of that form. |
5984 } | 5997 } |
5985 | 5998 |
5986 \LMHash{} | 5999 \LMHash{} |
5987 The current exception (\ref{throw}) is set to $p_1$, the current return value (\ ref{return}) becomes undefined, and the active stack trace (\ref{try}) is set to $p_2$. | 6000 The current exception (\ref{throw}) is set to $p_1$, the current return value (\ ref{return}) becomes undefined, and the active stack trace (\ref{try}) is set to $p_2$. |
5988 | 6001 |
5989 \LMHash{} | 6002 \LMHash{} |
5990 If $f$ is marked \ASYNC{} or \ASYNC* (\ref{functions}) and there is a dynamicall y enclosing exception handler (\ref{try}) $h$ introduced by the current activati on, control is transferred to $h$, otherwise $f$ terminates. | 6003 If $f$ is marked \ASYNC{} or \ASYNC* (\ref{functions}) and there is a dynamicall y enclosing exception handler (\ref{try}) $h$ introduced by the current activati on, control is transferred to $h$, otherwise $f$ terminates. |
5991 | 6004 |
5992 \rationale{ | 6005 \rationale{ |
5993 In the case of an asynchronous function, the dynamically enclosing exception han dler is only relevant within the function. If an exception is not caught within the function, the exception value is channelled through a future or stream rathe r than propagating via exception handlers. | 6006 In the case of an asynchronous function, the dynamically enclosing exception han dler is only relevant within the function. If an exception is not caught within the function, the exception value is channelled through a future or stream rathe r than propagating via exception handlers. |
5994 } | 6007 } |
5995 | 6008 |
5996 \LMHash{} | 6009 \LMHash{} |
5997 Otherwise, control is transferred to the innermost enclosing exception handler. | 6010 Otherwise, control is transferred to the innermost enclosing exception handler. |
5998 | 6011 |
5999 \commentary{The change in control may result in multiple functions terminating i f these functions do not catch the exception via a \CATCH{} or \FINALLY{} clause , both of which introduce a dynamically enclosing exception handler.} | 6012 \commentary{The change in control may result in multiple functions terminating i f these functions do not catch the exception via a \CATCH{} or \FINALLY{} clause , both of which introduce a dynamically enclosing exception handler.} |
6000 | 6013 |
6001 \LMHash{} | 6014 \LMHash{} |
6002 It is a compile-time error if a \code{\RETHROW{}} statement is not enclosed wit hin an \ON-\CATCH{} clause. | 6015 It is a compile-time error if a \code{\RETHROW{}} statement is not enclosed wit hin an \ON-\CATCH{} clause. |
6003 | 6016 |
6004 | 6017 |
6005 | 6018 |
6006 \subsection{ Try} | 6019 \subsection{ Try} |
6007 \LMLabel{try} | 6020 \LMLabel{try} |
6008 | 6021 |
6009 \LMHash{} | 6022 \LMHash{} |
6010 The try statement supports the definition of exception handling code in a struct ured way. | 6023 The try statement supports the definition of exception handling code in a struct ured way. |
6011 | 6024 |
6012 \begin{grammar} | 6025 \begin{grammar} |
6013 {\bf tryStatement:} | 6026 {\bf tryStatement:} |
6014 \TRY{} block (onPart+ finallyPart? $|$ finallyPart) | 6027 \TRY{} block (onPart+ finallyPart? $|$ finallyPart) |
6015 . | 6028 . |
6016 | 6029 |
6017 {\bf onPart:}catchPart block; | 6030 {\bf onPart:}catchPart block; |
6018 \ON{} type catchPart? block | 6031 \ON{} type catchPart? block |
6019 . | 6032 . |
6020 | 6033 |
6021 {\bf catchPart:} | 6034 {\bf catchPart:} |
6022 \CATCH{} `(' identifier (`,' identifier)? `)' | 6035 \CATCH{} `(' identifier (`,' identifier)? `)' |
6023 . | 6036 . |
6024 | 6037 |
6025 {\bf finallyPart:} | 6038 {\bf finallyPart:} |
6026 \FINALLY{} block | 6039 \FINALLY{} block |
6027 . | 6040 . |
6028 \end{grammar} | 6041 \end{grammar} |
6029 | 6042 |
6030 \LMHash{} | 6043 \LMHash{} |
6031 A try statement consists of a block statement, followed by at least one of: | 6044 A try statement consists of a block statement, followed by at least one of: |
6032 \begin{enumerate} | 6045 \begin{enumerate} |
6033 \item | 6046 \item |
6034 A set of \ON{}-\CATCH{} clauses, each of which specifies (either explicitly or implicitly) the type of exception object to be handled, one or two exception par ameters and a block statement. | 6047 A set of \ON{}-\CATCH{} clauses, each of which specifies (either explicitly or implicitly) the type of exception object to be handled, one or two exception par ameters and a block statement. |
6035 \item | 6048 \item |
6036 A \FINALLY{} clause, which consists of a block statement. | 6049 A \FINALLY{} clause, which consists of a block statement. |
6037 \end{enumerate} | 6050 \end{enumerate} |
6038 | 6051 |
6039 \rationale{ | 6052 \rationale{ |
6040 The syntax is designed to be upward compatible with existing Javascript programs . The \ON{} clause can be omitted, leaving what looks like a Javascript catch cl ause. | 6053 The syntax is designed to be upward compatible with existing Javascript programs . The \ON{} clause can be omitted, leaving what looks like a Javascript catch cl ause. |
6041 } | 6054 } |
6042 | 6055 |
6043 \LMHash{} | 6056 \LMHash{} |
6044 An \ON{}-\CATCH{} clause of the form \code{\ON{} $T$ \CATCH{} ($p_1, p_2$) $s$ } {\em matches} an object $o$ if the type of $o$ is a subtype of $T$. If $T$ is a malformed or deferred type (\ref{staticTypes}), then performing a match ca uses a run time error. | 6057 An \ON{}-\CATCH{} clause of the form \code{\ON{} $T$ \CATCH{} ($p_1, p_2$) $s$ } {\em matches} an object $o$ if the type of $o$ is a subtype of $T$. If $T$ is a malformed or deferred type (\ref{staticTypes}), then performing a match ca uses a run time error. |
6045 | 6058 |
6046 \commentary { | 6059 \commentary { |
6047 It is of course a static warning if $T$ is a deferred or malformed type. | 6060 It is of course a static warning if $T$ is a deferred or malformed type. |
6048 } | 6061 } |
6049 | 6062 |
6050 \LMHash{} | 6063 \LMHash{} |
6051 An \ON{}-\CATCH{} clause of the form \code{\ON{} $T$ \CATCH{} ($p_1, p_2$) $s$ } introduces a new scope $CS$ in which final local variables specified by $p_1$ and $p_2$ are defined. The statement $s$ is enclosed within $CS$. The static typ e of $p_1$ is $T$ and the static type of $p_2$ is \code{StackTrace}. | 6064 An \ON{}-\CATCH{} clause of the form \code{\ON{} $T$ \CATCH{} ($p_1, p_2$) $s$ } introduces a new scope $CS$ in which final local variables specified by $p_1$ and $p_2$ are defined. The statement $s$ is enclosed within $CS$. The static typ e of $p_1$ is $T$ and the static type of $p_2$ is \code{StackTrace}. |
6052 | 6065 |
6053 | 6066 |
6054 \LMHash{} | 6067 \LMHash{} |
6055 An \ON{}-\CATCH{} clause of the form \code{\ON{} $T$ \CATCH{} ($p_1$) $s$} is e quivalent to an \ON{}-\CATCH{} clause \code{\ON{} $T$ \CATCH{} ($p_1, p_2$) $s$ } where $p_2$ is an identifier that does not occur anywhere else in the program. | 6068 An \ON{}-\CATCH{} clause of the form \code{\ON{} $T$ \CATCH{} ($p_1$) $s$} is e quivalent to an \ON{}-\CATCH{} clause \code{\ON{} $T$ \CATCH{} ($p_1, p_2$) $s$ } where $p_2$ is an identifier that does not occur anywhere else in the program. |
6056 | 6069 |
6057 | 6070 |
6058 \LMHash{} | 6071 \LMHash{} |
6059 An \ON{}-\CATCH{} clause of the form \code{\CATCH{} ($p$) $s$} is equivalent to an \ON{}-\CATCH{} clause \code{\ON{} \DYNAMIC{} \CATCH{} ($p$) $s$}. An \ON{}- \CATCH{} clause of the form \code{\CATCH{} ($p_1, p_2$) $s$} is equivalent to a n \ON{}-\CATCH{} clause \code{\ON{} \DYNAMIC{} \CATCH{} ($p_1, p_2$) $s$}. | 6072 An \ON{}-\CATCH{} clause of the form \code{\CATCH{} ($p$) $s$} is equivalent to an \ON{}-\CATCH{} clause \code{\ON{} \DYNAMIC{} \CATCH{} ($p$) $s$}. An \ON{}- \CATCH{} clause of the form \code{\CATCH{} ($p_1, p_2$) $s$} is equivalent to a n \ON{}-\CATCH{} clause \code{\ON{} \DYNAMIC{} \CATCH{} ($p_1, p_2$) $s$}. |
6060 | 6073 |
6061 | 6074 |
6062 %If an explicit type is associated with of $p_2$, it is a static warning if that type is not \code{Object} or \DYNAMIC{}. | 6075 %If an explicit type is associated with of $p_2$, it is a static warning if that type is not \code{Object} or \DYNAMIC{}. |
6063 | 6076 |
6064 \LMHash{} | 6077 \LMHash{} |
6065 The {\em active stack trace} is an object whose \code{toString()} method produce s a string that is a record of exactly those function activations within the cur rent isolate that had not completed execution at the point where the current exc eption (\ref{throw}) was thrown. | 6078 The {\em active stack trace} is an object whose \code{toString()} method produce s a string that is a record of exactly those function activations within the cur rent isolate that had not completed execution at the point where the current exc eption (\ref{throw}) was thrown. |
6066 %\begin{enumerate} | 6079 %\begin{enumerate} |
6067 %\item Started execution after the currently executing function. | 6080 %\item Started execution after the currently executing function. |
6068 %\item Had not completed execution at the point where the exception caught by th e currently executing \ON{}-\CATCH{} clause was initially thrown. | 6081 %\item Had not completed execution at the point where the exception caught by th e currently executing \ON{}-\CATCH{} clause was initially thrown. |
6069 %\commentary{The active stack trace contains the frames between the exception ha ndling code and the original point when an exception is thrown, not where it was rethrown.} | 6082 %\commentary{The active stack trace contains the frames between the exception ha ndling code and the original point when an exception is thrown, not where it was rethrown.} |
6070 %\end{enumerate} | 6083 %\end{enumerate} |
6071 | 6084 |
6072 \commentary{ | 6085 \commentary{ |
6073 This implies that no synthetic function activations may be added to the trace, n or may any source level activations be omitted. | 6086 This implies that no synthetic function activations may be added to the trace, n or may any source level activations be omitted. |
6074 This means, for example, that any inlining of functions done as an optimization must not be visible in the trace. Similarly, any synthetic routines used by the implementation must not appear in the trace. | 6087 This means, for example, that any inlining of functions done as an optimization must not be visible in the trace. Similarly, any synthetic routines used by the implementation must not appear in the trace. |
6075 | 6088 |
6076 Nothing is said about how any native function calls may be represented in the tr ace. | 6089 Nothing is said about how any native function calls may be represented in the tr ace. |
6077 } | 6090 } |
6078 | 6091 |
6079 \commentary{ | 6092 \commentary{ |
6080 Note that we say nothing about the identity of the stack trace, or what notion o f equality is defined for stack traces. | 6093 Note that we say nothing about the identity of the stack trace, or what notion o f equality is defined for stack traces. |
6081 } | 6094 } |
6082 | 6095 |
6083 % Sadly, the info below cannot be computed efficiently. It would need to be comp uted at the throw point, since at latte points it might be destroyed. Native cod e in calling frames executes relative to the stack pointer, which therefore need s to be reset as each frame is unwound. This means that the | 6096 % Sadly, the info below cannot be computed efficiently. It would need to be comp uted at the throw point, since at latte points it might be destroyed. Native cod e in calling frames executes relative to the stack pointer, which therefore need s to be reset as each frame is unwound. This means that the |
6084 % OS kernel can dispose of this stack memory - it is not reliably preserved. And such code must execute if only to test if the exception should be caught or sen t onward. | 6097 % OS kernel can dispose of this stack memory - it is not reliably preserved. And such code must execute if only to test if the exception should be caught or sen t onward. |
6085 | 6098 |
6086 % For each such function activation, the active stack trace includes the name of the function, the bindings of all its formal parameters, local variables and \T HIS{}, and the position at which the function was executing. | 6099 % For each such function activation, the active stack trace includes the name of the function, the bindings of all its formal parameters, local variables and \T HIS{}, and the position at which the function was executing. |
6087 | 6100 |
6088 % Is this controversial? We were thinking of viewing the trace as a List<Invoca tion>, | 6101 % Is this controversial? We were thinking of viewing the trace as a List<Invoca tion>, |
6089 % but that won't capture the receiver or the locals. More generally, we need a standard interface that describes these traces, so one can type the stack trace variable in the catch. | 6102 % but that won't capture the receiver or the locals. More generally, we need a standard interface that describes these traces, so one can type the stack trace variable in the catch. |
6090 | 6103 |
6091 \commentary{The term position should not be interpreted as a line number, but r ather as a precise position - the exact character index of the expression that raised the exception. } | 6104 \commentary{The term position should not be interpreted as a line number, but r ather as a precise position - the exact character index of the expression that raised the exception. } |
6092 | 6105 |
6093 % A position can be represented via a Token. If we make that part of the core r eflection facility, we can state this here. | 6106 % A position can be represented via a Token. If we make that part of the core r eflection facility, we can state this here. |
6094 | 6107 |
6095 \LMHash{} | 6108 \LMHash{} |
6096 A try statement \TRY{} $s_1$ $on-catch_1 \ldots on-catch_n$ \FINALLY{} $s_f$ d efines an exception handler $h$ that executes as follows: | 6109 A try statement \TRY{} $s_1$ $on-catch_1 \ldots on-catch_n$ \FINALLY{} $s_f$ d efines an exception handler $h$ that executes as follows: |
6097 | 6110 |
6098 \LMHash{} | 6111 \LMHash{} |
6099 The \ON{}-\CATCH{} clauses are examined in order, starting with $catch_1$, until either an \ON{}-\CATCH{} clause that matches the current exception (\ref{throw} ) is found, or the list of \ON{}-\CATCH{} clauses has been exhausted. If an \ON{ }-\CATCH{} clause $on-catch_k$ is found, then $p_{k1}$ is bound to the current e xception, $p_{k2}$, if declared, is bound to the active stack trace, and then $catch_k$ is executed. If no \ON{}-\CATCH{} clause is found, the \FINALLY{} clau se is executed. Then, execution resumes at the end of the try statement. | 6112 The \ON{}-\CATCH{} clauses are examined in order, starting with $catch_1$, until either an \ON{}-\CATCH{} clause that matches the current exception (\ref{throw} ) is found, or the list of \ON{}-\CATCH{} clauses has been exhausted. If an \ON{ }-\CATCH{} clause $on-catch_k$ is found, then $p_{k1}$ is bound to the current e xception, $p_{k2}$, if declared, is bound to the active stack trace, and then $catch_k$ is executed. If no \ON{}-\CATCH{} clause is found, the \FINALLY{} clau se is executed. Then, execution resumes at the end of the try statement. |
6100 | 6113 |
6101 | 6114 |
6102 \LMHash{} | 6115 \LMHash{} |
6103 A finally clause \FINALLY{} $s$ defines an exception handler $h$ that executes a s follows: | 6116 A finally clause \FINALLY{} $s$ defines an exception handler $h$ that executes a s follows: |
6104 | 6117 |
6105 \LMHash{} | 6118 \LMHash{} |
6106 Let $r$ be the current return value (\ref{return}). Then the current return valu e becomes undefined. Any open streams associated with any asynchronous for loops (\ref{asynchronousFor-in}) and yield-each (\ref{yieldEach}) statements executin g within the dynamic scope of $h$ are canceled, in the order of their nesting, i nnermost first. | 6119 Let $r$ be the current return value (\ref{return}). Then the current return valu e becomes undefined. Any open streams associated with any asynchronous for loops (\ref{asynchronousFor-in}) and yield-each (\ref{yieldEach}) statements executin g within the dynamic scope of $h$ are canceled, in the order of their nesting, i nnermost first. |
6107 | 6120 |
6108 \rationale{ | 6121 \rationale{ |
6109 Streams left open by for loops that were escaped for whatever reason would be ca nceled at function termination, but it is best to cancel them as soon as possibl e. | 6122 Streams left open by for loops that were escaped for whatever reason would be ca nceled at function termination, but it is best to cancel them as soon as possibl e. |
6110 } | 6123 } |
6111 | 6124 |
6112 \LMHash{} | 6125 \LMHash{} |
6113 Then the \FINALLY{} clause is executed. Let $m$ be the immediately enclosing fun ction. If $r$ is defined then the current return value is set to $r$ and then: | 6126 Then the \FINALLY{} clause is executed. Let $m$ be the immediately enclosing fun ction. If $r$ is defined then the current return value is set to $r$ and then: |
6114 \begin{itemize} | 6127 \begin{itemize} |
6115 \item | 6128 \item |
6116 if there is a dynamically enclosing error handler $g$ defined by a \FINALLY{} c lause in $m$, control is transferred to $g$. | 6129 if there is a dynamically enclosing error handler $g$ defined by a \FINALLY{} c lause in $m$, control is transferred to $g$. |
6117 \item | 6130 \item |
6118 Otherwise $m$ terminates. | 6131 Otherwise $m$ terminates. |
6119 \end{itemize} | 6132 \end{itemize} |
6120 | 6133 |
6121 Otherwise, execution resumes at the end of the try statement. | 6134 Otherwise, execution resumes at the end of the try statement. |
6122 | 6135 |
6123 \LMHash{} | 6136 \LMHash{} |
6124 Execution of an \ON{}-\CATCH{} clause \code{\ON{} $T$ \CATCH{} ($p_1$, $p_2$)} $ s$ of a try statement $t$ proceeds as follows: The statement $s$ is executed in the dynamic scope of the exception handler defined by the finally clause of $t$. Then, the current exception and active stack trace both become undefined. | 6137 Execution of an \ON{}-\CATCH{} clause \code{\ON{} $T$ \CATCH{} ($p_1$, $p_2$)} $ s$ of a try statement $t$ proceeds as follows: The statement $s$ is executed in the dynamic scope of the exception handler defined by the finally clause of $t$. Then, the current exception and active stack trace both become undefined. |
6125 | 6138 |
6126 \LMHash{} | 6139 \LMHash{} |
6127 Execution of a \FINALLY{} clause \FINALLY{} $s$ of a try statement proceeds as f ollows: | 6140 Execution of a \FINALLY{} clause \FINALLY{} $s$ of a try statement proceeds as f ollows: |
6128 | 6141 |
6129 \LMHash{} | 6142 \LMHash{} |
6130 Let $x$ be the current exception and let $t$ be the active stack trace. Then the current exception and the active stack trace both become undefined. The stateme nt $s$ is executed. Then, if $x$ is defined, it is rethrown as if by a rethrow statement (\ref{rethrow}) enclosed in a \CATCH{} clause of the form \code{\CATCH {} ($v_x$, $v_t$)} where $v_x$ and $v_t$ are fresh variables bound to $x$ and $t $ respectively. | 6143 Let $x$ be the current exception and let $t$ be the active stack trace. Then the current exception and the active stack trace both become undefined. The stateme nt $s$ is executed. Then, if $x$ is defined, it is rethrown as if by a rethrow statement (\ref{rethrow}) enclosed in a \CATCH{} clause of the form \code{\CATCH {} ($v_x$, $v_t$)} where $v_x$ and $v_t$ are fresh variables bound to $x$ and $t $ respectively. |
6131 | 6144 |
6132 | 6145 |
6133 \LMHash{} | 6146 \LMHash{} |
6134 Execution of a try statement of the form \code{\TRY{} $s_1$ $on-catch_1 \ldots o n-catch_n$ \FINALLY{} $s_f$;} proceeds as follows: | 6147 Execution of a try statement of the form \code{\TRY{} $s_1$ $on-catch_1 \ldots o n-catch_n$ \FINALLY{} $s_f$;} proceeds as follows: |
6135 | 6148 |
6136 \LMHash{} | 6149 \LMHash{} |
6137 The statement $s_1$ is executed in the dynamic scope of the exception handler de fined by the try statement. Then, the \FINALLY{} clause is executed. | 6150 The statement $s_1$ is executed in the dynamic scope of the exception handler de fined by the try statement. Then, the \FINALLY{} clause is executed. |
6138 | 6151 |
6139 \commentary{ | 6152 \commentary{ |
6140 Whether any of the \ON{}-\CATCH{} clauses is executed depends on whether a match ing exception has been raised by $s_1$ (see the specification of the throw state ment). | 6153 Whether any of the \ON{}-\CATCH{} clauses is executed depends on whether a match ing exception has been raised by $s_1$ (see the specification of the throw state ment). |
6141 | 6154 |
6142 If $s_1$ has raised an exception, it will transfer control to the try statement' s handler, which will examine the catch clauses in order for a match as specifie d above. If no matches are found, the handler will execute the \FINALLY{} clause . | 6155 If $s_1$ has raised an exception, it will transfer control to the try statement' s handler, which will examine the catch clauses in order for a match as specifie d above. If no matches are found, the handler will execute the \FINALLY{} clause . |
6143 | 6156 |
6144 If a matching \ON{}-\CATCH{} was found, it will execute first, and then the \FIN ALLY{} clause will be executed. | 6157 If a matching \ON{}-\CATCH{} was found, it will execute first, and then the \FIN ALLY{} clause will be executed. |
6145 | 6158 |
6146 If an exception is thrown during execution of an \ON{}-\CATCH{} clause, this wil l transfer control to the handler for the \FINALLY{} clause, causing the \FINALL Y{} clause to execute in this case as well. | 6159 If an exception is thrown during execution of an \ON{}-\CATCH{} clause, this wil l transfer control to the handler for the \FINALLY{} clause, causing the \FINALL Y{} clause to execute in this case as well. |
6147 | 6160 |
6148 If no exception was raised, the \FINALLY{} clause is also executed. Execution of the \FINALLY{} clause could also raise an exception, which will cause transfer of control to the next enclosing handler. | 6161 If no exception was raised, the \FINALLY{} clause is also executed. Execution of the \FINALLY{} clause could also raise an exception, which will cause transfer of control to the next enclosing handler. |
6149 } | 6162 } |
6150 | 6163 |
6151 \LMHash{} | 6164 \LMHash{} |
6152 A try statement of the form \code{\TRY{} $s_1$ $on-catch_1 \ldots on-catch_n$;} is equivalent to the statement \code{\TRY{} $s_1$ $on-catch_1 \ldots on-catch_n$ \FINALLY{} $\{\}$}. | 6165 A try statement of the form \code{\TRY{} $s_1$ $on-catch_1 \ldots on-catch_n$;} is equivalent to the statement \code{\TRY{} $s_1$ $on-catch_1 \ldots on-catch_n$ \FINALLY{} $\{\}$}. |
6153 | 6166 |
6154 | 6167 |
6155 \subsection{ Return} | 6168 \subsection{ Return} |
6156 \LMLabel{return} | 6169 \LMLabel{return} |
6157 | 6170 |
6158 \LMHash{} | 6171 \LMHash{} |
6159 The {\em return statement} returns a result to the caller of a synchronous funct ion, completes the future associated with an asynchronous function or terminate s the stream or iterable associated with a generator (\ref{functions}). | 6172 The {\em return statement} returns a result to the caller of a synchronous funct ion, completes the future associated with an asynchronous function or terminate s the stream or iterable associated with a generator (\ref{functions}). |
6160 | 6173 |
6161 | 6174 |
6162 \begin{grammar} | 6175 \begin{grammar} |
6163 {\bf returnStatement:} | 6176 {\bf returnStatement:} |
6164 \RETURN{} expression? `{\escapegrammar ;}' % could do top level here | 6177 \RETURN{} expression? `{\escapegrammar ;}' % could do top level here |
6165 . | 6178 . |
6166 \end{grammar} | 6179 \end{grammar} |
6167 | 6180 |
6168 \commentary{ | 6181 \commentary{ |
6169 Due to \FINALLY{} clauses, the precise behavior of \RETURN{} is a little more i nvolved. Whether the value a return statement is supposed to return is actually returned depends on the behavior of any \FINALLY{} clauses in effect when execut ing the return. A \FINALLY{} clause may choose to return another value, or throw an exception, or even redirect control flow leading to other returns or throws. All a return statement really does is set a value that is intended to be return ed when the function terminates. | 6182 Due to \FINALLY{} clauses, the precise behavior of \RETURN{} is a little more i nvolved. Whether the value a return statement is supposed to return is actually returned depends on the behavior of any \FINALLY{} clauses in effect when execut ing the return. A \FINALLY{} clause may choose to return another value, or throw an exception, or even redirect control flow leading to other returns or throws. All a return statement really does is set a value that is intended to be return ed when the function terminates. |
6170 } | 6183 } |
6171 | 6184 |
6172 \LMHash{} | 6185 \LMHash{} |
6173 The {\em current return value} is a unique value specific to a given function ac tivation. It is undefined unless explicitly set in this specification. | 6186 The {\em current return value} is a unique value specific to a given function ac tivation. It is undefined unless explicitly set in this specification. |
6174 | 6187 |
6175 \LMHash{} | 6188 \LMHash{} |
6176 Executing a return statement \code{\RETURN{} $e$;} proceeds as follows: | 6189 Executing a return statement \code{\RETURN{} $e$;} proceeds as follows: |
6177 | 6190 |
6178 \LMHash{} | 6191 \LMHash{} |
6179 First the expression $e$ is evaluated, producing an object $o$. Next: | 6192 First the expression $e$ is evaluated, producing an object $o$. Next: |
6180 \begin{itemize} | 6193 \begin{itemize} |
6181 \item | 6194 \item |
6182 The current return value is set to $o$ and the current exception (\ref{throw}) a nd active stack trace (\ref{try}) become undefined. | 6195 The current return value is set to $o$ and the current exception (\ref{throw}) a nd active stack trace (\ref{try}) become undefined. |
6183 \item | 6196 \item |
6184 Let $c$ be the \FINALLY{} clause of the innermost enclosing try-finally statemen t (\ref{try}), if any. If $c$ is defined, let $h$ be the handler induced by $c$. If $h$ is defined, control is transferred to $h$. | 6197 Let $c$ be the \FINALLY{} clause of the innermost enclosing try-finally statemen t (\ref{try}), if any. If $c$ is defined, let $h$ be the handler induced by $c$. If $h$ is defined, control is transferred to $h$. |
6185 \item | 6198 \item |
6186 Otherwise execution of the current method terminates. | 6199 Otherwise execution of the current method terminates. |
6187 \end{itemize} | 6200 \end{itemize} |
6188 | 6201 |
6189 \commentary{ | 6202 \commentary{ |
6190 In the simplest case, the immediately enclosing function is an ordinary, synchro nous non-generator, and upon function termination, the current return value is g iven to the caller. The other possibility is that the function is marked \ASYNC {}, in which case the current return value is used to complete the future associ ated with the function invocation. Both these scenarios are specified in section \ref{functionInvocation}. | 6203 In the simplest case, the immediately enclosing function is an ordinary, synchro nous non-generator, and upon function termination, the current return value is g iven to the caller. The other possibility is that the function is marked \ASYNC {}, in which case the current return value is used to complete the future associ ated with the function invocation. Both these scenarios are specified in section \ref{functionInvocation}. |
6191 The enclosing function cannot be marked as generator (i.e, \ASYNC* or \SYNC*), s ince generators are not allowed to contain a statement of the form \code{\RETURN {} $e$;} as discussed below. | 6204 The enclosing function cannot be marked as generator (i.e, \ASYNC* or \SYNC*), s ince generators are not allowed to contain a statement of the form \code{\RETURN {} $e$;} as discussed below. |
6192 } | 6205 } |
6193 | 6206 |
6194 \LMHash{} | 6207 \LMHash{} |
6195 Let $T$ be the static type of $e$ and let $f$ be the immediately enclosing funct ion. | 6208 Let $T$ be the static type of $e$ and let $f$ be the immediately enclosing funct ion. |
6196 | 6209 |
6197 \LMHash{} | 6210 \LMHash{} |
6198 It is a static type warning if the body of $f$ is marked \ASYNC{} and the type \ code{Future$<$flatten(T)$>$} (\ref{functionExpressions}) may not be assigned to the declared return type of $f$. Otherwise, it is a static type warning if $T $ may not be assigned to the declared return type of $f$. | 6211 It is a static type warning if the body of $f$ is marked \ASYNC{} and the type \ code{Future$<$flatten(T)$>$} (\ref{functionExpressions}) may not be assigned to the declared return type of $f$. Otherwise, it is a static type warning if $T $ may not be assigned to the declared return type of $f$. |
6199 | 6212 |
6200 \LMHash{} | 6213 \LMHash{} |
6201 Let $S$ be the runtime type of $o$. In checked mode: | 6214 Let $S$ be the runtime type of $o$. In checked mode: |
6202 \begin{itemize} | 6215 \begin{itemize} |
6203 \item If the body of $f$ is marked \ASYNC{} (\ref{functions}) it is a dynamic t ype error if $o$ is not \NULL{} (\ref{null}) and \code{Future$<$S$>$} is not a s ubtype of the actual return type (\ref{actualTypeOfADeclaration}) of $f$. | 6216 \item If the body of $f$ is marked \ASYNC{} (\ref{functions}) it is a dynamic t ype error if $o$ is not \NULL{} (\ref{null}) and \code{Future$<$flatten(S)$>$} i s not a subtype of the actual return type (\ref{actualTypeOfADeclaration}) of $ f$. |
6204 \item Otherwise, it is a dynamic type error if $o$ is not \NULL{} and the runtim e type of $o$ is not a subtype of the actual return type of $f$. | 6217 \item Otherwise, it is a dynamic type error if $o$ is not \NULL{} and the runtim e type of $o$ is not a subtype of the actual return type of $f$. |
6205 \end{itemize} | 6218 \end{itemize} |
6206 | 6219 |
6207 \LMHash{} | 6220 \LMHash{} |
6208 It is a compile-time error if a return statement of the form \code{\RETURN{} $e$ ;} appears in a generative constructor (\ref{generativeConstructors}). | 6221 It is a compile-time error if a return statement of the form \code{\RETURN{} $e$ ;} appears in a generative constructor (\ref{generativeConstructors}). |
6209 | 6222 |
6210 \rationale{ | 6223 \rationale{ |
6211 It is quite easy to forget to add the factory prefix for a constructor, accident ally converting a factory into a generative constructor. The static checker may detect a type mismatch in some, but not all, of these cases. The rule above help s catch such errors, which can otherwise be very hard to recognize. There is no real downside to it, as returning a value from a generative constructor is meani ngless. | 6224 It is quite easy to forget to add the factory prefix for a constructor, accident ally converting a factory into a generative constructor. The static checker may detect a type mismatch in some, but not all, of these cases. The rule above help s catch such errors, which can otherwise be very hard to recognize. There is no real downside to it, as returning a value from a generative constructor is meani ngless. |
6212 } | 6225 } |
6213 | 6226 |
6214 \LMHash{} | 6227 \LMHash{} |
6215 It is a compile-time error if a return statement of the form \code{\RETURN{} $e$ ;} appears in a generator function. | 6228 It is a compile-time error if a return statement of the form \code{\RETURN{} $e$ ;} appears in a generator function. |
6216 | 6229 |
6217 \rationale{ | 6230 \rationale{ |
6218 In the case of a generator function, the value returned by the function is the i terable or stream associated with it, and individual elements are added to that iterable using yield statements, and so returning a value makes no sense. | 6231 In the case of a generator function, the value returned by the function is the i terable or stream associated with it, and individual elements are added to that iterable using yield statements, and so returning a value makes no sense. |
6219 } | 6232 } |
6220 | 6233 |
6221 \LMHash{} | 6234 \LMHash{} |
6222 Let $f$ be the function immediately enclosing a return statement of the form \RE TURN{}; It is a static warning $f$ is neither a generator nor a generative cons tructor and either: | 6235 Let $f$ be the function immediately enclosing a return statement of the form \RE TURN{}; It is a static warning $f$ is neither a generator nor a generative cons tructor and either: |
6223 \begin{itemize} | 6236 \begin{itemize} |
6224 \item $f$ is synchronous and the return type of $f$ may not be assigned to \VOI D{} (\ref{typeVoid}) or, | 6237 \item $f$ is synchronous and the return type of $f$ may not be assigned to \VOI D{} (\ref{typeVoid}) or, |
6225 \item $f$ is asynchronous and the return type of $f$ may not be assigned to \co de{Future$<$Null$>$}. | 6238 \item $f$ is asynchronous and the return type of $f$ may not be assigned to \co de{Future$<$Null$>$}. |
6226 \end{itemize} | 6239 \end{itemize} |
6227 | 6240 |
6228 \commentary{ | 6241 \commentary{ |
6229 Hence, a static warning will not be issued if $f$ has no declared return type, s ince the return type would be \DYNAMIC{} and \DYNAMIC{} may be assigned to \VO ID{} and to \code{Future$<$Null$>$}. However, any synchronous non-generator func tion that declares a return type must return an expression explicitly. | 6242 Hence, a static warning will not be issued if $f$ has no declared return type, s ince the return type would be \DYNAMIC{} and \DYNAMIC{} may be assigned to \VO ID{} and to \code{Future$<$Null$>$}. However, any synchronous non-generator func tion that declares a return type must return an expression explicitly. |
6230 } | 6243 } |
6231 \rationale{This helps catch situations where users forget to return a value in a return statement.} | 6244 \rationale{This helps catch situations where users forget to return a value in a return statement.} |
6232 | 6245 |
6233 \rationale{ An asynchronous non-generator always returns a future of some sort. If no expression is given, the future will be completed with \NULL{} and this mo tivates the requirement above.} \commentary{Leaving the return type of a functio n marked \ASYNC{} blank will be interpreted as \DYNAMIC{} as always, and cause no type error. Using \code{Future} or \code{Future$<$Object$>$} is acceptable as well, but any other type will cause a warning, since \NULL{} has no subtypes.} | 6246 \rationale{ An asynchronous non-generator always returns a future of some sort. If no expression is given, the future will be completed with \NULL{} and this mo tivates the requirement above.} \commentary{Leaving the return type of a functio n marked \ASYNC{} blank will be interpreted as \DYNAMIC{} as always, and cause no type error. Using \code{Future} or \code{Future$<$Object$>$} is acceptable as well, but any other type will cause a warning, since \NULL{} has no subtypes.} |
6234 | 6247 |
6235 \LMHash{} | 6248 \LMHash{} |
6236 A return statement with no expression, \code{\RETURN;} is executed as follows: | 6249 A return statement with no expression, \code{\RETURN;} is executed as follows: |
6237 | 6250 |
6238 \LMHash{} | 6251 \LMHash{} |
6239 If the immediately enclosing function $f$ is a generator, then: | 6252 If the immediately enclosing function $f$ is a generator, then: |
6240 \begin{itemize} | 6253 \begin{itemize} |
6241 \item | 6254 \item |
6242 The current return value is set to \NULL{}. | 6255 The current return value is set to \NULL{}. |
6243 \item | 6256 \item |
6244 Let $c$ be the \FINALLY{} clause of the innermost enclosing try-finally statemen t, if any. If $c$ is defined, let $h$ be the handler induced by $c$. If $h$ is defined, control is transferred to $h$. | 6257 Let $c$ be the \FINALLY{} clause of the innermost enclosing try-finally statemen t, if any. If $c$ is defined, let $h$ be the handler induced by $c$. If $h$ is defined, control is transferred to $h$. |
6245 \item | 6258 \item |
6246 Otherwise, execution of the current method terminates. | 6259 Otherwise, execution of the current method terminates. |
6247 \end{itemize} | 6260 \end{itemize} |
6248 | 6261 |
6249 \LMHash{} | 6262 \LMHash{} |
6250 Otherwise the return statement is executed by executing the statement \code{\RE TURN{} \NULL{};} if it occurs inside a method, getter, setter or factory; otherw ise, the return statement necessarily occurs inside a generative constructor, in which case it is executed by executing \code{\RETURN{} \THIS{};}. | 6263 Otherwise the return statement is executed by executing the statement \code{\RE TURN{} \NULL{};} if it occurs inside a method, getter, setter or factory; otherw ise, the return statement necessarily occurs inside a generative constructor, in which case it is executed by executing \code{\RETURN{} \THIS{};}. |
6251 | 6264 |
6252 \commentary{Despite the fact that \code{\RETURN{};} is executed as if by a \code {\RETURN{} $e$;}, it is important to understand that it is not a static warning to include a statement of the form \code{\RETURN{};} | 6265 \commentary{Despite the fact that \code{\RETURN{};} is executed as if by a \code {\RETURN{} $e$;}, it is important to understand that it is not a static warning to include a statement of the form \code{\RETURN{};} |
6253 %in a \VOID{} function; neither is it illegal | 6266 %in a \VOID{} function; neither is it illegal |
6254 in a generative constructor. The rules relate only to the specific syntactic for m \code{\RETURN{} $e$;}. | 6267 in a generative constructor. The rules relate only to the specific syntactic for m \code{\RETURN{} $e$;}. |
6255 } | 6268 } |
6256 | 6269 |
6257 | 6270 |
6258 \rationale{ | 6271 \rationale{ |
6259 The motivation for formulating \code{\RETURN{};} in this way stems from the basi c requirement that all function invocations indeed return a value. Function invo cations are expressions, and we cannot rely on a mandatory typechecker to always prohibit use of \VOID{} functions in expressions. Hence, a return statement mus t always return a value, even if no expression is specified. | 6272 The motivation for formulating \code{\RETURN{};} in this way stems from the basi c requirement that all function invocations indeed return a value. Function invo cations are expressions, and we cannot rely on a mandatory typechecker to always prohibit use of \VOID{} functions in expressions. Hence, a return statement mus t always return a value, even if no expression is specified. |
6260 | 6273 |
6261 The question then becomes, what value should a return statement return when no r eturn expression is given. In a generative constructor, it is obviously the obje ct being constructed (\THIS{}). A void function is not expected to participate i n an expression, which is why it is marked \VOID{} in the first place. Hence, th is situation is a mistake which should be detected as soon as possible. The stat ic rules help here, but if the code is executed, using \NULL{} leads to fast fai lure, which is desirable in this case. The same rationale applies for function b odies that do not contain a return statement at all. | 6274 The question then becomes, what value should a return statement return when no r eturn expression is given. In a generative constructor, it is obviously the obje ct being constructed (\THIS{}). A void function is not expected to participate i n an expression, which is why it is marked \VOID{} in the first place. Hence, th is situation is a mistake which should be detected as soon as possible. The stat ic rules help here, but if the code is executed, using \NULL{} leads to fast fai lure, which is desirable in this case. The same rationale applies for function b odies that do not contain a return statement at all. |
6262 } | 6275 } |
6263 | 6276 |
6264 \LMHash{} | 6277 \LMHash{} |
6265 It is a static warning if a function contains both one or more explicit return statements of the form \code{\RETURN;} and one or more return statements of the form \code{\RETURN{} $e$;}. | 6278 It is a static warning if a function contains both one or more explicit return statements of the form \code{\RETURN;} and one or more return statements of the form \code{\RETURN{} $e$;}. |
6266 | 6279 |
6267 | 6280 |
6268 | 6281 |
6269 | 6282 |
6270 \subsection{ Labels} | 6283 \subsection{ Labels} |
6271 \LMLabel{labels} | 6284 \LMLabel{labels} |
6272 | 6285 |
6273 \LMHash{} | 6286 \LMHash{} |
6274 A {\em label} is an identifier followed by a colon. A {\em labeled statement} is a statement prefixed by a label $L$. A {\em labeled case clause} is a case cla use within a switch statement (\ref{switch}) prefixed by a label $L$. | 6287 A {\em label} is an identifier followed by a colon. A {\em labeled statement} is a statement prefixed by a label $L$. A {\em labeled case clause} is a case cla use within a switch statement (\ref{switch}) prefixed by a label $L$. |
6275 | 6288 |
6276 \rationale{The sole role of labels is to provide targets for the break (\ref{bre ak}) and continue (\ref{continue}) statements.} | 6289 \rationale{The sole role of labels is to provide targets for the break (\ref{bre ak}) and continue (\ref{continue}) statements.} |
6277 | 6290 |
6278 %\Q{Are labels in a separate namespace? Bug 49774299} | 6291 %\Q{Are labels in a separate namespace? Bug 49774299} |
6279 | 6292 |
6280 \begin{grammar} | 6293 \begin{grammar} |
6281 {\bf label:} | 6294 {\bf label:} |
6282 identifier `{\escapegrammar :}' | 6295 identifier `{\escapegrammar :}' |
6283 . | 6296 . |
6284 \end{grammar} | 6297 \end{grammar} |
6285 | 6298 |
6286 \LMHash{} | 6299 \LMHash{} |
6287 The semantics of a labeled statement $L: s$ are identical to those of the state ment $s$. The namespace of labels is distinct from the one used for types, funct ions and variables. | 6300 The semantics of a labeled statement $L: s$ are identical to those of the state ment $s$. The namespace of labels is distinct from the one used for types, funct ions and variables. |
6288 | 6301 |
6289 \LMHash{} | 6302 \LMHash{} |
6290 The scope of a label that labels a statement $s$ is $s$. The scope of a label th at labels a case clause of a switch statement $s$ is $s$. | 6303 The scope of a label that labels a statement $s$ is $s$. The scope of a label th at labels a case clause of a switch statement $s$ is $s$. |
6291 | 6304 |
6292 \rationale{Labels should be avoided by programmers at all costs. The motivation for including labels in the language is primarily making Dart a better target fo r code generation. | 6305 \rationale{Labels should be avoided by programmers at all costs. The motivation for including labels in the language is primarily making Dart a better target fo r code generation. |
6293 } | 6306 } |
6294 | 6307 |
6295 | 6308 |
6296 \subsection{ Break} | 6309 \subsection{ Break} |
6297 \LMLabel{break} | 6310 \LMLabel{break} |
6298 | 6311 |
6299 \LMHash{} | 6312 \LMHash{} |
6300 The {\em break statement} consists of the reserved word \BREAK{} and an optional label (\ref{labels}). | 6313 The {\em break statement} consists of the reserved word \BREAK{} and an optional label (\ref{labels}). |
6301 | 6314 |
6302 \begin{grammar} | 6315 \begin{grammar} |
6303 {\bf breakStatement:} | 6316 {\bf breakStatement:} |
6304 \BREAK{} identifier? `{\escapegrammar ;}' | 6317 \BREAK{} identifier? `{\escapegrammar ;}' |
6305 . | 6318 . |
6306 \end{grammar} | 6319 \end{grammar} |
6307 | |
6308 \LMHash{} | |
6309 Let $s_b$ be a \BREAK{} statement. If $s_b$ is of the form \code{\BREAK{} $L$;} , then let $s_E$ be the innermost labeled statement with label $L$ enclosing $s_ b$. If $s_b$ is of the form \code{\BREAK{};}, then let $s_E$ be the innermost \DO{} (\ref{do}), \FOR{} (\ref{for}), \SWITCH{} (\ref{switch}) or \WHILE{} (\ref {while}) statement enclosing $s_b$. It is a compile-time error if no such state ment $s_E$ exists within the innermost function in which $s_b$ occurs. Further more, let $s_1, \ldots, s_n$ be those \TRY{} statements that are both enclosed i n $s_E$ and that enclose $s_b$, and that have a \FINALLY{} clause. Lastly, let $f_j$ be the \FINALLY{} clause of $s_j, 1 \le j \le n$. Executing $s_b$ first executes $f_1, \ldots, f_n$ in innermost-clause-first order and then terminat es $s_E$. | |
6310 | 6320 |
6311 \LMHash{} | 6321 \LMHash{} |
6312 If $s_E$ is an asynchronous for loop (\ref{asynchronousFor-in}), its associated stream subscription is canceled. Furthermore, let $a_k$ be the set of asynchrono us for loops and yield-each statements (\ref{yieldEach}) enclosing $s_b$ that a re enclosed in $s_E , 1 \le k \le m$, where $a_k$ is enclosed in $a_{k+1}$. Th e stream subscriptions associated with $a_j$ are canceled, $1 \le j \le m$, inne rmost first, so that $a_j$ is canceled before $a_{j+1}$. | 6322 Let $s_b$ be a \BREAK{} statement. If $s_b$ is of the form \code{\BREAK{} $L$;} , then let $s_E$ be the innermost labeled statement with label $L$ enclosing $s_ b$. If $s_b$ is of the form \code{\BREAK{};}, then let $s_E$ be the innermost \DO{} (\ref{do}), \FOR{} (\ref{for}), \SWITCH{} (\ref{switch}) or \WHILE{} (\ref {while}) statement enclosing $s_b$. It is a compile-time error if no such state ment $s_E$ exists within the innermost function in which $s_b$ occurs. Further more, let $s_1, \ldots, s_n$ be those \TRY{} statements that are both enclosed i n $s_E$ and that enclose $s_b$, and that have a \FINALLY{} clause. Lastly, let $f_j$ be the \FINALLY{} clause of $s_j, 1 \le j \le n$. Executing $s_b$ first executes $f_1, \ldots, f_n$ in innermost-clause-first order and then terminat es $s_E$. |
6323 | |
6324 \LMHash{} | |
6325 If $s_E$ is an asynchronous for loop (\ref{asynchronousFor-in}), its associated stream subscription is canceled. Furthermore, let $a_k$ be the set of asynchrono us for loops and yield-each statements (\ref{yieldEach}) enclosing $s_b$ that a re enclosed in $s_E , 1 \le k \le m$, where $a_k$ is enclosed in $a_{k+1}$. Th e stream subscriptions associated with $a_j$ are canceled, $1 \le j \le m$, inne rmost first, so that $a_j$ is canceled before $a_{j+1}$. | |
6313 | 6326 |
6314 | 6327 |
6315 | 6328 |
6316 \subsection{ Continue} | 6329 \subsection{ Continue} |
6317 \LMLabel{continue} | 6330 \LMLabel{continue} |
6318 | 6331 |
6319 \LMHash{} | 6332 \LMHash{} |
6320 The {\em continue statement} consists of the reserved word \CONTINUE{} and an op tional label (\ref{labels}). | 6333 The {\em continue statement} consists of the reserved word \CONTINUE{} and an op tional label (\ref{labels}). |
6321 | 6334 |
6322 \begin{grammar} | 6335 \begin{grammar} |
6323 {\bf continueStatement:} | 6336 {\bf continueStatement:} |
6324 \CONTINUE{} identifier? `{\escapegrammar ;}' | 6337 \CONTINUE{} identifier? `{\escapegrammar ;}' |
6325 . | 6338 . |
6326 \end{grammar} | 6339 \end{grammar} |
6327 | 6340 |
6328 \LMHash{} | 6341 \LMHash{} |
6329 Let $s_c$ be a \CONTINUE{} statement. If $s_c$ is of the form \code{\CONTINUE{ } $L$;}, then let $s_E$ be the innermost labeled \DO{} (\ref{do}), \FOR{} (\ref{ for}) or \WHILE{} (\ref{while}) statement or case clause with label $L$ enclosin g $s_c$. If $s_c$ is of the form \code{\CONTINUE{};} then let $s_E$ be the inne rmost \DO{} (\ref{do}), \FOR{} (\ref{for}) or \WHILE{} (\ref{while}) statement enclosing $s_c$. It is a compile-time error if no such statement or case clause $s_E$ exists within the innermost function in which $s_c$ occurs. Furthermore , let $s_1, \ldots, s_n$ be those \TRY{} statements that are both enclosed in $s _E$ and that enclose $s_c$, and that have a \FINALLY{} clause. Lastly, let $f_j $ be the \FINALLY{} clause of $s_j, 1 \le j \le n$. Executing $s_c$ first exe cutes $f_1, \ldots, f_n$ in innermost-clause-first order. Then, if $s_E$ is a case clause, control is transferred to the case clause. Otherwise, $s_E$ is nece ssarily a loop and execution resumes after the last statement in the loop body. | 6342 Let $s_c$ be a \CONTINUE{} statement. If $s_c$ is of the form \code{\CONTINUE{ } $L$;}, then let $s_E$ be the innermost labeled \DO{} (\ref{do}), \FOR{} (\ref{ for}) or \WHILE{} (\ref{while}) statement or case clause with label $L$ enclosin g $s_c$. If $s_c$ is of the form \code{\CONTINUE{};} then let $s_E$ be the inne rmost \DO{} (\ref{do}), \FOR{} (\ref{for}) or \WHILE{} (\ref{while}) statement enclosing $s_c$. It is a compile-time error if no such statement or case clause $s_E$ exists within the innermost function in which $s_c$ occurs. Furthermore , let $s_1, \ldots, s_n$ be those \TRY{} statements that are both enclosed in $s _E$ and that enclose $s_c$, and that have a \FINALLY{} clause. Lastly, let $f_j $ be the \FINALLY{} clause of $s_j, 1 \le j \le n$. Executing $s_c$ first exe cutes $f_1, \ldots, f_n$ in innermost-clause-first order. Then, if $s_E$ is a case clause, control is transferred to the case clause. Otherwise, $s_E$ is nece ssarily a loop and execution resumes after the last statement in the loop body. |
6330 | 6343 |
6331 \commentary{ | 6344 \commentary{ |
6332 In a while loop, that would be the boolean expression before the body. In a do loop, it would be the boolean expression after the body. In a for loop, it would be the increment clause. In other words, execution continues to the next itera tion of the loop. | 6345 In a while loop, that would be the boolean expression before the body. In a do loop, it would be the boolean expression after the body. In a for loop, it would be the increment clause. In other words, execution continues to the next itera tion of the loop. |
6333 } | 6346 } |
6334 | 6347 |
6335 \LMHash{} | 6348 \LMHash{} |
6336 If $s_E$ is an asynchronous for loop (\ref{asynchronousFor-in}), let $a_k$ be t he set of asynchronous for loops and yield-each statements (\ref{yieldEach}) enc losing $s_c$ that are enclosed in $s_E , 1 \le k \le m$, where $a_k$ is enclosed in $a_{k+1}$. The stream subscriptions associated with $a_j$ are canceled, $1 \le j \le m$, innermost first, so that $a_j$ is canceled before $a_{j+1}$. | 6349 If $s_E$ is an asynchronous for loop (\ref{asynchronousFor-in}), let $a_k$ be t he set of asynchronous for loops and yield-each statements (\ref{yieldEach}) enc losing $s_c$ that are enclosed in $s_E , 1 \le k \le m$, where $a_k$ is enclosed in $a_{k+1}$. The stream subscriptions associated with $a_j$ are canceled, $1 \le j \le m$, innermost first, so that $a_j$ is canceled before $a_{j+1}$. |
6337 | 6350 |
6338 \subsection{ Yield and Yield-Each} | 6351 \subsection{ Yield and Yield-Each} |
6339 \LMLabel{yieldAndYieldEach} | 6352 \LMLabel{yieldAndYieldEach} |
6340 | 6353 |
6341 \subsubsection{ Yield} | 6354 \subsubsection{ Yield} |
6342 \LMLabel{yield} | 6355 \LMLabel{yield} |
6343 | 6356 |
6344 \LMHash{} | 6357 \LMHash{} |
6345 The {\em yield statement} adds an element to the result of a generator function (\ref{functions}). | 6358 The {\em yield statement} adds an element to the result of a generator function (\ref{functions}). |
6346 | 6359 |
6347 \begin{grammar} | 6360 \begin{grammar} |
6348 {\bf yieldStatement:} | 6361 {\bf yieldStatement:} |
6349 \YIELD{} expression `{\escapegrammar ;}' | 6362 \YIELD{} expression `{\escapegrammar ;}' |
6350 . | 6363 . |
6351 \end{grammar} | 6364 \end{grammar} |
6352 | 6365 |
6353 \LMHash{} | 6366 \LMHash{} |
6354 Execution of a statement $s$ of the form \code{\YIELD{} $e$;} proceeds as follo ws: | 6367 Execution of a statement $s$ of the form \code{\YIELD{} $e$;} proceeds as follo ws: |
6355 | 6368 |
6356 \LMHash{} | 6369 \LMHash{} |
6357 First, the expression $e$ is evaluated to an object $o$. If the enclosing functi on $m$ is marked \ASYNC* (\ref{functions}) and the stream $u$ associated with $m $ has been paused, then execution of $m$ is suspended until $u$ is resumed or c anceled. | 6370 First, the expression $e$ is evaluated to an object $o$. If the enclosing functi on $m$ is marked \ASYNC* (\ref{functions}) and the stream $u$ associated with $m $ has been paused, then execution of $m$ is suspended until $u$ is resumed or c anceled. |
6358 | 6371 |
6359 \LMHash{} | 6372 \LMHash{} |
6360 Next, $o$ is added to the iterable or stream associated with the immediately enc losing function. | 6373 Next, $o$ is added to the iterable or stream associated with the immediately enc losing function. |
6361 | 6374 |
6362 \LMHash{} | 6375 \LMHash{} |
6363 If the enclosing function $m$ is marked \ASYNC* and the stream $u$ associated wi th $m$ has been canceled, then let $c$ be the \FINALLY{} clause (\ref{try}) of t he innermost enclosing try-finally statement, if any. If $c$ is defined, let $h$ be the handler induced by $c$. If $h$ is defined, control is transferred to $h$ . If $h$ is undefined, the immediately enclosing function terminates. | 6376 If the enclosing function $m$ is marked \ASYNC* and the stream $u$ associated wi th $m$ has been canceled, then let $c$ be the \FINALLY{} clause (\ref{try}) of t he innermost enclosing try-finally statement, if any. If $c$ is defined, let $h$ be the handler induced by $c$. If $h$ is defined, control is transferred to $h$ . If $h$ is undefined, the immediately enclosing function terminates. |
6364 | 6377 |
6365 \rationale{ | 6378 \rationale{ |
6366 The stream associated with an asynchronous generator could be canceled by any co de with a reference to that stream at any point where the generator was passivat ed. Such a cancellation constitutes an irretrievable error for the generator. A t this point, the only plausible action for the generator is to clean up after i tself via its \FINALLY{} clauses. | 6379 The stream associated with an asynchronous generator could be canceled by any co de with a reference to that stream at any point where the generator was passivat ed. Such a cancellation constitutes an irretrievable error for the generator. A t this point, the only plausible action for the generator is to clean up after i tself via its \FINALLY{} clauses. |
6367 } | 6380 } |
6368 | 6381 |
6369 \LMHash{} | 6382 \LMHash{} |
6370 Otherwise, if the enclosing function $m$ is marked \ASYNC* (\ref{functions}) the n the enclosing function may suspend. | 6383 Otherwise, if the enclosing function $m$ is marked \ASYNC* (\ref{functions}) the n the enclosing function may suspend. |
6371 | 6384 |
6372 \rationale { | 6385 \rationale { |
6373 If a \YIELD{} occurred inside an infinite loop and the enclosing function never suspended, there might not be an opportunity for consumers of the enclosing str eam to run and access the data in the stream. The stream might then accumulate an unbounded number of elements. Such a situation is untenable. Therefore, we al low the enclosing function to be suspended when a new value is added to its asso ciated stream. However, it is not essential (and in fact, can be quite costly) t o suspend the function on every \YIELD{}. The implementation is free to decide h ow often to suspend the enclosing function. The only requirement is that consume rs are not blocked indefinitely. | 6386 If a \YIELD{} occurred inside an infinite loop and the enclosing function never suspended, there might not be an opportunity for consumers of the enclosing str eam to run and access the data in the stream. The stream might then accumulate an unbounded number of elements. Such a situation is untenable. Therefore, we al low the enclosing function to be suspended when a new value is added to its asso ciated stream. However, it is not essential (and in fact, can be quite costly) t o suspend the function on every \YIELD{}. The implementation is free to decide h ow often to suspend the enclosing function. The only requirement is that consume rs are not blocked indefinitely. |
6374 } | 6387 } |
6375 | 6388 |
6376 | 6389 |
6377 \LMHash{} | 6390 \LMHash{} |
6378 If the enclosing function $m$ is marked \SYNC* (\ref{functions}) then: | 6391 If the enclosing function $m$ is marked \SYNC* (\ref{functions}) then: |
6379 \begin{itemize} | 6392 \begin{itemize} |
6380 \item | 6393 \item |
6381 Execution of the function $m$ immediately enclosing $s$ is suspended until the n ullary method \code{moveNext()} is invoked upon the iterator used to initiate th e current invocation of $m$. | 6394 Execution of the function $m$ immediately enclosing $s$ is suspended until the n ullary method \code{moveNext()} is invoked upon the iterator used to initiate th e current invocation of $m$. |
6382 \item | 6395 \item |
6383 The current call to \code{moveNext()} returns \TRUE. | 6396 The current call to \code{moveNext()} returns \TRUE. |
6384 \end{itemize} | 6397 \end{itemize} |
6385 | 6398 |
6386 \LMHash{} | 6399 \LMHash{} |
6387 It is a compile-time error if a yield statement appears in a function that is no t a generator function. | 6400 It is a compile-time error if a yield statement appears in a function that is no t a generator function. |
6388 | 6401 |
6389 \LMHash{} | 6402 \LMHash{} |
6390 Let $T$ be the static type of $e$ and let $f$ be the immediately enclosing funct ion. It is a static type warning if either: | 6403 Let $T$ be the static type of $e$ and let $f$ be the immediately enclosing funct ion. It is a static type warning if either: |
6391 \begin{itemize} | 6404 \begin{itemize} |
6392 \item | 6405 \item |
6393 the body of $f$ is marked \ASYNC* and the type \code{Stream$<$T$>$} may not be assigned to the declared return type of $f$. | 6406 the body of $f$ is marked \ASYNC* and the type \code{Stream$<$T$>$} may not be assigned to the declared return type of $f$. |
6394 \item | 6407 \item |
6395 the body of $f$ is marked \SYNC* and the type \code{Iterable$<$T$>$} may not be assigned to the declared return type of $f$. | 6408 the body of $f$ is marked \SYNC* and the type \code{Iterable$<$T$>$} may not be assigned to the declared return type of $f$. |
6396 \end{itemize} | 6409 \end{itemize} |
6397 | 6410 |
6398 | 6411 |
6399 \subsubsection{ Yield-Each} | 6412 \subsubsection{ Yield-Each} |
6400 \LMLabel{yieldEach} | 6413 \LMLabel{yieldEach} |
6401 | 6414 |
6402 \LMHash{} | 6415 \LMHash{} |
6403 The {\em yield-each statement} adds a series of values to the result of a gener ator function (\ref{functions}). | 6416 The {\em yield-each statement} adds a series of values to the result of a gener ator function (\ref{functions}). |
6404 | 6417 |
6405 \begin{grammar} | 6418 \begin{grammar} |
6406 {\bf yieldEachStatement:} | 6419 {\bf yieldEachStatement:} |
6407 \YIELD* expression `{\escapegrammar ;}' | 6420 \YIELD* expression `{\escapegrammar ;}' |
6408 . | 6421 . |
6409 \end{grammar} | 6422 \end{grammar} |
6410 | 6423 |
6411 \LMHash{} | 6424 \LMHash{} |
6412 Execution of a statement $s$ of the form \code{\YIELD* $e$;} proceeds as follow s: | 6425 Execution of a statement $s$ of the form \code{\YIELD* $e$;} proceeds as follow s: |
6413 | 6426 |
6414 \LMHash{} | 6427 \LMHash{} |
6415 First, the expression $e$ is evaluated to an object $o$. | 6428 First, the expression $e$ is evaluated to an object $o$. |
6416 | 6429 |
6417 \LMHash{} | 6430 \LMHash{} |
6418 If the immediately enclosing function $m$ is marked \SYNC* (\ref{functions}), th en: | 6431 If the immediately enclosing function $m$ is marked \SYNC* (\ref{functions}), th en: |
6419 \begin{enumerate} | 6432 \begin{enumerate} |
6420 \item It is a dynamic error if the class of $o$ does not implement \code{Iterabl e}. Otherwise | 6433 \item It is a dynamic error if the class of $o$ does not implement \code{Iterabl e}. Otherwise |
6421 \item The method \cd{iterator} is invoked upon $o$ returning an object $i$. | 6434 \item The method \cd{iterator} is invoked upon $o$ returning an object $i$. |
6422 \item \label{moveNext} The \cd{moveNext} method of $i$ is invoked on it with no arguments. If \cd{moveNext} returns \FALSE{} execution of $s$ is complete. Other wise | 6435 \item \label{moveNext} The \cd{moveNext} method of $i$ is invoked on it with no arguments. If \cd{moveNext} returns \FALSE{} execution of $s$ is complete. Other wise |
6423 \item The getter \cd{current} is invoked on $i$. If the invocation raises an exc eption $ex$, execution of $s$ throws $ex$. Otherwise, the result $x$ of the gett er invocation is added to the iterable associated with $m$. | 6436 \item The getter \cd{current} is invoked on $i$. If the invocation raises an exc eption $ex$, execution of $s$ throws $ex$. Otherwise, the result $x$ of the gett er invocation is added to the iterable associated with $m$. |
6424 Execution of the function $m$ immediately enclosing $s$ is suspended until the n ullary method \code{moveNext()} is invoked upon the iterator used to initiate th e current invocation of $m$, at which point execution of $s$ continues at \ref{m oveNext}. | 6437 Execution of the function $m$ immediately enclosing $s$ is suspended until the n ullary method \code{moveNext()} is invoked upon the iterator used to initiate th e current invocation of $m$, at which point execution of $s$ continues at \ref{m oveNext}. |
6425 \item | 6438 \item |
6426 The current call to \code{moveNext()} returns \TRUE. | 6439 The current call to \code{moveNext()} returns \TRUE. |
6427 \end{enumerate} | 6440 \end{enumerate} |
6428 | 6441 |
6429 \LMHash{} | 6442 \LMHash{} |
6430 If $m$ is marked \ASYNC* (\ref{functions}), then: | 6443 If $m$ is marked \ASYNC* (\ref{functions}), then: |
6431 \begin{itemize} | 6444 \begin{itemize} |
6432 \item It is a dynamic error if the class of $o$ does not implement \code{Stream }. Otherwise | 6445 \item It is a dynamic error if the class of $o$ does not implement \code{Stream }. Otherwise |
6433 \item For each element $x$ of $o$: | 6446 \item For each element $x$ of $o$: |
6434 \begin{itemize} | 6447 \begin{itemize} |
6435 \item | 6448 \item |
6436 If the stream $u$ associated with $m$ has been paused, then execution of $m$ is suspended until $u$ is resumed or canceled. | 6449 If the stream $u$ associated with $m$ has been paused, then execution of $m$ is suspended until $u$ is resumed or canceled. |
6437 \item | 6450 \item |
6438 If the stream $u$ associated with $m$ has been canceled, then let $c$ be the \FI NALLY{} clause (\ref{try}) of the innermost enclosing try-finally statement, if any. If $c$ is defined, let $h$ be the handler induced by $c$. If $h$ is define d, control is transferred to $h$. If $h$ is undefined, the immediately enclosing function terminates. | 6451 If the stream $u$ associated with $m$ has been canceled, then let $c$ be the \FI NALLY{} clause (\ref{try}) of the innermost enclosing try-finally statement, if any. If $c$ is defined, let $h$ be the handler induced by $c$. If $h$ is define d, control is transferred to $h$. If $h$ is undefined, the immediately enclosing function terminates. |
6439 \item | 6452 \item |
6440 Otherwise, $x$ is added to the stream associated with $m$ in the order it appea rs in $o$. The function $m$ may suspend. | 6453 Otherwise, $x$ is added to the stream associated with $m$ in the order it appea rs in $o$. The function $m$ may suspend. |
6441 \end{itemize} | 6454 \end{itemize} |
6442 \item If the stream $o$ is done, execution of $s$ is complete. | 6455 \item If the stream $o$ is done, execution of $s$ is complete. |
6443 \end{itemize} | 6456 \end{itemize} |
6444 | 6457 |
6445 | 6458 |
6446 \LMHash{} | 6459 \LMHash{} |
6447 It is a compile-time error if a yield-each statement appears in a function that is not a generator function. | 6460 It is a compile-time error if a yield-each statement appears in a function that is not a generator function. |
6448 | 6461 |
6449 \LMHash{} | 6462 \LMHash{} |
6450 Let $T$ be the static type of $e$ and let $f$ be the immediately enclosing funct ion. It is a static type warning if $T$ may not be assigned to the declared ret urn type of $f$. If $f$ is synchronous it is a static type warning if $T$ may not be assigned to \code{Iterable}. If $f$ is asynchronous it is a static type warning if $T$ may not be assigned to \code{Stream}. | 6463 Let $T$ be the static type of $e$ and let $f$ be the immediately enclosing funct ion. It is a static type warning if $T$ may not be assigned to the declared ret urn type of $f$. If $f$ is synchronous it is a static type warning if $T$ may not be assigned to \code{Iterable}. If $f$ is asynchronous it is a static type warning if $T$ may not be assigned to \code{Stream}. |
6451 | 6464 |
6452 | 6465 |
6453 \subsection{ Assert} | 6466 \subsection{ Assert} |
6454 \LMLabel{assert} | 6467 \LMLabel{assert} |
6455 | 6468 |
6456 \LMHash{} | 6469 \LMHash{} |
6457 An {\em assert statement} is used to disrupt normal execution if a given boolean condition does not hold. | 6470 An {\em assert statement} is used to disrupt normal execution if a given boolean condition does not hold. |
6458 | 6471 |
6459 \begin{grammar} | 6472 \begin{grammar} |
6460 {\bf assertStatement:} | 6473 {\bf assertStatement:} |
6461 assert `(' conditionalExpression `)' `{\escapegrammar ;}' | 6474 assert `(' conditionalExpression `)' `{\escapegrammar ;}' |
6462 . | 6475 . |
6463 \end{grammar} | 6476 \end{grammar} |
6464 | 6477 |
6465 \LMHash{} | 6478 \LMHash{} |
6466 The assert statement has no effect in production mode. In checked mode, executio n of an assert statement \code{\ASSERT{}($e$);} proceeds as follows: | 6479 The assert statement has no effect in production mode. In checked mode, executio n of an assert statement \code{\ASSERT{}($e$);} proceeds as follows: |
6467 | 6480 |
6468 \LMHash{} | 6481 \LMHash{} |
6469 The conditional expression $e$ is evaluated to an object $o$. If the class of $o $ is a subtype of \code{Function} then let $r$ be the result of invoking $o$ wit h no arguments. Otherwise, let $r$ be $o$. | 6482 The conditional expression $e$ is evaluated to an object $o$. If the class of $o $ is a subtype of \code{Function} then let $r$ be the result of invoking $o$ wit h no arguments. Otherwise, let $r$ be $o$. |
6470 It is a dynamic type error if $o$ is not of type \code{bool} or of type \code{Fu nction}, or if $r$ is not of type \code{bool}. If $r$ is \FALSE{}, we say that the assertion failed. If $r$ is \TRUE{}, we say that the assertion succeeded. If the assertion succeeded, execution of the assert statement is complete. If the assertion failed, an \code{AssertionError} is thrown. | 6483 It is a dynamic type error if $o$ is not of type \code{bool} or of type \code{Fu nction}, or if $r$ is not of type \code{bool}. If $r$ is \FALSE{}, we say that the assertion failed. If $r$ is \TRUE{}, we say that the assertion succeeded. If the assertion succeeded, execution of the assert statement is complete. If the assertion failed, an \code{AssertionError} is thrown. |
6471 | 6484 |
6472 %\Q{Might be cleaner to define it as \code{if (!$e$) \{\THROW{} \NEW{} Assertion Error();\}} (in checked mode only). | 6485 %\Q{Might be cleaner to define it as \code{if (!$e$) \{\THROW{} \NEW{} Assertion Error();\}} (in checked mode only). |
6473 %What about an error message as part of the assert?} | 6486 %What about an error message as part of the assert?} |
6474 | 6487 |
6475 \LMHash{} | 6488 \LMHash{} |
6476 It is a static type warning if the type of $e$ may not be assigned to either \ code{bool} or $() \rightarrow$ \code{bool}. | 6489 It is a static type warning if the type of $e$ may not be assigned to either \ code{bool} or $() \rightarrow$ \code{bool}. |
6477 | 6490 |
6478 \rationale{Why is this a statement, not a built in function call? Because it is handled magically so it has no effect and no overhead in production mode. Also, in the absence of final methods. one could not prevent it being overridden (thou gh there is no real harm in that). It cannot be viewed as a function call that is being optimized away because the argument might have side effects. | 6491 \rationale{Why is this a statement, not a built in function call? Because it is handled magically so it has no effect and no overhead in production mode. Also, in the absence of final methods. one could not prevent it being overridden (thou gh there is no real harm in that). It cannot be viewed as a function call that is being optimized away because the argument might have side effects. |
6479 } | 6492 } |
6480 | 6493 |
6481 %If a lexically visible declaration named \code{assert} is in scope, an assert s tatement | 6494 %If a lexically visible declaration named \code{assert} is in scope, an assert s tatement |
6482 %\code{\ASSERT{} (e); } | 6495 %\code{\ASSERT{} (e); } |
6483 %is interpreted as an expression statement \code{(assert(e));} . | 6496 %is interpreted as an expression statement \code{(assert(e));} . |
6484 | 6497 |
6485 %\rationale{ | 6498 %\rationale{ |
6486 %Since \ASSERT{} is a built-in identifier, one might define a function or method with this name. | 6499 %Since \ASSERT{} is a built-in identifier, one might define a function or method with this name. |
6487 %It is impossible to distinguish as \ASSERT{} statement from a method invocation in such a situation. | 6500 %It is impossible to distinguish as \ASSERT{} statement from a method invocation in such a situation. |
6488 %One could choose to always interpret such code as an \ASSERT{} statement. Or we could choose to give priority to any lexically visible user defined function. The former can cause rather puzzling situations, e.g.,} | 6501 %One could choose to always interpret such code as an \ASSERT{} statement. Or we could choose to give priority to any lexically visible user defined function. The former can cause rather puzzling situations, e.g.,} |
6489 | 6502 |
6490 %\begin{dartCode} | 6503 %\begin{dartCode} |
6491 % assert(bool b)\{print('My Personal Assertion \$b');\} | 6504 % assert(bool b)\{print('My Personal Assertion \$b');\} |
6492 | 6505 |
6493 % assert\_puzzler() \{ | 6506 % assert\_puzzler() \{ |
6494 % (assert(\TRUE{})); // prints true | 6507 % (assert(\TRUE{})); // prints true |
6495 % assert(\TRUE{}); // would do nothing | 6508 % assert(\TRUE{}); // would do nothing |
6496 % (assert(\FALSE{})); // prints false | 6509 % (assert(\FALSE{})); // prints false |
6497 % assert(\FALSE{}); // would throw if asserts enabled, or do nothing otherwise | 6510 % assert(\FALSE{}); // would throw if asserts enabled, or do nothing otherwise |
6498 % \} | 6511 % \} |
6499 | 6512 |
6500 %\end{dartCode} | 6513 %\end{dartCode} |
6501 | 6514 |
6502 %\rationale{therefore, we opt for the second option. Alternately, one could insi st that assert be a reserved word, which may have an undesirable effect with res pect to compatibility of Javascript code ported to Dart.} | 6515 %\rationale{therefore, we opt for the second option. Alternately, one could insi st that assert be a reserved word, which may have an undesirable effect with res pect to compatibility of Javascript code ported to Dart.} |
6503 | 6516 |
6504 \section{Libraries and Scripts} | 6517 \section{Libraries and Scripts} |
6505 \LMLabel{librariesAndScripts} | 6518 \LMLabel{librariesAndScripts} |
6506 | 6519 |
6507 \LMHash{} | 6520 \LMHash{} |
6508 A Dart program consists of one or more libraries, and may be built out of one or more {\em compilation units}. A compilation unit may be a library or a part (\r ef{parts}). | 6521 A Dart program consists of one or more libraries, and may be built out of one or more {\em compilation units}. A compilation unit may be a library or a part (\r ef{parts}). |
6509 | 6522 |
6510 \LMHash{} | 6523 \LMHash{} |
6511 A library consists of (a possibly empty) set of imports, a set of exports, and a set of top-level declarations. A top-level declaration is either a class (\ref {classes}), a type alias declaration (\ref{typedef}), a function (\ref{functions }) or a variable declaration (\ref{variables}). The members of a library $L$ are those top level declarations given within $L$. | 6524 A library consists of (a possibly empty) set of imports, a set of exports, and a set of top-level declarations. A top-level declaration is either a class (\ref {classes}), a type alias declaration (\ref{typedef}), a function (\ref{functions }) or a variable declaration (\ref{variables}). The members of a library $L$ are those top level declarations given within $L$. |
6512 | 6525 |
6513 \begin{grammar} | 6526 \begin{grammar} |
6514 {\bf topLevelDefinition:}classDefinition; | 6527 {\bf topLevelDefinition:}classDefinition; |
6515 enumType; | 6528 enumType; |
6516 % classDefinitionOrInterfaceInjection; | 6529 % classDefinitionOrInterfaceInjection; |
6517 % interfaceDefinitionOrInterfaceInjection; | 6530 % interfaceDefinitionOrInterfaceInjection; |
6518 % mixinApplication; | 6531 % mixinApplication; |
6519 typeAlias; | 6532 typeAlias; |
6520 \EXTERNAL{}? functionSignature `{\escapegrammar ;}'; | 6533 \EXTERNAL{}? functionSignature `{\escapegrammar ;}'; |
6521 \EXTERNAL{}? getterSignature `{\escapegrammar ;}'; | 6534 \EXTERNAL{}? getterSignature `{\escapegrammar ;}'; |
6522 \EXTERNAL{}? setterSignature `{\escapegrammar ;}'; | 6535 \EXTERNAL{}? setterSignature `{\escapegrammar ;}'; |
6523 functionSignature functionBody; | 6536 functionSignature functionBody; |
6524 returnType? \GET{} identifier functionBody; | 6537 returnType? \GET{} identifier functionBody; |
6525 returnType? \SET{} identifier formalParameterList functionBody; | 6538 returnType? \SET{} identifier formalParameterList functionBody; |
6526 (\FINAL{} $|$ \CONST{}) type? staticFinalDeclarationList `{\escapegrammar ;}'; | 6539 (\FINAL{} $|$ \CONST{}) type? staticFinalDeclarationList `{\escapegrammar ;}'; |
6527 variableDeclaration `{\escapegrammar ;}' | 6540 variableDeclaration `{\escapegrammar ;}' |
6528 . | 6541 . |
6529 | 6542 |
6530 {\bf getOrSet:} \GET{}; | 6543 {\bf getOrSet:} \GET{}; |
6531 \SET{} | 6544 \SET{} |
6532 . | 6545 . |
6533 | 6546 |
6534 % classDefinitionOrInterfaceInjection: | 6547 % classDefinitionOrInterfaceInjection: |
6535 % classDefinition; | 6548 % classDefinition; |
6536 % classInterfaceInjection | 6549 % classInterfaceInjection |
6537 % . | 6550 % . |
6538 | 6551 |
6539 %interfaceDefinitionOrInterfaceInjection: | 6552 %interfaceDefinitionOrInterfaceInjection: |
6540 % interfaceDefinition; | 6553 % interfaceDefinition; |
6541 % interfaceInterfaceInjection | 6554 % interfaceInterfaceInjection |
6542 % . | 6555 % . |
6543 | 6556 |
6544 {\bf libraryDefinition:} | 6557 {\bf libraryDefinition:} |
6545 % library '\{' libraryBody '\}' | 6558 % library '\{' libraryBody '\}' |
6546 scriptTag? libraryName? importOrExport* partDirective* topLevelDefinition* | 6559 scriptTag? libraryName? importOrExport* partDirective* topLevelDefinition* |
6547 . | 6560 . |
6548 | 6561 |
6549 {\bf scriptTag:} | 6562 {\bf scriptTag:} |
6550 `\#!' {\escapegrammar (\~{}NEWLINE)*} NEWLINE | 6563 `\#!' {\escapegrammar (\~{}NEWLINE)*} NEWLINE |
6551 . | 6564 . |
6552 | 6565 |
6553 {\bf libraryName:} | 6566 {\bf libraryName:} |
6554 metadata \LIBRARY{} identifier (`{\escapegrammar .}' identifier)* `{\escapegr ammar ;}' | 6567 metadata \LIBRARY{} identifier (`{\escapegrammar .}' identifier)* `{\escapegr ammar ;}' |
6555 . | 6568 . |
6556 | 6569 |
6557 {\bf importOrExport:}libraryImport ; | 6570 {\bf importOrExport:}libraryImport ; |
6558 libraryExport | 6571 libraryExport |
6559 \end{grammar} | 6572 \end{grammar} |
6560 | 6573 |
6561 \LMHash{} | 6574 \LMHash{} |
6562 Libraries may be {\em explicitly named} or {\em implicitly named}. An explicitl y named library begins with the word \LIBRARY{} (possibly prefaced with any ap plicable metadata annotations), followed by a qualified identifier that gives th e name of the library. | 6575 Libraries may be {\em explicitly named} or {\em implicitly named}. An explicitl y named library begins with the word \LIBRARY{} (possibly prefaced with any ap plicable metadata annotations), followed by a qualified identifier that gives th e name of the library. |
6563 | 6576 |
6564 \commentary{ | 6577 \commentary{ |
6565 Technically, each dot and identifier is a separate token and so spaces between them are acceptable. However, the actual library name is the concatenation of th e simple identifiers and dots and contains no spaces. | 6578 Technically, each dot and identifier is a separate token and so spaces between them are acceptable. However, the actual library name is the concatenation of th e simple identifiers and dots and contains no spaces. |
6566 } | 6579 } |
6567 | 6580 |
6568 \LMHash{} | 6581 \LMHash{} |
6569 An implicitly named library has the empty string as its name. | 6582 An implicitly named library has the empty string as its name. |
6570 | 6583 |
6571 \rationale{ | 6584 \rationale{ |
6572 The name of a library is used to tie it to separately compiled parts of the libr ary (called parts) and can be used for printing and, more generally, reflection . The name may be relevant for further language evolution. | 6585 The name of a library is used to tie it to separately compiled parts of the libr ary (called parts) and can be used for printing and, more generally, reflection . The name may be relevant for further language evolution. |
6573 } | 6586 } |
6574 | 6587 |
6575 \commentary{ | 6588 \commentary{ |
6576 Libraries intended for widespread use should avoid name collisions. Dart's \cod e{pub} package management system provides a mechanism for doing so. Each pub pa ckage is guaranteed a unique name, effectively enforcing a global namespace. | 6589 Libraries intended for widespread use should avoid name collisions. Dart's \cod e{pub} package management system provides a mechanism for doing so. Each pub pa ckage is guaranteed a unique name, effectively enforcing a global namespace. |
6577 } | 6590 } |
6578 | 6591 |
6579 \LMHash{} | 6592 \LMHash{} |
6580 A library may optionally begin with a {\em script tag}. Script tags are intende d for use with scripts (\ref{scripts}). A script tag can be used to identify th e interpreter of the script to whatever computing environment the script is embe dded in. The script tag must appear before any whitespace or comments. A script tag begins with the characters \#! and ends at the end of the line. Any charac ters that follow \#! in the script tag are ignored by the Dart implementation. | 6593 A library may optionally begin with a {\em script tag}. Script tags are intende d for use with scripts (\ref{scripts}). A script tag can be used to identify th e interpreter of the script to whatever computing environment the script is embe dded in. The script tag must appear before any whitespace or comments. A script tag begins with the characters \#! and ends at the end of the line. Any charac ters that follow \#! in the script tag are ignored by the Dart implementation. |
6581 | 6594 |
6582 \LMHash{} | 6595 \LMHash{} |
6583 Libraries are units of privacy. A private declaration declared within a library $L$ can only be accessed by code within $L$. Any attempt to access a private mem ber declaration from outside $L$ will cause a method, getter or setter lookup fa ilure. | 6596 Libraries are units of privacy. A private declaration declared within a library $L$ can only be accessed by code within $L$. Any attempt to access a private mem ber declaration from outside $L$ will cause a method, getter or setter lookup fa ilure. |
6584 | 6597 |
6585 \commentary{Since top level privates are not imported, using the top level priva tes of another library is never possible. } | 6598 \commentary{Since top level privates are not imported, using the top level priva tes of another library is never possible. } |
6586 | 6599 |
6587 \LMHash{} | 6600 \LMHash{} |
6588 The {\em public namespace} of library $L$ is the mapping that maps the simple na me of each public top-level member $m$ of $L$ to $m$. | 6601 The {\em public namespace} of library $L$ is the mapping that maps the simple na me of each public top-level member $m$ of $L$ to $m$. |
6589 The scope of a library $L$ consists of the names introduced by all top-level dec larations declared in $L$, and the names added by $L$'s imports (\ref{imports}). | 6602 The scope of a library $L$ consists of the names introduced by all top-level dec larations declared in $L$, and the names added by $L$'s imports (\ref{imports}). |
6590 | 6603 |
6591 | 6604 |
6592 \subsection{Imports} | 6605 \subsection{Imports} |
6593 \LMLabel{imports} | 6606 \LMLabel{imports} |
6594 | 6607 |
6595 \LMHash{} | 6608 \LMHash{} |
6596 An {\em import} specifies a library to be used in the scope of another library. | 6609 An {\em import} specifies a library to be used in the scope of another library. |
6597 \begin{grammar} | 6610 \begin{grammar} |
6598 {\bf libraryImport:} | 6611 {\bf libraryImport:} |
6599 metadata importSpecification | 6612 metadata importSpecification |
6600 . | 6613 . |
6601 | 6614 |
6602 {\bf importSpecification:} | 6615 {\bf importSpecification:} |
6603 \IMPORT{} uri (\AS{} identifier)? combinator* `{\escapegrammar ;}'; | 6616 \IMPORT{} uri (\AS{} identifier)? combinator* `{\escapegrammar ;}'; |
6604 \IMPORT{} uri \DEFERRED{} \AS{} identifier combinator* `{\escapegrammar ; }' | 6617 \IMPORT{} uri \DEFERRED{} \AS{} identifier combinator* `{\escapegrammar ; }' |
6605 . | 6618 . |
6606 | 6619 |
6607 {\bf combinator:}\SHOW{} identifierList; | 6620 {\bf combinator:}\SHOW{} identifierList; |
6608 \HIDE{} identifierList | 6621 \HIDE{} identifierList |
6609 . | 6622 . |
6610 | 6623 |
6611 {\bf identifierList:} | 6624 {\bf identifierList:} |
6612 identifier (, identifier)* | 6625 identifier (, identifier)* |
6613 \end{grammar} | 6626 \end{grammar} |
6614 | 6627 |
6615 | 6628 |
6616 \LMHash{} | 6629 \LMHash{} |
6617 An import specifies a URI $x$ where the declaration of an imported library is to be found. | 6630 An import specifies a URI $x$ where the declaration of an imported library is to be found. |
6618 | 6631 |
6619 \LMHash{} | 6632 \LMHash{} |
6620 Imports may be {\em deferred} or {\em immediate}. A deferred import is distingui shed by the appearance of the built-in identifier \DEFERRED{} after the URI. Any import that is not deferred is immediate. | 6633 Imports may be {\em deferred} or {\em immediate}. A deferred import is distingui shed by the appearance of the built-in identifier \DEFERRED{} after the URI. Any import that is not deferred is immediate. |
6621 | 6634 |
6622 \LMHash{} | 6635 \LMHash{} |
6623 It is a compile-time error if the specified URI of an immediate import does not refer to a library declaration. The interpretation of URIs is described in sec tion \ref{uris} below. | 6636 It is a compile-time error if the specified URI of an immediate import does not refer to a library declaration. The interpretation of URIs is described in sec tion \ref{uris} below. |
6624 | 6637 |
6625 \LMHash{} | 6638 \LMHash{} |
6626 It is a static warning if the specified URI of a deferred import does not refer to a library declaration. | 6639 It is a static warning if the specified URI of a deferred import does not refer to a library declaration. |
6627 | 6640 |
6628 \rationale{ | 6641 \rationale{ |
6629 One cannot detect the problem at compile time because compilation often occurs during execution and one does not know what the URI refers to. However the dev elopment environment should detect the problem. | 6642 One cannot detect the problem at compile time because compilation often occurs during execution and one does not know what the URI refers to. However the dev elopment environment should detect the problem. |
6630 } | 6643 } |
6631 | 6644 |
6632 | 6645 |
6633 \LMHash{} | 6646 \LMHash{} |
6634 The {\em current library} is the library currently being compiled. The import mo difies the namespace of the current library in a manner that is determined by t he imported library and by the optional elements of the import. | 6647 The {\em current library} is the library currently being compiled. The import mo difies the namespace of the current library in a manner that is determined by t he imported library and by the optional elements of the import. |
6635 | 6648 |
6636 \LMHash{} | 6649 \LMHash{} |
6637 An immediate import directive $I$ may optionally include a prefix clause of the form \AS{} \code{Id} used to prefix names imported by $I$. A deferred import mus t include a prefix clause or a compile time error occurs. It is a compile-time e rror if a prefix used in a deferred import is used in another import clause. | 6650 An immediate import directive $I$ may optionally include a prefix clause of the form \AS{} \code{Id} used to prefix names imported by $I$. A deferred import mus t include a prefix clause or a compile time error occurs. It is a compile-time e rror if a prefix used in a deferred import is used in another import clause. |
6638 | 6651 |
6639 \LMHash{} | 6652 \LMHash{} |
6640 An import directive $I$ may optionally include a namespace combinator clauses us ed to restrict the set of names imported by $I$. Currently, two namespace combin ators are supported: \HIDE{} and \SHOW{}. | 6653 An import directive $I$ may optionally include a namespace combinator clauses us ed to restrict the set of names imported by $I$. Currently, two namespace combin ators are supported: \HIDE{} and \SHOW{}. |
6641 | 6654 |
6642 \LMHash{} | 6655 \LMHash{} |
6643 Let $I$ be an import directive that refers to a URI via the string $s_1$. Evalua tion of $I$ proceeds as follows: | 6656 Let $I$ be an import directive that refers to a URI via the string $s_1$. Evalua tion of $I$ proceeds as follows: |
6644 | 6657 |
6645 \LMHash{} | 6658 \LMHash{} |
(...skipping 15 matching lines...) Expand all Loading... | |
6661 | 6674 |
6662 The static type of the prefix object $p$ is a unique interface type that has tho se members whose names and signatures are listed above. | 6675 The static type of the prefix object $p$ is a unique interface type that has tho se members whose names and signatures are listed above. |
6663 | 6676 |
6664 \LMHash{} | 6677 \LMHash{} |
6665 After a call succeeds, the name $p$ is mapped to a non-deferred prefix object as described below. In addition, the prefix object also supports the \code{loadLib rary} method, and so it is possible to call \code{loadLibrary} again. If a call fails, nothing happens, and one again has the option to call \code{loadLibrary} again. Whether a repeated call to \code{loadLibrary} succeeds will vary as descr ibed below. | 6678 After a call succeeds, the name $p$ is mapped to a non-deferred prefix object as described below. In addition, the prefix object also supports the \code{loadLib rary} method, and so it is possible to call \code{loadLibrary} again. If a call fails, nothing happens, and one again has the option to call \code{loadLibrary} again. Whether a repeated call to \code{loadLibrary} succeeds will vary as descr ibed below. |
6666 | 6679 |
6667 \LMHash{} | 6680 \LMHash{} |
6668 The effect of a repeated call to \code{$p$.loadLibrary} is as follows: | 6681 The effect of a repeated call to \code{$p$.loadLibrary} is as follows: |
6669 \begin{itemize} | 6682 \begin{itemize} |
6670 \item | 6683 \item |
6671 If another call to \code{$p$.loadLibrary} has already succeeded, the repeated ca ll also succeeds. | 6684 If another call to \code{$p$.loadLibrary} has already succeeded, the repeated ca ll also succeeds. |
6672 Otherwise, | 6685 Otherwise, |
6673 \item | 6686 \item |
6674 If another call to to \code{$p$.loadLibrary} has failed: | 6687 If another call to to \code{$p$.loadLibrary} has failed: |
6675 \begin{itemize} | 6688 \begin{itemize} |
6676 \item | 6689 \item |
6677 If the failure is due to a compilation error, the repeated call fails for the sa me reason. | 6690 If the failure is due to a compilation error, the repeated call fails for the sa me reason. |
6678 \item | 6691 \item |
6679 If the failure is due to other causes, the repeated call behaves as if no previo us call had been made. | 6692 If the failure is due to other causes, the repeated call behaves as if no previo us call had been made. |
6680 \end{itemize} | 6693 \end{itemize} |
6681 \end{itemize} | 6694 \end{itemize} |
(...skipping 11 matching lines...) Expand all Loading... | |
6693 \item | 6706 \item |
6694 If the URI that is the value of $s_1$ has not yet been accessed by an import or export (\ref{exports}) directive in the current isolate then the contents of t he URI are compiled to yield a library $B$. \commentary{Because libraries may h ave mutually recursive imports, care must be taken to avoid an infinite regress. | 6707 If the URI that is the value of $s_1$ has not yet been accessed by an import or export (\ref{exports}) directive in the current isolate then the contents of t he URI are compiled to yield a library $B$. \commentary{Because libraries may h ave mutually recursive imports, care must be taken to avoid an infinite regress. |
6695 } | 6708 } |
6696 \item Otherwise, the contents of the URI denoted by $s_1$ have been compiled int o a library $B$ within the current isolate. | 6709 \item Otherwise, the contents of the URI denoted by $s_1$ have been compiled int o a library $B$ within the current isolate. |
6697 \end{itemize} | 6710 \end{itemize} |
6698 | 6711 |
6699 | 6712 |
6700 \LMHash{} | 6713 \LMHash{} |
6701 Let $NS_0$ be the exported namespace (\ref{exports}) of $B$. Then, for each comb inator clause $C_i, i \in 1..n$ in $I$: | 6714 Let $NS_0$ be the exported namespace (\ref{exports}) of $B$. Then, for each comb inator clause $C_i, i \in 1..n$ in $I$: |
6702 \begin{itemize} | 6715 \begin{itemize} |
6703 \item If $C_i$ is of the form | 6716 \item If $C_i$ is of the form |
6704 | 6717 |
6705 \code{\SHOW{} $id_1, \ldots, id_k$} | 6718 \code{\SHOW{} $id_1, \ldots, id_k$} |
6706 | 6719 |
6707 then let $NS_i = \SHOW{}([id_1, \ldots, id_k], NS_{i-1}$) | 6720 then let $NS_i = \SHOW{}([id_1, \ldots, id_k], NS_{i-1}$) |
6708 | 6721 |
6709 where $show(l,n)$ takes a list of identifiers $l$ and a namespace $n$, and produ ces a namespace that maps each name in $l$ to the same element that $n$ does. Fu rthermore, for each name $x$ in $l$, if $n$ defines the name $x=$ then the new namespace maps $x=$ to the same element that $n$ does. Otherwise the resulting m apping is undefined. | 6722 where $show(l,n)$ takes a list of identifiers $l$ and a namespace $n$, and produ ces a namespace that maps each name in $l$ to the same element that $n$ does. Fu rthermore, for each name $x$ in $l$, if $n$ defines the name $x=$ then the new namespace maps $x=$ to the same element that $n$ does. Otherwise the resulting m apping is undefined. |
6710 | |
6711 \item If $C_i$ is of the form | |
6712 | 6723 |
6713 \code{\HIDE{} $id_1, \ldots, id_k$} | 6724 \item If $C_i$ is of the form |
6714 | 6725 |
6715 then let $NS_i = \HIDE{}([id_1, \ldots, id_k], NS_{i-1}$) | 6726 \code{\HIDE{} $id_1, \ldots, id_k$} |
6716 | 6727 |
6717 where $hide(l, n)$ takes a list of identifiers $l$ and a namespace $n$, and prod uces a namespace that is identical to $n$ except that for each name $k$ in $l$, $k$ and $k=$ are undefined. | 6728 then let $NS_i = \HIDE{}([id_1, \ldots, id_k], NS_{i-1}$) |
6729 | |
6730 where $hide(l, n)$ takes a list of identifiers $l$ and a namespace $n$, and prod uces a namespace that is identical to $n$ except that for each name $k$ in $l$, $k$ and $k=$ are undefined. | |
6718 \end{itemize} | 6731 \end{itemize} |
6719 | 6732 |
6720 \LMHash{} | 6733 \LMHash{} |
6721 Next, if $I$ includes a prefix clause of the form \AS{} $p$, let $NS = NS_n \cu p \{p: prefixObject(NS_n)\}$ where $prefixObject(NS_n)$ is a {\em prefix object} for the namespace $NS_n$, which is an object that has the following members: | 6734 Next, if $I$ includes a prefix clause of the form \AS{} $p$, let $NS = NS_n \cu p \{p: prefixObject(NS_n)\}$ where $prefixObject(NS_n)$ is a {\em prefix object} for the namespace $NS_n$, which is an object that has the following members: |
6722 | 6735 |
6723 \begin{itemize} | 6736 \begin{itemize} |
6724 \item For every top level function $f$ named $id$ in $NS_n$, a corresponding me thod with the same name and signature as $f$ that forwards (\ref{functionDeclar ations}) to $f$. | 6737 \item For every top level function $f$ named $id$ in $NS_n$, a corresponding me thod with the same name and signature as $f$ that forwards (\ref{functionDeclar ations}) to $f$. |
6725 \item For every top level getter with the same name and signature as $g$ named $id$ in $NS_n$, a corresponding getter that forwards to $g$. | 6738 \item For every top level getter with the same name and signature as $g$ named $id$ in $NS_n$, a corresponding getter that forwards to $g$. |
6726 \item For every top level setter $s$ with the same name and signature as named $id$ in $NS_n$, a corresponding setter that forwards to $s$. | 6739 \item For every top level setter $s$ with the same name and signature as named $id$ in $NS_n$, a corresponding setter that forwards to $s$. |
6727 \item For every type $T$ named $id$ in $NS_n$, a corresponding getter named $id$ with return type \code{Type}, that, when invoked, returns the type object for $ T$. | 6740 \item For every type $T$ named $id$ in $NS_n$, a corresponding getter named $id$ with return type \code{Type}, that, when invoked, returns the type object for $ T$. |
6728 \end{itemize} | 6741 \end{itemize} |
6729 | 6742 |
(...skipping 11 matching lines...) Expand all Loading... | |
6741 Then, for each entry mapping key $k$ to declaration $d$ in $NS$, $d$ is made av ailable in the top level scope of $L$ under the name $k$ unless either: | 6754 Then, for each entry mapping key $k$ to declaration $d$ in $NS$, $d$ is made av ailable in the top level scope of $L$ under the name $k$ unless either: |
6742 \begin{itemize} | 6755 \begin{itemize} |
6743 \item | 6756 \item |
6744 a top-level declaration with the name $k$ exists in $L$, OR | 6757 a top-level declaration with the name $k$ exists in $L$, OR |
6745 \item a prefix clause of the form \AS{} $k$ is used in $L$. | 6758 \item a prefix clause of the form \AS{} $k$ is used in $L$. |
6746 \end{itemize} | 6759 \end{itemize} |
6747 | 6760 |
6748 \rationale{The greatly increases the chance that a member can be added to a libr ary without breaking its importers.} | 6761 \rationale{The greatly increases the chance that a member can be added to a libr ary without breaking its importers.} |
6749 | 6762 |
6750 \LMHash{} | 6763 \LMHash{} |
6751 A {\em system library} is a library that is part of the Dart implementation. Any other library is a {\em non-system library}. If a name $N$ is referenced by a l ibrary $L$ and $N$ would be introduced into the top level scope of $L$ by | 6764 A {\em system library} is a library that is part of the Dart implementation. Any other library is a {\em non-system library}. If a name $N$ is referenced by a l ibrary $L$ and $N$ would be introduced into the top level scope of $L$ by |
6752 imports of two libraries, $L_1$ and $L_2$, and the exported namespace of $L_1$ b inds $N$ to a declaration originating in a system library: | 6765 imports of two libraries, $L_1$ and $L_2$, and the exported namespace of $L_1$ b inds $N$ to a declaration originating in a system library: |
6753 | 6766 |
6754 %an import of a system library and an import of a non-system library: | 6767 %an import of a system library and an import of a non-system library: |
6755 \begin{itemize} | 6768 \begin{itemize} |
6756 \item The import of $L_1$ is implicitly extended by a \code{\HIDE{} $N$} clause. | 6769 \item The import of $L_1$ is implicitly extended by a \code{\HIDE{} $N$} clause. |
6757 \item A static warning is issued. | 6770 \item A static warning is issued. |
6758 \end{itemize} | 6771 \end{itemize} |
6759 | 6772 |
6760 \rationale { | 6773 \rationale { |
6761 Whereas normal conflicts are resolved at deployment time, the functionality of \ code{dart:} libraries is injected into an application at run time, and may vary over time as browsers are upgraded. Thus, conflicts with \code{dart:} libraries can arise at runtime, outside the developer's control. To avoid breaking deploy ed applications in this way, conflicts with the \code{dart:} libraries are treat ed specially. | 6774 Whereas normal conflicts are resolved at deployment time, the functionality of \ code{dart:} libraries is injected into an application at run time, and may vary over time as browsers are upgraded. Thus, conflicts with \code{dart:} libraries can arise at runtime, outside the developer's control. To avoid breaking deploy ed applications in this way, conflicts with the \code{dart:} libraries are treat ed specially. |
6762 | 6775 |
6763 It is recommended that tools that deploy Dart code produce output in which all i mports use show clauses to ensure that additions to the namespace of a library n ever impact deployed code. | 6776 It is recommended that tools that deploy Dart code produce output in which all i mports use show clauses to ensure that additions to the namespace of a library n ever impact deployed code. |
6764 } | 6777 } |
6765 | 6778 |
6766 \LMHash{} | 6779 \LMHash{} |
6767 If a name $N$ is referenced by a library $L$ and $N$ is introduced into the to p level scope of $L$ by more than one import, and not all the imports denote the same declaration, then: | 6780 If a name $N$ is referenced by a library $L$ and $N$ is introduced into the to p level scope of $L$ by more than one import, and not all the imports denote the same declaration, then: |
6768 \begin{itemize} | 6781 \begin{itemize} |
6769 \item A static warning occurs. | 6782 \item A static warning occurs. |
6770 \item If $N$ is referenced as a function, getter or setter, a \code{NoSuchMethod Error} is thrown. | 6783 \item If $N$ is referenced as a function, getter or setter, a \code{NoSuchMethod Error} is thrown. |
6771 \item If $N$ is referenced as a type, it is treated as a malformed type. | 6784 \item If $N$ is referenced as a type, it is treated as a malformed type. |
6772 | 6785 |
6773 \end{itemize} | 6786 \end{itemize} |
6774 | 6787 |
6775 \LMHash{} | 6788 \LMHash{} |
6776 We say that the namespace $NS$ {\em has been imported into} $L$. | 6789 We say that the namespace $NS$ {\em has been imported into} $L$. |
6777 | 6790 |
6778 \commentary{ | 6791 \commentary{ |
6779 It is neither an error nor a warning if $N$ is introduced by two or more import s but never referred to. | 6792 It is neither an error nor a warning if $N$ is introduced by two or more import s but never referred to. |
6780 } | 6793 } |
6781 | 6794 |
6782 \rationale{ | 6795 \rationale{ |
6783 The policy above makes libraries more robust in the face of additions made to th eir imports. | 6796 The policy above makes libraries more robust in the face of additions made to th eir imports. |
6784 | 6797 |
6785 A clear distinction needs to be made between this approach, and seemingly simila r policies with respect to classes or interfaces. The use of a class or interfa ce, and of its members, is separate from its declaration. The usage and declarat ion may occur in widely separated places in the code, and may in fact be authore d by different people or organizations. It is important that errors are given a t the offending declaration so that the party that receives the error can respon d to it a meaningful way. | 6798 A clear distinction needs to be made between this approach, and seemingly simila r policies with respect to classes or interfaces. The use of a class or interfa ce, and of its members, is separate from its declaration. The usage and declarat ion may occur in widely separated places in the code, and may in fact be authore d by different people or organizations. It is important that errors are given a t the offending declaration so that the party that receives the error can respon d to it a meaningful way. |
6786 | 6799 |
6787 In contrast a library comprises both imports and their usage; the library is und er the control of a single party and so any problem stemming from the import can be resolved even if it is reported at the use site. | 6800 In contrast a library comprises both imports and their usage; the library is und er the control of a single party and so any problem stemming from the import can be resolved even if it is reported at the use site. |
6788 | 6801 |
6789 %On a related note, the provenance of the conflicting elements is not considered . An element that is imported via distinct paths may conflict with itself. This avoids variants of the well known "diamond" problem. | 6802 %On a related note, the provenance of the conflicting elements is not considered . An element that is imported via distinct paths may conflict with itself. This avoids variants of the well known "diamond" problem. |
6790 } | 6803 } |
6791 | 6804 |
6792 \LMHash{} | 6805 \LMHash{} |
6793 It is a static warning to import two different libraries with the same name unle ss their name is the empty string. | 6806 It is a static warning to import two different libraries with the same name unle ss their name is the empty string. |
6794 | 6807 |
6795 \commentary{ | 6808 \commentary{ |
6796 A widely disseminated library should be given a name that will not conflict with other such libraries. The preferred mechanism for this is using pub, the Dart p ackage manager, which provides a global namespace for libraries, and conventions that leverage that namespace. | 6809 A widely disseminated library should be given a name that will not conflict with other such libraries. The preferred mechanism for this is using pub, the Dart p ackage manager, which provides a global namespace for libraries, and conventions that leverage that namespace. |
6797 } | 6810 } |
6798 | 6811 |
6799 \commentary{Note that no errors or warnings are given if one hides or shows a na me that is not in a namespace.} | 6812 \commentary{Note that no errors or warnings are given if one hides or shows a na me that is not in a namespace.} |
6800 \rationale{ | 6813 \rationale{ |
6801 This prevents situations where removing a name from a library would cause breaka ge of a client library. | 6814 This prevents situations where removing a name from a library would cause breaka ge of a client library. |
6802 } | 6815 } |
6803 | 6816 |
6804 \LMHash{} | 6817 \LMHash{} |
6805 The dart core library \code{dart:core} is implicitly imported into every dart li brary other than itself via an import clause of the form | 6818 The dart core library \code{dart:core} is implicitly imported into every dart li brary other than itself via an import clause of the form |
6806 | 6819 |
6807 \code{\IMPORT{} `dart:core';} | 6820 \code{\IMPORT{} `dart:core';} |
6808 | 6821 |
6809 unless the importing library explicitly imports \code{dart:core}. | 6822 unless the importing library explicitly imports \code{dart:core}. |
6810 | 6823 |
6811 \commentary{ | 6824 \commentary{ |
6812 Any import of \code{dart:core}, even if restricted via \SHOW{}, \HIDE{} or \AS{} , preempts the automatic import. | 6825 Any import of \code{dart:core}, even if restricted via \SHOW{}, \HIDE{} or \AS{} , preempts the automatic import. |
6813 } | 6826 } |
6814 | 6827 |
6815 \rationale{ | 6828 \rationale{ |
6816 It would be nice if there was nothing special about \code{dart:core}. However, i ts use is pervasive, which leads to the decision to import it automatically. Ho wever, some library $L$ may wish to define entities with names used by \code{da rt:core} (which it can easily do, as the names declared by a library take preced ence). Other libraries may wish to use $L$ and may want to use members of $L$ th at conflict with the core library without having to use a prefix and without enc ountering warnings. The above rule makes this possible, essentially canceling \c ode{dart:core}'s special treatment by means of yet another special rule. | 6829 It would be nice if there was nothing special about \code{dart:core}. However, i ts use is pervasive, which leads to the decision to import it automatically. Ho wever, some library $L$ may wish to define entities with names used by \code{da rt:core} (which it can easily do, as the names declared by a library take preced ence). Other libraries may wish to use $L$ and may want to use members of $L$ th at conflict with the core library without having to use a prefix and without enc ountering warnings. The above rule makes this possible, essentially canceling \c ode{dart:core}'s special treatment by means of yet another special rule. |
6817 } | 6830 } |
6818 | 6831 |
6819 \subsection{Exports} | 6832 \subsection{Exports} |
6820 \LMLabel{exports} | 6833 \LMLabel{exports} |
6821 | 6834 |
6822 \LMHash{} | 6835 \LMHash{} |
6823 A library $L$ exports a namespace (\ref{scoping}), meaning that the declarations in the namespace are made available to other libraries if they choose to import $L$ (\ref{imports}). The namespace that $L$ exports is known as its {\em expor ted namespace}. | 6836 A library $L$ exports a namespace (\ref{scoping}), meaning that the declarations in the namespace are made available to other libraries if they choose to import $L$ (\ref{imports}). The namespace that $L$ exports is known as its {\em expor ted namespace}. |
6824 | 6837 |
6825 \begin{grammar} | 6838 \begin{grammar} |
6826 {\bf libraryExport:} | 6839 {\bf libraryExport:} |
6827 metadata \EXPORT{} uri combinator* `{\escapegrammar ;}' | 6840 metadata \EXPORT{} uri combinator* `{\escapegrammar ;}' |
6828 . | 6841 . |
6829 \end{grammar} | 6842 \end{grammar} |
6830 | 6843 |
6831 \LMHash{} | 6844 \LMHash{} |
6832 An export specifies a URI $x$ where the declaration of an exported library is t o be found. It is a compile-time error if the specified URI does not refer to a library declaration. | 6845 An export specifies a URI $x$ where the declaration of an exported library is t o be found. It is a compile-time error if the specified URI does not refer to a library declaration. |
6833 | 6846 |
6834 \LMHash{} | 6847 \LMHash{} |
6835 We say that a name {\em is exported by a library} (or equivalently, that a libra ry {\em exports a name}) if the name is in the library's exported namespace. We say that a declaration {\em is exported by a library} (or equivalently, that a l ibrary {\em exports a declaration}) if the declaration is in the library's expor ted namespace. | 6848 We say that a name {\em is exported by a library} (or equivalently, that a libra ry {\em exports a name}) if the name is in the library's exported namespace. We say that a declaration {\em is exported by a library} (or equivalently, that a l ibrary {\em exports a declaration}) if the declaration is in the library's expor ted namespace. |
6836 | 6849 |
6837 \LMHash{} | 6850 \LMHash{} |
6838 A library always exports all names and all declarations in its public namespace. In addition, a library may choose to re-export additional libraries via {\em ex port directives}, often referred to simply as {\em exports}. | 6851 A library always exports all names and all declarations in its public namespace. In addition, a library may choose to re-export additional libraries via {\em ex port directives}, often referred to simply as {\em exports}. |
6839 | 6852 |
6840 \LMHash{} | 6853 \LMHash{} |
6841 Let $E$ be an export directive that refers to a URI via the string $s_1$. Evalua tion of $E$ proceeds as follows: | 6854 Let $E$ be an export directive that refers to a URI via the string $s_1$. Evalua tion of $E$ proceeds as follows: |
6842 | 6855 |
6843 \LMHash{} | 6856 \LMHash{} |
6844 First, | 6857 First, |
6845 | 6858 |
6846 \begin{itemize} | 6859 \begin{itemize} |
6847 \item | 6860 \item |
6848 If the URI that is the value of $s_1$ has not yet been accessed by an import or export directive in the current isolate then the contents of the URI are comp iled to yield a library $B$. | 6861 If the URI that is the value of $s_1$ has not yet been accessed by an import or export directive in the current isolate then the contents of the URI are comp iled to yield a library $B$. |
6849 \item Otherwise, the contents of the URI denoted by $s_1$ have been compiled int o a library $B$ within the current isolate. | 6862 \item Otherwise, the contents of the URI denoted by $s_1$ have been compiled int o a library $B$ within the current isolate. |
6850 \end{itemize} | 6863 \end{itemize} |
6851 | 6864 |
6852 | 6865 |
6853 \LMHash{} | 6866 \LMHash{} |
6854 Let $NS_0$ be the exported namespace of $B$. Then, for each combinator clause $C _i, i \in 1..n$ in $E$: | 6867 Let $NS_0$ be the exported namespace of $B$. Then, for each combinator clause $C _i, i \in 1..n$ in $E$: |
6855 \begin{itemize} | 6868 \begin{itemize} |
6856 \item If $C_i$ is of the form \code{\SHOW{} $id_1, \ldots, id_k$} then let | 6869 \item If $C_i$ is of the form \code{\SHOW{} $id_1, \ldots, id_k$} then let |
6857 | 6870 |
6858 $NS_i = \SHOW{}([id_1, \ldots, id_k], NS_{i-1}$). | 6871 $NS_i = \SHOW{}([id_1, \ldots, id_k], NS_{i-1}$). |
6859 \item If $C_i$ is of the form \code{\HIDE{} $id_1, \ldots, id_k$} | 6872 \item If $C_i$ is of the form \code{\HIDE{} $id_1, \ldots, id_k$} |
6860 | 6873 |
6861 then let $NS_i = \HIDE{}([id_1, \ldots, id_k], NS_{i-1}$). | 6874 then let $NS_i = \HIDE{}([id_1, \ldots, id_k], NS_{i-1}$). |
6862 \end{itemize} | 6875 \end{itemize} |
6863 | 6876 |
6864 \LMHash{} | 6877 \LMHash{} |
6865 For each | 6878 For each |
6866 entry mapping key $k$ to declaration $d$ in $NS_n$ an entry mapping $k$ to $d$ i s added to the exported namespace of $L$ unless a top-level declaration with th e name $k$ exists in $L$. | 6879 entry mapping key $k$ to declaration $d$ in $NS_n$ an entry mapping $k$ to $d$ i s added to the exported namespace of $L$ unless a top-level declaration with th e name $k$ exists in $L$. |
6867 | 6880 |
6868 \LMHash{} | 6881 \LMHash{} |
6869 If a name $N$ is referenced by a library $L$ and $N$ would be introduced into th e exported namespace of $L$ by exports of two libraries, $L_1$ and $L_2$, and th e exported namespace of $L_1$ binds $N$ to a declaration originating in a system library: | 6882 If a name $N$ is referenced by a library $L$ and $N$ would be introduced into th e exported namespace of $L$ by exports of two libraries, $L_1$ and $L_2$, and th e exported namespace of $L_1$ binds $N$ to a declaration originating in a system library: |
6870 %an export of a system library and an export of a non-system library: | 6883 %an export of a system library and an export of a non-system library: |
6871 \begin{itemize} | 6884 \begin{itemize} |
6872 \item The export of $L_1$ is implicitly extended by a \code{\HIDE{} $N$} clause. | 6885 \item The export of $L_1$ is implicitly extended by a \code{\HIDE{} $N$} clause. |
6873 \item A static warning is issued. | 6886 \item A static warning is issued. |
6874 \end{itemize} | 6887 \end{itemize} |
6875 | 6888 |
6876 \rationale{ | 6889 \rationale{ |
6877 See the discussion in section \ref{imports} for the reasoning behind this rule. | 6890 See the discussion in section \ref{imports} for the reasoning behind this rule. |
6878 } | 6891 } |
6879 | 6892 |
6880 \LMHash{} | 6893 \LMHash{} |
6881 We say that $L$ {\em re-exports library } $B$, and also that $L$ {\em re-exports namespace } $NS_n$. When no confusion can arise, we may simply state that $L$ { \em re-exports }$B$, or that $L$ {\em re-exports }$NS_n$. | 6894 We say that $L$ {\em re-exports library } $B$, and also that $L$ {\em re-exports namespace } $NS_n$. When no confusion can arise, we may simply state that $L$ { \em re-exports }$B$, or that $L$ {\em re-exports }$NS_n$. |
6882 | 6895 |
6883 \LMHash{} | 6896 \LMHash{} |
6884 It is a compile-time error if a name $N$ is re-exported by a library $L$ and $N$ is introduced into the export namespace of $L$ by more than one export, unless all exports refer to same declaration for the name $N$. It is a static warnin g to export two different libraries with the same name unless their name is the empty string. | 6897 It is a compile-time error if a name $N$ is re-exported by a library $L$ and $N$ is introduced into the export namespace of $L$ by more than one export, unless all exports refer to same declaration for the name $N$. It is a static warnin g to export two different libraries with the same name unless their name is the empty string. |
6885 | 6898 |
6886 | 6899 |
6887 | 6900 |
6888 \subsection{Parts} | 6901 \subsection{Parts} |
6889 \LMLabel{parts} | 6902 \LMLabel{parts} |
6890 | 6903 |
6891 \LMHash{} | 6904 \LMHash{} |
6892 A library may be divided into {\em parts}, each of which can be stored in a sepa rate location. A library identifies its parts by listing them via \PART{} direct ives. | 6905 A library may be divided into {\em parts}, each of which can be stored in a sepa rate location. A library identifies its parts by listing them via \PART{} direct ives. |
6893 | 6906 |
6894 \LMHash{} | 6907 \LMHash{} |
6895 A {\em part directive} specifies a URI where a Dart compilation unit that should be incorporated into the current library may be found. | 6908 A {\em part directive} specifies a URI where a Dart compilation unit that should be incorporated into the current library may be found. |
6896 | 6909 |
6897 \begin{grammar} | 6910 \begin{grammar} |
6898 {\bf partDirective:} | 6911 {\bf partDirective:} |
6899 metadata \PART{} uri `{\escapegrammar ;}' | 6912 metadata \PART{} uri `{\escapegrammar ;}' |
6900 . | 6913 . |
6901 | 6914 |
6902 {\bf partHeader:} | 6915 {\bf partHeader:} |
6903 metadata \PART{} \OF{} identifier (`{\escapegrammar .}' identifier)* `{\es capegrammar ;}' | 6916 metadata \PART{} \OF{} identifier (`{\escapegrammar .}' identifier)* `{\es capegrammar ;}' |
6904 . | 6917 . |
6905 {\bf partDeclaration:} | 6918 {\bf partDeclaration:} |
6906 partHeader topLevelDefinition* EOF | 6919 partHeader topLevelDefinition* EOF |
6907 . | 6920 . |
6908 \end{grammar} | 6921 \end{grammar} |
6909 | 6922 |
6910 \LMHash{} | 6923 \LMHash{} |
6911 A {\em part header} begins with \PART{} \OF{} followed by the name of the libr ary the part belongs to. A part declaration consists of a part header followed by a sequence of top-level declarations. | 6924 A {\em part header} begins with \PART{} \OF{} followed by the name of the libr ary the part belongs to. A part declaration consists of a part header followed by a sequence of top-level declarations. |
6912 | 6925 |
6913 \LMHash{} | 6926 \LMHash{} |
6914 Compiling a part directive of the form \code{\PART{} $s$;} causes the Dart syste m to attempt to compile the contents of the URI that is the value of $s$. The to p-level declarations at that URI are then compiled by the Dart compiler in the s cope of the current library. It is a compile-time error if the contents of the U RI are not a valid part declaration. It is a static warning if the referenced pa rt declaration $p$ names a library other than the current library as the library to which $p$ belongs. | 6927 Compiling a part directive of the form \code{\PART{} $s$;} causes the Dart syste m to attempt to compile the contents of the URI that is the value of $s$. The to p-level declarations at that URI are then compiled by the Dart compiler in the s cope of the current library. It is a compile-time error if the contents of the U RI are not a valid part declaration. It is a static warning if the referenced pa rt declaration $p$ names a library other than the current library as the library to which $p$ belongs. |
6915 | 6928 |
6916 \subsection{Scripts} | 6929 \subsection{Scripts} |
6917 \LMLabel{scripts} | 6930 \LMLabel{scripts} |
6918 | 6931 |
6919 \LMHash{} | 6932 \LMHash{} |
6920 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 m ore than two required parameters. | 6933 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 m ore than two required parameters. |
6921 | 6934 |
6922 A script $S$ may be executed as follows: | 6935 A script $S$ may be executed as follows: |
6923 | 6936 |
6924 \LMHash{} | 6937 \LMHash{} |
6925 First, $S$ is compiled as a library as specified above. Then, the top-level func tion \code{main} that is in the exported namespace of $S$ is invoked. If \code{m ain} 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 a ctual argument whose runtime type implements \code{List$<$String$>$}. Otherwise \code{main} is invoked with the following two actual arguments: | 6938 First, $S$ is compiled as a library as specified above. Then, the top-level func tion \code{main} that is in the exported namespace of $S$ is invoked. If \code{m ain} 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 a ctual argument whose runtime type implements \code{List$<$String$>$}. Otherwise \code{main} is invoked with the following two actual arguments: |
6926 \begin{enumerate} | 6939 \begin{enumerate} |
6927 \item An object whose runtime type implements \code{List$<$String$>$}. | 6940 \item An object whose runtime type implements \code{List$<$String$>$}. |
6928 \item The initial message of the current isolate $i$ as determined by the invoca tion of \code{Isolate.spawnUri} that spawned $i$. | 6941 \item The initial message of the current isolate $i$ as determined by the invoca tion of \code{Isolate.spawnUri} that spawned $i$. |
6929 \end{enumerate} | 6942 \end{enumerate} |
6930 | 6943 |
6931 \LMHash{} | 6944 \LMHash{} |
6932 It is a run time error if $S$ does not declare or export either: | 6945 It is a run time error if $S$ does not declare or export either: |
6933 \begin{itemize} | 6946 \begin{itemize} |
6934 \item A top-level function named \code{main}, or | 6947 \item A top-level function named \code{main}, or |
6935 \item A top-level getter named \code{main} that returns a function. | 6948 \item A top-level getter named \code{main} that returns a function. |
6936 \end{itemize} | 6949 \end{itemize} |
6937 | 6950 |
6938 \commentary { | 6951 \commentary { |
6939 Note that if \code{main} requires more than two arguments, a run time error will occur. | 6952 Note that if \code{main} requires more than two arguments, a run time error will occur. |
6940 } | 6953 } |
6941 | 6954 |
6942 \rationale{ | 6955 \rationale{ |
6943 The names of scripts are optional, in the interests of interactive, informal use . However, any script of long term value should be given a name as a matter of g ood practice. | 6956 The names of scripts are optional, in the interests of interactive, informal use . However, any script of long term value should be given a name as a matter of g ood practice. |
6944 } | 6957 } |
6945 | 6958 |
6946 \commentary { | 6959 \commentary { |
6947 A Dart program will typically be executed by executing a script. | 6960 A Dart program will typically be executed by executing a script. |
6948 } | 6961 } |
6949 | 6962 |
6950 \subsection{URIs} | 6963 \subsection{URIs} |
6951 \LMLabel{uris} | 6964 \LMLabel{uris} |
6952 | 6965 |
6953 \LMHash{} | 6966 \LMHash{} |
6954 URIs are specified by means of string literals: | 6967 URIs are specified by means of string literals: |
6955 | 6968 |
6956 \begin{grammar} | 6969 \begin{grammar} |
6957 {\bf uri:} | 6970 {\bf uri:} |
6958 stringLiteral | 6971 stringLiteral |
6959 . | 6972 . |
6960 \end{grammar} | 6973 \end{grammar} |
6961 | 6974 |
6962 \LMHash{} | 6975 \LMHash{} |
6963 It is a compile-time error if the string literal $x$ that describes a URI is no t a compile-time constant, or if $x$ involves string interpolation. | 6976 It is a compile-time error if the string literal $x$ that describes a URI is no t a compile-time constant, or if $x$ involves string interpolation. |
6964 | 6977 |
6965 \LMHash{} | 6978 \LMHash{} |
6966 This specification does not discuss the interpretation of URIs, with the followi ng exceptions. | 6979 This specification does not discuss the interpretation of URIs, with the followi ng exceptions. |
6967 | 6980 |
6968 \rationale{ | 6981 \rationale{ |
6969 The interpretation of URIs is mostly left to the surrounding computing environm ent. For example, if Dart is running in a web browser, that browser will likely interpret some URIs. While it might seem attractive to specify, say, that URIs a re interpreted with respect to a standard such as IETF RFC 3986, in practice thi s will usually depend on the browser and cannot be relied upon. | 6982 The interpretation of URIs is mostly left to the surrounding computing environm ent. For example, if Dart is running in a web browser, that browser will likely interpret some URIs. While it might seem attractive to specify, say, that URIs a re interpreted with respect to a standard such as IETF RFC 3986, in practice thi s will usually depend on the browser and cannot be relied upon. |
6970 } | 6983 } |
6971 | 6984 |
6972 \LMHash{} | 6985 \LMHash{} |
6973 A URI of the form \code{dart:$s$} is interpreted as a reference to a system libr ary (\ref{imports}) $s$. | 6986 A URI of the form \code{dart:$s$} is interpreted as a reference to a system libr ary (\ref{imports}) $s$. |
6974 | 6987 |
6975 \LMHash{} | 6988 \LMHash{} |
6976 A URI of the form \code{package:$s$} is interpreted in an implementation specifi c manner. | 6989 A URI of the form \code{package:$s$} is interpreted in an implementation specifi c manner. |
6977 | 6990 |
6978 \rationale{ | 6991 \rationale{ |
6979 The intent is that, during development, Dart programmers can rely on a package m anager to find elements of their program. | 6992 The intent is that, during development, Dart programmers can rely on a package m anager to find elements of their program. |
6980 } | 6993 } |
6981 | 6994 |
6982 \LMHash{} | 6995 \LMHash{} |
6983 Otherwise, any relative URI is interpreted as relative to the location of the cu rrent library. All further interpretation of URIs is implementation dependent. | 6996 Otherwise, any relative URI is interpreted as relative to the location of the cu rrent library. All further interpretation of URIs is implementation dependent. |
6984 | 6997 |
6985 \commentary{This means it is dependent on the embedder.} | 6998 \commentary{This means it is dependent on the embedder.} |
6986 | 6999 |
6987 | 7000 |
6988 \section{Types} | 7001 \section{Types} |
6989 \LMLabel{types} | 7002 \LMLabel{types} |
6990 | 7003 |
6991 \LMHash{} | 7004 \LMHash{} |
6992 Dart supports optional typing based on interface types. | 7005 Dart supports optional typing based on interface types. |
6993 | 7006 |
6994 \rationale{The type system is unsound, due to the covariance of generic types. T his is a deliberate choice (and undoubtedly controversial). Experience has show n that sound type rules for generics fly in the face of programmer intuition. It is easy for tools to provide a sound type analysis if they choose, which may be useful for tasks like refactoring. | 7007 \rationale{The type system is unsound, due to the covariance of generic types. T his is a deliberate choice (and undoubtedly controversial). Experience has show n that sound type rules for generics fly in the face of programmer intuition. It is easy for tools to provide a sound type analysis if they choose, which may be useful for tasks like refactoring. |
6995 } | 7008 } |
6996 | 7009 |
6997 \subsection{Static Types} | 7010 \subsection{Static Types} |
6998 \LMLabel{staticTypes} | 7011 \LMLabel{staticTypes} |
6999 | 7012 |
7000 \LMHash{} | 7013 \LMHash{} |
7001 Static type annotations are used in variable declarations (\ref{variables}) (inc luding formal parameters (\ref{formalParameters})), in the return types of funct ions (\ref{functions}) and in the bounds of type variables. Static type annotat ions are used during static checking and when running programs in checked mode. They have no effect whatsoever in production mode. | 7014 Static type annotations are used in variable declarations (\ref{variables}) (inc luding formal parameters (\ref{formalParameters})), in the return types of funct ions (\ref{functions}) and in the bounds of type variables. Static type annotat ions are used during static checking and when running programs in checked mode. They have no effect whatsoever in production mode. |
7002 | 7015 |
7003 \begin{grammar} | 7016 \begin{grammar} |
7004 {\bf type:} | 7017 {\bf type:} |
7005 typeName typeArguments? | 7018 typeName typeArguments? |
7006 . | 7019 . |
7007 | 7020 |
7008 {\bf typeName:} | 7021 {\bf typeName:} |
7009 qualified | 7022 qualified |
7010 . | 7023 . |
7011 | 7024 |
7012 {\bf typeArguments:} | 7025 {\bf typeArguments:} |
7013 '<' typeList '>' | 7026 '<' typeList '>' |
7014 . | 7027 . |
7015 | 7028 |
7016 {\bf typeList:} | 7029 {\bf typeList:} |
7017 type (',' type)* | 7030 type (',' type)* |
7018 . | 7031 . |
7019 \end{grammar} | 7032 \end{grammar} |
7020 | 7033 |
7021 \LMHash{} | 7034 \LMHash{} |
7022 A Dart implementation must provide a static checker that detects and reports exa ctly those situations this specification identifies as static warnings and only those situations. However: | 7035 A Dart implementation must provide a static checker that detects and reports exa ctly those situations this specification identifies as static warnings and only those situations. However: |
7023 \begin{itemize} | 7036 \begin{itemize} |
7024 \item Running the static checker on a program $P$ is not required for compiling and running $P$. | 7037 \item Running the static checker on a program $P$ is not required for compiling and running $P$. |
7025 \item Running the static checker on a program $P$ must not prevent successful co mpilation of $P$ nor may it prevent the execution of $P$, regardless of whether any static warnings occur. | 7038 \item Running the static checker on a program $P$ must not prevent successful co mpilation of $P$ nor may it prevent the execution of $P$, regardless of whether any static warnings occur. |
7026 \end{itemize} | 7039 \end{itemize} |
7027 | 7040 |
7028 \commentary{Nothing precludes additional tools that implement alternative static analyses (e.g., interpreting the existing type annotations in a sound manner su ch as either non-variant generics, or inferring declaration based variance from the actual declarations). However, using these tools must not preclude successfu l compilation and execution of Dart code. | 7041 \commentary{Nothing precludes additional tools that implement alternative static analyses (e.g., interpreting the existing type annotations in a sound manner su ch as either non-variant generics, or inferring declaration based variance from the actual declarations). However, using these tools must not preclude successfu l compilation and execution of Dart code. |
7029 } | 7042 } |
7030 | 7043 |
7031 %\Q{Should we do something with respect to non-nullable types?} | 7044 %\Q{Should we do something with respect to non-nullable types?} |
7032 | 7045 |
7033 \LMHash{} | 7046 \LMHash{} |
7034 A type $T$ is {\em malformed} iff: | 7047 A type $T$ is {\em malformed} iff: |
7035 \begin{itemize} | 7048 \begin{itemize} |
7036 \item $T$ has the form $id$ or the form $prefix.id$, and in the enclosing lexica l scope, the name $id$ (respectively $prefix.id$) does not denote a type. | 7049 \item $T$ has the form $id$ or the form $prefix.id$, and in the enclosing lexica l scope, the name $id$ (respectively $prefix.id$) does not denote a type. |
7037 \item $T$ denotes a type variable in the enclosing lexical scope, but occurs in the signature or body of a static member. | 7050 \item $T$ denotes a type variable in the enclosing lexical scope, but occurs in the signature or body of a static member. |
7038 \item $T$ is a parameterized type of the form $G<S_1, \ldots , S_n>$, and $G$ i s malformed. | 7051 \item $T$ is a parameterized type of the form $G<S_1, \ldots , S_n>$, and $G$ i s malformed. |
7039 \item $T$ denotes declarations that were imported from multiple imports clauses. | 7052 \item $T$ denotes declarations that were imported from multiple imports clauses. |
7040 %Either $G$ or $S_i, i \in 1.. n$ are malformed. | 7053 %Either $G$ or $S_i, i \in 1.. n$ are malformed. |
7041 % \item $G$ is not a generic type with $n$ type parameters. | 7054 % \item $G$ is not a generic type with $n$ type parameters. |
7042 % \item Let $T_i$ be the type parameters of $G$ (if any) and let $B_i$ be the b ound of $T_i, i \in 1.. n$, and $S_i$ is not a subtype of $[S_1, \ldots, S_n/T _1, \ldots, T_n]B_i, i \in 1.. n$. | 7055 % \item Let $T_i$ be the type parameters of $G$ (if any) and let $B_i$ be the b ound of $T_i, i \in 1.. n$, and $S_i$ is not a subtype of $[S_1, \ldots, S_n/T _1, \ldots, T_n]B_i, i \in 1.. n$. |
7043 % \end{itemize} | 7056 % \end{itemize} |
7044 \end{itemize} | 7057 \end{itemize} |
7045 | 7058 |
7046 \LMHash{} | 7059 \LMHash{} |
7047 Any use of a malformed type gives rise to a static warning. A malformed type i s then interpreted as \DYNAMIC{} by the static type checker and the runtime unle ss explicitly specified otherwise. | 7060 Any use of a malformed type gives rise to a static warning. A malformed type i s then interpreted as \DYNAMIC{} by the static type checker and the runtime unle ss explicitly specified otherwise. |
7048 | 7061 |
7049 \rationale{ | 7062 \rationale{ |
7050 This ensures that the developer is spared a series of cascading warnings as the malformed type interacts with other types. | 7063 This ensures that the developer is spared a series of cascading warnings as the malformed type interacts with other types. |
7051 } | 7064 } |
7052 | 7065 |
7053 \LMHash{} | 7066 \LMHash{} |
7054 A type $T$ is {\em deferred} iff it is of the form $p.T$ where $p$ is a deferred prefix. | 7067 A type $T$ is {\em deferred} iff it is of the form $p.T$ where $p$ is a deferred prefix. |
7055 It is a static warning to use a deferred type in a type annotation, type test, t ype cast or as a type parameter. However, all other static warnings must be issu ed under the assumption that all deferred libraries have successfully been loade d. | 7068 It is a static warning to use a deferred type in a type annotation, type test, t ype cast or as a type parameter. However, all other static warnings must be issu ed under the assumption that all deferred libraries have successfully been loade d. |
7056 | 7069 |
7057 % Now, when passed to a generic, p.T also has to be treated as dynamic - otherwi se we have to fail immediately. Where do we say that? And how does this fit with idea that as a type object it fails? Should we say that the accessor on p retur ns dynamic instead of failing? Do we distinguish its use in a constructor vs its use in an annotation? It's not that we evaluate type objects in constructor arg s - these cannot represent parameterized types. | 7070 % Now, when passed to a generic, p.T also has to be treated as dynamic - otherwi se we have to fail immediately. Where do we say that? And how does this fit with idea that as a type object it fails? Should we say that the accessor on p retur ns dynamic instead of failing? Do we distinguish its use in a constructor vs its use in an annotation? It's not that we evaluate type objects in constructor arg s - these cannot represent parameterized types. |
7058 | 7071 |
7059 | 7072 |
7060 \subsubsection{Type Promotion} | 7073 \subsubsection{Type Promotion} |
7061 \LMLabel{typePromotion} | 7074 \LMLabel{typePromotion} |
7062 | 7075 |
7063 \LMHash{} | 7076 \LMHash{} |
7064 The static type system ascribes a static type to every expression. In some case s, the types of local variables and formal parameters may be promoted from their declared types based on control flow. | 7077 The static type system ascribes a static type to every expression. In some case s, the types of local variables and formal parameters may be promoted from their declared types based on control flow. |
7065 | 7078 |
7066 \LMHash{} | 7079 \LMHash{} |
7067 We say that a variable $v$ is known to have type $T$ whenever we allow the type of $v$ to be promoted. The exact circumstances when type promotion is allowed ar e given in the relevant sections of the specification (\ref{logicalBooleanExpres sions}, \ref{conditional} and \ref{if}). | 7080 We say that a variable $v$ is known to have type $T$ whenever we allow the type of $v$ to be promoted. The exact circumstances when type promotion is allowed ar e given in the relevant sections of the specification (\ref{logicalBooleanExpres sions}, \ref{conditional} and \ref{if}). |
7068 | 7081 |
7069 \LMHash{} | 7082 \LMHash{} |
7070 Type promotion for a variable $v$ is allowed only when we can deduce that such p romotion is valid based on an analysis of certain boolean expressions. In such c ases, we say that the boolean expression $b$ shows that $v$ has type $T$. As a r ule, for all variables $v$ and types $T$, a boolean expression does not show tha t $v$ has type $T$. Those situations where an expression does show that a variab le has a type are mentioned explicitly in the relevant sections of this specific ation (\ref{typeTest} and \ref{logicalBooleanExpressions}). | 7083 Type promotion for a variable $v$ is allowed only when we can deduce that such p romotion is valid based on an analysis of certain boolean expressions. In such c ases, we say that the boolean expression $b$ shows that $v$ has type $T$. As a r ule, for all variables $v$ and types $T$, a boolean expression does not show tha t $v$ has type $T$. Those situations where an expression does show that a variab le has a type are mentioned explicitly in the relevant sections of this specific ation (\ref{typeTest} and \ref{logicalBooleanExpressions}). |
7071 | 7084 |
7072 | 7085 |
7073 \subsection{Dynamic Type System} | 7086 \subsection{Dynamic Type System} |
7074 \LMLabel{dynamicTypeSystem} | 7087 \LMLabel{dynamicTypeSystem} |
7075 | 7088 |
7076 \LMHash{} | 7089 \LMHash{} |
7077 A Dart implementation must support execution in both {\em production mode} and { \em checked mode}. Those dynamic checks specified as occurring specifically in checked mode must be performed iff the code is executed in checked mode. | 7090 A Dart implementation must support execution in both {\em production mode} and { \em checked mode}. Those dynamic checks specified as occurring specifically in checked mode must be performed iff the code is executed in checked mode. |
7078 | 7091 |
7079 \commentary{ | 7092 \commentary{ |
7080 Note that this is the case even if the deferred type belongs to a prefix that ha s already been loaded. This is regrettable, since it strongly discourages the us e of type annotations that involve deferred types because Dart programmers use c hecked mode much of the time. | 7093 Note that this is the case even if the deferred type belongs to a prefix that ha s already been loaded. This is regrettable, since it strongly discourages the us e of type annotations that involve deferred types because Dart programmers use c hecked mode much of the time. |
7081 | 7094 |
7082 In practice, many scenarios involving deferred loading involve deferred loading of classes that implement eagerly loaded interfaces, so the situation is often l ess onerous than it seems. The current semantics were adopted based on considera tions of ease of implementation. | 7095 In practice, many scenarios involving deferred loading involve deferred loading of classes that implement eagerly loaded interfaces, so the situation is often l ess onerous than it seems. The current semantics were adopted based on considera tions of ease of implementation. |
7083 | 7096 |
7084 Clearly, if a deferred type has not yet been loaded, it is impossible to do a co rrect subtype test involving it, and one would expect a dynamic failure, as is t he case with type tests and casts. By the same token, one would expect checked m ode to work seamlessly once a type had been loaded. We hope to adopt these seman tics in the future; such a change would be upwardly compatible. | 7097 Clearly, if a deferred type has not yet been loaded, it is impossible to do a co rrect subtype test involving it, and one would expect a dynamic failure, as is t he case with type tests and casts. By the same token, one would expect checked m ode to work seamlessly once a type had been loaded. We hope to adopt these seman tics in the future; such a change would be upwardly compatible. |
7085 | 7098 |
7086 } | 7099 } |
7087 | 7100 |
7088 %It is a run-time type error to access an undeclared type outside . | 7101 %It is a run-time type error to access an undeclared type outside . |
7089 | 7102 |
7090 \LMHash{} | 7103 \LMHash{} |
7091 %It is a dynamic type error if a malformed type is used in a subtype test. | 7104 %It is a dynamic type error if a malformed type is used in a subtype test. |
7092 In checked mode, it is a dynamic type error if a deferred, malformed or malbound ed (\ref{parameterizedTypes}) | 7105 In checked mode, it is a dynamic type error if a deferred, malformed or malbound ed (\ref{parameterizedTypes}) |
7093 type is used in a subtype test. | 7106 type is used in a subtype test. |
7094 | 7107 |
7095 %In production mode, an undeclared type is treated as an instance of type \DYNAM IC{}. | 7108 %In production mode, an undeclared type is treated as an instance of type \DYNAM IC{}. |
7096 | 7109 |
7097 \commentary{Consider the following program} | 7110 \commentary{Consider the following program} |
7098 | 7111 |
7099 \begin{dartCode} | 7112 \begin{dartCode} |
7100 \TYPEDEF{} F(bool x); | 7113 \TYPEDEF{} F(bool x); |
7101 f(foo x) $=>$ x; | 7114 f(foo x) $=>$ x; |
7102 main() \{ | 7115 main() \{ |
7103 if (f is F) \{ | 7116 if (f is F) \{ |
7104 print("yoyoma"); | 7117 print("yoyoma"); |
7105 \} | 7118 \} |
7106 \} | 7119 \} |
7107 \end{dartCode} | 7120 \end{dartCode} |
7108 | 7121 |
7109 \commentary{ | 7122 \commentary{ |
7110 The type of the formal parameter of $f$ is $foo$, which is undeclared in the lex ical scope. This will lead to a static type warning. At runtime the program will print \cd{yoyoma}, because $foo$ is treated as \DYNAMIC{}. | 7123 The type of the formal parameter of $f$ is $foo$, which is undeclared in the lex ical scope. This will lead to a static type warning. At runtime the program will print \cd{yoyoma}, because $foo$ is treated as \DYNAMIC{}. |
7111 %fail when executing the type test on the first line of $main()$ because it lead s to a subtype comparison involving a malformed type ($foo$). | 7124 %fail when executing the type test on the first line of $main()$ because it lead s to a subtype comparison involving a malformed type ($foo$). |
7112 | 7125 |
7113 As another example take} | 7126 As another example take} |
7114 | 7127 |
7115 \begin{dartCode} | 7128 \begin{dartCode} |
7116 \VAR{} i; | 7129 \VAR{} i; |
7117 i j; // a variable j of type i (supposedly) | 7130 i j; // a variable j of type i (supposedly) |
7118 main() \{ | 7131 main() \{ |
7119 j = 'I am not an i'; | 7132 j = 'I am not an i'; |
7120 \} | 7133 \} |
7121 \end{dartCode} | 7134 \end{dartCode} |
7122 | 7135 |
7123 \commentary{ | 7136 \commentary{ |
7124 Since $i$ is not a type, a static warning will be issue at the declaration of $j $. However, the program can be executed without incident in production mode beca use he undeclared type $i$ is treated as \DYNAMIC{}. However, in checked mode, t he implicit subtype test at the assignment will trigger an error at runtime. | 7137 Since $i$ is not a type, a static warning will be issue at the declaration of $j $. However, the program can be executed without incident in production mode beca use he undeclared type $i$ is treated as \DYNAMIC{}. However, in checked mode, t he implicit subtype test at the assignment will trigger an error at runtime. |
7125 } | 7138 } |
7126 | 7139 |
7127 | 7140 |
7128 \commentary{ | 7141 \commentary{ |
7129 Here is an example involving malbounded types: | 7142 Here is an example involving malbounded types: |
7130 } | 7143 } |
7131 | 7144 |
7132 \begin{dartCode} | 7145 \begin{dartCode} |
7133 \CLASS{} I$<$T \EXTENDS{} num$>$ \{\} | 7146 \CLASS{} I$<$T \EXTENDS{} num$>$ \{\} |
7134 \CLASS{} J \{\} | 7147 \CLASS{} J \{\} |
7135 | 7148 |
7136 \CLASS{} A$<$T$>$ \IMPLEMENTS{} J, I$<$T$>$ // type warning: T is not a subtype of num | 7149 \CLASS{} A$<$T$>$ \IMPLEMENTS{} J, I$<$T$>$ // type warning: T is not a subtype of num |
7137 \{ ... | 7150 \{ ... |
7138 \} | 7151 \} |
7139 \end{dartCode} | 7152 \end{dartCode} |
7140 | 7153 |
7141 \commentary{Given the declarations above, the following} | 7154 \commentary{Given the declarations above, the following} |
7142 | 7155 |
7143 \begin{dartCode} | 7156 \begin{dartCode} |
7144 I x = \NEW{} A$<$String$>$(); | 7157 I x = \NEW{} A$<$String$>$(); |
7145 \end{dartCode} | 7158 \end{dartCode} |
7146 | 7159 |
7147 \commentary{ | 7160 \commentary{ |
7148 will cause a dynamic type error in checked mode, because the assignment requires a subtype test A$<$String$>$ $<$: I. To show that this holds, we need to show t hat A$<$String$>$ $<<$ I$<$String$>$, but I$<$String$>$ is a malbounded type, c ausing the dynamic error. No error is thrown in production mode. Note that | 7161 will cause a dynamic type error in checked mode, because the assignment requires a subtype test A$<$String$>$ $<$: I. To show that this holds, we need to show t hat A$<$String$>$ $<<$ I$<$String$>$, but I$<$String$>$ is a malbounded type, c ausing the dynamic error. No error is thrown in production mode. Note that |
7149 } | 7162 } |
7150 | 7163 |
7151 \begin{dartCode} | 7164 \begin{dartCode} |
7152 J x = \NEW{} A$<$String$>$(); | 7165 J x = \NEW{} A$<$String$>$(); |
7153 \end{dartCode} | 7166 \end{dartCode} |
7154 | 7167 |
7155 \commentary{ | 7168 \commentary{ |
7156 does not cause a dynamic error, as there is no need to test against \code{I$<$St ring$>$} in this case. | 7169 does not cause a dynamic error, as there is no need to test against \code{I$<$St ring$>$} in this case. |
7157 Similarly, in production mode | 7170 Similarly, in production mode |
7158 } | 7171 } |
7159 | 7172 |
7160 \begin{dartCode} | 7173 \begin{dartCode} |
7161 A x = \NEW{} A$<$String$>$(); | 7174 A x = \NEW{} A$<$String$>$(); |
7162 bool b = x is I; | 7175 bool b = x is I; |
7163 \end{dartCode} | 7176 \end{dartCode} |
7164 | 7177 |
7165 \commentary{ | 7178 \commentary{ |
7166 \code{b} is bound to \TRUE, but in checked mode the second line causes a dynamic type error. | 7179 \code{b} is bound to \TRUE, but in checked mode the second line causes a dynamic type error. |
7167 } | 7180 } |
7168 | 7181 |
7169 | 7182 |
7170 | 7183 |
7171 \subsection{Type Declarations} | 7184 \subsection{Type Declarations} |
7172 \LMLabel{typeDeclarations} | 7185 \LMLabel{typeDeclarations} |
7173 | 7186 |
7174 \subsubsection{Typedef} | 7187 \subsubsection{Typedef} |
7175 \LMLabel{typedef} | 7188 \LMLabel{typedef} |
7176 | 7189 |
7177 \LMHash{} | 7190 \LMHash{} |
7178 A {\em type alias} declares a name for a type expression. | 7191 A {\em type alias} declares a name for a type expression. |
7179 | 7192 |
7180 | 7193 |
7181 \begin{grammar} | 7194 \begin{grammar} |
7182 | 7195 |
7183 {\bf typeAlias:} | 7196 {\bf typeAlias:} |
7184 metadata \TYPEDEF{} typeAliasBody | 7197 metadata \TYPEDEF{} typeAliasBody |
7185 . | 7198 . |
7186 » | 7199 |
7187 {\bf typeAliasBody:} | 7200 {\bf typeAliasBody:} |
7188 functionTypeAlias | 7201 functionTypeAlias |
7189 . | 7202 . |
7190 | 7203 |
7191 {\bf functionTypeAlias:} | 7204 {\bf functionTypeAlias:} |
7192 functionPrefix typeParameters? formalParameterList '{\escapegrammar ;}' | 7205 functionPrefix typeParameters? formalParameterList '{\escapegrammar ;}' |
7193 . | 7206 . |
7194 | 7207 |
7195 {\bf functionPrefix:} | 7208 {\bf functionPrefix:} |
7196 returnType? identifier | 7209 returnType? identifier |
7197 . | 7210 . |
7198 | 7211 |
7199 \end{grammar} | 7212 \end{grammar} |
7200 | 7213 |
7201 \LMHash{} | 7214 \LMHash{} |
7202 The effect of a type alias of the form \code{\TYPEDEF{} $T$ $id (T_1$ $p_1, \l dots, T_n$ $p_n, [T_{n+1}$ $p_{n+1}, \ldots, T_{n+k}$ $p_{n+k}])$} declared in a library $L$ is is to introduce the name $id$ into the scope of $L$, bound to th e function type $(T_1, \ldots, T_n, [T_{n+1}$ $p_{n+1}, \ldots, T_{n+k}$ $p_{n+k }]) \rightarrow T$. The effect of a type alias of the form \code{\TYPEDEF{} $T$ $id (T_1$ $p_1, \ldots, T_n$ $p_n, \{T_{n+1}$ $p_{n+1}, \ldots, T_{n+k}$ $p_ {n+k}\})$} declared in a library $L$ is is to introduce the name $id$ into the s cope of $L$, bound to the function type $(T_1, \ldots, T_n, \{T_{n+1}$ $p_{n+1}, \ldots, T_{n+k}$ $p_{n+k}\}) \rightarrow T$. . In either case, iff no return t ype is specified, it is taken to be \DYNAMIC{}. Likewise, if a type annotation i s omitted on a formal parameter, it is taken to be \DYNAMIC{}. | 7215 The effect of a type alias of the form \code{\TYPEDEF{} $T$ $id (T_1$ $p_1, \l dots, T_n$ $p_n, [T_{n+1}$ $p_{n+1}, \ldots, T_{n+k}$ $p_{n+k}])$} declared in a library $L$ is is to introduce the name $id$ into the scope of $L$, bound to th e function type $(T_1, \ldots, T_n, [T_{n+1}$ $p_{n+1}, \ldots, T_{n+k}$ $p_{n+k }]) \rightarrow T$. The effect of a type alias of the form \code{\TYPEDEF{} $T$ $id (T_1$ $p_1, \ldots, T_n$ $p_n, \{T_{n+1}$ $p_{n+1}, \ldots, T_{n+k}$ $p_ {n+k}\})$} declared in a library $L$ is is to introduce the name $id$ into the s cope of $L$, bound to the function type $(T_1, \ldots, T_n, \{T_{n+1}$ $p_{n+1}, \ldots, T_{n+k}$ $p_{n+k}\}) \rightarrow T$. . In either case, iff no return t ype is specified, it is taken to be \DYNAMIC{}. Likewise, if a type annotation i s omitted on a formal parameter, it is taken to be \DYNAMIC{}. |
7203 | 7216 |
7204 \LMHash{} | 7217 \LMHash{} |
7205 It is a compile-time error if any default values are specified in the signature of a function type alias. | 7218 It is a compile-time error if any default values are specified in the signature of a function type alias. |
7206 %A typedef may only refer to itself via the bounds of its generic parameters. | 7219 %A typedef may only refer to itself via the bounds of its generic parameters. |
7207 Any self reference in a typedef, either directly, or recursively via another ty pedef, is a compile time error. | 7220 Any self reference in a typedef, either directly, or recursively via another ty pedef, is a compile time error. |
7208 %via a chain of references that does not include a class declaration. | 7221 %via a chain of references that does not include a class declaration. |
7209 | 7222 |
7210 | 7223 |
7211 | 7224 |
7212 \subsection{Interface Types} | 7225 \subsection{Interface Types} |
7213 \LMLabel{interfaceTypes} | 7226 \LMLabel{interfaceTypes} |
7214 | 7227 |
7215 \LMHash{} | 7228 \LMHash{} |
7216 The implicit interface of class $I$ is a direct supertype of the implicit interf ace of class $J$ iff: | 7229 The implicit interface of class $I$ is a direct supertype of the implicit interf ace of class $J$ iff: |
7217 \begin{itemize} | 7230 \begin{itemize} |
7218 \item | 7231 \item |
7219 If $I$ is \code{Object}, and $J$ has no \EXTENDS{} clause% and no interface inje ction declaration has extended $J. | 7232 If $I$ is \code{Object}, and $J$ has no \EXTENDS{} clause% and no interface inje ction declaration has extended $J. |
(...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
7260 $List <: List<String>$ and $List<int> <: List$, but $List<int>$ is not a subtype of $List<String>$. | 7273 $List <: List<String>$ and $List<int> <: List$, but $List<int>$ is not a subtype of $List<String>$. |
7261 Although $<:$ is not a partial order on types, it does contain a partial order, namely $<<$. This means that, barring raw types, intuition about classical subty pe rules does apply. | 7274 Although $<:$ is not a partial order on types, it does contain a partial order, namely $<<$. This means that, barring raw types, intuition about classical subty pe rules does apply. |
7262 } | 7275 } |
7263 | 7276 |
7264 \LMHash{} | 7277 \LMHash{} |
7265 $S$ is a supertype of $T$, written $S :> T$, iff $T$ is a subtype of $S$. | 7278 $S$ is a supertype of $T$, written $S :> T$, iff $T$ is a subtype of $S$. |
7266 | 7279 |
7267 \commentary{The supertypes of an interface are its direct supertypes and their s upertypes. } | 7280 \commentary{The supertypes of an interface are its direct supertypes and their s upertypes. } |
7268 | 7281 |
7269 \LMHash{} | 7282 \LMHash{} |
7270 An interface type $T$ may be assigned to a type $S$, written $T \Longleftrighta rrow S$, iff either $T <: S$ or $S <: T$. | 7283 An interface type $T$ may be assigned to a type $S$, written $T \Longleftrighta rrow S$, iff either $T <: S$ or $S <: T$. |
7271 | 7284 |
7272 \rationale{This rule may surprise readers accustomed to conventional typecheckin g. The intent of the $\Longleftrightarrow$ relation is not to ensure that an ass ignment is correct. Instead, it aims to only flag assignments that are almost ce rtain to be erroneous, without precluding assignments that may work. | 7285 \rationale{This rule may surprise readers accustomed to conventional typecheckin g. The intent of the $\Longleftrightarrow$ relation is not to ensure that an ass ignment is correct. Instead, it aims to only flag assignments that are almost ce rtain to be erroneous, without precluding assignments that may work. |
7273 | 7286 |
7274 For example, assigning a value of static type Object to a variable with static t ype String, while not guaranteed to be correct, might be fine if the runtime val ue happens to be a string. | 7287 For example, assigning a value of static type Object to a variable with static t ype String, while not guaranteed to be correct, might be fine if the runtime val ue happens to be a string. |
7275 } | 7288 } |
7276 | 7289 |
7277 \subsection{Function Types} | 7290 \subsection{Function Types} |
7278 \LMLabel{functionTypes} | 7291 \LMLabel{functionTypes} |
7279 | 7292 |
7280 \LMHash{} | 7293 \LMHash{} |
7281 Function types come in two variants: | 7294 Function types come in two variants: |
7282 \begin{enumerate} | 7295 \begin{enumerate} |
7283 \item | 7296 \item |
7284 The types of functions that only have positional parameters. These have the gen eral form $(T_1, \ldots, T_n, [T_{n+1} \ldots, T_{n+k}]) \rightarrow T$. | 7297 The types of functions that only have positional parameters. These have the gen eral form $(T_1, \ldots, T_n, [T_{n+1} \ldots, T_{n+k}]) \rightarrow T$. |
7285 \item | 7298 \item |
7286 The types of functions with named parameters. These have the general form $(T_1 , \ldots, T_n, \{T_{x_1}$ $x_1 \ldots, T_{x_k}$ $x_k\}) \rightarrow T$. | 7299 The types of functions with named parameters. These have the general form $(T_1 , \ldots, T_n, \{T_{x_1}$ $x_1 \ldots, T_{x_k}$ $x_k\}) \rightarrow T$. |
7287 \end{enumerate} | 7300 \end{enumerate} |
7288 | 7301 |
7289 %$(T_1, \ldots T_n) \rightarrow T$ is a subtype of $(S_1, \ldots, S_n, ) \right arrow S$, if all of the following conditions are met: | 7302 %$(T_1, \ldots T_n) \rightarrow T$ is a subtype of $(S_1, \ldots, S_n, ) \right arrow S$, if all of the following conditions are met: |
7290 %\begin{enumerate} | 7303 %\begin{enumerate} |
7291 %\item Either | 7304 %\item Either |
7292 %\begin{itemize} | 7305 %\begin{itemize} |
7293 %\item $S$ is \VOID{}, Or | 7306 %\item $S$ is \VOID{}, Or |
7294 %\item $T \Longleftrightarrow S$. | 7307 %\item $T \Longleftrightarrow S$. |
7295 %\end{itemize} | 7308 %\end{itemize} |
7296 %\item$ \forall i \in 1 .. n, T_i \Longleftrightarrow S_i$. | 7309 %\item$ \forall i \in 1 .. n, T_i \Longleftrightarrow S_i$. |
7297 %\end{enumerate} | 7310 %\end{enumerate} |
7298 | 7311 |
7299 \LMHash{} | 7312 \LMHash{} |
7300 %A function type $(T_1, \ldots T_n, [T_{n+1} \ldots, T_{n+k}]) \rightarrow T$ i s a subtype of the | 7313 %A function type $(T_1, \ldots T_n, [T_{n+1} \ldots, T_{n+k}]) \rightarrow T$ i s a subtype of the |
7301 % the line below revises the rule to be more liberal | 7314 % the line below revises the rule to be more liberal |
7302 A function type $(T_1, \ldots T_{k}, [T_{k+1} \ldots, T_{n+m}]) \rightarrow T$ is a subtype of the | 7315 A function type $(T_1, \ldots T_{k}, [T_{k+1} \ldots, T_{n+m}]) \rightarrow T$ is a subtype of the |
7303 function type $(S_1, \ldots, S_{k+j}, [S_{k+j+1} \ldots, S_{n}]) \rightarrow S$, if all of the following conditions are met: | 7316 function type $(S_1, \ldots, S_{k+j}, [S_{k+j+1} \ldots, S_{n}]) \rightarrow S$, if all of the following conditions are met: |
7304 \begin{enumerate} | 7317 \begin{enumerate} |
7305 \item Either | 7318 \item Either |
7306 \begin{itemize} | 7319 \begin{itemize} |
7307 \item $S$ is \VOID{}, Or | 7320 \item $S$ is \VOID{}, Or |
7308 \item $T \Longleftrightarrow S$. | 7321 \item $T \Longleftrightarrow S$. |
7309 \end{itemize} | 7322 \end{itemize} |
7310 \item $\forall i \in 1 .. n, T_i \Longleftrightarrow S_i$. | 7323 \item $\forall i \in 1 .. n, T_i \Longleftrightarrow S_i$. |
7311 \end{enumerate} | 7324 \end{enumerate} |
7312 | 7325 |
7313 | 7326 |
7314 \LMHash{} | 7327 \LMHash{} |
7315 A function type $(T_1, \ldots T_n, \{T_{x_1}$ $x_1, \ldots, T_{x_k}$ $x_k\}) \ri ghtarrow T$ is a subtype of the function type $(S_1, \ldots, S_n, \{S_{y_1}$ $y_ 1, \ldots, S_{y_m}$ $y_m\}) \rightarrow S$, if all of the following conditions a re met: | 7328 A function type $(T_1, \ldots T_n, \{T_{x_1}$ $x_1, \ldots, T_{x_k}$ $x_k\}) \ri ghtarrow T$ is a subtype of the function type $(S_1, \ldots, S_n, \{S_{y_1}$ $y_ 1, \ldots, S_{y_m}$ $y_m\}) \rightarrow S$, if all of the following conditions a re met: |
7316 \begin{enumerate} | 7329 \begin{enumerate} |
7317 \item Either | 7330 \item Either |
7318 \begin{itemize} | 7331 \begin{itemize} |
7319 \item $S$ is \VOID{}, Or | 7332 \item $S$ is \VOID{}, Or |
7320 \item $T \Longleftrightarrow S$. | 7333 \item $T \Longleftrightarrow S$. |
7321 \end{itemize} | 7334 \end{itemize} |
7322 \item $\forall i \in 1 .. n, T_i \Longleftrightarrow S_i$. | 7335 \item $\forall i \in 1 .. n, T_i \Longleftrightarrow S_i$. |
7323 \item $k \ge m$ and $y_i \in \{x_1, \ldots, x_k\}, i \in 1 .. m$. | 7336 \item $k \ge m$ and $y_i \in \{x_1, \ldots, x_k\}, i \in 1 .. m$. |
7324 %\{x_1, \ldots, x_k\}$ is a superset of $\{y_1, \ldots, y_m\}$. | 7337 %\{x_1, \ldots, x_k\}$ is a superset of $\{y_1, \ldots, y_m\}$. |
7325 \item For all $y_i \in \{y_1, \ldots, y_m\}, y_i = x_j \Rightarrow T_j \Longlef trightarrow S_i$ | 7338 \item For all $y_i \in \{y_1, \ldots, y_m\}, y_i = x_j \Rightarrow T_{x_j} \Lon gleftrightarrow S_{y_i}$ |
7326 \end{enumerate} | 7339 \end{enumerate} |
7327 | 7340 |
7328 %In addition, a function type $(T_1, \ldots, Tn, [T_{n+1} x_{n+1}, \ldots, T_{n+ k} x_{n+k}]) \rightarrow T$ is a subtype of the function type $(T_1, \ldots, T_n , T_{n+1} , [T_{n+2} x_{n+2}, \ldots, T_{n+k} x_{n+k}]) \rightarrow T$. | 7341 %In addition, a function type $(T_1, \ldots, Tn, [T_{n+1} x_{n+1}, \ldots, T_{n+ k} x_{n+k}]) \rightarrow T$ is a subtype of the function type $(T_1, \ldots, T_n , T_{n+1} , [T_{n+2} x_{n+2}, \ldots, T_{n+k} x_{n+k}]) \rightarrow T$. |
7329 | 7342 |
7330 %\rationale{This second rule is attractive to web developers, who are used to th is sort of flexibility from Javascript. However, it may be costly to implement e fficiently.} \Q{Should we do this or not?} | 7343 %\rationale{This second rule is attractive to web developers, who are used to th is sort of flexibility from Javascript. However, it may be costly to implement e fficiently.} \Q{Should we do this or not?} |
7331 | 7344 |
7332 %We write $(T_1, \ldots, T_n) \rightarrow T$ as a shorthand for the type $(T_1, \ldots, T_n, []) \rightarrow T$. | 7345 %We write $(T_1, \ldots, T_n) \rightarrow T$ as a shorthand for the type $(T_1, \ldots, T_n, []) \rightarrow T$. |
7333 | 7346 |
7334 %The rules above need to be sanity checked, but the intent is that we view funct ions with rest parameters as having type $(T_1, ..., T_n, [\_{Tn+1}[] \_]) \righ tarrow T$, where \_ is some magical identifier. Then the rules above may cover e verything. | 7347 %The rules above need to be sanity checked, but the intent is that we view funct ions with rest parameters as having type $(T_1, ..., T_n, [\_{Tn+1}[] \_]) \righ tarrow T$, where \_ is some magical identifier. Then the rules above may cover e verything. |
7335 % This is wrong - from the outside, the type takes an unbounded sequence of type s, not a list. This can be modeled as $(T_1, \ldots, T_n, [T_{n+1}, \_ \ldots, T _{n+k} \_]) \rightarrow T$ for some finite $k$. | 7348 % This is wrong - from the outside, the type takes an unbounded sequence of type s, not a list. This can be modeled as $(T_1, \ldots, T_n, [T_{n+1}, \_ \ldots, T _{n+k} \_]) \rightarrow T$ for some finite $k$. |
7336 | 7349 |
7337 \LMHash{} | 7350 \LMHash{} |
7338 In addition, the following subtype rules apply: | 7351 In addition, the following subtype rules apply: |
7339 | 7352 |
7340 | 7353 |
7341 $(T_1, \ldots, T_n, []) \rightarrow T <: (T_1, \ldots, T_n) \rightarrow T$. | 7354 $(T_1, \ldots, T_n, []) \rightarrow T <: (T_1, \ldots, T_n) \rightarrow T$. |
7342 | 7355 |
7343 $(T_1, \ldots, T_n) \rightarrow T <: (T_1, \ldots, T_n, \{\}) \rightarrow T$. | 7356 $(T_1, \ldots, T_n) \rightarrow T <: (T_1, \ldots, T_n, \{\}) \rightarrow T$. |
7344 | 7357 |
7345 $(T_1, \ldots, T_n, \{\}) \rightarrow T <: (T_1, \ldots, T_n) \rightarrow T$. | 7358 $(T_1, \ldots, T_n, \{\}) \rightarrow T <: (T_1, \ldots, T_n) \rightarrow T$. |
7346 | 7359 |
7347 $(T_1, \ldots, T_n) \rightarrow T <: (T_1, \ldots, T_n, []) \rightarrow T$. | 7360 $(T_1, \ldots, T_n) \rightarrow T <: (T_1, \ldots, T_n, []) \rightarrow T$. |
7348 | 7361 |
7349 \rationale{ | 7362 \rationale{ |
7350 The naive reader might conclude that, since it is not legal to declare a functio n with an empty optional parameter list, these rules are pointless. However, the y induce useful relationships between function types that declare no optional p arameters and those that do. | 7363 The naive reader might conclude that, since it is not legal to declare a functio n with an empty optional parameter list, these rules are pointless. However, the y induce useful relationships between function types that declare no optional p arameters and those that do. |
7351 } | 7364 } |
7352 | 7365 |
7353 \LMHash{} | 7366 \LMHash{} |
7354 A function type $T$ may be assigned to a function type $S$, written $T \Longlef trightarrow S$, iff $T <: S$. | 7367 A function type $T$ may be assigned to a function type $S$, written $T \Longlef trightarrow S$, iff $T <: S$. |
7355 | 7368 |
7356 \LMHash{} | 7369 \LMHash{} |
7357 % ensure that Object and dynamic may be assign dot a function type | 7370 % ensure that Object and dynamic may be assign dot a function type |
7358 A function is always an instance of some class that implements the class \code{F unction} and implements a \CALL{} method with the same signature as the function . All function types are subtypes of \code{Function}. | 7371 A function is always an instance of some class that implements the class \code{F unction} and implements a \CALL{} method with the same signature as the function . All function types are subtypes of \code{Function}. |
7359 If a type $I$ includes an instance method named \CALL{}, and the type of \CALL{} is the function type $F$, then $I$ is considered to be more specific than $F$. It is a static warning if a concrete class implements \cd{Function} and does no t have a concrete method named \CALL{} unless that class has an implementation o f \cd{noSuchMethod()} distinct from the one declared in class \cd{Object}. | 7372 If a type $I$ includes an instance method named \CALL{}, and the type of \CALL{} is the function type $F$, then $I$ is considered to be more specific than $F$. It is a static warning if a concrete class implements \cd{Function} and does no t have a concrete method named \CALL{} unless that class has an implementation o f \cd{noSuchMethod()} distinct from the one declared in class \cd{Object}. |
7360 | 7373 |
7361 | 7374 |
7362 | 7375 |
7363 | 7376 |
7364 %\commentary{Need to specify how a function values dynamic type is derived from its static signature.} | 7377 %\commentary{Need to specify how a function values dynamic type is derived from its static signature.} |
(...skipping 26 matching lines...) Expand all Loading... | |
7391 \end{enumerate} | 7404 \end{enumerate} |
7392 | 7405 |
7393 \LMHash{} | 7406 \LMHash{} |
7394 Furthermore, if $F$ is a function type, $F << \code{Function}$. | 7407 Furthermore, if $F$ is a function type, $F << \code{Function}$. |
7395 | 7408 |
7396 | 7409 |
7397 \subsection{Type \DYNAMIC{}} | 7410 \subsection{Type \DYNAMIC{}} |
7398 \LMLabel{typeDynamic} | 7411 \LMLabel{typeDynamic} |
7399 | 7412 |
7400 \LMHash{} | 7413 \LMHash{} |
7401 The type \DYNAMIC{} denotes the unknown type. | 7414 The type \DYNAMIC{} denotes the unknown type. |
7402 | 7415 |
7403 \LMHash{} | 7416 \LMHash{} |
7404 If no static type annotation has been provided the type system assumes the decla ration has the unknown type. If a generic type is used but type arguments are no t provided, then the type arguments default to the unknown type. | 7417 If no static type annotation has been provided the type system assumes the decla ration has the unknown type. If a generic type is used but type arguments are no t provided, then the type arguments default to the unknown type. |
7405 | 7418 |
7406 \commentary{This means that given a generic declaration $G<T_1, \ldots, T_n>$, t he type $G$ is equivalent to $G< \DYNAMIC{}, \ldots, \DYNAMIC{}>$. | 7419 \commentary{This means that given a generic declaration $G<T_1, \ldots, T_n>$, t he type $G$ is equivalent to $G< \DYNAMIC{}, \ldots, \DYNAMIC{}>$. |
7407 } | 7420 } |
7408 | 7421 |
7409 \LMHash{} | 7422 \LMHash{} |
7410 Type \DYNAMIC{} has methods for every possible identifier and arity, with every possible combination of named parameters. These methods all have \DYNAMIC{} as their return type, and their formal parameters all have type \DYNAMIC{}. | 7423 Type \DYNAMIC{} has methods for every possible identifier and arity, with every possible combination of named parameters. These methods all have \DYNAMIC{} as their return type, and their formal parameters all have type \DYNAMIC{}. |
7411 Type \DYNAMIC{} has properties for every possible identifier. These properties all have type \DYNAMIC{}. | 7424 Type \DYNAMIC{} has properties for every possible identifier. These properties all have type \DYNAMIC{}. |
7412 | 7425 |
7413 \rationale{From a usability perspective, we want to ensure that the checker does not issue errors everywhere an unknown type is used. The definitions above ensu re that no secondary errors are reported when accessing an unknown type. | 7426 \rationale{From a usability perspective, we want to ensure that the checker does not issue errors everywhere an unknown type is used. The definitions above ensu re that no secondary errors are reported when accessing an unknown type. |
7414 | 7427 |
7415 The current rules say that missing type arguments are treated as if they were th e type \DYNAMIC{}. An alternative is to consider them as meaning \code{Object} . This would lead to earlier error detection in checked mode, and more aggressi ve errors during static typechecking. For example: | 7428 The current rules say that missing type arguments are treated as if they were th e type \DYNAMIC{}. An alternative is to consider them as meaning \code{Object} . This would lead to earlier error detection in checked mode, and more aggressi ve errors during static typechecking. For example: |
7416 | 7429 |
7417 (1) \code{typedAPI(G\lt{String}\gt g)\{...\}} | 7430 (1) \code{typedAPI(G\lt{String}\gt g)\{...\}} |
7418 | 7431 |
7419 | 7432 |
7420 (2) \code{typedAPI(new G()); } | 7433 (2) \code{typedAPI(new G()); } |
7421 | 7434 |
7422 | 7435 |
7423 Under the alternative rules, (2) would cause a runtime error in checked mode. Th is seems desirable from the perspective of error localization. However, when a d ynamic error is thrown at (2), the only way to keep running is rewriting (2) int o | 7436 Under the alternative rules, (2) would cause a runtime error in checked mode. Th is seems desirable from the perspective of error localization. However, when a d ynamic error is thrown at (2), the only way to keep running is rewriting (2) int o |
7424 | 7437 |
7425 (3) \code{typedAPI(new G\lt{String}\gt());} | 7438 (3) \code{typedAPI(new G\lt{String}\gt());} |
7426 | 7439 |
7427 This forces users to write type information in their client code just because th ey are calling a typed API. We do not want to impose this on Dart programmers, some of which may be blissfully unaware of types in general, and genericity in p articular. | 7440 This forces users to write type information in their client code just because th ey are calling a typed API. We do not want to impose this on Dart programmers, some of which may be blissfully unaware of types in general, and genericity in p articular. |
7428 | 7441 |
7429 What of static checking? Surely we would want to flag (2) when users have explic itly asked for static typechecking? Yes, but the reality is that the Dart static checker is likely to be running in the background by default. Engineering teams typically desire a ``clean build'' free of warnings and so the checker is desig ned to be extremely charitable. Other tools can interpret the type information m ore aggressively and warn about violations of conventional (and sound) static ty pe discipline. | 7442 What of static checking? Surely we would want to flag (2) when users have explic itly asked for static typechecking? Yes, but the reality is that the Dart static checker is likely to be running in the background by default. Engineering teams typically desire a ``clean build'' free of warnings and so the checker is desig ned to be extremely charitable. Other tools can interpret the type information m ore aggressively and warn about violations of conventional (and sound) static ty pe discipline. |
7430 } | 7443 } |
7431 | 7444 |
7432 \LMHash{} | 7445 \LMHash{} |
7433 The name \DYNAMIC{} denotes a \cd{Type} object even though \DYNAMIC{} is not a c lass. | 7446 The name \DYNAMIC{} denotes a \cd{Type} object even though \DYNAMIC{} is not a c lass. |
7434 | 7447 |
7435 %\rationale { | 7448 %\rationale { |
7436 %Type objects reify the runtime types of instances. No instance ever has type \D YNAMIC{}. | 7449 %Type objects reify the runtime types of instances. No instance ever has type \D YNAMIC{}. |
7437 %} | 7450 %} |
7438 | 7451 |
7439 \subsection{Type Void} | 7452 \subsection{Type Void} |
7440 \LMLabel{typeVoid} | 7453 \LMLabel{typeVoid} |
7441 | 7454 |
7442 \LMHash{} | 7455 \LMHash{} |
7443 The special type \VOID{} may only be used as the return type of a function: it i s a compile-time error to use \VOID{} in any other context. | 7456 The special type \VOID{} may only be used as the return type of a function: it i s a compile-time error to use \VOID{} in any other context. |
7444 | 7457 |
7445 \commentary{ | 7458 \commentary{ |
7446 For example, as a type argument, or as the type of a variable or parameter | 7459 For example, as a type argument, or as the type of a variable or parameter |
7447 | 7460 |
7448 Void is not an interface type. | 7461 Void is not an interface type. |
7449 | 7462 |
7450 The only subtype relations that pertain to void are therefore: | 7463 The only subtype relations that pertain to void are therefore: |
7451 \begin{itemize} | 7464 \begin{itemize} |
7452 \item | 7465 \item |
7453 $\VOID{} <: \VOID{}$ (by reflexivity) | 7466 $\VOID{} <: \VOID{}$ (by reflexivity) |
7454 \item | 7467 \item |
7455 $\bot <: \VOID{}$ (as bottom is a subtype of all types). | 7468 $\bot <: \VOID{}$ (as bottom is a subtype of all types). |
7456 \item | 7469 \item |
7457 $\VOID{} <: \DYNAMIC{}$ (as \DYNAMIC{} is a supertype of all types) | 7470 $\VOID{} <: \DYNAMIC{}$ (as \DYNAMIC{} is a supertype of all types) |
7458 \end{itemize} | 7471 \end{itemize} |
7459 | 7472 |
7460 The analogous rules also hold for the $<<$ relation for similar reasons. | 7473 The analogous rules also hold for the $<<$ relation for similar reasons. |
7461 | 7474 |
7462 Hence, the static checker will issue warnings if one attempts to access a member of the result of a void method invocation (even for members of \NULL{}, such as \code{==}). Likewise, passing the result of a void method as a parameter or as signing it to a variable will cause a warning unless the variable/formal paramet er has type dynamic. | 7475 Hence, the static checker will issue warnings if one attempts to access a member of the result of a void method invocation (even for members of \NULL{}, such as \code{==}). Likewise, passing the result of a void method as a parameter or as signing it to a variable will cause a warning unless the variable/formal paramet er has type dynamic. |
7463 | 7476 |
7464 On the other hand, it is possible to return the result of a void method from wit hin a void method. One can also return \NULL{}; or a value of type \DYNAMIC{}. R eturning any other result will cause a type warning. In checked mode, a dynamic type error would arise if a non-null object was returned from a void method (sin ce no object has runtime type \DYNAMIC{}). | 7477 On the other hand, it is possible to return the result of a void method from wit hin a void method. One can also return \NULL{}; or a value of type \DYNAMIC{}. R eturning any other result will cause a type warning. In checked mode, a dynamic type error would arise if a non-null object was returned from a void method (sin ce no object has runtime type \DYNAMIC{}). |
7465 } | 7478 } |
7466 | 7479 |
7467 \commentary {The name \VOID{} does not denote a \cd{Type} object.} | 7480 \commentary {The name \VOID{} does not denote a \cd{Type} object.} |
7468 | 7481 |
7469 \rationale { | 7482 \rationale { |
7470 It is syntacticly illegal to use \VOID{} as an expression, and it would make no sense to do so. | 7483 It is syntacticly illegal to use \VOID{} as an expression, and it would make no sense to do so. |
7471 Type objects reify the runtime types of instances. No instance ever has type \VO ID{}. | 7484 Type objects reify the runtime types of instances. No instance ever has type \VO ID{}. |
7472 } | 7485 } |
7473 | 7486 |
7474 | 7487 |
7475 | 7488 |
7476 \subsection{Parameterized Types} | 7489 \subsection{Parameterized Types} |
7477 \LMLabel{parameterizedTypes} | 7490 \LMLabel{parameterizedTypes} |
7478 | 7491 |
7479 \LMHash{} | 7492 \LMHash{} |
7480 A {\em parameterized type} is an invocation of a generic type declaration. | 7493 A {\em parameterized type} is an invocation of a generic type declaration. |
7481 | 7494 |
7482 \LMHash{} | 7495 \LMHash{} |
7483 Let $T$ be a parameterized type $G<S_1, \ldots, S_n>$. If $G$ is not a generic type, the type arguments $S_i$, $1 \le i \le n$ are discarded. If $G$ has $m \n e n$ type parameters, $T$ is treated as as a parameterized type with $m$ argumen ts, all of which are \DYNAMIC{}. | 7496 Let $T$ be a parameterized type $G<S_1, \ldots, S_n>$. If $G$ is not a generic type, the type arguments $S_i$, $1 \le i \le n$ are discarded. If $G$ has $m \n e n$ type parameters, $T$ is treated as as a parameterized type with $m$ argumen ts, all of which are \DYNAMIC{}. |
7484 | 7497 |
7485 \commentary{In short, any arity mismatch results in all type arguments being dro pped, and replaced with the correct number of type arguments, all set to \DYNAMI C{}. Of course, a static warning will be issued. | 7498 \commentary{In short, any arity mismatch results in all type arguments being dro pped, and replaced with the correct number of type arguments, all set to \DYNAMI C{}. Of course, a static warning will be issued. |
7486 } | 7499 } |
7487 | 7500 |
7488 \LMHash{} | 7501 \LMHash{} |
7489 Otherwise, let | 7502 Otherwise, let |
7490 $T_i$ be the type parameters of $G$ and let $B_i$ be the bound of $T_i, i \in 1.. n$,. $T$ is {\em malbounded} iff either $S_i$ is malbounded or $S_i$ is not a subtype of $[S_1, \ldots, S_n/T_1, \ldots, T_n]B_i, i \in 1.. n$. | 7503 $T_i$ be the type parameters of $G$ and let $B_i$ be the bound of $T_i, i \in 1.. n$,. $T$ is {\em malbounded} iff either $S_i$ is malbounded or $S_i$ is not a subtype of $[S_1, \ldots, S_n/T_1, \ldots, T_n]B_i, i \in 1.. n$. |
7491 | 7504 |
7492 \commentary{ | 7505 \commentary{ |
7493 Note, that, in checked mode, it is a dynamic type error if a malbounded type is used in a type test as specified in \ref{dynamicTypeSystem}. | 7506 Note, that, in checked mode, it is a dynamic type error if a malbounded type is used in a type test as specified in \ref{dynamicTypeSystem}. |
7494 } | 7507 } |
7495 | 7508 |
7496 \LMHash{} | 7509 \LMHash{} |
7497 Any use of a malbounded type gives rise to a static warning. | 7510 Any use of a malbounded type gives rise to a static warning. |
7498 | 7511 |
7499 \LMHash{} | 7512 \LMHash{} |
7500 If $S$ is the static type of a member $m$ of $G$, then the static type of the me mber $m$ of $G<A_1, \ldots, A_n>$ is $[A_1, \ldots, A_n/T_1, \ldots, T_n]S$ where $T_1, \ldots, T_n$ are the formal type parameters of $G$. Let $B_i$, be the bounds of $T_i, 1 \le i \le n$. It is a static type warning if $A_i$ is not a subtype of $[A_1, \ldots, A_n/T_1, \ldots, T_n]B_i, i \in 1..n$. It is a s tatic type warning if $G$ is not a generic type with exactly $n$ type parameters . | 7513 If $S$ is the static type of a member $m$ of $G$, then the static type of the me mber $m$ of $G<A_1, \ldots, A_n>$ is $[A_1, \ldots, A_n/T_1, \ldots, T_n]S$ where $T_1, \ldots, T_n$ are the formal type parameters of $G$. Let $B_i$, be the bounds of $T_i, 1 \le i \le n$. It is a static type warning if $A_i$ is not a subtype of $[A_1, \ldots, A_n/T_1, \ldots, T_n]B_i, i \in 1..n$. It is a s tatic type warning if $G$ is not a generic type with exactly $n$ type parameters . |
7501 | 7514 |
7502 | 7515 |
7503 | 7516 |
7504 | 7517 |
7505 | 7518 |
(...skipping 13 matching lines...) Expand all Loading... | |
7519 \begin{itemize} | 7532 \begin{itemize} |
7520 \item $[A_1, \ldots, A_n/U_1, \ldots, U_n]T$ if $d$ depends on type parameters $U_1, \ldots, U_n$, and $A_i$ is the value of $U_i, 1 \le i \le n$. | 7533 \item $[A_1, \ldots, A_n/U_1, \ldots, U_n]T$ if $d$ depends on type parameters $U_1, \ldots, U_n$, and $A_i$ is the value of $U_i, 1 \le i \le n$. |
7521 \item $T$ otherwise. | 7534 \item $T$ otherwise. |
7522 \end{itemize} | 7535 \end{itemize} |
7523 | 7536 |
7524 \subsubsection{Least Upper Bounds} | 7537 \subsubsection{Least Upper Bounds} |
7525 \LMLabel{leastUpperBounds} | 7538 \LMLabel{leastUpperBounds} |
7526 | 7539 |
7527 \LMHash{} | 7540 \LMHash{} |
7528 % does this diverge in some cases? | 7541 % does this diverge in some cases? |
7529 Given two interfaces $I$ and $J$, let $S_I$ be the set of superinterfaces of $I$ , let $S_J$ be the set of superinterfaces of $J$ and let $S = (I \cup S_I) \ca p (J \cup S_J)$. Furthermore, we define $S_n = \{T | T \in S \wedge depth(T) = n\}$ for any finite $n$ %, and $k=max(depth(T_1), \ldots, depth(T_m)), T_i \in S , i \in 1..m$, | 7542 Given two interfaces $I$ and $J$, let $S_I$ be the set of superinterfaces of $I$ , let $S_J$ be the set of superinterfaces of $J$ and let $S = (I \cup S_I) \ca p (J \cup S_J)$. Furthermore, we define $S_n = \{T | T \in S \wedge depth(T) = n\}$ for any finite $n$ %, and $k=max(depth(T_1), \ldots, depth(T_m)), T_i \in S , i \in 1..m$, |
7530 where $depth(T)$ is the number of steps in the longest inheritance path from $T$ to \code{Object}. Let $q$ be the largest number such that $S_q$ has cardinality one. The least upper bound of $I$ and $J$ is the sole element of $S_q$. | 7543 where $depth(T)$ is the number of steps in the longest inheritance path from $T$ to \code{Object}. Let $q$ be the largest number such that $S_q$ has cardinality one. The least upper bound of $I$ and $J$ is the sole element of $S_q$. |
7531 | 7544 |
7532 \LMHash{} | 7545 \LMHash{} |
7533 The least upper bound of \DYNAMIC{} and any type $T$ is \DYNAMIC{}. | 7546 The least upper bound of \DYNAMIC{} and any type $T$ is \DYNAMIC{}. |
7534 The least upper bound of \VOID{} and any type $T \ne \DYNAMIC{}$ is \VOID{}. | 7547 The least upper bound of \VOID{} and any type $T \ne \DYNAMIC{}$ is \VOID{}. |
7535 The least upper bound of $\bot$ and any type $T$ is $T$. | 7548 The least upper bound of $\bot$ and any type $T$ is $T$. |
7536 Let $U$ be a type variable with upper bound $B$. The least upper bound of $U$ an d a type $T \ne \bot$ is the least upper bound of $B$ and $T$. | 7549 Let $U$ be a type variable with upper bound $B$. The least upper bound of $U$ an d a type $T \ne \bot$ is the least upper bound of $B$ and $T$. |
7537 | 7550 |
7538 \LMHash{} | 7551 \LMHash{} |
7539 The least upper bound relation is symmetric and reflexive. | 7552 The least upper bound relation is symmetric and reflexive. |
7540 | 7553 |
7541 % Function types | 7554 % Function types |
7542 | 7555 |
7543 \LMHash{} | 7556 \LMHash{} |
7544 The least upper bound of a function type and an interface type $T$ is the least upper bound of \cd{Function} and $T$. | 7557 The least upper bound of a function type and an interface type $T$ is the least upper bound of \cd{Function} and $T$. |
7545 Let $F$ and $G$ be function types. If $F$ and $G$ differ in their number of requ ired parameters, then the least upper bound of $F$ and $G$ is \cd{Function}. Ot herwise: | 7558 Let $F$ and $G$ be function types. If $F$ and $G$ differ in their number of requ ired parameters, then the least upper bound of $F$ and $G$ is \cd{Function}. Ot herwise: |
7546 \begin{itemize} | 7559 \begin{itemize} |
7547 \item If | 7560 \item If |
7548 | |
7549 $F= (T_1 \ldots T_r, [T_{r+1}, \ldots, T_n]) \longrightarrow T_0$, | |
7550 | |
7551 $G= (S_1 \ldots S_r, [S_{r+1}, \ldots, S_k]) \longrightarrow S_0$ | |
7552 | |
7553 where $k \le n$ then the least upper bound of $F$ and $G$ is | |
7554 | |
7555 $(L_1 \ldots L_r, [L_{r+1}, \ldots, L_k]) \longrightarrow L_0$ | |
7556 | |
7557 where $L_i$ is the least upper bound of $T_i$ and $S_i, i \in 0..k$. | |
7558 \item If | |
7559 | 7561 |
7560 $F= (T_1 \ldots T_r, [T_{r+1}, \ldots, T_n]) \longrightarrow T_0$, | 7562 $F= (T_1 \ldots T_r, [T_{r+1}, \ldots, T_n]) \longrightarrow T_0$, |
7561 | 7563 |
7562 $G= (S_1 \ldots S_r, \{ \ldots \}) \longrightarrow S_0$ | 7564 $G= (S_1 \ldots S_r, [S_{r+1}, \ldots, S_k]) \longrightarrow S_0$ |
7563 | 7565 |
7564 then the least upper bound of $F$ and $G$ is | 7566 where $k \le n$ then the least upper bound of $F$ and $G$ is |
7565 | 7567 |
7566 $(L_1 \ldots L_r) \longrightarrow L_0$ | 7568 $(L_1 \ldots L_r, [L_{r+1}, \ldots, L_k]) \longrightarrow L_0$ |
7567 | 7569 |
7568 where $L_i$ | 7570 where $L_i$ is the least upper bound of $T_i$ and $S_i, i \in 0..k$. |
7571 \item If | |
7572 | |
7573 $F= (T_1 \ldots T_r, [T_{r+1}, \ldots, T_n]) \longrightarrow T_0$, | |
7574 | |
7575 $G= (S_1 \ldots S_r, \{ \ldots \}) \longrightarrow S_0$ | |
7576 | |
7577 then the least upper bound of $F$ and $G$ is | |
7578 | |
7579 $(L_1 \ldots L_r) \longrightarrow L_0$ | |
7580 | |
7581 where $L_i$ | |
7569 is the least upper bound of $T_i$ and $S_i, i \in 0..r$. | 7582 is the least upper bound of $T_i$ and $S_i, i \in 0..r$. |
7570 \item If | 7583 \item If |
7571 | 7584 |
7572 $F= (T_1 \ldots T_r, \{T_{r+1}$ $p_{r+1}, \ldots, T_f$ $p_f\}) \longrightarrow T_0$, | 7585 $F= (T_1 \ldots T_r, \{T_{r+1}$ $p_{r+1}, \ldots, T_f$ $p_f\}) \longrightarrow T_0$, |
7573 | 7586 |
7574 $G= (S_1 \ldots S_r, \{ S_{r+1}$ $q_{r+1}, \ldots, S_g$ $q_g\}) \longrightarrow S_0$ | 7587 $G= (S_1 \ldots S_r, \{ S_{r+1}$ $q_{r+1}, \ldots, S_g$ $q_g\}) \longrightarrow S_0$ |
7575 | 7588 |
7576 then let $\{x_m, \ldots x_n\} = \{p_{r+1}, \ldots, p_f\} \cap \{q_{r+1}, \ldots , q_g\}$ and let $X_j$ be the least upper bound of the types of $x_j$ in $F$ and $G, j \in m..n$. Then | 7589 then let $\{x_m, \ldots x_n\} = \{p_{r+1}, \ldots, p_f\} \cap \{q_{r+1}, \ldots , q_g\}$ and let $X_j$ be the least upper bound of the types of $x_j$ in $F$ and $G, j \in m..n$. Then |
7577 the least upper bound of $F$ and $G$ is | 7590 the least upper bound of $F$ and $G$ is |
7578 | 7591 |
7579 $(L_1 \ldots L_r, \{ X_m$ $x_m, \ldots, X_n$ $x_n\}) \longrightarrow L_0$ | 7592 $(L_1 \ldots L_r, \{ X_m$ $x_m, \ldots, X_n$ $x_n\}) \longrightarrow L_0$ |
7580 | 7593 |
7581 where $L_i$ is the least upper bound of $T_i$ and $S_i, i \in 0..r$ | 7594 where $L_i$ is the least upper bound of $T_i$ and $S_i, i \in 0..r$ |
7582 \end{itemize} | 7595 \end{itemize} |
7583 | 7596 |
7584 | 7597 |
7585 \section{Reference} | 7598 \section{Reference} |
7586 \LMLabel{reference} | 7599 \LMLabel{reference} |
7587 | 7600 |
7588 \subsection{Lexical Rules} | 7601 \subsection{Lexical Rules} |
7589 \LMLabel{lexicalRules} | 7602 \LMLabel{lexicalRules} |
7590 | 7603 |
7591 \LMHash{} | 7604 \LMHash{} |
7592 Dart source text is represented as a sequence of Unicode code points. This sequ ence is first converted into a sequence of tokens according to the lexical rules given in this specification. At any point in the tokenization process, the lon gest possible token is recognized. | 7605 Dart source text is represented as a sequence of Unicode code points. This sequ ence is first converted into a sequence of tokens according to the lexical rules given in this specification. At any point in the tokenization process, the lon gest possible token is recognized. |
7593 | 7606 |
7594 \subsubsection{Reserved Words} | 7607 \subsubsection{Reserved Words} |
7595 \LMLabel{reservedWords} | 7608 \LMLabel{reservedWords} |
7596 | 7609 |
7597 \LMHash{} | 7610 \LMHash{} |
7598 A {\em reserved word} may not be used as an identifier; it is a compile-time err or if a reserved word is used where an identifier is expected. | 7611 A {\em reserved word} may not be used as an identifier; it is a compile-time err or if a reserved word is used where an identifier is expected. |
7599 | 7612 |
7600 \ASSERT{}, \BREAK{}, \CASE{}, \CATCH{}, \CLASS{}, \CONST{}, \CONTINUE{}, \DEFAUL T{}, \DO{}, \ELSE{}, \ENUM{}, \EXTENDS{}, \FALSE{}, \FINAL{}, \FINALLY{}, \FOR{} , \IF{}, \IN{}, \IS{}, \NEW{}, \NULL{}, \RETHROW, \RETURN{}, \SUPER{}, \SWITCH{} , \THIS{}, \THROW{}, \TRUE{}, \TRY{}, \VAR{}, \VOID{}, \WHILE{}, \WITH{}. | 7613 \ASSERT{}, \BREAK{}, \CASE{}, \CATCH{}, \CLASS{}, \CONST{}, \CONTINUE{}, \DEFAUL T{}, \DO{}, \ELSE{}, \ENUM{}, \EXTENDS{}, \FALSE{}, \FINAL{}, \FINALLY{}, \FOR{} , \IF{}, \IN{}, \IS{}, \NEW{}, \NULL{}, \RETHROW, \RETURN{}, \SUPER{}, \SWITCH{} , \THIS{}, \THROW{}, \TRUE{}, \TRY{}, \VAR{}, \VOID{}, \WHILE{}, \WITH{}. |
7601 | 7614 |
7602 | 7615 |
7603 | 7616 |
7604 %\Q{Unicode characters.} | 7617 %\Q{Unicode characters.} |
(...skipping 19 matching lines...) Expand all Loading... | |
7624 {\em Comments} are sections of program text that are used for documentation. | 7637 {\em Comments} are sections of program text that are used for documentation. |
7625 | 7638 |
7626 \begin{grammar}{\bf SINGLE\_LINE\_COMMENT:} | 7639 \begin{grammar}{\bf SINGLE\_LINE\_COMMENT:} |
7627 `//' \~{}(NEWLINE)* (NEWLINE)? | 7640 `//' \~{}(NEWLINE)* (NEWLINE)? |
7628 . | 7641 . |
7629 | 7642 |
7630 {\bf MULTI\_LINE\_COMMENT:} | 7643 {\bf MULTI\_LINE\_COMMENT:} |
7631 `/*' (MULTI\_LINE\_COMMENT $|$ \~{} `*/')* `*/' | 7644 `/*' (MULTI\_LINE\_COMMENT $|$ \~{} `*/')* `*/' |
7632 . | 7645 . |
7633 \end{grammar} | 7646 \end{grammar} |
7634 | |
7635 \LMHash{} | |
7636 Dart supports both single-line and multi-line comments. A {\em single line comme nt} begins with the token \code{//}. Everything between \code{//} and the end of line must be ignored by the Dart compiler unless the comment is a documentation comment. . | |
7637 | 7647 |
7638 \LMHash{} | 7648 \LMHash{} |
7639 A {\em multi-line comment} begins with the token \code{/*} and ends with the tok en \code{*/}. Everything between \code{/}* and \code{*}/ must be ignored by the Dart compiler unless the comment is a documentation comment. Comments may nest. | 7649 Dart supports both single-line and multi-line comments. A {\em single line comme nt} begins with the token \code{//}. Everything between \code{//} and the end of line must be ignored by the Dart compiler unless the comment is a documentation comment. . |
7640 | 7650 |
7641 \LMHash{} | 7651 \LMHash{} |
7642 {\em Documentation comments} are comments that begin with the tokens \code{///} or \code{/**}. Documentation comments are intended to be processed by a tool t hat produces human readable documentation. | 7652 A {\em multi-line comment} begins with the token \code{/*} and ends with the tok en \code{*/}. Everything between \code{/}* and \code{*}/ must be ignored by the Dart compiler unless the comment is a documentation comment. Comments may nest. |
7653 | |
7654 \LMHash{} | |
7655 {\em Documentation comments} are comments that begin with the tokens \code{///} or \code{/**}. Documentation comments are intended to be processed by a tool t hat produces human readable documentation. | |
7643 | 7656 |
7644 | 7657 |
7645 \LMHash{} | 7658 \LMHash{} |
7646 The scope of a documentation comment immediately preceding the declaration of a class $C$ is the instance scope of $C$. | 7659 The scope of a documentation comment immediately preceding the declaration of a class $C$ is the instance scope of $C$. |
7647 | 7660 |
7648 \LMHash{} | 7661 \LMHash{} |
7649 The scope of a documentation comment immediately preceding the declaration of a function $f$ is the scope in force at the very beginning of the body of $f$. | 7662 The scope of a documentation comment immediately preceding the declaration of a function $f$ is the scope in force at the very beginning of the body of $f$. |
7650 | 7663 |
7651 | 7664 |
7652 | 7665 |
7653 | 7666 |
7654 | 7667 |
7655 %\subsection{Grammar} | 7668 %\subsection{Grammar} |
7656 %\LMLabel{grammar} | 7669 %\LMLabel{grammar} |
7657 \subsection{Operator Precedence} | 7670 \subsection{Operator Precedence} |
7658 \LMLabel{operatorPrecedence} | 7671 \LMLabel{operatorPrecedence} |
7659 | 7672 |
7660 \LMHash{} | 7673 \LMHash{} |
7661 Operator precedence is given implicitly by the grammar. | 7674 Operator precedence is given implicitly by the grammar. |
7662 | 7675 |
7663 \commentary{The following non-normative table may be helpful | 7676 \commentary{The following non-normative table may be helpful |
7664 \newline | 7677 \newline |
7665 | 7678 |
7666 \begin{tabular}{| r | r | r | r |} | 7679 \begin{tabular}{| r | r | r | r |} |
7667 \hline | 7680 \hline |
7668 Description & Operator & Associativity & Precedence \\ | 7681 Description & Operator & Associativity & Precedence \\ |
7669 \hline | 7682 \hline |
7670 Unary postfix & ., ?., e++, e--, e1[e2], e1() , () & None & 16 \\ | 7683 Unary postfix & ., ?., e++, e--, e1[e2], e1() , () & None & 16 \\ |
7671 \hline | 7684 \hline |
7672 Unary prefix & -e, !e, \~{}e, ++e, --e & None & 15\\ | 7685 Unary prefix & -e, !e, \~{}e, ++e, --e & None & 15\\ |
7673 \hline | 7686 \hline |
7674 Multiplicative & *, /, \~/, \% & Left & 14\\ | 7687 Multiplicative & *, /, \~/, \% & Left & 14\\ |
7675 \hline | 7688 \hline |
7676 Additive & +, - & Left & 13\\ | 7689 Additive & +, - & Left & 13\\ |
7677 \hline | 7690 \hline |
7678 Shift & $<<$, $>>$& Left & 12\\ | 7691 Shift & $<<$, $>>$& Left & 12\\ |
7679 \hline | 7692 \hline |
7680 Bitwise AND & \& & Left & 11\\ | 7693 Bitwise AND & \& & Left & 11\\ |
7681 \hline | 7694 \hline |
7682 Bitwise XOR & \^{} & Left & 10\\ | 7695 Bitwise XOR & \^{} & Left & 10\\ |
7683 \hline | 7696 \hline |
7684 Bitwise Or & $|$ & Left & 9\\ | 7697 Bitwise Or & $|$ & Left & 9\\ |
7685 \hline | 7698 \hline |
7686 Relational & $<$, $>$, $<=$, $>=$, \AS{}, \IS{}, \IS{}! & None & 8\\ | 7699 Relational & $<$, $>$, $<=$, $>=$, \AS{}, \IS{}, \IS{}! & None & 8\\ |
7687 \hline | 7700 \hline |
(...skipping 15 matching lines...) Expand all Loading... | |
7703 } | 7716 } |
7704 %\subsection{Glossary} | 7717 %\subsection{Glossary} |
7705 %\LMLabel{glossary} | 7718 %\LMLabel{glossary} |
7706 | 7719 |
7707 %\bibliographystyle{alpha} | 7720 %\bibliographystyle{alpha} |
7708 %\bibliography{/users/gilad/research/bibs/master} | 7721 %\bibliography{/users/gilad/research/bibs/master} |
7709 \section*{Appendix: Naming Conventions} | 7722 \section*{Appendix: Naming Conventions} |
7710 \LMLabel{namingConventions} | 7723 \LMLabel{namingConventions} |
7711 | 7724 |
7712 \commentary{ | 7725 \commentary{ |
7713 The following naming conventions are customary in Dart programs. | 7726 The following naming conventions are customary in Dart programs. |
7714 \begin{itemize} | 7727 \begin{itemize} |
7715 \item The names of compile time constant variables never use lower case letters. If they consist of multiple words, those words are separated by underscores. Ex amples: PI, I\_AM\_A\_CONSTANT. | 7728 \item The names of compile time constant variables never use lower case letters. If they consist of multiple words, those words are separated by underscores. Ex amples: PI, I\_AM\_A\_CONSTANT. |
7716 \item The names of functions (including getters, setters, methods and local or l ibrary functions) and non-constant variables begin with a lowercase letter. If t he name consists of multiple words, each word (except the first) begins with an uppercase letter. No other uppercase letters are used. Examples: camlCase, dar t4TheWorld | 7729 \item The names of functions (including getters, setters, methods and local or l ibrary functions) and non-constant variables begin with a lowercase letter. If t he name consists of multiple words, each word (except the first) begins with an uppercase letter. No other uppercase letters are used. Examples: camlCase, dar t4TheWorld |
7717 \item The names of types (including classes and type aliases) begin with an uppe r case letter. If the name consists of multiple words, each word begins with an uppercase letter. No other uppercase letters are used. Examples: CamlCase, D art4TheWorld. | 7730 \item The names of types (including classes and type aliases) begin with an uppe r case letter. If the name consists of multiple words, each word begins with an uppercase letter. No other uppercase letters are used. Examples: CamlCase, D art4TheWorld. |
7718 \item The names of type variables are short (preferably single letter). Examples : T, S, K, V , E. | 7731 \item The names of type variables are short (preferably single letter). Examples : T, S, K, V , E. |
7719 \item The names of libraries or library prefixes never use upper case letters. I f they consist of multiple words, those words are separated by underscores. Exam ple: my\_favorite\_library. | 7732 \item The names of libraries or library prefixes never use upper case letters. I f they consist of multiple words, those words are separated by underscores. Exam ple: my\_favorite\_library. |
7720 \end{itemize} | 7733 \end{itemize} |
7721 } | 7734 } |
7722 | 7735 |
7723 | 7736 |
(...skipping 144 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
7868 | 7881 |
7869 The invariant that each normative paragraph is associated with a line | 7882 The invariant that each normative paragraph is associated with a line |
7870 containing the text \LMHash{} should be maintained. Extra occurrences | 7883 containing the text \LMHash{} should be maintained. Extra occurrences |
7871 of \LMHash{} can be added if needed, e.g., in order to make | 7884 of \LMHash{} can be added if needed, e.g., in order to make |
7872 individual \item{}s in itemized lists addressable. Each \LM.. command | 7885 individual \item{}s in itemized lists addressable. Each \LM.. command |
7873 must occur on a separate line. \LMHash{} must occur immediately | 7886 must occur on a separate line. \LMHash{} must occur immediately |
7874 before the associated paragraph, and \LMLabel must occur immediately | 7887 before the associated paragraph, and \LMLabel must occur immediately |
7875 after the associated \section{}, \subsection{} etc. | 7888 after the associated \section{}, \subsection{} etc. |
7876 | 7889 |
7877 ---------------------------------------------------------------------- | 7890 ---------------------------------------------------------------------- |
OLD | NEW |