OLD | NEW |
1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file |
2 // for details. All rights reserved. Use of this source code is governed by a | 2 // for details. All rights reserved. Use of this source code is governed by a |
3 // BSD-style license that can be found in the LICENSE file. | 3 // BSD-style license that can be found in the LICENSE file. |
4 | 4 |
5 /** | 5 /** |
6 * An event generating parser of Dart programs. This parser expects | 6 * An event generating parser of Dart programs. This parser expects |
7 * all tokens in a linked list (aka a token stream). | 7 * all tokens in a linked list (aka a token stream). |
8 * | 8 * |
9 * The class [Scanner] is used to generate a token stream. See the | 9 * The class [Scanner] is used to generate a token stream. See the |
10 * file scanner.dart. | 10 * file scanner.dart. |
(...skipping 124 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
135 listener.beginFormalParameters(begin); | 135 listener.beginFormalParameters(begin); |
136 expect('(', token); | 136 expect('(', token); |
137 int parameterCount = 0; | 137 int parameterCount = 0; |
138 if (optional(')', token.next)) { | 138 if (optional(')', token.next)) { |
139 listener.endFormalParameters(parameterCount, begin, token.next); | 139 listener.endFormalParameters(parameterCount, begin, token.next); |
140 return token.next.next; | 140 return token.next.next; |
141 } | 141 } |
142 do { | 142 do { |
143 ++parameterCount; | 143 ++parameterCount; |
144 token = token.next; | 144 token = token.next; |
145 if (optional('[', token)) { | 145 String value = token.stringValue; |
146 token = parseOptionalFormalParameters(token); | 146 if (value === '[') { |
| 147 token = parseOptionalFormalParameters(token, false); |
| 148 break; |
| 149 } else if (value === '{') { |
| 150 token = parseOptionalFormalParameters(token, true); |
147 break; | 151 break; |
148 } | 152 } |
149 token = parseFormalParameter(token); | 153 token = parseFormalParameter(token); |
150 } while (optional(',', token)); | 154 } while (optional(',', token)); |
151 listener.endFormalParameters(parameterCount, begin, token); | 155 listener.endFormalParameters(parameterCount, begin, token); |
152 return expect(')', token); | 156 return expect(')', token); |
153 } | 157 } |
154 | 158 |
155 Token parseFormalParameter(Token token) { | 159 Token parseFormalParameter(Token token) { |
156 listener.beginFormalParameter(token); | 160 listener.beginFormalParameter(token); |
157 token = parseModifiers(token); | 161 token = parseModifiers(token); |
158 // TODO(ahe): Validate that there are formal parameters if void. | 162 // TODO(ahe): Validate that there are formal parameters if void. |
159 token = parseReturnTypeOpt(token); | 163 token = parseReturnTypeOpt(token); |
160 Token thisKeyword = null; | 164 Token thisKeyword = null; |
161 if (optional('this', token)) { | 165 if (optional('this', token)) { |
162 thisKeyword = token; | 166 thisKeyword = token; |
163 // TODO(ahe): Validate field initializers are only used in | 167 // TODO(ahe): Validate field initializers are only used in |
164 // constructors, and not for function-typed arguments. | 168 // constructors, and not for function-typed arguments. |
165 token = expect('.', token.next); | 169 token = expect('.', token.next); |
166 } | 170 } |
167 token = parseIdentifier(token); | 171 token = parseIdentifier(token); |
168 if (optional('(', token)) { | 172 if (optional('(', token)) { |
169 token = parseFormalParameters(token); | 173 token = parseFormalParameters(token); |
170 listener.handleFunctionTypedFormalParameter(token); | 174 listener.handleFunctionTypedFormalParameter(token); |
171 } | 175 } |
172 if (optional('=', token)) { | 176 String value = token.stringValue; |
| 177 if (('=' === value) || (':' === value)) { |
173 // TODO(ahe): Validate that these are only used for optional parameters. | 178 // TODO(ahe): Validate that these are only used for optional parameters. |
174 Token equal = token; | 179 Token equal = token; |
175 token = parseExpression(token.next); | 180 token = parseExpression(token.next); |
176 listener.handleValuedFormalParameter(equal, token); | 181 listener.handleValuedFormalParameter(equal, token); |
177 } | 182 } |
178 listener.endFormalParameter(token, thisKeyword); | 183 listener.endFormalParameter(token, thisKeyword); |
179 return token; | 184 return token; |
180 } | 185 } |
181 | 186 |
182 Token parseOptionalFormalParameters(Token token) { | 187 Token parseOptionalFormalParameters(Token token, bool isNamed) { |
183 Token begin = token; | 188 Token begin = token; |
184 listener.beginOptionalFormalParameters(begin); | 189 listener.beginOptionalFormalParameters(begin); |
185 assert(optional('[', token)); | 190 assert((isNamed && optional('{', token)) || optional('[', token)); |
186 int parameterCount = 0; | 191 int parameterCount = 0; |
187 do { | 192 do { |
188 token = token.next; | 193 token = token.next; |
189 token = parseFormalParameter(token); | 194 token = parseFormalParameter(token); |
190 ++parameterCount; | 195 ++parameterCount; |
191 } while (optional(',', token)); | 196 } while (optional(',', token)); |
192 listener.endOptionalFormalParameters(parameterCount, begin, token); | 197 listener.endOptionalFormalParameters(parameterCount, begin, token); |
193 return expect(']', token); | 198 if (isNamed) { |
| 199 return expect('}', token); |
| 200 } else { |
| 201 return expect(']', token); |
| 202 } |
194 } | 203 } |
195 | 204 |
196 Token parseTypeOpt(Token token) { | 205 Token parseTypeOpt(Token token) { |
197 String value = token.stringValue; | 206 String value = token.stringValue; |
198 if (value === 'var') return parseType(token); | 207 if (value === 'var') return parseType(token); |
199 if (value !== 'this') { | 208 if (value !== 'this') { |
200 Token peek = peekAfterExpectedType(token); | 209 Token peek = peekAfterExpectedType(token); |
201 if (isIdentifier(peek) || optional('this', peek)) { | 210 if (isIdentifier(peek) || optional('this', peek)) { |
202 return parseType(token); | 211 return parseType(token); |
203 } | 212 } |
(...skipping 1642 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1846 } | 1855 } |
1847 listener.handleContinueStatement(hasTarget, continueKeyword, token); | 1856 listener.handleContinueStatement(hasTarget, continueKeyword, token); |
1848 return expectSemicolon(token); | 1857 return expectSemicolon(token); |
1849 } | 1858 } |
1850 | 1859 |
1851 Token parseEmptyStatement(Token token) { | 1860 Token parseEmptyStatement(Token token) { |
1852 listener.handleEmptyStatement(token); | 1861 listener.handleEmptyStatement(token); |
1853 return expectSemicolon(token); | 1862 return expectSemicolon(token); |
1854 } | 1863 } |
1855 } | 1864 } |
OLD | NEW |