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

Side by Side Diff: runtime/vm/parser.cc

Issue 10905109: Add named constructor name checking (Closed) Base URL: http://dart.googlecode.com/svn/branches/bleeding_edge/dart/
Patch Set: Created 8 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
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 #include "vm/parser.h" 5 #include "vm/parser.h"
6 6
7 #include "vm/bigint_operations.h" 7 #include "vm/bigint_operations.h"
8 #include "vm/class_finalizer.h" 8 #include "vm/class_finalizer.h"
9 #include "vm/compiler.h" 9 #include "vm/compiler.h"
10 #include "vm/compiler_stats.h" 10 #include "vm/compiler_stats.h"
11 #include "vm/dart_api_impl.h" 11 #include "vm/dart_api_impl.h"
12 #include "vm/dart_entry.h" 12 #include "vm/dart_entry.h"
13 #include "vm/flags.h" 13 #include "vm/flags.h"
14 #include "vm/growable_array.h" 14 #include "vm/growable_array.h"
15 #include "vm/longjump.h" 15 #include "vm/longjump.h"
16 #include "vm/native_entry.h" 16 #include "vm/native_entry.h"
17 #include "vm/object.h" 17 #include "vm/object.h"
18 #include "vm/object_store.h" 18 #include "vm/object_store.h"
19 #include "vm/resolver.h" 19 #include "vm/resolver.h"
20 #include "vm/scopes.h" 20 #include "vm/scopes.h"
21 #include "vm/symbols.h" 21 #include "vm/symbols.h"
22 22
23 namespace dart { 23 namespace dart {
24 24
25 DEFINE_FLAG(bool, constructor_name_check, false,
26 "Named constructors may not clash with other members");
25 DEFINE_FLAG(bool, enable_asserts, false, "Enable assert statements."); 27 DEFINE_FLAG(bool, enable_asserts, false, "Enable assert statements.");
26 DEFINE_FLAG(bool, enable_type_checks, false, "Enable type checks."); 28 DEFINE_FLAG(bool, enable_type_checks, false, "Enable type checks.");
27 DEFINE_FLAG(bool, trace_parser, false, "Trace parser operations."); 29 DEFINE_FLAG(bool, trace_parser, false, "Trace parser operations.");
28 DEFINE_FLAG(bool, warning_as_error, false, "Treat warnings as errors."); 30 DEFINE_FLAG(bool, warning_as_error, false, "Treat warnings as errors.");
29 DEFINE_FLAG(bool, silent_warnings, false, "Silence warnings."); 31 DEFINE_FLAG(bool, silent_warnings, false, "Silence warnings.");
30 DEFINE_FLAG(bool, warn_legacy_map_literal, false, 32 DEFINE_FLAG(bool, warn_legacy_map_literal, false,
31 "Warning on legacy map literal syntax (single type argument)"); 33 "Warning on legacy map literal syntax (single type argument)");
32 34
33 static void CheckedModeHandler(bool value) { 35 static void CheckedModeHandler(bool value) {
34 FLAG_enable_asserts = value; 36 FLAG_enable_asserts = value;
(...skipping 438 matching lines...) Expand 10 before | Expand all | Expand 10 after
473 has_final = false; 475 has_final = false;
474 has_const = false; 476 has_const = false;
475 has_static = false; 477 has_static = false;
476 has_var = false; 478 has_var = false;
477 has_factory = false; 479 has_factory = false;
478 has_operator = false; 480 has_operator = false;
479 type = NULL; 481 type = NULL;
480 name_pos = 0; 482 name_pos = 0;
481 name = NULL; 483 name = NULL;
482 redirect_name = NULL; 484 redirect_name = NULL;
485 constructor_name = NULL;
483 params.Clear(); 486 params.Clear();
484 kind = RawFunction::kRegularFunction; 487 kind = RawFunction::kRegularFunction;
485 } 488 }
486 bool IsConstructor() const { 489 bool IsConstructor() const {
487 return (kind == RawFunction::kConstructor) && !has_static; 490 return (kind == RawFunction::kConstructor) && !has_static;
488 } 491 }
489 bool IsFactory() const { 492 bool IsFactory() const {
490 return (kind == RawFunction::kConstructor) && has_static; 493 return (kind == RawFunction::kConstructor) && has_static;
491 } 494 }
492 bool IsFactoryOrConstructor() const { 495 bool IsFactoryOrConstructor() const {
493 return (kind == RawFunction::kConstructor); 496 return (kind == RawFunction::kConstructor);
494 } 497 }
495 bool IsGetter() const { 498 bool IsGetter() const {
496 return kind == RawFunction::kGetterFunction; 499 return kind == RawFunction::kGetterFunction;
497 } 500 }
498 bool IsSetter() const { 501 bool IsSetter() const {
499 return kind == RawFunction::kSetterFunction; 502 return kind == RawFunction::kSetterFunction;
500 } 503 }
501 bool has_abstract; 504 bool has_abstract;
502 bool has_external; 505 bool has_external;
503 bool has_final; 506 bool has_final;
504 bool has_const; 507 bool has_const;
505 bool has_static; 508 bool has_static;
506 bool has_var; 509 bool has_var;
507 bool has_factory; 510 bool has_factory;
508 bool has_operator; 511 bool has_operator;
509 const AbstractType* type; 512 const AbstractType* type;
510 intptr_t name_pos; 513 intptr_t name_pos;
511 String* name; 514 String* name;
512 String* redirect_name; // For constructors: NULL or redirected constructor. 515 // For constructors: NULL or redirected constructor.
516 String* redirect_name;
517 // For constructors: NULL for unnamed constructor,
518 // identifier after classname for named constructors.
519 String* constructor_name;
513 ParamList params; 520 ParamList params;
514 RawFunction::Kind kind; 521 RawFunction::Kind kind;
515 }; 522 };
516 523
517 524
518 class ClassDesc : public ValueObject { 525 class ClassDesc : public ValueObject {
519 public: 526 public:
520 ClassDesc(const Class& cls, 527 ClassDesc(const Class& cls,
521 const String& cls_name, 528 const String& cls_name,
522 bool is_interface, 529 bool is_interface,
(...skipping 1869 matching lines...) Expand 10 before | Expand all | Expand 10 after
2392 (method->params.num_fixed_parameters == 1)) { 2399 (method->params.num_fixed_parameters == 1)) {
2393 // Patch up name for unary operator - so it does not clash with the 2400 // Patch up name for unary operator - so it does not clash with the
2394 // name for binary operator -. 2401 // name for binary operator -.
2395 *method->name = Symbols::New("unary-"); 2402 *method->name = Symbols::New("unary-");
2396 } 2403 }
2397 2404
2398 if (members->FunctionNameExists(*method->name, method->kind)) { 2405 if (members->FunctionNameExists(*method->name, method->kind)) {
2399 ErrorMsg(method->name_pos, 2406 ErrorMsg(method->name_pos,
2400 "field or method '%s' already defined", method->name->ToCString()); 2407 "field or method '%s' already defined", method->name->ToCString());
2401 } 2408 }
2409 if (FLAG_constructor_name_check && method->constructor_name != NULL) {
2410 if (members->FunctionNameExists(*method->constructor_name, method->kind)) {
2411 ErrorMsg(method->name_pos,
2412 "Named constructor '%s' conflicts with method or field '%s'",
2413 method->name->ToCString(),
2414 method->constructor_name->ToCString());
2415 }
2416 }
siva 2012/09/06 16:52:10 As discussed offline how do we report errors for t
hausner 2012/09/06 18:02:13 Correct. We really should have a simpler way to re
2402 2417
2403 // Mangle the name for getter and setter functions and check function 2418 // Mangle the name for getter and setter functions and check function
2404 // arity. 2419 // arity.
2405 if (method->IsGetter() || method->IsSetter()) { 2420 if (method->IsGetter() || method->IsSetter()) {
2406 int expected_num_parameters = 0; 2421 int expected_num_parameters = 0;
2407 if (method->IsGetter()) { 2422 if (method->IsGetter()) {
2408 expected_num_parameters = (method->has_static) ? 0 : 1; 2423 expected_num_parameters = (method->has_static) ? 0 : 1;
2409 method->name = &String::ZoneHandle(Field::GetterSymbol(*method->name)); 2424 method->name = &String::ZoneHandle(Field::GetterSymbol(*method->name));
2410 } else { 2425 } else {
2411 ASSERT(method->IsSetter()); 2426 ASSERT(method->IsSetter());
(...skipping 446 matching lines...) Expand 10 before | Expand all | Expand 10 after
2858 member.name_pos = TokenPos(); 2873 member.name_pos = TokenPos();
2859 member.name = CurrentLiteral(); 2874 member.name = CurrentLiteral();
2860 ConsumeToken(); 2875 ConsumeToken();
2861 } 2876 }
2862 // We must be dealing with a constructor or named constructor. 2877 // We must be dealing with a constructor or named constructor.
2863 member.kind = RawFunction::kConstructor; 2878 member.kind = RawFunction::kConstructor;
2864 String& ctor_suffix = String::ZoneHandle(Symbols::Dot()); 2879 String& ctor_suffix = String::ZoneHandle(Symbols::Dot());
2865 if (CurrentToken() == Token::kPERIOD) { 2880 if (CurrentToken() == Token::kPERIOD) {
2866 // Named constructor. 2881 // Named constructor.
2867 ConsumeToken(); 2882 ConsumeToken();
2868 const String* name = ExpectIdentifier("identifier expected"); 2883 member.constructor_name = ExpectIdentifier("identifier expected");
2869 ctor_suffix = String::Concat(ctor_suffix, *name); 2884 ctor_suffix = String::Concat(ctor_suffix, *member.constructor_name);
2870 } 2885 }
2871 *member.name = String::Concat(*member.name, ctor_suffix); 2886 *member.name = String::Concat(*member.name, ctor_suffix);
2872 // Ensure that names are symbols. 2887 // Ensure that names are symbols.
2873 *member.name = Symbols::New(*member.name); 2888 *member.name = Symbols::New(*member.name);
2874 if (member.type == NULL) { 2889 if (member.type == NULL) {
2875 ASSERT(!member.has_factory); 2890 ASSERT(!member.has_factory);
2876 // The body of the constructor cannot modify the type arguments of the 2891 // The body of the constructor cannot modify the type arguments of the
2877 // constructed instance, which is passed in as a hidden parameter. 2892 // constructed instance, which is passed in as a hidden parameter.
2878 // Therefore, there is no need to set the result type to be checked. 2893 // Therefore, there is no need to set the result type to be checked.
2879 member.type = &Type::ZoneHandle(Type::DynamicType()); 2894 member.type = &Type::ZoneHandle(Type::DynamicType());
(...skipping 6505 matching lines...) Expand 10 before | Expand all | Expand 10 after
9385 void Parser::SkipQualIdent() { 9400 void Parser::SkipQualIdent() {
9386 ASSERT(IsIdentifier()); 9401 ASSERT(IsIdentifier());
9387 ConsumeToken(); 9402 ConsumeToken();
9388 if (CurrentToken() == Token::kPERIOD) { 9403 if (CurrentToken() == Token::kPERIOD) {
9389 ConsumeToken(); // Consume the kPERIOD token. 9404 ConsumeToken(); // Consume the kPERIOD token.
9390 ExpectIdentifier("identifier expected after '.'"); 9405 ExpectIdentifier("identifier expected after '.'");
9391 } 9406 }
9392 } 9407 }
9393 9408
9394 } // namespace dart 9409 } // namespace dart
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698