From 51bb1d4e4ca2e65d8e0fe646e6ef93b44fdaee4e Mon Sep 17 00:00:00 2001 From: "hausner@google.com" Date: Wed, 30 Nov 2011 18:55:37 +0000 Subject: [PATCH] Properly detect name collisions at library level Fixing issue 592 Review URL: http://codereview.chromium.org//8724015 git-svn-id: https://dart.googlecode.com/svn/branches/bleeding_edge/dart@1934 260f80e4-7a28-3924-810f-c04153c831b5 --- runtime/vm/parser.cc | 31 +++++++++++++++++++ .../language/src/ToplevelCollision1Test.dart | 15 +++++++++ .../language/src/ToplevelCollision2Test.dart | 21 +++++++++++++ 3 files changed, 67 insertions(+) create mode 100644 tests/language/src/ToplevelCollision1Test.dart create mode 100644 tests/language/src/ToplevelCollision2Test.dart diff --git a/runtime/vm/parser.cc b/runtime/vm/parser.cc index e91265c053b..1c15da2c8cf 100644 --- a/runtime/vm/parser.cc +++ b/runtime/vm/parser.cc @@ -2940,6 +2940,17 @@ void Parser::ParseTopLevelVariable(TopLevel* top_level) { if (library_.LookupObject(var_name) != Object::null()) { ErrorMsg(name_pos, "'%s' is already defined", var_name.ToCString()); } + String& accessor_name = String::Handle(Field::GetterName(var_name)); + if (library_.LookupObject(accessor_name) != Object::null()) { + ErrorMsg(name_pos, "getter for '%s' is already defined", + var_name.ToCString()); + } + accessor_name = Field::SetterName(var_name); + if (library_.LookupObject(accessor_name) != Object::null()) { + ErrorMsg(name_pos, "setter for '%s' is already defined", + var_name.ToCString()); + } + Field& field = Field::ZoneHandle( Field::New(var_name, is_static, is_final, name_pos)); field.set_type(type); @@ -2992,6 +3003,16 @@ void Parser::ParseTopLevelFunction(TopLevel* top_level) { if (library_.LookupObject(func_name) != Object::null()) { ErrorMsg(name_pos, "'%s' is already defined", func_name.ToCString()); } + String& accessor_name = String::Handle(Field::GetterName(func_name)); + if (library_.LookupObject(accessor_name) != Object::null()) { + ErrorMsg(name_pos, "'%s' is already defined as getter", + func_name.ToCString()); + } + accessor_name = Field::SetterName(func_name); + if (library_.LookupObject(accessor_name) != Object::null()) { + ErrorMsg(name_pos, "'%s' is already defined as setter", + func_name.ToCString()); + } if (CurrentToken() != Token::kLPAREN) { ErrorMsg("'(' expected"); @@ -3069,6 +3090,16 @@ void Parser::ParseTopLevelAccessor(TopLevel* top_level) { is_getter ? "getter" : "setter"); } + if (library_.LookupObject(*field_name) != Object::null()) { + ErrorMsg(name_pos, "'%s' is already defined in this library", + field_name->ToCString()); + } + if (library_.LookupObject(accessor_name) != Object::null()) { + ErrorMsg(name_pos, "%s for '%s' is already defined", + is_getter ? "getter" : "setter", + field_name->ToCString()); + } + if (CurrentToken() == Token::kLBRACE) { SkipBlock(); } else if (CurrentToken() == Token::kARROW) { diff --git a/tests/language/src/ToplevelCollision1Test.dart b/tests/language/src/ToplevelCollision1Test.dart new file mode 100644 index 00000000000..e71acebf89f --- /dev/null +++ b/tests/language/src/ToplevelCollision1Test.dart @@ -0,0 +1,15 @@ +// Copyright (c) 2011, the Dart project authors. Please see the AUTHORS file +// for details. All rights reserved. Use of this source code is governed by a +// BSD-style license that can be found in the LICENSE file. + +int x = 100; + +get x() => 200; /// 00: compile-time error +set x(var i) { print(i); } /// 01: compile-time error + +int x(a, b) { print(a + b); } /// 02: compile-time error + + +void main() { + // No need to reference x. +} diff --git a/tests/language/src/ToplevelCollision2Test.dart b/tests/language/src/ToplevelCollision2Test.dart new file mode 100644 index 00000000000..d0f0e5c6533 --- /dev/null +++ b/tests/language/src/ToplevelCollision2Test.dart @@ -0,0 +1,21 @@ +// Copyright (c) 2011, the Dart project authors. Please see the AUTHORS file +// for details. All rights reserved. Use of this source code is governed by a +// BSD-style license that can be found in the LICENSE file. + + +get x() => 200; + +// Ok: can have a setter named x when getter x is defined. +set x(var i) { print(i); } + +// Error: there is already a getter for x +int x; /// 00: compile-time error + +// Error: there is already a getter named x. +int x(a, b) { print(a + b); } /// 01: compile-time error + + + +void main() { + // No need to reference x. +}