| 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 #include "vm/flags.h" | 6 #include "vm/flags.h" |
| 7 | 7 |
| 8 #ifndef DART_PRECOMPILED | 8 #ifndef DART_PRECOMPILED |
| 9 | 9 |
| 10 #include "lib/invocation_mirror.h" | 10 #include "lib/invocation_mirror.h" |
| (...skipping 431 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 442 | 442 |
| 443 | 443 |
| 444 void Parser::set_current_class(const Class& value) { | 444 void Parser::set_current_class(const Class& value) { |
| 445 current_class_ = value.raw(); | 445 current_class_ = value.raw(); |
| 446 } | 446 } |
| 447 | 447 |
| 448 | 448 |
| 449 void Parser::SetPosition(intptr_t position) { | 449 void Parser::SetPosition(intptr_t position) { |
| 450 tokens_iterator_.SetCurrentPosition(position); | 450 tokens_iterator_.SetCurrentPosition(position); |
| 451 token_kind_ = Token::kILLEGAL; | 451 token_kind_ = Token::kILLEGAL; |
| 452 prev_token_pos_ = position; |
| 452 } | 453 } |
| 453 | 454 |
| 454 | 455 |
| 455 void Parser::ParseCompilationUnit(const Library& library, | 456 void Parser::ParseCompilationUnit(const Library& library, |
| 456 const Script& script) { | 457 const Script& script) { |
| 457 Thread* thread = Thread::Current(); | 458 Thread* thread = Thread::Current(); |
| 458 ASSERT(thread->long_jump_base()->IsSafeToJump()); | 459 ASSERT(thread->long_jump_base()->IsSafeToJump()); |
| 459 CSTAT_TIMER_SCOPE(thread, parser_timer); | 460 CSTAT_TIMER_SCOPE(thread, parser_timer); |
| 460 VMTagScope tagScope(thread, VMTag::kCompileTopLevelTagId); | 461 VMTagScope tagScope(thread, VMTag::kCompileTopLevelTagId); |
| 461 TimelineDurationScope tds(thread, | 462 TimelineDurationScope tds(thread, |
| (...skipping 501 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 963 // Fall-through: Handle non-implicit closures. | 964 // Fall-through: Handle non-implicit closures. |
| 964 case RawFunction::kRegularFunction: | 965 case RawFunction::kRegularFunction: |
| 965 case RawFunction::kGetterFunction: | 966 case RawFunction::kGetterFunction: |
| 966 case RawFunction::kSetterFunction: | 967 case RawFunction::kSetterFunction: |
| 967 case RawFunction::kConstructor: | 968 case RawFunction::kConstructor: |
| 968 // The call to a redirecting factory is redirected. | 969 // The call to a redirecting factory is redirected. |
| 969 ASSERT(!func.IsRedirectingFactory()); | 970 ASSERT(!func.IsRedirectingFactory()); |
| 970 if (!func.IsImplicitConstructor()) { | 971 if (!func.IsImplicitConstructor()) { |
| 971 parser.SkipFunctionPreamble(); | 972 parser.SkipFunctionPreamble(); |
| 972 } | 973 } |
| 973 node_sequence = parser.ParseFunc(func); | 974 node_sequence = parser.ParseFunc(func, false); |
| 974 break; | 975 break; |
| 975 case RawFunction::kImplicitGetter: | 976 case RawFunction::kImplicitGetter: |
| 976 ASSERT(!func.is_static()); | 977 ASSERT(!func.is_static()); |
| 977 node_sequence = parser.ParseInstanceGetter(func); | 978 node_sequence = parser.ParseInstanceGetter(func); |
| 978 break; | 979 break; |
| 979 case RawFunction::kImplicitSetter: | 980 case RawFunction::kImplicitSetter: |
| 980 ASSERT(!func.is_static()); | 981 ASSERT(!func.is_static()); |
| 981 node_sequence = parser.ParseInstanceSetter(func); | 982 node_sequence = parser.ParseInstanceSetter(func); |
| 982 break; | 983 break; |
| 983 case RawFunction::kImplicitStaticFinalGetter: | 984 case RawFunction::kImplicitStaticFinalGetter: |
| (...skipping 744 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1728 unexpected_token_found = true; | 1729 unexpected_token_found = true; |
| 1729 break; | 1730 break; |
| 1730 default: | 1731 default: |
| 1731 // nothing. | 1732 // nothing. |
| 1732 break; | 1733 break; |
| 1733 } | 1734 } |
| 1734 } while (!token_stack.is_empty() && is_match && !unexpected_token_found); | 1735 } while (!token_stack.is_empty() && is_match && !unexpected_token_found); |
| 1735 if (!is_match) { | 1736 if (!is_match) { |
| 1736 const Error& error = Error::Handle( | 1737 const Error& error = Error::Handle( |
| 1737 LanguageError::NewFormatted(Error::Handle(), | 1738 LanguageError::NewFormatted(Error::Handle(), |
| 1738 script_, opening_pos, Report::kWarning, Heap::kNew, | 1739 script_, opening_pos, Report::AtLocation, |
| 1740 Report::kWarning, Heap::kNew, |
| 1739 "unbalanced '%s' opens here", Token::Str(opening_token))); | 1741 "unbalanced '%s' opens here", Token::Str(opening_token))); |
| 1740 ReportErrors(error, script_, token_pos, | 1742 ReportErrors(error, script_, token_pos, |
| 1741 "unbalanced '%s'", Token::Str(token)); | 1743 "unbalanced '%s'", Token::Str(token)); |
| 1742 } else if (unexpected_token_found) { | 1744 } else if (unexpected_token_found) { |
| 1743 ReportError(start_pos, "unterminated '%s'", Token::Str(opening_token)); | 1745 ReportError(start_pos, "unterminated '%s'", Token::Str(opening_token)); |
| 1744 } | 1746 } |
| 1745 } | 1747 } |
| 1746 | 1748 |
| 1747 | 1749 |
| 1748 | 1750 |
| (...skipping 1386 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3135 } | 3137 } |
| 3136 current_block_->statements->Add(new ReturnNode(func.end_token_pos())); | 3138 current_block_->statements->Add(new ReturnNode(func.end_token_pos())); |
| 3137 SequenceNode* statements = CloseBlock(); | 3139 SequenceNode* statements = CloseBlock(); |
| 3138 return statements; | 3140 return statements; |
| 3139 } | 3141 } |
| 3140 | 3142 |
| 3141 | 3143 |
| 3142 // Parser is at the opening parenthesis of the formal parameter | 3144 // Parser is at the opening parenthesis of the formal parameter |
| 3143 // declaration of the function or constructor. | 3145 // declaration of the function or constructor. |
| 3144 // Parse the formal parameters and code. | 3146 // Parse the formal parameters and code. |
| 3145 SequenceNode* Parser::ParseFunc(const Function& func) { | 3147 SequenceNode* Parser::ParseFunc(const Function& func, bool check_semicolon) { |
| 3146 TRACE_PARSER("ParseFunc"); | 3148 TRACE_PARSER("ParseFunc"); |
| 3147 Function& saved_innermost_function = | 3149 Function& saved_innermost_function = |
| 3148 Function::Handle(Z, innermost_function().raw()); | 3150 Function::Handle(Z, innermost_function().raw()); |
| 3149 innermost_function_ = func.raw(); | 3151 innermost_function_ = func.raw(); |
| 3150 | 3152 |
| 3151 // Save current try index. Try index starts at zero for each function. | 3153 // Save current try index. Try index starts at zero for each function. |
| 3152 intptr_t saved_try_index = last_used_try_index_; | 3154 intptr_t saved_try_index = last_used_try_index_; |
| 3153 last_used_try_index_ = 0; | 3155 last_used_try_index_ = 0; |
| 3154 | 3156 |
| 3155 // In case of nested async functions we also need to save the scope where | 3157 // In case of nested async functions we also need to save the scope where |
| (...skipping 186 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3342 const Class& owner = Class::Handle(Z, func.Owner()); | 3344 const Class& owner = Class::Handle(Z, func.Owner()); |
| 3343 if (!owner.IsObjectClass()) { | 3345 if (!owner.IsObjectClass()) { |
| 3344 AddEqualityNullCheck(); | 3346 AddEqualityNullCheck(); |
| 3345 } | 3347 } |
| 3346 } | 3348 } |
| 3347 const intptr_t expr_pos = TokenPos(); | 3349 const intptr_t expr_pos = TokenPos(); |
| 3348 AstNode* expr = ParseAwaitableExpr(kAllowConst, kConsumeCascades, NULL); | 3350 AstNode* expr = ParseAwaitableExpr(kAllowConst, kConsumeCascades, NULL); |
| 3349 ASSERT(expr != NULL); | 3351 ASSERT(expr != NULL); |
| 3350 current_block_->statements->Add(new ReturnNode(expr_pos, expr)); | 3352 current_block_->statements->Add(new ReturnNode(expr_pos, expr)); |
| 3351 end_token_pos = TokenPos(); | 3353 end_token_pos = TokenPos(); |
| 3354 if (check_semicolon) { |
| 3355 ExpectSemicolon(); |
| 3356 } |
| 3352 } else if (IsSymbol(Symbols::Native())) { | 3357 } else if (IsSymbol(Symbols::Native())) { |
| 3353 if (String::Handle(Z, func.name()).Equals( | 3358 if (String::Handle(Z, func.name()).Equals( |
| 3354 Symbols::EqualOperator())) { | 3359 Symbols::EqualOperator())) { |
| 3355 const Class& owner = Class::Handle(Z, func.Owner()); | 3360 const Class& owner = Class::Handle(Z, func.Owner()); |
| 3356 if (!owner.IsObjectClass()) { | 3361 if (!owner.IsObjectClass()) { |
| 3357 AddEqualityNullCheck(); | 3362 AddEqualityNullCheck(); |
| 3358 } | 3363 } |
| 3359 } | 3364 } |
| 3360 ParseNativeFunctionBlock(¶ms, func); | 3365 ParseNativeFunctionBlock(¶ms, func); |
| 3361 end_token_pos = TokenPos(); | 3366 end_token_pos = TokenPos(); |
| (...skipping 3862 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 7224 // with the formal parameter types and names. | 7229 // with the formal parameter types and names. |
| 7225 void Parser::AddFormalParamsToFunction(const ParamList* params, | 7230 void Parser::AddFormalParamsToFunction(const ParamList* params, |
| 7226 const Function& func) { | 7231 const Function& func) { |
| 7227 ASSERT((params != NULL) && (params->parameters != NULL)); | 7232 ASSERT((params != NULL) && (params->parameters != NULL)); |
| 7228 ASSERT((params->num_optional_parameters > 0) == | 7233 ASSERT((params->num_optional_parameters > 0) == |
| 7229 (params->has_optional_positional_parameters || | 7234 (params->has_optional_positional_parameters || |
| 7230 params->has_optional_named_parameters)); | 7235 params->has_optional_named_parameters)); |
| 7231 if (!Utils::IsInt(16, params->num_fixed_parameters) || | 7236 if (!Utils::IsInt(16, params->num_fixed_parameters) || |
| 7232 !Utils::IsInt(16, params->num_optional_parameters)) { | 7237 !Utils::IsInt(16, params->num_optional_parameters)) { |
| 7233 const Script& script = Script::Handle(Class::Handle(func.Owner()).script()); | 7238 const Script& script = Script::Handle(Class::Handle(func.Owner()).script()); |
| 7234 Report::MessageF(Report::kError, script, func.token_pos(), | 7239 Report::MessageF(Report::kError, |
| 7240 script, func.token_pos(), Report::AtLocation, |
| 7235 "too many formal parameters"); | 7241 "too many formal parameters"); |
| 7236 } | 7242 } |
| 7237 func.set_num_fixed_parameters(params->num_fixed_parameters); | 7243 func.set_num_fixed_parameters(params->num_fixed_parameters); |
| 7238 func.SetNumOptionalParameters(params->num_optional_parameters, | 7244 func.SetNumOptionalParameters(params->num_optional_parameters, |
| 7239 params->has_optional_positional_parameters); | 7245 params->has_optional_positional_parameters); |
| 7240 const int num_parameters = params->parameters->length(); | 7246 const int num_parameters = params->parameters->length(); |
| 7241 ASSERT(num_parameters == func.NumParameters()); | 7247 ASSERT(num_parameters == func.NumParameters()); |
| 7242 func.set_parameter_types(Array::Handle(Array::New(num_parameters, | 7248 func.set_parameter_types(Array::Handle(Array::New(num_parameters, |
| 7243 Heap::kOld))); | 7249 Heap::kOld))); |
| 7244 func.set_parameter_names(Array::Handle(Array::New(num_parameters, | 7250 func.set_parameter_names(Array::Handle(Array::New(num_parameters, |
| (...skipping 359 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 7604 true); | 7610 true); |
| 7605 ASSERT(existing_var != NULL); | 7611 ASSERT(existing_var != NULL); |
| 7606 // Use before define cases have already been detected and reported above. | 7612 // Use before define cases have already been detected and reported above. |
| 7607 ASSERT(existing_var->owner() == current_block_->scope); | 7613 ASSERT(existing_var->owner() == current_block_->scope); |
| 7608 ReportError(function_pos, "identifier '%s' already defined", | 7614 ReportError(function_pos, "identifier '%s' already defined", |
| 7609 function_variable->name().ToCString()); | 7615 function_variable->name().ToCString()); |
| 7610 } | 7616 } |
| 7611 } | 7617 } |
| 7612 | 7618 |
| 7613 // Parse the local function. | 7619 // Parse the local function. |
| 7614 SequenceNode* statements = Parser::ParseFunc(function); | 7620 SequenceNode* statements = Parser::ParseFunc(function, !is_literal); |
| 7615 INC_STAT(thread(), num_functions_parsed, 1); | 7621 INC_STAT(thread(), num_functions_parsed, 1); |
| 7616 | 7622 |
| 7617 // Now that the local function has formal parameters, lookup the signature | 7623 // Now that the local function has formal parameters, lookup the signature |
| 7618 // class in the current library (but not in its imports) and only create a new | 7624 // class in the current library (but not in its imports) and only create a new |
| 7619 // canonical signature class if it does not exist yet. | 7625 // canonical signature class if it does not exist yet. |
| 7620 const String& signature = String::Handle(Z, function.Signature()); | 7626 const String& signature = String::Handle(Z, function.Signature()); |
| 7621 Class& signature_class = Class::ZoneHandle(Z); | 7627 Class& signature_class = Class::ZoneHandle(Z); |
| 7622 if (!is_new_closure) { | 7628 if (!is_new_closure) { |
| 7623 signature_class = function.signature_class(); | 7629 signature_class = function.signature_class(); |
| 7624 } | 7630 } |
| (...skipping 2466 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 10091 va_start(args, format); | 10097 va_start(args, format); |
| 10092 Report::LongJumpV(prev_error, script, token_pos, format, args); | 10098 Report::LongJumpV(prev_error, script, token_pos, format, args); |
| 10093 va_end(args); | 10099 va_end(args); |
| 10094 UNREACHABLE(); | 10100 UNREACHABLE(); |
| 10095 } | 10101 } |
| 10096 | 10102 |
| 10097 | 10103 |
| 10098 void Parser::ReportError(intptr_t token_pos, const char* format, ...) const { | 10104 void Parser::ReportError(intptr_t token_pos, const char* format, ...) const { |
| 10099 va_list args; | 10105 va_list args; |
| 10100 va_start(args, format); | 10106 va_start(args, format); |
| 10101 Report::MessageV(Report::kError, script_, token_pos, format, args); | 10107 Report::MessageV(Report::kError, |
| 10108 script_, token_pos, Report::AtLocation, format, args); |
| 10102 va_end(args); | 10109 va_end(args); |
| 10103 UNREACHABLE(); | 10110 UNREACHABLE(); |
| 10104 } | 10111 } |
| 10112 |
| 10113 |
| 10114 void Parser::ReportErrorBefore(const char* format, ...) { |
| 10115 va_list args; |
| 10116 va_start(args, format); |
| 10117 Report::MessageV(Report::kError, |
| 10118 script_, PrevTokenPos(), Report::AfterLocation, |
| 10119 format, args); |
| 10120 va_end(args); |
| 10121 UNREACHABLE(); |
| 10122 } |
| 10105 | 10123 |
| 10106 | 10124 |
| 10107 void Parser::ReportError(const char* format, ...) const { | 10125 void Parser::ReportError(const char* format, ...) const { |
| 10108 va_list args; | 10126 va_list args; |
| 10109 va_start(args, format); | 10127 va_start(args, format); |
| 10110 Report::MessageV(Report::kError, script_, TokenPos(), format, args); | 10128 Report::MessageV(Report::kError, |
| 10129 script_, TokenPos(), Report::AtLocation, format, args); |
| 10111 va_end(args); | 10130 va_end(args); |
| 10112 UNREACHABLE(); | 10131 UNREACHABLE(); |
| 10113 } | 10132 } |
| 10114 | 10133 |
| 10115 | 10134 |
| 10116 void Parser::ReportWarning(intptr_t token_pos, const char* format, ...) const { | 10135 void Parser::ReportWarning(intptr_t token_pos, const char* format, ...) const { |
| 10117 va_list args; | 10136 va_list args; |
| 10118 va_start(args, format); | 10137 va_start(args, format); |
| 10119 Report::MessageV(Report::kWarning, script_, token_pos, format, args); | 10138 Report::MessageV(Report::kWarning, |
| 10139 script_, token_pos, Report::AtLocation, format, args); |
| 10120 va_end(args); | 10140 va_end(args); |
| 10121 } | 10141 } |
| 10122 | 10142 |
| 10123 | 10143 |
| 10124 void Parser::ReportWarning(const char* format, ...) const { | 10144 void Parser::ReportWarning(const char* format, ...) const { |
| 10125 va_list args; | 10145 va_list args; |
| 10126 va_start(args, format); | 10146 va_start(args, format); |
| 10127 Report::MessageV(Report::kWarning, script_, TokenPos(), format, args); | 10147 Report::MessageV(Report::kWarning, |
| 10148 script_, TokenPos(), Report::AtLocation, format, args); |
| 10128 va_end(args); | 10149 va_end(args); |
| 10129 } | 10150 } |
| 10130 | 10151 |
| 10131 | 10152 |
| 10132 void Parser::CheckToken(Token::Kind token_expected, const char* msg) { | 10153 void Parser::CheckToken(Token::Kind token_expected, const char* msg) { |
| 10133 if (CurrentToken() != token_expected) { | 10154 if (CurrentToken() != token_expected) { |
| 10134 if (msg != NULL) { | 10155 if (msg != NULL) { |
| 10135 ReportError("%s", msg); | 10156 ReportError("%s", msg); |
| 10136 } else { | 10157 } else { |
| 10137 ReportError("'%s' expected", Token::Str(token_expected)); | 10158 ReportError("'%s' expected", Token::Str(token_expected)); |
| 10138 } | 10159 } |
| 10139 } | 10160 } |
| 10140 } | 10161 } |
| 10141 | 10162 |
| 10142 | 10163 |
| 10143 void Parser::ExpectToken(Token::Kind token_expected) { | 10164 void Parser::ExpectToken(Token::Kind token_expected) { |
| 10144 if (CurrentToken() != token_expected) { | 10165 if (CurrentToken() != token_expected) { |
| 10145 ReportError("'%s' expected", Token::Str(token_expected)); | 10166 ReportError("'%s' expected", Token::Str(token_expected)); |
| 10146 } | 10167 } |
| 10147 ConsumeToken(); | 10168 ConsumeToken(); |
| 10148 } | 10169 } |
| 10149 | 10170 |
| 10150 | 10171 |
| 10151 void Parser::ExpectSemicolon() { | 10172 void Parser::ExpectSemicolon() { |
| 10152 if (CurrentToken() != Token::kSEMICOLON) { | 10173 if (CurrentToken() != Token::kSEMICOLON) { |
| 10153 ReportError("semicolon expected"); | 10174 ReportErrorBefore("semicolon expected"); |
| 10154 } | 10175 } |
| 10155 ConsumeToken(); | 10176 ConsumeToken(); |
| 10156 } | 10177 } |
| 10157 | 10178 |
| 10158 | 10179 |
| 10159 void Parser::UnexpectedToken() { | 10180 void Parser::UnexpectedToken() { |
| 10160 ReportError("unexpected token '%s'", | 10181 ReportError("unexpected token '%s'", |
| 10161 CurrentToken() == Token::kIDENT ? | 10182 CurrentToken() == Token::kIDENT ? |
| 10162 CurrentLiteral()->ToCString() : Token::Str(CurrentToken())); | 10183 CurrentLiteral()->ToCString() : Token::Str(CurrentToken())); |
| 10163 } | 10184 } |
| (...skipping 4232 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 14396 const ArgumentListNode& function_args, | 14417 const ArgumentListNode& function_args, |
| 14397 const LocalVariable* temp_for_last_arg, | 14418 const LocalVariable* temp_for_last_arg, |
| 14398 bool is_super_invocation) { | 14419 bool is_super_invocation) { |
| 14399 UNREACHABLE(); | 14420 UNREACHABLE(); |
| 14400 return NULL; | 14421 return NULL; |
| 14401 } | 14422 } |
| 14402 | 14423 |
| 14403 } // namespace dart | 14424 } // namespace dart |
| 14404 | 14425 |
| 14405 #endif // DART_PRECOMPILED | 14426 #endif // DART_PRECOMPILED |
| OLD | NEW |