| 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 |