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 41 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
52 static const char* kInterpolateName = "_interpolate"; | 52 static const char* kInterpolateName = "_interpolate"; |
53 static const char* kThisName = "this"; | 53 static const char* kThisName = "this"; |
54 static const char* kPhaseParameterName = ":phase"; | 54 static const char* kPhaseParameterName = ":phase"; |
55 static const char* kGetIteratorName = "iterator"; | 55 static const char* kGetIteratorName = "iterator"; |
56 static const char* kNoSuchMethodName = "noSuchMethod"; | 56 static const char* kNoSuchMethodName = "noSuchMethod"; |
57 | 57 |
58 #if defined(DEBUG) | 58 #if defined(DEBUG) |
59 | 59 |
60 class TraceParser : public ValueObject { | 60 class TraceParser : public ValueObject { |
61 public: | 61 public: |
62 TraceParser(intptr_t token_index, const Script& script, const char* msg) { | 62 TraceParser(intptr_t token_pos, const Script& script, const char* msg) { |
63 if (FLAG_trace_parser) { | 63 if (FLAG_trace_parser) { |
64 intptr_t line, column; | 64 intptr_t line, column; |
65 script.GetTokenLocation(token_index, &line, &column); | 65 script.GetTokenLocation(token_pos, &line, &column); |
66 PrintIndent(); | 66 PrintIndent(); |
67 OS::Print("%s (line %d, col %d, token %d)\n", | 67 OS::Print("%s (line %d, col %d, token %d)\n", |
68 msg, line, column, token_index); | 68 msg, line, column, token_pos); |
69 indent_++; | 69 indent_++; |
70 } | 70 } |
71 } | 71 } |
72 ~TraceParser() { indent_--; } | 72 ~TraceParser() { indent_--; } |
73 private: | 73 private: |
74 void PrintIndent() { | 74 void PrintIndent() { |
75 for (int i = 0; i < indent_; i++) { OS::Print(". "); } | 75 for (int i = 0; i < indent_; i++) { OS::Print(". "); } |
76 } | 76 } |
77 static int indent_; | 77 static int indent_; |
78 }; | 78 }; |
79 | 79 |
80 int TraceParser::indent_ = 0; | 80 int TraceParser::indent_ = 0; |
81 | 81 |
82 #define TRACE_PARSER(s) \ | 82 #define TRACE_PARSER(s) \ |
83 TraceParser __p__(this->token_index_, this->script_, s) | 83 TraceParser __p__(this->TokenPos(), this->script_, s) |
84 | 84 |
85 #else // not DEBUG | 85 #else // not DEBUG |
86 #define TRACE_PARSER(s) | 86 #define TRACE_PARSER(s) |
87 #endif // DEBUG | 87 #endif // DEBUG |
88 | 88 |
89 | 89 |
90 static RawTypeArguments* NewTypeArguments(const GrowableObjectArray& objs) { | 90 static RawTypeArguments* NewTypeArguments(const GrowableObjectArray& objs) { |
91 const TypeArguments& a = | 91 const TypeArguments& a = |
92 TypeArguments::Handle(TypeArguments::New(objs.Length())); | 92 TypeArguments::Handle(TypeArguments::New(objs.Length())); |
93 AbstractType& type = AbstractType::Handle(); | 93 AbstractType& type = AbstractType::Handle(); |
(...skipping 11 matching lines...) Expand all Loading... |
105 UnhandledException& excp = UnhandledException::Handle(); | 105 UnhandledException& excp = UnhandledException::Handle(); |
106 excp ^= obj.raw(); | 106 excp ^= obj.raw(); |
107 const Instance& exception = Instance::ZoneHandle(excp.exception()); | 107 const Instance& exception = Instance::ZoneHandle(excp.exception()); |
108 const Instance& stack_trace = Instance::ZoneHandle(excp.stacktrace()); | 108 const Instance& stack_trace = Instance::ZoneHandle(excp.stacktrace()); |
109 return new ThrowNode(token_pos, | 109 return new ThrowNode(token_pos, |
110 new LiteralNode(token_pos, exception), | 110 new LiteralNode(token_pos, exception), |
111 new LiteralNode(token_pos, stack_trace)); | 111 new LiteralNode(token_pos, stack_trace)); |
112 } | 112 } |
113 | 113 |
114 | 114 |
115 LocalVariable* ParsedFunction::CreateExpressionTempVar(intptr_t token_index) { | 115 LocalVariable* ParsedFunction::CreateExpressionTempVar(intptr_t token_pos) { |
116 return new LocalVariable(token_index, | 116 return new LocalVariable(token_pos, |
117 String::ZoneHandle(String::NewSymbol(":expr_temp")), | 117 String::ZoneHandle(String::NewSymbol(":expr_temp")), |
118 Type::ZoneHandle(Type::DynamicType())); | 118 Type::ZoneHandle(Type::DynamicType())); |
119 } | 119 } |
120 | 120 |
121 | 121 |
122 void ParsedFunction::SetNodeSequence(SequenceNode* node_sequence) { | 122 void ParsedFunction::SetNodeSequence(SequenceNode* node_sequence) { |
123 ASSERT(node_sequence_ == NULL); | 123 ASSERT(node_sequence_ == NULL); |
124 ASSERT(node_sequence != NULL); | 124 ASSERT(node_sequence != NULL); |
125 node_sequence_ = node_sequence; | 125 node_sequence_ = node_sequence; |
126 const int num_fixed_params = function().num_fixed_parameters(); | 126 const int num_fixed_params = function().num_fixed_parameters(); |
(...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
175 scope, | 175 scope, |
176 &context_owner); | 176 &context_owner); |
177 | 177 |
178 // If this function is not a closure function and if it contains captured | 178 // If this function is not a closure function and if it contains captured |
179 // variables, the context needs to be saved on entry and restored on exit. | 179 // variables, the context needs to be saved on entry and restored on exit. |
180 // Add and allocate a local variable to this purpose. | 180 // Add and allocate a local variable to this purpose. |
181 if ((context_owner != NULL) && !function().IsClosureFunction()) { | 181 if ((context_owner != NULL) && !function().IsClosureFunction()) { |
182 const String& context_var_name = String::ZoneHandle( | 182 const String& context_var_name = String::ZoneHandle( |
183 String::NewSymbol(LocalVariable::kSavedContextVarName)); | 183 String::NewSymbol(LocalVariable::kSavedContextVarName)); |
184 LocalVariable* context_var = | 184 LocalVariable* context_var = |
185 new LocalVariable(function().token_index(), | 185 new LocalVariable(function().token_pos(), |
186 context_var_name, | 186 context_var_name, |
187 Type::ZoneHandle(Type::DynamicType())); | 187 Type::ZoneHandle(Type::DynamicType())); |
188 context_var->set_index(next_free_frame_index--); | 188 context_var->set_index(next_free_frame_index--); |
189 scope->AddVariable(context_var); | 189 scope->AddVariable(context_var); |
190 set_saved_context_var(context_var); | 190 set_saved_context_var(context_var); |
191 } | 191 } |
192 | 192 |
193 // Frame indices are relative to the frame pointer and are decreasing. | 193 // Frame indices are relative to the frame pointer and are decreasing. |
194 ASSERT(next_free_frame_index <= first_stack_local_index_); | 194 ASSERT(next_free_frame_index <= first_stack_local_index_); |
195 stack_local_count_ = first_stack_local_index_ - next_free_frame_index; | 195 stack_local_count_ = first_stack_local_index_ - next_free_frame_index; |
196 } | 196 } |
197 | 197 |
198 | 198 |
| 199 bool TokenStreamIterator::IsValid() const { |
| 200 return !tokens_.IsNull(); |
| 201 } |
| 202 |
| 203 |
| 204 Token::Kind TokenStreamIterator::CurrentTokenKind() const { |
| 205 return tokens_.KindAt(token_position_); |
| 206 } |
| 207 |
| 208 |
| 209 Token::Kind TokenStreamIterator::LookaheadTokenKind(intptr_t num_tokens) const { |
| 210 return tokens_.KindAt(token_position_ + num_tokens); |
| 211 } |
| 212 |
| 213 |
| 214 RawObject* TokenStreamIterator::CurrentToken() const { |
| 215 return tokens_.TokenAt(token_position_); |
| 216 } |
| 217 |
| 218 |
| 219 RawString* TokenStreamIterator::CurrentLiteral() const { |
| 220 return tokens_.LiteralAt(token_position_); |
| 221 } |
| 222 |
| 223 |
199 struct Parser::Block : public ZoneAllocated { | 224 struct Parser::Block : public ZoneAllocated { |
200 Block(Block* outer_block, LocalScope* local_scope, SequenceNode* seq) | 225 Block(Block* outer_block, LocalScope* local_scope, SequenceNode* seq) |
201 : parent(outer_block), scope(local_scope), statements(seq) { | 226 : parent(outer_block), scope(local_scope), statements(seq) { |
202 ASSERT(scope != NULL); | 227 ASSERT(scope != NULL); |
203 ASSERT(statements != NULL); | 228 ASSERT(statements != NULL); |
204 } | 229 } |
205 Block* parent; // Enclosing block, or NULL if outermost. | 230 Block* parent; // Enclosing block, or NULL if outermost. |
206 LocalScope* scope; | 231 LocalScope* scope; |
207 SequenceNode* statements; | 232 SequenceNode* statements; |
208 }; | 233 }; |
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
240 | 265 |
241 void Parser::TryBlocks::AddNodeForFinallyInlining(AstNode* node) { | 266 void Parser::TryBlocks::AddNodeForFinallyInlining(AstNode* node) { |
242 inlined_finally_nodes_.Add(node); | 267 inlined_finally_nodes_.Add(node); |
243 } | 268 } |
244 | 269 |
245 | 270 |
246 // For parsing a compilation unit. | 271 // For parsing a compilation unit. |
247 Parser::Parser(const Script& script, | 272 Parser::Parser(const Script& script, |
248 const Library& library) | 273 const Library& library) |
249 : script_(script), | 274 : script_(script), |
250 tokens_(TokenStream::Handle(script.tokens())), | 275 tokens_iterator_(TokenStream::Handle(script.tokens()), 0), |
251 token_index_(0), | 276 token_kind_(Token::kILLEGAL), |
252 current_block_(NULL), | 277 current_block_(NULL), |
253 is_top_level_(false), | 278 is_top_level_(false), |
254 current_member_(NULL), | 279 current_member_(NULL), |
255 allow_function_literals_(true), | 280 allow_function_literals_(true), |
256 current_function_(Function::Handle()), | 281 current_function_(Function::Handle()), |
257 current_class_(Class::Handle()), | 282 current_class_(Class::Handle()), |
258 library_(library), | 283 library_(library), |
259 try_blocks_list_(NULL), | 284 try_blocks_list_(NULL), |
260 expression_temp_(NULL) { | 285 expression_temp_(NULL) { |
261 ASSERT(!tokens_.IsNull()); | 286 ASSERT(tokens_iterator_.IsValid()); |
262 ASSERT(!library.IsNull()); | 287 ASSERT(!library.IsNull()); |
263 SetPosition(0); | |
264 } | 288 } |
265 | 289 |
266 | 290 |
267 // For parsing a function. | 291 // For parsing a function. |
268 Parser::Parser(const Script& script, | 292 Parser::Parser(const Script& script, |
269 const Function& function, | 293 const Function& function, |
270 intptr_t token_index) | 294 intptr_t token_position) |
271 : script_(script), | 295 : script_(script), |
272 tokens_(TokenStream::Handle(script.tokens())), | 296 tokens_iterator_(TokenStream::Handle(script.tokens()), token_position), |
273 token_index_(0), | 297 token_kind_(Token::kILLEGAL), |
274 current_block_(NULL), | 298 current_block_(NULL), |
275 is_top_level_(false), | 299 is_top_level_(false), |
276 current_member_(NULL), | 300 current_member_(NULL), |
277 allow_function_literals_(true), | 301 allow_function_literals_(true), |
278 current_function_(function), | 302 current_function_(function), |
279 current_class_(Class::Handle(current_function_.owner())), | 303 current_class_(Class::Handle(current_function_.owner())), |
280 library_(Library::Handle(current_class_.library())), | 304 library_(Library::Handle(current_class_.library())), |
281 try_blocks_list_(NULL), | 305 try_blocks_list_(NULL), |
282 expression_temp_(NULL) { | 306 expression_temp_(NULL) { |
283 ASSERT(!tokens_.IsNull()); | 307 ASSERT(tokens_iterator_.IsValid()); |
284 ASSERT(!function.IsNull()); | 308 ASSERT(!function.IsNull()); |
285 SetPosition(token_index); | |
286 if (FLAG_enable_type_checks) { | 309 if (FLAG_enable_type_checks) { |
287 EnsureExpressionTemp(); | 310 EnsureExpressionTemp(); |
288 } | 311 } |
289 } | 312 } |
290 | 313 |
291 | 314 |
292 bool Parser::SetAllowFunctionLiterals(bool value) { | 315 bool Parser::SetAllowFunctionLiterals(bool value) { |
293 bool current_value = allow_function_literals_; | 316 bool current_value = allow_function_literals_; |
294 allow_function_literals_ = value; | 317 allow_function_literals_ = value; |
295 return current_value; | 318 return current_value; |
296 } | 319 } |
297 | 320 |
298 | 321 |
299 const Function& Parser::current_function() const { | 322 const Function& Parser::current_function() const { |
300 return current_function_; | 323 return current_function_; |
301 } | 324 } |
302 | 325 |
303 | 326 |
304 const Class& Parser::current_class() const { | 327 const Class& Parser::current_class() const { |
305 return current_class_; | 328 return current_class_; |
306 } | 329 } |
307 | 330 |
308 | 331 |
309 void Parser::set_current_class(const Class& value) { | 332 void Parser::set_current_class(const Class& value) { |
310 current_class_ = value.raw(); | 333 current_class_ = value.raw(); |
311 } | 334 } |
312 | 335 |
313 | 336 |
314 void Parser::SetPosition(intptr_t position) { | 337 void Parser::SetPosition(intptr_t position) { |
315 if (position < token_index_ && position != 0) { | 338 if (position < TokenPos() && position != 0) { |
316 CompilerStats::num_tokens_rewind += (token_index_ - position); | 339 CompilerStats::num_tokens_rewind += (TokenPos() - position); |
317 } | 340 } |
318 token_index_ = position; | 341 tokens_iterator_.SetCurrentPosition(position); |
319 token_kind_ = Token::kILLEGAL; | 342 token_kind_ = Token::kILLEGAL; |
320 } | 343 } |
321 | 344 |
322 | 345 |
323 void Parser::ParseCompilationUnit(const Library& library, | 346 void Parser::ParseCompilationUnit(const Library& library, |
324 const Script& script) { | 347 const Script& script) { |
325 ASSERT(Isolate::Current()->long_jump_base()->IsSafeToJump()); | 348 ASSERT(Isolate::Current()->long_jump_base()->IsSafeToJump()); |
326 TimerScope timer(FLAG_compiler_stats, &CompilerStats::parser_timer); | 349 TimerScope timer(FLAG_compiler_stats, &CompilerStats::parser_timer); |
327 Parser parser(script, library); | 350 Parser parser(script, library); |
328 parser.ParseTopLevel(); | 351 parser.ParseTopLevel(); |
329 if (FLAG_compiler_stats) { | 352 if (FLAG_compiler_stats) { |
330 CompilerStats::num_tokens_total += parser.tokens_.Length(); | 353 CompilerStats::num_tokens_total += parser.tokens_iterator_.NumberOfTokens(); |
331 } | 354 } |
332 } | 355 } |
333 | 356 |
334 | 357 |
335 Token::Kind Parser::CurrentToken() { | 358 Token::Kind Parser::CurrentToken() { |
336 if (token_kind_ == Token::kILLEGAL) { | 359 if (token_kind_ == Token::kILLEGAL) { |
337 token_kind_ = tokens_.KindAt(token_index_); | 360 token_kind_ = tokens_iterator_.CurrentTokenKind(); |
338 if (token_kind_ == Token::kERROR) { | 361 if (token_kind_ == Token::kERROR) { |
339 ErrorMsg(token_index_, CurrentLiteral()->ToCString()); | 362 ErrorMsg(TokenPos(), CurrentLiteral()->ToCString()); |
340 } | 363 } |
341 } | 364 } |
342 CompilerStats::num_token_checks++; | 365 CompilerStats::num_token_checks++; |
343 return token_kind_; | 366 return token_kind_; |
344 } | 367 } |
345 | 368 |
346 | 369 |
347 Token::Kind Parser::LookaheadToken(int num_tokens) { | 370 Token::Kind Parser::LookaheadToken(int num_tokens) { |
348 CompilerStats::num_tokens_lookahead++; | 371 CompilerStats::num_tokens_lookahead++; |
349 CompilerStats::num_token_checks++; | 372 CompilerStats::num_token_checks++; |
350 return tokens_.KindAt(token_index_ + num_tokens); | 373 return tokens_iterator_.LookaheadTokenKind(num_tokens); |
351 } | 374 } |
352 | 375 |
353 | 376 |
354 String* Parser::CurrentLiteral() const { | 377 String* Parser::CurrentLiteral() const { |
355 String& result = String::ZoneHandle(); | 378 String& result = String::ZoneHandle(); |
356 result ^= tokens_.LiteralAt(token_index_); | 379 result ^= tokens_iterator_.CurrentLiteral(); |
357 return &result; | 380 return &result; |
358 } | 381 } |
359 | 382 |
360 | 383 |
361 RawDouble* Parser::CurrentDoubleLiteral() const { | 384 RawDouble* Parser::CurrentDoubleLiteral() const { |
362 LiteralToken& token = LiteralToken::Handle(); | 385 LiteralToken& token = LiteralToken::Handle(); |
363 token ^= tokens_.TokenAt(token_index_); | 386 token ^= tokens_iterator_.CurrentToken(); |
364 ASSERT(token.kind() == Token::kDOUBLE); | 387 ASSERT(token.kind() == Token::kDOUBLE); |
365 return reinterpret_cast<RawDouble*>(token.value()); | 388 return reinterpret_cast<RawDouble*>(token.value()); |
366 } | 389 } |
367 | 390 |
368 | 391 |
369 RawInteger* Parser::CurrentIntegerLiteral() const { | 392 RawInteger* Parser::CurrentIntegerLiteral() const { |
370 LiteralToken& token = LiteralToken::Handle(); | 393 LiteralToken& token = LiteralToken::Handle(); |
371 token ^= tokens_.TokenAt(token_index_); | 394 token ^= tokens_iterator_.CurrentToken(); |
372 ASSERT(token.kind() == Token::kINTEGER); | 395 ASSERT(token.kind() == Token::kINTEGER); |
373 return reinterpret_cast<RawInteger*>(token.value()); | 396 return reinterpret_cast<RawInteger*>(token.value()); |
374 } | 397 } |
375 | 398 |
376 | 399 |
377 // A QualIdent is an optionally qualified identifier. | 400 // A QualIdent is an optionally qualified identifier. |
378 struct QualIdent { | 401 struct QualIdent { |
379 QualIdent() { | 402 QualIdent() { |
380 Clear(); | 403 Clear(); |
381 } | 404 } |
(...skipping 287 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
669 TimerScope timer(FLAG_compiler_stats, &CompilerStats::parser_timer); | 692 TimerScope timer(FLAG_compiler_stats, &CompilerStats::parser_timer); |
670 Isolate* isolate = Isolate::Current(); | 693 Isolate* isolate = Isolate::Current(); |
671 ASSERT(isolate->long_jump_base()->IsSafeToJump()); | 694 ASSERT(isolate->long_jump_base()->IsSafeToJump()); |
672 // Compilation can be nested, preserve the ast node id. | 695 // Compilation can be nested, preserve the ast node id. |
673 const intptr_t prev_ast_node_id = isolate->ast_node_id(); | 696 const intptr_t prev_ast_node_id = isolate->ast_node_id(); |
674 isolate->set_ast_node_id(0); | 697 isolate->set_ast_node_id(0); |
675 ASSERT(parsed_function != NULL); | 698 ASSERT(parsed_function != NULL); |
676 const Function& func = parsed_function->function(); | 699 const Function& func = parsed_function->function(); |
677 const Class& cls = Class::Handle(isolate, func.owner()); | 700 const Class& cls = Class::Handle(isolate, func.owner()); |
678 const Script& script = Script::Handle(isolate, cls.script()); | 701 const Script& script = Script::Handle(isolate, cls.script()); |
679 Parser parser(script, func, func.token_index()); | 702 Parser parser(script, func, func.token_pos()); |
680 SequenceNode* node_sequence = NULL; | 703 SequenceNode* node_sequence = NULL; |
681 Array& default_parameter_values = Array::Handle(isolate, Array::null()); | 704 Array& default_parameter_values = Array::Handle(isolate, Array::null()); |
682 switch (func.kind()) { | 705 switch (func.kind()) { |
683 case RawFunction::kFunction: | 706 case RawFunction::kFunction: |
684 case RawFunction::kClosureFunction: | 707 case RawFunction::kClosureFunction: |
685 case RawFunction::kGetterFunction: | 708 case RawFunction::kGetterFunction: |
686 case RawFunction::kSetterFunction: | 709 case RawFunction::kSetterFunction: |
687 case RawFunction::kConstructor: | 710 case RawFunction::kConstructor: |
688 node_sequence = parser.ParseFunc(func, default_parameter_values); | 711 node_sequence = parser.ParseFunc(func, default_parameter_values); |
689 break; | 712 break; |
690 case RawFunction::kImplicitGetter: | 713 case RawFunction::kImplicitGetter: |
691 ASSERT(!func.is_static()); | 714 ASSERT(!func.is_static()); |
692 node_sequence = parser.ParseInstanceGetter(func); | 715 node_sequence = parser.ParseInstanceGetter(func); |
693 break; | 716 break; |
694 case RawFunction::kImplicitSetter: | 717 case RawFunction::kImplicitSetter: |
695 ASSERT(!func.is_static()); | 718 ASSERT(!func.is_static()); |
696 node_sequence = parser.ParseInstanceSetter(func); | 719 node_sequence = parser.ParseInstanceSetter(func); |
697 break; | 720 break; |
698 case RawFunction::kConstImplicitGetter: | 721 case RawFunction::kConstImplicitGetter: |
699 node_sequence = parser.ParseStaticConstGetter(func); | 722 node_sequence = parser.ParseStaticConstGetter(func); |
700 break; | 723 break; |
701 default: | 724 default: |
702 UNREACHABLE(); | 725 UNREACHABLE(); |
703 } | 726 } |
704 | 727 |
705 if (!HasReturnNode(node_sequence)) { | 728 if (!HasReturnNode(node_sequence)) { |
706 // Add implicit return node. | 729 // Add implicit return node. |
707 node_sequence->Add(new ReturnNode(parser.token_index_)); | 730 node_sequence->Add(new ReturnNode(parser.TokenPos())); |
708 } | 731 } |
709 if (parser.expression_temp_ != NULL) { | 732 if (parser.expression_temp_ != NULL) { |
710 parsed_function->set_expression_temp_var(parser.expression_temp_); | 733 parsed_function->set_expression_temp_var(parser.expression_temp_); |
711 } | 734 } |
712 if (parsed_function->has_expression_temp_var()) { | 735 if (parsed_function->has_expression_temp_var()) { |
713 node_sequence->scope()->AddVariable(parsed_function->expression_temp_var()); | 736 node_sequence->scope()->AddVariable(parsed_function->expression_temp_var()); |
714 } | 737 } |
715 parsed_function->SetNodeSequence(node_sequence); | 738 parsed_function->SetNodeSequence(node_sequence); |
716 | 739 |
717 // The instantiator may be required at run time for generic type checks or | 740 // The instantiator may be required at run time for generic type checks or |
718 // allocation of generic types. | 741 // allocation of generic types. |
719 if (parser.IsInstantiatorRequired()) { | 742 if (parser.IsInstantiatorRequired()) { |
720 // In the case of a local function, only set the instantiator if the | 743 // In the case of a local function, only set the instantiator if the |
721 // receiver was captured. | 744 // receiver was captured. |
722 const bool kTestOnly = true; | 745 const bool kTestOnly = true; |
723 LocalVariable* receiver = | 746 LocalVariable* receiver = |
724 parser.LookupReceiver(node_sequence->scope(), | 747 parser.LookupReceiver(node_sequence->scope(), |
725 kTestOnly); | 748 kTestOnly); |
726 if (!parser.current_function().IsLocalFunction() || | 749 if (!parser.current_function().IsLocalFunction() || |
727 ((receiver != NULL) && receiver->is_captured())) { | 750 ((receiver != NULL) && receiver->is_captured())) { |
728 parsed_function->set_instantiator( | 751 parsed_function->set_instantiator( |
729 new LoadLocalNode(node_sequence->token_index(), *receiver)); | 752 new LoadLocalNode(node_sequence->token_pos(), *receiver)); |
730 } | 753 } |
731 } | 754 } |
732 | 755 |
733 parsed_function->set_default_parameter_values(default_parameter_values); | 756 parsed_function->set_default_parameter_values(default_parameter_values); |
734 isolate->set_ast_node_id(prev_ast_node_id); | 757 isolate->set_ast_node_id(prev_ast_node_id); |
735 } | 758 } |
736 | 759 |
737 | 760 |
738 // TODO(regis): Implement support for non-const final static fields (currently | 761 // TODO(regis): Implement support for non-const final static fields (currently |
739 // supported "final" fields are actually const fields). | 762 // supported "final" fields are actually const fields). |
(...skipping 17 matching lines...) Expand all Loading... |
757 Field::ZoneHandle(field_class.LookupStaticField(field_name)); | 780 Field::ZoneHandle(field_class.LookupStaticField(field_name)); |
758 | 781 |
759 // Static const fields must have an initializer. | 782 // Static const fields must have an initializer. |
760 ExpectToken(Token::kASSIGN); | 783 ExpectToken(Token::kASSIGN); |
761 | 784 |
762 // We don't want to use ParseConstExpr() here because we don't want | 785 // We don't want to use ParseConstExpr() here because we don't want |
763 // the constant folding code to create, compile and execute a code | 786 // the constant folding code to create, compile and execute a code |
764 // fragment to evaluate the expression. Instead, we just make sure | 787 // fragment to evaluate the expression. Instead, we just make sure |
765 // the static const field initializer is a constant expression and | 788 // the static const field initializer is a constant expression and |
766 // leave the evaluation to the getter function. | 789 // leave the evaluation to the getter function. |
767 const intptr_t expr_pos = token_index_; | 790 const intptr_t expr_pos = TokenPos(); |
768 AstNode* expr = ParseExpr(kAllowConst); | 791 AstNode* expr = ParseExpr(kAllowConst); |
769 if (field.is_const()) { | 792 if (field.is_const()) { |
770 // This getter will only be called once at compile time. | 793 // This getter will only be called once at compile time. |
771 if (expr->EvalConstExpr() == NULL) { | 794 if (expr->EvalConstExpr() == NULL) { |
772 ErrorMsg(expr_pos, "initializer must be a compile time constant"); | 795 ErrorMsg(expr_pos, "initializer must be a compile time constant"); |
773 } | 796 } |
774 ReturnNode* return_node = new ReturnNode(token_index_, expr); | 797 ReturnNode* return_node = new ReturnNode(TokenPos(), expr); |
775 current_block_->statements->Add(return_node); | 798 current_block_->statements->Add(return_node); |
776 } else { | 799 } else { |
777 // This getter may be called each time the static field is accessed. | 800 // This getter may be called each time the static field is accessed. |
778 // The following generated code lazily initializes the field: | 801 // The following generated code lazily initializes the field: |
779 // if (field.value === transition_sentinel) { | 802 // if (field.value === transition_sentinel) { |
780 // field.value = null; | 803 // field.value = null; |
781 // throw("circular dependency in field initialization"); | 804 // throw("circular dependency in field initialization"); |
782 // } | 805 // } |
783 // if (field.value === sentinel) { | 806 // if (field.value === sentinel) { |
784 // field.value = transition_sentinel; | 807 // field.value = transition_sentinel; |
785 // field.value = expr; | 808 // field.value = expr; |
786 // } | 809 // } |
787 // return field.value; // Type check is executed here in checked mode. | 810 // return field.value; // Type check is executed here in checked mode. |
788 | 811 |
789 // TODO(regis): Remove this check once we support proper const fields. | 812 // TODO(regis): Remove this check once we support proper const fields. |
790 if (expr->EvalConstExpr() == NULL) { | 813 if (expr->EvalConstExpr() == NULL) { |
791 ErrorMsg(expr_pos, "initializer must be a compile time constant"); | 814 ErrorMsg(expr_pos, "initializer must be a compile time constant"); |
792 } | 815 } |
793 | 816 |
794 // Generate code checking for circular dependency in field initialization. | 817 // Generate code checking for circular dependency in field initialization. |
795 AstNode* compare_circular = new ComparisonNode( | 818 AstNode* compare_circular = new ComparisonNode( |
796 token_index_, | 819 TokenPos(), |
797 Token::kEQ_STRICT, | 820 Token::kEQ_STRICT, |
798 new LoadStaticFieldNode(token_index_, field), | 821 new LoadStaticFieldNode(TokenPos(), field), |
799 new LiteralNode(token_index_, | 822 new LiteralNode(TokenPos(), |
800 Instance::ZoneHandle(Object::transition_sentinel()))); | 823 Instance::ZoneHandle(Object::transition_sentinel()))); |
801 // Set field to null prior to throwing exception, so that subsequent | 824 // Set field to null prior to throwing exception, so that subsequent |
802 // accesses to the field do not throw again, since initializers should only | 825 // accesses to the field do not throw again, since initializers should only |
803 // be executed once. | 826 // be executed once. |
804 SequenceNode* report_circular = new SequenceNode(token_index_, NULL); | 827 SequenceNode* report_circular = new SequenceNode(TokenPos(), NULL); |
805 report_circular->Add( | 828 report_circular->Add( |
806 new StoreStaticFieldNode( | 829 new StoreStaticFieldNode( |
807 token_index_, | 830 TokenPos(), |
808 field, | 831 field, |
809 new LiteralNode(token_index_, Instance::ZoneHandle()))); | 832 new LiteralNode(TokenPos(), Instance::ZoneHandle()))); |
810 // TODO(regis): Exception to throw is not specified by spec. | 833 // TODO(regis): Exception to throw is not specified by spec. |
811 const String& circular_error = String::ZoneHandle( | 834 const String& circular_error = String::ZoneHandle( |
812 String::NewSymbol("circular dependency in field initialization")); | 835 String::NewSymbol("circular dependency in field initialization")); |
813 report_circular->Add( | 836 report_circular->Add( |
814 new ThrowNode(token_index_, | 837 new ThrowNode(TokenPos(), |
815 new LiteralNode(token_index_, circular_error), | 838 new LiteralNode(TokenPos(), circular_error), |
816 NULL)); | 839 NULL)); |
817 AstNode* circular_check = | 840 AstNode* circular_check = |
818 new IfNode(token_index_, compare_circular, report_circular, NULL); | 841 new IfNode(TokenPos(), compare_circular, report_circular, NULL); |
819 current_block_->statements->Add(circular_check); | 842 current_block_->statements->Add(circular_check); |
820 | 843 |
821 // Generate code checking for uninitialized field. | 844 // Generate code checking for uninitialized field. |
822 AstNode* compare_uninitialized = new ComparisonNode( | 845 AstNode* compare_uninitialized = new ComparisonNode( |
823 token_index_, | 846 TokenPos(), |
824 Token::kEQ_STRICT, | 847 Token::kEQ_STRICT, |
825 new LoadStaticFieldNode(token_index_, field), | 848 new LoadStaticFieldNode(TokenPos(), field), |
826 new LiteralNode(token_index_, | 849 new LiteralNode(TokenPos(), |
827 Instance::ZoneHandle(Object::sentinel()))); | 850 Instance::ZoneHandle(Object::sentinel()))); |
828 SequenceNode* initialize_field = new SequenceNode(token_index_, NULL); | 851 SequenceNode* initialize_field = new SequenceNode(TokenPos(), NULL); |
829 initialize_field->Add( | 852 initialize_field->Add( |
830 new StoreStaticFieldNode( | 853 new StoreStaticFieldNode( |
831 token_index_, | 854 TokenPos(), |
832 field, | 855 field, |
833 new LiteralNode( | 856 new LiteralNode( |
834 token_index_, | 857 TokenPos(), |
835 Instance::ZoneHandle(Object::transition_sentinel())))); | 858 Instance::ZoneHandle(Object::transition_sentinel())))); |
836 initialize_field->Add(new StoreStaticFieldNode(token_index_, field, expr)); | 859 initialize_field->Add(new StoreStaticFieldNode(TokenPos(), field, expr)); |
837 AstNode* uninitialized_check = | 860 AstNode* uninitialized_check = |
838 new IfNode(token_index_, compare_uninitialized, initialize_field, NULL); | 861 new IfNode(TokenPos(), compare_uninitialized, initialize_field, NULL); |
839 current_block_->statements->Add(uninitialized_check); | 862 current_block_->statements->Add(uninitialized_check); |
840 | 863 |
841 // Generate code returning the field value. | 864 // Generate code returning the field value. |
842 ReturnNode* return_node = | 865 ReturnNode* return_node = |
843 new ReturnNode(token_index_, | 866 new ReturnNode(TokenPos(), |
844 new LoadStaticFieldNode(token_index_, field)); | 867 new LoadStaticFieldNode(TokenPos(), field)); |
845 current_block_->statements->Add(return_node); | 868 current_block_->statements->Add(return_node); |
846 } | 869 } |
847 return CloseBlock(); | 870 return CloseBlock(); |
848 } | 871 } |
849 | 872 |
850 | 873 |
851 // Create AstNodes for an implicit instance getter method: | 874 // Create AstNodes for an implicit instance getter method: |
852 // LoadLocalNode 0 ('this'); | 875 // LoadLocalNode 0 ('this'); |
853 // LoadInstanceFieldNode (field_name); | 876 // LoadInstanceFieldNode (field_name); |
854 // ReturnNode (field's value); | 877 // ReturnNode (field's value); |
855 SequenceNode* Parser::ParseInstanceGetter(const Function& func) { | 878 SequenceNode* Parser::ParseInstanceGetter(const Function& func) { |
856 TRACE_PARSER("ParseInstanceGetter"); | 879 TRACE_PARSER("ParseInstanceGetter"); |
857 ParamList params; | 880 ParamList params; |
858 params.AddReceiver(token_index_); | 881 params.AddReceiver(TokenPos()); |
859 ASSERT(func.num_fixed_parameters() == 1); // receiver. | 882 ASSERT(func.num_fixed_parameters() == 1); // receiver. |
860 ASSERT(func.num_optional_parameters() == 0); | 883 ASSERT(func.num_optional_parameters() == 0); |
861 ASSERT(AbstractType::Handle(func.result_type()).IsResolved()); | 884 ASSERT(AbstractType::Handle(func.result_type()).IsResolved()); |
862 | 885 |
863 // Build local scope for function and populate with the formal parameters. | 886 // Build local scope for function and populate with the formal parameters. |
864 OpenFunctionBlock(func); | 887 OpenFunctionBlock(func); |
865 AddFormalParamsToScope(¶ms, current_block_->scope); | 888 AddFormalParamsToScope(¶ms, current_block_->scope); |
866 | 889 |
867 // Receiver is local 0. | 890 // Receiver is local 0. |
868 LocalVariable* receiver = current_block_->scope->VariableAt(0); | 891 LocalVariable* receiver = current_block_->scope->VariableAt(0); |
869 LoadLocalNode* load_receiver = new LoadLocalNode(token_index_, *receiver); | 892 LoadLocalNode* load_receiver = new LoadLocalNode(TokenPos(), *receiver); |
870 // token_index_ is the function's token position which points to the name of | 893 // TokenPos() returns the function's token position which points to the |
871 // the field; | 894 // name of the field; |
872 ASSERT(IsIdentifier()); | 895 ASSERT(IsIdentifier()); |
873 const String& field_name = *CurrentLiteral(); | 896 const String& field_name = *CurrentLiteral(); |
874 const Class& field_class = Class::Handle(func.owner()); | 897 const Class& field_class = Class::Handle(func.owner()); |
875 const Field& field = | 898 const Field& field = |
876 Field::ZoneHandle(field_class.LookupInstanceField(field_name)); | 899 Field::ZoneHandle(field_class.LookupInstanceField(field_name)); |
877 | 900 |
878 LoadInstanceFieldNode* load_field = | 901 LoadInstanceFieldNode* load_field = |
879 new LoadInstanceFieldNode(token_index_, load_receiver, field); | 902 new LoadInstanceFieldNode(TokenPos(), load_receiver, field); |
880 | 903 |
881 ReturnNode* return_node = new ReturnNode(token_index_, load_field); | 904 ReturnNode* return_node = new ReturnNode(TokenPos(), load_field); |
882 current_block_->statements->Add(return_node); | 905 current_block_->statements->Add(return_node); |
883 return CloseBlock(); | 906 return CloseBlock(); |
884 } | 907 } |
885 | 908 |
886 | 909 |
887 // Create AstNodes for an implicit instance setter method: | 910 // Create AstNodes for an implicit instance setter method: |
888 // LoadLocalNode 0 ('this') | 911 // LoadLocalNode 0 ('this') |
889 // LoadLocalNode 1 ('value') | 912 // LoadLocalNode 1 ('value') |
890 // SetInstanceField (field_name); | 913 // SetInstanceField (field_name); |
891 // ReturnNode (void); | 914 // ReturnNode (void); |
892 SequenceNode* Parser::ParseInstanceSetter(const Function& func) { | 915 SequenceNode* Parser::ParseInstanceSetter(const Function& func) { |
893 TRACE_PARSER("ParseInstanceSetter"); | 916 TRACE_PARSER("ParseInstanceSetter"); |
894 // token_index_ is the function's token position which points to the name of | 917 // TokenPos() returns the function's token position which points to |
895 // the field; we can use it to form the field_name. | 918 // the name of the field; we can use it to form the field_name. |
896 const String& field_name = *CurrentLiteral(); | 919 const String& field_name = *CurrentLiteral(); |
897 const Class& field_class = Class::ZoneHandle(func.owner()); | 920 const Class& field_class = Class::ZoneHandle(func.owner()); |
898 const Field& field = | 921 const Field& field = |
899 Field::ZoneHandle(field_class.LookupInstanceField(field_name)); | 922 Field::ZoneHandle(field_class.LookupInstanceField(field_name)); |
900 const AbstractType& field_type = AbstractType::ZoneHandle(field.type()); | 923 const AbstractType& field_type = AbstractType::ZoneHandle(field.type()); |
901 | 924 |
902 ParamList params; | 925 ParamList params; |
903 params.AddReceiver(token_index_); | 926 params.AddReceiver(TokenPos()); |
904 params.AddFinalParameter(token_index_, "value", &field_type); | 927 params.AddFinalParameter(TokenPos(), "value", &field_type); |
905 ASSERT(func.num_fixed_parameters() == 2); // receiver, value. | 928 ASSERT(func.num_fixed_parameters() == 2); // receiver, value. |
906 ASSERT(func.num_optional_parameters() == 0); | 929 ASSERT(func.num_optional_parameters() == 0); |
907 ASSERT(AbstractType::Handle(func.result_type()).IsVoidType()); | 930 ASSERT(AbstractType::Handle(func.result_type()).IsVoidType()); |
908 | 931 |
909 // Build local scope for function and populate with the formal parameters. | 932 // Build local scope for function and populate with the formal parameters. |
910 OpenFunctionBlock(func); | 933 OpenFunctionBlock(func); |
911 AddFormalParamsToScope(¶ms, current_block_->scope); | 934 AddFormalParamsToScope(¶ms, current_block_->scope); |
912 | 935 |
913 LoadLocalNode* receiver = | 936 LoadLocalNode* receiver = |
914 new LoadLocalNode(token_index_, *current_block_->scope->VariableAt(0)); | 937 new LoadLocalNode(TokenPos(), *current_block_->scope->VariableAt(0)); |
915 LoadLocalNode* value = | 938 LoadLocalNode* value = |
916 new LoadLocalNode(token_index_, *current_block_->scope->VariableAt(1)); | 939 new LoadLocalNode(TokenPos(), *current_block_->scope->VariableAt(1)); |
917 | 940 |
918 StoreInstanceFieldNode* store_field = | 941 StoreInstanceFieldNode* store_field = |
919 new StoreInstanceFieldNode(token_index_, receiver, field, value); | 942 new StoreInstanceFieldNode(TokenPos(), receiver, field, value); |
920 | 943 |
921 current_block_->statements->Add(store_field); | 944 current_block_->statements->Add(store_field); |
922 current_block_->statements->Add(new ReturnNode(token_index_)); | 945 current_block_->statements->Add(new ReturnNode(TokenPos())); |
923 return CloseBlock(); | 946 return CloseBlock(); |
924 } | 947 } |
925 | 948 |
926 | 949 |
927 void Parser::SkipBlock() { | 950 void Parser::SkipBlock() { |
928 ASSERT(CurrentToken() == Token::kLBRACE); | 951 ASSERT(CurrentToken() == Token::kLBRACE); |
929 GrowableArray<Token::Kind> token_stack(8); | 952 GrowableArray<Token::Kind> token_stack(8); |
930 const intptr_t block_start_pos = token_index_; | 953 const intptr_t block_start_pos = TokenPos(); |
931 bool is_match = true; | 954 bool is_match = true; |
932 bool unexpected_token_found = false; | 955 bool unexpected_token_found = false; |
933 Token::Kind token; | 956 Token::Kind token; |
934 intptr_t token_index; | 957 intptr_t token_pos; |
935 do { | 958 do { |
936 token = CurrentToken(); | 959 token = CurrentToken(); |
937 token_index = token_index_; | 960 token_pos = TokenPos(); |
938 switch (token) { | 961 switch (token) { |
939 case Token::kLBRACE: | 962 case Token::kLBRACE: |
940 case Token::kLPAREN: | 963 case Token::kLPAREN: |
941 case Token::kLBRACK: | 964 case Token::kLBRACK: |
942 token_stack.Add(token); | 965 token_stack.Add(token); |
943 break; | 966 break; |
944 case Token::kRBRACE: | 967 case Token::kRBRACE: |
945 is_match = token_stack.Last() == Token::kLBRACE; | 968 is_match = token_stack.Last() == Token::kLBRACE; |
946 token_stack.RemoveLast(); | 969 token_stack.RemoveLast(); |
947 break; | 970 break; |
948 case Token::kRPAREN: | 971 case Token::kRPAREN: |
949 is_match = token_stack.Last() == Token::kLPAREN; | 972 is_match = token_stack.Last() == Token::kLPAREN; |
950 token_stack.RemoveLast(); | 973 token_stack.RemoveLast(); |
951 break; | 974 break; |
952 case Token::kRBRACK: | 975 case Token::kRBRACK: |
953 is_match = token_stack.Last() == Token::kLBRACK; | 976 is_match = token_stack.Last() == Token::kLBRACK; |
954 token_stack.RemoveLast(); | 977 token_stack.RemoveLast(); |
955 break; | 978 break; |
956 case Token::kEOS: | 979 case Token::kEOS: |
957 unexpected_token_found = true; | 980 unexpected_token_found = true; |
958 break; | 981 break; |
959 default: | 982 default: |
960 // nothing. | 983 // nothing. |
961 break; | 984 break; |
962 } | 985 } |
963 ConsumeToken(); | 986 ConsumeToken(); |
964 } while (!token_stack.is_empty() && is_match && !unexpected_token_found); | 987 } while (!token_stack.is_empty() && is_match && !unexpected_token_found); |
965 if (!is_match) { | 988 if (!is_match) { |
966 ErrorMsg(token_index, "unbalanced '%s'", Token::Str(token)); | 989 ErrorMsg(token_pos, "unbalanced '%s'", Token::Str(token)); |
967 } else if (unexpected_token_found) { | 990 } else if (unexpected_token_found) { |
968 ErrorMsg(block_start_pos, "unterminated block"); | 991 ErrorMsg(block_start_pos, "unterminated block"); |
969 } | 992 } |
970 } | 993 } |
971 | 994 |
972 | 995 |
973 void Parser::ParseFormalParameter(bool allow_explicit_default_value, | 996 void Parser::ParseFormalParameter(bool allow_explicit_default_value, |
974 ParamList* params) { | 997 ParamList* params) { |
975 TRACE_PARSER("ParseFormalParameter"); | 998 TRACE_PARSER("ParseFormalParameter"); |
976 ParamDesc parameter; | 999 ParamDesc parameter; |
(...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1028 } | 1051 } |
1029 } | 1052 } |
1030 if (!this_seen && (CurrentToken() == Token::kTHIS)) { | 1053 if (!this_seen && (CurrentToken() == Token::kTHIS)) { |
1031 ConsumeToken(); | 1054 ConsumeToken(); |
1032 ExpectToken(Token::kPERIOD); | 1055 ExpectToken(Token::kPERIOD); |
1033 this_seen = true; | 1056 this_seen = true; |
1034 parameter.is_field_initializer = true; | 1057 parameter.is_field_initializer = true; |
1035 } | 1058 } |
1036 | 1059 |
1037 // At this point, we must see an identifier for the parameter name. | 1060 // At this point, we must see an identifier for the parameter name. |
1038 parameter.name_pos = token_index_; | 1061 parameter.name_pos = TokenPos(); |
1039 parameter.name = ExpectIdentifier("parameter name expected"); | 1062 parameter.name = ExpectIdentifier("parameter name expected"); |
1040 if (parameter.is_field_initializer) { | 1063 if (parameter.is_field_initializer) { |
1041 params->has_field_initializer = true; | 1064 params->has_field_initializer = true; |
1042 } | 1065 } |
1043 | 1066 |
1044 // Check for duplicate formal parameters. | 1067 // Check for duplicate formal parameters. |
1045 const intptr_t num_existing_parameters = | 1068 const intptr_t num_existing_parameters = |
1046 params->num_fixed_parameters + params->num_optional_parameters; | 1069 params->num_fixed_parameters + params->num_optional_parameters; |
1047 for (intptr_t i = 0; i < num_existing_parameters; i++) { | 1070 for (intptr_t i = 0; i < num_existing_parameters; i++) { |
1048 ParamDesc& existing_parameter = (*params->parameters)[i]; | 1071 ParamDesc& existing_parameter = (*params->parameters)[i]; |
(...skipping 137 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1186 if (CurrentToken() != Token::kSTRING) { | 1209 if (CurrentToken() != Token::kSTRING) { |
1187 ErrorMsg("string literal expected"); | 1210 ErrorMsg("string literal expected"); |
1188 } | 1211 } |
1189 String& native_name = *CurrentLiteral(); | 1212 String& native_name = *CurrentLiteral(); |
1190 ConsumeToken(); | 1213 ConsumeToken(); |
1191 ExpectSemicolon(); | 1214 ExpectSemicolon(); |
1192 return native_name; | 1215 return native_name; |
1193 } | 1216 } |
1194 | 1217 |
1195 | 1218 |
1196 void Parser::CheckFunctionIsCallable(intptr_t token_index, | 1219 void Parser::CheckFunctionIsCallable(intptr_t token_pos, |
1197 const Function& function) { | 1220 const Function& function) { |
1198 if (Class::Handle(function.owner()).is_interface()) { | 1221 if (Class::Handle(function.owner()).is_interface()) { |
1199 ErrorMsg(token_index, "cannot call function of interface '%s'", | 1222 ErrorMsg(token_pos, "cannot call function of interface '%s'", |
1200 function.ToFullyQualifiedCString()); | 1223 function.ToFullyQualifiedCString()); |
1201 } | 1224 } |
1202 } | 1225 } |
1203 | 1226 |
1204 | 1227 |
1205 static RawFunction* ResolveDynamicFunction(const Class& cls, | 1228 static RawFunction* ResolveDynamicFunction(const Class& cls, |
1206 const String& name) { | 1229 const String& name) { |
1207 Function& func = Function::Handle(cls.LookupDynamicFunction(name)); | 1230 Function& func = Function::Handle(cls.LookupDynamicFunction(name)); |
1208 if (func.IsNull()) { | 1231 if (func.IsNull()) { |
1209 Class& super_cls = Class::Handle(cls.SuperClass()); | 1232 Class& super_cls = Class::Handle(cls.SuperClass()); |
(...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1263 name = String::NewSymbol(name); | 1286 name = String::NewSymbol(name); |
1264 } | 1287 } |
1265 return core_lib.LookupClass(name); | 1288 return core_lib.LookupClass(name); |
1266 } | 1289 } |
1267 | 1290 |
1268 | 1291 |
1269 ArgumentListNode* Parser::BuildNoSuchMethodArguments( | 1292 ArgumentListNode* Parser::BuildNoSuchMethodArguments( |
1270 const String& function_name, | 1293 const String& function_name, |
1271 const ArgumentListNode& function_args) { | 1294 const ArgumentListNode& function_args) { |
1272 ASSERT(function_args.length() >= 1); // The receiver is the first argument. | 1295 ASSERT(function_args.length() >= 1); // The receiver is the first argument. |
1273 const intptr_t args_pos = function_args.token_index(); | 1296 const intptr_t args_pos = function_args.token_pos(); |
1274 ArgumentListNode* arguments = new ArgumentListNode(args_pos); | 1297 ArgumentListNode* arguments = new ArgumentListNode(args_pos); |
1275 arguments->Add(function_args.NodeAt(0)); | 1298 arguments->Add(function_args.NodeAt(0)); |
1276 // The second argument is the original function name. | 1299 // The second argument is the original function name. |
1277 // TODO(regis): This will change once mirrors are supported. | 1300 // TODO(regis): This will change once mirrors are supported. |
1278 arguments->Add(new LiteralNode(args_pos, function_name)); | 1301 arguments->Add(new LiteralNode(args_pos, function_name)); |
1279 // The third argument is an array containing the original function arguments. | 1302 // The third argument is an array containing the original function arguments. |
1280 ArrayNode* args_array = new ArrayNode(args_pos, TypeArguments::ZoneHandle()); | 1303 ArrayNode* args_array = new ArrayNode(args_pos, TypeArguments::ZoneHandle()); |
1281 for (intptr_t i = 1; i < function_args.length(); i++) { | 1304 for (intptr_t i = 1; i < function_args.length(); i++) { |
1282 args_array->AddElement(function_args.NodeAt(i)); | 1305 args_array->AddElement(function_args.NodeAt(i)); |
1283 } | 1306 } |
1284 arguments->Add(args_array); | 1307 arguments->Add(args_array); |
1285 return arguments; | 1308 return arguments; |
1286 } | 1309 } |
1287 | 1310 |
1288 | 1311 |
1289 AstNode* Parser::ParseSuperCall(const String& function_name) { | 1312 AstNode* Parser::ParseSuperCall(const String& function_name) { |
1290 TRACE_PARSER("ParseSuperCall"); | 1313 TRACE_PARSER("ParseSuperCall"); |
1291 ASSERT(CurrentToken() == Token::kLPAREN); | 1314 ASSERT(CurrentToken() == Token::kLPAREN); |
1292 const intptr_t supercall_pos = token_index_; | 1315 const intptr_t supercall_pos = TokenPos(); |
1293 | 1316 |
1294 bool is_no_such_method = false; | 1317 bool is_no_such_method = false; |
1295 const Function& super_function = Function::ZoneHandle( | 1318 const Function& super_function = Function::ZoneHandle( |
1296 GetSuperFunction(supercall_pos, function_name, &is_no_such_method)); | 1319 GetSuperFunction(supercall_pos, function_name, &is_no_such_method)); |
1297 | 1320 |
1298 ArgumentListNode* arguments = new ArgumentListNode(supercall_pos); | 1321 ArgumentListNode* arguments = new ArgumentListNode(supercall_pos); |
1299 // 'this' parameter is the first argument to super call. | 1322 // 'this' parameter is the first argument to super call. |
1300 AstNode* receiver = LoadReceiver(supercall_pos); | 1323 AstNode* receiver = LoadReceiver(supercall_pos); |
1301 arguments->Add(receiver); | 1324 arguments->Add(receiver); |
1302 ParseActualParameters(arguments, kAllowConst); | 1325 ParseActualParameters(arguments, kAllowConst); |
(...skipping 12 matching lines...) Expand all Loading... |
1315 if (node->IsLoadLocalNode() && !node->AsLoadLocalNode()->HasPseudo()) { | 1338 if (node->IsLoadLocalNode() && !node->AsLoadLocalNode()->HasPseudo()) { |
1316 return true; | 1339 return true; |
1317 } | 1340 } |
1318 return false; | 1341 return false; |
1319 } | 1342 } |
1320 | 1343 |
1321 | 1344 |
1322 AstNode* Parser::ParseSuperOperator() { | 1345 AstNode* Parser::ParseSuperOperator() { |
1323 TRACE_PARSER("ParseSuperOperator"); | 1346 TRACE_PARSER("ParseSuperOperator"); |
1324 AstNode* super_op = NULL; | 1347 AstNode* super_op = NULL; |
1325 const intptr_t operator_pos = token_index_; | 1348 const intptr_t operator_pos = TokenPos(); |
1326 | 1349 |
1327 if (CurrentToken() == Token::kLBRACK) { | 1350 if (CurrentToken() == Token::kLBRACK) { |
1328 ConsumeToken(); | 1351 ConsumeToken(); |
1329 AstNode* index_expr = ParseExpr(kAllowConst); | 1352 AstNode* index_expr = ParseExpr(kAllowConst); |
1330 ExpectToken(Token::kRBRACK); | 1353 ExpectToken(Token::kRBRACK); |
1331 | 1354 |
1332 if (Token::IsAssignmentOperator(CurrentToken()) && | 1355 if (Token::IsAssignmentOperator(CurrentToken()) && |
1333 (CurrentToken() != Token::kASSIGN)) { | 1356 (CurrentToken() != Token::kASSIGN)) { |
1334 // Compound assignment. Ensure side effects in index expression | 1357 // Compound assignment. Ensure side effects in index expression |
1335 // only execute once. If the index is not a local variable or an | 1358 // only execute once. If the index is not a local variable or an |
(...skipping 104 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1440 CaptureReceiver(); | 1463 CaptureReceiver(); |
1441 } | 1464 } |
1442 } | 1465 } |
1443 } | 1466 } |
1444 return new ClosureNode(token_pos, implicit_closure_function, receiver, NULL); | 1467 return new ClosureNode(token_pos, implicit_closure_function, receiver, NULL); |
1445 } | 1468 } |
1446 | 1469 |
1447 | 1470 |
1448 AstNode* Parser::ParseSuperFieldAccess(const String& field_name) { | 1471 AstNode* Parser::ParseSuperFieldAccess(const String& field_name) { |
1449 TRACE_PARSER("ParseSuperFieldAccess"); | 1472 TRACE_PARSER("ParseSuperFieldAccess"); |
1450 const intptr_t field_pos = token_index_; | 1473 const intptr_t field_pos = TokenPos(); |
1451 const Class& super_class = Class::Handle(current_class().SuperClass()); | 1474 const Class& super_class = Class::Handle(current_class().SuperClass()); |
1452 if (super_class.IsNull()) { | 1475 if (super_class.IsNull()) { |
1453 ErrorMsg("class '%s' does not have a superclass", | 1476 ErrorMsg("class '%s' does not have a superclass", |
1454 String::Handle(current_class().Name()).ToCString()); | 1477 String::Handle(current_class().Name()).ToCString()); |
1455 } | 1478 } |
1456 AstNode* implicit_argument = LoadReceiver(field_pos); | 1479 AstNode* implicit_argument = LoadReceiver(field_pos); |
1457 | 1480 |
1458 const String& getter_name = | 1481 const String& getter_name = |
1459 String::ZoneHandle(Field::GetterName(field_name)); | 1482 String::ZoneHandle(Field::GetterName(field_name)); |
1460 const Function& super_getter = Function::ZoneHandle( | 1483 const Function& super_getter = Function::ZoneHandle( |
(...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1503 setter_arguments->Add(implicit_argument); | 1526 setter_arguments->Add(implicit_argument); |
1504 setter_arguments->Add(value); | 1527 setter_arguments->Add(value); |
1505 super_field = new StaticCallNode(field_pos, super_setter, setter_arguments); | 1528 super_field = new StaticCallNode(field_pos, super_setter, setter_arguments); |
1506 } | 1529 } |
1507 return super_field; | 1530 return super_field; |
1508 } | 1531 } |
1509 | 1532 |
1510 | 1533 |
1511 void Parser::GenerateSuperConstructorCall(const Class& cls, | 1534 void Parser::GenerateSuperConstructorCall(const Class& cls, |
1512 LocalVariable* receiver) { | 1535 LocalVariable* receiver) { |
1513 const intptr_t supercall_pos = token_index_; | 1536 const intptr_t supercall_pos = TokenPos(); |
1514 const Class& super_class = Class::Handle(cls.SuperClass()); | 1537 const Class& super_class = Class::Handle(cls.SuperClass()); |
1515 // Omit the implicit super() if there is no super class (i.e. | 1538 // Omit the implicit super() if there is no super class (i.e. |
1516 // we're not compiling class Object), or if the super class is an | 1539 // we're not compiling class Object), or if the super class is an |
1517 // artificially generated "wrapper class" that has no constructor. | 1540 // artificially generated "wrapper class" that has no constructor. |
1518 if (super_class.IsNull() || (super_class.num_native_fields() > 0)) { | 1541 if (super_class.IsNull() || (super_class.num_native_fields() > 0)) { |
1519 return; | 1542 return; |
1520 } | 1543 } |
1521 String& ctor_name = String::Handle(super_class.Name()); | 1544 String& ctor_name = String::Handle(super_class.Name()); |
1522 String& ctor_suffix = String::Handle(String::NewSymbol(".")); | 1545 String& ctor_suffix = String::Handle(String::NewSymbol(".")); |
1523 ctor_name = String::Concat(ctor_name, ctor_suffix); | 1546 ctor_name = String::Concat(ctor_name, ctor_suffix); |
(...skipping 18 matching lines...) Expand all Loading... |
1542 CheckFunctionIsCallable(supercall_pos, super_ctor); | 1565 CheckFunctionIsCallable(supercall_pos, super_ctor); |
1543 current_block_->statements->Add( | 1566 current_block_->statements->Add( |
1544 new StaticCallNode(supercall_pos, super_ctor, arguments)); | 1567 new StaticCallNode(supercall_pos, super_ctor, arguments)); |
1545 } | 1568 } |
1546 | 1569 |
1547 | 1570 |
1548 AstNode* Parser::ParseSuperInitializer(const Class& cls, | 1571 AstNode* Parser::ParseSuperInitializer(const Class& cls, |
1549 LocalVariable* receiver) { | 1572 LocalVariable* receiver) { |
1550 TRACE_PARSER("ParseSuperInitializer"); | 1573 TRACE_PARSER("ParseSuperInitializer"); |
1551 ASSERT(CurrentToken() == Token::kSUPER); | 1574 ASSERT(CurrentToken() == Token::kSUPER); |
1552 const intptr_t supercall_pos = token_index_; | 1575 const intptr_t supercall_pos = TokenPos(); |
1553 ConsumeToken(); | 1576 ConsumeToken(); |
1554 const Class& super_class = Class::Handle(cls.SuperClass()); | 1577 const Class& super_class = Class::Handle(cls.SuperClass()); |
1555 ASSERT(!super_class.IsNull()); | 1578 ASSERT(!super_class.IsNull()); |
1556 String& ctor_name = String::Handle(super_class.Name()); | 1579 String& ctor_name = String::Handle(super_class.Name()); |
1557 String& ctor_suffix = String::Handle(String::NewSymbol(".")); | 1580 String& ctor_suffix = String::Handle(String::NewSymbol(".")); |
1558 if (CurrentToken() == Token::kPERIOD) { | 1581 if (CurrentToken() == Token::kPERIOD) { |
1559 ConsumeToken(); | 1582 ConsumeToken(); |
1560 ctor_suffix = String::Concat( | 1583 ctor_suffix = String::Concat( |
1561 ctor_suffix, *ExpectIdentifier("constructor name expected")); | 1584 ctor_suffix, *ExpectIdentifier("constructor name expected")); |
1562 } | 1585 } |
(...skipping 29 matching lines...) Expand all Loading... |
1592 "super class constructor '%s' not found", | 1615 "super class constructor '%s' not found", |
1593 ctor_name.ToCString()); | 1616 ctor_name.ToCString()); |
1594 } | 1617 } |
1595 CheckFunctionIsCallable(supercall_pos, super_ctor); | 1618 CheckFunctionIsCallable(supercall_pos, super_ctor); |
1596 return new StaticCallNode(supercall_pos, super_ctor, arguments); | 1619 return new StaticCallNode(supercall_pos, super_ctor, arguments); |
1597 } | 1620 } |
1598 | 1621 |
1599 | 1622 |
1600 AstNode* Parser::ParseInitializer(const Class& cls, LocalVariable* receiver) { | 1623 AstNode* Parser::ParseInitializer(const Class& cls, LocalVariable* receiver) { |
1601 TRACE_PARSER("ParseInitializer"); | 1624 TRACE_PARSER("ParseInitializer"); |
1602 const intptr_t field_pos = token_index_; | 1625 const intptr_t field_pos = TokenPos(); |
1603 if (CurrentToken() == Token::kTHIS) { | 1626 if (CurrentToken() == Token::kTHIS) { |
1604 ConsumeToken(); | 1627 ConsumeToken(); |
1605 ExpectToken(Token::kPERIOD); | 1628 ExpectToken(Token::kPERIOD); |
1606 } | 1629 } |
1607 const String& field_name = *ExpectIdentifier("field name expected"); | 1630 const String& field_name = *ExpectIdentifier("field name expected"); |
1608 ExpectToken(Token::kASSIGN); | 1631 ExpectToken(Token::kASSIGN); |
1609 | 1632 |
1610 const bool saved_mode = SetAllowFunctionLiterals(false); | 1633 const bool saved_mode = SetAllowFunctionLiterals(false); |
1611 // "this" must not be accessible in initializer expressions. | 1634 // "this" must not be accessible in initializer expressions. |
1612 receiver->set_invisible(true); | 1635 receiver->set_invisible(true); |
(...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1656 Field* inst_field; | 1679 Field* inst_field; |
1657 AstNode* expr; | 1680 AstNode* expr; |
1658 }; | 1681 }; |
1659 | 1682 |
1660 | 1683 |
1661 void Parser::ParseInitializedInstanceFields(const Class& cls, | 1684 void Parser::ParseInitializedInstanceFields(const Class& cls, |
1662 GrowableArray<FieldInitExpression>* initializers) { | 1685 GrowableArray<FieldInitExpression>* initializers) { |
1663 TRACE_PARSER("ParseInitializedInstanceFields"); | 1686 TRACE_PARSER("ParseInitializedInstanceFields"); |
1664 const Array& fields = Array::Handle(cls.fields()); | 1687 const Array& fields = Array::Handle(cls.fields()); |
1665 Field& f = Field::Handle(); | 1688 Field& f = Field::Handle(); |
1666 const intptr_t saved_pos = token_index_; | 1689 const intptr_t saved_pos = TokenPos(); |
1667 for (int i = 0; i < fields.Length(); i++) { | 1690 for (int i = 0; i < fields.Length(); i++) { |
1668 f ^= fields.At(i); | 1691 f ^= fields.At(i); |
1669 if (!f.is_static() && f.has_initializer()) { | 1692 if (!f.is_static() && f.has_initializer()) { |
1670 Field& field = Field::ZoneHandle(); | 1693 Field& field = Field::ZoneHandle(); |
1671 field ^= fields.At(i); | 1694 field ^= fields.At(i); |
1672 intptr_t field_pos = field.token_index(); | 1695 intptr_t field_pos = field.token_pos(); |
1673 SetPosition(field_pos); | 1696 SetPosition(field_pos); |
1674 ASSERT(IsIdentifier()); | 1697 ASSERT(IsIdentifier()); |
1675 ConsumeToken(); | 1698 ConsumeToken(); |
1676 ExpectToken(Token::kASSIGN); | 1699 ExpectToken(Token::kASSIGN); |
1677 AstNode* init_expr = ParseConstExpr(); | 1700 AstNode* init_expr = ParseConstExpr(); |
1678 ASSERT(init_expr != NULL); | 1701 ASSERT(init_expr != NULL); |
1679 FieldInitExpression initializer; | 1702 FieldInitExpression initializer; |
1680 initializer.inst_field = &field; | 1703 initializer.inst_field = &field; |
1681 initializer.expr = init_expr; | 1704 initializer.expr = init_expr; |
1682 initializers->Add(initializer); | 1705 initializers->Add(initializer); |
(...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1723 GenerateSuperConstructorCall(cls, receiver); | 1746 GenerateSuperConstructorCall(cls, receiver); |
1724 } | 1747 } |
1725 CheckConstFieldsInitialized(cls); | 1748 CheckConstFieldsInitialized(cls); |
1726 } | 1749 } |
1727 | 1750 |
1728 | 1751 |
1729 void Parser::ParseConstructorRedirection(const Class& cls, | 1752 void Parser::ParseConstructorRedirection(const Class& cls, |
1730 LocalVariable* receiver) { | 1753 LocalVariable* receiver) { |
1731 TRACE_PARSER("ParseConstructorRedirection"); | 1754 TRACE_PARSER("ParseConstructorRedirection"); |
1732 ASSERT(CurrentToken() == Token::kTHIS); | 1755 ASSERT(CurrentToken() == Token::kTHIS); |
1733 const intptr_t call_pos = token_index_; | 1756 const intptr_t call_pos = TokenPos(); |
1734 ConsumeToken(); | 1757 ConsumeToken(); |
1735 String& ctor_name = String::Handle(cls.Name()); | 1758 String& ctor_name = String::Handle(cls.Name()); |
1736 String& ctor_suffix = String::Handle(String::NewSymbol(".")); | 1759 String& ctor_suffix = String::Handle(String::NewSymbol(".")); |
1737 | 1760 |
1738 if (CurrentToken() == Token::kPERIOD) { | 1761 if (CurrentToken() == Token::kPERIOD) { |
1739 ConsumeToken(); | 1762 ConsumeToken(); |
1740 ctor_suffix = String::Concat( | 1763 ctor_suffix = String::Concat( |
1741 ctor_suffix, *ExpectIdentifier("constructor name expected")); | 1764 ctor_suffix, *ExpectIdentifier("constructor name expected")); |
1742 } | 1765 } |
1743 ctor_name = String::Concat(ctor_name, ctor_suffix); | 1766 ctor_name = String::Concat(ctor_name, ctor_suffix); |
(...skipping 22 matching lines...) Expand all Loading... |
1766 ctor_name.ToCString()); | 1789 ctor_name.ToCString()); |
1767 } | 1790 } |
1768 CheckFunctionIsCallable(call_pos, redirect_ctor); | 1791 CheckFunctionIsCallable(call_pos, redirect_ctor); |
1769 current_block_->statements->Add( | 1792 current_block_->statements->Add( |
1770 new StaticCallNode(call_pos, redirect_ctor, arguments)); | 1793 new StaticCallNode(call_pos, redirect_ctor, arguments)); |
1771 } | 1794 } |
1772 | 1795 |
1773 | 1796 |
1774 SequenceNode* Parser::MakeImplicitConstructor(const Function& func) { | 1797 SequenceNode* Parser::MakeImplicitConstructor(const Function& func) { |
1775 ASSERT(func.IsConstructor()); | 1798 ASSERT(func.IsConstructor()); |
1776 const intptr_t ctor_pos = token_index_; | 1799 const intptr_t ctor_pos = TokenPos(); |
1777 | 1800 |
1778 // Implicit 'this' is the only parameter/local variable. | 1801 // Implicit 'this' is the only parameter/local variable. |
1779 OpenFunctionBlock(func); | 1802 OpenFunctionBlock(func); |
1780 | 1803 |
1781 // Parse expressions of instance fields that have an explicit | 1804 // Parse expressions of instance fields that have an explicit |
1782 // initializers. | 1805 // initializers. |
1783 GrowableArray<FieldInitExpression> initializers; | 1806 GrowableArray<FieldInitExpression> initializers; |
1784 Class& cls = Class::Handle(func.owner()); | 1807 Class& cls = Class::Handle(func.owner()); |
1785 ParseInitializedInstanceFields(cls, &initializers); | 1808 ParseInitializedInstanceFields(cls, &initializers); |
1786 | 1809 |
1787 LocalVariable* receiver = new LocalVariable( | 1810 LocalVariable* receiver = new LocalVariable( |
1788 ctor_pos, | 1811 ctor_pos, |
1789 String::ZoneHandle(String::NewSymbol(kThisName)), | 1812 String::ZoneHandle(String::NewSymbol(kThisName)), |
1790 Type::ZoneHandle(Type::DynamicType())); | 1813 Type::ZoneHandle(Type::DynamicType())); |
1791 current_block_->scope->AddVariable(receiver); | 1814 current_block_->scope->AddVariable(receiver); |
1792 | 1815 |
1793 LocalVariable* phase_parameter = new LocalVariable( | 1816 LocalVariable* phase_parameter = new LocalVariable( |
1794 ctor_pos, | 1817 ctor_pos, |
1795 String::ZoneHandle(String::NewSymbol(kPhaseParameterName)), | 1818 String::ZoneHandle(String::NewSymbol(kPhaseParameterName)), |
1796 Type::ZoneHandle(Type::DynamicType())); | 1819 Type::ZoneHandle(Type::DynamicType())); |
1797 current_block_->scope->AddVariable(phase_parameter); | 1820 current_block_->scope->AddVariable(phase_parameter); |
1798 | 1821 |
1799 // Now that the "this" parameter is in scope, we can generate the code | 1822 // Now that the "this" parameter is in scope, we can generate the code |
1800 // to strore the initializer expressions in the respective instance fields. | 1823 // to strore the initializer expressions in the respective instance fields. |
1801 for (int i = 0; i < initializers.length(); i++) { | 1824 for (int i = 0; i < initializers.length(); i++) { |
1802 const Field* field = initializers[i].inst_field; | 1825 const Field* field = initializers[i].inst_field; |
1803 AstNode* instance = new LoadLocalNode(field->token_index(), *receiver); | 1826 AstNode* instance = new LoadLocalNode(field->token_pos(), *receiver); |
1804 AstNode* field_init = | 1827 AstNode* field_init = |
1805 new StoreInstanceFieldNode(field->token_index(), | 1828 new StoreInstanceFieldNode(field->token_pos(), |
1806 instance, | 1829 instance, |
1807 *field, | 1830 *field, |
1808 initializers[i].expr); | 1831 initializers[i].expr); |
1809 current_block_->statements->Add(field_init); | 1832 current_block_->statements->Add(field_init); |
1810 } | 1833 } |
1811 | 1834 |
1812 GenerateSuperConstructorCall(cls, receiver); | 1835 GenerateSuperConstructorCall(cls, receiver); |
1813 CheckConstFieldsInitialized(cls); | 1836 CheckConstFieldsInitialized(cls); |
1814 | 1837 |
1815 // Empty constructor body. | 1838 // Empty constructor body. |
(...skipping 26 matching lines...) Expand all Loading... |
1842 return MakeImplicitConstructor(func); | 1865 return MakeImplicitConstructor(func); |
1843 } | 1866 } |
1844 | 1867 |
1845 OpenFunctionBlock(func); | 1868 OpenFunctionBlock(func); |
1846 ParamList params; | 1869 ParamList params; |
1847 const bool allow_explicit_default_values = true; | 1870 const bool allow_explicit_default_values = true; |
1848 ASSERT(CurrentToken() == Token::kLPAREN); | 1871 ASSERT(CurrentToken() == Token::kLPAREN); |
1849 | 1872 |
1850 // Add implicit receiver parameter which is passed the allocated | 1873 // Add implicit receiver parameter which is passed the allocated |
1851 // but uninitialized instance to construct. | 1874 // but uninitialized instance to construct. |
1852 params.AddReceiver(token_index_); | 1875 params.AddReceiver(TokenPos()); |
1853 | 1876 |
1854 // Add implicit parameter for construction phase. | 1877 // Add implicit parameter for construction phase. |
1855 params.AddFinalParameter( | 1878 params.AddFinalParameter( |
1856 token_index_, | 1879 TokenPos(), |
1857 kPhaseParameterName, | 1880 kPhaseParameterName, |
1858 &Type::ZoneHandle(Type::DynamicType())); | 1881 &Type::ZoneHandle(Type::DynamicType())); |
1859 | 1882 |
1860 if (func.is_const()) { | 1883 if (func.is_const()) { |
1861 params.SetImplicitlyFinal(); | 1884 params.SetImplicitlyFinal(); |
1862 } | 1885 } |
1863 ParseFormalParameterList(allow_explicit_default_values, ¶ms); | 1886 ParseFormalParameterList(allow_explicit_default_values, ¶ms); |
1864 | 1887 |
1865 SetupDefaultsForOptionalParams(¶ms, default_parameter_values); | 1888 SetupDefaultsForOptionalParams(¶ms, default_parameter_values); |
1866 ASSERT(AbstractType::Handle(func.result_type()).IsResolved()); | 1889 ASSERT(AbstractType::Handle(func.result_type()).IsResolved()); |
(...skipping 12 matching lines...) Expand all Loading... |
1879 AddFormalParamsToScope(¶ms, current_block_->scope); | 1902 AddFormalParamsToScope(¶ms, current_block_->scope); |
1880 LocalVariable* receiver = current_block_->scope->VariableAt(0); | 1903 LocalVariable* receiver = current_block_->scope->VariableAt(0); |
1881 | 1904 |
1882 // Now that the "this" parameter is in scope, we can generate the code | 1905 // Now that the "this" parameter is in scope, we can generate the code |
1883 // to store the initializer expressions in the respective instance fields. | 1906 // to store the initializer expressions in the respective instance fields. |
1884 // We do this before the field parameters and the initializers from the | 1907 // We do this before the field parameters and the initializers from the |
1885 // constructor's initializer list get compiled. | 1908 // constructor's initializer list get compiled. |
1886 OpenBlock(); | 1909 OpenBlock(); |
1887 for (int i = 0; i < initializers.length(); i++) { | 1910 for (int i = 0; i < initializers.length(); i++) { |
1888 const Field* field = initializers[i].inst_field; | 1911 const Field* field = initializers[i].inst_field; |
1889 AstNode* instance = new LoadLocalNode(field->token_index(), *receiver); | 1912 AstNode* instance = new LoadLocalNode(field->token_pos(), *receiver); |
1890 AstNode* field_init = | 1913 AstNode* field_init = |
1891 new StoreInstanceFieldNode(field->token_index(), | 1914 new StoreInstanceFieldNode(field->token_pos(), |
1892 instance, | 1915 instance, |
1893 *field, | 1916 *field, |
1894 initializers[i].expr); | 1917 initializers[i].expr); |
1895 current_block_->statements->Add(field_init); | 1918 current_block_->statements->Add(field_init); |
1896 } | 1919 } |
1897 | 1920 |
1898 // Turn formal field parameters into field initializers or report error | 1921 // Turn formal field parameters into field initializers or report error |
1899 // if the function is not a constructor. | 1922 // if the function is not a constructor. |
1900 if (params.has_field_initializer) { | 1923 if (params.has_field_initializer) { |
1901 for (int i = 0; i < params.parameters->length(); i++) { | 1924 for (int i = 0; i < params.parameters->length(); i++) { |
(...skipping 22 matching lines...) Expand all Loading... |
1924 } | 1947 } |
1925 } | 1948 } |
1926 | 1949 |
1927 // Now parse the explicit initializer list or constructor redirection. | 1950 // Now parse the explicit initializer list or constructor redirection. |
1928 ParseInitializers(cls, receiver); | 1951 ParseInitializers(cls, receiver); |
1929 | 1952 |
1930 SequenceNode* init_statements = CloseBlock(); | 1953 SequenceNode* init_statements = CloseBlock(); |
1931 if (init_statements->length() > 0) { | 1954 if (init_statements->length() > 0) { |
1932 // Generate guard around the initializer code. | 1955 // Generate guard around the initializer code. |
1933 LocalVariable* phase_param = LookupPhaseParameter(); | 1956 LocalVariable* phase_param = LookupPhaseParameter(); |
1934 AstNode* phase_value = new LoadLocalNode(token_index_, *phase_param); | 1957 AstNode* phase_value = new LoadLocalNode(TokenPos(), *phase_param); |
1935 AstNode* phase_check = new BinaryOpNode( | 1958 AstNode* phase_check = new BinaryOpNode( |
1936 token_index_, Token::kBIT_AND, phase_value, | 1959 TokenPos(), Token::kBIT_AND, phase_value, |
1937 new LiteralNode(token_index_, | 1960 new LiteralNode(TokenPos(), |
1938 Smi::ZoneHandle(Smi::New(Function::kCtorPhaseInit)))); | 1961 Smi::ZoneHandle(Smi::New(Function::kCtorPhaseInit)))); |
1939 AstNode* comparison = | 1962 AstNode* comparison = |
1940 new ComparisonNode(token_index_, Token::kNE_STRICT, | 1963 new ComparisonNode(TokenPos(), Token::kNE_STRICT, |
1941 phase_check, | 1964 phase_check, |
1942 new LiteralNode(token_index_, | 1965 new LiteralNode(TokenPos(), |
1943 Smi::ZoneHandle(Smi::New(0)))); | 1966 Smi::ZoneHandle(Smi::New(0)))); |
1944 AstNode* guarded_init_statements = | 1967 AstNode* guarded_init_statements = |
1945 new IfNode(token_index_, comparison, init_statements, NULL); | 1968 new IfNode(TokenPos(), comparison, init_statements, NULL); |
1946 current_block_->statements->Add(guarded_init_statements); | 1969 current_block_->statements->Add(guarded_init_statements); |
1947 } | 1970 } |
1948 | 1971 |
1949 // Parsing of initializers done. Now we parse the constructor body | 1972 // Parsing of initializers done. Now we parse the constructor body |
1950 // and add the implicit super call to the super constructor's body | 1973 // and add the implicit super call to the super constructor's body |
1951 // if necessary. | 1974 // if necessary. |
1952 StaticCallNode* super_call = NULL; | 1975 StaticCallNode* super_call = NULL; |
1953 // Look for the super initializer call in the sequence of initializer | 1976 // Look for the super initializer call in the sequence of initializer |
1954 // statements. If it exists and is not the last initializer statement, | 1977 // statements. If it exists and is not the last initializer statement, |
1955 // we need to create an implicit super call to the super constructor's | 1978 // we need to create an implicit super call to the super constructor's |
(...skipping 17 matching lines...) Expand all Loading... |
1973 // The temporary variables are necessary so that the argument | 1996 // The temporary variables are necessary so that the argument |
1974 // expressions are not evaluated twice. | 1997 // expressions are not evaluated twice. |
1975 ArgumentListNode* ctor_args = super_call->arguments(); | 1998 ArgumentListNode* ctor_args = super_call->arguments(); |
1976 // The super initializer call has at least 2 arguments: the | 1999 // The super initializer call has at least 2 arguments: the |
1977 // implicit receiver, and the hidden construction phase. | 2000 // implicit receiver, and the hidden construction phase. |
1978 ASSERT(ctor_args->length() >= 2); | 2001 ASSERT(ctor_args->length() >= 2); |
1979 for (int i = 2; i < ctor_args->length(); i++) { | 2002 for (int i = 2; i < ctor_args->length(); i++) { |
1980 AstNode* arg = ctor_args->NodeAt(i); | 2003 AstNode* arg = ctor_args->NodeAt(i); |
1981 if (!IsSimpleLocalOrLiteralNode(arg)) { | 2004 if (!IsSimpleLocalOrLiteralNode(arg)) { |
1982 LocalVariable* temp = | 2005 LocalVariable* temp = |
1983 CreateTempConstVariable(arg->token_index(), arg->id(), "sca"); | 2006 CreateTempConstVariable(arg->token_pos(), arg->id(), "sca"); |
1984 AstNode* save_temp = | 2007 AstNode* save_temp = |
1985 new StoreLocalNode(arg->token_index(), *temp, arg); | 2008 new StoreLocalNode(arg->token_pos(), *temp, arg); |
1986 ctor_args->SetNodeAt(i, save_temp); | 2009 ctor_args->SetNodeAt(i, save_temp); |
1987 } | 2010 } |
1988 } | 2011 } |
1989 } | 2012 } |
1990 OpenBlock(); // Block to collect constructor body nodes. | 2013 OpenBlock(); // Block to collect constructor body nodes. |
1991 | 2014 |
1992 // Insert the implicit super call to the super constructor body. | 2015 // Insert the implicit super call to the super constructor body. |
1993 if (super_call != NULL) { | 2016 if (super_call != NULL) { |
1994 ArgumentListNode* initializer_args = super_call->arguments(); | 2017 ArgumentListNode* initializer_args = super_call->arguments(); |
1995 const Function& super_ctor = super_call->function(); | 2018 const Function& super_ctor = super_call->function(); |
1996 // Patch the initializer call so it only executes the super initializer. | 2019 // Patch the initializer call so it only executes the super initializer. |
1997 initializer_args->SetNodeAt(1, | 2020 initializer_args->SetNodeAt(1, |
1998 new LiteralNode(token_index_, | 2021 new LiteralNode(TokenPos(), |
1999 Smi::ZoneHandle(Smi::New(Function::kCtorPhaseInit)))); | 2022 Smi::ZoneHandle(Smi::New(Function::kCtorPhaseInit)))); |
2000 | 2023 |
2001 ArgumentListNode* super_call_args = new ArgumentListNode(token_index_); | 2024 ArgumentListNode* super_call_args = new ArgumentListNode(TokenPos()); |
2002 // First argument is the receiver. | 2025 // First argument is the receiver. |
2003 super_call_args->Add(new LoadLocalNode(token_index_, *receiver)); | 2026 super_call_args->Add(new LoadLocalNode(TokenPos(), *receiver)); |
2004 // Second argument is the construction phase argument. | 2027 // Second argument is the construction phase argument. |
2005 AstNode* phase_parameter = | 2028 AstNode* phase_parameter = |
2006 new LiteralNode(token_index_, | 2029 new LiteralNode(TokenPos(), |
2007 Smi::ZoneHandle(Smi::New(Function::kCtorPhaseBody))); | 2030 Smi::ZoneHandle(Smi::New(Function::kCtorPhaseBody))); |
2008 super_call_args->Add(phase_parameter); | 2031 super_call_args->Add(phase_parameter); |
2009 super_call_args->set_names(initializer_args->names()); | 2032 super_call_args->set_names(initializer_args->names()); |
2010 for (int i = 2; i < initializer_args->length(); i++) { | 2033 for (int i = 2; i < initializer_args->length(); i++) { |
2011 AstNode* arg = initializer_args->NodeAt(i); | 2034 AstNode* arg = initializer_args->NodeAt(i); |
2012 if (arg->IsLiteralNode()) { | 2035 if (arg->IsLiteralNode()) { |
2013 LiteralNode* lit = arg->AsLiteralNode(); | 2036 LiteralNode* lit = arg->AsLiteralNode(); |
2014 super_call_args->Add(new LiteralNode(token_index_, lit->literal())); | 2037 super_call_args->Add(new LiteralNode(TokenPos(), lit->literal())); |
2015 } else { | 2038 } else { |
2016 ASSERT(arg->IsLoadLocalNode() || arg->IsStoreLocalNode()); | 2039 ASSERT(arg->IsLoadLocalNode() || arg->IsStoreLocalNode()); |
2017 if (arg->IsLoadLocalNode()) { | 2040 if (arg->IsLoadLocalNode()) { |
2018 const LocalVariable& temp = arg->AsLoadLocalNode()->local(); | 2041 const LocalVariable& temp = arg->AsLoadLocalNode()->local(); |
2019 super_call_args->Add(new LoadLocalNode(token_index_, temp)); | 2042 super_call_args->Add(new LoadLocalNode(TokenPos(), temp)); |
2020 } else if (arg->IsStoreLocalNode()) { | 2043 } else if (arg->IsStoreLocalNode()) { |
2021 const LocalVariable& temp = arg->AsStoreLocalNode()->local(); | 2044 const LocalVariable& temp = arg->AsStoreLocalNode()->local(); |
2022 super_call_args->Add(new LoadLocalNode(token_index_, temp)); | 2045 super_call_args->Add(new LoadLocalNode(TokenPos(), temp)); |
2023 } | 2046 } |
2024 } | 2047 } |
2025 } | 2048 } |
2026 ASSERT(super_ctor.AreValidArguments(super_call_args->length(), | 2049 ASSERT(super_ctor.AreValidArguments(super_call_args->length(), |
2027 super_call_args->names())); | 2050 super_call_args->names())); |
2028 current_block_->statements->Add( | 2051 current_block_->statements->Add( |
2029 new StaticCallNode(token_index_, super_ctor, super_call_args)); | 2052 new StaticCallNode(TokenPos(), super_ctor, super_call_args)); |
2030 } | 2053 } |
2031 | 2054 |
2032 if (CurrentToken() == Token::kLBRACE) { | 2055 if (CurrentToken() == Token::kLBRACE) { |
2033 ConsumeToken(); | 2056 ConsumeToken(); |
2034 ParseStatementSequence(); | 2057 ParseStatementSequence(); |
2035 ExpectToken(Token::kRBRACE); | 2058 ExpectToken(Token::kRBRACE); |
2036 } else if (CurrentToken() == Token::kARROW) { | 2059 } else if (CurrentToken() == Token::kARROW) { |
2037 ErrorMsg("constructors may not return a value"); | 2060 ErrorMsg("constructors may not return a value"); |
2038 } else if (IsLiteral("native")) { | 2061 } else if (IsLiteral("native")) { |
2039 ErrorMsg("native constructors not supported"); | 2062 ErrorMsg("native constructors not supported"); |
2040 } else if (CurrentToken() == Token::kSEMICOLON) { | 2063 } else if (CurrentToken() == Token::kSEMICOLON) { |
2041 // Some constructors have no function body. | 2064 // Some constructors have no function body. |
2042 ConsumeToken(); | 2065 ConsumeToken(); |
2043 } else { | 2066 } else { |
2044 UnexpectedToken(); | 2067 UnexpectedToken(); |
2045 } | 2068 } |
2046 | 2069 |
2047 SequenceNode* ctor_block = CloseBlock(); | 2070 SequenceNode* ctor_block = CloseBlock(); |
2048 if (ctor_block->length() > 0) { | 2071 if (ctor_block->length() > 0) { |
2049 // Generate guard around the constructor body code. | 2072 // Generate guard around the constructor body code. |
2050 LocalVariable* phase_param = LookupPhaseParameter(); | 2073 LocalVariable* phase_param = LookupPhaseParameter(); |
2051 AstNode* phase_value = new LoadLocalNode(token_index_, *phase_param); | 2074 AstNode* phase_value = new LoadLocalNode(TokenPos(), *phase_param); |
2052 AstNode* phase_check = | 2075 AstNode* phase_check = |
2053 new BinaryOpNode(token_index_, Token::kBIT_AND, | 2076 new BinaryOpNode(TokenPos(), Token::kBIT_AND, |
2054 phase_value, | 2077 phase_value, |
2055 new LiteralNode(token_index_, | 2078 new LiteralNode(TokenPos(), |
2056 Smi::ZoneHandle(Smi::New(Function::kCtorPhaseBody)))); | 2079 Smi::ZoneHandle(Smi::New(Function::kCtorPhaseBody)))); |
2057 AstNode* comparison = | 2080 AstNode* comparison = |
2058 new ComparisonNode(token_index_, Token::kNE_STRICT, | 2081 new ComparisonNode(TokenPos(), Token::kNE_STRICT, |
2059 phase_check, | 2082 phase_check, |
2060 new LiteralNode(token_index_, | 2083 new LiteralNode(TokenPos(), |
2061 Smi::ZoneHandle(Smi::New(0)))); | 2084 Smi::ZoneHandle(Smi::New(0)))); |
2062 AstNode* guarded_block_statements = | 2085 AstNode* guarded_block_statements = |
2063 new IfNode(token_index_, comparison, ctor_block, NULL); | 2086 new IfNode(TokenPos(), comparison, ctor_block, NULL); |
2064 current_block_->statements->Add(guarded_block_statements); | 2087 current_block_->statements->Add(guarded_block_statements); |
2065 } | 2088 } |
2066 | 2089 |
2067 SequenceNode* statements = CloseBlock(); | 2090 SequenceNode* statements = CloseBlock(); |
2068 return statements; | 2091 return statements; |
2069 } | 2092 } |
2070 | 2093 |
2071 | 2094 |
2072 // Parser is at the opening parenthesis of the formal parameter | 2095 // Parser is at the opening parenthesis of the formal parameter |
2073 // declaration of the function or constructor. | 2096 // declaration of the function or constructor. |
(...skipping 11 matching lines...) Expand all Loading... |
2085 ParamList params; | 2108 ParamList params; |
2086 // Static functions do not have a receiver. | 2109 // Static functions do not have a receiver. |
2087 // An instance closure may capture and access the receiver, but via the | 2110 // An instance closure may capture and access the receiver, but via the |
2088 // context and not via the first formal parameter. | 2111 // context and not via the first formal parameter. |
2089 // The first parameter of a factory is the AbstractTypeArguments vector of the | 2112 // The first parameter of a factory is the AbstractTypeArguments vector of the |
2090 // type of the instance to be allocated. We name this hidden parameter 'this'. | 2113 // type of the instance to be allocated. We name this hidden parameter 'this'. |
2091 const bool has_receiver = !func.IsClosureFunction() && | 2114 const bool has_receiver = !func.IsClosureFunction() && |
2092 (!func.is_static() || func.IsFactory()); | 2115 (!func.is_static() || func.IsFactory()); |
2093 const bool allow_explicit_default_values = true; | 2116 const bool allow_explicit_default_values = true; |
2094 if (has_receiver) { | 2117 if (has_receiver) { |
2095 params.AddReceiver(token_index_); | 2118 params.AddReceiver(TokenPos()); |
2096 } | 2119 } |
2097 ASSERT(CurrentToken() == Token::kLPAREN); | 2120 ASSERT(CurrentToken() == Token::kLPAREN); |
2098 ParseFormalParameterList(allow_explicit_default_values, ¶ms); | 2121 ParseFormalParameterList(allow_explicit_default_values, ¶ms); |
2099 | 2122 |
2100 // The number of parameters and their type are not yet set in local functions, | 2123 // The number of parameters and their type are not yet set in local functions, |
2101 // since they are not 'top-level' parsed. | 2124 // since they are not 'top-level' parsed. |
2102 if (func.IsLocalFunction()) { | 2125 if (func.IsLocalFunction()) { |
2103 AddFormalParamsToFunction(¶ms, func); | 2126 AddFormalParamsToFunction(¶ms, func); |
2104 } | 2127 } |
2105 SetupDefaultsForOptionalParams(¶ms, default_parameter_values); | 2128 SetupDefaultsForOptionalParams(¶ms, default_parameter_values); |
(...skipping 27 matching lines...) Expand all Loading... |
2133 } | 2156 } |
2134 } | 2157 } |
2135 | 2158 |
2136 OpenBlock(); // Open a nested scope for the outermost function block. | 2159 OpenBlock(); // Open a nested scope for the outermost function block. |
2137 if (CurrentToken() == Token::kLBRACE) { | 2160 if (CurrentToken() == Token::kLBRACE) { |
2138 ConsumeToken(); | 2161 ConsumeToken(); |
2139 ParseStatementSequence(); | 2162 ParseStatementSequence(); |
2140 ExpectToken(Token::kRBRACE); | 2163 ExpectToken(Token::kRBRACE); |
2141 } else if (CurrentToken() == Token::kARROW) { | 2164 } else if (CurrentToken() == Token::kARROW) { |
2142 ConsumeToken(); | 2165 ConsumeToken(); |
2143 const intptr_t expr_pos = token_index_; | 2166 const intptr_t expr_pos = TokenPos(); |
2144 AstNode* expr = ParseExpr(kAllowConst); | 2167 AstNode* expr = ParseExpr(kAllowConst); |
2145 ASSERT(expr != NULL); | 2168 ASSERT(expr != NULL); |
2146 current_block_->statements->Add(new ReturnNode(expr_pos, expr)); | 2169 current_block_->statements->Add(new ReturnNode(expr_pos, expr)); |
2147 } else if (IsLiteral("native")) { | 2170 } else if (IsLiteral("native")) { |
2148 ParseNativeFunctionBlock(¶ms, func); | 2171 ParseNativeFunctionBlock(¶ms, func); |
2149 } else { | 2172 } else { |
2150 UnexpectedToken(); | 2173 UnexpectedToken(); |
2151 } | 2174 } |
2152 SequenceNode* body = CloseBlock(); | 2175 SequenceNode* body = CloseBlock(); |
2153 current_block_->statements->Add(body); | 2176 current_block_->statements->Add(body); |
(...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2201 SetAllowFunctionLiterals(true); | 2224 SetAllowFunctionLiterals(true); |
2202 } | 2225 } |
2203 } while (CurrentToken() == Token::kCOMMA); | 2226 } while (CurrentToken() == Token::kCOMMA); |
2204 } | 2227 } |
2205 | 2228 |
2206 | 2229 |
2207 void Parser::ParseQualIdent(QualIdent* qual_ident) { | 2230 void Parser::ParseQualIdent(QualIdent* qual_ident) { |
2208 TRACE_PARSER("ParseQualIdent"); | 2231 TRACE_PARSER("ParseQualIdent"); |
2209 ASSERT(IsIdentifier()); | 2232 ASSERT(IsIdentifier()); |
2210 ASSERT(!current_class().IsNull()); | 2233 ASSERT(!current_class().IsNull()); |
2211 qual_ident->ident_pos = token_index_; | 2234 qual_ident->ident_pos = TokenPos(); |
2212 qual_ident->ident = CurrentLiteral(); | 2235 qual_ident->ident = CurrentLiteral(); |
2213 qual_ident->lib_prefix = NULL; | 2236 qual_ident->lib_prefix = NULL; |
2214 ConsumeToken(); | 2237 ConsumeToken(); |
2215 if (CurrentToken() == Token::kPERIOD) { | 2238 if (CurrentToken() == Token::kPERIOD) { |
2216 // An identifier cannot be resolved in a local scope when top level parsing. | 2239 // An identifier cannot be resolved in a local scope when top level parsing. |
2217 if (is_top_level_ || | 2240 if (is_top_level_ || |
2218 !ResolveIdentInLocalScope(qual_ident->ident_pos, | 2241 !ResolveIdentInLocalScope(qual_ident->ident_pos, |
2219 *(qual_ident->ident), | 2242 *(qual_ident->ident), |
2220 NULL)) { | 2243 NULL)) { |
2221 LibraryPrefix& lib_prefix = LibraryPrefix::ZoneHandle(); | 2244 LibraryPrefix& lib_prefix = LibraryPrefix::ZoneHandle(); |
2222 lib_prefix = current_class().LookupLibraryPrefix(*(qual_ident->ident)); | 2245 lib_prefix = current_class().LookupLibraryPrefix(*(qual_ident->ident)); |
2223 if (!lib_prefix.IsNull()) { | 2246 if (!lib_prefix.IsNull()) { |
2224 // We have a library prefix qualified identifier, unless the prefix is | 2247 // We have a library prefix qualified identifier, unless the prefix is |
2225 // shadowed by a type parameter in scope. | 2248 // shadowed by a type parameter in scope. |
2226 const Class& scope_class = Class::Handle(TypeParametersScopeClass()); | 2249 const Class& scope_class = Class::Handle(TypeParametersScopeClass()); |
2227 if (scope_class.IsNull() || | 2250 if (scope_class.IsNull() || |
2228 (scope_class.LookupTypeParameter(*(qual_ident->ident), | 2251 (scope_class.LookupTypeParameter(*(qual_ident->ident), |
2229 token_index_) == | 2252 TokenPos()) == |
2230 TypeParameter::null())) { | 2253 TypeParameter::null())) { |
2231 ConsumeToken(); // Consume the kPERIOD token. | 2254 ConsumeToken(); // Consume the kPERIOD token. |
2232 qual_ident->lib_prefix = &lib_prefix; | 2255 qual_ident->lib_prefix = &lib_prefix; |
2233 qual_ident->ident_pos = token_index_; | 2256 qual_ident->ident_pos = TokenPos(); |
2234 qual_ident->ident = | 2257 qual_ident->ident = |
2235 ExpectIdentifier("identifier expected after '.'"); | 2258 ExpectIdentifier("identifier expected after '.'"); |
2236 } | 2259 } |
2237 } | 2260 } |
2238 } | 2261 } |
2239 } | 2262 } |
2240 } | 2263 } |
2241 | 2264 |
2242 | 2265 |
2243 void Parser::ParseMethodOrConstructor(ClassDesc* members, MemberDesc* method) { | 2266 void Parser::ParseMethodOrConstructor(ClassDesc* members, MemberDesc* method) { |
2244 TRACE_PARSER("ParseMethodOrConstructor"); | 2267 TRACE_PARSER("ParseMethodOrConstructor"); |
2245 ASSERT(CurrentToken() == Token::kLPAREN); | 2268 ASSERT(CurrentToken() == Token::kLPAREN); |
2246 intptr_t method_pos = this->token_index_; | 2269 intptr_t method_pos = this->TokenPos(); |
2247 ASSERT(method->type != NULL); | 2270 ASSERT(method->type != NULL); |
2248 ASSERT(method->name_pos > 0); | 2271 ASSERT(method->name_pos > 0); |
2249 ASSERT(current_member_ == method); | 2272 ASSERT(current_member_ == method); |
2250 | 2273 |
2251 if (method->has_var) { | 2274 if (method->has_var) { |
2252 ErrorMsg(method->name_pos, "keyword var not allowed for methods"); | 2275 ErrorMsg(method->name_pos, "keyword var not allowed for methods"); |
2253 } | 2276 } |
2254 if (method->has_final) { | 2277 if (method->has_final) { |
2255 ErrorMsg(method->name_pos, "'final' not allowed for methods"); | 2278 ErrorMsg(method->name_pos, "'final' not allowed for methods"); |
2256 } | 2279 } |
(...skipping 22 matching lines...) Expand all Loading... |
2279 "field or method '%s' already defined", method->name->ToCString()); | 2302 "field or method '%s' already defined", method->name->ToCString()); |
2280 } | 2303 } |
2281 | 2304 |
2282 // Parse the formal parameters. | 2305 // Parse the formal parameters. |
2283 // The first parameter of factory methods is an implicit parameter called | 2306 // The first parameter of factory methods is an implicit parameter called |
2284 // 'this' of type AbstractTypeArguments. | 2307 // 'this' of type AbstractTypeArguments. |
2285 const bool has_this_param = | 2308 const bool has_this_param = |
2286 !method->has_static || method->IsConstructor() || method->has_factory; | 2309 !method->has_static || method->IsConstructor() || method->has_factory; |
2287 const bool are_implicitly_final = method->has_const; | 2310 const bool are_implicitly_final = method->has_const; |
2288 const bool allow_explicit_default_values = true; | 2311 const bool allow_explicit_default_values = true; |
2289 const intptr_t formal_param_pos = token_index_; | 2312 const intptr_t formal_param_pos = TokenPos(); |
2290 method->params.Clear(); | 2313 method->params.Clear(); |
2291 if (has_this_param) { | 2314 if (has_this_param) { |
2292 method->params.AddReceiver(formal_param_pos); | 2315 method->params.AddReceiver(formal_param_pos); |
2293 } | 2316 } |
2294 // Constructors have an implicit parameter for the construction phase. | 2317 // Constructors have an implicit parameter for the construction phase. |
2295 if (method->IsConstructor()) { | 2318 if (method->IsConstructor()) { |
2296 method->params.AddFinalParameter( | 2319 method->params.AddFinalParameter( |
2297 token_index_, | 2320 TokenPos(), |
2298 kPhaseParameterName, | 2321 kPhaseParameterName, |
2299 &Type::ZoneHandle(Type::DynamicType())); | 2322 &Type::ZoneHandle(Type::DynamicType())); |
2300 } | 2323 } |
2301 if (are_implicitly_final) { | 2324 if (are_implicitly_final) { |
2302 method->params.SetImplicitlyFinal(); | 2325 method->params.SetImplicitlyFinal(); |
2303 } | 2326 } |
2304 ParseFormalParameterList(allow_explicit_default_values, &method->params); | 2327 ParseFormalParameterList(allow_explicit_default_values, &method->params); |
2305 if (method->IsGetter() || method->IsSetter()) { | 2328 if (method->IsGetter() || method->IsSetter()) { |
2306 int expected_num_parameters = 0; | 2329 int expected_num_parameters = 0; |
2307 if (method->IsGetter()) { | 2330 if (method->IsGetter()) { |
(...skipping 68 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2376 ErrorMsg(method->name_pos, | 2399 ErrorMsg(method->name_pos, |
2377 "function body not allowed in interface declaration"); | 2400 "function body not allowed in interface declaration"); |
2378 } | 2401 } |
2379 if (CurrentToken() == Token::kLBRACE) { | 2402 if (CurrentToken() == Token::kLBRACE) { |
2380 SkipBlock(); | 2403 SkipBlock(); |
2381 } else { | 2404 } else { |
2382 ConsumeToken(); | 2405 ConsumeToken(); |
2383 SkipExpr(); | 2406 SkipExpr(); |
2384 ExpectSemicolon(); | 2407 ExpectSemicolon(); |
2385 } | 2408 } |
2386 method_end_pos = token_index_; | 2409 method_end_pos = TokenPos(); |
2387 } else if (IsLiteral("native")) { | 2410 } else if (IsLiteral("native")) { |
2388 if (method->has_abstract) { | 2411 if (method->has_abstract) { |
2389 ErrorMsg(method->name_pos, | 2412 ErrorMsg(method->name_pos, |
2390 "abstract method '%s' may not have function body", | 2413 "abstract method '%s' may not have function body", |
2391 method->name->ToCString()); | 2414 method->name->ToCString()); |
2392 } else if (members->is_interface()) { | 2415 } else if (members->is_interface()) { |
2393 ErrorMsg(method->name_pos, | 2416 ErrorMsg(method->name_pos, |
2394 "function body not allowed in interface declaration"); | 2417 "function body not allowed in interface declaration"); |
2395 } else if (method->IsConstructor() && method->has_const) { | 2418 } else if (method->IsConstructor() && method->has_const) { |
2396 ErrorMsg(method->name_pos, | 2419 ErrorMsg(method->name_pos, |
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2434 } else { | 2457 } else { |
2435 function_kind = RawFunction::kFunction; | 2458 function_kind = RawFunction::kFunction; |
2436 } | 2459 } |
2437 Function& func = Function::Handle( | 2460 Function& func = Function::Handle( |
2438 Function::New(*method->name, | 2461 Function::New(*method->name, |
2439 function_kind, | 2462 function_kind, |
2440 method->has_static, | 2463 method->has_static, |
2441 method->has_const, | 2464 method->has_const, |
2442 method_pos)); | 2465 method_pos)); |
2443 func.set_result_type(*method->type); | 2466 func.set_result_type(*method->type); |
2444 func.set_end_token_index(method_end_pos); | 2467 func.set_end_token_pos(method_end_pos); |
2445 | 2468 |
2446 // No need to resolve parameter types yet, or add parameters to local scope. | 2469 // No need to resolve parameter types yet, or add parameters to local scope. |
2447 ASSERT(is_top_level_); | 2470 ASSERT(is_top_level_); |
2448 AddFormalParamsToFunction(&method->params, func); | 2471 AddFormalParamsToFunction(&method->params, func); |
2449 members->AddFunction(func); | 2472 members->AddFunction(func); |
2450 } | 2473 } |
2451 | 2474 |
2452 | 2475 |
2453 void Parser::ParseFieldDefinition(ClassDesc* members, MemberDesc* field) { | 2476 void Parser::ParseFieldDefinition(ClassDesc* members, MemberDesc* field) { |
2454 TRACE_PARSER("ParseFieldDefinition"); | 2477 TRACE_PARSER("ParseFieldDefinition"); |
(...skipping 61 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2516 members->AddFunction(getter); | 2539 members->AddFunction(getter); |
2517 } | 2540 } |
2518 | 2541 |
2519 // For instance fields, we create implicit getter and setter methods. | 2542 // For instance fields, we create implicit getter and setter methods. |
2520 if (!field->has_static) { | 2543 if (!field->has_static) { |
2521 String& getter_name = String::Handle(Field::GetterSymbol(*field->name)); | 2544 String& getter_name = String::Handle(Field::GetterSymbol(*field->name)); |
2522 getter = Function::New(getter_name, RawFunction::kImplicitGetter, | 2545 getter = Function::New(getter_name, RawFunction::kImplicitGetter, |
2523 field->has_static, field->has_final, | 2546 field->has_static, field->has_final, |
2524 field->name_pos); | 2547 field->name_pos); |
2525 ParamList params; | 2548 ParamList params; |
2526 params.AddReceiver(token_index_); | 2549 params.AddReceiver(TokenPos()); |
2527 getter.set_result_type(*field->type); | 2550 getter.set_result_type(*field->type); |
2528 AddFormalParamsToFunction(¶ms, getter); | 2551 AddFormalParamsToFunction(¶ms, getter); |
2529 members->AddFunction(getter); | 2552 members->AddFunction(getter); |
2530 if (!field->has_final) { | 2553 if (!field->has_final) { |
2531 // Build a setter accessor for non-const fields. | 2554 // Build a setter accessor for non-const fields. |
2532 String& setter_name = String::Handle(Field::SetterSymbol(*field->name)); | 2555 String& setter_name = String::Handle(Field::SetterSymbol(*field->name)); |
2533 setter = Function::New(setter_name, RawFunction::kImplicitSetter, | 2556 setter = Function::New(setter_name, RawFunction::kImplicitSetter, |
2534 field->has_static, field->has_final, | 2557 field->has_static, field->has_final, |
2535 field->name_pos); | 2558 field->name_pos); |
2536 ParamList params; | 2559 ParamList params; |
2537 params.AddReceiver(token_index_); | 2560 params.AddReceiver(TokenPos()); |
2538 params.AddFinalParameter(token_index_, "value", field->type); | 2561 params.AddFinalParameter(TokenPos(), "value", field->type); |
2539 setter.set_result_type(Type::Handle(Type::VoidType())); | 2562 setter.set_result_type(Type::Handle(Type::VoidType())); |
2540 AddFormalParamsToFunction(¶ms, setter); | 2563 AddFormalParamsToFunction(¶ms, setter); |
2541 members->AddFunction(setter); | 2564 members->AddFunction(setter); |
2542 } | 2565 } |
2543 } | 2566 } |
2544 | 2567 |
2545 if (CurrentToken() != Token::kCOMMA) { | 2568 if (CurrentToken() != Token::kCOMMA) { |
2546 break; | 2569 break; |
2547 } | 2570 } |
2548 ConsumeToken(); | 2571 ConsumeToken(); |
2549 field->name_pos = this->token_index_; | 2572 field->name_pos = this->TokenPos(); |
2550 field->name = ExpectIdentifier("field name expected"); | 2573 field->name = ExpectIdentifier("field name expected"); |
2551 } | 2574 } |
2552 ExpectSemicolon(); | 2575 ExpectSemicolon(); |
2553 } | 2576 } |
2554 | 2577 |
2555 | 2578 |
2556 void Parser::CheckOperatorArity( | 2579 void Parser::CheckOperatorArity( |
2557 const MemberDesc& member, Token::Kind operator_token) { | 2580 const MemberDesc& member, Token::Kind operator_token) { |
2558 intptr_t expected_num_parameters; // Includes receiver. | 2581 intptr_t expected_num_parameters; // Includes receiver. |
2559 if (operator_token == Token::kASSIGN_INDEX) { | 2582 if (operator_token == Token::kASSIGN_INDEX) { |
(...skipping 101 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2661 } | 2684 } |
2662 const Object& result_type_class = Object::Handle( | 2685 const Object& result_type_class = Object::Handle( |
2663 UnresolvedClass::New(lib_prefix, | 2686 UnresolvedClass::New(lib_prefix, |
2664 *factory_name.ident, | 2687 *factory_name.ident, |
2665 factory_name.ident_pos)); | 2688 factory_name.ident_pos)); |
2666 // The type arguments of the result type are set during finalization. | 2689 // The type arguments of the result type are set during finalization. |
2667 member.type = &Type::ZoneHandle(Type::New(result_type_class, | 2690 member.type = &Type::ZoneHandle(Type::New(result_type_class, |
2668 TypeArguments::Handle(), | 2691 TypeArguments::Handle(), |
2669 factory_name.ident_pos)); | 2692 factory_name.ident_pos)); |
2670 } else { | 2693 } else { |
2671 member.name_pos = token_index_; | 2694 member.name_pos = TokenPos(); |
2672 member.name = CurrentLiteral(); | 2695 member.name = CurrentLiteral(); |
2673 ConsumeToken(); | 2696 ConsumeToken(); |
2674 } | 2697 } |
2675 // We must be dealing with a constructor or named constructor. | 2698 // We must be dealing with a constructor or named constructor. |
2676 member.kind = RawFunction::kConstructor; | 2699 member.kind = RawFunction::kConstructor; |
2677 String& ctor_suffix = String::ZoneHandle(String::NewSymbol(".")); | 2700 String& ctor_suffix = String::ZoneHandle(String::NewSymbol(".")); |
2678 if (CurrentToken() == Token::kPERIOD) { | 2701 if (CurrentToken() == Token::kPERIOD) { |
2679 // Named constructor. | 2702 // Named constructor. |
2680 ConsumeToken(); | 2703 ConsumeToken(); |
2681 const String* name = ExpectIdentifier("identifier expected"); | 2704 const String* name = ExpectIdentifier("identifier expected"); |
(...skipping 17 matching lines...) Expand all Loading... |
2699 if (CurrentToken() != Token::kLPAREN) { | 2722 if (CurrentToken() != Token::kLPAREN) { |
2700 ErrorMsg("left parenthesis expected"); | 2723 ErrorMsg("left parenthesis expected"); |
2701 } | 2724 } |
2702 } else if ((CurrentToken() == Token::kGET) && !member.has_var && | 2725 } else if ((CurrentToken() == Token::kGET) && !member.has_var && |
2703 (LookaheadToken(1) != Token::kLPAREN) && | 2726 (LookaheadToken(1) != Token::kLPAREN) && |
2704 (LookaheadToken(1) != Token::kASSIGN) && | 2727 (LookaheadToken(1) != Token::kASSIGN) && |
2705 (LookaheadToken(1) != Token::kCOMMA) && | 2728 (LookaheadToken(1) != Token::kCOMMA) && |
2706 (LookaheadToken(1) != Token::kSEMICOLON)) { | 2729 (LookaheadToken(1) != Token::kSEMICOLON)) { |
2707 ConsumeToken(); | 2730 ConsumeToken(); |
2708 member.kind = RawFunction::kGetterFunction; | 2731 member.kind = RawFunction::kGetterFunction; |
2709 member.name_pos = this->token_index_; | 2732 member.name_pos = this->TokenPos(); |
2710 member.name = ExpectIdentifier("identifier expected"); | 2733 member.name = ExpectIdentifier("identifier expected"); |
2711 if (CurrentToken() != Token::kLPAREN) { | 2734 if (CurrentToken() != Token::kLPAREN) { |
2712 ErrorMsg("'(' expected"); | 2735 ErrorMsg("'(' expected"); |
2713 } | 2736 } |
2714 // If the result type was not specified, it will be set to DynamicType. | 2737 // If the result type was not specified, it will be set to DynamicType. |
2715 } else if ((CurrentToken() == Token::kSET) && !member.has_var && | 2738 } else if ((CurrentToken() == Token::kSET) && !member.has_var && |
2716 (LookaheadToken(1) != Token::kLPAREN) && | 2739 (LookaheadToken(1) != Token::kLPAREN) && |
2717 (LookaheadToken(1) != Token::kASSIGN) && | 2740 (LookaheadToken(1) != Token::kASSIGN) && |
2718 (LookaheadToken(1) != Token::kCOMMA) && | 2741 (LookaheadToken(1) != Token::kCOMMA) && |
2719 (LookaheadToken(1) != Token::kSEMICOLON)) { | 2742 (LookaheadToken(1) != Token::kSEMICOLON)) { |
2720 ConsumeToken(); | 2743 ConsumeToken(); |
2721 member.kind = RawFunction::kSetterFunction; | 2744 member.kind = RawFunction::kSetterFunction; |
2722 member.name_pos = this->token_index_; | 2745 member.name_pos = this->TokenPos(); |
2723 member.name = ExpectIdentifier("identifier expected"); | 2746 member.name = ExpectIdentifier("identifier expected"); |
2724 if (CurrentToken() != Token::kLPAREN) { | 2747 if (CurrentToken() != Token::kLPAREN) { |
2725 ErrorMsg("'(' expected"); | 2748 ErrorMsg("'(' expected"); |
2726 } | 2749 } |
2727 // The grammar allows a return type, so member.type is not always NULL here. | 2750 // The grammar allows a return type, so member.type is not always NULL here. |
2728 // If no return type is specified, the return type of the setter is Dynamic. | 2751 // If no return type is specified, the return type of the setter is Dynamic. |
2729 if (member.type == NULL) { | 2752 if (member.type == NULL) { |
2730 member.type = &Type::ZoneHandle(Type::DynamicType()); | 2753 member.type = &Type::ZoneHandle(Type::DynamicType()); |
2731 } | 2754 } |
2732 } else if ((CurrentToken() == Token::kOPERATOR) && !member.has_var && | 2755 } else if ((CurrentToken() == Token::kOPERATOR) && !member.has_var && |
2733 (LookaheadToken(1) != Token::kLPAREN) && | 2756 (LookaheadToken(1) != Token::kLPAREN) && |
2734 (LookaheadToken(1) != Token::kASSIGN) && | 2757 (LookaheadToken(1) != Token::kASSIGN) && |
2735 (LookaheadToken(1) != Token::kCOMMA) && | 2758 (LookaheadToken(1) != Token::kCOMMA) && |
2736 (LookaheadToken(1) != Token::kSEMICOLON)) { | 2759 (LookaheadToken(1) != Token::kSEMICOLON)) { |
2737 ConsumeToken(); | 2760 ConsumeToken(); |
2738 if (!Token::CanBeOverloaded(CurrentToken())) { | 2761 if (!Token::CanBeOverloaded(CurrentToken())) { |
2739 ErrorMsg("invalid operator overloading"); | 2762 ErrorMsg("invalid operator overloading"); |
2740 } | 2763 } |
2741 if (member.has_static) { | 2764 if (member.has_static) { |
2742 ErrorMsg("operator overloading functions cannot be static"); | 2765 ErrorMsg("operator overloading functions cannot be static"); |
2743 } | 2766 } |
2744 operator_token = CurrentToken(); | 2767 operator_token = CurrentToken(); |
2745 member.kind = RawFunction::kFunction; | 2768 member.kind = RawFunction::kFunction; |
2746 member.name_pos = this->token_index_; | 2769 member.name_pos = this->TokenPos(); |
2747 member.name = | 2770 member.name = |
2748 &String::ZoneHandle(String::NewSymbol(Token::Str(operator_token))); | 2771 &String::ZoneHandle(String::NewSymbol(Token::Str(operator_token))); |
2749 ConsumeToken(); | 2772 ConsumeToken(); |
2750 } else if (IsIdentifier()) { | 2773 } else if (IsIdentifier()) { |
2751 member.name = CurrentLiteral(); | 2774 member.name = CurrentLiteral(); |
2752 member.name_pos = token_index_; | 2775 member.name_pos = TokenPos(); |
2753 ConsumeToken(); | 2776 ConsumeToken(); |
2754 } else { | 2777 } else { |
2755 ErrorMsg("identifier expected"); | 2778 ErrorMsg("identifier expected"); |
2756 } | 2779 } |
2757 | 2780 |
2758 ASSERT(member.name != NULL); | 2781 ASSERT(member.name != NULL); |
2759 if (CurrentToken() == Token::kLPAREN) { | 2782 if (CurrentToken() == Token::kLPAREN) { |
2760 if (members->is_interface() && member.has_static) { | 2783 if (members->is_interface() && member.has_static) { |
2761 if (member.has_factory) { | 2784 if (member.has_factory) { |
2762 ErrorMsg("factory constructors are not allowed in interfaces"); | 2785 ErrorMsg("factory constructors are not allowed in interfaces"); |
(...skipping 27 matching lines...) Expand all Loading... |
2790 } else { | 2813 } else { |
2791 UnexpectedToken(); | 2814 UnexpectedToken(); |
2792 } | 2815 } |
2793 current_member_ = NULL; | 2816 current_member_ = NULL; |
2794 members->AddMember(member); | 2817 members->AddMember(member); |
2795 } | 2818 } |
2796 | 2819 |
2797 | 2820 |
2798 void Parser::ParseClassDefinition(const GrowableObjectArray& pending_classes) { | 2821 void Parser::ParseClassDefinition(const GrowableObjectArray& pending_classes) { |
2799 TRACE_PARSER("ParseClassDefinition"); | 2822 TRACE_PARSER("ParseClassDefinition"); |
2800 const intptr_t class_pos = token_index_; | 2823 const intptr_t class_pos = TokenPos(); |
2801 ExpectToken(Token::kCLASS); | 2824 ExpectToken(Token::kCLASS); |
2802 const intptr_t classname_pos = token_index_; | 2825 const intptr_t classname_pos = TokenPos(); |
2803 String& class_name = *ExpectTypeIdentifier("class name expected"); | 2826 String& class_name = *ExpectTypeIdentifier("class name expected"); |
2804 if (FLAG_trace_parser) { | 2827 if (FLAG_trace_parser) { |
2805 OS::Print("TopLevel parsing class '%s'\n", class_name.ToCString()); | 2828 OS::Print("TopLevel parsing class '%s'\n", class_name.ToCString()); |
2806 } | 2829 } |
2807 Class& cls = Class::Handle(); | 2830 Class& cls = Class::Handle(); |
2808 Object& obj = Object::Handle(library_.LookupObject(class_name)); | 2831 Object& obj = Object::Handle(library_.LookupObject(class_name)); |
2809 if (obj.IsNull()) { | 2832 if (obj.IsNull()) { |
2810 cls = Class::New(class_name, script_, classname_pos); | 2833 cls = Class::New(class_name, script_, classname_pos); |
2811 library_.AddClass(cls); | 2834 library_.AddClass(cls); |
2812 } else { | 2835 } else { |
(...skipping 10 matching lines...) Expand all Loading... |
2823 class_name.ToCString()); | 2846 class_name.ToCString()); |
2824 } | 2847 } |
2825 } | 2848 } |
2826 ASSERT(!cls.IsNull()); | 2849 ASSERT(!cls.IsNull()); |
2827 ASSERT(cls.functions() == Array::Empty()); | 2850 ASSERT(cls.functions() == Array::Empty()); |
2828 set_current_class(cls); | 2851 set_current_class(cls); |
2829 ParseTypeParameters(cls); | 2852 ParseTypeParameters(cls); |
2830 Type& super_type = Type::Handle(); | 2853 Type& super_type = Type::Handle(); |
2831 if (CurrentToken() == Token::kEXTENDS) { | 2854 if (CurrentToken() == Token::kEXTENDS) { |
2832 ConsumeToken(); | 2855 ConsumeToken(); |
2833 const intptr_t type_pos = token_index_; | 2856 const intptr_t type_pos = TokenPos(); |
2834 const AbstractType& type = AbstractType::Handle( | 2857 const AbstractType& type = AbstractType::Handle( |
2835 ParseType(ClassFinalizer::kTryResolve)); | 2858 ParseType(ClassFinalizer::kTryResolve)); |
2836 if (type.IsTypeParameter()) { | 2859 if (type.IsTypeParameter()) { |
2837 ErrorMsg(type_pos, | 2860 ErrorMsg(type_pos, |
2838 "class '%s' may not extend type parameter '%s'", | 2861 "class '%s' may not extend type parameter '%s'", |
2839 class_name.ToCString(), | 2862 class_name.ToCString(), |
2840 String::Handle(type.Name()).ToCString()); | 2863 String::Handle(type.Name()).ToCString()); |
2841 } | 2864 } |
2842 super_type ^= type.raw(); | 2865 super_type ^= type.raw(); |
2843 if (super_type.IsInterfaceType()) { | 2866 if (super_type.IsInterfaceType()) { |
2844 ErrorMsg(type_pos, | 2867 ErrorMsg(type_pos, |
2845 "class '%s' may implement, but cannot extend interface '%s'", | 2868 "class '%s' may implement, but cannot extend interface '%s'", |
2846 class_name.ToCString(), | 2869 class_name.ToCString(), |
2847 String::Handle(super_type.Name()).ToCString()); | 2870 String::Handle(super_type.Name()).ToCString()); |
2848 } | 2871 } |
2849 } else { | 2872 } else { |
2850 // No extends clause: Implicitly extend Object. | 2873 // No extends clause: Implicitly extend Object. |
2851 super_type = Type::ObjectType(); | 2874 super_type = Type::ObjectType(); |
2852 } | 2875 } |
2853 ASSERT(!super_type.IsNull()); | 2876 ASSERT(!super_type.IsNull()); |
2854 cls.set_super_type(super_type); | 2877 cls.set_super_type(super_type); |
2855 | 2878 |
2856 if (CurrentToken() == Token::kIMPLEMENTS) { | 2879 if (CurrentToken() == Token::kIMPLEMENTS) { |
2857 Array& interfaces = Array::Handle(); | 2880 Array& interfaces = Array::Handle(); |
2858 const intptr_t interfaces_pos = token_index_; | 2881 const intptr_t interfaces_pos = TokenPos(); |
2859 interfaces = ParseInterfaceList(); | 2882 interfaces = ParseInterfaceList(); |
2860 AddInterfaces(interfaces_pos, cls, interfaces); | 2883 AddInterfaces(interfaces_pos, cls, interfaces); |
2861 } | 2884 } |
2862 | 2885 |
2863 ExpectToken(Token::kLBRACE); | 2886 ExpectToken(Token::kLBRACE); |
2864 ClassDesc members(cls, class_name, false, class_pos); | 2887 ClassDesc members(cls, class_name, false, class_pos); |
2865 while (CurrentToken() != Token::kRBRACE) { | 2888 while (CurrentToken() != Token::kRBRACE) { |
2866 ParseClassMemberDefinition(&members); | 2889 ParseClassMemberDefinition(&members); |
2867 } | 2890 } |
2868 ExpectToken(Token::kRBRACE); | 2891 ExpectToken(Token::kRBRACE); |
(...skipping 26 matching lines...) Expand all Loading... |
2895 // The token position for the implicit constructor is the 'class' | 2918 // The token position for the implicit constructor is the 'class' |
2896 // keyword of the constructor's class. | 2919 // keyword of the constructor's class. |
2897 Function& ctor = Function::Handle( | 2920 Function& ctor = Function::Handle( |
2898 Function::New(ctor_name, | 2921 Function::New(ctor_name, |
2899 RawFunction::kConstructor, | 2922 RawFunction::kConstructor, |
2900 /* is_static = */ false, | 2923 /* is_static = */ false, |
2901 /* is_const = */ false, | 2924 /* is_const = */ false, |
2902 class_desc->token_pos())); | 2925 class_desc->token_pos())); |
2903 ParamList params; | 2926 ParamList params; |
2904 // Add implicit 'this' parameter. | 2927 // Add implicit 'this' parameter. |
2905 params.AddReceiver(token_index_); | 2928 params.AddReceiver(TokenPos()); |
2906 // Add implicit parameter for construction phase. | 2929 // Add implicit parameter for construction phase. |
2907 params.AddFinalParameter( | 2930 params.AddFinalParameter( |
2908 token_index_, | 2931 TokenPos(), |
2909 kPhaseParameterName, | 2932 kPhaseParameterName, |
2910 &Type::ZoneHandle(Type::DynamicType())); | 2933 &Type::ZoneHandle(Type::DynamicType())); |
2911 | 2934 |
2912 AddFormalParamsToFunction(¶ms, ctor); | 2935 AddFormalParamsToFunction(¶ms, ctor); |
2913 // The body of the constructor cannot modify the type arguments of the | 2936 // The body of the constructor cannot modify the type arguments of the |
2914 // constructed instance, which is passed in as a hidden parameter. | 2937 // constructed instance, which is passed in as a hidden parameter. |
2915 // Therefore, there is no need to set the result type to be checked. | 2938 // Therefore, there is no need to set the result type to be checked. |
2916 const AbstractType& result_type = Type::ZoneHandle(Type::DynamicType()); | 2939 const AbstractType& result_type = Type::ZoneHandle(Type::DynamicType()); |
2917 ctor.set_result_type(result_type); | 2940 ctor.set_result_type(result_type); |
2918 class_desc->AddFunction(ctor); | 2941 class_desc->AddFunction(ctor); |
(...skipping 26 matching lines...) Expand all Loading... |
2945 | 2968 |
2946 | 2969 |
2947 // Look ahead to detect if we are seeing ident [ TypeParameters ] "(". | 2970 // Look ahead to detect if we are seeing ident [ TypeParameters ] "(". |
2948 // We need this lookahead to distinguish between the optional return type | 2971 // We need this lookahead to distinguish between the optional return type |
2949 // and the alias name of a function type alias. | 2972 // and the alias name of a function type alias. |
2950 // Token position remains unchanged. | 2973 // Token position remains unchanged. |
2951 bool Parser::IsFunctionTypeAliasName() { | 2974 bool Parser::IsFunctionTypeAliasName() { |
2952 if (IsIdentifier() && (LookaheadToken(1) == Token::kLPAREN)) { | 2975 if (IsIdentifier() && (LookaheadToken(1) == Token::kLPAREN)) { |
2953 return true; | 2976 return true; |
2954 } | 2977 } |
2955 const intptr_t saved_pos = token_index_; | 2978 const intptr_t saved_pos = TokenPos(); |
2956 bool is_alias_name = false; | 2979 bool is_alias_name = false; |
2957 if (IsIdentifier() && (LookaheadToken(1) == Token::kLT)) { | 2980 if (IsIdentifier() && (LookaheadToken(1) == Token::kLT)) { |
2958 ConsumeToken(); | 2981 ConsumeToken(); |
2959 if (TryParseTypeParameter() && (CurrentToken() == Token::kLPAREN)) { | 2982 if (TryParseTypeParameter() && (CurrentToken() == Token::kLPAREN)) { |
2960 is_alias_name = true; | 2983 is_alias_name = true; |
2961 } | 2984 } |
2962 } | 2985 } |
2963 SetPosition(saved_pos); | 2986 SetPosition(saved_pos); |
2964 return is_alias_name; | 2987 return is_alias_name; |
2965 } | 2988 } |
2966 | 2989 |
2967 | 2990 |
2968 void Parser::ParseFunctionTypeAlias( | 2991 void Parser::ParseFunctionTypeAlias( |
2969 const GrowableObjectArray& pending_classes) { | 2992 const GrowableObjectArray& pending_classes) { |
2970 TRACE_PARSER("ParseFunctionTypeAlias"); | 2993 TRACE_PARSER("ParseFunctionTypeAlias"); |
2971 ExpectToken(Token::kTYPEDEF); | 2994 ExpectToken(Token::kTYPEDEF); |
2972 | 2995 |
2973 // Allocate an interface to hold the type parameters and their bounds. | 2996 // Allocate an interface to hold the type parameters and their bounds. |
2974 // Make it the owner of the function type descriptor. | 2997 // Make it the owner of the function type descriptor. |
2975 const Class& alias_owner = Class::Handle( | 2998 const Class& alias_owner = Class::Handle( |
2976 Class::New(String::Handle(String::NewSymbol(":alias_owner")), | 2999 Class::New(String::Handle(String::NewSymbol(":alias_owner")), |
2977 Script::Handle(), | 3000 Script::Handle(), |
2978 token_index_)); | 3001 TokenPos())); |
2979 alias_owner.set_is_interface(); | 3002 alias_owner.set_is_interface(); |
2980 alias_owner.set_library(library_); | 3003 alias_owner.set_library(library_); |
2981 set_current_class(alias_owner); | 3004 set_current_class(alias_owner); |
2982 | 3005 |
2983 // Parse the result type of the function type. | 3006 // Parse the result type of the function type. |
2984 AbstractType& result_type = Type::Handle(Type::DynamicType()); | 3007 AbstractType& result_type = Type::Handle(Type::DynamicType()); |
2985 if (CurrentToken() == Token::kVOID) { | 3008 if (CurrentToken() == Token::kVOID) { |
2986 ConsumeToken(); | 3009 ConsumeToken(); |
2987 result_type = Type::VoidType(); | 3010 result_type = Type::VoidType(); |
2988 } else if (!IsFunctionTypeAliasName()) { | 3011 } else if (!IsFunctionTypeAliasName()) { |
2989 // Type annotations in typedef are never ignored, even in unchecked mode. | 3012 // Type annotations in typedef are never ignored, even in unchecked mode. |
2990 // Wait until we have an owner class before resolving the result type. | 3013 // Wait until we have an owner class before resolving the result type. |
2991 result_type = ParseType(ClassFinalizer::kDoNotResolve); | 3014 result_type = ParseType(ClassFinalizer::kDoNotResolve); |
2992 } | 3015 } |
2993 | 3016 |
2994 const intptr_t alias_name_pos = token_index_; | 3017 const intptr_t alias_name_pos = TokenPos(); |
2995 const String* alias_name = | 3018 const String* alias_name = |
2996 ExpectTypeIdentifier("function alias name expected"); | 3019 ExpectTypeIdentifier("function alias name expected"); |
2997 | 3020 |
2998 // Parse the type parameters of the function type. | 3021 // Parse the type parameters of the function type. |
2999 ParseTypeParameters(alias_owner); | 3022 ParseTypeParameters(alias_owner); |
3000 // At this point, the type parameters have been parsed, so we can resolve the | 3023 // At this point, the type parameters have been parsed, so we can resolve the |
3001 // result type. | 3024 // result type. |
3002 if (!result_type.IsNull()) { | 3025 if (!result_type.IsNull()) { |
3003 ResolveTypeFromClass(alias_owner, | 3026 ResolveTypeFromClass(alias_owner, |
3004 ClassFinalizer::kTryResolve, | 3027 ClassFinalizer::kTryResolve, |
(...skipping 58 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3063 ASSERT(!function_type_alias.is_finalized()); | 3086 ASSERT(!function_type_alias.is_finalized()); |
3064 library_.AddClass(function_type_alias); | 3087 library_.AddClass(function_type_alias); |
3065 ExpectSemicolon(); | 3088 ExpectSemicolon(); |
3066 pending_classes.Add(function_type_alias, Heap::kOld); | 3089 pending_classes.Add(function_type_alias, Heap::kOld); |
3067 } | 3090 } |
3068 | 3091 |
3069 | 3092 |
3070 void Parser::ParseInterfaceDefinition( | 3093 void Parser::ParseInterfaceDefinition( |
3071 const GrowableObjectArray& pending_classes) { | 3094 const GrowableObjectArray& pending_classes) { |
3072 TRACE_PARSER("ParseInterfaceDefinition"); | 3095 TRACE_PARSER("ParseInterfaceDefinition"); |
3073 const intptr_t interface_pos = token_index_; | 3096 const intptr_t interface_pos = TokenPos(); |
3074 ExpectToken(Token::kINTERFACE); | 3097 ExpectToken(Token::kINTERFACE); |
3075 const intptr_t interfacename_pos = token_index_; | 3098 const intptr_t interfacename_pos = TokenPos(); |
3076 String& interface_name = *ExpectTypeIdentifier("interface name expected"); | 3099 String& interface_name = *ExpectTypeIdentifier("interface name expected"); |
3077 if (FLAG_trace_parser) { | 3100 if (FLAG_trace_parser) { |
3078 OS::Print("TopLevel parsing interface '%s'\n", interface_name.ToCString()); | 3101 OS::Print("TopLevel parsing interface '%s'\n", interface_name.ToCString()); |
3079 } | 3102 } |
3080 Class& interface = Class::Handle(); | 3103 Class& interface = Class::Handle(); |
3081 Object& obj = Object::Handle(library_.LookupObject(interface_name)); | 3104 Object& obj = Object::Handle(library_.LookupObject(interface_name)); |
3082 if (obj.IsNull()) { | 3105 if (obj.IsNull()) { |
3083 interface = Class::NewInterface(interface_name, script_, interfacename_pos); | 3106 interface = Class::NewInterface(interface_name, script_, interfacename_pos); |
3084 library_.AddClass(interface); | 3107 library_.AddClass(interface); |
3085 } else { | 3108 } else { |
(...skipping 12 matching lines...) Expand all Loading... |
3098 interface_name.ToCString()); | 3121 interface_name.ToCString()); |
3099 } | 3122 } |
3100 } | 3123 } |
3101 ASSERT(!interface.IsNull()); | 3124 ASSERT(!interface.IsNull()); |
3102 ASSERT(interface.functions() == Array::Empty()); | 3125 ASSERT(interface.functions() == Array::Empty()); |
3103 set_current_class(interface); | 3126 set_current_class(interface); |
3104 ParseTypeParameters(interface); | 3127 ParseTypeParameters(interface); |
3105 | 3128 |
3106 if (CurrentToken() == Token::kEXTENDS) { | 3129 if (CurrentToken() == Token::kEXTENDS) { |
3107 Array& interfaces = Array::Handle(); | 3130 Array& interfaces = Array::Handle(); |
3108 const intptr_t interfaces_pos = token_index_; | 3131 const intptr_t interfaces_pos = TokenPos(); |
3109 interfaces = ParseInterfaceList(); | 3132 interfaces = ParseInterfaceList(); |
3110 AddInterfaces(interfaces_pos, interface, interfaces); | 3133 AddInterfaces(interfaces_pos, interface, interfaces); |
3111 } | 3134 } |
3112 | 3135 |
3113 if (CurrentToken() == Token::kDEFAULT) { | 3136 if (CurrentToken() == Token::kDEFAULT) { |
3114 ConsumeToken(); | 3137 ConsumeToken(); |
3115 if (CurrentToken() != Token::kIDENT) { | 3138 if (CurrentToken() != Token::kIDENT) { |
3116 ErrorMsg("class name expected"); | 3139 ErrorMsg("class name expected"); |
3117 } | 3140 } |
3118 QualIdent factory_name; | 3141 QualIdent factory_name; |
(...skipping 120 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3239 AbstractType& bound = Type::Handle(); | 3262 AbstractType& bound = Type::Handle(); |
3240 do { | 3263 do { |
3241 ConsumeToken(); | 3264 ConsumeToken(); |
3242 if (CurrentToken() != Token::kIDENT) { | 3265 if (CurrentToken() != Token::kIDENT) { |
3243 ErrorMsg("type parameter name expected"); | 3266 ErrorMsg("type parameter name expected"); |
3244 } | 3267 } |
3245 String& type_parameter_name = *CurrentLiteral(); | 3268 String& type_parameter_name = *CurrentLiteral(); |
3246 type_parameter = TypeParameter::New(cls, | 3269 type_parameter = TypeParameter::New(cls, |
3247 index, | 3270 index, |
3248 type_parameter_name, | 3271 type_parameter_name, |
3249 token_index_); | 3272 TokenPos()); |
3250 // Check for duplicate type parameters. | 3273 // Check for duplicate type parameters. |
3251 for (intptr_t i = 0; i < index; i++) { | 3274 for (intptr_t i = 0; i < index; i++) { |
3252 existing_type_parameter ^= type_parameters_array.At(i); | 3275 existing_type_parameter ^= type_parameters_array.At(i); |
3253 existing_type_parameter_name = existing_type_parameter.Name(); | 3276 existing_type_parameter_name = existing_type_parameter.Name(); |
3254 if (existing_type_parameter_name.Equals(type_parameter_name)) { | 3277 if (existing_type_parameter_name.Equals(type_parameter_name)) { |
3255 ErrorMsg("duplicate type parameter '%s'", | 3278 ErrorMsg("duplicate type parameter '%s'", |
3256 type_parameter_name.ToCString()); | 3279 type_parameter_name.ToCString()); |
3257 } | 3280 } |
3258 } | 3281 } |
3259 ConsumeToken(); | 3282 ConsumeToken(); |
(...skipping 76 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3336 ASSERT((CurrentToken() == Token::kIMPLEMENTS) || | 3359 ASSERT((CurrentToken() == Token::kIMPLEMENTS) || |
3337 (CurrentToken() == Token::kEXTENDS)); | 3360 (CurrentToken() == Token::kEXTENDS)); |
3338 const GrowableObjectArray& interfaces = | 3361 const GrowableObjectArray& interfaces = |
3339 GrowableObjectArray::Handle(GrowableObjectArray::New()); | 3362 GrowableObjectArray::Handle(GrowableObjectArray::New()); |
3340 String& interface_name = String::Handle(); | 3363 String& interface_name = String::Handle(); |
3341 AbstractType& interface = AbstractType::Handle(); | 3364 AbstractType& interface = AbstractType::Handle(); |
3342 String& other_name = String::Handle(); | 3365 String& other_name = String::Handle(); |
3343 AbstractType& other_interface = AbstractType::Handle(); | 3366 AbstractType& other_interface = AbstractType::Handle(); |
3344 do { | 3367 do { |
3345 ConsumeToken(); | 3368 ConsumeToken(); |
3346 intptr_t supertype_pos = token_index_; | 3369 intptr_t supertype_pos = TokenPos(); |
3347 interface = ParseType(ClassFinalizer::kTryResolve); | 3370 interface = ParseType(ClassFinalizer::kTryResolve); |
3348 interface_name = interface.Name(); | 3371 interface_name = interface.Name(); |
3349 for (int i = 0; i < interfaces.Length(); i++) { | 3372 for (int i = 0; i < interfaces.Length(); i++) { |
3350 other_interface ^= interfaces.At(i); | 3373 other_interface ^= interfaces.At(i); |
3351 other_name = other_interface.Name(); | 3374 other_name = other_interface.Name(); |
3352 if (interface_name.Equals(other_name)) { | 3375 if (interface_name.Equals(other_name)) { |
3353 ErrorMsg(supertype_pos, "Duplicate supertype '%s'", | 3376 ErrorMsg(supertype_pos, "Duplicate supertype '%s'", |
3354 interface_name.ToCString()); | 3377 interface_name.ToCString()); |
3355 } | 3378 } |
3356 } | 3379 } |
(...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3408 void Parser::ParseTopLevelVariable(TopLevel* top_level) { | 3431 void Parser::ParseTopLevelVariable(TopLevel* top_level) { |
3409 TRACE_PARSER("ParseTopLevelVariable"); | 3432 TRACE_PARSER("ParseTopLevelVariable"); |
3410 const bool is_final = (CurrentToken() == Token::kFINAL); | 3433 const bool is_final = (CurrentToken() == Token::kFINAL); |
3411 const bool is_static = true; | 3434 const bool is_static = true; |
3412 const AbstractType& type = AbstractType::ZoneHandle(ParseFinalVarOrType( | 3435 const AbstractType& type = AbstractType::ZoneHandle(ParseFinalVarOrType( |
3413 FLAG_enable_type_checks ? ClassFinalizer::kTryResolve : | 3436 FLAG_enable_type_checks ? ClassFinalizer::kTryResolve : |
3414 ClassFinalizer::kIgnore)); | 3437 ClassFinalizer::kIgnore)); |
3415 Field& field = Field::Handle(); | 3438 Field& field = Field::Handle(); |
3416 Function& getter = Function::Handle(); | 3439 Function& getter = Function::Handle(); |
3417 while (true) { | 3440 while (true) { |
3418 const intptr_t name_pos = token_index_; | 3441 const intptr_t name_pos = TokenPos(); |
3419 String& var_name = *ExpectIdentifier("variable name expected"); | 3442 String& var_name = *ExpectIdentifier("variable name expected"); |
3420 | 3443 |
3421 if (library_.LookupObject(var_name) != Object::null()) { | 3444 if (library_.LookupObject(var_name) != Object::null()) { |
3422 ErrorMsg(name_pos, "'%s' is already defined", var_name.ToCString()); | 3445 ErrorMsg(name_pos, "'%s' is already defined", var_name.ToCString()); |
3423 } | 3446 } |
3424 String& accessor_name = String::Handle(Field::GetterName(var_name)); | 3447 String& accessor_name = String::Handle(Field::GetterName(var_name)); |
3425 if (library_.LookupObject(accessor_name) != Object::null()) { | 3448 if (library_.LookupObject(accessor_name) != Object::null()) { |
3426 ErrorMsg(name_pos, "getter for '%s' is already defined", | 3449 ErrorMsg(name_pos, "getter for '%s' is already defined", |
3427 var_name.ToCString()); | 3450 var_name.ToCString()); |
3428 } | 3451 } |
(...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3470 if (CurrentToken() == Token::kVOID) { | 3493 if (CurrentToken() == Token::kVOID) { |
3471 ConsumeToken(); | 3494 ConsumeToken(); |
3472 result_type = Type::VoidType(); | 3495 result_type = Type::VoidType(); |
3473 } else { | 3496 } else { |
3474 // Parse optional type. | 3497 // Parse optional type. |
3475 if ((CurrentToken() == Token::kIDENT) && | 3498 if ((CurrentToken() == Token::kIDENT) && |
3476 (LookaheadToken(1) != Token::kLPAREN)) { | 3499 (LookaheadToken(1) != Token::kLPAREN)) { |
3477 result_type = ParseType(ClassFinalizer::kTryResolve); | 3500 result_type = ParseType(ClassFinalizer::kTryResolve); |
3478 } | 3501 } |
3479 } | 3502 } |
3480 const intptr_t name_pos = token_index_; | 3503 const intptr_t name_pos = TokenPos(); |
3481 const String& func_name = *ExpectIdentifier("function name expected"); | 3504 const String& func_name = *ExpectIdentifier("function name expected"); |
3482 | 3505 |
3483 if (library_.LookupObject(func_name) != Object::null()) { | 3506 if (library_.LookupObject(func_name) != Object::null()) { |
3484 ErrorMsg(name_pos, "'%s' is already defined", func_name.ToCString()); | 3507 ErrorMsg(name_pos, "'%s' is already defined", func_name.ToCString()); |
3485 } | 3508 } |
3486 String& accessor_name = String::Handle(Field::GetterName(func_name)); | 3509 String& accessor_name = String::Handle(Field::GetterName(func_name)); |
3487 if (library_.LookupObject(accessor_name) != Object::null()) { | 3510 if (library_.LookupObject(accessor_name) != Object::null()) { |
3488 ErrorMsg(name_pos, "'%s' is already defined as getter", | 3511 ErrorMsg(name_pos, "'%s' is already defined as getter", |
3489 func_name.ToCString()); | 3512 func_name.ToCString()); |
3490 } | 3513 } |
3491 accessor_name = Field::SetterName(func_name); | 3514 accessor_name = Field::SetterName(func_name); |
3492 if (library_.LookupObject(accessor_name) != Object::null()) { | 3515 if (library_.LookupObject(accessor_name) != Object::null()) { |
3493 ErrorMsg(name_pos, "'%s' is already defined as setter", | 3516 ErrorMsg(name_pos, "'%s' is already defined as setter", |
3494 func_name.ToCString()); | 3517 func_name.ToCString()); |
3495 } | 3518 } |
3496 | 3519 |
3497 if (CurrentToken() != Token::kLPAREN) { | 3520 if (CurrentToken() != Token::kLPAREN) { |
3498 ErrorMsg("'(' expected"); | 3521 ErrorMsg("'(' expected"); |
3499 } | 3522 } |
3500 const intptr_t function_pos = token_index_; | 3523 const intptr_t function_pos = TokenPos(); |
3501 ParamList params; | 3524 ParamList params; |
3502 const bool allow_explicit_default_values = true; | 3525 const bool allow_explicit_default_values = true; |
3503 ParseFormalParameterList(allow_explicit_default_values, ¶ms); | 3526 ParseFormalParameterList(allow_explicit_default_values, ¶ms); |
3504 | 3527 |
3505 intptr_t function_end_pos = function_pos; | 3528 intptr_t function_end_pos = function_pos; |
3506 if (CurrentToken() == Token::kLBRACE) { | 3529 if (CurrentToken() == Token::kLBRACE) { |
3507 SkipBlock(); | 3530 SkipBlock(); |
3508 function_end_pos = token_index_; | 3531 function_end_pos = TokenPos(); |
3509 } else if (CurrentToken() == Token::kARROW) { | 3532 } else if (CurrentToken() == Token::kARROW) { |
3510 ConsumeToken(); | 3533 ConsumeToken(); |
3511 SkipExpr(); | 3534 SkipExpr(); |
3512 ExpectSemicolon(); | 3535 ExpectSemicolon(); |
3513 function_end_pos = token_index_; | 3536 function_end_pos = TokenPos(); |
3514 } else if (IsLiteral("native")) { | 3537 } else if (IsLiteral("native")) { |
3515 ParseNativeDeclaration(); | 3538 ParseNativeDeclaration(); |
3516 } else { | 3539 } else { |
3517 ErrorMsg("function block expected"); | 3540 ErrorMsg("function block expected"); |
3518 } | 3541 } |
3519 Function& func = Function::Handle( | 3542 Function& func = Function::Handle( |
3520 Function::New(func_name, RawFunction::kFunction, | 3543 Function::New(func_name, RawFunction::kFunction, |
3521 is_static, false, function_pos)); | 3544 is_static, false, function_pos)); |
3522 func.set_result_type(result_type); | 3545 func.set_result_type(result_type); |
3523 func.set_end_token_index(function_end_pos); | 3546 func.set_end_token_pos(function_end_pos); |
3524 AddFormalParamsToFunction(¶ms, func); | 3547 AddFormalParamsToFunction(¶ms, func); |
3525 top_level->functions.Add(func); | 3548 top_level->functions.Add(func); |
3526 library_.AddObject(func, func_name); | 3549 library_.AddObject(func, func_name); |
3527 } | 3550 } |
3528 | 3551 |
3529 | 3552 |
3530 void Parser::ParseTopLevelAccessor(TopLevel* top_level) { | 3553 void Parser::ParseTopLevelAccessor(TopLevel* top_level) { |
3531 TRACE_PARSER("ParseTopLevelAccessor"); | 3554 TRACE_PARSER("ParseTopLevelAccessor"); |
3532 const bool is_static = true; | 3555 const bool is_static = true; |
3533 AbstractType& result_type = AbstractType::Handle(); | 3556 AbstractType& result_type = AbstractType::Handle(); |
3534 bool is_getter = (CurrentToken() == Token::kGET); | 3557 bool is_getter = (CurrentToken() == Token::kGET); |
3535 if (CurrentToken() == Token::kGET || | 3558 if (CurrentToken() == Token::kGET || |
3536 CurrentToken() == Token::kSET) { | 3559 CurrentToken() == Token::kSET) { |
3537 ConsumeToken(); | 3560 ConsumeToken(); |
3538 result_type = Type::DynamicType(); | 3561 result_type = Type::DynamicType(); |
3539 } else { | 3562 } else { |
3540 if (CurrentToken() == Token::kVOID) { | 3563 if (CurrentToken() == Token::kVOID) { |
3541 ConsumeToken(); | 3564 ConsumeToken(); |
3542 result_type = Type::VoidType(); | 3565 result_type = Type::VoidType(); |
3543 } else { | 3566 } else { |
3544 result_type = ParseType(ClassFinalizer::kTryResolve); | 3567 result_type = ParseType(ClassFinalizer::kTryResolve); |
3545 } | 3568 } |
3546 is_getter = (CurrentToken() == Token::kGET); | 3569 is_getter = (CurrentToken() == Token::kGET); |
3547 if (CurrentToken() == Token::kGET || CurrentToken() == Token::kSET) { | 3570 if (CurrentToken() == Token::kGET || CurrentToken() == Token::kSET) { |
3548 ConsumeToken(); | 3571 ConsumeToken(); |
3549 } else { | 3572 } else { |
3550 UnexpectedToken(); | 3573 UnexpectedToken(); |
3551 } | 3574 } |
3552 } | 3575 } |
3553 const intptr_t name_pos = token_index_; | 3576 const intptr_t name_pos = TokenPos(); |
3554 const String* field_name = ExpectIdentifier("accessor name expected"); | 3577 const String* field_name = ExpectIdentifier("accessor name expected"); |
3555 | 3578 |
3556 if (CurrentToken() != Token::kLPAREN) { | 3579 if (CurrentToken() != Token::kLPAREN) { |
3557 ErrorMsg("'(' expected"); | 3580 ErrorMsg("'(' expected"); |
3558 } | 3581 } |
3559 const intptr_t accessor_pos = token_index_; | 3582 const intptr_t accessor_pos = TokenPos(); |
3560 ParamList params; | 3583 ParamList params; |
3561 const bool allow_explicit_default_values = true; | 3584 const bool allow_explicit_default_values = true; |
3562 ParseFormalParameterList(allow_explicit_default_values, ¶ms); | 3585 ParseFormalParameterList(allow_explicit_default_values, ¶ms); |
3563 String& accessor_name = String::ZoneHandle(); | 3586 String& accessor_name = String::ZoneHandle(); |
3564 int expected_num_parameters = -1; | 3587 int expected_num_parameters = -1; |
3565 if (is_getter) { | 3588 if (is_getter) { |
3566 expected_num_parameters = 0; | 3589 expected_num_parameters = 0; |
3567 accessor_name = Field::GetterSymbol(*field_name); | 3590 accessor_name = Field::GetterSymbol(*field_name); |
3568 } else { | 3591 } else { |
3569 expected_num_parameters = 1; | 3592 expected_num_parameters = 1; |
(...skipping 76 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3646 prev_error ^= Api::UnwrapHandle(result); | 3669 prev_error ^= Api::UnwrapHandle(result); |
3647 AppendErrorMsg(prev_error, token_pos, "library handler failed"); | 3670 AppendErrorMsg(prev_error, token_pos, "library handler failed"); |
3648 } | 3671 } |
3649 return result; | 3672 return result; |
3650 } | 3673 } |
3651 | 3674 |
3652 | 3675 |
3653 void Parser::ParseLibraryImport() { | 3676 void Parser::ParseLibraryImport() { |
3654 TRACE_PARSER("ParseLibraryImport"); | 3677 TRACE_PARSER("ParseLibraryImport"); |
3655 while (CurrentToken() == Token::kIMPORT) { | 3678 while (CurrentToken() == Token::kIMPORT) { |
3656 const intptr_t import_pos = token_index_; | 3679 const intptr_t import_pos = TokenPos(); |
3657 ConsumeToken(); | 3680 ConsumeToken(); |
3658 ExpectToken(Token::kLPAREN); | 3681 ExpectToken(Token::kLPAREN); |
3659 if (CurrentToken() != Token::kSTRING) { | 3682 if (CurrentToken() != Token::kSTRING) { |
3660 ErrorMsg("library url expected"); | 3683 ErrorMsg("library url expected"); |
3661 } | 3684 } |
3662 const String& url = *ParseImportStringLiteral(); | 3685 const String& url = *ParseImportStringLiteral(); |
3663 String& prefix = String::Handle(); | 3686 String& prefix = String::Handle(); |
3664 if (CurrentToken() == Token::kCOMMA) { | 3687 if (CurrentToken() == Token::kCOMMA) { |
3665 ConsumeToken(); | 3688 ConsumeToken(); |
3666 if (!IsLiteral("prefix")) { | 3689 if (!IsLiteral("prefix")) { |
(...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3710 library_.AddObject(library_prefix, prefix); | 3733 library_.AddObject(library_prefix, prefix); |
3711 } | 3734 } |
3712 } | 3735 } |
3713 } | 3736 } |
3714 } | 3737 } |
3715 | 3738 |
3716 | 3739 |
3717 void Parser::ParseLibraryInclude() { | 3740 void Parser::ParseLibraryInclude() { |
3718 TRACE_PARSER("ParseLibraryInclude"); | 3741 TRACE_PARSER("ParseLibraryInclude"); |
3719 while (CurrentToken() == Token::kSOURCE) { | 3742 while (CurrentToken() == Token::kSOURCE) { |
3720 const intptr_t source_pos = token_index_; | 3743 const intptr_t source_pos = TokenPos(); |
3721 ConsumeToken(); | 3744 ConsumeToken(); |
3722 ExpectToken(Token::kLPAREN); | 3745 ExpectToken(Token::kLPAREN); |
3723 if (CurrentToken() != Token::kSTRING) { | 3746 if (CurrentToken() != Token::kSTRING) { |
3724 ErrorMsg("source url expected"); | 3747 ErrorMsg("source url expected"); |
3725 } | 3748 } |
3726 const String& url = *ParseImportStringLiteral(); | 3749 const String& url = *ParseImportStringLiteral(); |
3727 ExpectToken(Token::kRPAREN); | 3750 ExpectToken(Token::kRPAREN); |
3728 ExpectToken(Token::kSEMICOLON); | 3751 ExpectToken(Token::kSEMICOLON); |
3729 Dart_Handle handle = CallLibraryTagHandler(kCanonicalizeUrl, | 3752 Dart_Handle handle = CallLibraryTagHandler(kCanonicalizeUrl, |
3730 source_pos, | 3753 source_pos, |
(...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3775 Isolate* isolate = Isolate::Current(); | 3798 Isolate* isolate = Isolate::Current(); |
3776 ObjectStore* object_store = isolate->object_store(); | 3799 ObjectStore* object_store = isolate->object_store(); |
3777 const GrowableObjectArray& pending_classes = | 3800 const GrowableObjectArray& pending_classes = |
3778 GrowableObjectArray::Handle(isolate, object_store->pending_classes()); | 3801 GrowableObjectArray::Handle(isolate, object_store->pending_classes()); |
3779 SetPosition(0); | 3802 SetPosition(0); |
3780 is_top_level_ = true; | 3803 is_top_level_ = true; |
3781 TopLevel top_level; | 3804 TopLevel top_level; |
3782 Class& toplevel_class = Class::Handle( | 3805 Class& toplevel_class = Class::Handle( |
3783 Class::New(String::ZoneHandle(String::NewSymbol("::")), | 3806 Class::New(String::ZoneHandle(String::NewSymbol("::")), |
3784 script_, | 3807 script_, |
3785 token_index_)); | 3808 TokenPos())); |
3786 toplevel_class.set_library(library_); | 3809 toplevel_class.set_library(library_); |
3787 | 3810 |
3788 if (is_library_source()) { | 3811 if (is_library_source()) { |
3789 ParseLibraryDefinition(); | 3812 ParseLibraryDefinition(); |
3790 } | 3813 } |
3791 | 3814 |
3792 while (true) { | 3815 while (true) { |
3793 set_current_class(Class::Handle()); // No current class. | 3816 set_current_class(Class::Handle()); // No current class. |
3794 if (CurrentToken() == Token::kCLASS) { | 3817 if (CurrentToken() == Token::kCLASS) { |
3795 ParseClassDefinition(pending_classes); | 3818 ParseClassDefinition(pending_classes); |
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3828 | 3851 |
3829 library_.AddAnonymousClass(toplevel_class); | 3852 library_.AddAnonymousClass(toplevel_class); |
3830 pending_classes.Add(toplevel_class, Heap::kOld); | 3853 pending_classes.Add(toplevel_class, Heap::kOld); |
3831 } | 3854 } |
3832 } | 3855 } |
3833 | 3856 |
3834 | 3857 |
3835 void Parser::ChainNewBlock(LocalScope* outer_scope) { | 3858 void Parser::ChainNewBlock(LocalScope* outer_scope) { |
3836 Block* block = new Block(current_block_, | 3859 Block* block = new Block(current_block_, |
3837 outer_scope, | 3860 outer_scope, |
3838 new SequenceNode(token_index_, outer_scope)); | 3861 new SequenceNode(TokenPos(), outer_scope)); |
3839 current_block_ = block; | 3862 current_block_ = block; |
3840 } | 3863 } |
3841 | 3864 |
3842 | 3865 |
3843 void Parser::OpenBlock() { | 3866 void Parser::OpenBlock() { |
3844 ASSERT(current_block_ != NULL); | 3867 ASSERT(current_block_ != NULL); |
3845 LocalScope* outer_scope = current_block_->scope; | 3868 LocalScope* outer_scope = current_block_->scope; |
3846 ChainNewBlock(new LocalScope(outer_scope, | 3869 ChainNewBlock(new LocalScope(outer_scope, |
3847 outer_scope->function_level(), | 3870 outer_scope->function_level(), |
3848 outer_scope->loop_level())); | 3871 outer_scope->loop_level())); |
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3881 } | 3904 } |
3882 ChainNewBlock(outer_scope); | 3905 ChainNewBlock(outer_scope); |
3883 } | 3906 } |
3884 | 3907 |
3885 | 3908 |
3886 SequenceNode* Parser::CloseBlock() { | 3909 SequenceNode* Parser::CloseBlock() { |
3887 SequenceNode* statements = current_block_->statements; | 3910 SequenceNode* statements = current_block_->statements; |
3888 if (current_block_->scope != NULL) { | 3911 if (current_block_->scope != NULL) { |
3889 // Record the begin and end token index of the scope. | 3912 // Record the begin and end token index of the scope. |
3890 ASSERT(statements != NULL); | 3913 ASSERT(statements != NULL); |
3891 current_block_->scope->set_begin_token_index(statements->token_index()); | 3914 current_block_->scope->set_begin_token_pos(statements->token_pos()); |
3892 current_block_->scope->set_end_token_index(token_index_); | 3915 current_block_->scope->set_end_token_pos(TokenPos()); |
3893 } | 3916 } |
3894 current_block_ = current_block_->parent; | 3917 current_block_ = current_block_->parent; |
3895 return statements; | 3918 return statements; |
3896 } | 3919 } |
3897 | 3920 |
3898 | 3921 |
3899 // Set up default values for all optional parameters to the function. | 3922 // Set up default values for all optional parameters to the function. |
3900 void Parser::SetupDefaultsForOptionalParams(const ParamList* params, | 3923 void Parser::SetupDefaultsForOptionalParams(const ParamList* params, |
3901 Array& default_values) { | 3924 Array& default_values) { |
3902 if (params->num_optional_parameters > 0) { | 3925 if (params->num_optional_parameters > 0) { |
(...skipping 60 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3963 void Parser::ParseNativeFunctionBlock(const ParamList* params, | 3986 void Parser::ParseNativeFunctionBlock(const ParamList* params, |
3964 const Function& func) { | 3987 const Function& func) { |
3965 func.set_is_native(true); | 3988 func.set_is_native(true); |
3966 TRACE_PARSER("ParseNativeFunctionBlock"); | 3989 TRACE_PARSER("ParseNativeFunctionBlock"); |
3967 const Class& cls = Class::Handle(func.owner()); | 3990 const Class& cls = Class::Handle(func.owner()); |
3968 const int num_parameters = params->parameters->length(); | 3991 const int num_parameters = params->parameters->length(); |
3969 const bool is_instance_closure = func.IsImplicitInstanceClosureFunction(); | 3992 const bool is_instance_closure = func.IsImplicitInstanceClosureFunction(); |
3970 int num_params_for_resolution = num_parameters; | 3993 int num_params_for_resolution = num_parameters; |
3971 | 3994 |
3972 // Parse the function name out. | 3995 // Parse the function name out. |
3973 const intptr_t native_pos = token_index_; | 3996 const intptr_t native_pos = TokenPos(); |
3974 const String& native_name = ParseNativeDeclaration(); | 3997 const String& native_name = ParseNativeDeclaration(); |
3975 | 3998 |
3976 if (is_instance_closure) { | 3999 if (is_instance_closure) { |
3977 num_params_for_resolution += 1; // account for 'this' when resolving. | 4000 num_params_for_resolution += 1; // account for 'this' when resolving. |
3978 } | 4001 } |
3979 // Now resolve the native function to the corresponding native entrypoint. | 4002 // Now resolve the native function to the corresponding native entrypoint. |
3980 NativeFunction native_function = NativeEntry::ResolveNative( | 4003 NativeFunction native_function = NativeEntry::ResolveNative( |
3981 cls, native_name, num_params_for_resolution); | 4004 cls, native_name, num_params_for_resolution); |
3982 if (native_function == NULL) { | 4005 if (native_function == NULL) { |
3983 ErrorMsg(native_pos, "native function '%s' cannot be found", | 4006 ErrorMsg(native_pos, "native function '%s' cannot be found", |
3984 native_name.ToCString()); | 4007 native_name.ToCString()); |
3985 } | 4008 } |
3986 | 4009 |
3987 const bool has_opt_params = (params->num_optional_parameters > 0); | 4010 const bool has_opt_params = (params->num_optional_parameters > 0); |
3988 | 4011 |
3989 // Now add the NativeBodyNode and return statement. | 4012 // Now add the NativeBodyNode and return statement. |
3990 current_block_->statements->Add( | 4013 current_block_->statements->Add( |
3991 new ReturnNode(token_index_, new NativeBodyNode(token_index_, | 4014 new ReturnNode(TokenPos(), new NativeBodyNode(TokenPos(), |
3992 native_name, | 4015 native_name, |
3993 native_function, | 4016 native_function, |
3994 num_parameters, | 4017 num_parameters, |
3995 has_opt_params, | 4018 has_opt_params, |
3996 is_instance_closure))); | 4019 is_instance_closure))); |
3997 } | 4020 } |
3998 | 4021 |
3999 | 4022 |
4000 LocalVariable* Parser::LookupReceiver(LocalScope* from_scope, | 4023 LocalVariable* Parser::LookupReceiver(LocalScope* from_scope, |
4001 bool test_only) { | 4024 bool test_only) { |
(...skipping 23 matching lines...) Expand all Loading... |
4025 // A nested function may access 'this', referring to the receiver of the | 4048 // A nested function may access 'this', referring to the receiver of the |
4026 // outermost enclosing function. | 4049 // outermost enclosing function. |
4027 // We should not be loading the receiver from a static scope. | 4050 // We should not be loading the receiver from a static scope. |
4028 ASSERT(!current_function().is_static() || | 4051 ASSERT(!current_function().is_static() || |
4029 current_function().IsInFactoryScope()); | 4052 current_function().IsInFactoryScope()); |
4030 const bool kTestOnly = false; | 4053 const bool kTestOnly = false; |
4031 LocalVariable* receiver = LookupReceiver(current_block_->scope, kTestOnly); | 4054 LocalVariable* receiver = LookupReceiver(current_block_->scope, kTestOnly); |
4032 if (receiver == NULL) { | 4055 if (receiver == NULL) { |
4033 ErrorMsg(token_pos, "illegal implicit access to receiver 'this'"); | 4056 ErrorMsg(token_pos, "illegal implicit access to receiver 'this'"); |
4034 } | 4057 } |
4035 return new LoadLocalNode(token_index_, *receiver); | 4058 return new LoadLocalNode(TokenPos(), *receiver); |
4036 } | 4059 } |
4037 | 4060 |
4038 | 4061 |
4039 AstNode* Parser::CallGetter(intptr_t token_index, | 4062 AstNode* Parser::CallGetter(intptr_t token_pos, |
4040 AstNode* object, | 4063 AstNode* object, |
4041 const String& name) { | 4064 const String& name) { |
4042 return new InstanceGetterNode(token_index_, object, name); | 4065 return new InstanceGetterNode(TokenPos(), object, name); |
4043 } | 4066 } |
4044 | 4067 |
4045 | 4068 |
4046 // Returns ast nodes of the variable initialization. | 4069 // Returns ast nodes of the variable initialization. |
4047 AstNode* Parser::ParseVariableDeclaration( | 4070 AstNode* Parser::ParseVariableDeclaration( |
4048 const AbstractType& type, bool is_final) { | 4071 const AbstractType& type, bool is_final) { |
4049 TRACE_PARSER("ParseVariableDeclaration"); | 4072 TRACE_PARSER("ParseVariableDeclaration"); |
4050 ASSERT(IsIdentifier()); | 4073 ASSERT(IsIdentifier()); |
4051 const intptr_t ident_pos = token_index_; | 4074 const intptr_t ident_pos = TokenPos(); |
4052 LocalVariable* variable = | 4075 LocalVariable* variable = |
4053 new LocalVariable(ident_pos, *CurrentLiteral(), type); | 4076 new LocalVariable(ident_pos, *CurrentLiteral(), type); |
4054 ASSERT(current_block_ != NULL); | 4077 ASSERT(current_block_ != NULL); |
4055 ASSERT(current_block_->scope != NULL); | 4078 ASSERT(current_block_->scope != NULL); |
4056 ConsumeToken(); // Variable identifier. | 4079 ConsumeToken(); // Variable identifier. |
4057 AstNode* initialization = NULL; | 4080 AstNode* initialization = NULL; |
4058 if (CurrentToken() == Token::kASSIGN) { | 4081 if (CurrentToken() == Token::kASSIGN) { |
4059 // Variable initialization. | 4082 // Variable initialization. |
4060 const intptr_t assign_pos = token_index_; | 4083 const intptr_t assign_pos = TokenPos(); |
4061 ConsumeToken(); | 4084 ConsumeToken(); |
4062 AstNode* expr = ParseExpr(kAllowConst); | 4085 AstNode* expr = ParseExpr(kAllowConst); |
4063 initialization = new StoreLocalNode(assign_pos, *variable, expr); | 4086 initialization = new StoreLocalNode(assign_pos, *variable, expr); |
4064 } else if (is_final) { | 4087 } else if (is_final) { |
4065 ErrorMsg(ident_pos, "missing initialization of 'final' variable"); | 4088 ErrorMsg(ident_pos, "missing initialization of 'final' variable"); |
4066 } else { | 4089 } else { |
4067 // Initialize variable with null. | 4090 // Initialize variable with null. |
4068 AstNode* null_expr = new LiteralNode(ident_pos, Instance::ZoneHandle()); | 4091 AstNode* null_expr = new LiteralNode(ident_pos, Instance::ZoneHandle()); |
4069 initialization = new StoreLocalNode(ident_pos, *variable, null_expr); | 4092 initialization = new StoreLocalNode(ident_pos, *variable, null_expr); |
4070 } | 4093 } |
(...skipping 63 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4134 | 4157 |
4135 AstNode* initializers = ParseVariableDeclaration(type, is_final); | 4158 AstNode* initializers = ParseVariableDeclaration(type, is_final); |
4136 ASSERT(initializers != NULL); | 4159 ASSERT(initializers != NULL); |
4137 while (CurrentToken() == Token::kCOMMA) { | 4160 while (CurrentToken() == Token::kCOMMA) { |
4138 ConsumeToken(); | 4161 ConsumeToken(); |
4139 if (!IsIdentifier()) { | 4162 if (!IsIdentifier()) { |
4140 ErrorMsg("identifier expected after comma"); | 4163 ErrorMsg("identifier expected after comma"); |
4141 } | 4164 } |
4142 // We have a second initializer. Allocate a sequence node now. | 4165 // We have a second initializer. Allocate a sequence node now. |
4143 // The sequence does not own the current scope. Set its own scope to NULL. | 4166 // The sequence does not own the current scope. Set its own scope to NULL. |
4144 SequenceNode* sequence = NodeAsSequenceNode(initializers->token_index(), | 4167 SequenceNode* sequence = NodeAsSequenceNode(initializers->token_pos(), |
4145 initializers, | 4168 initializers, |
4146 NULL); | 4169 NULL); |
4147 sequence->Add(ParseVariableDeclaration(type, is_final)); | 4170 sequence->Add(ParseVariableDeclaration(type, is_final)); |
4148 initializers = sequence; | 4171 initializers = sequence; |
4149 } | 4172 } |
4150 return initializers; | 4173 return initializers; |
4151 } | 4174 } |
4152 | 4175 |
4153 | 4176 |
4154 AstNode* Parser::ParseFunctionStatement(bool is_literal) { | 4177 AstNode* Parser::ParseFunctionStatement(bool is_literal) { |
4155 TRACE_PARSER("ParseFunctionStatement"); | 4178 TRACE_PARSER("ParseFunctionStatement"); |
4156 AbstractType& result_type = AbstractType::Handle(); | 4179 AbstractType& result_type = AbstractType::Handle(); |
4157 const String* variable_name = NULL; | 4180 const String* variable_name = NULL; |
4158 const String* function_name = NULL; | 4181 const String* function_name = NULL; |
4159 | 4182 |
4160 result_type = Type::DynamicType(); | 4183 result_type = Type::DynamicType(); |
4161 if (CurrentToken() == Token::kVOID) { | 4184 if (CurrentToken() == Token::kVOID) { |
4162 ConsumeToken(); | 4185 ConsumeToken(); |
4163 result_type = Type::VoidType(); | 4186 result_type = Type::VoidType(); |
4164 } else if ((CurrentToken() == Token::kIDENT) && | 4187 } else if ((CurrentToken() == Token::kIDENT) && |
4165 (LookaheadToken(1) != Token::kLPAREN)) { | 4188 (LookaheadToken(1) != Token::kLPAREN)) { |
4166 result_type = ParseType(ClassFinalizer::kFinalize); | 4189 result_type = ParseType(ClassFinalizer::kFinalize); |
4167 } | 4190 } |
4168 const intptr_t ident_pos = token_index_; | 4191 const intptr_t ident_pos = TokenPos(); |
4169 if (IsIdentifier()) { | 4192 if (IsIdentifier()) { |
4170 variable_name = CurrentLiteral(); | 4193 variable_name = CurrentLiteral(); |
4171 function_name = variable_name; | 4194 function_name = variable_name; |
4172 ConsumeToken(); | 4195 ConsumeToken(); |
4173 } else { | 4196 } else { |
4174 if (!is_literal) { | 4197 if (!is_literal) { |
4175 ErrorMsg("function name expected"); | 4198 ErrorMsg("function name expected"); |
4176 } | 4199 } |
4177 const String& anonymous_function_name = | 4200 const String& anonymous_function_name = |
4178 String::ZoneHandle(String::NewSymbol("function")); | 4201 String::ZoneHandle(String::NewSymbol("function")); |
4179 function_name = &anonymous_function_name; | 4202 function_name = &anonymous_function_name; |
4180 } | 4203 } |
4181 ASSERT(ident_pos >= 0); | 4204 ASSERT(ident_pos >= 0); |
4182 | 4205 |
4183 if (CurrentToken() != Token::kLPAREN) { | 4206 if (CurrentToken() != Token::kLPAREN) { |
4184 ErrorMsg("'(' expected"); | 4207 ErrorMsg("'(' expected"); |
4185 } | 4208 } |
4186 intptr_t function_pos = token_index_; | 4209 intptr_t function_pos = TokenPos(); |
4187 | 4210 |
4188 // Check whether we have parsed this closure function before, in a previous | 4211 // Check whether we have parsed this closure function before, in a previous |
4189 // compilation. If so, reuse the function object, else create a new one | 4212 // compilation. If so, reuse the function object, else create a new one |
4190 // and register it in the current class. | 4213 // and register it in the current class. |
4191 // Note that we cannot share the same closure function between the closurized | 4214 // Note that we cannot share the same closure function between the closurized |
4192 // and non-closurized versions of the same parent function. | 4215 // and non-closurized versions of the same parent function. |
4193 Function& function = Function::ZoneHandle(); | 4216 Function& function = Function::ZoneHandle(); |
4194 bool is_new_closure = false; | 4217 bool is_new_closure = false; |
4195 // TODO(hausner): There could be two different closures at the given | 4218 // TODO(hausner): There could be two different closures at the given |
4196 // function_pos, one enclosed in a closurized function and one enclosed in the | 4219 // function_pos, one enclosed in a closurized function and one enclosed in the |
4197 // non-closurized version of this same function. | 4220 // non-closurized version of this same function. |
4198 function = current_class().LookupClosureFunction(function_pos); | 4221 function = current_class().LookupClosureFunction(function_pos); |
4199 if (function.IsNull() || (function.token_index() != function_pos) || | 4222 if (function.IsNull() || (function.token_pos() != function_pos) || |
4200 (function.parent_function() != current_function().raw())) { | 4223 (function.parent_function() != current_function().raw())) { |
4201 is_new_closure = true; | 4224 is_new_closure = true; |
4202 function = Function::NewClosureFunction(*function_name, | 4225 function = Function::NewClosureFunction(*function_name, |
4203 current_function(), | 4226 current_function(), |
4204 function_pos); | 4227 function_pos); |
4205 function.set_result_type(result_type); | 4228 function.set_result_type(result_type); |
4206 current_class().AddClosureFunction(function); | 4229 current_class().AddClosureFunction(function); |
4207 } | 4230 } |
4208 | 4231 |
4209 // The function type does not need to be determined at compile time, unless | 4232 // The function type does not need to be determined at compile time, unless |
(...skipping 26 matching lines...) Expand all Loading... |
4236 if (!current_block_->scope->AddVariable(function_variable)) { | 4259 if (!current_block_->scope->AddVariable(function_variable)) { |
4237 ErrorMsg(ident_pos, "identifier '%s' already defined", | 4260 ErrorMsg(ident_pos, "identifier '%s' already defined", |
4238 function_variable->name().ToCString()); | 4261 function_variable->name().ToCString()); |
4239 } | 4262 } |
4240 } | 4263 } |
4241 | 4264 |
4242 // Parse the local function. | 4265 // Parse the local function. |
4243 Array& default_parameter_values = Array::Handle(); | 4266 Array& default_parameter_values = Array::Handle(); |
4244 SequenceNode* statements = Parser::ParseFunc(function, | 4267 SequenceNode* statements = Parser::ParseFunc(function, |
4245 default_parameter_values); | 4268 default_parameter_values); |
4246 ASSERT(is_new_closure || (function.end_token_index() == token_index_)); | 4269 ASSERT(is_new_closure || (function.end_token_pos() == TokenPos())); |
4247 function.set_end_token_index(token_index_); | 4270 function.set_end_token_pos(TokenPos()); |
4248 | 4271 |
4249 // Now that the local function has formal parameters, lookup the signature | 4272 // Now that the local function has formal parameters, lookup the signature |
4250 // class in the current library (but not in its imports) and only create a new | 4273 // class in the current library (but not in its imports) and only create a new |
4251 // canonical signature class if it does not exist yet. | 4274 // canonical signature class if it does not exist yet. |
4252 const String& signature = String::Handle(function.Signature()); | 4275 const String& signature = String::Handle(function.Signature()); |
4253 Class& signature_class = Class::ZoneHandle( | 4276 Class& signature_class = Class::ZoneHandle( |
4254 library_.LookupLocalClass(signature)); | 4277 library_.LookupLocalClass(signature)); |
4255 | 4278 |
4256 if (signature_class.IsNull()) { | 4279 if (signature_class.IsNull()) { |
4257 // If we don't have a signature class yet, this must be a closure we | 4280 // If we don't have a signature class yet, this must be a closure we |
(...skipping 158 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4416 // Token position remains unchanged. | 4439 // Token position remains unchanged. |
4417 bool Parser::IsVariableDeclaration() { | 4440 bool Parser::IsVariableDeclaration() { |
4418 if ((CurrentToken() == Token::kVAR) || | 4441 if ((CurrentToken() == Token::kVAR) || |
4419 (CurrentToken() == Token::kFINAL)) { | 4442 (CurrentToken() == Token::kFINAL)) { |
4420 return true; | 4443 return true; |
4421 } | 4444 } |
4422 if (CurrentToken() != Token::kIDENT) { | 4445 if (CurrentToken() != Token::kIDENT) { |
4423 // Not a legal type identifier. | 4446 // Not a legal type identifier. |
4424 return false; | 4447 return false; |
4425 } | 4448 } |
4426 const intptr_t saved_pos = token_index_; | 4449 const intptr_t saved_pos = TokenPos(); |
4427 bool is_var_decl = false; | 4450 bool is_var_decl = false; |
4428 if (TryParseOptionalType()) { | 4451 if (TryParseOptionalType()) { |
4429 if (IsIdentifier()) { | 4452 if (IsIdentifier()) { |
4430 ConsumeToken(); | 4453 ConsumeToken(); |
4431 if ((CurrentToken() == Token::kSEMICOLON) || | 4454 if ((CurrentToken() == Token::kSEMICOLON) || |
4432 (CurrentToken() == Token::kCOMMA) || | 4455 (CurrentToken() == Token::kCOMMA) || |
4433 (CurrentToken() == Token::kASSIGN)) { | 4456 (CurrentToken() == Token::kASSIGN)) { |
4434 is_var_decl = true; | 4457 is_var_decl = true; |
4435 } | 4458 } |
4436 } | 4459 } |
4437 } | 4460 } |
4438 SetPosition(saved_pos); | 4461 SetPosition(saved_pos); |
4439 return is_var_decl; | 4462 return is_var_decl; |
4440 } | 4463 } |
4441 | 4464 |
4442 | 4465 |
4443 // Look ahead to detect whether the next tokens should be parsed as | 4466 // Look ahead to detect whether the next tokens should be parsed as |
4444 // a function declaration. Token position remains unchanged. | 4467 // a function declaration. Token position remains unchanged. |
4445 bool Parser::IsFunctionDeclaration() { | 4468 bool Parser::IsFunctionDeclaration() { |
4446 const intptr_t saved_pos = token_index_; | 4469 const intptr_t saved_pos = TokenPos(); |
4447 if (IsIdentifier() && (LookaheadToken(1) == Token::kLPAREN)) { | 4470 if (IsIdentifier() && (LookaheadToken(1) == Token::kLPAREN)) { |
4448 // Possibly a function without explicit return type. | 4471 // Possibly a function without explicit return type. |
4449 ConsumeToken(); // Consume function identifier. | 4472 ConsumeToken(); // Consume function identifier. |
4450 } else if (TryParseReturnType()) { | 4473 } else if (TryParseReturnType()) { |
4451 if (!IsIdentifier()) { | 4474 if (!IsIdentifier()) { |
4452 SetPosition(saved_pos); | 4475 SetPosition(saved_pos); |
4453 return false; | 4476 return false; |
4454 } | 4477 } |
4455 ConsumeToken(); // Consume function identifier. | 4478 ConsumeToken(); // Consume function identifier. |
4456 } else { | 4479 } else { |
(...skipping 12 matching lines...) Expand all Loading... |
4469 } | 4492 } |
4470 SetPosition(saved_pos); | 4493 SetPosition(saved_pos); |
4471 return false; | 4494 return false; |
4472 } | 4495 } |
4473 | 4496 |
4474 | 4497 |
4475 bool Parser::IsTopLevelAccessor() { | 4498 bool Parser::IsTopLevelAccessor() { |
4476 if ((CurrentToken() == Token::kGET) || (CurrentToken() == Token::kSET)) { | 4499 if ((CurrentToken() == Token::kGET) || (CurrentToken() == Token::kSET)) { |
4477 return true; | 4500 return true; |
4478 } | 4501 } |
4479 const intptr_t saved_pos = token_index_; | 4502 const intptr_t saved_pos = TokenPos(); |
4480 if (TryParseReturnType()) { | 4503 if (TryParseReturnType()) { |
4481 if ((CurrentToken() == Token::kGET) || (CurrentToken() == Token::kSET)) { | 4504 if ((CurrentToken() == Token::kGET) || (CurrentToken() == Token::kSET)) { |
4482 if (Token::IsIdentifier(LookaheadToken(1))) { // Accessor name. | 4505 if (Token::IsIdentifier(LookaheadToken(1))) { // Accessor name. |
4483 SetPosition(saved_pos); | 4506 SetPosition(saved_pos); |
4484 return true; | 4507 return true; |
4485 } | 4508 } |
4486 } | 4509 } |
4487 } | 4510 } |
4488 SetPosition(saved_pos); | 4511 SetPosition(saved_pos); |
4489 return false; | 4512 return false; |
4490 } | 4513 } |
4491 | 4514 |
4492 | 4515 |
4493 bool Parser::IsFunctionLiteral() { | 4516 bool Parser::IsFunctionLiteral() { |
4494 if (!allow_function_literals_) { | 4517 if (!allow_function_literals_) { |
4495 return false; | 4518 return false; |
4496 } | 4519 } |
4497 const intptr_t saved_pos = token_index_; | 4520 const intptr_t saved_pos = TokenPos(); |
4498 bool is_function_literal = false; | 4521 bool is_function_literal = false; |
4499 if (IsIdentifier() && (LookaheadToken(1) == Token::kLPAREN)) { | 4522 if (IsIdentifier() && (LookaheadToken(1) == Token::kLPAREN)) { |
4500 ConsumeToken(); // Consume function identifier. | 4523 ConsumeToken(); // Consume function identifier. |
4501 } else if (TryParseReturnType()) { | 4524 } else if (TryParseReturnType()) { |
4502 if (!IsIdentifier()) { | 4525 if (!IsIdentifier()) { |
4503 SetPosition(saved_pos); | 4526 SetPosition(saved_pos); |
4504 return false; | 4527 return false; |
4505 } | 4528 } |
4506 ConsumeToken(); // Comsume function identifier. | 4529 ConsumeToken(); // Comsume function identifier. |
4507 } | 4530 } |
4508 if (CurrentToken() == Token::kLPAREN) { | 4531 if (CurrentToken() == Token::kLPAREN) { |
4509 SkipToMatchingParenthesis(); | 4532 SkipToMatchingParenthesis(); |
4510 if ((CurrentToken() == Token::kLBRACE) || | 4533 if ((CurrentToken() == Token::kLBRACE) || |
4511 (CurrentToken() == Token::kARROW)) { | 4534 (CurrentToken() == Token::kARROW)) { |
4512 is_function_literal = true; | 4535 is_function_literal = true; |
4513 } | 4536 } |
4514 } | 4537 } |
4515 SetPosition(saved_pos); | 4538 SetPosition(saved_pos); |
4516 return is_function_literal; | 4539 return is_function_literal; |
4517 } | 4540 } |
4518 | 4541 |
4519 | 4542 |
4520 // Current token position is the token after the opening ( of the for | 4543 // Current token position is the token after the opening ( of the for |
4521 // statement. Returns true if we recognize a for ( .. in expr) | 4544 // statement. Returns true if we recognize a for ( .. in expr) |
4522 // statement. | 4545 // statement. |
4523 bool Parser::IsForInStatement() { | 4546 bool Parser::IsForInStatement() { |
4524 const intptr_t saved_pos = token_index_; | 4547 const intptr_t saved_pos = TokenPos(); |
4525 bool result = false; | 4548 bool result = false; |
4526 if (CurrentToken() == Token::kVAR || CurrentToken() == Token::kFINAL) { | 4549 if (CurrentToken() == Token::kVAR || CurrentToken() == Token::kFINAL) { |
4527 ConsumeToken(); | 4550 ConsumeToken(); |
4528 } | 4551 } |
4529 if (IsIdentifier()) { | 4552 if (IsIdentifier()) { |
4530 if (LookaheadToken(1) == Token::kIN) { | 4553 if (LookaheadToken(1) == Token::kIN) { |
4531 result = true; | 4554 result = true; |
4532 } else if (TryParseOptionalType()) { | 4555 } else if (TryParseOptionalType()) { |
4533 if (IsIdentifier()) { | 4556 if (IsIdentifier()) { |
4534 ConsumeToken(); | 4557 ConsumeToken(); |
(...skipping 25 matching lines...) Expand all Loading... |
4560 } | 4583 } |
4561 return false; | 4584 return false; |
4562 } | 4585 } |
4563 | 4586 |
4564 | 4587 |
4565 void Parser::ParseStatementSequence() { | 4588 void Parser::ParseStatementSequence() { |
4566 TRACE_PARSER("ParseStatementSequence"); | 4589 TRACE_PARSER("ParseStatementSequence"); |
4567 const bool dead_code_allowed = true; | 4590 const bool dead_code_allowed = true; |
4568 bool abrupt_completing_seen = false; | 4591 bool abrupt_completing_seen = false; |
4569 while (CurrentToken() != Token::kRBRACE) { | 4592 while (CurrentToken() != Token::kRBRACE) { |
4570 const intptr_t statement_pos = token_index_; | 4593 const intptr_t statement_pos = TokenPos(); |
4571 AstNode* statement = ParseStatement(); | 4594 AstNode* statement = ParseStatement(); |
4572 // Do not add statements with no effect (e.g., LoadLocalNode). | 4595 // Do not add statements with no effect (e.g., LoadLocalNode). |
4573 if ((statement != NULL) && statement->IsLoadLocalNode()) { | 4596 if ((statement != NULL) && statement->IsLoadLocalNode()) { |
4574 // Skip load local. | 4597 // Skip load local. |
4575 statement = statement->AsLoadLocalNode()->pseudo(); | 4598 statement = statement->AsLoadLocalNode()->pseudo(); |
4576 } | 4599 } |
4577 if (statement != NULL) { | 4600 if (statement != NULL) { |
4578 if (!dead_code_allowed && abrupt_completing_seen) { | 4601 if (!dead_code_allowed && abrupt_completing_seen) { |
4579 ErrorMsg(statement_pos, "dead code after abrupt completing statement"); | 4602 ErrorMsg(statement_pos, "dead code after abrupt completing statement"); |
4580 } | 4603 } |
(...skipping 29 matching lines...) Expand all Loading... |
4610 } | 4633 } |
4611 } | 4634 } |
4612 SequenceNode* sequence = CloseBlock(); | 4635 SequenceNode* sequence = CloseBlock(); |
4613 return sequence; | 4636 return sequence; |
4614 } | 4637 } |
4615 | 4638 |
4616 | 4639 |
4617 AstNode* Parser::ParseIfStatement(String* label_name) { | 4640 AstNode* Parser::ParseIfStatement(String* label_name) { |
4618 TRACE_PARSER("ParseIfStatement"); | 4641 TRACE_PARSER("ParseIfStatement"); |
4619 ASSERT(CurrentToken() == Token::kIF); | 4642 ASSERT(CurrentToken() == Token::kIF); |
4620 const intptr_t if_pos = token_index_; | 4643 const intptr_t if_pos = TokenPos(); |
4621 SourceLabel* label = NULL; | 4644 SourceLabel* label = NULL; |
4622 if (label_name != NULL) { | 4645 if (label_name != NULL) { |
4623 label = SourceLabel::New(if_pos, label_name, SourceLabel::kStatement); | 4646 label = SourceLabel::New(if_pos, label_name, SourceLabel::kStatement); |
4624 OpenBlock(); | 4647 OpenBlock(); |
4625 current_block_->scope->AddLabel(label); | 4648 current_block_->scope->AddLabel(label); |
4626 } | 4649 } |
4627 ConsumeToken(); | 4650 ConsumeToken(); |
4628 ExpectToken(Token::kLPAREN); | 4651 ExpectToken(Token::kLPAREN); |
4629 AstNode* cond_expr = ParseExpr(kAllowConst); | 4652 AstNode* cond_expr = ParseExpr(kAllowConst); |
4630 ExpectToken(Token::kRPAREN); | 4653 ExpectToken(Token::kRPAREN); |
(...skipping 12 matching lines...) Expand all Loading... |
4643 if_node = sequence; | 4666 if_node = sequence; |
4644 } | 4667 } |
4645 return if_node; | 4668 return if_node; |
4646 } | 4669 } |
4647 | 4670 |
4648 | 4671 |
4649 CaseNode* Parser::ParseCaseClause(LocalVariable* switch_expr_value, | 4672 CaseNode* Parser::ParseCaseClause(LocalVariable* switch_expr_value, |
4650 SourceLabel* case_label) { | 4673 SourceLabel* case_label) { |
4651 TRACE_PARSER("ParseCaseStatement"); | 4674 TRACE_PARSER("ParseCaseStatement"); |
4652 bool default_seen = false; | 4675 bool default_seen = false; |
4653 const intptr_t case_pos = token_index_; | 4676 const intptr_t case_pos = TokenPos(); |
4654 // The case expressions node sequence does not own the enclosing scope. | 4677 // The case expressions node sequence does not own the enclosing scope. |
4655 SequenceNode* case_expressions = new SequenceNode(case_pos, NULL); | 4678 SequenceNode* case_expressions = new SequenceNode(case_pos, NULL); |
4656 while (CurrentToken() == Token::kCASE || CurrentToken() == Token::kDEFAULT) { | 4679 while (CurrentToken() == Token::kCASE || CurrentToken() == Token::kDEFAULT) { |
4657 if (CurrentToken() == Token::kCASE) { | 4680 if (CurrentToken() == Token::kCASE) { |
4658 if (default_seen) { | 4681 if (default_seen) { |
4659 ErrorMsg("default clause must be last case"); | 4682 ErrorMsg("default clause must be last case"); |
4660 } | 4683 } |
4661 ConsumeToken(); // Keyword case. | 4684 ConsumeToken(); // Keyword case. |
4662 const intptr_t expr_pos = token_index_; | 4685 const intptr_t expr_pos = TokenPos(); |
4663 AstNode* expr = ParseExpr(kAllowConst); | 4686 AstNode* expr = ParseExpr(kAllowConst); |
4664 AstNode* switch_expr_load = new LoadLocalNode(case_pos, | 4687 AstNode* switch_expr_load = new LoadLocalNode(case_pos, |
4665 *switch_expr_value); | 4688 *switch_expr_value); |
4666 AstNode* case_comparison = new ComparisonNode(expr_pos, | 4689 AstNode* case_comparison = new ComparisonNode(expr_pos, |
4667 Token::kEQ, | 4690 Token::kEQ, |
4668 expr, | 4691 expr, |
4669 switch_expr_load); | 4692 switch_expr_load); |
4670 case_expressions->Add(case_comparison); | 4693 case_expressions->Add(case_comparison); |
4671 } else { | 4694 } else { |
4672 if (default_seen) { | 4695 if (default_seen) { |
(...skipping 19 matching lines...) Expand all Loading... |
4692 next_token = CurrentToken(); | 4715 next_token = CurrentToken(); |
4693 } | 4716 } |
4694 if (next_token == Token::kRBRACE) { | 4717 if (next_token == Token::kRBRACE) { |
4695 // End of switch statement. | 4718 // End of switch statement. |
4696 break; | 4719 break; |
4697 } | 4720 } |
4698 if ((next_token == Token::kCASE) || (next_token == Token::kDEFAULT)) { | 4721 if ((next_token == Token::kCASE) || (next_token == Token::kDEFAULT)) { |
4699 // End of this case clause. If there is a possible fall-through to | 4722 // End of this case clause. If there is a possible fall-through to |
4700 // the next case clause, throw an implicit FallThroughError. | 4723 // the next case clause, throw an implicit FallThroughError. |
4701 if (!abrupt_completing_seen) { | 4724 if (!abrupt_completing_seen) { |
4702 ArgumentListNode* arguments = new ArgumentListNode(token_index_); | 4725 ArgumentListNode* arguments = new ArgumentListNode(TokenPos()); |
4703 arguments->Add(new LiteralNode( | 4726 arguments->Add(new LiteralNode( |
4704 token_index_, Integer::ZoneHandle(Integer::New(token_index_)))); | 4727 TokenPos(), Integer::ZoneHandle(Integer::New(TokenPos())))); |
4705 current_block_->statements->Add( | 4728 current_block_->statements->Add( |
4706 MakeStaticCall(kFallThroughErrorName, kThrowNewName, arguments)); | 4729 MakeStaticCall(kFallThroughErrorName, kThrowNewName, arguments)); |
4707 } | 4730 } |
4708 break; | 4731 break; |
4709 } | 4732 } |
4710 // The next statement still belongs to this case. | 4733 // The next statement still belongs to this case. |
4711 AstNode* statement = ParseStatement(); | 4734 AstNode* statement = ParseStatement(); |
4712 if (statement != NULL) { | 4735 if (statement != NULL) { |
4713 current_block_->statements->Add(statement); | 4736 current_block_->statements->Add(statement); |
4714 abrupt_completing_seen |= IsAbruptCompleting(statement); | 4737 abrupt_completing_seen |= IsAbruptCompleting(statement); |
4715 } | 4738 } |
4716 } | 4739 } |
4717 SequenceNode* statements = CloseBlock(); | 4740 SequenceNode* statements = CloseBlock(); |
4718 return new CaseNode(case_pos, case_label, | 4741 return new CaseNode(case_pos, case_label, |
4719 case_expressions, default_seen, switch_expr_value, statements); | 4742 case_expressions, default_seen, switch_expr_value, statements); |
4720 } | 4743 } |
4721 | 4744 |
4722 | 4745 |
4723 AstNode* Parser::ParseSwitchStatement(String* label_name) { | 4746 AstNode* Parser::ParseSwitchStatement(String* label_name) { |
4724 TRACE_PARSER("ParseSwitchStatement"); | 4747 TRACE_PARSER("ParseSwitchStatement"); |
4725 ASSERT(CurrentToken() == Token::kSWITCH); | 4748 ASSERT(CurrentToken() == Token::kSWITCH); |
4726 const intptr_t switch_pos = token_index_; | 4749 const intptr_t switch_pos = TokenPos(); |
4727 SourceLabel* label = | 4750 SourceLabel* label = |
4728 SourceLabel::New(switch_pos, label_name, SourceLabel::kSwitch); | 4751 SourceLabel::New(switch_pos, label_name, SourceLabel::kSwitch); |
4729 ConsumeToken(); | 4752 ConsumeToken(); |
4730 const bool parens_are_mandatory = false; | 4753 const bool parens_are_mandatory = false; |
4731 bool paren_found = false; | 4754 bool paren_found = false; |
4732 if (CurrentToken() == Token::kLPAREN) { | 4755 if (CurrentToken() == Token::kLPAREN) { |
4733 paren_found = true; | 4756 paren_found = true; |
4734 ConsumeToken(); | 4757 ConsumeToken(); |
4735 } else if (parens_are_mandatory) { | 4758 } else if (parens_are_mandatory) { |
4736 ErrorMsg("'(' expected"); | 4759 ErrorMsg("'(' expected"); |
4737 } | 4760 } |
4738 const intptr_t expr_pos = token_index_; | 4761 const intptr_t expr_pos = TokenPos(); |
4739 AstNode* switch_expr = ParseExpr(kAllowConst); | 4762 AstNode* switch_expr = ParseExpr(kAllowConst); |
4740 if (paren_found) { | 4763 if (paren_found) { |
4741 ExpectToken(Token::kRPAREN); | 4764 ExpectToken(Token::kRPAREN); |
4742 } | 4765 } |
4743 ExpectToken(Token::kLBRACE); | 4766 ExpectToken(Token::kLBRACE); |
4744 OpenBlock(); | 4767 OpenBlock(); |
4745 current_block_->scope->AddLabel(label); | 4768 current_block_->scope->AddLabel(label); |
4746 | 4769 |
4747 // Store switch expression in temporary local variable. | 4770 // Store switch expression in temporary local variable. |
4748 LocalVariable* temp_variable = | 4771 LocalVariable* temp_variable = |
4749 new LocalVariable(expr_pos, | 4772 new LocalVariable(expr_pos, |
4750 String::ZoneHandle(String::NewSymbol(":switch_expr")), | 4773 String::ZoneHandle(String::NewSymbol(":switch_expr")), |
4751 Type::ZoneHandle(Type::DynamicType())); | 4774 Type::ZoneHandle(Type::DynamicType())); |
4752 current_block_->scope->AddVariable(temp_variable); | 4775 current_block_->scope->AddVariable(temp_variable); |
4753 AstNode* save_switch_expr = | 4776 AstNode* save_switch_expr = |
4754 new StoreLocalNode(expr_pos, *temp_variable, switch_expr); | 4777 new StoreLocalNode(expr_pos, *temp_variable, switch_expr); |
4755 current_block_->statements->Add(save_switch_expr); | 4778 current_block_->statements->Add(save_switch_expr); |
4756 | 4779 |
4757 // Parse case clauses | 4780 // Parse case clauses |
4758 bool default_seen = false; | 4781 bool default_seen = false; |
4759 while (true) { | 4782 while (true) { |
4760 // Check for statement label | 4783 // Check for statement label |
4761 SourceLabel* case_label = NULL; | 4784 SourceLabel* case_label = NULL; |
4762 if (IsIdentifier() && LookaheadToken(1) == Token::kCOLON) { | 4785 if (IsIdentifier() && LookaheadToken(1) == Token::kCOLON) { |
4763 // Case statements start with a label. | 4786 // Case statements start with a label. |
4764 String* label_name = CurrentLiteral(); | 4787 String* label_name = CurrentLiteral(); |
4765 const intptr_t label_pos = token_index_; | 4788 const intptr_t label_pos = TokenPos(); |
4766 ConsumeToken(); // Consume label identifier. | 4789 ConsumeToken(); // Consume label identifier. |
4767 ConsumeToken(); // Consume colon. | 4790 ConsumeToken(); // Consume colon. |
4768 case_label = current_block_->scope->LocalLookupLabel(*label_name); | 4791 case_label = current_block_->scope->LocalLookupLabel(*label_name); |
4769 if (case_label == NULL) { | 4792 if (case_label == NULL) { |
4770 // Label does not exist yet. Add it to scope of switch statement. | 4793 // Label does not exist yet. Add it to scope of switch statement. |
4771 case_label = | 4794 case_label = |
4772 new SourceLabel(label_pos, *label_name, SourceLabel::kCase); | 4795 new SourceLabel(label_pos, *label_name, SourceLabel::kCase); |
4773 current_block_->scope->AddLabel(case_label); | 4796 current_block_->scope->AddLabel(case_label); |
4774 } else if (case_label->kind() == SourceLabel::kForward) { | 4797 } else if (case_label->kind() == SourceLabel::kForward) { |
4775 // We have seen a 'continue' with this label name. Resolve | 4798 // We have seen a 'continue' with this label name. Resolve |
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4807 } | 4830 } |
4808 | 4831 |
4809 SequenceNode* switch_body = CloseBlock(); | 4832 SequenceNode* switch_body = CloseBlock(); |
4810 ExpectToken(Token::kRBRACE); | 4833 ExpectToken(Token::kRBRACE); |
4811 return new SwitchNode(switch_pos, label, switch_body); | 4834 return new SwitchNode(switch_pos, label, switch_body); |
4812 } | 4835 } |
4813 | 4836 |
4814 | 4837 |
4815 AstNode* Parser::ParseWhileStatement(String* label_name) { | 4838 AstNode* Parser::ParseWhileStatement(String* label_name) { |
4816 TRACE_PARSER("ParseWhileStatement"); | 4839 TRACE_PARSER("ParseWhileStatement"); |
4817 const intptr_t while_pos = token_index_; | 4840 const intptr_t while_pos = TokenPos(); |
4818 SourceLabel* label = | 4841 SourceLabel* label = |
4819 SourceLabel::New(while_pos, label_name, SourceLabel::kWhile); | 4842 SourceLabel::New(while_pos, label_name, SourceLabel::kWhile); |
4820 ConsumeToken(); | 4843 ConsumeToken(); |
4821 ExpectToken(Token::kLPAREN); | 4844 ExpectToken(Token::kLPAREN); |
4822 AstNode* cond_expr = ParseExpr(kAllowConst); | 4845 AstNode* cond_expr = ParseExpr(kAllowConst); |
4823 ExpectToken(Token::kRPAREN); | 4846 ExpectToken(Token::kRPAREN); |
4824 const bool parsing_loop_body = true; | 4847 const bool parsing_loop_body = true; |
4825 SequenceNode* while_body = ParseNestedStatement(parsing_loop_body, label); | 4848 SequenceNode* while_body = ParseNestedStatement(parsing_loop_body, label); |
4826 return new WhileNode(while_pos, label, cond_expr, while_body); | 4849 return new WhileNode(while_pos, label, cond_expr, while_body); |
4827 } | 4850 } |
4828 | 4851 |
4829 | 4852 |
4830 AstNode* Parser::ParseDoWhileStatement(String* label_name) { | 4853 AstNode* Parser::ParseDoWhileStatement(String* label_name) { |
4831 TRACE_PARSER("ParseDoWhileStatement"); | 4854 TRACE_PARSER("ParseDoWhileStatement"); |
4832 const intptr_t do_pos = token_index_; | 4855 const intptr_t do_pos = TokenPos(); |
4833 SourceLabel* label = | 4856 SourceLabel* label = |
4834 SourceLabel::New(do_pos, label_name, SourceLabel::kDoWhile); | 4857 SourceLabel::New(do_pos, label_name, SourceLabel::kDoWhile); |
4835 ConsumeToken(); | 4858 ConsumeToken(); |
4836 const bool parsing_loop_body = true; | 4859 const bool parsing_loop_body = true; |
4837 SequenceNode* dowhile_body = ParseNestedStatement(parsing_loop_body, label); | 4860 SequenceNode* dowhile_body = ParseNestedStatement(parsing_loop_body, label); |
4838 ExpectToken(Token::kWHILE); | 4861 ExpectToken(Token::kWHILE); |
4839 ExpectToken(Token::kLPAREN); | 4862 ExpectToken(Token::kLPAREN); |
4840 AstNode* cond_expr = ParseExpr(kAllowConst); | 4863 AstNode* cond_expr = ParseExpr(kAllowConst); |
4841 ExpectToken(Token::kRPAREN); | 4864 ExpectToken(Token::kRPAREN); |
4842 ExpectSemicolon(); | 4865 ExpectSemicolon(); |
4843 return new DoWhileNode(do_pos, label, cond_expr, dowhile_body); | 4866 return new DoWhileNode(do_pos, label, cond_expr, dowhile_body); |
4844 } | 4867 } |
4845 | 4868 |
4846 | 4869 |
4847 AstNode* Parser::ParseForInStatement(intptr_t forin_pos, | 4870 AstNode* Parser::ParseForInStatement(intptr_t forin_pos, |
4848 SourceLabel* label) { | 4871 SourceLabel* label) { |
4849 TRACE_PARSER("ParseForInStatement"); | 4872 TRACE_PARSER("ParseForInStatement"); |
4850 bool is_final = (CurrentToken() == Token::kFINAL); | 4873 bool is_final = (CurrentToken() == Token::kFINAL); |
4851 const String* loop_var_name = NULL; | 4874 const String* loop_var_name = NULL; |
4852 LocalVariable* loop_var = NULL; | 4875 LocalVariable* loop_var = NULL; |
4853 intptr_t loop_var_pos = 0; | 4876 intptr_t loop_var_pos = 0; |
4854 if (LookaheadToken(1) == Token::kIN) { | 4877 if (LookaheadToken(1) == Token::kIN) { |
4855 loop_var_pos = token_index_; | 4878 loop_var_pos = TokenPos(); |
4856 loop_var_name = ExpectIdentifier("variable name expected"); | 4879 loop_var_name = ExpectIdentifier("variable name expected"); |
4857 } else { | 4880 } else { |
4858 // The case without a type is handled above, so require a type here. | 4881 // The case without a type is handled above, so require a type here. |
4859 const AbstractType& type = AbstractType::ZoneHandle(ParseFinalVarOrType( | 4882 const AbstractType& type = AbstractType::ZoneHandle(ParseFinalVarOrType( |
4860 FLAG_enable_type_checks ? ClassFinalizer::kFinalize : | 4883 FLAG_enable_type_checks ? ClassFinalizer::kFinalize : |
4861 ClassFinalizer::kIgnore)); | 4884 ClassFinalizer::kIgnore)); |
4862 loop_var_pos = token_index_; | 4885 loop_var_pos = TokenPos(); |
4863 loop_var_name = ExpectIdentifier("variable name expected"); | 4886 loop_var_name = ExpectIdentifier("variable name expected"); |
4864 loop_var = new LocalVariable(loop_var_pos, *loop_var_name, type); | 4887 loop_var = new LocalVariable(loop_var_pos, *loop_var_name, type); |
4865 if (is_final) { | 4888 if (is_final) { |
4866 loop_var->set_is_final(); | 4889 loop_var->set_is_final(); |
4867 } | 4890 } |
4868 } | 4891 } |
4869 ExpectToken(Token::kIN); | 4892 ExpectToken(Token::kIN); |
4870 const intptr_t collection_pos = token_index_; | 4893 const intptr_t collection_pos = TokenPos(); |
4871 AstNode* collection_expr = ParseExpr(kAllowConst); | 4894 AstNode* collection_expr = ParseExpr(kAllowConst); |
4872 ExpectToken(Token::kRPAREN); | 4895 ExpectToken(Token::kRPAREN); |
4873 | 4896 |
4874 OpenBlock(); // Implicit block around while loop. | 4897 OpenBlock(); // Implicit block around while loop. |
4875 | 4898 |
4876 // Generate implicit iterator variable and add to scope. | 4899 // Generate implicit iterator variable and add to scope. |
4877 const String& iterator_name = | 4900 const String& iterator_name = |
4878 String::ZoneHandle(String::NewSymbol(":for-in-iter")); | 4901 String::ZoneHandle(String::NewSymbol(":for-in-iter")); |
4879 // We could set the type of the implicit iterator variable to Iterator<T> | 4902 // We could set the type of the implicit iterator variable to Iterator<T> |
4880 // where T is the type of the for loop variable. However, the type error | 4903 // where T is the type of the for loop variable. However, the type error |
(...skipping 72 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4953 AstNode* while_statement = | 4976 AstNode* while_statement = |
4954 new WhileNode(forin_pos, label, iterator_has_next, for_loop_statement); | 4977 new WhileNode(forin_pos, label, iterator_has_next, for_loop_statement); |
4955 current_block_->statements->Add(while_statement); | 4978 current_block_->statements->Add(while_statement); |
4956 | 4979 |
4957 return CloseBlock(); // Implicit block around while loop. | 4980 return CloseBlock(); // Implicit block around while loop. |
4958 } | 4981 } |
4959 | 4982 |
4960 | 4983 |
4961 AstNode* Parser::ParseForStatement(String* label_name) { | 4984 AstNode* Parser::ParseForStatement(String* label_name) { |
4962 TRACE_PARSER("ParseForStatement"); | 4985 TRACE_PARSER("ParseForStatement"); |
4963 const intptr_t for_pos = token_index_; | 4986 const intptr_t for_pos = TokenPos(); |
4964 ConsumeToken(); | 4987 ConsumeToken(); |
4965 ExpectToken(Token::kLPAREN); | 4988 ExpectToken(Token::kLPAREN); |
4966 SourceLabel* label = SourceLabel::New(for_pos, label_name, SourceLabel::kFor); | 4989 SourceLabel* label = SourceLabel::New(for_pos, label_name, SourceLabel::kFor); |
4967 if (IsForInStatement()) { | 4990 if (IsForInStatement()) { |
4968 return ParseForInStatement(for_pos, label); | 4991 return ParseForInStatement(for_pos, label); |
4969 } | 4992 } |
4970 OpenBlock(); | 4993 OpenBlock(); |
4971 // The label is added to the implicit scope that also contains | 4994 // The label is added to the implicit scope that also contains |
4972 // the loop variable declarations. | 4995 // the loop variable declarations. |
4973 current_block_->scope->AddLabel(label); | 4996 current_block_->scope->AddLabel(label); |
4974 AstNode* initializer = NULL; | 4997 AstNode* initializer = NULL; |
4975 const intptr_t init_pos = token_index_; | 4998 const intptr_t init_pos = TokenPos(); |
4976 LocalScope* init_scope = current_block_->scope; | 4999 LocalScope* init_scope = current_block_->scope; |
4977 if (CurrentToken() != Token::kSEMICOLON) { | 5000 if (CurrentToken() != Token::kSEMICOLON) { |
4978 if (IsVariableDeclaration()) { | 5001 if (IsVariableDeclaration()) { |
4979 initializer = ParseVariableDeclarationList(); | 5002 initializer = ParseVariableDeclarationList(); |
4980 } else { | 5003 } else { |
4981 initializer = ParseExpr(kAllowConst); | 5004 initializer = ParseExpr(kAllowConst); |
4982 } | 5005 } |
4983 } | 5006 } |
4984 ExpectSemicolon(); | 5007 ExpectSemicolon(); |
4985 AstNode* condition = NULL; | 5008 AstNode* condition = NULL; |
4986 if (CurrentToken() != Token::kSEMICOLON) { | 5009 if (CurrentToken() != Token::kSEMICOLON) { |
4987 condition = ParseExpr(kAllowConst); | 5010 condition = ParseExpr(kAllowConst); |
4988 } | 5011 } |
4989 ExpectSemicolon(); | 5012 ExpectSemicolon(); |
4990 AstNode* increment = NULL; | 5013 AstNode* increment = NULL; |
4991 const intptr_t incr_pos = token_index_; | 5014 const intptr_t incr_pos = TokenPos(); |
4992 LocalScope* incr_scope = current_block_->scope; | 5015 LocalScope* incr_scope = current_block_->scope; |
4993 if (CurrentToken() != Token::kRPAREN) { | 5016 if (CurrentToken() != Token::kRPAREN) { |
4994 increment = ParseExprList(); | 5017 increment = ParseExprList(); |
4995 } | 5018 } |
4996 ExpectToken(Token::kRPAREN); | 5019 ExpectToken(Token::kRPAREN); |
4997 const bool parsing_loop_body = true; | 5020 const bool parsing_loop_body = true; |
4998 SequenceNode* body = ParseNestedStatement(parsing_loop_body, NULL); | 5021 SequenceNode* body = ParseNestedStatement(parsing_loop_body, NULL); |
4999 | 5022 |
5000 // Check whether any of the variables in the initializer part of | 5023 // Check whether any of the variables in the initializer part of |
5001 // the for statement are captured by a closure. If so, we insert a | 5024 // the for statement are captured by a closure. If so, we insert a |
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
5033 ASSERT(!cls.IsNull()); | 5056 ASSERT(!cls.IsNull()); |
5034 const String& func_name = | 5057 const String& func_name = |
5035 String::ZoneHandle(String::NewSymbol(function_name)); | 5058 String::ZoneHandle(String::NewSymbol(function_name)); |
5036 const Function& func = Function::ZoneHandle( | 5059 const Function& func = Function::ZoneHandle( |
5037 Resolver::ResolveStatic(cls, | 5060 Resolver::ResolveStatic(cls, |
5038 func_name, | 5061 func_name, |
5039 arguments->length(), | 5062 arguments->length(), |
5040 arguments->names(), | 5063 arguments->names(), |
5041 Resolver::kIsQualified)); | 5064 Resolver::kIsQualified)); |
5042 ASSERT(!func.IsNull()); | 5065 ASSERT(!func.IsNull()); |
5043 CheckFunctionIsCallable(arguments->token_index(), func); | 5066 CheckFunctionIsCallable(arguments->token_pos(), func); |
5044 return new StaticCallNode(arguments->token_index(), func, arguments); | 5067 return new StaticCallNode(arguments->token_pos(), func, arguments); |
5045 } | 5068 } |
5046 | 5069 |
5047 | 5070 |
5048 AstNode* Parser::MakeAssertCall(intptr_t begin, intptr_t end) { | 5071 AstNode* Parser::MakeAssertCall(intptr_t begin, intptr_t end) { |
5049 ArgumentListNode* arguments = new ArgumentListNode(begin); | 5072 ArgumentListNode* arguments = new ArgumentListNode(begin); |
5050 arguments->Add(new LiteralNode(begin, | 5073 arguments->Add(new LiteralNode(begin, |
5051 Integer::ZoneHandle(Integer::New(begin)))); | 5074 Integer::ZoneHandle(Integer::New(begin)))); |
5052 arguments->Add(new LiteralNode(end, | 5075 arguments->Add(new LiteralNode(end, |
5053 Integer::ZoneHandle(Integer::New(end)))); | 5076 Integer::ZoneHandle(Integer::New(end)))); |
5054 return MakeStaticCall(kAssertionErrorName, kThrowNewName, arguments); | 5077 return MakeStaticCall(kAssertionErrorName, kThrowNewName, arguments); |
5055 } | 5078 } |
5056 | 5079 |
5057 | 5080 |
5058 AstNode* Parser::InsertClosureCallNodes(AstNode* condition) { | 5081 AstNode* Parser::InsertClosureCallNodes(AstNode* condition) { |
5059 if (condition->IsClosureNode() || | 5082 if (condition->IsClosureNode() || |
5060 (condition->IsStoreLocalNode() && | 5083 (condition->IsStoreLocalNode() && |
5061 condition->AsStoreLocalNode()->value()->IsClosureNode())) { | 5084 condition->AsStoreLocalNode()->value()->IsClosureNode())) { |
5062 EnsureExpressionTemp(); | 5085 EnsureExpressionTemp(); |
5063 // Function literal in assert implies a call. | 5086 // Function literal in assert implies a call. |
5064 const intptr_t pos = condition->token_index(); | 5087 const intptr_t pos = condition->token_pos(); |
5065 condition = new ClosureCallNode(pos, condition, new ArgumentListNode(pos)); | 5088 condition = new ClosureCallNode(pos, condition, new ArgumentListNode(pos)); |
5066 } else if (condition->IsConditionalExprNode()) { | 5089 } else if (condition->IsConditionalExprNode()) { |
5067 ConditionalExprNode* cond_expr = condition->AsConditionalExprNode(); | 5090 ConditionalExprNode* cond_expr = condition->AsConditionalExprNode(); |
5068 cond_expr->set_true_expr(InsertClosureCallNodes(cond_expr->true_expr())); | 5091 cond_expr->set_true_expr(InsertClosureCallNodes(cond_expr->true_expr())); |
5069 cond_expr->set_false_expr(InsertClosureCallNodes(cond_expr->false_expr())); | 5092 cond_expr->set_false_expr(InsertClosureCallNodes(cond_expr->false_expr())); |
5070 } | 5093 } |
5071 return condition; | 5094 return condition; |
5072 } | 5095 } |
5073 | 5096 |
5074 | 5097 |
5075 AstNode* Parser::ParseAssertStatement() { | 5098 AstNode* Parser::ParseAssertStatement() { |
5076 TRACE_PARSER("ParseAssertStatement"); | 5099 TRACE_PARSER("ParseAssertStatement"); |
5077 ConsumeToken(); // Consume assert keyword. | 5100 ConsumeToken(); // Consume assert keyword. |
5078 ExpectToken(Token::kLPAREN); | 5101 ExpectToken(Token::kLPAREN); |
5079 const intptr_t condition_pos = token_index_; | 5102 const intptr_t condition_pos = TokenPos(); |
5080 if (!FLAG_enable_asserts && !FLAG_enable_type_checks) { | 5103 if (!FLAG_enable_asserts && !FLAG_enable_type_checks) { |
5081 SkipExpr(); | 5104 SkipExpr(); |
5082 ExpectToken(Token::kRPAREN); | 5105 ExpectToken(Token::kRPAREN); |
5083 return NULL; | 5106 return NULL; |
5084 } | 5107 } |
5085 AstNode* condition = ParseExpr(kAllowConst); | 5108 AstNode* condition = ParseExpr(kAllowConst); |
5086 const intptr_t condition_end = token_index_; | 5109 const intptr_t condition_end = TokenPos(); |
5087 ExpectToken(Token::kRPAREN); | 5110 ExpectToken(Token::kRPAREN); |
5088 condition = InsertClosureCallNodes(condition); | 5111 condition = InsertClosureCallNodes(condition); |
5089 condition = new UnaryOpNode(condition_pos, Token::kNOT, condition); | 5112 condition = new UnaryOpNode(condition_pos, Token::kNOT, condition); |
5090 AstNode* assert_throw = MakeAssertCall(condition_pos, condition_end); | 5113 AstNode* assert_throw = MakeAssertCall(condition_pos, condition_end); |
5091 return new IfNode(condition_pos, | 5114 return new IfNode(condition_pos, |
5092 condition, | 5115 condition, |
5093 NodeAsSequenceNode(condition_pos, assert_throw, NULL), | 5116 NodeAsSequenceNode(condition_pos, assert_throw, NULL), |
5094 NULL); | 5117 NULL); |
5095 } | 5118 } |
5096 | 5119 |
5097 | 5120 |
5098 struct CatchParamDesc { | 5121 struct CatchParamDesc { |
5099 CatchParamDesc() | 5122 CatchParamDesc() |
5100 : token_index(0), type(NULL), var(NULL), is_final(false) { } | 5123 : token_pos(0), type(NULL), var(NULL), is_final(false) { } |
5101 intptr_t token_index; | 5124 intptr_t token_pos; |
5102 const AbstractType* type; | 5125 const AbstractType* type; |
5103 const String* var; | 5126 const String* var; |
5104 bool is_final; | 5127 bool is_final; |
5105 }; | 5128 }; |
5106 | 5129 |
5107 | 5130 |
5108 // Parse the parameter specified in the catch clause. | 5131 // Parse the parameter specified in the catch clause. |
5109 void Parser::ParseCatchParameter(CatchParamDesc* catch_param) { | 5132 void Parser::ParseCatchParameter(CatchParamDesc* catch_param) { |
5110 TRACE_PARSER("ParseCatchParameter"); | 5133 TRACE_PARSER("ParseCatchParameter"); |
5111 ASSERT(catch_param != NULL); | 5134 ASSERT(catch_param != NULL); |
5112 catch_param->is_final = (CurrentToken() == Token::kFINAL); | 5135 catch_param->is_final = (CurrentToken() == Token::kFINAL); |
5113 // The type of the catch parameter must always be resolved, even in unchecked | 5136 // The type of the catch parameter must always be resolved, even in unchecked |
5114 // mode. | 5137 // mode. |
5115 catch_param->type = &AbstractType::ZoneHandle( | 5138 catch_param->type = &AbstractType::ZoneHandle( |
5116 ParseFinalVarOrType(ClassFinalizer::kFinalizeWellFormed)); | 5139 ParseFinalVarOrType(ClassFinalizer::kFinalizeWellFormed)); |
5117 catch_param->token_index = token_index_; | 5140 catch_param->token_pos = TokenPos(); |
5118 catch_param->var = ExpectIdentifier("identifier expected"); | 5141 catch_param->var = ExpectIdentifier("identifier expected"); |
5119 } | 5142 } |
5120 | 5143 |
5121 | 5144 |
5122 // Populate local scope of the catch block with the catch parameters. | 5145 // Populate local scope of the catch block with the catch parameters. |
5123 void Parser::AddCatchParamsToScope(const CatchParamDesc& exception_param, | 5146 void Parser::AddCatchParamsToScope(const CatchParamDesc& exception_param, |
5124 const CatchParamDesc& stack_trace_param, | 5147 const CatchParamDesc& stack_trace_param, |
5125 LocalScope* scope) { | 5148 LocalScope* scope) { |
5126 ASSERT(exception_param.var != NULL); | 5149 ASSERT(exception_param.var != NULL); |
5127 LocalVariable* var = new LocalVariable(exception_param.token_index, | 5150 LocalVariable* var = new LocalVariable(exception_param.token_pos, |
5128 *exception_param.var, | 5151 *exception_param.var, |
5129 *exception_param.type); | 5152 *exception_param.type); |
5130 if (exception_param.is_final) { | 5153 if (exception_param.is_final) { |
5131 var->set_is_final(); | 5154 var->set_is_final(); |
5132 } | 5155 } |
5133 bool added_to_scope = scope->AddVariable(var); | 5156 bool added_to_scope = scope->AddVariable(var); |
5134 ASSERT(added_to_scope); | 5157 ASSERT(added_to_scope); |
5135 if (stack_trace_param.var != NULL) { | 5158 if (stack_trace_param.var != NULL) { |
5136 var = new LocalVariable(token_index_, | 5159 var = new LocalVariable(TokenPos(), |
5137 *stack_trace_param.var, | 5160 *stack_trace_param.var, |
5138 *stack_trace_param.type); | 5161 *stack_trace_param.type); |
5139 if (stack_trace_param.is_final) { | 5162 if (stack_trace_param.is_final) { |
5140 var->set_is_final(); | 5163 var->set_is_final(); |
5141 } | 5164 } |
5142 added_to_scope = scope->AddVariable(var); | 5165 added_to_scope = scope->AddVariable(var); |
5143 if (!added_to_scope) { | 5166 if (!added_to_scope) { |
5144 ErrorMsg(stack_trace_param.token_index, | 5167 ErrorMsg(stack_trace_param.token_pos, |
5145 "name '%s' already exists in scope", | 5168 "name '%s' already exists in scope", |
5146 stack_trace_param.var->ToCString()); | 5169 stack_trace_param.var->ToCString()); |
5147 } | 5170 } |
5148 } | 5171 } |
5149 } | 5172 } |
5150 | 5173 |
5151 | 5174 |
5152 SequenceNode* Parser::ParseFinallyBlock() { | 5175 SequenceNode* Parser::ParseFinallyBlock() { |
5153 TRACE_PARSER("ParseFinallyBlock"); | 5176 TRACE_PARSER("ParseFinallyBlock"); |
5154 OpenBlock(); | 5177 OpenBlock(); |
(...skipping 70 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
5225 // the stack trace was copied into when an exception was | 5248 // the stack trace was copied into when an exception was |
5226 // thrown. | 5249 // thrown. |
5227 // :exception_var and :stacktrace_var get set with the exception object | 5250 // :exception_var and :stacktrace_var get set with the exception object |
5228 // and the stacktrace object when an exception is thrown. | 5251 // and the stacktrace object when an exception is thrown. |
5229 // These three implicit variables can never be captured variables. | 5252 // These three implicit variables can never be captured variables. |
5230 const String& context_var_name = | 5253 const String& context_var_name = |
5231 String::ZoneHandle(String::NewSymbol(":saved_context_var")); | 5254 String::ZoneHandle(String::NewSymbol(":saved_context_var")); |
5232 LocalVariable* context_var = | 5255 LocalVariable* context_var = |
5233 current_block_->scope->LocalLookupVariable(context_var_name); | 5256 current_block_->scope->LocalLookupVariable(context_var_name); |
5234 if (context_var == NULL) { | 5257 if (context_var == NULL) { |
5235 context_var = new LocalVariable(token_index_, | 5258 context_var = new LocalVariable(TokenPos(), |
5236 context_var_name, | 5259 context_var_name, |
5237 Type::ZoneHandle(Type::DynamicType())); | 5260 Type::ZoneHandle(Type::DynamicType())); |
5238 current_block_->scope->AddVariable(context_var); | 5261 current_block_->scope->AddVariable(context_var); |
5239 } | 5262 } |
5240 const String& catch_excp_var_name = | 5263 const String& catch_excp_var_name = |
5241 String::ZoneHandle(String::NewSymbol(":exception_var")); | 5264 String::ZoneHandle(String::NewSymbol(":exception_var")); |
5242 LocalVariable* catch_excp_var = | 5265 LocalVariable* catch_excp_var = |
5243 current_block_->scope->LocalLookupVariable(catch_excp_var_name); | 5266 current_block_->scope->LocalLookupVariable(catch_excp_var_name); |
5244 if (catch_excp_var == NULL) { | 5267 if (catch_excp_var == NULL) { |
5245 catch_excp_var = new LocalVariable(token_index_, | 5268 catch_excp_var = new LocalVariable(TokenPos(), |
5246 catch_excp_var_name, | 5269 catch_excp_var_name, |
5247 Type::ZoneHandle(Type::DynamicType())); | 5270 Type::ZoneHandle(Type::DynamicType())); |
5248 current_block_->scope->AddVariable(catch_excp_var); | 5271 current_block_->scope->AddVariable(catch_excp_var); |
5249 } | 5272 } |
5250 const String& catch_trace_var_name = | 5273 const String& catch_trace_var_name = |
5251 String::ZoneHandle(String::NewSymbol(":stacktrace_var")); | 5274 String::ZoneHandle(String::NewSymbol(":stacktrace_var")); |
5252 LocalVariable* catch_trace_var = | 5275 LocalVariable* catch_trace_var = |
5253 current_block_->scope->LocalLookupVariable(catch_trace_var_name); | 5276 current_block_->scope->LocalLookupVariable(catch_trace_var_name); |
5254 if (catch_trace_var == NULL) { | 5277 if (catch_trace_var == NULL) { |
5255 catch_trace_var = new LocalVariable(token_index_, | 5278 catch_trace_var = new LocalVariable(TokenPos(), |
5256 catch_trace_var_name, | 5279 catch_trace_var_name, |
5257 Type::ZoneHandle(Type::DynamicType())); | 5280 Type::ZoneHandle(Type::DynamicType())); |
5258 current_block_->scope->AddVariable(catch_trace_var); | 5281 current_block_->scope->AddVariable(catch_trace_var); |
5259 } | 5282 } |
5260 | 5283 |
5261 const intptr_t try_pos = token_index_; | 5284 const intptr_t try_pos = TokenPos(); |
5262 ConsumeToken(); // Consume the 'try'. | 5285 ConsumeToken(); // Consume the 'try'. |
5263 | 5286 |
5264 SourceLabel* try_label = NULL; | 5287 SourceLabel* try_label = NULL; |
5265 if (label_name != NULL) { | 5288 if (label_name != NULL) { |
5266 try_label = SourceLabel::New(try_pos, label_name, SourceLabel::kStatement); | 5289 try_label = SourceLabel::New(try_pos, label_name, SourceLabel::kStatement); |
5267 OpenBlock(); | 5290 OpenBlock(); |
5268 current_block_->scope->AddLabel(try_label); | 5291 current_block_->scope->AddLabel(try_label); |
5269 } | 5292 } |
5270 | 5293 |
5271 // Now parse the 'try' block. | 5294 // Now parse the 'try' block. |
5272 OpenBlock(); | 5295 OpenBlock(); |
5273 Block* current_try_block = current_block_; | 5296 Block* current_try_block = current_block_; |
5274 PushTryBlock(current_try_block); | 5297 PushTryBlock(current_try_block); |
5275 ExpectToken(Token::kLBRACE); | 5298 ExpectToken(Token::kLBRACE); |
5276 ParseStatementSequence(); | 5299 ParseStatementSequence(); |
5277 ExpectToken(Token::kRBRACE); | 5300 ExpectToken(Token::kRBRACE); |
5278 SequenceNode* try_block = CloseBlock(); | 5301 SequenceNode* try_block = CloseBlock(); |
5279 | 5302 |
5280 // Now create a label for the end of catch block processing so that we can | 5303 // Now create a label for the end of catch block processing so that we can |
5281 // jump over the catch block code after executing the try block. | 5304 // jump over the catch block code after executing the try block. |
5282 SourceLabel* end_catch_label = | 5305 SourceLabel* end_catch_label = |
5283 SourceLabel::New(token_index_, NULL, SourceLabel::kCatch); | 5306 SourceLabel::New(TokenPos(), NULL, SourceLabel::kCatch); |
5284 | 5307 |
5285 // Now parse the 'catch' blocks if any and merge all of them into | 5308 // Now parse the 'catch' blocks if any and merge all of them into |
5286 // an if-then sequence of the different types specified using the 'is' | 5309 // an if-then sequence of the different types specified using the 'is' |
5287 // operator. | 5310 // operator. |
5288 bool catch_seen = false; | 5311 bool catch_seen = false; |
5289 bool generic_catch_seen = false; | 5312 bool generic_catch_seen = false; |
5290 SequenceNode* catch_handler_list = NULL; | 5313 SequenceNode* catch_handler_list = NULL; |
5291 const intptr_t handler_pos = token_index_; | 5314 const intptr_t handler_pos = TokenPos(); |
5292 OpenBlock(); // Start the catch block sequence. | 5315 OpenBlock(); // Start the catch block sequence. |
5293 current_block_->scope->AddLabel(end_catch_label); | 5316 current_block_->scope->AddLabel(end_catch_label); |
5294 while (CurrentToken() == Token::kCATCH) { | 5317 while (CurrentToken() == Token::kCATCH) { |
5295 catch_seen = true; | 5318 catch_seen = true; |
5296 const intptr_t catch_pos = token_index_; | 5319 const intptr_t catch_pos = TokenPos(); |
5297 ConsumeToken(); // Consume the 'catch'. | 5320 ConsumeToken(); // Consume the 'catch'. |
5298 ExpectToken(Token::kLPAREN); | 5321 ExpectToken(Token::kLPAREN); |
5299 CatchParamDesc exception_param; | 5322 CatchParamDesc exception_param; |
5300 CatchParamDesc stack_trace_param; | 5323 CatchParamDesc stack_trace_param; |
5301 ParseCatchParameter(&exception_param); | 5324 ParseCatchParameter(&exception_param); |
5302 if (CurrentToken() == Token::kCOMMA) { | 5325 if (CurrentToken() == Token::kCOMMA) { |
5303 ConsumeToken(); | 5326 ConsumeToken(); |
5304 ParseCatchParameter(&stack_trace_param); | 5327 ParseCatchParameter(&stack_trace_param); |
5305 } | 5328 } |
5306 ExpectToken(Token::kRPAREN); | 5329 ExpectToken(Token::kRPAREN); |
(...skipping 74 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
5381 current_block_->statements->Add(catch_clause); | 5404 current_block_->statements->Add(catch_clause); |
5382 } | 5405 } |
5383 catch_handler_list = CloseBlock(); | 5406 catch_handler_list = CloseBlock(); |
5384 TryBlocks* inner_try_block = PopTryBlock(); | 5407 TryBlocks* inner_try_block = PopTryBlock(); |
5385 | 5408 |
5386 // Finally parse the 'finally' block. | 5409 // Finally parse the 'finally' block. |
5387 SequenceNode* finally_block = NULL; | 5410 SequenceNode* finally_block = NULL; |
5388 if (CurrentToken() == Token::kFINALLY) { | 5411 if (CurrentToken() == Token::kFINALLY) { |
5389 current_function_.set_is_optimizable(false); | 5412 current_function_.set_is_optimizable(false); |
5390 ConsumeToken(); // Consume the 'finally'. | 5413 ConsumeToken(); // Consume the 'finally'. |
5391 const intptr_t finally_pos = token_index_; | 5414 const intptr_t finally_pos = TokenPos(); |
5392 // Add the finally block to the exit points recorded so far. | 5415 // Add the finally block to the exit points recorded so far. |
5393 intptr_t node_index = 0; | 5416 intptr_t node_index = 0; |
5394 AstNode* node_to_inline = | 5417 AstNode* node_to_inline = |
5395 inner_try_block->GetNodeToInlineFinally(node_index); | 5418 inner_try_block->GetNodeToInlineFinally(node_index); |
5396 while (node_to_inline != NULL) { | 5419 while (node_to_inline != NULL) { |
5397 finally_block = ParseFinallyBlock(); | 5420 finally_block = ParseFinallyBlock(); |
5398 InlinedFinallyNode* node = new InlinedFinallyNode(finally_pos, | 5421 InlinedFinallyNode* node = new InlinedFinallyNode(finally_pos, |
5399 finally_block, | 5422 finally_block, |
5400 *context_var); | 5423 *context_var); |
5401 AddFinallyBlockToNode(node_to_inline, node); | 5424 AddFinallyBlockToNode(node_to_inline, node); |
5402 node_index += 1; | 5425 node_index += 1; |
5403 node_to_inline = inner_try_block->GetNodeToInlineFinally(node_index); | 5426 node_to_inline = inner_try_block->GetNodeToInlineFinally(node_index); |
5404 token_index_ = finally_pos; | 5427 tokens_iterator_.SetCurrentPosition(finally_pos); |
5405 } | 5428 } |
5406 if (!generic_catch_seen) { | 5429 if (!generic_catch_seen) { |
5407 // No generic catch handler exists so execute this finally block | 5430 // No generic catch handler exists so execute this finally block |
5408 // before rethrowing the exception. | 5431 // before rethrowing the exception. |
5409 finally_block = ParseFinallyBlock(); | 5432 finally_block = ParseFinallyBlock(); |
5410 catch_handler_list->Add(finally_block); | 5433 catch_handler_list->Add(finally_block); |
5411 token_index_ = finally_pos; | 5434 tokens_iterator_.SetCurrentPosition(finally_pos); |
5412 } | 5435 } |
5413 finally_block = ParseFinallyBlock(); | 5436 finally_block = ParseFinallyBlock(); |
5414 } else { | 5437 } else { |
5415 if (!catch_seen) { | 5438 if (!catch_seen) { |
5416 ErrorMsg("'catch' or 'finally' expected"); | 5439 ErrorMsg("'catch' or 'finally' expected"); |
5417 } | 5440 } |
5418 } | 5441 } |
5419 | 5442 |
5420 if (!generic_catch_seen) { | 5443 if (!generic_catch_seen) { |
5421 // No generic catch handler exists so rethrow the exception so that | 5444 // No generic catch handler exists so rethrow the exception so that |
(...skipping 23 matching lines...) Expand all Loading... |
5445 try_catch_node = sequence; | 5468 try_catch_node = sequence; |
5446 } | 5469 } |
5447 return try_catch_node; | 5470 return try_catch_node; |
5448 } | 5471 } |
5449 | 5472 |
5450 | 5473 |
5451 AstNode* Parser::ParseJump(String* label_name) { | 5474 AstNode* Parser::ParseJump(String* label_name) { |
5452 TRACE_PARSER("ParseJump"); | 5475 TRACE_PARSER("ParseJump"); |
5453 ASSERT(CurrentToken() == Token::kBREAK || CurrentToken() == Token::kCONTINUE); | 5476 ASSERT(CurrentToken() == Token::kBREAK || CurrentToken() == Token::kCONTINUE); |
5454 Token::Kind jump_kind = CurrentToken(); | 5477 Token::Kind jump_kind = CurrentToken(); |
5455 const intptr_t jump_pos = token_index_; | 5478 const intptr_t jump_pos = TokenPos(); |
5456 SourceLabel* target = NULL; | 5479 SourceLabel* target = NULL; |
5457 ConsumeToken(); | 5480 ConsumeToken(); |
5458 if (IsIdentifier()) { | 5481 if (IsIdentifier()) { |
5459 // Explicit label after break/continue. | 5482 // Explicit label after break/continue. |
5460 const String& target_name = *CurrentLiteral(); | 5483 const String& target_name = *CurrentLiteral(); |
5461 ConsumeToken(); | 5484 ConsumeToken(); |
5462 // Handle pathological cases first. | 5485 // Handle pathological cases first. |
5463 if (label_name != NULL && target_name.Equals(*label_name)) { | 5486 if (label_name != NULL && target_name.Equals(*label_name)) { |
5464 if (jump_kind == Token::kCONTINUE) { | 5487 if (jump_kind == Token::kCONTINUE) { |
5465 ErrorMsg(jump_pos, "'continue' jump to label '%s' is illegal", | 5488 ErrorMsg(jump_pos, "'continue' jump to label '%s' is illegal", |
5466 target_name.ToCString()); | 5489 target_name.ToCString()); |
5467 } | 5490 } |
5468 // L: break L; is a no-op. | 5491 // L: break L; is a no-op. |
5469 return NULL; | 5492 return NULL; |
5470 } | 5493 } |
5471 target = current_block_->scope->LookupLabel(target_name); | 5494 target = current_block_->scope->LookupLabel(target_name); |
5472 if (target == NULL && jump_kind == Token::kCONTINUE) { | 5495 if (target == NULL && jump_kind == Token::kCONTINUE) { |
5473 // Either a reference to a non-existent label, or a forward reference | 5496 // Either a reference to a non-existent label, or a forward reference |
5474 // to a case label that we haven't seen yet. If we are inside a switch | 5497 // to a case label that we haven't seen yet. If we are inside a switch |
5475 // statement, create a "forward reference" label in the scope of | 5498 // statement, create a "forward reference" label in the scope of |
5476 // the switch statement. | 5499 // the switch statement. |
5477 LocalScope* switch_scope = current_block_->scope->LookupSwitchScope(); | 5500 LocalScope* switch_scope = current_block_->scope->LookupSwitchScope(); |
5478 if (switch_scope != NULL) { | 5501 if (switch_scope != NULL) { |
5479 // We found a switch scope. Enter a forward reference to the label. | 5502 // We found a switch scope. Enter a forward reference to the label. |
5480 target = new SourceLabel( | 5503 target = new SourceLabel( |
5481 token_index_, target_name, SourceLabel::kForward); | 5504 TokenPos(), target_name, SourceLabel::kForward); |
5482 switch_scope->AddLabel(target); | 5505 switch_scope->AddLabel(target); |
5483 } | 5506 } |
5484 } | 5507 } |
5485 if (target == NULL) { | 5508 if (target == NULL) { |
5486 ErrorMsg(jump_pos, "label '%s' not found", target_name.ToCString()); | 5509 ErrorMsg(jump_pos, "label '%s' not found", target_name.ToCString()); |
5487 } | 5510 } |
5488 } else { | 5511 } else { |
5489 target = current_block_->scope->LookupInnermostLabel(jump_kind); | 5512 target = current_block_->scope->LookupInnermostLabel(jump_kind); |
5490 if (target == NULL) { | 5513 if (target == NULL) { |
5491 ErrorMsg(jump_pos, "'%s' is illegal here", Token::Str(jump_kind)); | 5514 ErrorMsg(jump_pos, "'%s' is illegal here", Token::Str(jump_kind)); |
(...skipping 13 matching lines...) Expand all Loading... |
5505 } | 5528 } |
5506 if (target->FunctionLevel() != current_block_->scope->function_level()) { | 5529 if (target->FunctionLevel() != current_block_->scope->function_level()) { |
5507 ErrorMsg(jump_pos, "'%s' target must be in same function context", | 5530 ErrorMsg(jump_pos, "'%s' target must be in same function context", |
5508 Token::Str(jump_kind)); | 5531 Token::Str(jump_kind)); |
5509 } | 5532 } |
5510 return new JumpNode(jump_pos, jump_kind, target); | 5533 return new JumpNode(jump_pos, jump_kind, target); |
5511 } | 5534 } |
5512 | 5535 |
5513 | 5536 |
5514 bool Parser::IsDefinedInLexicalScope(const String& ident) { | 5537 bool Parser::IsDefinedInLexicalScope(const String& ident) { |
5515 if (ResolveIdentInLocalScope(token_index_, ident, NULL)) { | 5538 if (ResolveIdentInLocalScope(TokenPos(), ident, NULL)) { |
5516 return true; | 5539 return true; |
5517 } | 5540 } |
5518 Object& obj = Object::Handle(); | 5541 Object& obj = Object::Handle(); |
5519 obj = library_.LookupObject(ident); | 5542 obj = library_.LookupObject(ident); |
5520 return !obj.IsNull(); | 5543 return !obj.IsNull(); |
5521 } | 5544 } |
5522 | 5545 |
5523 | 5546 |
5524 AstNode* Parser::ParseStatement() { | 5547 AstNode* Parser::ParseStatement() { |
5525 TRACE_PARSER("ParseStatement"); | 5548 TRACE_PARSER("ParseStatement"); |
5526 AstNode* statement = NULL; | 5549 AstNode* statement = NULL; |
5527 intptr_t label_pos = 0; | 5550 intptr_t label_pos = 0; |
5528 String* label_name = NULL; | 5551 String* label_name = NULL; |
5529 if (IsIdentifier()) { | 5552 if (IsIdentifier()) { |
5530 if (LookaheadToken(1) == Token::kCOLON) { | 5553 if (LookaheadToken(1) == Token::kCOLON) { |
5531 // Statement starts with a label. | 5554 // Statement starts with a label. |
5532 label_name = CurrentLiteral(); | 5555 label_name = CurrentLiteral(); |
5533 label_pos = token_index_; | 5556 label_pos = TokenPos(); |
5534 ASSERT(label_pos > 0); | 5557 ASSERT(label_pos > 0); |
5535 ConsumeToken(); // Consume identifier. | 5558 ConsumeToken(); // Consume identifier. |
5536 ConsumeToken(); // Consume colon. | 5559 ConsumeToken(); // Consume colon. |
5537 } | 5560 } |
5538 } | 5561 } |
5539 const intptr_t statement_pos = token_index_; | 5562 const intptr_t statement_pos = TokenPos(); |
5540 | 5563 |
5541 if (CurrentToken() == Token::kWHILE) { | 5564 if (CurrentToken() == Token::kWHILE) { |
5542 statement = ParseWhileStatement(label_name); | 5565 statement = ParseWhileStatement(label_name); |
5543 } else if (CurrentToken() == Token::kFOR) { | 5566 } else if (CurrentToken() == Token::kFOR) { |
5544 statement = ParseForStatement(label_name); | 5567 statement = ParseForStatement(label_name); |
5545 } else if (CurrentToken() == Token::kDO) { | 5568 } else if (CurrentToken() == Token::kDO) { |
5546 statement = ParseDoWhileStatement(label_name); | 5569 statement = ParseDoWhileStatement(label_name); |
5547 } else if (CurrentToken() == Token::kSWITCH) { | 5570 } else if (CurrentToken() == Token::kSWITCH) { |
5548 statement = ParseSwitchStatement(label_name); | 5571 statement = ParseSwitchStatement(label_name); |
5549 } else if (CurrentToken() == Token::kTRY) { | 5572 } else if (CurrentToken() == Token::kTRY) { |
5550 statement = ParseTryStatement(label_name); | 5573 statement = ParseTryStatement(label_name); |
5551 } else if (CurrentToken() == Token::kRETURN) { | 5574 } else if (CurrentToken() == Token::kRETURN) { |
5552 const intptr_t return_pos = token_index_; | 5575 const intptr_t return_pos = TokenPos(); |
5553 ConsumeToken(); | 5576 ConsumeToken(); |
5554 if (CurrentToken() != Token::kSEMICOLON) { | 5577 if (CurrentToken() != Token::kSEMICOLON) { |
5555 if (current_function().IsConstructor() && | 5578 if (current_function().IsConstructor() && |
5556 (current_block_->scope->function_level() == 0)) { | 5579 (current_block_->scope->function_level() == 0)) { |
5557 ErrorMsg(return_pos, "return of a value not allowed in constructors"); | 5580 ErrorMsg(return_pos, "return of a value not allowed in constructors"); |
5558 } | 5581 } |
5559 AstNode* expr = ParseExpr(kAllowConst); | 5582 AstNode* expr = ParseExpr(kAllowConst); |
5560 statement = new ReturnNode(statement_pos, expr); | 5583 statement = new ReturnNode(statement_pos, expr); |
5561 } else { | 5584 } else { |
5562 statement = new ReturnNode(statement_pos); | 5585 statement = new ReturnNode(statement_pos); |
(...skipping 66 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
5629 } else { | 5652 } else { |
5630 statement = ParseExpr(kAllowConst); | 5653 statement = ParseExpr(kAllowConst); |
5631 ExpectSemicolon(); | 5654 ExpectSemicolon(); |
5632 } | 5655 } |
5633 return statement; | 5656 return statement; |
5634 } | 5657 } |
5635 | 5658 |
5636 | 5659 |
5637 RawError* Parser::FormatErrorWithAppend(const Error& prev_error, | 5660 RawError* Parser::FormatErrorWithAppend(const Error& prev_error, |
5638 const Script& script, | 5661 const Script& script, |
5639 intptr_t token_index, | 5662 intptr_t token_pos, |
5640 const char* message_header, | 5663 const char* message_header, |
5641 const char* format, | 5664 const char* format, |
5642 va_list args) { | 5665 va_list args) { |
5643 const intptr_t kMessageBufferSize = 512; | 5666 const intptr_t kMessageBufferSize = 512; |
5644 char message_buffer[kMessageBufferSize]; | 5667 char message_buffer[kMessageBufferSize]; |
5645 FormatMessage(script, token_index, message_header, | 5668 FormatMessage(script, token_pos, message_header, |
5646 message_buffer, kMessageBufferSize, | 5669 message_buffer, kMessageBufferSize, |
5647 format, args); | 5670 format, args); |
5648 const String& msg1 = String::Handle(String::New(prev_error.ToErrorCString())); | 5671 const String& msg1 = String::Handle(String::New(prev_error.ToErrorCString())); |
5649 const String& msg2 = String::Handle(String::New(message_buffer)); | 5672 const String& msg2 = String::Handle(String::New(message_buffer)); |
5650 return LanguageError::New(String::Handle(String::Concat(msg1, msg2))); | 5673 return LanguageError::New(String::Handle(String::Concat(msg1, msg2))); |
5651 } | 5674 } |
5652 | 5675 |
5653 | 5676 |
5654 RawError* Parser::FormatError(const Script& script, | 5677 RawError* Parser::FormatError(const Script& script, |
5655 intptr_t token_index, | 5678 intptr_t token_pos, |
5656 const char* message_header, | 5679 const char* message_header, |
5657 const char* format, | 5680 const char* format, |
5658 va_list args) { | 5681 va_list args) { |
5659 const intptr_t kMessageBufferSize = 512; | 5682 const intptr_t kMessageBufferSize = 512; |
5660 char message_buffer[kMessageBufferSize]; | 5683 char message_buffer[kMessageBufferSize]; |
5661 FormatMessage(script, token_index, message_header, | 5684 FormatMessage(script, token_pos, message_header, |
5662 message_buffer, kMessageBufferSize, | 5685 message_buffer, kMessageBufferSize, |
5663 format, args); | 5686 format, args); |
5664 const String& msg = String::Handle(String::New(message_buffer)); | 5687 const String& msg = String::Handle(String::New(message_buffer)); |
5665 return LanguageError::New(msg); | 5688 return LanguageError::New(msg); |
5666 } | 5689 } |
5667 | 5690 |
5668 | 5691 |
5669 void Parser::FormatMessage(const Script& script, | 5692 void Parser::FormatMessage(const Script& script, |
5670 intptr_t token_index, | 5693 intptr_t token_pos, |
5671 const char* message_header, | 5694 const char* message_header, |
5672 char* message_buffer, | 5695 char* message_buffer, |
5673 intptr_t message_buffer_size, | 5696 intptr_t message_buffer_size, |
5674 const char* format, va_list args) { | 5697 const char* format, va_list args) { |
5675 intptr_t msg_len = 0; | 5698 intptr_t msg_len = 0; |
5676 if (!script.IsNull()) { | 5699 if (!script.IsNull()) { |
5677 const String& script_url = String::CheckedHandle(script.url()); | 5700 const String& script_url = String::CheckedHandle(script.url()); |
5678 if (token_index >= 0) { | 5701 if (token_pos >= 0) { |
5679 intptr_t line, column; | 5702 intptr_t line, column; |
5680 script.GetTokenLocation(token_index, &line, &column); | 5703 script.GetTokenLocation(token_pos, &line, &column); |
5681 msg_len += OS::SNPrint(message_buffer + msg_len, | 5704 msg_len += OS::SNPrint(message_buffer + msg_len, |
5682 message_buffer_size - msg_len, | 5705 message_buffer_size - msg_len, |
5683 "'%s': %s: line %d pos %d: ", | 5706 "'%s': %s: line %d pos %d: ", |
5684 script_url.ToCString(), | 5707 script_url.ToCString(), |
5685 message_header, | 5708 message_header, |
5686 line, | 5709 line, |
5687 column); | 5710 column); |
5688 if (msg_len < message_buffer_size) { | 5711 if (msg_len < message_buffer_size) { |
5689 // Append the formatted error or warning message. | 5712 // Append the formatted error or warning message. |
5690 msg_len += OS::VSNPrint(message_buffer + msg_len, | 5713 msg_len += OS::VSNPrint(message_buffer + msg_len, |
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
5722 // Script is unknown. | 5745 // Script is unknown. |
5723 // Append the formatted error or warning message. | 5746 // Append the formatted error or warning message. |
5724 msg_len += OS::VSNPrint(message_buffer + msg_len, | 5747 msg_len += OS::VSNPrint(message_buffer + msg_len, |
5725 message_buffer_size - msg_len, | 5748 message_buffer_size - msg_len, |
5726 format, | 5749 format, |
5727 args); | 5750 args); |
5728 } | 5751 } |
5729 } | 5752 } |
5730 | 5753 |
5731 | 5754 |
5732 void Parser::ErrorMsg(intptr_t token_index, const char* format, ...) { | 5755 void Parser::ErrorMsg(intptr_t token_pos, const char* format, ...) { |
5733 va_list args; | 5756 va_list args; |
5734 va_start(args, format); | 5757 va_start(args, format); |
5735 const Error& error = Error::Handle( | 5758 const Error& error = Error::Handle( |
5736 FormatError(script_, token_index, "Error", format, args)); | 5759 FormatError(script_, token_pos, "Error", format, args)); |
5737 va_end(args); | 5760 va_end(args); |
5738 Isolate::Current()->long_jump_base()->Jump(1, error); | 5761 Isolate::Current()->long_jump_base()->Jump(1, error); |
5739 UNREACHABLE(); | 5762 UNREACHABLE(); |
5740 } | 5763 } |
5741 | 5764 |
5742 | 5765 |
5743 void Parser::ErrorMsg(const char* format, ...) { | 5766 void Parser::ErrorMsg(const char* format, ...) { |
5744 va_list args; | 5767 va_list args; |
5745 va_start(args, format); | 5768 va_start(args, format); |
5746 const Error& error = Error::Handle( | 5769 const Error& error = Error::Handle( |
5747 FormatError(script_, token_index_, "Error", format, args)); | 5770 FormatError(script_, TokenPos(), "Error", format, args)); |
5748 va_end(args); | 5771 va_end(args); |
5749 Isolate::Current()->long_jump_base()->Jump(1, error); | 5772 Isolate::Current()->long_jump_base()->Jump(1, error); |
5750 UNREACHABLE(); | 5773 UNREACHABLE(); |
5751 } | 5774 } |
5752 | 5775 |
5753 | 5776 |
5754 void Parser::ErrorMsg(const Error& error) { | 5777 void Parser::ErrorMsg(const Error& error) { |
5755 Isolate::Current()->long_jump_base()->Jump(1, error); | 5778 Isolate::Current()->long_jump_base()->Jump(1, error); |
5756 UNREACHABLE(); | 5779 UNREACHABLE(); |
5757 } | 5780 } |
5758 | 5781 |
5759 | 5782 |
5760 void Parser::AppendErrorMsg( | 5783 void Parser::AppendErrorMsg( |
5761 const Error& prev_error, intptr_t token_index, const char* format, ...) { | 5784 const Error& prev_error, intptr_t token_pos, const char* format, ...) { |
5762 va_list args; | 5785 va_list args; |
5763 va_start(args, format); | 5786 va_start(args, format); |
5764 const Error& error = Error::Handle(FormatErrorWithAppend( | 5787 const Error& error = Error::Handle(FormatErrorWithAppend( |
5765 prev_error, script_, token_index, "Error", format, args)); | 5788 prev_error, script_, token_pos, "Error", format, args)); |
5766 va_end(args); | 5789 va_end(args); |
5767 Isolate::Current()->long_jump_base()->Jump(1, error); | 5790 Isolate::Current()->long_jump_base()->Jump(1, error); |
5768 UNREACHABLE(); | 5791 UNREACHABLE(); |
5769 } | 5792 } |
5770 | 5793 |
5771 | 5794 |
5772 void Parser::Warning(intptr_t token_index, const char* format, ...) { | 5795 void Parser::Warning(intptr_t token_pos, const char* format, ...) { |
5773 if (FLAG_silent_warnings) return; | 5796 if (FLAG_silent_warnings) return; |
5774 va_list args; | 5797 va_list args; |
5775 va_start(args, format); | 5798 va_start(args, format); |
5776 const Error& error = Error::Handle( | 5799 const Error& error = Error::Handle( |
5777 FormatError(script_, token_index, "Warning", format, args)); | 5800 FormatError(script_, token_pos, "Warning", format, args)); |
5778 va_end(args); | 5801 va_end(args); |
5779 if (FLAG_warning_as_error) { | 5802 if (FLAG_warning_as_error) { |
5780 Isolate::Current()->long_jump_base()->Jump(1, error); | 5803 Isolate::Current()->long_jump_base()->Jump(1, error); |
5781 UNREACHABLE(); | 5804 UNREACHABLE(); |
5782 } else { | 5805 } else { |
5783 OS::Print("%s", error.ToErrorCString()); | 5806 OS::Print("%s", error.ToErrorCString()); |
5784 } | 5807 } |
5785 } | 5808 } |
5786 | 5809 |
5787 | 5810 |
5788 void Parser::Warning(const char* format, ...) { | 5811 void Parser::Warning(const char* format, ...) { |
5789 if (FLAG_silent_warnings) return; | 5812 if (FLAG_silent_warnings) return; |
5790 va_list args; | 5813 va_list args; |
5791 va_start(args, format); | 5814 va_start(args, format); |
5792 const Error& error = Error::Handle( | 5815 const Error& error = Error::Handle( |
5793 FormatError(script_, token_index_, "Warning", format, args)); | 5816 FormatError(script_, TokenPos(), "Warning", format, args)); |
5794 va_end(args); | 5817 va_end(args); |
5795 if (FLAG_warning_as_error) { | 5818 if (FLAG_warning_as_error) { |
5796 Isolate::Current()->long_jump_base()->Jump(1, error); | 5819 Isolate::Current()->long_jump_base()->Jump(1, error); |
5797 UNREACHABLE(); | 5820 UNREACHABLE(); |
5798 } else { | 5821 } else { |
5799 OS::Print("%s", error.ToErrorCString()); | 5822 OS::Print("%s", error.ToErrorCString()); |
5800 } | 5823 } |
5801 } | 5824 } |
5802 | 5825 |
5803 | 5826 |
5804 void Parser::Unimplemented(const char* msg) { | 5827 void Parser::Unimplemented(const char* msg) { |
5805 ErrorMsg(token_index_, msg); | 5828 ErrorMsg(TokenPos(), msg); |
5806 } | 5829 } |
5807 | 5830 |
5808 | 5831 |
5809 void Parser::ExpectToken(Token::Kind token_expected) { | 5832 void Parser::ExpectToken(Token::Kind token_expected) { |
5810 if (CurrentToken() != token_expected) { | 5833 if (CurrentToken() != token_expected) { |
5811 ErrorMsg("'%s' expected", Token::Str(token_expected)); | 5834 ErrorMsg("'%s' expected", Token::Str(token_expected)); |
5812 } | 5835 } |
5813 ConsumeToken(); | 5836 ConsumeToken(); |
5814 } | 5837 } |
5815 | 5838 |
(...skipping 93 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
5909 TRACE_PARSER("ParseBinaryExpr"); | 5932 TRACE_PARSER("ParseBinaryExpr"); |
5910 ASSERT(min_preced >= 4); | 5933 ASSERT(min_preced >= 4); |
5911 AstNode* left_operand = ParseUnaryExpr(); | 5934 AstNode* left_operand = ParseUnaryExpr(); |
5912 int current_preced = Token::Precedence(CurrentToken()); | 5935 int current_preced = Token::Precedence(CurrentToken()); |
5913 while (current_preced >= min_preced) { | 5936 while (current_preced >= min_preced) { |
5914 while (Token::Precedence(CurrentToken()) == current_preced) { | 5937 while (Token::Precedence(CurrentToken()) == current_preced) { |
5915 Token::Kind op_kind = CurrentToken(); | 5938 Token::Kind op_kind = CurrentToken(); |
5916 if (op_kind == Token::kTIGHTADD) { | 5939 if (op_kind == Token::kTIGHTADD) { |
5917 op_kind = Token::kADD; | 5940 op_kind = Token::kADD; |
5918 } | 5941 } |
5919 const intptr_t op_pos = token_index_; | 5942 const intptr_t op_pos = TokenPos(); |
5920 ConsumeToken(); | 5943 ConsumeToken(); |
5921 AstNode* right_operand = NULL; | 5944 AstNode* right_operand = NULL; |
5922 if (op_kind != Token::kIS) { | 5945 if (op_kind != Token::kIS) { |
5923 right_operand = ParseBinaryExpr(current_preced + 1); | 5946 right_operand = ParseBinaryExpr(current_preced + 1); |
5924 } else { | 5947 } else { |
5925 // For 'is' we expect the right operand to be a type. | 5948 // For 'is' we expect the right operand to be a type. |
5926 if (CurrentToken() == Token::kNOT) { | 5949 if (CurrentToken() == Token::kNOT) { |
5927 ConsumeToken(); | 5950 ConsumeToken(); |
5928 op_kind = Token::kISNOT; | 5951 op_kind = Token::kISNOT; |
5929 } | 5952 } |
5930 const intptr_t type_pos = token_index_; | 5953 const intptr_t type_pos = TokenPos(); |
5931 const AbstractType& type = | 5954 const AbstractType& type = |
5932 AbstractType::ZoneHandle(ParseType(ClassFinalizer::kFinalize)); | 5955 AbstractType::ZoneHandle(ParseType(ClassFinalizer::kFinalize)); |
5933 if (!type.IsInstantiated() && | 5956 if (!type.IsInstantiated() && |
5934 (current_block_->scope->function_level() > 0)) { | 5957 (current_block_->scope->function_level() > 0)) { |
5935 // Make sure that the instantiator is captured. | 5958 // Make sure that the instantiator is captured. |
5936 CaptureReceiver(); | 5959 CaptureReceiver(); |
5937 } | 5960 } |
5938 right_operand = new TypeNode(type_pos, type); | 5961 right_operand = new TypeNode(type_pos, type); |
5939 if (type.IsMalformed()) { | 5962 if (type.IsMalformed()) { |
5940 // Note that a type error is thrown even if the tested value is null. | 5963 // Note that a type error is thrown even if the tested value is null. |
(...skipping 30 matching lines...) Expand all Loading... |
5971 || expr->IsInstanceGetterNode() | 5994 || expr->IsInstanceGetterNode() |
5972 || expr->IsLoadIndexedNode(); | 5995 || expr->IsLoadIndexedNode(); |
5973 } | 5996 } |
5974 | 5997 |
5975 | 5998 |
5976 AstNode* Parser::ParseExprList() { | 5999 AstNode* Parser::ParseExprList() { |
5977 TRACE_PARSER("ParseExprList"); | 6000 TRACE_PARSER("ParseExprList"); |
5978 AstNode* expressions = ParseExpr(kAllowConst); | 6001 AstNode* expressions = ParseExpr(kAllowConst); |
5979 if (CurrentToken() == Token::kCOMMA) { | 6002 if (CurrentToken() == Token::kCOMMA) { |
5980 // Collect comma-separated expressions in a non scope owning sequence node. | 6003 // Collect comma-separated expressions in a non scope owning sequence node. |
5981 SequenceNode* list = new SequenceNode(token_index_, NULL); | 6004 SequenceNode* list = new SequenceNode(TokenPos(), NULL); |
5982 list->Add(expressions); | 6005 list->Add(expressions); |
5983 while (CurrentToken() == Token::kCOMMA) { | 6006 while (CurrentToken() == Token::kCOMMA) { |
5984 ConsumeToken(); | 6007 ConsumeToken(); |
5985 AstNode* expr = ParseExpr(kAllowConst); | 6008 AstNode* expr = ParseExpr(kAllowConst); |
5986 list->Add(expr); | 6009 list->Add(expr); |
5987 } | 6010 } |
5988 expressions = list; | 6011 expressions = list; |
5989 } | 6012 } |
5990 return expressions; | 6013 return expressions; |
5991 } | 6014 } |
5992 | 6015 |
5993 | 6016 |
5994 const LocalVariable& Parser::GetIncrementTempLocal() { | 6017 const LocalVariable& Parser::GetIncrementTempLocal() { |
5995 if (expression_temp_ == NULL) { | 6018 if (expression_temp_ == NULL) { |
5996 expression_temp_ = ParsedFunction::CreateExpressionTempVar( | 6019 expression_temp_ = ParsedFunction::CreateExpressionTempVar( |
5997 current_function().token_index()); | 6020 current_function().token_pos()); |
5998 } | 6021 } |
5999 return *expression_temp_; | 6022 return *expression_temp_; |
6000 } | 6023 } |
6001 | 6024 |
6002 | 6025 |
6003 void Parser::EnsureExpressionTemp() { | 6026 void Parser::EnsureExpressionTemp() { |
6004 // Temporary used later by the flow_graph_builder. | 6027 // Temporary used later by the flow_graph_builder. |
6005 GetIncrementTempLocal(); | 6028 GetIncrementTempLocal(); |
6006 } | 6029 } |
6007 | 6030 |
6008 | 6031 |
6009 LocalVariable* Parser::CreateTempConstVariable(intptr_t token_index, | 6032 LocalVariable* Parser::CreateTempConstVariable(intptr_t token_pos, |
6010 intptr_t token_id, | 6033 intptr_t token_id, |
6011 const char* s) { | 6034 const char* s) { |
6012 char name[64]; | 6035 char name[64]; |
6013 OS::SNPrint(name, 64, ":%s%d", s, token_id); | 6036 OS::SNPrint(name, 64, ":%s%d", s, token_id); |
6014 LocalVariable* temp = | 6037 LocalVariable* temp = |
6015 new LocalVariable(token_index, | 6038 new LocalVariable(token_pos, |
6016 String::ZoneHandle(String::NewSymbol(name)), | 6039 String::ZoneHandle(String::NewSymbol(name)), |
6017 Type::ZoneHandle(Type::DynamicType())); | 6040 Type::ZoneHandle(Type::DynamicType())); |
6018 temp->set_is_final(); | 6041 temp->set_is_final(); |
6019 current_block_->scope->AddVariable(temp); | 6042 current_block_->scope->AddVariable(temp); |
6020 return temp; | 6043 return temp; |
6021 } | 6044 } |
6022 | 6045 |
6023 | 6046 |
6024 // TODO(srdjan): Implement other optimizations. | 6047 // TODO(srdjan): Implement other optimizations. |
6025 AstNode* Parser::OptimizeBinaryOpNode(intptr_t op_pos, | 6048 AstNode* Parser::OptimizeBinaryOpNode(intptr_t op_pos, |
(...skipping 80 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
6106 // side effect creating inputs into locals. The load part reads then from | 6129 // side effect creating inputs into locals. The load part reads then from |
6107 // those locals. If expr may have side effects, it will be split into two new | 6130 // those locals. If expr may have side effects, it will be split into two new |
6108 // left and right nodes. 'expr' becomes the right node, left node is returned as | 6131 // left and right nodes. 'expr' becomes the right node, left node is returned as |
6109 // result. | 6132 // result. |
6110 AstNode* Parser::PrepareCompoundAssignmentNodes(AstNode** expr) { | 6133 AstNode* Parser::PrepareCompoundAssignmentNodes(AstNode** expr) { |
6111 AstNode* node = *expr; | 6134 AstNode* node = *expr; |
6112 if (node->IsLoadIndexedNode()) { | 6135 if (node->IsLoadIndexedNode()) { |
6113 LoadIndexedNode* left_node = node->AsLoadIndexedNode(); | 6136 LoadIndexedNode* left_node = node->AsLoadIndexedNode(); |
6114 LoadIndexedNode* right_node = left_node; | 6137 LoadIndexedNode* right_node = left_node; |
6115 intptr_t node_id = node->id(); | 6138 intptr_t node_id = node->id(); |
6116 intptr_t token_index = node->token_index(); | 6139 intptr_t token_pos = node->token_pos(); |
6117 node = NULL; // Do not use it. | 6140 node = NULL; // Do not use it. |
6118 if (!IsSimpleLocalOrLiteralNode(left_node->array())) { | 6141 if (!IsSimpleLocalOrLiteralNode(left_node->array())) { |
6119 LocalVariable* temp = | 6142 LocalVariable* temp = |
6120 CreateTempConstVariable(token_index, node_id, "lia"); | 6143 CreateTempConstVariable(token_pos, node_id, "lia"); |
6121 StoreLocalNode* save = | 6144 StoreLocalNode* save = |
6122 new StoreLocalNode(token_index, *temp, left_node->array()); | 6145 new StoreLocalNode(token_pos, *temp, left_node->array()); |
6123 left_node = | 6146 left_node = |
6124 new LoadIndexedNode(token_index, save, left_node->index_expr()); | 6147 new LoadIndexedNode(token_pos, save, left_node->index_expr()); |
6125 right_node = new LoadIndexedNode(token_index, | 6148 right_node = new LoadIndexedNode(token_pos, |
6126 new LoadLocalNode(token_index, *temp), | 6149 new LoadLocalNode(token_pos, *temp), |
6127 right_node->index_expr()); | 6150 right_node->index_expr()); |
6128 } | 6151 } |
6129 if (!IsSimpleLocalOrLiteralNode(left_node->index_expr())) { | 6152 if (!IsSimpleLocalOrLiteralNode(left_node->index_expr())) { |
6130 LocalVariable* temp = | 6153 LocalVariable* temp = |
6131 CreateTempConstVariable(token_index, node_id, "lix"); | 6154 CreateTempConstVariable(token_pos, node_id, "lix"); |
6132 StoreLocalNode* save = | 6155 StoreLocalNode* save = |
6133 new StoreLocalNode(token_index, *temp, left_node->index_expr()); | 6156 new StoreLocalNode(token_pos, *temp, left_node->index_expr()); |
6134 left_node = new LoadIndexedNode(token_index, | 6157 left_node = new LoadIndexedNode(token_pos, |
6135 left_node->array(), | 6158 left_node->array(), |
6136 save); | 6159 save); |
6137 right_node = new LoadIndexedNode(token_index, | 6160 right_node = new LoadIndexedNode(token_pos, |
6138 right_node->array(), | 6161 right_node->array(), |
6139 new LoadLocalNode(token_index, *temp)); | 6162 new LoadLocalNode(token_pos, *temp)); |
6140 } | 6163 } |
6141 *expr = right_node; | 6164 *expr = right_node; |
6142 return left_node; | 6165 return left_node; |
6143 } | 6166 } |
6144 if (node->IsInstanceGetterNode()) { | 6167 if (node->IsInstanceGetterNode()) { |
6145 InstanceGetterNode* left_node = node->AsInstanceGetterNode(); | 6168 InstanceGetterNode* left_node = node->AsInstanceGetterNode(); |
6146 InstanceGetterNode* right_node = left_node; | 6169 InstanceGetterNode* right_node = left_node; |
6147 intptr_t node_id = node->id(); | 6170 intptr_t node_id = node->id(); |
6148 intptr_t token_index = node->token_index(); | 6171 intptr_t token_pos = node->token_pos(); |
6149 node = NULL; // Do not use it. | 6172 node = NULL; // Do not use it. |
6150 if (!IsSimpleLocalOrLiteralNode(left_node->receiver())) { | 6173 if (!IsSimpleLocalOrLiteralNode(left_node->receiver())) { |
6151 LocalVariable* temp = | 6174 LocalVariable* temp = |
6152 CreateTempConstVariable(token_index, node_id, "igr"); | 6175 CreateTempConstVariable(token_pos, node_id, "igr"); |
6153 StoreLocalNode* save = | 6176 StoreLocalNode* save = |
6154 new StoreLocalNode(token_index, *temp, left_node->receiver()); | 6177 new StoreLocalNode(token_pos, *temp, left_node->receiver()); |
6155 left_node = new InstanceGetterNode(token_index, | 6178 left_node = new InstanceGetterNode(token_pos, |
6156 save, | 6179 save, |
6157 left_node->field_name()); | 6180 left_node->field_name()); |
6158 right_node = new InstanceGetterNode(token_index, | 6181 right_node = new InstanceGetterNode(token_pos, |
6159 new LoadLocalNode(token_index, *temp), | 6182 new LoadLocalNode(token_pos, *temp), |
6160 right_node->field_name()); | 6183 right_node->field_name()); |
6161 } | 6184 } |
6162 *expr = right_node; | 6185 *expr = right_node; |
6163 return left_node; | 6186 return left_node; |
6164 } | 6187 } |
6165 return *expr; | 6188 return *expr; |
6166 } | 6189 } |
6167 | 6190 |
6168 | 6191 |
6169 // Ensure that the expression temp is allocated for nodes that may need it. | 6192 // Ensure that the expression temp is allocated for nodes that may need it. |
6170 AstNode* Parser::CreateAssignmentNode(AstNode* original, AstNode* rhs) { | 6193 AstNode* Parser::CreateAssignmentNode(AstNode* original, AstNode* rhs) { |
6171 AstNode* result = original->MakeAssignmentNode(rhs); | 6194 AstNode* result = original->MakeAssignmentNode(rhs); |
6172 if ((result != NULL) && | 6195 if ((result != NULL) && |
6173 (result->IsStoreIndexedNode() || result->IsInstanceSetterNode())) { | 6196 (result->IsStoreIndexedNode() || result->IsInstanceSetterNode())) { |
6174 EnsureExpressionTemp(); | 6197 EnsureExpressionTemp(); |
6175 } | 6198 } |
6176 return result; | 6199 return result; |
6177 } | 6200 } |
6178 | 6201 |
6179 | 6202 |
6180 AstNode* Parser::ParseExpr(bool require_compiletime_const) { | 6203 AstNode* Parser::ParseExpr(bool require_compiletime_const) { |
6181 TRACE_PARSER("ParseExpr"); | 6204 TRACE_PARSER("ParseExpr"); |
6182 const intptr_t expr_pos = token_index_; | 6205 const intptr_t expr_pos = TokenPos(); |
6183 AstNode* expr = ParseConditionalExpr(); | 6206 AstNode* expr = ParseConditionalExpr(); |
6184 if (!Token::IsAssignmentOperator(CurrentToken())) { | 6207 if (!Token::IsAssignmentOperator(CurrentToken())) { |
6185 if (require_compiletime_const) { | 6208 if (require_compiletime_const) { |
6186 expr = FoldConstExpr(expr_pos, expr); | 6209 expr = FoldConstExpr(expr_pos, expr); |
6187 } | 6210 } |
6188 return expr; | 6211 return expr; |
6189 } | 6212 } |
6190 // Assignment expressions. | 6213 // Assignment expressions. |
6191 Token::Kind assignment_op = CurrentToken(); | 6214 Token::Kind assignment_op = CurrentToken(); |
6192 const intptr_t assignment_pos = token_index_; | 6215 const intptr_t assignment_pos = TokenPos(); |
6193 ConsumeToken(); | 6216 ConsumeToken(); |
6194 const intptr_t right_expr_pos = token_index_; | 6217 const intptr_t right_expr_pos = TokenPos(); |
6195 if (require_compiletime_const && (assignment_op != Token::kASSIGN)) { | 6218 if (require_compiletime_const && (assignment_op != Token::kASSIGN)) { |
6196 ErrorMsg(right_expr_pos, "expression must be a compile time constant"); | 6219 ErrorMsg(right_expr_pos, "expression must be a compile time constant"); |
6197 } | 6220 } |
6198 AstNode* right_expr = ParseExpr(require_compiletime_const); | 6221 AstNode* right_expr = ParseExpr(require_compiletime_const); |
6199 AstNode* left_expr = expr; | 6222 AstNode* left_expr = expr; |
6200 if (assignment_op != Token::kASSIGN) { | 6223 if (assignment_op != Token::kASSIGN) { |
6201 // Compound assignment: store inputs with side effects into temp. locals. | 6224 // Compound assignment: store inputs with side effects into temp. locals. |
6202 left_expr = PrepareCompoundAssignmentNodes(&expr); | 6225 left_expr = PrepareCompoundAssignmentNodes(&expr); |
6203 } | 6226 } |
6204 right_expr = | 6227 right_expr = |
(...skipping 11 matching lines...) Expand all Loading... |
6216 LiteralNode* Parser::ParseConstExpr() { | 6239 LiteralNode* Parser::ParseConstExpr() { |
6217 TRACE_PARSER("ParseConstExpr"); | 6240 TRACE_PARSER("ParseConstExpr"); |
6218 AstNode* expr = ParseExpr(kRequireConst); | 6241 AstNode* expr = ParseExpr(kRequireConst); |
6219 ASSERT(expr->IsLiteralNode()); | 6242 ASSERT(expr->IsLiteralNode()); |
6220 return expr->AsLiteralNode(); | 6243 return expr->AsLiteralNode(); |
6221 } | 6244 } |
6222 | 6245 |
6223 | 6246 |
6224 AstNode* Parser::ParseConditionalExpr() { | 6247 AstNode* Parser::ParseConditionalExpr() { |
6225 TRACE_PARSER("ParseConditionalExpr"); | 6248 TRACE_PARSER("ParseConditionalExpr"); |
6226 const intptr_t expr_pos = token_index_; | 6249 const intptr_t expr_pos = TokenPos(); |
6227 AstNode* expr = ParseBinaryExpr(Token::Precedence(Token::kOR)); | 6250 AstNode* expr = ParseBinaryExpr(Token::Precedence(Token::kOR)); |
6228 if (CurrentToken() == Token::kCONDITIONAL) { | 6251 if (CurrentToken() == Token::kCONDITIONAL) { |
6229 EnsureExpressionTemp(); | 6252 EnsureExpressionTemp(); |
6230 ConsumeToken(); | 6253 ConsumeToken(); |
6231 AstNode* expr1 = ParseExpr(kAllowConst); | 6254 AstNode* expr1 = ParseExpr(kAllowConst); |
6232 ExpectToken(Token::kCOLON); | 6255 ExpectToken(Token::kCOLON); |
6233 AstNode* expr2 = ParseExpr(kAllowConst); | 6256 AstNode* expr2 = ParseExpr(kAllowConst); |
6234 expr = new ConditionalExprNode(expr_pos, expr, expr1, expr2); | 6257 expr = new ConditionalExprNode(expr_pos, expr, expr1, expr2); |
6235 } | 6258 } |
6236 return expr; | 6259 return expr; |
6237 } | 6260 } |
6238 | 6261 |
6239 | 6262 |
6240 AstNode* Parser::ParseUnaryExpr() { | 6263 AstNode* Parser::ParseUnaryExpr() { |
6241 TRACE_PARSER("ParseUnaryExpr"); | 6264 TRACE_PARSER("ParseUnaryExpr"); |
6242 AstNode* expr = NULL; | 6265 AstNode* expr = NULL; |
6243 const intptr_t op_pos = token_index_; | 6266 const intptr_t op_pos = TokenPos(); |
6244 if (IsPrefixOperator(CurrentToken())) { | 6267 if (IsPrefixOperator(CurrentToken())) { |
6245 Token::Kind unary_op = CurrentToken(); | 6268 Token::Kind unary_op = CurrentToken(); |
6246 ConsumeToken(); | 6269 ConsumeToken(); |
6247 expr = ParseUnaryExpr(); | 6270 expr = ParseUnaryExpr(); |
6248 if (unary_op == Token::kTIGHTADD) { | 6271 if (unary_op == Token::kTIGHTADD) { |
6249 // kTIGHADD is added only in front of a number literal. | 6272 // kTIGHADD is added only in front of a number literal. |
6250 if (!expr->IsLiteralNode()) { | 6273 if (!expr->IsLiteralNode()) { |
6251 ErrorMsg(op_pos, "unexpected operator '+'"); | 6274 ErrorMsg(op_pos, "unexpected operator '+'"); |
6252 } | 6275 } |
6253 // Expression is the literal itself. | 6276 // Expression is the literal itself. |
(...skipping 26 matching lines...) Expand all Loading... |
6280 | 6303 |
6281 | 6304 |
6282 ArgumentListNode* Parser::ParseActualParameters( | 6305 ArgumentListNode* Parser::ParseActualParameters( |
6283 ArgumentListNode* implicit_arguments, | 6306 ArgumentListNode* implicit_arguments, |
6284 bool require_const) { | 6307 bool require_const) { |
6285 TRACE_PARSER("ParseActualParameters"); | 6308 TRACE_PARSER("ParseActualParameters"); |
6286 ASSERT(CurrentToken() == Token::kLPAREN); | 6309 ASSERT(CurrentToken() == Token::kLPAREN); |
6287 const bool saved_mode = SetAllowFunctionLiterals(true); | 6310 const bool saved_mode = SetAllowFunctionLiterals(true); |
6288 ArgumentListNode* arguments; | 6311 ArgumentListNode* arguments; |
6289 if (implicit_arguments == NULL) { | 6312 if (implicit_arguments == NULL) { |
6290 arguments = new ArgumentListNode(token_index_); | 6313 arguments = new ArgumentListNode(TokenPos()); |
6291 } else { | 6314 } else { |
6292 arguments = implicit_arguments; | 6315 arguments = implicit_arguments; |
6293 } | 6316 } |
6294 const GrowableObjectArray& names = | 6317 const GrowableObjectArray& names = |
6295 GrowableObjectArray::Handle(GrowableObjectArray::New()); | 6318 GrowableObjectArray::Handle(GrowableObjectArray::New()); |
6296 bool named_argument_seen = false; | 6319 bool named_argument_seen = false; |
6297 if (LookaheadToken(1) != Token::kRPAREN) { | 6320 if (LookaheadToken(1) != Token::kRPAREN) { |
6298 String& arg_name = String::Handle(); | 6321 String& arg_name = String::Handle(); |
6299 do { | 6322 do { |
6300 ASSERT((CurrentToken() == Token::kLPAREN) || | 6323 ASSERT((CurrentToken() == Token::kLPAREN) || |
(...skipping 28 matching lines...) Expand all Loading... |
6329 arguments->set_names(Array::Handle(Array::MakeArray(names))); | 6352 arguments->set_names(Array::Handle(Array::MakeArray(names))); |
6330 } | 6353 } |
6331 return arguments; | 6354 return arguments; |
6332 } | 6355 } |
6333 | 6356 |
6334 | 6357 |
6335 AstNode* Parser::ParseStaticCall(const Class& cls, | 6358 AstNode* Parser::ParseStaticCall(const Class& cls, |
6336 const String& func_name, | 6359 const String& func_name, |
6337 intptr_t ident_pos) { | 6360 intptr_t ident_pos) { |
6338 TRACE_PARSER("ParseStaticCall"); | 6361 TRACE_PARSER("ParseStaticCall"); |
6339 const intptr_t call_pos = token_index_; | 6362 const intptr_t call_pos = TokenPos(); |
6340 ASSERT(CurrentToken() == Token::kLPAREN); | 6363 ASSERT(CurrentToken() == Token::kLPAREN); |
6341 ArgumentListNode* arguments = ParseActualParameters(NULL, kAllowConst); | 6364 ArgumentListNode* arguments = ParseActualParameters(NULL, kAllowConst); |
6342 const int num_arguments = arguments->length(); | 6365 const int num_arguments = arguments->length(); |
6343 const Function& func = Function::ZoneHandle( | 6366 const Function& func = Function::ZoneHandle( |
6344 Resolver::ResolveStatic(cls, | 6367 Resolver::ResolveStatic(cls, |
6345 func_name, | 6368 func_name, |
6346 num_arguments, | 6369 num_arguments, |
6347 arguments->names(), | 6370 arguments->names(), |
6348 Resolver::kIsQualified)); | 6371 Resolver::kIsQualified)); |
6349 if (func.IsNull()) { | 6372 if (func.IsNull()) { |
(...skipping 29 matching lines...) Expand all Loading... |
6379 // Could not resolve static method: throw an exception if the arguments | 6402 // Could not resolve static method: throw an exception if the arguments |
6380 // do not match or compile time error otherwise. | 6403 // do not match or compile time error otherwise. |
6381 const Function& test_func = Function::Handle( | 6404 const Function& test_func = Function::Handle( |
6382 Resolver::ResolveStaticByName(cls, func_name, Resolver::kIsQualified)); | 6405 Resolver::ResolveStaticByName(cls, func_name, Resolver::kIsQualified)); |
6383 if (test_func.IsNull()) { | 6406 if (test_func.IsNull()) { |
6384 ErrorMsg(ident_pos, "unresolved static method '%s'", | 6407 ErrorMsg(ident_pos, "unresolved static method '%s'", |
6385 func_name.ToCString()); | 6408 func_name.ToCString()); |
6386 } else { | 6409 } else { |
6387 ArgumentListNode* arguments = new ArgumentListNode(ident_pos); | 6410 ArgumentListNode* arguments = new ArgumentListNode(ident_pos); |
6388 arguments->Add(new LiteralNode( | 6411 arguments->Add(new LiteralNode( |
6389 token_index_, Integer::ZoneHandle(Integer::New(ident_pos)))); | 6412 TokenPos(), Integer::ZoneHandle(Integer::New(ident_pos)))); |
6390 return MakeStaticCall(kStaticResolutionExceptionName, | 6413 return MakeStaticCall(kStaticResolutionExceptionName, |
6391 kThrowNewName, | 6414 kThrowNewName, |
6392 arguments); | 6415 arguments); |
6393 } | 6416 } |
6394 } | 6417 } |
6395 CheckFunctionIsCallable(call_pos, func); | 6418 CheckFunctionIsCallable(call_pos, func); |
6396 return new StaticCallNode(call_pos, func, arguments); | 6419 return new StaticCallNode(call_pos, func, arguments); |
6397 } | 6420 } |
6398 | 6421 |
6399 | 6422 |
6400 AstNode* Parser::ParseInstanceCall(AstNode* receiver, const String& func_name) { | 6423 AstNode* Parser::ParseInstanceCall(AstNode* receiver, const String& func_name) { |
6401 TRACE_PARSER("ParseInstanceCall"); | 6424 TRACE_PARSER("ParseInstanceCall"); |
6402 const intptr_t call_pos = token_index_; | 6425 const intptr_t call_pos = TokenPos(); |
6403 if (CurrentToken() != Token::kLPAREN) { | 6426 if (CurrentToken() != Token::kLPAREN) { |
6404 ErrorMsg(call_pos, "left parenthesis expected"); | 6427 ErrorMsg(call_pos, "left parenthesis expected"); |
6405 } | 6428 } |
6406 ArgumentListNode* arguments = ParseActualParameters(NULL, kAllowConst); | 6429 ArgumentListNode* arguments = ParseActualParameters(NULL, kAllowConst); |
6407 return new InstanceCallNode(call_pos, receiver, func_name, arguments); | 6430 return new InstanceCallNode(call_pos, receiver, func_name, arguments); |
6408 } | 6431 } |
6409 | 6432 |
6410 | 6433 |
6411 AstNode* Parser::ParseClosureCall(AstNode* closure) { | 6434 AstNode* Parser::ParseClosureCall(AstNode* closure) { |
6412 TRACE_PARSER("ParseClosureCall"); | 6435 TRACE_PARSER("ParseClosureCall"); |
6413 const intptr_t call_pos = token_index_; | 6436 const intptr_t call_pos = TokenPos(); |
6414 ASSERT(CurrentToken() == Token::kLPAREN); | 6437 ASSERT(CurrentToken() == Token::kLPAREN); |
6415 EnsureExpressionTemp(); | 6438 EnsureExpressionTemp(); |
6416 ArgumentListNode* arguments = ParseActualParameters(NULL, kAllowConst); | 6439 ArgumentListNode* arguments = ParseActualParameters(NULL, kAllowConst); |
6417 return new ClosureCallNode(call_pos, closure, arguments); | 6440 return new ClosureCallNode(call_pos, closure, arguments); |
6418 } | 6441 } |
6419 | 6442 |
6420 | 6443 |
6421 AstNode* Parser::ParseInstanceFieldAccess(AstNode* receiver, | 6444 AstNode* Parser::ParseInstanceFieldAccess(AstNode* receiver, |
6422 const String& field_name) { | 6445 const String& field_name) { |
6423 TRACE_PARSER("ParseInstanceFieldAccess"); | 6446 TRACE_PARSER("ParseInstanceFieldAccess"); |
6424 AstNode* access = NULL; | 6447 AstNode* access = NULL; |
6425 const intptr_t call_pos = token_index_; | 6448 const intptr_t call_pos = TokenPos(); |
6426 if (Token::IsAssignmentOperator(CurrentToken())) { | 6449 if (Token::IsAssignmentOperator(CurrentToken())) { |
6427 Token::Kind assignment_op = CurrentToken(); | 6450 Token::Kind assignment_op = CurrentToken(); |
6428 ConsumeToken(); | 6451 ConsumeToken(); |
6429 AstNode* value = ParseExpr(kAllowConst); | 6452 AstNode* value = ParseExpr(kAllowConst); |
6430 AstNode* load_access = | 6453 AstNode* load_access = |
6431 new InstanceGetterNode(call_pos, receiver, field_name); | 6454 new InstanceGetterNode(call_pos, receiver, field_name); |
6432 AstNode* left_load_access = load_access; | 6455 AstNode* left_load_access = load_access; |
6433 if (assignment_op != Token::kASSIGN) { | 6456 if (assignment_op != Token::kASSIGN) { |
6434 // Compound assignment: store inputs with side effects into temp. locals. | 6457 // Compound assignment: store inputs with side effects into temp. locals. |
6435 left_load_access = PrepareCompoundAssignmentNodes(&load_access); | 6458 left_load_access = PrepareCompoundAssignmentNodes(&load_access); |
(...skipping 26 matching lines...) Expand all Loading... |
6462 // Access the field directly. | 6485 // Access the field directly. |
6463 return new LoadStaticFieldNode(ident_pos, Field::ZoneHandle(field.raw())); | 6486 return new LoadStaticFieldNode(ident_pos, Field::ZoneHandle(field.raw())); |
6464 } | 6487 } |
6465 | 6488 |
6466 | 6489 |
6467 AstNode* Parser::ParseStaticFieldAccess(const Class& cls, | 6490 AstNode* Parser::ParseStaticFieldAccess(const Class& cls, |
6468 const String& field_name, | 6491 const String& field_name, |
6469 intptr_t ident_pos) { | 6492 intptr_t ident_pos) { |
6470 TRACE_PARSER("ParseStaticFieldAccess"); | 6493 TRACE_PARSER("ParseStaticFieldAccess"); |
6471 AstNode* access = NULL; | 6494 AstNode* access = NULL; |
6472 const intptr_t call_pos = token_index_; | 6495 const intptr_t call_pos = TokenPos(); |
6473 const Field& field = Field::ZoneHandle(cls.LookupStaticField(field_name)); | 6496 const Field& field = Field::ZoneHandle(cls.LookupStaticField(field_name)); |
6474 Function& func = Function::ZoneHandle(); | 6497 Function& func = Function::ZoneHandle(); |
6475 if (Token::IsAssignmentOperator(CurrentToken())) { | 6498 if (Token::IsAssignmentOperator(CurrentToken())) { |
6476 Token::Kind assignment_op = CurrentToken(); | 6499 Token::Kind assignment_op = CurrentToken(); |
6477 if (field.IsNull()) { | 6500 if (field.IsNull()) { |
6478 // No field, check if we have an explicit setter function. | 6501 // No field, check if we have an explicit setter function. |
6479 const String& setter_name = | 6502 const String& setter_name = |
6480 String::ZoneHandle(Field::SetterName(field_name)); | 6503 String::ZoneHandle(Field::SetterName(field_name)); |
6481 const int kNumArguments = 1; // value. | 6504 const int kNumArguments = 1; // value. |
6482 const Array& kNoArgumentNames = Array::Handle(); | 6505 const Array& kNoArgumentNames = Array::Handle(); |
(...skipping 25 matching lines...) Expand all Loading... |
6508 } else { | 6531 } else { |
6509 // Field exists. | 6532 // Field exists. |
6510 if (field.is_final()) { | 6533 if (field.is_final()) { |
6511 // Field has been marked as final, report an error as the field | 6534 // Field has been marked as final, report an error as the field |
6512 // is not settable. | 6535 // is not settable. |
6513 ErrorMsg(ident_pos, | 6536 ErrorMsg(ident_pos, |
6514 "field '%s' is const static, cannot assign to it", | 6537 "field '%s' is const static, cannot assign to it", |
6515 field_name.ToCString()); | 6538 field_name.ToCString()); |
6516 return access; | 6539 return access; |
6517 } | 6540 } |
6518 load_access = GenerateStaticFieldLookup(field, token_index_); | 6541 load_access = GenerateStaticFieldLookup(field, TokenPos()); |
6519 } | 6542 } |
6520 value = ExpandAssignableOp(call_pos, assignment_op, load_access, value); | 6543 value = ExpandAssignableOp(call_pos, assignment_op, load_access, value); |
6521 access = CreateAssignmentNode(load_access, value); | 6544 access = CreateAssignmentNode(load_access, value); |
6522 } else { // Not Token::IsAssignmentOperator(CurrentToken()). | 6545 } else { // Not Token::IsAssignmentOperator(CurrentToken()). |
6523 if (field.IsNull()) { | 6546 if (field.IsNull()) { |
6524 // No field, check if we have an explicit getter function. | 6547 // No field, check if we have an explicit getter function. |
6525 const String& getter_name = | 6548 const String& getter_name = |
6526 String::ZoneHandle(Field::GetterName(field_name)); | 6549 String::ZoneHandle(Field::GetterName(field_name)); |
6527 const int kNumArguments = 0; // no arguments. | 6550 const int kNumArguments = 0; // no arguments. |
6528 const Array& kNoArgumentNames = Array::Handle(); | 6551 const Array& kNoArgumentNames = Array::Handle(); |
(...skipping 13 matching lines...) Expand all Loading... |
6542 return access; | 6565 return access; |
6543 } | 6566 } |
6544 access = CreateImplicitClosureNode(func, call_pos, NULL); | 6567 access = CreateImplicitClosureNode(func, call_pos, NULL); |
6545 } else { | 6568 } else { |
6546 ASSERT(func.kind() != RawFunction::kConstImplicitGetter); | 6569 ASSERT(func.kind() != RawFunction::kConstImplicitGetter); |
6547 access = new StaticGetterNode(call_pos, | 6570 access = new StaticGetterNode(call_pos, |
6548 Class::ZoneHandle(cls.raw()), | 6571 Class::ZoneHandle(cls.raw()), |
6549 field_name); | 6572 field_name); |
6550 } | 6573 } |
6551 } else { | 6574 } else { |
6552 return GenerateStaticFieldLookup(field, token_index_); | 6575 return GenerateStaticFieldLookup(field, TokenPos()); |
6553 } | 6576 } |
6554 } | 6577 } |
6555 return access; | 6578 return access; |
6556 } | 6579 } |
6557 | 6580 |
6558 | 6581 |
6559 AstNode* Parser::LoadFieldIfUnresolved(AstNode* node) { | 6582 AstNode* Parser::LoadFieldIfUnresolved(AstNode* node) { |
6560 if (!node->IsPrimaryNode()) { | 6583 if (!node->IsPrimaryNode()) { |
6561 return node; | 6584 return node; |
6562 } | 6585 } |
6563 PrimaryNode* primary = node->AsPrimaryNode(); | 6586 PrimaryNode* primary = node->AsPrimaryNode(); |
6564 if (primary->primary().IsString()) { | 6587 if (primary->primary().IsString()) { |
6565 // In a static method, an unresolved identifier is an error. | 6588 // In a static method, an unresolved identifier is an error. |
6566 // In an instance method, we convert this into a getter call | 6589 // In an instance method, we convert this into a getter call |
6567 // for a field (which may be defined in a subclass.) | 6590 // for a field (which may be defined in a subclass.) |
6568 String& name = String::CheckedZoneHandle(primary->primary().raw()); | 6591 String& name = String::CheckedZoneHandle(primary->primary().raw()); |
6569 if (current_function().is_static() || | 6592 if (current_function().is_static() || |
6570 current_function().IsInFactoryScope()) { | 6593 current_function().IsInFactoryScope()) { |
6571 ErrorMsg(primary->token_index(), | 6594 ErrorMsg(primary->token_pos(), |
6572 "identifier '%s' is not declared in this scope", | 6595 "identifier '%s' is not declared in this scope", |
6573 name.ToCString()); | 6596 name.ToCString()); |
6574 } else { | 6597 } else { |
6575 AstNode* receiver = LoadReceiver(primary->token_index()); | 6598 AstNode* receiver = LoadReceiver(primary->token_pos()); |
6576 return CallGetter(node->token_index(), receiver, name); | 6599 return CallGetter(node->token_pos(), receiver, name); |
6577 } | 6600 } |
6578 } | 6601 } |
6579 return primary; | 6602 return primary; |
6580 } | 6603 } |
6581 | 6604 |
6582 | 6605 |
6583 AstNode* Parser::LoadClosure(PrimaryNode* primary) { | 6606 AstNode* Parser::LoadClosure(PrimaryNode* primary) { |
6584 ASSERT(primary->primary().IsFunction()); | 6607 ASSERT(primary->primary().IsFunction()); |
6585 AstNode* closure = NULL; | 6608 AstNode* closure = NULL; |
6586 const Function& func = | 6609 const Function& func = |
6587 Function::CheckedZoneHandle(primary->primary().raw()); | 6610 Function::CheckedZoneHandle(primary->primary().raw()); |
6588 const String& funcname = String::ZoneHandle(func.name()); | 6611 const String& funcname = String::ZoneHandle(func.name()); |
6589 if (func.is_static()) { | 6612 if (func.is_static()) { |
6590 // Static function access. | 6613 // Static function access. |
6591 closure = CreateImplicitClosureNode(func, primary->token_index(), NULL); | 6614 closure = CreateImplicitClosureNode(func, primary->token_pos(), NULL); |
6592 } else { | 6615 } else { |
6593 // Instance function access. | 6616 // Instance function access. |
6594 if (current_function().is_static() || | 6617 if (current_function().is_static() || |
6595 current_function().IsInFactoryScope()) { | 6618 current_function().IsInFactoryScope()) { |
6596 ErrorMsg(primary->token_index(), | 6619 ErrorMsg(primary->token_pos(), |
6597 "cannot access instance method '%s' from static method", | 6620 "cannot access instance method '%s' from static method", |
6598 funcname.ToCString()); | 6621 funcname.ToCString()); |
6599 } | 6622 } |
6600 AstNode* receiver = LoadReceiver(primary->token_index()); | 6623 AstNode* receiver = LoadReceiver(primary->token_pos()); |
6601 closure = CallGetter(primary->token_index(), receiver, funcname); | 6624 closure = CallGetter(primary->token_pos(), receiver, funcname); |
6602 } | 6625 } |
6603 return closure; | 6626 return closure; |
6604 } | 6627 } |
6605 | 6628 |
6606 | 6629 |
6607 AstNode* Parser::ParsePostfixExpr() { | 6630 AstNode* Parser::ParsePostfixExpr() { |
6608 TRACE_PARSER("ParsePostfixExpr"); | 6631 TRACE_PARSER("ParsePostfixExpr"); |
6609 const intptr_t postfix_expr_pos = token_index_; | 6632 const intptr_t postfix_expr_pos = TokenPos(); |
6610 AstNode* postfix_expr = ParsePrimary(); | 6633 AstNode* postfix_expr = ParsePrimary(); |
6611 while (true) { | 6634 while (true) { |
6612 AstNode* selector = NULL; | 6635 AstNode* selector = NULL; |
6613 AstNode* left = postfix_expr; | 6636 AstNode* left = postfix_expr; |
6614 if (CurrentToken() == Token::kPERIOD) { | 6637 if (CurrentToken() == Token::kPERIOD) { |
6615 ConsumeToken(); | 6638 ConsumeToken(); |
6616 if (left->IsPrimaryNode()) { | 6639 if (left->IsPrimaryNode()) { |
6617 if (left->AsPrimaryNode()->primary().IsFunction()) { | 6640 if (left->AsPrimaryNode()->primary().IsFunction()) { |
6618 left = LoadClosure(left->AsPrimaryNode()); | 6641 left = LoadClosure(left->AsPrimaryNode()); |
6619 } else { | 6642 } else { |
6620 left = LoadFieldIfUnresolved(left); | 6643 left = LoadFieldIfUnresolved(left); |
6621 } | 6644 } |
6622 } | 6645 } |
6623 const intptr_t ident_pos = token_index_; | 6646 const intptr_t ident_pos = TokenPos(); |
6624 String* ident = ExpectIdentifier("identifier expected"); | 6647 String* ident = ExpectIdentifier("identifier expected"); |
6625 if (CurrentToken() == Token::kLPAREN) { | 6648 if (CurrentToken() == Token::kLPAREN) { |
6626 // Identifier followed by a opening paren: method call. | 6649 // Identifier followed by a opening paren: method call. |
6627 if (left->IsPrimaryNode() | 6650 if (left->IsPrimaryNode() |
6628 && left->AsPrimaryNode()->primary().IsClass()) { | 6651 && left->AsPrimaryNode()->primary().IsClass()) { |
6629 // Static method call prefixed with class name. | 6652 // Static method call prefixed with class name. |
6630 Class& cls = Class::CheckedHandle( | 6653 Class& cls = Class::CheckedHandle( |
6631 left->AsPrimaryNode()->primary().raw()); | 6654 left->AsPrimaryNode()->primary().raw()); |
6632 selector = ParseStaticCall(cls, *ident, ident_pos); | 6655 selector = ParseStaticCall(cls, *ident, ident_pos); |
6633 } else { | 6656 } else { |
(...skipping 12 matching lines...) Expand all Loading... |
6646 } | 6669 } |
6647 if (cls.IsNull()) { | 6670 if (cls.IsNull()) { |
6648 // Instance field access. | 6671 // Instance field access. |
6649 selector = ParseInstanceFieldAccess(left, *ident); | 6672 selector = ParseInstanceFieldAccess(left, *ident); |
6650 } else { | 6673 } else { |
6651 // Static field access. | 6674 // Static field access. |
6652 selector = ParseStaticFieldAccess(cls, *ident, ident_pos); | 6675 selector = ParseStaticFieldAccess(cls, *ident, ident_pos); |
6653 } | 6676 } |
6654 } | 6677 } |
6655 } else if (CurrentToken() == Token::kLBRACK) { | 6678 } else if (CurrentToken() == Token::kLBRACK) { |
6656 const intptr_t bracket_pos = token_index_; | 6679 const intptr_t bracket_pos = TokenPos(); |
6657 ConsumeToken(); | 6680 ConsumeToken(); |
6658 left = LoadFieldIfUnresolved(left); | 6681 left = LoadFieldIfUnresolved(left); |
6659 const bool saved_mode = SetAllowFunctionLiterals(true); | 6682 const bool saved_mode = SetAllowFunctionLiterals(true); |
6660 AstNode* index = ParseExpr(kAllowConst); | 6683 AstNode* index = ParseExpr(kAllowConst); |
6661 SetAllowFunctionLiterals(saved_mode); | 6684 SetAllowFunctionLiterals(saved_mode); |
6662 ExpectToken(Token::kRBRACK); | 6685 ExpectToken(Token::kRBRACK); |
6663 AstNode* array = left; | 6686 AstNode* array = left; |
6664 if (left->IsPrimaryNode()) { | 6687 if (left->IsPrimaryNode()) { |
6665 PrimaryNode* primary = left->AsPrimaryNode(); | 6688 PrimaryNode* primary = left->AsPrimaryNode(); |
6666 if (primary->primary().IsFunction()) { | 6689 if (primary->primary().IsFunction()) { |
6667 array = LoadClosure(primary); | 6690 array = LoadClosure(primary); |
6668 } else if (primary->primary().IsClass()) { | 6691 } else if (primary->primary().IsClass()) { |
6669 ErrorMsg(bracket_pos, "cannot apply index operator to class"); | 6692 ErrorMsg(bracket_pos, "cannot apply index operator to class"); |
6670 } else { | 6693 } else { |
6671 UNREACHABLE(); // Internal parser error. | 6694 UNREACHABLE(); // Internal parser error. |
6672 } | 6695 } |
6673 } | 6696 } |
6674 selector = new LoadIndexedNode(bracket_pos, array, index); | 6697 selector = new LoadIndexedNode(bracket_pos, array, index); |
6675 } else if (CurrentToken() == Token::kLPAREN) { | 6698 } else if (CurrentToken() == Token::kLPAREN) { |
6676 if (left->IsPrimaryNode()) { | 6699 if (left->IsPrimaryNode()) { |
6677 PrimaryNode* primary = left->AsPrimaryNode(); | 6700 PrimaryNode* primary = left->AsPrimaryNode(); |
6678 const intptr_t primary_pos = primary->token_index(); | 6701 const intptr_t primary_pos = primary->token_pos(); |
6679 if (primary->primary().IsFunction()) { | 6702 if (primary->primary().IsFunction()) { |
6680 Function& func = Function::CheckedHandle(primary->primary().raw()); | 6703 Function& func = Function::CheckedHandle(primary->primary().raw()); |
6681 String& func_name = String::ZoneHandle(func.name()); | 6704 String& func_name = String::ZoneHandle(func.name()); |
6682 if (func.is_static()) { | 6705 if (func.is_static()) { |
6683 // Parse static function call. | 6706 // Parse static function call. |
6684 Class& cls = Class::Handle(func.owner()); | 6707 Class& cls = Class::Handle(func.owner()); |
6685 selector = ParseStaticCall(cls, func_name, primary_pos); | 6708 selector = ParseStaticCall(cls, func_name, primary_pos); |
6686 } else { | 6709 } else { |
6687 // Dynamic function call on implicit "this" parameter. | 6710 // Dynamic function call on implicit "this" parameter. |
6688 if (current_function().is_static()) { | 6711 if (current_function().is_static()) { |
6689 ErrorMsg(primary_pos, | 6712 ErrorMsg(primary_pos, |
6690 "cannot access instance method '%s' " | 6713 "cannot access instance method '%s' " |
6691 "from static function", | 6714 "from static function", |
6692 func_name.ToCString()); | 6715 func_name.ToCString()); |
6693 } | 6716 } |
6694 selector = ParseInstanceCall(LoadReceiver(primary_pos), func_name); | 6717 selector = ParseInstanceCall(LoadReceiver(primary_pos), func_name); |
6695 } | 6718 } |
6696 } else if (primary->primary().IsString()) { | 6719 } else if (primary->primary().IsString()) { |
6697 // Primary is an unresolved name. | 6720 // Primary is an unresolved name. |
6698 String& name = String::CheckedZoneHandle(primary->primary().raw()); | 6721 String& name = String::CheckedZoneHandle(primary->primary().raw()); |
6699 if (current_function().is_static()) { | 6722 if (current_function().is_static()) { |
6700 ErrorMsg(primary->token_index(), | 6723 ErrorMsg(primary->token_pos(), |
6701 "identifier '%s' is not declared in this scope", | 6724 "identifier '%s' is not declared in this scope", |
6702 name.ToCString()); | 6725 name.ToCString()); |
6703 } else { | 6726 } else { |
6704 // Treat as call to unresolved (instance) method. | 6727 // Treat as call to unresolved (instance) method. |
6705 AstNode* receiver = LoadReceiver(primary->token_index()); | 6728 AstNode* receiver = LoadReceiver(primary->token_pos()); |
6706 selector = ParseInstanceCall(receiver, name); | 6729 selector = ParseInstanceCall(receiver, name); |
6707 } | 6730 } |
6708 } else if (primary->primary().IsClass()) { | 6731 } else if (primary->primary().IsClass()) { |
6709 ErrorMsg(left->token_index(), | 6732 ErrorMsg(left->token_pos(), |
6710 "must use 'new' or 'const' to construct new instance"); | 6733 "must use 'new' or 'const' to construct new instance"); |
6711 } else { | 6734 } else { |
6712 UNREACHABLE(); // Internal parser error. | 6735 UNREACHABLE(); // Internal parser error. |
6713 } | 6736 } |
6714 } else { | 6737 } else { |
6715 // Left is not a primary node; this must be a closure call. | 6738 // Left is not a primary node; this must be a closure call. |
6716 AstNode* closure = left; | 6739 AstNode* closure = left; |
6717 selector = ParseClosureCall(closure); | 6740 selector = ParseClosureCall(closure); |
6718 } | 6741 } |
6719 } else { | 6742 } else { |
6720 // No (more) selector to parse. | 6743 // No (more) selector to parse. |
6721 left = LoadFieldIfUnresolved(left); | 6744 left = LoadFieldIfUnresolved(left); |
6722 if (left->IsPrimaryNode()) { | 6745 if (left->IsPrimaryNode()) { |
6723 PrimaryNode* primary = left->AsPrimaryNode(); | 6746 PrimaryNode* primary = left->AsPrimaryNode(); |
6724 if (primary->primary().IsFunction()) { | 6747 if (primary->primary().IsFunction()) { |
6725 // Treat as implicit closure. | 6748 // Treat as implicit closure. |
6726 left = LoadClosure(primary); | 6749 left = LoadClosure(primary); |
6727 } else if (left->AsPrimaryNode()->primary().IsClass()) { | 6750 } else if (left->AsPrimaryNode()->primary().IsClass()) { |
6728 Class& cls = Class::CheckedHandle( | 6751 Class& cls = Class::CheckedHandle( |
6729 left->AsPrimaryNode()->primary().raw()); | 6752 left->AsPrimaryNode()->primary().raw()); |
6730 String& cls_name = String::Handle(cls.Name()); | 6753 String& cls_name = String::Handle(cls.Name()); |
6731 ErrorMsg(left->token_index(), | 6754 ErrorMsg(left->token_pos(), |
6732 "illegal use of class name '%s'", | 6755 "illegal use of class name '%s'", |
6733 cls_name.ToCString()); | 6756 cls_name.ToCString()); |
6734 } else { | 6757 } else { |
6735 UNREACHABLE(); // Internal parser error. | 6758 UNREACHABLE(); // Internal parser error. |
6736 } | 6759 } |
6737 } | 6760 } |
6738 postfix_expr = left; | 6761 postfix_expr = left; |
6739 // Done parsing selectors. | 6762 // Done parsing selectors. |
6740 break; | 6763 break; |
6741 } | 6764 } |
(...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
6790 const UnresolvedClass& unresolved_class = | 6813 const UnresolvedClass& unresolved_class = |
6791 UnresolvedClass::Handle(type->unresolved_class()); | 6814 UnresolvedClass::Handle(type->unresolved_class()); |
6792 const String& unresolved_class_name = | 6815 const String& unresolved_class_name = |
6793 String::Handle(unresolved_class.ident()); | 6816 String::Handle(unresolved_class.ident()); |
6794 Class& resolved_type_class = Class::Handle(); | 6817 Class& resolved_type_class = Class::Handle(); |
6795 if (unresolved_class.library_prefix() == LibraryPrefix::null()) { | 6818 if (unresolved_class.library_prefix() == LibraryPrefix::null()) { |
6796 if (!scope_class.IsNull()) { | 6819 if (!scope_class.IsNull()) { |
6797 // First check if the type is a type parameter of the given scope class. | 6820 // First check if the type is a type parameter of the given scope class. |
6798 const TypeParameter& type_parameter = TypeParameter::Handle( | 6821 const TypeParameter& type_parameter = TypeParameter::Handle( |
6799 scope_class.LookupTypeParameter(unresolved_class_name, | 6822 scope_class.LookupTypeParameter(unresolved_class_name, |
6800 type->token_index())); | 6823 type->token_pos())); |
6801 if (!type_parameter.IsNull()) { | 6824 if (!type_parameter.IsNull()) { |
6802 // A type parameter cannot be parameterized, so report an error if | 6825 // A type parameter cannot be parameterized, so report an error if |
6803 // type arguments have previously been parsed. | 6826 // type arguments have previously been parsed. |
6804 if (!AbstractTypeArguments::Handle(type->arguments()).IsNull()) { | 6827 if (!AbstractTypeArguments::Handle(type->arguments()).IsNull()) { |
6805 ErrorMsg(type_parameter.token_index(), | 6828 ErrorMsg(type_parameter.token_pos(), |
6806 "type parameter '%s' cannot be parameterized", | 6829 "type parameter '%s' cannot be parameterized", |
6807 String::Handle(type_parameter.Name()).ToCString()); | 6830 String::Handle(type_parameter.Name()).ToCString()); |
6808 } | 6831 } |
6809 *type = type_parameter.raw(); | 6832 *type = type_parameter.raw(); |
6810 return; | 6833 return; |
6811 } | 6834 } |
6812 } | 6835 } |
6813 // Global lookup in current library. | 6836 // Global lookup in current library. |
6814 resolved_type_class = library_.LookupClass(unresolved_class_name); | 6837 resolved_type_class = library_.LookupClass(unresolved_class_name); |
6815 } else { | 6838 } else { |
(...skipping 98 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
6914 // If the field is not initialized and not const, return the ast for the getter. | 6937 // If the field is not initialized and not const, return the ast for the getter. |
6915 AstNode* Parser::RunStaticFieldInitializer(const Field& field) { | 6938 AstNode* Parser::RunStaticFieldInitializer(const Field& field) { |
6916 ASSERT(field.is_static()); | 6939 ASSERT(field.is_static()); |
6917 const Instance& value = Instance::Handle(field.value()); | 6940 const Instance& value = Instance::Handle(field.value()); |
6918 if (value.raw() == Object::transition_sentinel()) { | 6941 if (value.raw() == Object::transition_sentinel()) { |
6919 if (field.is_const()) { | 6942 if (field.is_const()) { |
6920 ErrorMsg("circular dependency while initializing static field '%s'", | 6943 ErrorMsg("circular dependency while initializing static field '%s'", |
6921 String::Handle(field.name()).ToCString()); | 6944 String::Handle(field.name()).ToCString()); |
6922 } else { | 6945 } else { |
6923 // The implicit static getter will throw the exception if necessary. | 6946 // The implicit static getter will throw the exception if necessary. |
6924 return new StaticGetterNode(token_index_, | 6947 return new StaticGetterNode(TokenPos(), |
6925 Class::ZoneHandle(field.owner()), | 6948 Class::ZoneHandle(field.owner()), |
6926 String::ZoneHandle(field.name())); | 6949 String::ZoneHandle(field.name())); |
6927 } | 6950 } |
6928 } else if (value.raw() == Object::sentinel()) { | 6951 } else if (value.raw() == Object::sentinel()) { |
6929 // This field has not been referenced yet and thus the value has | 6952 // This field has not been referenced yet and thus the value has |
6930 // not been evaluated. If the field is const, call the static getter method | 6953 // not been evaluated. If the field is const, call the static getter method |
6931 // to evaluate the expression and canonicalize the value. | 6954 // to evaluate the expression and canonicalize the value. |
6932 if (field.is_const()) { | 6955 if (field.is_const()) { |
6933 field.set_value(Instance::Handle(Object::transition_sentinel())); | 6956 field.set_value(Instance::Handle(Object::transition_sentinel())); |
6934 const String& field_name = String::Handle(field.name()); | 6957 const String& field_name = String::Handle(field.name()); |
(...skipping 13 matching lines...) Expand all Loading... |
6948 ASSERT(func.kind() == RawFunction::kConstImplicitGetter); | 6971 ASSERT(func.kind() == RawFunction::kConstImplicitGetter); |
6949 Object& const_value = Object::Handle( | 6972 Object& const_value = Object::Handle( |
6950 DartEntry::InvokeStatic(func, arguments, kNoArgumentNames)); | 6973 DartEntry::InvokeStatic(func, arguments, kNoArgumentNames)); |
6951 if (const_value.IsError()) { | 6974 if (const_value.IsError()) { |
6952 Error& error = Error::Handle(); | 6975 Error& error = Error::Handle(); |
6953 error ^= const_value.raw(); | 6976 error ^= const_value.raw(); |
6954 if (const_value.IsUnhandledException()) { | 6977 if (const_value.IsUnhandledException()) { |
6955 field.set_value(Instance::Handle()); | 6978 field.set_value(Instance::Handle()); |
6956 // It is a compile-time error if evaluation of a compile-time constant | 6979 // It is a compile-time error if evaluation of a compile-time constant |
6957 // would raise an exception. | 6980 // would raise an exception. |
6958 AppendErrorMsg(error, token_index_, | 6981 AppendErrorMsg(error, TokenPos(), |
6959 "error initializing final field '%s'", | 6982 "error initializing final field '%s'", |
6960 String::Handle(field.name()).ToCString()); | 6983 String::Handle(field.name()).ToCString()); |
6961 } else { | 6984 } else { |
6962 Isolate::Current()->long_jump_base()->Jump(1, error); | 6985 Isolate::Current()->long_jump_base()->Jump(1, error); |
6963 } | 6986 } |
6964 } | 6987 } |
6965 ASSERT(const_value.IsNull() || const_value.IsInstance()); | 6988 ASSERT(const_value.IsNull() || const_value.IsInstance()); |
6966 Instance& instance = Instance::Handle(); | 6989 Instance& instance = Instance::Handle(); |
6967 instance ^= const_value.raw(); | 6990 instance ^= const_value.raw(); |
6968 if (!instance.IsNull()) { | 6991 if (!instance.IsNull()) { |
6969 instance ^= instance.Canonicalize(); | 6992 instance ^= instance.Canonicalize(); |
6970 } | 6993 } |
6971 field.set_value(instance); | 6994 field.set_value(instance); |
6972 } else { | 6995 } else { |
6973 return new StaticGetterNode(token_index_, | 6996 return new StaticGetterNode(TokenPos(), |
6974 Class::ZoneHandle(field.owner()), | 6997 Class::ZoneHandle(field.owner()), |
6975 String::ZoneHandle(field.name())); | 6998 String::ZoneHandle(field.name())); |
6976 } | 6999 } |
6977 } | 7000 } |
6978 return NULL; | 7001 return NULL; |
6979 } | 7002 } |
6980 | 7003 |
6981 | 7004 |
6982 RawObject* Parser::EvaluateConstConstructorCall( | 7005 RawObject* Parser::EvaluateConstConstructorCall( |
6983 const Class& type_class, | 7006 const Class& type_class, |
(...skipping 424 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
7408 // Parse "[" [ expr { "," expr } ["," ] "]". | 7431 // Parse "[" [ expr { "," expr } ["," ] "]". |
7409 // Note: if the list literal is empty and the brackets have no whitespace | 7432 // Note: if the list literal is empty and the brackets have no whitespace |
7410 // between them, the scanner recognizes the opening and closing bracket | 7433 // between them, the scanner recognizes the opening and closing bracket |
7411 // as one token of type Token::kINDEX. | 7434 // as one token of type Token::kINDEX. |
7412 AstNode* Parser::ParseListLiteral(intptr_t type_pos, | 7435 AstNode* Parser::ParseListLiteral(intptr_t type_pos, |
7413 bool is_const, | 7436 bool is_const, |
7414 const AbstractTypeArguments& type_arguments) { | 7437 const AbstractTypeArguments& type_arguments) { |
7415 TRACE_PARSER("ParseListLiteral"); | 7438 TRACE_PARSER("ParseListLiteral"); |
7416 ASSERT(type_pos >= 0); | 7439 ASSERT(type_pos >= 0); |
7417 ASSERT(CurrentToken() == Token::kLBRACK || CurrentToken() == Token::kINDEX); | 7440 ASSERT(CurrentToken() == Token::kLBRACK || CurrentToken() == Token::kINDEX); |
7418 const intptr_t literal_pos = token_index_; | 7441 const intptr_t literal_pos = TokenPos(); |
7419 bool is_empty_literal = CurrentToken() == Token::kINDEX; | 7442 bool is_empty_literal = CurrentToken() == Token::kINDEX; |
7420 ConsumeToken(); | 7443 ConsumeToken(); |
7421 | 7444 |
7422 AbstractType& element_type = Type::ZoneHandle(Type::DynamicType()); | 7445 AbstractType& element_type = Type::ZoneHandle(Type::DynamicType()); |
7423 // If no type argument vector is provided, leave it as null, which is | 7446 // If no type argument vector is provided, leave it as null, which is |
7424 // equivalent to using Dynamic as the type argument for the element type. | 7447 // equivalent to using Dynamic as the type argument for the element type. |
7425 if (!type_arguments.IsNull()) { | 7448 if (!type_arguments.IsNull()) { |
7426 ASSERT(type_arguments.Length() > 0); | 7449 ASSERT(type_arguments.Length() > 0); |
7427 // List literals take a single type argument. | 7450 // List literals take a single type argument. |
7428 element_type = type_arguments.TypeAt(0); | 7451 element_type = type_arguments.TypeAt(0); |
7429 if (type_arguments.Length() != 1) { | 7452 if (type_arguments.Length() != 1) { |
7430 ErrorMsg(type_pos, | 7453 ErrorMsg(type_pos, |
7431 "a list literal takes one type argument specifying " | 7454 "a list literal takes one type argument specifying " |
7432 "the element type"); | 7455 "the element type"); |
7433 } | 7456 } |
7434 if (is_const && !element_type.IsInstantiated()) { | 7457 if (is_const && !element_type.IsInstantiated()) { |
7435 ErrorMsg(type_pos, | 7458 ErrorMsg(type_pos, |
7436 "the type argument of a constant list literal cannot include " | 7459 "the type argument of a constant list literal cannot include " |
7437 "a type variable"); | 7460 "a type variable"); |
7438 } | 7461 } |
7439 } | 7462 } |
7440 ASSERT(type_arguments.IsNull() || (type_arguments.Length() == 1)); | 7463 ASSERT(type_arguments.IsNull() || (type_arguments.Length() == 1)); |
7441 | 7464 |
7442 // Parse the list elements. Note: there may be an optional extra | 7465 // Parse the list elements. Note: there may be an optional extra |
7443 // comma after the last element. | 7466 // comma after the last element. |
7444 ArrayNode* list = new ArrayNode(token_index_, type_arguments); | 7467 ArrayNode* list = new ArrayNode(TokenPos(), type_arguments); |
7445 if (!is_empty_literal) { | 7468 if (!is_empty_literal) { |
7446 const bool saved_mode = SetAllowFunctionLiterals(true); | 7469 const bool saved_mode = SetAllowFunctionLiterals(true); |
7447 const String& dst_name = String::ZoneHandle( | 7470 const String& dst_name = String::ZoneHandle( |
7448 String::NewSymbol("list literal element")); | 7471 String::NewSymbol("list literal element")); |
7449 while (CurrentToken() != Token::kRBRACK) { | 7472 while (CurrentToken() != Token::kRBRACK) { |
7450 const intptr_t element_pos = token_index_; | 7473 const intptr_t element_pos = TokenPos(); |
7451 AstNode* element = ParseExpr(is_const); | 7474 AstNode* element = ParseExpr(is_const); |
7452 if (FLAG_enable_type_checks && | 7475 if (FLAG_enable_type_checks && |
7453 !is_const && | 7476 !is_const && |
7454 !element_type.IsDynamicType()) { | 7477 !element_type.IsDynamicType()) { |
7455 element = new AssignableNode(element_pos, | 7478 element = new AssignableNode(element_pos, |
7456 element, | 7479 element, |
7457 element_type, | 7480 element_type, |
7458 dst_name); | 7481 dst_name); |
7459 } | 7482 } |
7460 list->AddElement(element); | 7483 list->AddElement(element); |
(...skipping 20 matching lines...) Expand all Loading... |
7481 ASSERT(elem->IsLiteralNode()); | 7504 ASSERT(elem->IsLiteralNode()); |
7482 if (FLAG_enable_type_checks && | 7505 if (FLAG_enable_type_checks && |
7483 !element_type.IsDynamicType() && | 7506 !element_type.IsDynamicType() && |
7484 (!elem->AsLiteralNode()->literal().IsNull() && | 7507 (!elem->AsLiteralNode()->literal().IsNull() && |
7485 !elem->AsLiteralNode()->literal().IsInstanceOf( | 7508 !elem->AsLiteralNode()->literal().IsInstanceOf( |
7486 element_type, TypeArguments::Handle(), &malformed_error))) { | 7509 element_type, TypeArguments::Handle(), &malformed_error))) { |
7487 // If the failure is due to a malformed type error, display it instead. | 7510 // If the failure is due to a malformed type error, display it instead. |
7488 if (!malformed_error.IsNull()) { | 7511 if (!malformed_error.IsNull()) { |
7489 ErrorMsg(malformed_error); | 7512 ErrorMsg(malformed_error); |
7490 } else { | 7513 } else { |
7491 ErrorMsg(elem->AsLiteralNode()->token_index(), | 7514 ErrorMsg(elem->AsLiteralNode()->token_pos(), |
7492 "list literal element at index %d must be " | 7515 "list literal element at index %d must be " |
7493 "a constant of type '%s'", | 7516 "a constant of type '%s'", |
7494 i, | 7517 i, |
7495 String::Handle(element_type.Name()).ToCString()); | 7518 String::Handle(element_type.Name()).ToCString()); |
7496 } | 7519 } |
7497 } | 7520 } |
7498 const_list.SetAt(i, elem->AsLiteralNode()->literal()); | 7521 const_list.SetAt(i, elem->AsLiteralNode()->literal()); |
7499 } | 7522 } |
7500 const_list ^= const_list.Canonicalize(); | 7523 const_list ^= const_list.Canonicalize(); |
7501 const_list.MakeImmutable(); | 7524 const_list.MakeImmutable(); |
(...skipping 22 matching lines...) Expand all Loading... |
7524 AbstractTypeArguments::ZoneHandle(type_arguments.Canonicalize()); | 7547 AbstractTypeArguments::ZoneHandle(type_arguments.Canonicalize()); |
7525 return CreateConstructorCallNode(literal_pos, | 7548 return CreateConstructorCallNode(literal_pos, |
7526 canonical_type_arguments, | 7549 canonical_type_arguments, |
7527 list_literal_factory, | 7550 list_literal_factory, |
7528 factory_param); | 7551 factory_param); |
7529 } | 7552 } |
7530 } | 7553 } |
7531 | 7554 |
7532 | 7555 |
7533 ConstructorCallNode* Parser::CreateConstructorCallNode( | 7556 ConstructorCallNode* Parser::CreateConstructorCallNode( |
7534 intptr_t token_index, | 7557 intptr_t token_pos, |
7535 const AbstractTypeArguments& type_arguments, | 7558 const AbstractTypeArguments& type_arguments, |
7536 const Function& constructor, | 7559 const Function& constructor, |
7537 ArgumentListNode* arguments) { | 7560 ArgumentListNode* arguments) { |
7538 if (!type_arguments.IsNull() && !type_arguments.IsInstantiated()) { | 7561 if (!type_arguments.IsNull() && !type_arguments.IsInstantiated()) { |
7539 EnsureExpressionTemp(); | 7562 EnsureExpressionTemp(); |
7540 } | 7563 } |
7541 LocalVariable* allocated = | 7564 LocalVariable* allocated = |
7542 CreateTempConstVariable(token_index, token_index, "alloc"); | 7565 CreateTempConstVariable(token_pos, token_pos, "alloc"); |
7543 return new ConstructorCallNode(token_index, | 7566 return new ConstructorCallNode(token_pos, |
7544 type_arguments, | 7567 type_arguments, |
7545 constructor, | 7568 constructor, |
7546 arguments, | 7569 arguments, |
7547 *allocated); | 7570 *allocated); |
7548 } | 7571 } |
7549 | 7572 |
7550 | 7573 |
7551 static void AddKeyValuePair(ArrayNode* pairs, | 7574 static void AddKeyValuePair(ArrayNode* pairs, |
7552 bool is_const, | 7575 bool is_const, |
7553 AstNode* key, | 7576 AstNode* key, |
(...skipping 18 matching lines...) Expand all Loading... |
7572 pairs->AddElement(value); | 7595 pairs->AddElement(value); |
7573 } | 7596 } |
7574 | 7597 |
7575 | 7598 |
7576 AstNode* Parser::ParseMapLiteral(intptr_t type_pos, | 7599 AstNode* Parser::ParseMapLiteral(intptr_t type_pos, |
7577 bool is_const, | 7600 bool is_const, |
7578 const AbstractTypeArguments& type_arguments) { | 7601 const AbstractTypeArguments& type_arguments) { |
7579 TRACE_PARSER("ParseMapLiteral"); | 7602 TRACE_PARSER("ParseMapLiteral"); |
7580 ASSERT(type_pos >= 0); | 7603 ASSERT(type_pos >= 0); |
7581 ASSERT(CurrentToken() == Token::kLBRACE); | 7604 ASSERT(CurrentToken() == Token::kLBRACE); |
7582 const intptr_t literal_pos = token_index_; | 7605 const intptr_t literal_pos = TokenPos(); |
7583 ConsumeToken(); | 7606 ConsumeToken(); |
7584 | 7607 |
7585 AbstractType& value_type = Type::ZoneHandle(Type::DynamicType()); | 7608 AbstractType& value_type = Type::ZoneHandle(Type::DynamicType()); |
7586 AbstractTypeArguments& map_type_arguments = | 7609 AbstractTypeArguments& map_type_arguments = |
7587 AbstractTypeArguments::ZoneHandle(type_arguments.raw()); | 7610 AbstractTypeArguments::ZoneHandle(type_arguments.raw()); |
7588 // If no type argument vector is provided, leave it as null, which is | 7611 // If no type argument vector is provided, leave it as null, which is |
7589 // equivalent to using Dynamic as the type argument for the value type. | 7612 // equivalent to using Dynamic as the type argument for the value type. |
7590 if (!map_type_arguments.IsNull()) { | 7613 if (!map_type_arguments.IsNull()) { |
7591 ASSERT(map_type_arguments.Length() > 0); | 7614 ASSERT(map_type_arguments.Length() > 0); |
7592 // Map literals take a single type argument. | 7615 // Map literals take a single type argument. |
(...skipping 27 matching lines...) Expand all Loading... |
7620 } | 7643 } |
7621 } | 7644 } |
7622 ASSERT(map_type_arguments.IsNull() || (map_type_arguments.Length() == 2)); | 7645 ASSERT(map_type_arguments.IsNull() || (map_type_arguments.Length() == 2)); |
7623 map_type_arguments ^= map_type_arguments.Canonicalize(); | 7646 map_type_arguments ^= map_type_arguments.Canonicalize(); |
7624 | 7647 |
7625 // Parse the map entries. Note: there may be an optional extra | 7648 // Parse the map entries. Note: there may be an optional extra |
7626 // comma after the last entry. | 7649 // comma after the last entry. |
7627 // The kv_pair array is temporary and of element type Dynamic. It is passed | 7650 // The kv_pair array is temporary and of element type Dynamic. It is passed |
7628 // to the factory to initialize a properly typed map. | 7651 // to the factory to initialize a properly typed map. |
7629 ArrayNode* kv_pairs = | 7652 ArrayNode* kv_pairs = |
7630 new ArrayNode(token_index_, TypeArguments::ZoneHandle()); | 7653 new ArrayNode(TokenPos(), TypeArguments::ZoneHandle()); |
7631 const String& dst_name = String::ZoneHandle( | 7654 const String& dst_name = String::ZoneHandle( |
7632 String::NewSymbol("list literal element")); | 7655 String::NewSymbol("list literal element")); |
7633 while (CurrentToken() != Token::kRBRACE) { | 7656 while (CurrentToken() != Token::kRBRACE) { |
7634 AstNode* key = NULL; | 7657 AstNode* key = NULL; |
7635 if (CurrentToken() == Token::kSTRING) { | 7658 if (CurrentToken() == Token::kSTRING) { |
7636 key = ParseStringLiteral(); | 7659 key = ParseStringLiteral(); |
7637 } | 7660 } |
7638 if (key == NULL) { | 7661 if (key == NULL) { |
7639 ErrorMsg("map entry key must be string literal"); | 7662 ErrorMsg("map entry key must be string literal"); |
7640 } else if (is_const && !key->IsLiteralNode()) { | 7663 } else if (is_const && !key->IsLiteralNode()) { |
7641 ErrorMsg("map entry key must be compile time constant string"); | 7664 ErrorMsg("map entry key must be compile time constant string"); |
7642 } | 7665 } |
7643 ExpectToken(Token::kCOLON); | 7666 ExpectToken(Token::kCOLON); |
7644 const bool saved_mode = SetAllowFunctionLiterals(true); | 7667 const bool saved_mode = SetAllowFunctionLiterals(true); |
7645 const intptr_t value_pos = token_index_; | 7668 const intptr_t value_pos = TokenPos(); |
7646 AstNode* value = ParseExpr(is_const); | 7669 AstNode* value = ParseExpr(is_const); |
7647 SetAllowFunctionLiterals(saved_mode); | 7670 SetAllowFunctionLiterals(saved_mode); |
7648 if (FLAG_enable_type_checks && | 7671 if (FLAG_enable_type_checks && |
7649 !is_const && | 7672 !is_const && |
7650 !value_type.IsDynamicType()) { | 7673 !value_type.IsDynamicType()) { |
7651 value = new AssignableNode(value_pos, | 7674 value = new AssignableNode(value_pos, |
7652 value, | 7675 value, |
7653 value_type, | 7676 value_type, |
7654 dst_name); | 7677 dst_name); |
7655 } | 7678 } |
(...skipping 24 matching lines...) Expand all Loading... |
7680 if (FLAG_enable_type_checks && | 7703 if (FLAG_enable_type_checks && |
7681 ((i % 2) == 1) && // Check values only, not keys. | 7704 ((i % 2) == 1) && // Check values only, not keys. |
7682 !value_type.IsDynamicType() && | 7705 !value_type.IsDynamicType() && |
7683 (!arg->AsLiteralNode()->literal().IsNull() && | 7706 (!arg->AsLiteralNode()->literal().IsNull() && |
7684 !arg->AsLiteralNode()->literal().IsInstanceOf( | 7707 !arg->AsLiteralNode()->literal().IsInstanceOf( |
7685 value_type, TypeArguments::Handle(), &malformed_error))) { | 7708 value_type, TypeArguments::Handle(), &malformed_error))) { |
7686 // If the failure is due to a malformed type error, display it instead. | 7709 // If the failure is due to a malformed type error, display it instead. |
7687 if (!malformed_error.IsNull()) { | 7710 if (!malformed_error.IsNull()) { |
7688 ErrorMsg(malformed_error); | 7711 ErrorMsg(malformed_error); |
7689 } else { | 7712 } else { |
7690 ErrorMsg(arg->AsLiteralNode()->token_index(), | 7713 ErrorMsg(arg->AsLiteralNode()->token_pos(), |
7691 "map literal value at index %d must be " | 7714 "map literal value at index %d must be " |
7692 "a constant of type '%s'", | 7715 "a constant of type '%s'", |
7693 i >> 1, | 7716 i >> 1, |
7694 String::Handle(value_type.Name()).ToCString()); | 7717 String::Handle(value_type.Name()).ToCString()); |
7695 } | 7718 } |
7696 } | 7719 } |
7697 key_value_array.SetAt(i, arg->AsLiteralNode()->literal()); | 7720 key_value_array.SetAt(i, arg->AsLiteralNode()->literal()); |
7698 } | 7721 } |
7699 key_value_array ^= key_value_array.Canonicalize(); | 7722 key_value_array ^= key_value_array.Canonicalize(); |
7700 key_value_array.MakeImmutable(); | 7723 key_value_array.MakeImmutable(); |
7701 | 7724 |
7702 // Construct the map object. | 7725 // Construct the map object. |
7703 const String& immutable_map_class_name = | 7726 const String& immutable_map_class_name = |
7704 String::Handle(String::NewSymbol(kImmutableMapName)); | 7727 String::Handle(String::NewSymbol(kImmutableMapName)); |
7705 const Class& immutable_map_class = | 7728 const Class& immutable_map_class = |
7706 Class::Handle(LookupImplClass(immutable_map_class_name)); | 7729 Class::Handle(LookupImplClass(immutable_map_class_name)); |
7707 ASSERT(!immutable_map_class.IsNull()); | 7730 ASSERT(!immutable_map_class.IsNull()); |
7708 ArgumentListNode* constr_args = new ArgumentListNode(token_index_); | 7731 ArgumentListNode* constr_args = new ArgumentListNode(TokenPos()); |
7709 constr_args->Add(new LiteralNode(literal_pos, key_value_array)); | 7732 constr_args->Add(new LiteralNode(literal_pos, key_value_array)); |
7710 const String& constr_name = | 7733 const String& constr_name = |
7711 String::Handle(String::NewSymbol(kImmutableMapConstructorName)); | 7734 String::Handle(String::NewSymbol(kImmutableMapConstructorName)); |
7712 const Function& map_constr = Function::ZoneHandle( | 7735 const Function& map_constr = Function::ZoneHandle( |
7713 immutable_map_class.LookupConstructor(constr_name)); | 7736 immutable_map_class.LookupConstructor(constr_name)); |
7714 ASSERT(!map_constr.IsNull()); | 7737 ASSERT(!map_constr.IsNull()); |
7715 const Object& constructor_result = Object::Handle( | 7738 const Object& constructor_result = Object::Handle( |
7716 EvaluateConstConstructorCall(immutable_map_class, | 7739 EvaluateConstConstructorCall(immutable_map_class, |
7717 map_type_arguments, | 7740 map_type_arguments, |
7718 map_constr, | 7741 map_constr, |
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
7752 } | 7775 } |
7753 | 7776 |
7754 | 7777 |
7755 AstNode* Parser::ParseCompoundLiteral() { | 7778 AstNode* Parser::ParseCompoundLiteral() { |
7756 TRACE_PARSER("ParseCompoundLiteral"); | 7779 TRACE_PARSER("ParseCompoundLiteral"); |
7757 bool is_const = false; | 7780 bool is_const = false; |
7758 if (CurrentToken() == Token::kCONST) { | 7781 if (CurrentToken() == Token::kCONST) { |
7759 is_const = true; | 7782 is_const = true; |
7760 ConsumeToken(); | 7783 ConsumeToken(); |
7761 } | 7784 } |
7762 const intptr_t type_pos = token_index_; | 7785 const intptr_t type_pos = TokenPos(); |
7763 Error& malformed_error = Error::Handle(); | 7786 Error& malformed_error = Error::Handle(); |
7764 AbstractTypeArguments& type_arguments = AbstractTypeArguments::ZoneHandle( | 7787 AbstractTypeArguments& type_arguments = AbstractTypeArguments::ZoneHandle( |
7765 ParseTypeArguments(&malformed_error, | 7788 ParseTypeArguments(&malformed_error, |
7766 ClassFinalizer::kFinalizeWellFormed)); | 7789 ClassFinalizer::kFinalizeWellFormed)); |
7767 // Map and List interfaces do not declare bounds on their type parameters, so | 7790 // Map and List interfaces do not declare bounds on their type parameters, so |
7768 // we should never see a malformed type error here. | 7791 // we should never see a malformed type error here. |
7769 // Note that a bound error is the only possible malformed type error returned | 7792 // Note that a bound error is the only possible malformed type error returned |
7770 // when requesting kFinalizeWellFormed type finalization. | 7793 // when requesting kFinalizeWellFormed type finalization. |
7771 ASSERT(malformed_error.IsNull()); | 7794 ASSERT(malformed_error.IsNull()); |
7772 AstNode* primary = NULL; | 7795 AstNode* primary = NULL; |
(...skipping 20 matching lines...) Expand all Loading... |
7793 String::Handle(String::Concat(type_class_name, period)); | 7816 String::Handle(String::Concat(type_class_name, period)); |
7794 if (named_constructor != NULL) { | 7817 if (named_constructor != NULL) { |
7795 constructor_name = String::Concat(constructor_name, *named_constructor); | 7818 constructor_name = String::Concat(constructor_name, *named_constructor); |
7796 } | 7819 } |
7797 return constructor_name; | 7820 return constructor_name; |
7798 } | 7821 } |
7799 | 7822 |
7800 | 7823 |
7801 AstNode* Parser::ParseNewOperator() { | 7824 AstNode* Parser::ParseNewOperator() { |
7802 TRACE_PARSER("ParseNewOperator"); | 7825 TRACE_PARSER("ParseNewOperator"); |
7803 const intptr_t new_pos = token_index_; | 7826 const intptr_t new_pos = TokenPos(); |
7804 ASSERT((CurrentToken() == Token::kNEW) || (CurrentToken() == Token::kCONST)); | 7827 ASSERT((CurrentToken() == Token::kNEW) || (CurrentToken() == Token::kCONST)); |
7805 bool is_const = (CurrentToken() == Token::kCONST); | 7828 bool is_const = (CurrentToken() == Token::kCONST); |
7806 ConsumeToken(); | 7829 ConsumeToken(); |
7807 if (!IsIdentifier()) { | 7830 if (!IsIdentifier()) { |
7808 ErrorMsg("type name expected"); | 7831 ErrorMsg("type name expected"); |
7809 } | 7832 } |
7810 intptr_t type_pos = token_index_; | 7833 intptr_t type_pos = TokenPos(); |
7811 const AbstractType& type = AbstractType::Handle( | 7834 const AbstractType& type = AbstractType::Handle( |
7812 ParseType(ClassFinalizer::kFinalizeWellFormed)); | 7835 ParseType(ClassFinalizer::kFinalizeWellFormed)); |
7813 // Malformed bounds never result in a compile time error, therefore, the | 7836 // Malformed bounds never result in a compile time error, therefore, the |
7814 // parsed type may be malformed although we requested kFinalizeWellFormed. | 7837 // parsed type may be malformed although we requested kFinalizeWellFormed. |
7815 // In that case, we throw a dynamic type error instead of calling the | 7838 // In that case, we throw a dynamic type error instead of calling the |
7816 // constructor. | 7839 // constructor. |
7817 if (type.IsTypeParameter()) { | 7840 if (type.IsTypeParameter()) { |
7818 ErrorMsg(type_pos, | 7841 ErrorMsg(type_pos, |
7819 "type parameter '%s' cannot be instantiated", | 7842 "type parameter '%s' cannot be instantiated", |
7820 String::Handle(type.Name()).ToCString()); | 7843 String::Handle(type.Name()).ToCString()); |
(...skipping 19 matching lines...) Expand all Loading... |
7840 String* named_constructor = NULL; | 7863 String* named_constructor = NULL; |
7841 if (CurrentToken() == Token::kPERIOD) { | 7864 if (CurrentToken() == Token::kPERIOD) { |
7842 ConsumeToken(); | 7865 ConsumeToken(); |
7843 named_constructor = ExpectIdentifier("name of constructor expected"); | 7866 named_constructor = ExpectIdentifier("name of constructor expected"); |
7844 } | 7867 } |
7845 | 7868 |
7846 // Parse constructor parameters. | 7869 // Parse constructor parameters. |
7847 if (CurrentToken() != Token::kLPAREN) { | 7870 if (CurrentToken() != Token::kLPAREN) { |
7848 ErrorMsg("'(' expected"); | 7871 ErrorMsg("'(' expected"); |
7849 } | 7872 } |
7850 intptr_t call_pos = token_index_; | 7873 intptr_t call_pos = TokenPos(); |
7851 ArgumentListNode* arguments = ParseActualParameters(NULL, is_const); | 7874 ArgumentListNode* arguments = ParseActualParameters(NULL, is_const); |
7852 | 7875 |
7853 // A constructor has an implicit 'this' parameter (instance to construct) | 7876 // A constructor has an implicit 'this' parameter (instance to construct) |
7854 // and a factory has an implicit 'this' parameter (type_arguments). | 7877 // and a factory has an implicit 'this' parameter (type_arguments). |
7855 // A constructor has a second implicit 'phase' parameter. | 7878 // A constructor has a second implicit 'phase' parameter. |
7856 intptr_t arguments_length = arguments->length() + 2; | 7879 intptr_t arguments_length = arguments->length() + 2; |
7857 | 7880 |
7858 if (type_class.is_interface()) { | 7881 if (type_class.is_interface()) { |
7859 // We need to make sure that an appropriate constructor is | 7882 // We need to make sure that an appropriate constructor is |
7860 // declared in the interface. | 7883 // declared in the interface. |
(...skipping 95 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
7956 if (i < num_type_arguments) { | 7979 if (i < num_type_arguments) { |
7957 type_argument = type_arguments.TypeAt(i); | 7980 type_argument = type_arguments.TypeAt(i); |
7958 } else { | 7981 } else { |
7959 type_argument = Type::DynamicType(); | 7982 type_argument = Type::DynamicType(); |
7960 } | 7983 } |
7961 temp_type_arguments.SetTypeAt(i, type_argument); | 7984 temp_type_arguments.SetTypeAt(i, type_argument); |
7962 } | 7985 } |
7963 } | 7986 } |
7964 // TODO(regis): Temporary type should be allocated in new gen heap. | 7987 // TODO(regis): Temporary type should be allocated in new gen heap. |
7965 Type& temp_type = Type::Handle( | 7988 Type& temp_type = Type::Handle( |
7966 Type::New(constructor_class, temp_type_arguments, type.token_index())); | 7989 Type::New(constructor_class, temp_type_arguments, type.token_pos())); |
7967 temp_type ^= ClassFinalizer::FinalizeType( | 7990 temp_type ^= ClassFinalizer::FinalizeType( |
7968 current_class(), temp_type, ClassFinalizer::kFinalize); | 7991 current_class(), temp_type, ClassFinalizer::kFinalize); |
7969 // The type argument vector may have been expanded with the type arguments | 7992 // The type argument vector may have been expanded with the type arguments |
7970 // of the super type when finalizing the temporary type. | 7993 // of the super type when finalizing the temporary type. |
7971 type_arguments = temp_type.arguments(); | 7994 type_arguments = temp_type.arguments(); |
7972 // The type parameter bounds of the factory class may be more specific than | 7995 // The type parameter bounds of the factory class may be more specific than |
7973 // the type parameter bounds of the interface class. Therefore, although | 7996 // the type parameter bounds of the interface class. Therefore, although |
7974 // type was not malformed, temp_type may be malformed. | 7997 // type was not malformed, temp_type may be malformed. |
7975 if (!type.IsMalformed() && temp_type.IsMalformed()) { | 7998 if (!type.IsMalformed() && temp_type.IsMalformed()) { |
7976 const Error& error = Error::Handle(temp_type.malformed_error()); | 7999 const Error& error = Error::Handle(temp_type.malformed_error()); |
(...skipping 85 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
8062 | 8085 |
8063 // A string literal consists of the concatenation of the next n tokens | 8086 // A string literal consists of the concatenation of the next n tokens |
8064 // that satisfy the EBNF grammar: | 8087 // that satisfy the EBNF grammar: |
8065 // literal = kSTRING {{ interpol } kSTRING } | 8088 // literal = kSTRING {{ interpol } kSTRING } |
8066 // interpol = kINTERPOL_VAR | (kINTERPOL_START expression kINTERPOL_END) | 8089 // interpol = kINTERPOL_VAR | (kINTERPOL_START expression kINTERPOL_END) |
8067 // In other words, the scanner breaks down interpolated strings so that | 8090 // In other words, the scanner breaks down interpolated strings so that |
8068 // a string literal always begins and ends with a kSTRING token. | 8091 // a string literal always begins and ends with a kSTRING token. |
8069 AstNode* Parser::ParseStringLiteral() { | 8092 AstNode* Parser::ParseStringLiteral() { |
8070 TRACE_PARSER("ParseStringLiteral"); | 8093 TRACE_PARSER("ParseStringLiteral"); |
8071 AstNode* primary = NULL; | 8094 AstNode* primary = NULL; |
8072 const intptr_t literal_start = token_index_; | 8095 const intptr_t literal_start = TokenPos(); |
8073 ASSERT(CurrentToken() == Token::kSTRING); | 8096 ASSERT(CurrentToken() == Token::kSTRING); |
8074 Token::Kind l1_token = LookaheadToken(1); | 8097 Token::Kind l1_token = LookaheadToken(1); |
8075 if ((l1_token != Token::kSTRING) && | 8098 if ((l1_token != Token::kSTRING) && |
8076 (l1_token != Token::kINTERPOL_VAR) && | 8099 (l1_token != Token::kINTERPOL_VAR) && |
8077 (l1_token != Token::kINTERPOL_START)) { | 8100 (l1_token != Token::kINTERPOL_START)) { |
8078 // Common case: no interpolation. | 8101 // Common case: no interpolation. |
8079 primary = new LiteralNode(literal_start, *CurrentLiteral()); | 8102 primary = new LiteralNode(literal_start, *CurrentLiteral()); |
8080 ConsumeToken(); | 8103 ConsumeToken(); |
8081 return primary; | 8104 return primary; |
8082 } | 8105 } |
8083 // String interpolation needed. | 8106 // String interpolation needed. |
8084 bool is_compiletime_const = true; | 8107 bool is_compiletime_const = true; |
8085 ArrayNode* values = new ArrayNode(token_index_, TypeArguments::ZoneHandle()); | 8108 ArrayNode* values = new ArrayNode(TokenPos(), TypeArguments::ZoneHandle()); |
8086 while (CurrentToken() == Token::kSTRING) { | 8109 while (CurrentToken() == Token::kSTRING) { |
8087 values->AddElement(new LiteralNode(token_index_, *CurrentLiteral())); | 8110 values->AddElement(new LiteralNode(TokenPos(), *CurrentLiteral())); |
8088 ConsumeToken(); | 8111 ConsumeToken(); |
8089 while ((CurrentToken() == Token::kINTERPOL_VAR) || | 8112 while ((CurrentToken() == Token::kINTERPOL_VAR) || |
8090 (CurrentToken() == Token::kINTERPOL_START)) { | 8113 (CurrentToken() == Token::kINTERPOL_START)) { |
8091 AstNode* expr = NULL; | 8114 AstNode* expr = NULL; |
8092 const intptr_t expr_pos = token_index_; | 8115 const intptr_t expr_pos = TokenPos(); |
8093 if (CurrentToken() == Token::kINTERPOL_VAR) { | 8116 if (CurrentToken() == Token::kINTERPOL_VAR) { |
8094 expr = ResolveIdent(token_index_, *CurrentLiteral(), true); | 8117 expr = ResolveIdent(TokenPos(), *CurrentLiteral(), true); |
8095 ConsumeToken(); | 8118 ConsumeToken(); |
8096 } else { | 8119 } else { |
8097 ASSERT(CurrentToken() == Token::kINTERPOL_START); | 8120 ASSERT(CurrentToken() == Token::kINTERPOL_START); |
8098 ConsumeToken(); | 8121 ConsumeToken(); |
8099 expr = ParseExpr(kAllowConst); | 8122 expr = ParseExpr(kAllowConst); |
8100 ExpectToken(Token::kINTERPOL_END); | 8123 ExpectToken(Token::kINTERPOL_END); |
8101 } | 8124 } |
8102 // Check if this interpolated string is still considered a compile time | 8125 // Check if this interpolated string is still considered a compile time |
8103 // constant. If it is we need to evaluate if the current string part is | 8126 // constant. If it is we need to evaluate if the current string part is |
8104 // a constant or not. | 8127 // a constant or not. |
8105 if (is_compiletime_const) { | 8128 if (is_compiletime_const) { |
8106 const Object* const_expr = expr->EvalConstExpr(); | 8129 const Object* const_expr = expr->EvalConstExpr(); |
8107 if (const_expr != NULL) { | 8130 if (const_expr != NULL) { |
8108 // Change expr into a literal. | 8131 // Change expr into a literal. |
8109 expr = new LiteralNode(expr_pos, EvaluateConstExpr(expr)); | 8132 expr = new LiteralNode(expr_pos, EvaluateConstExpr(expr)); |
8110 } else { | 8133 } else { |
8111 is_compiletime_const = false; | 8134 is_compiletime_const = false; |
8112 } | 8135 } |
8113 } | 8136 } |
8114 values->AddElement(expr); | 8137 values->AddElement(expr); |
8115 } | 8138 } |
8116 } | 8139 } |
8117 if (is_compiletime_const) { | 8140 if (is_compiletime_const) { |
8118 primary = new LiteralNode(literal_start, Interpolate(values)); | 8141 primary = new LiteralNode(literal_start, Interpolate(values)); |
8119 } else { | 8142 } else { |
8120 ArgumentListNode* interpolate_arg = | 8143 ArgumentListNode* interpolate_arg = |
8121 new ArgumentListNode(values->token_index()); | 8144 new ArgumentListNode(values->token_pos()); |
8122 interpolate_arg->Add(values); | 8145 interpolate_arg->Add(values); |
8123 primary = MakeStaticCall(kStringClassName, | 8146 primary = MakeStaticCall(kStringClassName, |
8124 kInterpolateName, | 8147 kInterpolateName, |
8125 interpolate_arg); | 8148 interpolate_arg); |
8126 } | 8149 } |
8127 return primary; | 8150 return primary; |
8128 } | 8151 } |
8129 | 8152 |
8130 | 8153 |
8131 // An import string literal consists of the concatenation of the next n tokens | 8154 // An import string literal consists of the concatenation of the next n tokens |
(...skipping 21 matching lines...) Expand all Loading... |
8153 ConsumeToken(); | 8176 ConsumeToken(); |
8154 if ((CurrentToken() != Token::kINTERPOL_VAR) && | 8177 if ((CurrentToken() != Token::kINTERPOL_VAR) && |
8155 (CurrentToken() != Token::kINTERPOL_START)) { | 8178 (CurrentToken() != Token::kINTERPOL_START)) { |
8156 break; | 8179 break; |
8157 } | 8180 } |
8158 while ((CurrentToken() == Token::kINTERPOL_VAR) || | 8181 while ((CurrentToken() == Token::kINTERPOL_VAR) || |
8159 (CurrentToken() == Token::kINTERPOL_START)) { | 8182 (CurrentToken() == Token::kINTERPOL_START)) { |
8160 if (CurrentToken() == Token::kINTERPOL_START) { | 8183 if (CurrentToken() == Token::kINTERPOL_START) { |
8161 ConsumeToken(); | 8184 ConsumeToken(); |
8162 if (IsIdentifier()) { | 8185 if (IsIdentifier()) { |
8163 resolved_name = ResolveImportVar(token_index_, *CurrentLiteral()); | 8186 resolved_name = ResolveImportVar(TokenPos(), *CurrentLiteral()); |
8164 result = String::Concat(result, resolved_name); | 8187 result = String::Concat(result, resolved_name); |
8165 ConsumeToken(); | 8188 ConsumeToken(); |
8166 if (CurrentToken() != Token::kINTERPOL_END) { | 8189 if (CurrentToken() != Token::kINTERPOL_END) { |
8167 ErrorMsg("'}' expected"); | 8190 ErrorMsg("'}' expected"); |
8168 } | 8191 } |
8169 ConsumeToken(); | 8192 ConsumeToken(); |
8170 } else { | 8193 } else { |
8171 ErrorMsg("identifier expected"); | 8194 ErrorMsg("identifier expected"); |
8172 } | 8195 } |
8173 } else { | 8196 } else { |
8174 ASSERT(CurrentToken() == Token::kINTERPOL_VAR); | 8197 ASSERT(CurrentToken() == Token::kINTERPOL_VAR); |
8175 resolved_name = ResolveImportVar(token_index_, *CurrentLiteral()); | 8198 resolved_name = ResolveImportVar(TokenPos(), *CurrentLiteral()); |
8176 result = String::Concat(result, resolved_name); | 8199 result = String::Concat(result, resolved_name); |
8177 ConsumeToken(); | 8200 ConsumeToken(); |
8178 } | 8201 } |
8179 } | 8202 } |
8180 // A string literal always ends with a kSTRING token. | 8203 // A string literal always ends with a kSTRING token. |
8181 ASSERT(CurrentToken() == Token::kSTRING); | 8204 ASSERT(CurrentToken() == Token::kSTRING); |
8182 } | 8205 } |
8183 return &result; | 8206 return &result; |
8184 } | 8207 } |
8185 | 8208 |
(...skipping 14 matching lines...) Expand all Loading... |
8200 if (qual_ident.lib_prefix == NULL) { | 8223 if (qual_ident.lib_prefix == NULL) { |
8201 if (!ResolveIdentInLocalScope(qual_ident.ident_pos, | 8224 if (!ResolveIdentInLocalScope(qual_ident.ident_pos, |
8202 *qual_ident.ident, | 8225 *qual_ident.ident, |
8203 &primary)) { | 8226 &primary)) { |
8204 // Check whether the identifier is a type parameter. Type parameters | 8227 // Check whether the identifier is a type parameter. Type parameters |
8205 // can never be used as part of primary expressions. | 8228 // can never be used as part of primary expressions. |
8206 const Class& scope_class = Class::Handle(TypeParametersScopeClass()); | 8229 const Class& scope_class = Class::Handle(TypeParametersScopeClass()); |
8207 if (!scope_class.IsNull()) { | 8230 if (!scope_class.IsNull()) { |
8208 TypeParameter& type_param = TypeParameter::ZoneHandle( | 8231 TypeParameter& type_param = TypeParameter::ZoneHandle( |
8209 scope_class.LookupTypeParameter(*(qual_ident.ident), | 8232 scope_class.LookupTypeParameter(*(qual_ident.ident), |
8210 token_index_)); | 8233 TokenPos())); |
8211 if (!type_param.IsNull()) { | 8234 if (!type_param.IsNull()) { |
8212 String& type_param_name = String::Handle(type_param.Name()); | 8235 String& type_param_name = String::Handle(type_param.Name()); |
8213 ErrorMsg(qual_ident.ident_pos, | 8236 ErrorMsg(qual_ident.ident_pos, |
8214 "illegal use of type parameter %s", | 8237 "illegal use of type parameter %s", |
8215 type_param_name.ToCString()); | 8238 type_param_name.ToCString()); |
8216 } | 8239 } |
8217 } | 8240 } |
8218 // This is a non-local unqualified identifier so resolve the | 8241 // This is a non-local unqualified identifier so resolve the |
8219 // identifier locally in the main app library and all libraries | 8242 // identifier locally in the main app library and all libraries |
8220 // imported by it. | 8243 // imported by it. |
8221 primary = ResolveIdentInLibraryScope(library_, | 8244 primary = ResolveIdentInLibraryScope(library_, |
8222 qual_ident, | 8245 qual_ident, |
8223 kResolveIncludingImports); | 8246 kResolveIncludingImports); |
8224 } | 8247 } |
8225 } else { | 8248 } else { |
8226 // This is a qualified identifier with a library prefix so resolve | 8249 // This is a qualified identifier with a library prefix so resolve |
8227 // the identifier locally in that library (we do not include the | 8250 // the identifier locally in that library (we do not include the |
8228 // libraries imported by that library). | 8251 // libraries imported by that library). |
8229 primary = ResolveIdentInLibraryPrefixScope(*(qual_ident.lib_prefix), | 8252 primary = ResolveIdentInLibraryPrefixScope(*(qual_ident.lib_prefix), |
8230 qual_ident); | 8253 qual_ident); |
8231 } | 8254 } |
8232 ASSERT(primary != NULL); | 8255 ASSERT(primary != NULL); |
8233 } else if (CurrentToken() == Token::kTHIS) { | 8256 } else if (CurrentToken() == Token::kTHIS) { |
8234 const String& this_name = String::Handle(String::NewSymbol(kThisName)); | 8257 const String& this_name = String::Handle(String::NewSymbol(kThisName)); |
8235 LocalVariable* local = LookupLocalScope(this_name); | 8258 LocalVariable* local = LookupLocalScope(this_name); |
8236 if (local == NULL) { | 8259 if (local == NULL) { |
8237 ErrorMsg("receiver 'this' is not in scope"); | 8260 ErrorMsg("receiver 'this' is not in scope"); |
8238 } | 8261 } |
8239 primary = new LoadLocalNode(token_index_, *local); | 8262 primary = new LoadLocalNode(TokenPos(), *local); |
8240 ConsumeToken(); | 8263 ConsumeToken(); |
8241 } else if (CurrentToken() == Token::kINTEGER) { | 8264 } else if (CurrentToken() == Token::kINTEGER) { |
8242 const Integer& literal = Integer::ZoneHandle(CurrentIntegerLiteral()); | 8265 const Integer& literal = Integer::ZoneHandle(CurrentIntegerLiteral()); |
8243 primary = new LiteralNode(token_index_, literal); | 8266 primary = new LiteralNode(TokenPos(), literal); |
8244 ConsumeToken(); | 8267 ConsumeToken(); |
8245 } else if (CurrentToken() == Token::kTRUE) { | 8268 } else if (CurrentToken() == Token::kTRUE) { |
8246 primary = new LiteralNode(token_index_, Bool::ZoneHandle(Bool::True())); | 8269 primary = new LiteralNode(TokenPos(), Bool::ZoneHandle(Bool::True())); |
8247 ConsumeToken(); | 8270 ConsumeToken(); |
8248 } else if (CurrentToken() == Token::kFALSE) { | 8271 } else if (CurrentToken() == Token::kFALSE) { |
8249 primary = new LiteralNode(token_index_, Bool::ZoneHandle(Bool::False())); | 8272 primary = new LiteralNode(TokenPos(), Bool::ZoneHandle(Bool::False())); |
8250 ConsumeToken(); | 8273 ConsumeToken(); |
8251 } else if (CurrentToken() == Token::kNULL) { | 8274 } else if (CurrentToken() == Token::kNULL) { |
8252 primary = new LiteralNode(token_index_, Instance::ZoneHandle()); | 8275 primary = new LiteralNode(TokenPos(), Instance::ZoneHandle()); |
8253 ConsumeToken(); | 8276 ConsumeToken(); |
8254 } else if (CurrentToken() == Token::kLPAREN) { | 8277 } else if (CurrentToken() == Token::kLPAREN) { |
8255 ConsumeToken(); | 8278 ConsumeToken(); |
8256 const bool saved_mode = SetAllowFunctionLiterals(true); | 8279 const bool saved_mode = SetAllowFunctionLiterals(true); |
8257 primary = ParseExpr(kAllowConst); | 8280 primary = ParseExpr(kAllowConst); |
8258 SetAllowFunctionLiterals(saved_mode); | 8281 SetAllowFunctionLiterals(saved_mode); |
8259 ExpectToken(Token::kRPAREN); | 8282 ExpectToken(Token::kRPAREN); |
8260 } else if (CurrentToken() == Token::kDOUBLE) { | 8283 } else if (CurrentToken() == Token::kDOUBLE) { |
8261 Double& double_value = Double::ZoneHandle(CurrentDoubleLiteral()); | 8284 Double& double_value = Double::ZoneHandle(CurrentDoubleLiteral()); |
8262 if (double_value.IsNull()) { | 8285 if (double_value.IsNull()) { |
8263 ErrorMsg("invalid double literal"); | 8286 ErrorMsg("invalid double literal"); |
8264 } | 8287 } |
8265 primary = new LiteralNode(token_index_, double_value); | 8288 primary = new LiteralNode(TokenPos(), double_value); |
8266 ConsumeToken(); | 8289 ConsumeToken(); |
8267 } else if (CurrentToken() == Token::kSTRING) { | 8290 } else if (CurrentToken() == Token::kSTRING) { |
8268 primary = ParseStringLiteral(); | 8291 primary = ParseStringLiteral(); |
8269 } else if (CurrentToken() == Token::kNEW) { | 8292 } else if (CurrentToken() == Token::kNEW) { |
8270 primary = ParseNewOperator(); | 8293 primary = ParseNewOperator(); |
8271 } else if (CurrentToken() == Token::kCONST) { | 8294 } else if (CurrentToken() == Token::kCONST) { |
8272 if ((LookaheadToken(1) == Token::kLT) || | 8295 if ((LookaheadToken(1) == Token::kLT) || |
8273 (LookaheadToken(1) == Token::kLBRACK) || | 8296 (LookaheadToken(1) == Token::kLBRACK) || |
8274 (LookaheadToken(1) == Token::kINDEX) || | 8297 (LookaheadToken(1) == Token::kINDEX) || |
8275 (LookaheadToken(1) == Token::kLBRACE)) { | 8298 (LookaheadToken(1) == Token::kLBRACE)) { |
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
8310 } | 8333 } |
8311 | 8334 |
8312 | 8335 |
8313 // Evaluate expression in expr and return the value. The expression must | 8336 // Evaluate expression in expr and return the value. The expression must |
8314 // be a compile time constant. | 8337 // be a compile time constant. |
8315 const Instance& Parser::EvaluateConstExpr(AstNode* expr) { | 8338 const Instance& Parser::EvaluateConstExpr(AstNode* expr) { |
8316 if (expr->IsLiteralNode()) { | 8339 if (expr->IsLiteralNode()) { |
8317 return expr->AsLiteralNode()->literal(); | 8340 return expr->AsLiteralNode()->literal(); |
8318 } else { | 8341 } else { |
8319 ASSERT(expr->EvalConstExpr() != NULL); | 8342 ASSERT(expr->EvalConstExpr() != NULL); |
8320 ReturnNode* ret = new ReturnNode(expr->token_index(), expr); | 8343 ReturnNode* ret = new ReturnNode(expr->token_pos(), expr); |
8321 // Compile time constant expressions cannot reference anything from a | 8344 // Compile time constant expressions cannot reference anything from a |
8322 // local scope. | 8345 // local scope. |
8323 LocalScope* empty_scope = new LocalScope(NULL, 0, 0); | 8346 LocalScope* empty_scope = new LocalScope(NULL, 0, 0); |
8324 SequenceNode* seq = new SequenceNode(expr->token_index(), empty_scope); | 8347 SequenceNode* seq = new SequenceNode(expr->token_pos(), empty_scope); |
8325 seq->Add(ret); | 8348 seq->Add(ret); |
8326 | 8349 |
8327 Object& result = Object::Handle(Compiler::ExecuteOnce(seq)); | 8350 Object& result = Object::Handle(Compiler::ExecuteOnce(seq)); |
8328 if (result.IsError()) { | 8351 if (result.IsError()) { |
8329 // Propagate the compilation error. | 8352 // Propagate the compilation error. |
8330 Error& error = Error::Handle(); | 8353 Error& error = Error::Handle(); |
8331 error ^= result.raw(); | 8354 error ^= result.raw(); |
8332 Isolate::Current()->long_jump_base()->Jump(1, error); | 8355 Isolate::Current()->long_jump_base()->Jump(1, error); |
8333 UNREACHABLE(); | 8356 UNREACHABLE(); |
8334 } | 8357 } |
(...skipping 252 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
8587 void Parser::SkipQualIdent() { | 8610 void Parser::SkipQualIdent() { |
8588 ASSERT(IsIdentifier()); | 8611 ASSERT(IsIdentifier()); |
8589 ConsumeToken(); | 8612 ConsumeToken(); |
8590 if (CurrentToken() == Token::kPERIOD) { | 8613 if (CurrentToken() == Token::kPERIOD) { |
8591 ConsumeToken(); // Consume the kPERIOD token. | 8614 ConsumeToken(); // Consume the kPERIOD token. |
8592 ExpectIdentifier("identifier expected after '.'"); | 8615 ExpectIdentifier("identifier expected after '.'"); |
8593 } | 8616 } |
8594 } | 8617 } |
8595 | 8618 |
8596 } // namespace dart | 8619 } // namespace dart |
OLD | NEW |