Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(444)

Side by Side Diff: runtime/vm/parser.cc

Issue 12827007: Support initialized mixin fields across scripts (Closed) Base URL: http://dart.googlecode.com/svn/branches/bleeding_edge/dart/
Patch Set: Created 7 years, 9 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « runtime/vm/parser.h ('k') | tests/language/language.status » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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 243 matching lines...) Expand 10 before | Expand all | Expand 10 after
254 }; 254 };
255 255
256 256
257 void Parser::TryBlocks::AddNodeForFinallyInlining(AstNode* node) { 257 void Parser::TryBlocks::AddNodeForFinallyInlining(AstNode* node) {
258 inlined_finally_nodes_.Add(node); 258 inlined_finally_nodes_.Add(node);
259 } 259 }
260 260
261 261
262 // For parsing a compilation unit. 262 // For parsing a compilation unit.
263 Parser::Parser(const Script& script, const Library& library) 263 Parser::Parser(const Script& script, const Library& library)
264 : script_(script), 264 : script_(Script::Handle(script.raw())),
265 tokens_iterator_(TokenStream::Handle(script.tokens()), 0), 265 tokens_iterator_(TokenStream::Handle(script.tokens()), 0),
266 token_kind_(Token::kILLEGAL), 266 token_kind_(Token::kILLEGAL),
267 current_block_(NULL), 267 current_block_(NULL),
268 is_top_level_(false), 268 is_top_level_(false),
269 current_member_(NULL), 269 current_member_(NULL),
270 allow_function_literals_(true), 270 allow_function_literals_(true),
271 parsed_function_(NULL), 271 parsed_function_(NULL),
272 innermost_function_(Function::Handle()), 272 innermost_function_(Function::Handle()),
273 current_class_(Class::Handle()), 273 current_class_(Class::Handle()),
274 library_(library), 274 library_(Library::Handle(library.raw())),
275 try_blocks_list_(NULL) { 275 try_blocks_list_(NULL) {
276 ASSERT(tokens_iterator_.IsValid()); 276 ASSERT(tokens_iterator_.IsValid());
277 ASSERT(!library.IsNull()); 277 ASSERT(!library.IsNull());
278 } 278 }
279 279
280 280
281 // For parsing a function. 281 // For parsing a function.
282 Parser::Parser(const Script& script, 282 Parser::Parser(const Script& script,
283 ParsedFunction* parsed_function, 283 ParsedFunction* parsed_function,
284 intptr_t token_position) 284 intptr_t token_position)
285 : script_(script), 285 : script_(Script::Handle(script.raw())),
286 tokens_iterator_(TokenStream::Handle(script.tokens()), token_position), 286 tokens_iterator_(TokenStream::Handle(script.tokens()), token_position),
287 token_kind_(Token::kILLEGAL), 287 token_kind_(Token::kILLEGAL),
288 current_block_(NULL), 288 current_block_(NULL),
289 is_top_level_(false), 289 is_top_level_(false),
290 current_member_(NULL), 290 current_member_(NULL),
291 allow_function_literals_(true), 291 allow_function_literals_(true),
292 parsed_function_(parsed_function), 292 parsed_function_(parsed_function),
293 innermost_function_(Function::Handle(parsed_function->function().raw())), 293 innermost_function_(Function::Handle(parsed_function->function().raw())),
294 current_class_(Class::Handle(parsed_function->function().Owner())), 294 current_class_(Class::Handle(parsed_function->function().Owner())),
295 library_(Library::Handle(Class::Handle( 295 library_(Library::Handle(Class::Handle(
296 parsed_function->function().origin()).library())), 296 parsed_function->function().origin()).library())),
297 try_blocks_list_(NULL) { 297 try_blocks_list_(NULL) {
298 ASSERT(tokens_iterator_.IsValid()); 298 ASSERT(tokens_iterator_.IsValid());
299 ASSERT(!current_function().IsNull()); 299 ASSERT(!current_function().IsNull());
300 if (FLAG_enable_type_checks) { 300 if (FLAG_enable_type_checks) {
301 EnsureExpressionTemp(); 301 EnsureExpressionTemp();
302 } 302 }
303 } 303 }
304 304
305 305
306 void Parser::SetScript(const Script & script, intptr_t token_pos) {
307 script_ = script.raw();
308 tokens_iterator_.SetStream(TokenStream::Handle(script.tokens()), token_pos);
309 token_kind_ = Token::kILLEGAL;
310 }
311
312
306 bool Parser::SetAllowFunctionLiterals(bool value) { 313 bool Parser::SetAllowFunctionLiterals(bool value) {
307 bool current_value = allow_function_literals_; 314 bool current_value = allow_function_literals_;
308 allow_function_literals_ = value; 315 allow_function_literals_ = value;
309 return current_value; 316 return current_value;
310 } 317 }
311 318
312 319
313 const Function& Parser::current_function() const { 320 const Function& Parser::current_function() const {
314 ASSERT(parsed_function() != NULL); 321 ASSERT(parsed_function() != NULL);
315 return parsed_function()->function(); 322 return parsed_function()->function();
(...skipping 1508 matching lines...) Expand 10 before | Expand all | Expand 10 after
1824 if (field.is_final()) { 1831 if (field.is_final()) {
1825 ErrorMsg("final field '%s' not initialized", 1832 ErrorMsg("final field '%s' not initialized",
1826 String::Handle(field.name()).ToCString()); 1833 String::Handle(field.name()).ToCString());
1827 } else { 1834 } else {
1828 field.UpdateCid(kNullCid); 1835 field.UpdateCid(kNullCid);
1829 } 1836 }
1830 } 1837 }
1831 } 1838 }
1832 1839
1833 1840
1841 AstNode* Parser::ParseExternalInitializedField(const Field& field) {
1842 // Only use this function if the initialized field originates
1843 // from a different class. We need to save and restore current
1844 // class, library, and token stream (script).
1845 ASSERT(current_class().raw() != field.origin());
1846 const Class& saved_class = Class::Handle(current_class().raw());
1847 const Library& saved_library = Library::Handle(library().raw());
1848 const Script& saved_script = Script::Handle(script().raw());
1849 const intptr_t saved_token_pos = TokenPos();
1850
1851 set_current_class(Class::Handle(field.origin()));
1852 set_library(Library::Handle(current_class().library()));
1853 SetScript(Script::Handle(current_class().script()), field.token_pos());
1854
1855 ASSERT(IsIdentifier());
1856 ConsumeToken();
1857 ExpectToken(Token::kASSIGN);
1858 AstNode* init_expr = NULL;
1859 if (field.is_const()) {
1860 init_expr = ParseConstExpr();
1861 } else {
1862 init_expr = ParseExpr(kAllowConst, kConsumeCascades);
1863 if (init_expr->EvalConstExpr() != NULL) {
1864 init_expr =
1865 new LiteralNode(field.token_pos(), EvaluateConstExpr(init_expr));
1866 }
1867 }
1868 set_current_class(saved_class);
1869 set_library(saved_library);
1870 SetScript(saved_script, saved_token_pos);
1871 return init_expr;
1872 }
1873
1874
1834 void Parser::ParseInitializedInstanceFields(const Class& cls, 1875 void Parser::ParseInitializedInstanceFields(const Class& cls,
1835 LocalVariable* receiver, 1876 LocalVariable* receiver,
1836 GrowableArray<Field*>* initialized_fields) { 1877 GrowableArray<Field*>* initialized_fields) {
1837 TRACE_PARSER("ParseInitializedInstanceFields"); 1878 TRACE_PARSER("ParseInitializedInstanceFields");
1838 const Array& fields = Array::Handle(cls.fields()); 1879 const Array& fields = Array::Handle(cls.fields());
1839 Field& f = Field::Handle(); 1880 Field& f = Field::Handle();
1840 const intptr_t saved_pos = TokenPos(); 1881 const intptr_t saved_pos = TokenPos();
1841 for (int i = 0; i < fields.Length(); i++) { 1882 for (int i = 0; i < fields.Length(); i++) {
1842 f ^= fields.At(i); 1883 f ^= fields.At(i);
1843 if (!f.is_static() && f.has_initializer()) { 1884 if (!f.is_static() && f.has_initializer()) {
1844 Field& field = Field::ZoneHandle(); 1885 Field& field = Field::ZoneHandle();
1845 field ^= fields.At(i); 1886 field ^= fields.At(i);
1846 if (field.is_final()) { 1887 if (field.is_final()) {
1847 // Final fields with initializer expression may not be initialized 1888 // Final fields with initializer expression may not be initialized
1848 // again by constructors. Remember that this field is already 1889 // again by constructors. Remember that this field is already
1849 // initialized. 1890 // initialized.
1850 initialized_fields->Add(&field); 1891 initialized_fields->Add(&field);
1851 } 1892 }
1852 intptr_t field_pos = field.token_pos(); 1893 AstNode* init_expr = NULL;
1853 if (current_class().raw() != field.origin()) { 1894 if (current_class().raw() != field.origin()) {
1854 const Class& origin_class = Class::Handle(field.origin()); 1895 init_expr = ParseExternalInitializedField(field);
1855 if (origin_class.library() != library_.raw()) {
1856 ErrorMsg("Cannot handle initialized mixin field '%s'"
1857 "from imported library\n", field.ToCString());
1858 }
1859 }
1860 SetPosition(field_pos);
1861 ASSERT(IsIdentifier());
1862 ConsumeToken();
1863 ExpectToken(Token::kASSIGN);
1864
1865 AstNode* init_expr = NULL;
1866 if (field.is_const()) {
1867 init_expr = ParseConstExpr();
1868 } else { 1896 } else {
1869 init_expr = ParseExpr(kAllowConst, kConsumeCascades); 1897 SetPosition(field.token_pos());
1870 if (init_expr->EvalConstExpr() != NULL) { 1898 ASSERT(IsIdentifier());
1871 init_expr = new LiteralNode(field_pos, EvaluateConstExpr(init_expr)); 1899 ConsumeToken();
1900 ExpectToken(Token::kASSIGN);
1901 if (field.is_const()) {
1902 init_expr = ParseConstExpr();
1903 } else {
1904 init_expr = ParseExpr(kAllowConst, kConsumeCascades);
1905 if (init_expr->EvalConstExpr() != NULL) {
1906 init_expr = new LiteralNode(field.token_pos(),
1907 EvaluateConstExpr(init_expr));
1908 }
1872 } 1909 }
1873 } 1910 }
1874 ASSERT(init_expr != NULL); 1911 ASSERT(init_expr != NULL);
1875 AstNode* instance = new LoadLocalNode(field.token_pos(), receiver); 1912 AstNode* instance = new LoadLocalNode(field.token_pos(), receiver);
1876 EnsureExpressionTemp(); 1913 EnsureExpressionTemp();
1877 AstNode* field_init = 1914 AstNode* field_init =
1878 new StoreInstanceFieldNode(field.token_pos(), 1915 new StoreInstanceFieldNode(field.token_pos(),
1879 instance, 1916 instance,
1880 field, 1917 field,
1881 init_expr); 1918 init_expr);
(...skipping 8110 matching lines...) Expand 10 before | Expand all | Expand 10 after
9992 void Parser::SkipQualIdent() { 10029 void Parser::SkipQualIdent() {
9993 ASSERT(IsIdentifier()); 10030 ASSERT(IsIdentifier());
9994 ConsumeToken(); 10031 ConsumeToken();
9995 if (CurrentToken() == Token::kPERIOD) { 10032 if (CurrentToken() == Token::kPERIOD) {
9996 ConsumeToken(); // Consume the kPERIOD token. 10033 ConsumeToken(); // Consume the kPERIOD token.
9997 ExpectIdentifier("identifier expected after '.'"); 10034 ExpectIdentifier("identifier expected after '.'");
9998 } 10035 }
9999 } 10036 }
10000 10037
10001 } // namespace dart 10038 } // namespace dart
OLDNEW
« no previous file with comments | « runtime/vm/parser.h ('k') | tests/language/language.status » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698