| 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 3058 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3069 CurrentLiteral()->Equals("patch")) { | 3069 CurrentLiteral()->Equals("patch")) { |
| 3070 ConsumeToken(); | 3070 ConsumeToken(); |
| 3071 is_patch = true; | 3071 is_patch = true; |
| 3072 } else if (CurrentToken() == Token::kABSTRACT) { | 3072 } else if (CurrentToken() == Token::kABSTRACT) { |
| 3073 is_abstract = true; | 3073 is_abstract = true; |
| 3074 ConsumeToken(); | 3074 ConsumeToken(); |
| 3075 } | 3075 } |
| 3076 const intptr_t class_pos = TokenPos(); | 3076 const intptr_t class_pos = TokenPos(); |
| 3077 ExpectToken(Token::kCLASS); | 3077 ExpectToken(Token::kCLASS); |
| 3078 const intptr_t classname_pos = TokenPos(); | 3078 const intptr_t classname_pos = TokenPos(); |
| 3079 String& class_name = *ExpectClassIdentifier("class name expected"); | 3079 String& class_name = *ExpectUserDefinedTypeIdentifier("class name expected"); |
| 3080 if (FLAG_trace_parser) { | 3080 if (FLAG_trace_parser) { |
| 3081 OS::Print("TopLevel parsing class '%s'\n", class_name.ToCString()); | 3081 OS::Print("TopLevel parsing class '%s'\n", class_name.ToCString()); |
| 3082 } | 3082 } |
| 3083 Class& cls = Class::Handle(); | 3083 Class& cls = Class::Handle(); |
| 3084 Object& obj = Object::Handle(library_.LookupLocalObject(class_name)); | 3084 Object& obj = Object::Handle(library_.LookupLocalObject(class_name)); |
| 3085 if (obj.IsNull()) { | 3085 if (obj.IsNull()) { |
| 3086 if (is_patch) { | 3086 if (is_patch) { |
| 3087 ErrorMsg(classname_pos, "missing class '%s' cannot be patched", | 3087 ErrorMsg(classname_pos, "missing class '%s' cannot be patched", |
| 3088 class_name.ToCString()); | 3088 class_name.ToCString()); |
| 3089 } | 3089 } |
| (...skipping 223 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3313 ConsumeToken(); | 3313 ConsumeToken(); |
| 3314 result_type = Type::VoidType(); | 3314 result_type = Type::VoidType(); |
| 3315 } else if (!IsFunctionTypeAliasName()) { | 3315 } else if (!IsFunctionTypeAliasName()) { |
| 3316 // Type annotations in typedef are never ignored, even in unchecked mode. | 3316 // Type annotations in typedef are never ignored, even in unchecked mode. |
| 3317 // Wait until we have an owner class before resolving the result type. | 3317 // Wait until we have an owner class before resolving the result type. |
| 3318 result_type = ParseType(ClassFinalizer::kDoNotResolve); | 3318 result_type = ParseType(ClassFinalizer::kDoNotResolve); |
| 3319 } | 3319 } |
| 3320 | 3320 |
| 3321 const intptr_t alias_name_pos = TokenPos(); | 3321 const intptr_t alias_name_pos = TokenPos(); |
| 3322 const String* alias_name = | 3322 const String* alias_name = |
| 3323 ExpectClassIdentifier("function alias name expected"); | 3323 ExpectUserDefinedTypeIdentifier("function alias name expected"); |
| 3324 | 3324 |
| 3325 // Parse the type parameters of the function type. | 3325 // Parse the type parameters of the function type. |
| 3326 ParseTypeParameters(alias_owner); | 3326 ParseTypeParameters(alias_owner); |
| 3327 // At this point, the type parameters have been parsed, so we can resolve the | 3327 // At this point, the type parameters have been parsed, so we can resolve the |
| 3328 // result type. | 3328 // result type. |
| 3329 if (!result_type.IsNull()) { | 3329 if (!result_type.IsNull()) { |
| 3330 ResolveTypeFromClass(alias_owner, | 3330 ResolveTypeFromClass(alias_owner, |
| 3331 ClassFinalizer::kTryResolve, | 3331 ClassFinalizer::kTryResolve, |
| 3332 &result_type); | 3332 &result_type); |
| 3333 } | 3333 } |
| (...skipping 61 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3395 pending_classes.Add(function_type_alias, Heap::kOld); | 3395 pending_classes.Add(function_type_alias, Heap::kOld); |
| 3396 } | 3396 } |
| 3397 | 3397 |
| 3398 | 3398 |
| 3399 void Parser::ParseInterfaceDefinition( | 3399 void Parser::ParseInterfaceDefinition( |
| 3400 const GrowableObjectArray& pending_classes) { | 3400 const GrowableObjectArray& pending_classes) { |
| 3401 TRACE_PARSER("ParseInterfaceDefinition"); | 3401 TRACE_PARSER("ParseInterfaceDefinition"); |
| 3402 const intptr_t interface_pos = TokenPos(); | 3402 const intptr_t interface_pos = TokenPos(); |
| 3403 ExpectToken(Token::kINTERFACE); | 3403 ExpectToken(Token::kINTERFACE); |
| 3404 const intptr_t interfacename_pos = TokenPos(); | 3404 const intptr_t interfacename_pos = TokenPos(); |
| 3405 String& interface_name = *ExpectClassIdentifier("interface name expected"); | 3405 String& interface_name = |
| 3406 *ExpectUserDefinedTypeIdentifier("interface name expected"); |
| 3406 if (FLAG_trace_parser) { | 3407 if (FLAG_trace_parser) { |
| 3407 OS::Print("TopLevel parsing interface '%s'\n", interface_name.ToCString()); | 3408 OS::Print("TopLevel parsing interface '%s'\n", interface_name.ToCString()); |
| 3408 } | 3409 } |
| 3409 Class& interface = Class::Handle(); | 3410 Class& interface = Class::Handle(); |
| 3410 Object& obj = Object::Handle(library_.LookupLocalObject(interface_name)); | 3411 Object& obj = Object::Handle(library_.LookupLocalObject(interface_name)); |
| 3411 if (obj.IsNull()) { | 3412 if (obj.IsNull()) { |
| 3412 interface = Class::NewInterface(interface_name, script_, interfacename_pos); | 3413 interface = Class::NewInterface(interface_name, script_, interfacename_pos); |
| 3413 library_.AddClass(interface); | 3414 library_.AddClass(interface); |
| 3414 } else { | 3415 } else { |
| 3415 if (!obj.IsClass()) { | 3416 if (!obj.IsClass()) { |
| (...skipping 166 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3582 const GrowableObjectArray& type_parameters_array = | 3583 const GrowableObjectArray& type_parameters_array = |
| 3583 GrowableObjectArray::Handle(GrowableObjectArray::New()); | 3584 GrowableObjectArray::Handle(GrowableObjectArray::New()); |
| 3584 intptr_t index = 0; | 3585 intptr_t index = 0; |
| 3585 TypeParameter& type_parameter = TypeParameter::Handle(); | 3586 TypeParameter& type_parameter = TypeParameter::Handle(); |
| 3586 TypeParameter& existing_type_parameter = TypeParameter::Handle(); | 3587 TypeParameter& existing_type_parameter = TypeParameter::Handle(); |
| 3587 String& existing_type_parameter_name = String::Handle(); | 3588 String& existing_type_parameter_name = String::Handle(); |
| 3588 AbstractType& type_parameter_bound = Type::Handle(); | 3589 AbstractType& type_parameter_bound = Type::Handle(); |
| 3589 do { | 3590 do { |
| 3590 ConsumeToken(); | 3591 ConsumeToken(); |
| 3591 SkipMetadata(); | 3592 SkipMetadata(); |
| 3592 if (CurrentToken() != Token::kIDENT) { | |
| 3593 ErrorMsg("type parameter name expected"); | |
| 3594 } | |
| 3595 String& type_parameter_name = *CurrentLiteral(); | |
| 3596 const intptr_t type_parameter_pos = TokenPos(); | 3593 const intptr_t type_parameter_pos = TokenPos(); |
| 3594 String& type_parameter_name = |
| 3595 *ExpectUserDefinedTypeIdentifier("type parameter expected"); |
| 3597 // Check for duplicate type parameters. | 3596 // Check for duplicate type parameters. |
| 3598 for (intptr_t i = 0; i < index; i++) { | 3597 for (intptr_t i = 0; i < index; i++) { |
| 3599 existing_type_parameter ^= type_parameters_array.At(i); | 3598 existing_type_parameter ^= type_parameters_array.At(i); |
| 3600 existing_type_parameter_name = existing_type_parameter.name(); | 3599 existing_type_parameter_name = existing_type_parameter.name(); |
| 3601 if (existing_type_parameter_name.Equals(type_parameter_name)) { | 3600 if (existing_type_parameter_name.Equals(type_parameter_name)) { |
| 3602 ErrorMsg("duplicate type parameter '%s'", | 3601 ErrorMsg(type_parameter_pos, "duplicate type parameter '%s'", |
| 3603 type_parameter_name.ToCString()); | 3602 type_parameter_name.ToCString()); |
| 3604 } | 3603 } |
| 3605 } | 3604 } |
| 3606 ConsumeToken(); | |
| 3607 if (CurrentToken() == Token::kEXTENDS) { | 3605 if (CurrentToken() == Token::kEXTENDS) { |
| 3608 ConsumeToken(); | 3606 ConsumeToken(); |
| 3609 // A bound may refer to the owner of the type parameter it applies to, | 3607 // A bound may refer to the owner of the type parameter it applies to, |
| 3610 // i.e. to the class or interface currently being parsed. | 3608 // i.e. to the class or interface currently being parsed. |
| 3611 // Postpone resolution in order to avoid resolving the class and its | 3609 // Postpone resolution in order to avoid resolving the class and its |
| 3612 // type parameters, as they are not fully parsed yet. | 3610 // type parameters, as they are not fully parsed yet. |
| 3613 type_parameter_bound = ParseType(ClassFinalizer::kDoNotResolve); | 3611 type_parameter_bound = ParseType(ClassFinalizer::kDoNotResolve); |
| 3614 } else { | 3612 } else { |
| 3615 type_parameter_bound = isolate->object_store()->object_type(); | 3613 type_parameter_bound = isolate->object_store()->object_type(); |
| 3616 } | 3614 } |
| (...skipping 2960 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 6577 } | 6575 } |
| 6578 | 6576 |
| 6579 | 6577 |
| 6580 void Parser::UnexpectedToken() { | 6578 void Parser::UnexpectedToken() { |
| 6581 ErrorMsg("unexpected token '%s'", | 6579 ErrorMsg("unexpected token '%s'", |
| 6582 CurrentToken() == Token::kIDENT ? | 6580 CurrentToken() == Token::kIDENT ? |
| 6583 CurrentLiteral()->ToCString() : Token::Str(CurrentToken())); | 6581 CurrentLiteral()->ToCString() : Token::Str(CurrentToken())); |
| 6584 } | 6582 } |
| 6585 | 6583 |
| 6586 | 6584 |
| 6587 String* Parser::ExpectClassIdentifier(const char* msg) { | 6585 String* Parser::ExpectUserDefinedTypeIdentifier(const char* msg) { |
| 6588 if (CurrentToken() != Token::kIDENT) { | 6586 if (CurrentToken() != Token::kIDENT) { |
| 6589 ErrorMsg("%s", msg); | 6587 ErrorMsg("%s", msg); |
| 6590 } | 6588 } |
| 6591 String* ident = CurrentLiteral(); | 6589 String* ident = CurrentLiteral(); |
| 6592 // TODO(hausner): Remove check for 'Dynamic' once support for upper-case | 6590 // TODO(hausner): Remove check for 'Dynamic' once support for upper-case |
| 6593 // type dynamic is gone. | 6591 // type dynamic is gone. |
| 6594 if (ident->Equals("Dynamic") || ident->Equals("dynamic")) { | 6592 if (ident->Equals("Dynamic") || ident->Equals("dynamic")) { |
| 6595 ErrorMsg("%s", msg); | 6593 ErrorMsg("%s", msg); |
| 6596 } | 6594 } |
| 6597 ConsumeToken(); | 6595 ConsumeToken(); |
| (...skipping 3242 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 9840 void Parser::SkipQualIdent() { | 9838 void Parser::SkipQualIdent() { |
| 9841 ASSERT(IsIdentifier()); | 9839 ASSERT(IsIdentifier()); |
| 9842 ConsumeToken(); | 9840 ConsumeToken(); |
| 9843 if (CurrentToken() == Token::kPERIOD) { | 9841 if (CurrentToken() == Token::kPERIOD) { |
| 9844 ConsumeToken(); // Consume the kPERIOD token. | 9842 ConsumeToken(); // Consume the kPERIOD token. |
| 9845 ExpectIdentifier("identifier expected after '.'"); | 9843 ExpectIdentifier("identifier expected after '.'"); |
| 9846 } | 9844 } |
| 9847 } | 9845 } |
| 9848 | 9846 |
| 9849 } // namespace dart | 9847 } // namespace dart |
| OLD | NEW |