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 344 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
355 | 355 |
356 Token::Kind Parser::LookaheadToken(int num_tokens) { | 356 Token::Kind Parser::LookaheadToken(int num_tokens) { |
357 CompilerStats::num_tokens_lookahead++; | 357 CompilerStats::num_tokens_lookahead++; |
358 CompilerStats::num_token_checks++; | 358 CompilerStats::num_token_checks++; |
359 return tokens_iterator_.LookaheadTokenKind(num_tokens); | 359 return tokens_iterator_.LookaheadTokenKind(num_tokens); |
360 } | 360 } |
361 | 361 |
362 | 362 |
363 String* Parser::CurrentLiteral() const { | 363 String* Parser::CurrentLiteral() const { |
364 String& result = String::ZoneHandle(); | 364 String& result = String::ZoneHandle(); |
365 result |= tokens_iterator_.CurrentLiteral(); | 365 result = tokens_iterator_.CurrentLiteral(); |
366 return &result; | 366 return &result; |
367 } | 367 } |
368 | 368 |
369 | 369 |
370 RawDouble* Parser::CurrentDoubleLiteral() const { | 370 RawDouble* Parser::CurrentDoubleLiteral() const { |
371 LiteralToken& token = LiteralToken::Handle(); | 371 LiteralToken& token = LiteralToken::Handle(); |
372 token |= tokens_iterator_.CurrentToken(); | 372 token ^= tokens_iterator_.CurrentToken(); |
373 ASSERT(token.kind() == Token::kDOUBLE); | 373 ASSERT(token.kind() == Token::kDOUBLE); |
374 return reinterpret_cast<RawDouble*>(token.value()); | 374 return reinterpret_cast<RawDouble*>(token.value()); |
375 } | 375 } |
376 | 376 |
377 | 377 |
378 RawInteger* Parser::CurrentIntegerLiteral() const { | 378 RawInteger* Parser::CurrentIntegerLiteral() const { |
379 LiteralToken& token = LiteralToken::Handle(); | 379 LiteralToken& token = LiteralToken::Handle(); |
380 token |= tokens_iterator_.CurrentToken(); | 380 token ^= tokens_iterator_.CurrentToken(); |
381 ASSERT(token.kind() == Token::kINTEGER); | 381 ASSERT(token.kind() == Token::kINTEGER); |
382 return reinterpret_cast<RawInteger*>(token.value()); | 382 return reinterpret_cast<RawInteger*>(token.value()); |
383 } | 383 } |
384 | 384 |
385 | 385 |
386 // A QualIdent is an optionally qualified identifier. | 386 // A QualIdent is an optionally qualified identifier. |
387 struct QualIdent { | 387 struct QualIdent { |
388 QualIdent() { | 388 QualIdent() { |
389 Clear(); | 389 Clear(); |
390 } | 390 } |
(...skipping 226 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
617 return clazz_.raw(); | 617 return clazz_.raw(); |
618 } | 618 } |
619 | 619 |
620 const String& class_name() const { | 620 const String& class_name() const { |
621 return class_name_; | 621 return class_name_; |
622 } | 622 } |
623 | 623 |
624 bool has_constructor() const { | 624 bool has_constructor() const { |
625 Function& func = Function::Handle(); | 625 Function& func = Function::Handle(); |
626 for (int i = 0; i < functions_.Length(); i++) { | 626 for (int i = 0; i < functions_.Length(); i++) { |
627 func |= functions_.At(i); | 627 func ^= functions_.At(i); |
628 if (func.kind() == RawFunction::kConstructor) { | 628 if (func.kind() == RawFunction::kConstructor) { |
629 return true; | 629 return true; |
630 } | 630 } |
631 } | 631 } |
632 return false; | 632 return false; |
633 } | 633 } |
634 | 634 |
635 intptr_t token_pos() const { | 635 intptr_t token_pos() const { |
636 return token_pos_; | 636 return token_pos_; |
637 } | 637 } |
(...skipping 13 matching lines...) Expand all Loading... |
651 } | 651 } |
652 } | 652 } |
653 return NULL; | 653 return NULL; |
654 } | 654 } |
655 | 655 |
656 private: | 656 private: |
657 Field* LookupField(const String& name) const { | 657 Field* LookupField(const String& name) const { |
658 String& test_name = String::Handle(); | 658 String& test_name = String::Handle(); |
659 Field& field = Field::Handle(); | 659 Field& field = Field::Handle(); |
660 for (int i = 0; i < fields_.Length(); i++) { | 660 for (int i = 0; i < fields_.Length(); i++) { |
661 field |= fields_.At(i); | 661 field ^= fields_.At(i); |
662 test_name = field.name(); | 662 test_name = field.name(); |
663 if (name.Equals(test_name)) { | 663 if (name.Equals(test_name)) { |
664 return &field; | 664 return &field; |
665 } | 665 } |
666 } | 666 } |
667 return NULL; | 667 return NULL; |
668 } | 668 } |
669 | 669 |
670 bool FieldExists(const String& name) const { | 670 bool FieldExists(const String& name) const { |
671 return LookupField(name) != NULL; | 671 return LookupField(name) != NULL; |
672 } | 672 } |
673 | 673 |
674 Function* LookupFunction(const String& name) const { | 674 Function* LookupFunction(const String& name) const { |
675 String& test_name = String::Handle(); | 675 String& test_name = String::Handle(); |
676 Function& func = Function::Handle(); | 676 Function& func = Function::Handle(); |
677 for (int i = 0; i < functions_.Length(); i++) { | 677 for (int i = 0; i < functions_.Length(); i++) { |
678 func |= functions_.At(i); | 678 func ^= functions_.At(i); |
679 test_name = func.name(); | 679 test_name = func.name(); |
680 if (name.Equals(test_name)) { | 680 if (name.Equals(test_name)) { |
681 return &func; | 681 return &func; |
682 } | 682 } |
683 } | 683 } |
684 return NULL; | 684 return NULL; |
685 } | 685 } |
686 | 686 |
687 bool FunctionExists(const String& name) const { | 687 bool FunctionExists(const String& name) const { |
688 return LookupFunction(name) != NULL; | 688 return LookupFunction(name) != NULL; |
(...skipping 1071 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1760 AstNode* instance = new LoadLocalNode(field_pos, receiver); | 1760 AstNode* instance = new LoadLocalNode(field_pos, receiver); |
1761 return new StoreInstanceFieldNode(field_pos, instance, field, init_expr); | 1761 return new StoreInstanceFieldNode(field_pos, instance, field, init_expr); |
1762 } | 1762 } |
1763 | 1763 |
1764 | 1764 |
1765 void Parser::CheckConstFieldsInitialized(const Class& cls) { | 1765 void Parser::CheckConstFieldsInitialized(const Class& cls) { |
1766 const Array& fields = Array::Handle(cls.fields()); | 1766 const Array& fields = Array::Handle(cls.fields()); |
1767 Field& field = Field::Handle(); | 1767 Field& field = Field::Handle(); |
1768 SequenceNode* initializers = current_block_->statements; | 1768 SequenceNode* initializers = current_block_->statements; |
1769 for (int field_num = 0; field_num < fields.Length(); field_num++) { | 1769 for (int field_num = 0; field_num < fields.Length(); field_num++) { |
1770 field |= fields.At(field_num); | 1770 field ^= fields.At(field_num); |
1771 if (field.is_static() || !field.is_final()) { | 1771 if (field.is_static() || !field.is_final()) { |
1772 continue; | 1772 continue; |
1773 } | 1773 } |
1774 bool found = false; | 1774 bool found = false; |
1775 for (int i = 0; i < initializers->length(); i++) { | 1775 for (int i = 0; i < initializers->length(); i++) { |
1776 found = false; | 1776 found = false; |
1777 if (initializers->NodeAt(i)->IsStoreInstanceFieldNode()) { | 1777 if (initializers->NodeAt(i)->IsStoreInstanceFieldNode()) { |
1778 StoreInstanceFieldNode* initializer = | 1778 StoreInstanceFieldNode* initializer = |
1779 initializers->NodeAt(i)->AsStoreInstanceFieldNode(); | 1779 initializers->NodeAt(i)->AsStoreInstanceFieldNode(); |
1780 if (initializer->field().raw() == field.raw()) { | 1780 if (initializer->field().raw() == field.raw()) { |
(...skipping 11 matching lines...) Expand all Loading... |
1792 | 1792 |
1793 | 1793 |
1794 void Parser::ParseInitializedInstanceFields(const Class& cls, | 1794 void Parser::ParseInitializedInstanceFields(const Class& cls, |
1795 LocalVariable* receiver, | 1795 LocalVariable* receiver, |
1796 GrowableArray<Field*>* initialized_fields) { | 1796 GrowableArray<Field*>* initialized_fields) { |
1797 TRACE_PARSER("ParseInitializedInstanceFields"); | 1797 TRACE_PARSER("ParseInitializedInstanceFields"); |
1798 const Array& fields = Array::Handle(cls.fields()); | 1798 const Array& fields = Array::Handle(cls.fields()); |
1799 Field& f = Field::Handle(); | 1799 Field& f = Field::Handle(); |
1800 const intptr_t saved_pos = TokenPos(); | 1800 const intptr_t saved_pos = TokenPos(); |
1801 for (int i = 0; i < fields.Length(); i++) { | 1801 for (int i = 0; i < fields.Length(); i++) { |
1802 f |= fields.At(i); | 1802 f ^= fields.At(i); |
1803 if (!f.is_static() && f.has_initializer()) { | 1803 if (!f.is_static() && f.has_initializer()) { |
1804 Field& field = Field::ZoneHandle(); | 1804 Field& field = Field::ZoneHandle(); |
1805 field |= fields.At(i); | 1805 field ^= fields.At(i); |
1806 if (field.is_final()) { | 1806 if (field.is_final()) { |
1807 // Final fields with initializer expression may not be initialized | 1807 // Final fields with initializer expression may not be initialized |
1808 // again by constructors. Remember that this field is already | 1808 // again by constructors. Remember that this field is already |
1809 // initialized. | 1809 // initialized. |
1810 initialized_fields->Add(&field); | 1810 initialized_fields->Add(&field); |
1811 } | 1811 } |
1812 intptr_t field_pos = field.token_pos(); | 1812 intptr_t field_pos = field.token_pos(); |
1813 SetPosition(field_pos); | 1813 SetPosition(field_pos); |
1814 ASSERT(IsIdentifier()); | 1814 ASSERT(IsIdentifier()); |
1815 ConsumeToken(); | 1815 ConsumeToken(); |
(...skipping 1316 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3132 ErrorMsg(classname_pos, "missing class '%s' cannot be patched", | 3132 ErrorMsg(classname_pos, "missing class '%s' cannot be patched", |
3133 class_name.ToCString()); | 3133 class_name.ToCString()); |
3134 } | 3134 } |
3135 cls = Class::New(class_name, script_, classname_pos); | 3135 cls = Class::New(class_name, script_, classname_pos); |
3136 library_.AddClass(cls); | 3136 library_.AddClass(cls); |
3137 } else { | 3137 } else { |
3138 if (!obj.IsClass()) { | 3138 if (!obj.IsClass()) { |
3139 ErrorMsg(classname_pos, "'%s' is already defined", | 3139 ErrorMsg(classname_pos, "'%s' is already defined", |
3140 class_name.ToCString()); | 3140 class_name.ToCString()); |
3141 } | 3141 } |
3142 cls |= obj.raw(); | 3142 cls ^= obj.raw(); |
3143 if (is_patch) { | 3143 if (is_patch) { |
3144 String& patch = String::Handle( | 3144 String& patch = String::Handle( |
3145 String::Concat(Symbols::PatchSpace(), class_name)); | 3145 String::Concat(Symbols::PatchSpace(), class_name)); |
3146 patch = Symbols::New(patch); | 3146 patch = Symbols::New(patch); |
3147 cls = Class::New(patch, script_, classname_pos); | 3147 cls = Class::New(patch, script_, classname_pos); |
3148 cls.set_library(library_); | 3148 cls.set_library(library_); |
3149 } else { | 3149 } else { |
3150 // Not patching a class, but it has been found. This must be one of the | 3150 // Not patching a class, but it has been found. This must be one of the |
3151 // pre-registered classes from object.cc or a duplicate definition. | 3151 // pre-registered classes from object.cc or a duplicate definition. |
3152 if (cls.functions() != Object::empty_array().raw()) { | 3152 if (cls.functions() != Object::empty_array().raw()) { |
(...skipping 3954 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
7107 ASSERT((CurrentToken() == Token::kLPAREN) || | 7107 ASSERT((CurrentToken() == Token::kLPAREN) || |
7108 (CurrentToken() == Token::kCOMMA)); | 7108 (CurrentToken() == Token::kCOMMA)); |
7109 ConsumeToken(); | 7109 ConsumeToken(); |
7110 if (IsIdentifier() && (LookaheadToken(1) == Token::kCOLON)) { | 7110 if (IsIdentifier() && (LookaheadToken(1) == Token::kCOLON)) { |
7111 named_argument_seen = true; | 7111 named_argument_seen = true; |
7112 // The canonicalization of the arguments descriptor array built in | 7112 // The canonicalization of the arguments descriptor array built in |
7113 // the code generator requires that the names are symbols, i.e. | 7113 // the code generator requires that the names are symbols, i.e. |
7114 // canonicalized strings. | 7114 // canonicalized strings. |
7115 ASSERT(CurrentLiteral()->IsSymbol()); | 7115 ASSERT(CurrentLiteral()->IsSymbol()); |
7116 for (int i = 0; i < names.Length(); i++) { | 7116 for (int i = 0; i < names.Length(); i++) { |
7117 arg_name |= names.At(i); | 7117 arg_name ^= names.At(i); |
7118 if (CurrentLiteral()->Equals(arg_name)) { | 7118 if (CurrentLiteral()->Equals(arg_name)) { |
7119 ErrorMsg("duplicate named argument"); | 7119 ErrorMsg("duplicate named argument"); |
7120 } | 7120 } |
7121 } | 7121 } |
7122 names.Add(*CurrentLiteral()); | 7122 names.Add(*CurrentLiteral()); |
7123 ConsumeToken(); // ident. | 7123 ConsumeToken(); // ident. |
7124 ConsumeToken(); // colon. | 7124 ConsumeToken(); // colon. |
7125 } else if (named_argument_seen) { | 7125 } else if (named_argument_seen) { |
7126 ErrorMsg("named argument expected"); | 7126 ErrorMsg("named argument expected"); |
7127 } | 7127 } |
(...skipping 268 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
7396 selector = ParseInstanceCall(left, *ident); | 7396 selector = ParseInstanceCall(left, *ident); |
7397 } | 7397 } |
7398 } else { | 7398 } else { |
7399 // Field access. | 7399 // Field access. |
7400 Class& cls = Class::Handle(); | 7400 Class& cls = Class::Handle(); |
7401 if (left->IsPrimaryNode()) { | 7401 if (left->IsPrimaryNode()) { |
7402 PrimaryNode* primary_node = left->AsPrimaryNode(); | 7402 PrimaryNode* primary_node = left->AsPrimaryNode(); |
7403 if (primary_node->primary().IsClass()) { | 7403 if (primary_node->primary().IsClass()) { |
7404 // If the primary node referred to a class we are loading a | 7404 // If the primary node referred to a class we are loading a |
7405 // qualified static field. | 7405 // qualified static field. |
7406 cls |= primary_node->primary().raw(); | 7406 cls ^= primary_node->primary().raw(); |
7407 } | 7407 } |
7408 } | 7408 } |
7409 if (cls.IsNull()) { | 7409 if (cls.IsNull()) { |
7410 // Instance field access. | 7410 // Instance field access. |
7411 selector = CallGetter(ident_pos, left, *ident); | 7411 selector = CallGetter(ident_pos, left, *ident); |
7412 } else { | 7412 } else { |
7413 // Static field access. | 7413 // Static field access. |
7414 selector = | 7414 selector = |
7415 ParseStaticFieldAccess(cls, *ident, ident_pos, !is_cascade); | 7415 ParseStaticFieldAccess(cls, *ident, ident_pos, !is_cascade); |
7416 } | 7416 } |
(...skipping 712 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
8129 TRACE_PARSER("ResolveNameInCurrentLibraryScope"); | 8129 TRACE_PARSER("ResolveNameInCurrentLibraryScope"); |
8130 Object& obj = Object::Handle(LookupNameInLibrary(library_, name)); | 8130 Object& obj = Object::Handle(LookupNameInLibrary(library_, name)); |
8131 if (obj.IsNull()) { | 8131 if (obj.IsNull()) { |
8132 // Name is not found in current library. Check scope of all | 8132 // Name is not found in current library. Check scope of all |
8133 // imported libraries. | 8133 // imported libraries. |
8134 String& first_lib_url = String::Handle(); | 8134 String& first_lib_url = String::Handle(); |
8135 Namespace& import = Namespace::Handle(); | 8135 Namespace& import = Namespace::Handle(); |
8136 intptr_t num_imports = library_.num_imports(); | 8136 intptr_t num_imports = library_.num_imports(); |
8137 Object& imported_obj = Object::Handle(); | 8137 Object& imported_obj = Object::Handle(); |
8138 for (int i = 0; i < num_imports; i++) { | 8138 for (int i = 0; i < num_imports; i++) { |
8139 import |= library_.ImportAt(i); | 8139 import = library_.ImportAt(i); |
8140 imported_obj = LookupNameInImport(import, name); | 8140 imported_obj = LookupNameInImport(import, name); |
8141 if (!imported_obj.IsNull()) { | 8141 if (!imported_obj.IsNull()) { |
8142 const Library& lib = Library::Handle(import.library()); | 8142 const Library& lib = Library::Handle(import.library()); |
8143 if (!first_lib_url.IsNull()) { | 8143 if (!first_lib_url.IsNull()) { |
8144 // Found duplicate definition. | 8144 // Found duplicate definition. |
8145 Error& ambiguous_ref_error = Error::Handle(); | 8145 Error& ambiguous_ref_error = Error::Handle(); |
8146 if (first_lib_url.raw() == lib.url()) { | 8146 if (first_lib_url.raw() == lib.url()) { |
8147 ambiguous_ref_error = FormatErrorMsg( | 8147 ambiguous_ref_error = FormatErrorMsg( |
8148 script_, ident_pos, "Error", | 8148 script_, ident_pos, "Error", |
8149 "ambiguous reference: " | 8149 "ambiguous reference: " |
(...skipping 82 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
8232 const LibraryPrefix& prefix, | 8232 const LibraryPrefix& prefix, |
8233 const String& name, | 8233 const String& name, |
8234 Error* error) { | 8234 Error* error) { |
8235 TRACE_PARSER("ResolveNameInPrefixScope"); | 8235 TRACE_PARSER("ResolveNameInPrefixScope"); |
8236 Namespace& import = Namespace::Handle(); | 8236 Namespace& import = Namespace::Handle(); |
8237 String& first_lib_url = String::Handle(); | 8237 String& first_lib_url = String::Handle(); |
8238 Object& obj = Object::Handle(); | 8238 Object& obj = Object::Handle(); |
8239 Object& resolved_obj = Object::Handle(); | 8239 Object& resolved_obj = Object::Handle(); |
8240 const Array& imports = Array::Handle(prefix.imports()); | 8240 const Array& imports = Array::Handle(prefix.imports()); |
8241 for (intptr_t i = 0; i < prefix.num_imports(); i++) { | 8241 for (intptr_t i = 0; i < prefix.num_imports(); i++) { |
8242 import |= imports.At(i); | 8242 import ^= imports.At(i); |
8243 resolved_obj = LookupNameInImport(import, name); | 8243 resolved_obj = LookupNameInImport(import, name); |
8244 if (!resolved_obj.IsNull()) { | 8244 if (!resolved_obj.IsNull()) { |
8245 obj = resolved_obj.raw(); | 8245 obj = resolved_obj.raw(); |
8246 const Library& lib = Library::Handle(import.library()); | 8246 const Library& lib = Library::Handle(import.library()); |
8247 if (first_lib_url.IsNull()) { | 8247 if (first_lib_url.IsNull()) { |
8248 first_lib_url = lib.url(); | 8248 first_lib_url = lib.url(); |
8249 } else { | 8249 } else { |
8250 // Found duplicate definition. | 8250 // Found duplicate definition. |
8251 Error& ambiguous_ref_error = Error::Handle(); | 8251 Error& ambiguous_ref_error = Error::Handle(); |
8252 if (first_lib_url.raw() == lib.url()) { | 8252 if (first_lib_url.raw() == lib.url()) { |
(...skipping 866 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
9119 ASSERT(values->ElementAt(i)->IsLiteralNode()); | 9119 ASSERT(values->ElementAt(i)->IsLiteralNode()); |
9120 value_arr.SetAt(i, values->ElementAt(i)->AsLiteralNode()->literal()); | 9120 value_arr.SetAt(i, values->ElementAt(i)->AsLiteralNode()->literal()); |
9121 } | 9121 } |
9122 | 9122 |
9123 // Build argument array to pass to the interpolation function. | 9123 // Build argument array to pass to the interpolation function. |
9124 const Array& interpolate_arg = Array::Handle(Array::New(1)); | 9124 const Array& interpolate_arg = Array::Handle(Array::New(1)); |
9125 interpolate_arg.SetAt(0, value_arr); | 9125 interpolate_arg.SetAt(0, value_arr); |
9126 | 9126 |
9127 // Call interpolation function. | 9127 // Call interpolation function. |
9128 String& concatenated = String::ZoneHandle(); | 9128 String& concatenated = String::ZoneHandle(); |
9129 concatenated |= DartEntry::InvokeStatic(func, interpolate_arg); | 9129 concatenated ^= DartEntry::InvokeStatic(func, interpolate_arg); |
9130 if (concatenated.IsUnhandledException()) { | 9130 if (concatenated.IsUnhandledException()) { |
9131 ErrorMsg("Exception thrown in Parser::Interpolate"); | 9131 ErrorMsg("Exception thrown in Parser::Interpolate"); |
9132 } | 9132 } |
9133 concatenated = Symbols::New(concatenated); | 9133 concatenated = Symbols::New(concatenated); |
9134 return concatenated; | 9134 return concatenated; |
9135 } | 9135 } |
9136 | 9136 |
9137 | 9137 |
9138 // A string literal consists of the concatenation of the next n tokens | 9138 // A string literal consists of the concatenation of the next n tokens |
9139 // that satisfy the EBNF grammar: | 9139 // that satisfy the EBNF grammar: |
(...skipping 557 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
9697 void Parser::SkipQualIdent() { | 9697 void Parser::SkipQualIdent() { |
9698 ASSERT(IsIdentifier()); | 9698 ASSERT(IsIdentifier()); |
9699 ConsumeToken(); | 9699 ConsumeToken(); |
9700 if (CurrentToken() == Token::kPERIOD) { | 9700 if (CurrentToken() == Token::kPERIOD) { |
9701 ConsumeToken(); // Consume the kPERIOD token. | 9701 ConsumeToken(); // Consume the kPERIOD token. |
9702 ExpectIdentifier("identifier expected after '.'"); | 9702 ExpectIdentifier("identifier expected after '.'"); |
9703 } | 9703 } |
9704 } | 9704 } |
9705 | 9705 |
9706 } // namespace dart | 9706 } // namespace dart |
OLD | NEW |