| 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 "vm/bigint_operations.h" | 8 #include "vm/bigint_operations.h" |
| 9 #include "vm/class_finalizer.h" | 9 #include "vm/class_finalizer.h" |
| 10 #include "vm/compiler.h" | 10 #include "vm/compiler.h" |
| (...skipping 969 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 980 | 980 |
| 981 // Build local scope for function and populate with the formal parameters. | 981 // Build local scope for function and populate with the formal parameters. |
| 982 OpenFunctionBlock(func); | 982 OpenFunctionBlock(func); |
| 983 AddFormalParamsToScope(¶ms, current_block_->scope); | 983 AddFormalParamsToScope(¶ms, current_block_->scope); |
| 984 | 984 |
| 985 LoadLocalNode* receiver = | 985 LoadLocalNode* receiver = |
| 986 new LoadLocalNode(ident_pos, current_block_->scope->VariableAt(0)); | 986 new LoadLocalNode(ident_pos, current_block_->scope->VariableAt(0)); |
| 987 LoadLocalNode* value = | 987 LoadLocalNode* value = |
| 988 new LoadLocalNode(ident_pos, current_block_->scope->VariableAt(1)); | 988 new LoadLocalNode(ident_pos, current_block_->scope->VariableAt(1)); |
| 989 | 989 |
| 990 EnsureExpressionTemp(); |
| 990 StoreInstanceFieldNode* store_field = | 991 StoreInstanceFieldNode* store_field = |
| 991 new StoreInstanceFieldNode(ident_pos, receiver, field, value); | 992 new StoreInstanceFieldNode(ident_pos, receiver, field, value); |
| 992 | |
| 993 current_block_->statements->Add(store_field); | 993 current_block_->statements->Add(store_field); |
| 994 current_block_->statements->Add(new ReturnNode(ident_pos)); | 994 current_block_->statements->Add(new ReturnNode(ident_pos)); |
| 995 return CloseBlock(); | 995 return CloseBlock(); |
| 996 } | 996 } |
| 997 | 997 |
| 998 | 998 |
| 999 SequenceNode* Parser::ParseMethodExtractor(const Function& func) { | 999 SequenceNode* Parser::ParseMethodExtractor(const Function& func) { |
| 1000 TRACE_PARSER("ParseMethodExtractor"); | 1000 TRACE_PARSER("ParseMethodExtractor"); |
| 1001 ParamList params; | 1001 ParamList params; |
| 1002 | 1002 |
| (...skipping 781 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1784 } | 1784 } |
| 1785 receiver->set_invisible(false); | 1785 receiver->set_invisible(false); |
| 1786 SetAllowFunctionLiterals(saved_mode); | 1786 SetAllowFunctionLiterals(saved_mode); |
| 1787 Field& field = Field::ZoneHandle(cls.LookupInstanceField(field_name)); | 1787 Field& field = Field::ZoneHandle(cls.LookupInstanceField(field_name)); |
| 1788 if (field.IsNull()) { | 1788 if (field.IsNull()) { |
| 1789 ErrorMsg(field_pos, "unresolved reference to instance field '%s'", | 1789 ErrorMsg(field_pos, "unresolved reference to instance field '%s'", |
| 1790 field_name.ToCString()); | 1790 field_name.ToCString()); |
| 1791 } | 1791 } |
| 1792 CheckDuplicateFieldInit(field_pos, initialized_fields, &field); | 1792 CheckDuplicateFieldInit(field_pos, initialized_fields, &field); |
| 1793 AstNode* instance = new LoadLocalNode(field_pos, receiver); | 1793 AstNode* instance = new LoadLocalNode(field_pos, receiver); |
| 1794 EnsureExpressionTemp(); |
| 1794 return new StoreInstanceFieldNode(field_pos, instance, field, init_expr); | 1795 return new StoreInstanceFieldNode(field_pos, instance, field, init_expr); |
| 1795 } | 1796 } |
| 1796 | 1797 |
| 1797 | 1798 |
| 1798 void Parser::CheckConstFieldsInitialized(const Class& cls) { | 1799 void Parser::CheckConstFieldsInitialized(const Class& cls) { |
| 1799 const Array& fields = Array::Handle(cls.fields()); | 1800 const Array& fields = Array::Handle(cls.fields()); |
| 1800 Field& field = Field::Handle(); | 1801 Field& field = Field::Handle(); |
| 1801 SequenceNode* initializers = current_block_->statements; | 1802 SequenceNode* initializers = current_block_->statements; |
| 1802 for (int field_num = 0; field_num < fields.Length(); field_num++) { | 1803 for (int field_num = 0; field_num < fields.Length(); field_num++) { |
| 1803 field ^= fields.At(field_num); | 1804 field ^= fields.At(field_num); |
| 1804 if (field.is_static() || !field.is_final()) { | 1805 if (field.is_static()) { |
| 1805 continue; | 1806 continue; |
| 1806 } | 1807 } |
| 1808 |
| 1807 bool found = false; | 1809 bool found = false; |
| 1808 for (int i = 0; i < initializers->length(); i++) { | 1810 for (int i = 0; i < initializers->length(); i++) { |
| 1809 found = false; | 1811 found = false; |
| 1810 if (initializers->NodeAt(i)->IsStoreInstanceFieldNode()) { | 1812 if (initializers->NodeAt(i)->IsStoreInstanceFieldNode()) { |
| 1811 StoreInstanceFieldNode* initializer = | 1813 StoreInstanceFieldNode* initializer = |
| 1812 initializers->NodeAt(i)->AsStoreInstanceFieldNode(); | 1814 initializers->NodeAt(i)->AsStoreInstanceFieldNode(); |
| 1813 if (initializer->field().raw() == field.raw()) { | 1815 if (initializer->field().raw() == field.raw()) { |
| 1814 found = true; | 1816 found = true; |
| 1815 break; | 1817 break; |
| 1816 } | 1818 } |
| 1817 } | 1819 } |
| 1818 } | 1820 } |
| 1819 if (!found) { | 1821 |
| 1822 if (found) continue; |
| 1823 |
| 1824 if (field.is_final()) { |
| 1820 ErrorMsg("final field '%s' not initialized", | 1825 ErrorMsg("final field '%s' not initialized", |
| 1821 String::Handle(field.name()).ToCString()); | 1826 String::Handle(field.name()).ToCString()); |
| 1827 } else { |
| 1828 field.UpdateCid(kNullCid); |
| 1822 } | 1829 } |
| 1823 } | 1830 } |
| 1824 } | 1831 } |
| 1825 | 1832 |
| 1826 | 1833 |
| 1827 void Parser::ParseInitializedInstanceFields(const Class& cls, | 1834 void Parser::ParseInitializedInstanceFields(const Class& cls, |
| 1828 LocalVariable* receiver, | 1835 LocalVariable* receiver, |
| 1829 GrowableArray<Field*>* initialized_fields) { | 1836 GrowableArray<Field*>* initialized_fields) { |
| 1830 TRACE_PARSER("ParseInitializedInstanceFields"); | 1837 TRACE_PARSER("ParseInitializedInstanceFields"); |
| 1831 const Array& fields = Array::Handle(cls.fields()); | 1838 const Array& fields = Array::Handle(cls.fields()); |
| (...skipping 27 matching lines...) Expand all Loading... |
| 1859 if (field.is_const()) { | 1866 if (field.is_const()) { |
| 1860 init_expr = ParseConstExpr(); | 1867 init_expr = ParseConstExpr(); |
| 1861 } else { | 1868 } else { |
| 1862 init_expr = ParseExpr(kAllowConst, kConsumeCascades); | 1869 init_expr = ParseExpr(kAllowConst, kConsumeCascades); |
| 1863 if (init_expr->EvalConstExpr() != NULL) { | 1870 if (init_expr->EvalConstExpr() != NULL) { |
| 1864 init_expr = new LiteralNode(field_pos, EvaluateConstExpr(init_expr)); | 1871 init_expr = new LiteralNode(field_pos, EvaluateConstExpr(init_expr)); |
| 1865 } | 1872 } |
| 1866 } | 1873 } |
| 1867 ASSERT(init_expr != NULL); | 1874 ASSERT(init_expr != NULL); |
| 1868 AstNode* instance = new LoadLocalNode(field.token_pos(), receiver); | 1875 AstNode* instance = new LoadLocalNode(field.token_pos(), receiver); |
| 1876 EnsureExpressionTemp(); |
| 1869 AstNode* field_init = | 1877 AstNode* field_init = |
| 1870 new StoreInstanceFieldNode(field.token_pos(), | 1878 new StoreInstanceFieldNode(field.token_pos(), |
| 1871 instance, | 1879 instance, |
| 1872 field, | 1880 field, |
| 1873 init_expr); | 1881 init_expr); |
| 1874 current_block_->statements->Add(field_init); | 1882 current_block_->statements->Add(field_init); |
| 1875 } | 1883 } |
| 1876 } | 1884 } |
| 1877 SetPosition(saved_pos); | 1885 SetPosition(saved_pos); |
| 1878 } | 1886 } |
| (...skipping 232 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2111 CheckDuplicateFieldInit(param.name_pos, &initialized_fields, &field); | 2119 CheckDuplicateFieldInit(param.name_pos, &initialized_fields, &field); |
| 2112 AstNode* instance = new LoadLocalNode(param.name_pos, receiver); | 2120 AstNode* instance = new LoadLocalNode(param.name_pos, receiver); |
| 2113 LocalVariable* p = | 2121 LocalVariable* p = |
| 2114 current_block_->scope->LookupVariable(*param.name, false); | 2122 current_block_->scope->LookupVariable(*param.name, false); |
| 2115 ASSERT(p != NULL); | 2123 ASSERT(p != NULL); |
| 2116 // Initializing formals cannot be used in the explicit initializer | 2124 // Initializing formals cannot be used in the explicit initializer |
| 2117 // list, nor can they be used in the constructor body. | 2125 // list, nor can they be used in the constructor body. |
| 2118 // Thus, make the parameter invisible. | 2126 // Thus, make the parameter invisible. |
| 2119 p->set_invisible(true); | 2127 p->set_invisible(true); |
| 2120 AstNode* value = new LoadLocalNode(param.name_pos, p); | 2128 AstNode* value = new LoadLocalNode(param.name_pos, p); |
| 2129 EnsureExpressionTemp(); |
| 2121 AstNode* initializer = new StoreInstanceFieldNode( | 2130 AstNode* initializer = new StoreInstanceFieldNode( |
| 2122 param.name_pos, instance, field, value); | 2131 param.name_pos, instance, field, value); |
| 2123 current_block_->statements->Add(initializer); | 2132 current_block_->statements->Add(initializer); |
| 2124 } | 2133 } |
| 2125 } | 2134 } |
| 2126 } | 2135 } |
| 2127 | 2136 |
| 2128 // Now parse the explicit initializer list or constructor redirection. | 2137 // Now parse the explicit initializer list or constructor redirection. |
| 2129 ParseInitializers(cls, receiver, &initialized_fields); | 2138 ParseInitializers(cls, receiver, &initialized_fields); |
| 2130 | 2139 |
| (...skipping 7938 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 10069 void Parser::SkipQualIdent() { | 10078 void Parser::SkipQualIdent() { |
| 10070 ASSERT(IsIdentifier()); | 10079 ASSERT(IsIdentifier()); |
| 10071 ConsumeToken(); | 10080 ConsumeToken(); |
| 10072 if (CurrentToken() == Token::kPERIOD) { | 10081 if (CurrentToken() == Token::kPERIOD) { |
| 10073 ConsumeToken(); // Consume the kPERIOD token. | 10082 ConsumeToken(); // Consume the kPERIOD token. |
| 10074 ExpectIdentifier("identifier expected after '.'"); | 10083 ExpectIdentifier("identifier expected after '.'"); |
| 10075 } | 10084 } |
| 10076 } | 10085 } |
| 10077 | 10086 |
| 10078 } // namespace dart | 10087 } // namespace dart |
| OLD | NEW |