Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(129)

Side by Side Diff: sdk/lib/_internal/compiler/implementation/scanner/parser.dart

Issue 23456030: Emit compile-time error for incorrectly used optional parameters. (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Address Kathy's comments. Created 7 years, 3 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « no previous file | sdk/lib/_internal/compiler/implementation/warnings.dart » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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 part of scanner; 5 part of scanner;
6 6
7 class FormalParameterType {
8 final String type;
9 const FormalParameterType(this.type);
10 bool get isRequired => this == REQUIRED;
11 bool get isPositional => this == POSITIONAL;
12 bool get isNamed => this == NAMED;
13 static final REQUIRED = const FormalParameterType('required');
14 static final POSITIONAL = const FormalParameterType('positional');
15 static final NAMED = const FormalParameterType('named');
16 }
17
7 /** 18 /**
8 * An event generating parser of Dart programs. This parser expects 19 * An event generating parser of Dart programs. This parser expects
9 * all tokens in a linked list (aka a token stream). 20 * all tokens in a linked list (aka a token stream).
10 * 21 *
11 * The class [Scanner] is used to generate a token stream. See the 22 * The class [Scanner] is used to generate a token stream. See the
12 * file scanner.dart. 23 * file scanner.dart.
13 * 24 *
14 * Subclasses of the class [Listener] are used to listen to events. 25 * Subclasses of the class [Listener] are used to listen to events.
15 * 26 *
16 * Most methods of this class belong in one of two major categories: 27 * Most methods of this class belong in one of two major categories:
(...skipping 282 matching lines...) Expand 10 before | Expand all | Expand 10 after
299 ++parameterCount; 310 ++parameterCount;
300 token = token.next; 311 token = token.next;
301 String value = token.stringValue; 312 String value = token.stringValue;
302 if (identical(value, '[')) { 313 if (identical(value, '[')) {
303 token = parseOptionalFormalParameters(token, false); 314 token = parseOptionalFormalParameters(token, false);
304 break; 315 break;
305 } else if (identical(value, '{')) { 316 } else if (identical(value, '{')) {
306 token = parseOptionalFormalParameters(token, true); 317 token = parseOptionalFormalParameters(token, true);
307 break; 318 break;
308 } 319 }
309 token = parseFormalParameter(token); 320 token = parseFormalParameter(token, FormalParameterType.REQUIRED);
310 } while (optional(',', token)); 321 } while (optional(',', token));
311 listener.endFormalParameters(parameterCount, begin, token); 322 listener.endFormalParameters(parameterCount, begin, token);
312 return expect(')', token); 323 return expect(')', token);
313 } 324 }
314 325
315 Token parseFormalParameter(Token token) { 326 Token parseFormalParameter(Token token, FormalParameterType type) {
316 listener.beginFormalParameter(token); 327 listener.beginFormalParameter(token);
317 token = parseModifiers(token); 328 token = parseModifiers(token);
318 // TODO(ahe): Validate that there are formal parameters if void. 329 // TODO(ahe): Validate that there are formal parameters if void.
319 token = parseReturnTypeOpt(token); 330 token = parseReturnTypeOpt(token);
320 Token thisKeyword = null; 331 Token thisKeyword = null;
321 if (optional('this', token)) { 332 if (optional('this', token)) {
322 thisKeyword = token; 333 thisKeyword = token;
323 // TODO(ahe): Validate field initializers are only used in 334 // TODO(ahe): Validate field initializers are only used in
324 // constructors, and not for function-typed arguments. 335 // constructors, and not for function-typed arguments.
325 token = expect('.', token.next); 336 token = expect('.', token.next);
326 } 337 }
327 token = parseIdentifier(token); 338 token = parseIdentifier(token);
328 if (optional('(', token)) { 339 if (optional('(', token)) {
329 token = parseFormalParameters(token); 340 token = parseFormalParameters(token);
330 listener.handleFunctionTypedFormalParameter(token); 341 listener.handleFunctionTypedFormalParameter(token);
331 } 342 }
332 String value = token.stringValue; 343 String value = token.stringValue;
333 if ((identical('=', value)) || (identical(':', value))) { 344 if ((identical('=', value)) || (identical(':', value))) {
334 // TODO(ahe): Validate that these are only used for optional parameters. 345 // TODO(ahe): Validate that these are only used for optional parameters.
335 Token equal = token; 346 Token equal = token;
336 token = parseExpression(token.next); 347 token = parseExpression(token.next);
337 listener.handleValuedFormalParameter(equal, token); 348 listener.handleValuedFormalParameter(equal, token);
349 if (type.isRequired) {
350 listener.reportError(equal,
351 MessageKind.REQUIRED_PARAMETER_WITH_DEFAULT);
352 } else if (type.isNamed && identical('=', value)) {
353 listener.reportError(equal, MessageKind.NAMED_PARAMETER_WITH_EQUALS);
354 } else if (type.isPositional && identical(':', value)) {
355 listener.reportError(equal,
356 MessageKind.POSITIONAL_PARAMETER_WITH_EQUALS);
357 }
338 } 358 }
339 listener.endFormalParameter(thisKeyword); 359 listener.endFormalParameter(thisKeyword);
340 return token; 360 return token;
341 } 361 }
342 362
343 Token parseOptionalFormalParameters(Token token, bool isNamed) { 363 Token parseOptionalFormalParameters(Token token, bool isNamed) {
344 Token begin = token; 364 Token begin = token;
345 listener.beginOptionalFormalParameters(begin); 365 listener.beginOptionalFormalParameters(begin);
346 assert((isNamed && optional('{', token)) || optional('[', token)); 366 assert((isNamed && optional('{', token)) || optional('[', token));
347 int parameterCount = 0; 367 int parameterCount = 0;
348 do { 368 do {
349 token = token.next; 369 token = token.next;
350 token = parseFormalParameter(token); 370 var type = isNamed ? FormalParameterType.NAMED
371 : FormalParameterType.POSITIONAL;
372 token = parseFormalParameter(token, type);
351 ++parameterCount; 373 ++parameterCount;
352 } while (optional(',', token)); 374 } while (optional(',', token));
353 listener.endOptionalFormalParameters(parameterCount, begin, token); 375 listener.endOptionalFormalParameters(parameterCount, begin, token);
354 if (isNamed) { 376 if (isNamed) {
355 return expect('}', token); 377 return expect('}', token);
356 } else { 378 } else {
357 return expect(']', token); 379 return expect(']', token);
358 } 380 }
359 } 381 }
360 382
(...skipping 2018 matching lines...) Expand 10 before | Expand all | Expand 10 after
2379 } 2401 }
2380 listener.handleContinueStatement(hasTarget, continueKeyword, token); 2402 listener.handleContinueStatement(hasTarget, continueKeyword, token);
2381 return expectSemicolon(token); 2403 return expectSemicolon(token);
2382 } 2404 }
2383 2405
2384 Token parseEmptyStatement(Token token) { 2406 Token parseEmptyStatement(Token token) {
2385 listener.handleEmptyStatement(token); 2407 listener.handleEmptyStatement(token);
2386 return expectSemicolon(token); 2408 return expectSemicolon(token);
2387 } 2409 }
2388 } 2410 }
OLDNEW
« no previous file with comments | « no previous file | sdk/lib/_internal/compiler/implementation/warnings.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698