| 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 #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" |
| (...skipping 2713 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2724 signature_class = Class::NewSignatureClass(signature, | 2724 signature_class = Class::NewSignatureClass(signature, |
| 2725 signature_function, | 2725 signature_function, |
| 2726 script_); | 2726 script_); |
| 2727 // Record the function signature class in the current library. | 2727 // Record the function signature class in the current library. |
| 2728 library_.AddClass(signature_class); | 2728 library_.AddClass(signature_class); |
| 2729 } else { | 2729 } else { |
| 2730 // Forget the just created signature function and use the existing one. | 2730 // Forget the just created signature function and use the existing one. |
| 2731 signature_function = signature_class.signature_function(); | 2731 signature_function = signature_class.signature_function(); |
| 2732 } | 2732 } |
| 2733 ASSERT(signature_function.signature_class() == signature_class.raw()); | 2733 ASSERT(signature_function.signature_class() == signature_class.raw()); |
| 2734 // Lookup the class by its alias name and report an error if it exists. | 2734 |
| 2735 Class& function_type_alias = | 2735 // Lookup alias name and report an error if it is already defined in |
| 2736 Class::ZoneHandle(library_.LookupClass(*alias_name)); | 2736 // the library scope. |
| 2737 if (function_type_alias.IsNull()) { | 2737 const Object& obj = Object::Handle(library_.LookupObject(*alias_name)); |
| 2738 // Create the function type alias, but share the signature function of the | 2738 if (!obj.IsNull()) { |
| 2739 // canonical signature class. | 2739 ErrorMsg(alias_name_pos, |
| 2740 function_type_alias = Class::NewSignatureClass(*alias_name, | 2740 "'%s' is already defined", alias_name->ToCString()); |
| 2741 signature_function, | |
| 2742 script_); | |
| 2743 library_.AddClass(function_type_alias); | |
| 2744 } else { | |
| 2745 const char* format = function_type_alias.is_interface() ? | |
| 2746 "'%s' is already defined" : "'%s' is already defined as class"; | |
| 2747 ErrorMsg(alias_name_pos, format, alias_name->ToCString()); | |
| 2748 } | 2741 } |
| 2742 |
| 2743 // Create the function type alias, but share the signature function of the |
| 2744 // canonical signature class. |
| 2745 Class& function_type_alias = Class::ZoneHandle( |
| 2746 Class::NewSignatureClass(*alias_name, |
| 2747 signature_function, |
| 2748 script_)); |
| 2749 library_.AddClass(function_type_alias); |
| 2749 ExpectSemicolon(); | 2750 ExpectSemicolon(); |
| 2750 classes->Add(&function_type_alias); | 2751 classes->Add(&function_type_alias); |
| 2751 } | 2752 } |
| 2752 | 2753 |
| 2753 | 2754 |
| 2754 void Parser::ParseInterfaceDefinition(GrowableArray<const Class*>* classes) { | 2755 void Parser::ParseInterfaceDefinition(GrowableArray<const Class*>* classes) { |
| 2755 TRACE_PARSER("ParseInterfaceDefinition"); | 2756 TRACE_PARSER("ParseInterfaceDefinition"); |
| 2756 const intptr_t interface_pos = token_index_; | 2757 const intptr_t interface_pos = token_index_; |
| 2757 ExpectToken(Token::kINTERFACE); | 2758 ExpectToken(Token::kINTERFACE); |
| 2758 const intptr_t interfacename_pos = token_index_; | 2759 const intptr_t interfacename_pos = token_index_; |
| (...skipping 4430 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 7189 | 7190 |
| 7190 AstNode* Parser::ParseNewOperator() { | 7191 AstNode* Parser::ParseNewOperator() { |
| 7191 TRACE_PARSER("ParseNewOperator"); | 7192 TRACE_PARSER("ParseNewOperator"); |
| 7192 const intptr_t new_pos = token_index_; | 7193 const intptr_t new_pos = token_index_; |
| 7193 ASSERT((CurrentToken() == Token::kNEW) || (CurrentToken() == Token::kCONST)); | 7194 ASSERT((CurrentToken() == Token::kNEW) || (CurrentToken() == Token::kCONST)); |
| 7194 bool is_const = (CurrentToken() == Token::kCONST); | 7195 bool is_const = (CurrentToken() == Token::kCONST); |
| 7195 ConsumeToken(); | 7196 ConsumeToken(); |
| 7196 if (!IsIdentifier()) { | 7197 if (!IsIdentifier()) { |
| 7197 ErrorMsg("type name expected"); | 7198 ErrorMsg("type name expected"); |
| 7198 } | 7199 } |
| 7200 intptr_t type_pos = token_index_; |
| 7199 | 7201 |
| 7200 const AbstractType& type = AbstractType::Handle(ParseType(kMustResolve)); | 7202 const AbstractType& type = AbstractType::Handle(ParseType(kMustResolve)); |
| 7201 if (type.IsTypeParameter()) { | 7203 if (type.IsTypeParameter()) { |
| 7202 ErrorMsg(type.token_index(), | 7204 ErrorMsg(type_pos, |
| 7203 "type parameter '%s' cannot be instantiated", | 7205 "type parameter '%s' cannot be instantiated", |
| 7204 String::Handle(type.Name()).ToCString()); | 7206 String::Handle(type.Name()).ToCString()); |
| 7205 } | 7207 } |
| 7206 Class& type_class = Class::Handle(type.type_class()); | 7208 Class& type_class = Class::Handle(type.type_class()); |
| 7207 String& type_class_name = String::Handle(type_class.Name()); | 7209 String& type_class_name = String::Handle(type_class.Name()); |
| 7208 AbstractTypeArguments& type_arguments = | 7210 AbstractTypeArguments& type_arguments = |
| 7209 AbstractTypeArguments::ZoneHandle(type.arguments()); | 7211 AbstractTypeArguments::ZoneHandle(type.arguments()); |
| 7210 | 7212 |
| 7211 // The constructor class and its name are those of the parsed type, unless the | 7213 // The constructor class and its name are those of the parsed type, unless the |
| 7212 // parsed type is an interface and a default factory class is specified, in | 7214 // parsed type is an interface and a default factory class is specified, in |
| 7213 // which case constructor_class and constructor_class_name are modified below. | 7215 // which case constructor_class and constructor_class_name are modified below. |
| 7214 Class& constructor_class = Class::ZoneHandle(type_class.raw()); | 7216 Class& constructor_class = Class::ZoneHandle(type_class.raw()); |
| 7215 String& constructor_class_name = String::Handle(type_class_name.raw()); | 7217 String& constructor_class_name = String::Handle(type_class_name.raw()); |
| 7216 | 7218 |
| 7217 // The grammar allows for an optional ('.' identifier)? after the type, which | 7219 // The grammar allows for an optional ('.' identifier)? after the type, which |
| 7218 // is a named constructor. Note that ParseType(kMustResolve) above will not | 7220 // is a named constructor. Note that ParseType(kMustResolve) above will not |
| 7219 // consume it as part of a misinterpreted qualified identifier, because only a | 7221 // consume it as part of a misinterpreted qualified identifier, because only a |
| 7220 // valid library prefix is accepted as qualifier. | 7222 // valid library prefix is accepted as qualifier. |
| 7221 String* named_constructor = NULL; | 7223 String* named_constructor = NULL; |
| 7222 if (CurrentToken() == Token::kPERIOD) { | 7224 if (CurrentToken() == Token::kPERIOD) { |
| 7223 ConsumeToken(); | 7225 ConsumeToken(); |
| 7224 named_constructor = ExpectIdentifier("name of constructor expected"); | 7226 named_constructor = ExpectIdentifier("name of constructor expected"); |
| 7225 } | 7227 } |
| 7226 | 7228 |
| 7227 // Parse constructor parameters. | 7229 // Parse constructor parameters. |
| 7228 if (CurrentToken() != Token::kLPAREN) { | 7230 if (CurrentToken() != Token::kLPAREN) { |
| 7229 ErrorMsg("'(' expected"); | 7231 ErrorMsg("'(' expected"); |
| 7230 } | 7232 } |
| 7233 intptr_t call_pos = token_index_; |
| 7231 ArgumentListNode* arguments = ParseActualParameters(NULL, is_const); | 7234 ArgumentListNode* arguments = ParseActualParameters(NULL, is_const); |
| 7232 | 7235 |
| 7233 // A constructor has an implicit 'this' parameter (instance to construct) | 7236 // A constructor has an implicit 'this' parameter (instance to construct) |
| 7234 // and a factory has an implicit 'this' parameter (type_arguments). | 7237 // and a factory has an implicit 'this' parameter (type_arguments). |
| 7235 // A constructor has a second implicit 'phase' parameter. | 7238 // A constructor has a second implicit 'phase' parameter. |
| 7236 intptr_t arguments_length = arguments->length() + 2; | 7239 intptr_t arguments_length = arguments->length() + 2; |
| 7237 | 7240 |
| 7238 if (type_class.is_interface()) { | 7241 if (type_class.is_interface()) { |
| 7239 // We need to make sure that an appropriate constructor is | 7242 // We need to make sure that an appropriate constructor is |
| 7240 // declared in the interface. | 7243 // declared in the interface. |
| 7241 const String& constructor_name = | 7244 const String& constructor_name = |
| 7242 BuildConstructorName(type_class_name, named_constructor); | 7245 BuildConstructorName(type_class_name, named_constructor); |
| 7243 const String& external_constructor_name = | 7246 const String& external_constructor_name = |
| 7244 (named_constructor ? constructor_name : type_class_name); | 7247 (named_constructor ? constructor_name : type_class_name); |
| 7245 Function& constructor = Function::ZoneHandle( | 7248 Function& constructor = Function::ZoneHandle( |
| 7246 type_class.LookupConstructor(constructor_name)); | 7249 type_class.LookupConstructor(constructor_name)); |
| 7247 if (constructor.IsNull()) { | 7250 if (constructor.IsNull()) { |
| 7248 ErrorMsg(type.token_index(), | 7251 ErrorMsg(type_pos, |
| 7249 "interface '%s' has no constructor named '%s'", | 7252 "interface '%s' has no constructor named '%s'", |
| 7250 type_class_name.ToCString(), | 7253 type_class_name.ToCString(), |
| 7251 external_constructor_name.ToCString()); | 7254 external_constructor_name.ToCString()); |
| 7252 } | 7255 } |
| 7253 if (!constructor.AreValidArguments(arguments_length, arguments->names())) { | 7256 if (!constructor.AreValidArguments(arguments_length, arguments->names())) { |
| 7254 ErrorMsg(type.token_index(), | 7257 ErrorMsg(call_pos, |
| 7255 "invalid arguments passed to constructor '%s' " | 7258 "invalid arguments passed to constructor '%s' " |
| 7256 "for interface '%s'", | 7259 "for interface '%s'", |
| 7257 external_constructor_name.ToCString(), | 7260 external_constructor_name.ToCString(), |
| 7258 type_class_name.ToCString()); | 7261 type_class_name.ToCString()); |
| 7259 } | 7262 } |
| 7260 if (!type_class.HasFactoryClass()) { | 7263 if (!type_class.HasFactoryClass()) { |
| 7261 ErrorMsg("cannot allocate interface '%s' without factory class", | 7264 ErrorMsg(type_pos, |
| 7265 "cannot allocate interface '%s' without factory class", |
| 7262 type_class_name.ToCString()); | 7266 type_class_name.ToCString()); |
| 7263 } | 7267 } |
| 7264 if (!type_class.HasResolvedFactoryClass()) { | 7268 if (!type_class.HasResolvedFactoryClass()) { |
| 7265 // This error can occur only with bootstrap classes. | 7269 // This error can occur only with bootstrap classes. |
| 7266 const UnresolvedClass& unresolved = | 7270 const UnresolvedClass& unresolved = |
| 7267 UnresolvedClass::Handle(type_class.UnresolvedFactoryClass()); | 7271 UnresolvedClass::Handle(type_class.UnresolvedFactoryClass()); |
| 7268 const String& missing_class_name = String::Handle(unresolved.ident()); | 7272 const String& missing_class_name = String::Handle(unresolved.ident()); |
| 7269 ErrorMsg("unresolved factory class '%s'", missing_class_name.ToCString()); | 7273 ErrorMsg("unresolved factory class '%s'", missing_class_name.ToCString()); |
| 7270 } | 7274 } |
| 7271 // Only change the class of the constructor to the factory class if the | 7275 // Only change the class of the constructor to the factory class if the |
| (...skipping 18 matching lines...) Expand all Loading... |
| 7290 Function& constructor = Function::ZoneHandle( | 7294 Function& constructor = Function::ZoneHandle( |
| 7291 constructor_class.LookupConstructor(constructor_name)); | 7295 constructor_class.LookupConstructor(constructor_name)); |
| 7292 if (constructor.IsNull()) { | 7296 if (constructor.IsNull()) { |
| 7293 constructor = constructor_class.LookupFactory(constructor_name); | 7297 constructor = constructor_class.LookupFactory(constructor_name); |
| 7294 // A factory does not have the implicit 'phase' parameter. | 7298 // A factory does not have the implicit 'phase' parameter. |
| 7295 arguments_length -= 1; | 7299 arguments_length -= 1; |
| 7296 } | 7300 } |
| 7297 if (constructor.IsNull()) { | 7301 if (constructor.IsNull()) { |
| 7298 const String& external_constructor_name = | 7302 const String& external_constructor_name = |
| 7299 (named_constructor ? constructor_name : constructor_class_name); | 7303 (named_constructor ? constructor_name : constructor_class_name); |
| 7300 ErrorMsg(type.token_index(), | 7304 ErrorMsg(type_pos, |
| 7301 "class '%s' has no constructor or factory named '%s'", | 7305 "class '%s' has no constructor or factory named '%s'", |
| 7302 String::Handle(constructor_class.Name()).ToCString(), | 7306 String::Handle(constructor_class.Name()).ToCString(), |
| 7303 external_constructor_name.ToCString()); | 7307 external_constructor_name.ToCString()); |
| 7304 } | 7308 } |
| 7305 if (!constructor.AreValidArguments(arguments_length, arguments->names())) { | 7309 if (!constructor.AreValidArguments(arguments_length, arguments->names())) { |
| 7306 const String& external_constructor_name = | 7310 const String& external_constructor_name = |
| 7307 (named_constructor ? constructor_name : constructor_class_name); | 7311 (named_constructor ? constructor_name : constructor_class_name); |
| 7308 ErrorMsg(type.token_index(), | 7312 ErrorMsg(call_pos, |
| 7309 "invalid arguments passed to constructor '%s' for class '%s'", | 7313 "invalid arguments passed to constructor '%s' for class '%s'", |
| 7310 external_constructor_name.ToCString(), | 7314 external_constructor_name.ToCString(), |
| 7311 String::Handle(constructor_class.Name()).ToCString()); | 7315 String::Handle(constructor_class.Name()).ToCString()); |
| 7312 } | 7316 } |
| 7313 | 7317 |
| 7314 // Now that the constructor to be called is identified, finalize the type | 7318 // Now that the constructor to be called is identified, finalize the type |
| 7315 // argument vector to be passed. | 7319 // argument vector to be passed. |
| 7316 // The type argument vector of the parsed type was finalized in ParseType. | 7320 // The type argument vector of the parsed type was finalized in ParseType. |
| 7317 // If the constructor class was changed from the interface class to the | 7321 // If the constructor class was changed from the interface class to the |
| 7318 // factory class, we need to finalize the type argument vector again, because | 7322 // factory class, we need to finalize the type argument vector again, because |
| (...skipping 590 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 7909 void Parser::SkipQualIdent() { | 7913 void Parser::SkipQualIdent() { |
| 7910 ASSERT(IsIdentifier()); | 7914 ASSERT(IsIdentifier()); |
| 7911 ConsumeToken(); | 7915 ConsumeToken(); |
| 7912 if (CurrentToken() == Token::kPERIOD) { | 7916 if (CurrentToken() == Token::kPERIOD) { |
| 7913 ConsumeToken(); // Consume the kPERIOD token. | 7917 ConsumeToken(); // Consume the kPERIOD token. |
| 7914 ExpectIdentifier("identifier expected after '.'"); | 7918 ExpectIdentifier("identifier expected after '.'"); |
| 7915 } | 7919 } |
| 7916 } | 7920 } |
| 7917 | 7921 |
| 7918 } // namespace dart | 7922 } // namespace dart |
| OLD | NEW |