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

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 set_current_class(Class::Handle(field.origin()));
1848
1849 const Library& saved_library = Library::Handle(library().raw());
1850 set_library(Library::Handle(current_class().library()));
1851
1852 intptr_t saved_token_pos = TokenPos();
1853 const Script& saved_script = Script::Handle(script().raw());
1854 SetScript(Script::Handle(current_class().script()), field.token_pos());
siva 2013/03/22 16:47:56 It would probably be much more readable if you clu
hausner 2013/03/22 17:11:06 Done.
1855
1856 ASSERT(IsIdentifier());
1857 ConsumeToken();
1858 ExpectToken(Token::kASSIGN);
1859 AstNode* init_expr = NULL;
1860 if (field.is_const()) {
1861 init_expr = ParseConstExpr();
1862 } else {
1863 init_expr = ParseExpr(kAllowConst, kConsumeCascades);
1864 if (init_expr->EvalConstExpr() != NULL) {
1865 init_expr =
1866 new LiteralNode(field.token_pos(), EvaluateConstExpr(init_expr));
1867 }
1868 }
1869 set_current_class(saved_class);
1870 set_library(saved_library);
1871 SetScript(saved_script, saved_token_pos);
1872 return init_expr;
1873 }
1874
1875
1834 void Parser::ParseInitializedInstanceFields(const Class& cls, 1876 void Parser::ParseInitializedInstanceFields(const Class& cls,
1835 LocalVariable* receiver, 1877 LocalVariable* receiver,
1836 GrowableArray<Field*>* initialized_fields) { 1878 GrowableArray<Field*>* initialized_fields) {
1837 TRACE_PARSER("ParseInitializedInstanceFields"); 1879 TRACE_PARSER("ParseInitializedInstanceFields");
1838 const Array& fields = Array::Handle(cls.fields()); 1880 const Array& fields = Array::Handle(cls.fields());
1839 Field& f = Field::Handle(); 1881 Field& f = Field::Handle();
1840 const intptr_t saved_pos = TokenPos(); 1882 const intptr_t saved_pos = TokenPos();
1841 for (int i = 0; i < fields.Length(); i++) { 1883 for (int i = 0; i < fields.Length(); i++) {
1842 f ^= fields.At(i); 1884 f ^= fields.At(i);
1843 if (!f.is_static() && f.has_initializer()) { 1885 if (!f.is_static() && f.has_initializer()) {
1844 Field& field = Field::ZoneHandle(); 1886 Field& field = Field::ZoneHandle();
1845 field ^= fields.At(i); 1887 field ^= fields.At(i);
1846 if (field.is_final()) { 1888 if (field.is_final()) {
1847 // Final fields with initializer expression may not be initialized 1889 // Final fields with initializer expression may not be initialized
1848 // again by constructors. Remember that this field is already 1890 // again by constructors. Remember that this field is already
1849 // initialized. 1891 // initialized.
1850 initialized_fields->Add(&field); 1892 initialized_fields->Add(&field);
1851 } 1893 }
1852 intptr_t field_pos = field.token_pos(); 1894 AstNode* init_expr = NULL;
1853 if (current_class().raw() != field.origin()) { 1895 if (current_class().raw() != field.origin()) {
1854 const Class& origin_class = Class::Handle(field.origin()); 1896 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 { 1897 } else {
1869 init_expr = ParseExpr(kAllowConst, kConsumeCascades); 1898 SetPosition(field.token_pos());
1870 if (init_expr->EvalConstExpr() != NULL) { 1899 ASSERT(IsIdentifier());
1871 init_expr = new LiteralNode(field_pos, EvaluateConstExpr(init_expr)); 1900 ConsumeToken();
1901 ExpectToken(Token::kASSIGN);
1902 if (field.is_const()) {
1903 init_expr = ParseConstExpr();
1904 } else {
1905 init_expr = ParseExpr(kAllowConst, kConsumeCascades);
1906 if (init_expr->EvalConstExpr() != NULL) {
1907 init_expr = new LiteralNode(field.token_pos(),
1908 EvaluateConstExpr(init_expr));
1909 }
1872 } 1910 }
1873 } 1911 }
1874 ASSERT(init_expr != NULL); 1912 ASSERT(init_expr != NULL);
1875 AstNode* instance = new LoadLocalNode(field.token_pos(), receiver); 1913 AstNode* instance = new LoadLocalNode(field.token_pos(), receiver);
1876 EnsureExpressionTemp(); 1914 EnsureExpressionTemp();
1877 AstNode* field_init = 1915 AstNode* field_init =
1878 new StoreInstanceFieldNode(field.token_pos(), 1916 new StoreInstanceFieldNode(field.token_pos(),
1879 instance, 1917 instance,
1880 field, 1918 field,
1881 init_expr); 1919 init_expr);
(...skipping 8110 matching lines...) Expand 10 before | Expand all | Expand 10 after
9992 void Parser::SkipQualIdent() { 10030 void Parser::SkipQualIdent() {
9993 ASSERT(IsIdentifier()); 10031 ASSERT(IsIdentifier());
9994 ConsumeToken(); 10032 ConsumeToken();
9995 if (CurrentToken() == Token::kPERIOD) { 10033 if (CurrentToken() == Token::kPERIOD) {
9996 ConsumeToken(); // Consume the kPERIOD token. 10034 ConsumeToken(); // Consume the kPERIOD token.
9997 ExpectIdentifier("identifier expected after '.'"); 10035 ExpectIdentifier("identifier expected after '.'");
9998 } 10036 }
9999 } 10037 }
10000 10038
10001 } // namespace dart 10039 } // 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