| 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 "lib/invocation_mirror.h" | 7 #include "lib/invocation_mirror.h" |
| 8 #include "platform/utils.h" | 8 #include "platform/utils.h" |
| 9 #include "vm/ast_transformer.h" | 9 #include "vm/ast_transformer.h" |
| 10 #include "vm/bootstrap.h" | 10 #include "vm/bootstrap.h" |
| 11 #include "vm/class_finalizer.h" | 11 #include "vm/class_finalizer.h" |
| 12 #include "vm/compiler.h" | 12 #include "vm/compiler.h" |
| 13 #include "vm/compiler_stats.h" | 13 #include "vm/compiler_stats.h" |
| 14 #include "vm/dart_api_impl.h" | 14 #include "vm/dart_api_impl.h" |
| 15 #include "vm/dart_entry.h" | 15 #include "vm/dart_entry.h" |
| 16 #include "vm/flags.h" | 16 #include "vm/flags.h" |
| 17 #include "vm/growable_array.h" | 17 #include "vm/growable_array.h" |
| 18 #include "vm/handles.h" | 18 #include "vm/handles.h" |
| 19 #include "vm/hash_table.h" |
| 19 #include "vm/heap.h" | 20 #include "vm/heap.h" |
| 20 #include "vm/isolate.h" | 21 #include "vm/isolate.h" |
| 21 #include "vm/longjump.h" | 22 #include "vm/longjump.h" |
| 22 #include "vm/native_arguments.h" | 23 #include "vm/native_arguments.h" |
| 23 #include "vm/native_entry.h" | 24 #include "vm/native_entry.h" |
| 24 #include "vm/object.h" | 25 #include "vm/object.h" |
| 25 #include "vm/object_store.h" | 26 #include "vm/object_store.h" |
| 26 #include "vm/os.h" | 27 #include "vm/os.h" |
| 27 #include "vm/regexp_assembler.h" | 28 #include "vm/regexp_assembler.h" |
| 28 #include "vm/report.h" | 29 #include "vm/report.h" |
| (...skipping 11849 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 11878 bool Parser::IsInstantiatorRequired() const { | 11879 bool Parser::IsInstantiatorRequired() const { |
| 11879 ASSERT(!current_function().IsNull()); | 11880 ASSERT(!current_function().IsNull()); |
| 11880 if (current_function().is_static() && | 11881 if (current_function().is_static() && |
| 11881 !current_function().IsInFactoryScope()) { | 11882 !current_function().IsInFactoryScope()) { |
| 11882 return false; | 11883 return false; |
| 11883 } | 11884 } |
| 11884 return current_class().NumTypeParameters() > 0; | 11885 return current_class().NumTypeParameters() > 0; |
| 11885 } | 11886 } |
| 11886 | 11887 |
| 11887 | 11888 |
| 11889 class ConstMapKeyEqualsTraits { |
| 11890 public: |
| 11891 static bool IsMatch(const Object& a, const Object& b) { |
| 11892 return String::Cast(a).Equals(String::Cast(b)); |
| 11893 } |
| 11894 static bool IsMatch(const char* key, const Object& b) { |
| 11895 return String::Cast(b).Equals(key); |
| 11896 } |
| 11897 static uword Hash(const Object& obj) { |
| 11898 return String::Cast(obj).Hash(); |
| 11899 } |
| 11900 static uword Hash(const char* key) { |
| 11901 return String::Hash(key, strlen(key)); |
| 11902 } |
| 11903 }; |
| 11904 typedef UnorderedHashMap<ConstMapKeyEqualsTraits> ConstantsMap; |
| 11905 |
| 11906 |
| 11907 void Parser::CacheConstantValue(intptr_t token_pos, const Instance& value) { |
| 11908 String& key = String::Handle(Z, script_.url()); |
| 11909 String& suffix = |
| 11910 String::Handle(Z, String::NewFormatted("_%" Pd "", token_pos)); |
| 11911 key = Symbols::FromConcat(key, suffix); |
| 11912 if (isolate()->object_store()->compile_time_constants() == Array::null()) { |
| 11913 const intptr_t kInitialConstMapSize = 16; |
| 11914 isolate()->object_store()->set_compile_time_constants( |
| 11915 Array::Handle(Z, HashTables::New<ConstantsMap>(kInitialConstMapSize))); |
| 11916 } |
| 11917 ConstantsMap constants(isolate()->object_store()->compile_time_constants()); |
| 11918 constants.UpdateOrInsert(key, value); |
| 11919 if (FLAG_compiler_stats) { |
| 11920 isolate_->compiler_stats()->num_cached_consts = constants.NumOccupied(); |
| 11921 } |
| 11922 isolate()->object_store()->set_compile_time_constants(constants.Release()); |
| 11923 } |
| 11924 |
| 11925 |
| 11926 bool Parser::GetCachedConstant(intptr_t token_pos, Instance* value) { |
| 11927 if (isolate()->object_store()->compile_time_constants() == Array::null()) { |
| 11928 return false; |
| 11929 } |
| 11930 // We don't want to allocate anything in the heap here since this code |
| 11931 // is called from the optimizing compiler in the background thread. Allocate |
| 11932 // the key value in the zone instead. |
| 11933 const char* key = Z->PrintToString("%s_%" Pd "", |
| 11934 String::Handle(Z, script_.url()).ToCString(), |
| 11935 token_pos); |
| 11936 ConstantsMap constants(isolate()->object_store()->compile_time_constants()); |
| 11937 bool is_present = false; |
| 11938 *value ^= constants.GetOrNull<const char *>(key, &is_present); |
| 11939 ASSERT(constants.Release().raw() == |
| 11940 isolate()->object_store()->compile_time_constants()); |
| 11941 if (FLAG_compiler_stats && is_present) { |
| 11942 isolate_->compiler_stats()->num_const_cache_hits++; |
| 11943 } |
| 11944 return is_present; |
| 11945 } |
| 11946 |
| 11947 |
| 11888 RawInstance* Parser::TryCanonicalize(const Instance& instance, | 11948 RawInstance* Parser::TryCanonicalize(const Instance& instance, |
| 11889 intptr_t token_pos) { | 11949 intptr_t token_pos) { |
| 11890 if (instance.IsNull()) { | 11950 if (instance.IsNull()) { |
| 11891 return instance.raw(); | 11951 return instance.raw(); |
| 11892 } | 11952 } |
| 11893 const char* error_str = NULL; | 11953 const char* error_str = NULL; |
| 11894 Instance& result = | 11954 Instance& result = |
| 11895 Instance::Handle(Z, instance.CheckAndCanonicalize(&error_str)); | 11955 Instance::Handle(Z, instance.CheckAndCanonicalize(&error_str)); |
| 11896 if (result.IsNull()) { | 11956 if (result.IsNull()) { |
| 11897 ReportError(token_pos, "Invalid const object %s", error_str); | 11957 ReportError(token_pos, "Invalid const object %s", error_str); |
| (...skipping 602 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 12500 // Note: if the list literal is empty and the brackets have no whitespace | 12560 // Note: if the list literal is empty and the brackets have no whitespace |
| 12501 // between them, the scanner recognizes the opening and closing bracket | 12561 // between them, the scanner recognizes the opening and closing bracket |
| 12502 // as one token of type Token::kINDEX. | 12562 // as one token of type Token::kINDEX. |
| 12503 AstNode* Parser::ParseListLiteral(intptr_t type_pos, | 12563 AstNode* Parser::ParseListLiteral(intptr_t type_pos, |
| 12504 bool is_const, | 12564 bool is_const, |
| 12505 const TypeArguments& type_arguments) { | 12565 const TypeArguments& type_arguments) { |
| 12506 TRACE_PARSER("ParseListLiteral"); | 12566 TRACE_PARSER("ParseListLiteral"); |
| 12507 ASSERT(type_pos >= 0); | 12567 ASSERT(type_pos >= 0); |
| 12508 ASSERT(CurrentToken() == Token::kLBRACK || CurrentToken() == Token::kINDEX); | 12568 ASSERT(CurrentToken() == Token::kLBRACK || CurrentToken() == Token::kINDEX); |
| 12509 const intptr_t literal_pos = TokenPos(); | 12569 const intptr_t literal_pos = TokenPos(); |
| 12570 |
| 12571 if (is_const) { |
| 12572 Instance& existing_const = Instance::ZoneHandle(Z); |
| 12573 if (GetCachedConstant(literal_pos, &existing_const)) { |
| 12574 SkipListLiteral(); |
| 12575 return new(Z) LiteralNode(literal_pos, existing_const); |
| 12576 } |
| 12577 } |
| 12578 |
| 12510 bool is_empty_literal = CurrentToken() == Token::kINDEX; | 12579 bool is_empty_literal = CurrentToken() == Token::kINDEX; |
| 12511 ConsumeToken(); | 12580 ConsumeToken(); |
| 12512 | 12581 |
| 12513 AbstractType& element_type = Type::ZoneHandle(Z, Type::DynamicType()); | 12582 AbstractType& element_type = Type::ZoneHandle(Z, Type::DynamicType()); |
| 12514 TypeArguments& list_type_arguments = | 12583 TypeArguments& list_type_arguments = |
| 12515 TypeArguments::ZoneHandle(Z, type_arguments.raw()); | 12584 TypeArguments::ZoneHandle(Z, type_arguments.raw()); |
| 12516 // If no type argument vector is provided, leave it as null, which is | 12585 // If no type argument vector is provided, leave it as null, which is |
| 12517 // equivalent to using dynamic as the type argument for the element type. | 12586 // equivalent to using dynamic as the type argument for the element type. |
| 12518 if (!list_type_arguments.IsNull()) { | 12587 if (!list_type_arguments.IsNull()) { |
| 12519 ASSERT(list_type_arguments.Length() > 0); | 12588 ASSERT(list_type_arguments.Length() > 0); |
| (...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 12567 } else if (CurrentToken() != Token::kRBRACK) { | 12636 } else if (CurrentToken() != Token::kRBRACK) { |
| 12568 ReportError("comma or ']' expected"); | 12637 ReportError("comma or ']' expected"); |
| 12569 } | 12638 } |
| 12570 } | 12639 } |
| 12571 ExpectToken(Token::kRBRACK); | 12640 ExpectToken(Token::kRBRACK); |
| 12572 SetAllowFunctionLiterals(saved_mode); | 12641 SetAllowFunctionLiterals(saved_mode); |
| 12573 } | 12642 } |
| 12574 | 12643 |
| 12575 if (is_const) { | 12644 if (is_const) { |
| 12576 // Allocate and initialize the const list at compile time. | 12645 // Allocate and initialize the const list at compile time. |
| 12577 Array& const_list = | 12646 Array& const_list = Array::ZoneHandle(Z, |
| 12578 Array::ZoneHandle(Z, Array::New(element_list.length(), Heap::kOld)); | 12647 Array::New(element_list.length(), Heap::kOld)); |
| 12579 const_list.SetTypeArguments( | 12648 const_list.SetTypeArguments( |
| 12580 TypeArguments::Handle(Z, list_type_arguments.Canonicalize())); | 12649 TypeArguments::Handle(Z, list_type_arguments.Canonicalize())); |
| 12581 Error& malformed_error = Error::Handle(Z); | 12650 Error& malformed_error = Error::Handle(Z); |
| 12582 for (int i = 0; i < element_list.length(); i++) { | 12651 for (int i = 0; i < element_list.length(); i++) { |
| 12583 AstNode* elem = element_list[i]; | 12652 AstNode* elem = element_list[i]; |
| 12584 // Arguments have been evaluated to a literal value already. | 12653 // Arguments have been evaluated to a literal value already. |
| 12585 ASSERT(elem->IsLiteralNode()); | 12654 ASSERT(elem->IsLiteralNode()); |
| 12586 ASSERT(!is_top_level_); // We cannot check unresolved types. | 12655 ASSERT(!is_top_level_); // We cannot check unresolved types. |
| 12587 if (I->flags().type_checks() && | 12656 if (I->flags().type_checks() && |
| 12588 !element_type.IsDynamicType() && | 12657 !element_type.IsDynamicType() && |
| (...skipping 11 matching lines...) Expand all Loading... |
| 12600 "a constant of type '%s'", | 12669 "a constant of type '%s'", |
| 12601 i, | 12670 i, |
| 12602 String::Handle(Z, | 12671 String::Handle(Z, |
| 12603 element_type.UserVisibleName()).ToCString()); | 12672 element_type.UserVisibleName()).ToCString()); |
| 12604 } | 12673 } |
| 12605 } | 12674 } |
| 12606 const_list.SetAt(i, elem->AsLiteralNode()->literal()); | 12675 const_list.SetAt(i, elem->AsLiteralNode()->literal()); |
| 12607 } | 12676 } |
| 12608 const_list.MakeImmutable(); | 12677 const_list.MakeImmutable(); |
| 12609 const_list ^= TryCanonicalize(const_list, literal_pos); | 12678 const_list ^= TryCanonicalize(const_list, literal_pos); |
| 12679 CacheConstantValue(literal_pos, const_list); |
| 12610 return new(Z) LiteralNode(literal_pos, const_list); | 12680 return new(Z) LiteralNode(literal_pos, const_list); |
| 12611 } else { | 12681 } else { |
| 12612 // Factory call at runtime. | 12682 // Factory call at runtime. |
| 12613 const Class& factory_class = | 12683 const Class& factory_class = |
| 12614 Class::Handle(Z, Library::LookupCoreClass(Symbols::List())); | 12684 Class::Handle(Z, Library::LookupCoreClass(Symbols::List())); |
| 12615 ASSERT(!factory_class.IsNull()); | 12685 ASSERT(!factory_class.IsNull()); |
| 12616 const Function& factory_method = Function::ZoneHandle(Z, | 12686 const Function& factory_method = Function::ZoneHandle(Z, |
| 12617 factory_class.LookupFactory( | 12687 factory_class.LookupFactory( |
| 12618 Library::PrivateCoreLibName(Symbols::ListLiteralFactory()))); | 12688 Library::PrivateCoreLibName(Symbols::ListLiteralFactory()))); |
| 12619 ASSERT(!factory_method.IsNull()); | 12689 ASSERT(!factory_method.IsNull()); |
| (...skipping 73 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 12693 } | 12763 } |
| 12694 | 12764 |
| 12695 | 12765 |
| 12696 AstNode* Parser::ParseMapLiteral(intptr_t type_pos, | 12766 AstNode* Parser::ParseMapLiteral(intptr_t type_pos, |
| 12697 bool is_const, | 12767 bool is_const, |
| 12698 const TypeArguments& type_arguments) { | 12768 const TypeArguments& type_arguments) { |
| 12699 TRACE_PARSER("ParseMapLiteral"); | 12769 TRACE_PARSER("ParseMapLiteral"); |
| 12700 ASSERT(type_pos >= 0); | 12770 ASSERT(type_pos >= 0); |
| 12701 ASSERT(CurrentToken() == Token::kLBRACE); | 12771 ASSERT(CurrentToken() == Token::kLBRACE); |
| 12702 const intptr_t literal_pos = TokenPos(); | 12772 const intptr_t literal_pos = TokenPos(); |
| 12703 ConsumeToken(); | |
| 12704 | 12773 |
| 12774 if (is_const) { |
| 12775 Instance& existing_const = Instance::ZoneHandle(Z); |
| 12776 if (GetCachedConstant(literal_pos, &existing_const)) { |
| 12777 SkipMapLiteral(); |
| 12778 return new(Z) LiteralNode(literal_pos, existing_const); |
| 12779 } |
| 12780 } |
| 12781 |
| 12782 ConsumeToken(); // Opening brace. |
| 12705 AbstractType& key_type = Type::ZoneHandle(Z, Type::DynamicType()); | 12783 AbstractType& key_type = Type::ZoneHandle(Z, Type::DynamicType()); |
| 12706 AbstractType& value_type = Type::ZoneHandle(Z, Type::DynamicType()); | 12784 AbstractType& value_type = Type::ZoneHandle(Z, Type::DynamicType()); |
| 12707 TypeArguments& map_type_arguments = | 12785 TypeArguments& map_type_arguments = |
| 12708 TypeArguments::ZoneHandle(Z, type_arguments.raw()); | 12786 TypeArguments::ZoneHandle(Z, type_arguments.raw()); |
| 12709 // If no type argument vector is provided, leave it as null, which is | 12787 // If no type argument vector is provided, leave it as null, which is |
| 12710 // equivalent to using dynamic as the type argument for the both key and value | 12788 // equivalent to using dynamic as the type argument for the both key and value |
| 12711 // types. | 12789 // types. |
| 12712 if (!map_type_arguments.IsNull()) { | 12790 if (!map_type_arguments.IsNull()) { |
| 12713 ASSERT(map_type_arguments.Length() > 0); | 12791 ASSERT(map_type_arguments.Length() > 0); |
| 12714 // Map literals take two type arguments. | 12792 // Map literals take two type arguments. |
| (...skipping 136 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 12851 EvaluateConstConstructorCall(immutable_map_class, | 12929 EvaluateConstConstructorCall(immutable_map_class, |
| 12852 map_type_arguments, | 12930 map_type_arguments, |
| 12853 map_constr, | 12931 map_constr, |
| 12854 constr_args)); | 12932 constr_args)); |
| 12855 if (constructor_result.IsUnhandledException()) { | 12933 if (constructor_result.IsUnhandledException()) { |
| 12856 ReportErrors(Error::Cast(constructor_result), | 12934 ReportErrors(Error::Cast(constructor_result), |
| 12857 script_, literal_pos, | 12935 script_, literal_pos, |
| 12858 "error executing const Map constructor"); | 12936 "error executing const Map constructor"); |
| 12859 } else { | 12937 } else { |
| 12860 const Instance& const_instance = Instance::Cast(constructor_result); | 12938 const Instance& const_instance = Instance::Cast(constructor_result); |
| 12939 CacheConstantValue(literal_pos, const_instance); |
| 12861 return new(Z) LiteralNode( | 12940 return new(Z) LiteralNode( |
| 12862 literal_pos, Instance::ZoneHandle(Z, const_instance.raw())); | 12941 literal_pos, Instance::ZoneHandle(Z, const_instance.raw())); |
| 12863 } | 12942 } |
| 12864 } else { | 12943 } else { |
| 12865 // Factory call at runtime. | 12944 // Factory call at runtime. |
| 12866 const Class& factory_class = | 12945 const Class& factory_class = |
| 12867 Class::Handle(Z, Library::LookupCoreClass(Symbols::Map())); | 12946 Class::Handle(Z, Library::LookupCoreClass(Symbols::Map())); |
| 12868 ASSERT(!factory_class.IsNull()); | 12947 ASSERT(!factory_class.IsNull()); |
| 12869 const Function& factory_method = Function::ZoneHandle(Z, | 12948 const Function& factory_method = Function::ZoneHandle(Z, |
| 12870 factory_class.LookupFactory( | 12949 factory_class.LookupFactory( |
| (...skipping 523 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 13394 // Make the constructor call. | 13473 // Make the constructor call. |
| 13395 AstNode* new_object = NULL; | 13474 AstNode* new_object = NULL; |
| 13396 if (is_const) { | 13475 if (is_const) { |
| 13397 if (!constructor.is_const()) { | 13476 if (!constructor.is_const()) { |
| 13398 const String& external_constructor_name = | 13477 const String& external_constructor_name = |
| 13399 (named_constructor ? constructor_name : type_class_name); | 13478 (named_constructor ? constructor_name : type_class_name); |
| 13400 ReportError("non-const constructor '%s' cannot be used in " | 13479 ReportError("non-const constructor '%s' cannot be used in " |
| 13401 "const object creation", | 13480 "const object creation", |
| 13402 external_constructor_name.ToCString()); | 13481 external_constructor_name.ToCString()); |
| 13403 } | 13482 } |
| 13404 const Object& constructor_result = Object::Handle(Z, | 13483 |
| 13405 EvaluateConstConstructorCall(type_class, | 13484 Instance& const_instance = Instance::ZoneHandle(Z); |
| 13406 type_arguments, | 13485 if (GetCachedConstant(new_pos, &const_instance)) { |
| 13407 constructor, | 13486 // Cache hit, nothing else to do. |
| 13408 arguments)); | |
| 13409 if (constructor_result.IsUnhandledException()) { | |
| 13410 // It's a compile-time error if invocation of a const constructor | |
| 13411 // call fails. | |
| 13412 ReportErrors(Error::Cast(constructor_result), | |
| 13413 script_, new_pos, | |
| 13414 "error while evaluating const constructor"); | |
| 13415 } else { | 13487 } else { |
| 13416 // Const constructors can return null in the case where a const native | 13488 Object& constructor_result = Object::Handle(Z, |
| 13417 // factory returns a null value. Thus we cannot use a Instance::Cast here. | 13489 EvaluateConstConstructorCall(type_class, |
| 13418 Instance& const_instance = Instance::Handle(Z); | 13490 type_arguments, |
| 13491 constructor, |
| 13492 arguments)); |
| 13493 if (constructor_result.IsUnhandledException()) { |
| 13494 // It's a compile-time error if invocation of a const constructor |
| 13495 // call fails. |
| 13496 ReportErrors(Error::Cast(constructor_result), |
| 13497 script_, new_pos, |
| 13498 "error while evaluating const constructor"); |
| 13499 } |
| 13419 const_instance ^= constructor_result.raw(); | 13500 const_instance ^= constructor_result.raw(); |
| 13420 new_object = new(Z) LiteralNode( | 13501 CacheConstantValue(new_pos, const_instance); |
| 13421 new_pos, Instance::ZoneHandle(Z, const_instance.raw())); | 13502 } |
| 13422 if (!type_bound.IsNull()) { | 13503 new_object = new(Z) LiteralNode(new_pos, const_instance); |
| 13423 ASSERT(!type_bound.IsMalformed()); | 13504 if (!type_bound.IsNull()) { |
| 13424 Error& malformed_error = Error::Handle(Z); | 13505 ASSERT(!type_bound.IsMalformed()); |
| 13425 ASSERT(!is_top_level_); // We cannot check unresolved types. | 13506 Error& malformed_error = Error::Handle(Z); |
| 13426 if (!const_instance.IsInstanceOf(type_bound, | 13507 ASSERT(!is_top_level_); // We cannot check unresolved types. |
| 13427 TypeArguments::Handle(Z), | 13508 if (!const_instance.IsInstanceOf(type_bound, |
| 13428 &malformed_error)) { | 13509 TypeArguments::Handle(Z), |
| 13429 type_bound = ClassFinalizer::NewFinalizedMalformedType( | 13510 &malformed_error)) { |
| 13430 malformed_error, | 13511 type_bound = ClassFinalizer::NewFinalizedMalformedType( |
| 13431 script_, | 13512 malformed_error, |
| 13432 new_pos, | 13513 script_, |
| 13433 "const factory result is not an instance of '%s'", | 13514 new_pos, |
| 13434 String::Handle(Z, type_bound.UserVisibleName()).ToCString()); | 13515 "const factory result is not an instance of '%s'", |
| 13435 new_object = ThrowTypeError(new_pos, type_bound); | 13516 String::Handle(Z, type_bound.UserVisibleName()).ToCString()); |
| 13436 } | 13517 new_object = ThrowTypeError(new_pos, type_bound); |
| 13437 type_bound = AbstractType::null(); | |
| 13438 } | 13518 } |
| 13519 type_bound = AbstractType::null(); |
| 13439 } | 13520 } |
| 13440 } else { | 13521 } else { |
| 13441 CheckConstructorCallTypeArguments(new_pos, constructor, type_arguments); | 13522 CheckConstructorCallTypeArguments(new_pos, constructor, type_arguments); |
| 13442 if (!type_arguments.IsNull() && | 13523 if (!type_arguments.IsNull() && |
| 13443 !type_arguments.IsInstantiated() && | 13524 !type_arguments.IsInstantiated() && |
| 13444 (current_block_->scope->function_level() > 0)) { | 13525 (current_block_->scope->function_level() > 0)) { |
| 13445 // Make sure that the instantiator is captured. | 13526 // Make sure that the instantiator is captured. |
| 13446 CaptureInstantiator(); | 13527 CaptureInstantiator(); |
| 13447 } | 13528 } |
| 13448 // If the type argument vector is not instantiated, we verify in checked | 13529 // If the type argument vector is not instantiated, we verify in checked |
| (...skipping 738 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 14187 void Parser::SkipQualIdent() { | 14268 void Parser::SkipQualIdent() { |
| 14188 ASSERT(IsIdentifier()); | 14269 ASSERT(IsIdentifier()); |
| 14189 ConsumeToken(); | 14270 ConsumeToken(); |
| 14190 if (CurrentToken() == Token::kPERIOD) { | 14271 if (CurrentToken() == Token::kPERIOD) { |
| 14191 ConsumeToken(); // Consume the kPERIOD token. | 14272 ConsumeToken(); // Consume the kPERIOD token. |
| 14192 ExpectIdentifier("identifier expected after '.'"); | 14273 ExpectIdentifier("identifier expected after '.'"); |
| 14193 } | 14274 } |
| 14194 } | 14275 } |
| 14195 | 14276 |
| 14196 } // namespace dart | 14277 } // namespace dart |
| OLD | NEW |