| 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 "lib/invocation_mirror.h" | 7 #include "lib/invocation_mirror.h" |
| 8 #include "platform/utils.h" | 8 #include "platform/utils.h" |
| 9 #include "vm/ast_transformer.h" | 9 #include "vm/ast_transformer.h" |
| 10 #include "vm/bootstrap.h" | 10 #include "vm/bootstrap.h" |
| (...skipping 81 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 92 int TraceParser::indent_ = 0; | 92 int TraceParser::indent_ = 0; |
| 93 | 93 |
| 94 #define TRACE_PARSER(s) \ | 94 #define TRACE_PARSER(s) \ |
| 95 TraceParser __p__(this->TokenPos(), this->script_, s) | 95 TraceParser __p__(this->TokenPos(), this->script_, s) |
| 96 | 96 |
| 97 #else // not DEBUG | 97 #else // not DEBUG |
| 98 #define TRACE_PARSER(s) | 98 #define TRACE_PARSER(s) |
| 99 #endif // DEBUG | 99 #endif // DEBUG |
| 100 | 100 |
| 101 | 101 |
| 102 class BoolScope : public ValueObject { |
| 103 public: |
| 104 BoolScope(bool* addr, bool new_value) : _addr(addr), _saved_value(*addr) { |
| 105 *_addr = new_value; |
| 106 } |
| 107 ~BoolScope() { |
| 108 *_addr = _saved_value; |
| 109 } |
| 110 |
| 111 private: |
| 112 bool* _addr; |
| 113 bool _saved_value; |
| 114 }; |
| 115 |
| 116 |
| 102 static RawTypeArguments* NewTypeArguments(const GrowableObjectArray& objs) { | 117 static RawTypeArguments* NewTypeArguments(const GrowableObjectArray& objs) { |
| 103 const TypeArguments& a = | 118 const TypeArguments& a = |
| 104 TypeArguments::Handle(TypeArguments::New(objs.Length())); | 119 TypeArguments::Handle(TypeArguments::New(objs.Length())); |
| 105 AbstractType& type = AbstractType::Handle(); | 120 AbstractType& type = AbstractType::Handle(); |
| 106 for (int i = 0; i < objs.Length(); i++) { | 121 for (int i = 0; i < objs.Length(); i++) { |
| 107 type ^= objs.At(i); | 122 type ^= objs.At(i); |
| 108 a.SetTypeAt(i, type); | 123 a.SetTypeAt(i, type); |
| 109 } | 124 } |
| 110 // Cannot canonicalize TypeArgument yet as its types may not have been | 125 // Cannot canonicalize TypeArgument yet as its types may not have been |
| 111 // finalized yet. | 126 // finalized yet. |
| (...skipping 2936 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3048 | 3063 |
| 3049 OpenBlock(); // Open a nested scope for the outermost function block. | 3064 OpenBlock(); // Open a nested scope for the outermost function block. |
| 3050 | 3065 |
| 3051 Function& async_closure = Function::ZoneHandle(I); | 3066 Function& async_closure = Function::ZoneHandle(I); |
| 3052 if (func.IsAsyncFunction() && !func.is_async_closure()) { | 3067 if (func.IsAsyncFunction() && !func.is_async_closure()) { |
| 3053 async_closure = OpenAsyncFunction(formal_params_pos); | 3068 async_closure = OpenAsyncFunction(formal_params_pos); |
| 3054 } else if (func.is_async_closure()) { | 3069 } else if (func.is_async_closure()) { |
| 3055 OpenAsyncClosure(); | 3070 OpenAsyncClosure(); |
| 3056 } | 3071 } |
| 3057 | 3072 |
| 3058 bool saved_await_is_keyword = await_is_keyword_; | 3073 BoolScope allow_await(&this->await_is_keyword_, |
| 3059 await_is_keyword_ = func.IsAsyncFunction() || func.is_async_closure(); | 3074 func.IsAsyncFunction() || func.is_async_closure()); |
| 3060 | |
| 3061 intptr_t end_token_pos = 0; | 3075 intptr_t end_token_pos = 0; |
| 3062 if (CurrentToken() == Token::kLBRACE) { | 3076 if (CurrentToken() == Token::kLBRACE) { |
| 3063 ConsumeToken(); | 3077 ConsumeToken(); |
| 3064 if (String::Handle(I, func.name()).Equals(Symbols::EqualOperator())) { | 3078 if (String::Handle(I, func.name()).Equals(Symbols::EqualOperator())) { |
| 3065 const Class& owner = Class::Handle(I, func.Owner()); | 3079 const Class& owner = Class::Handle(I, func.Owner()); |
| 3066 if (!owner.IsObjectClass()) { | 3080 if (!owner.IsObjectClass()) { |
| 3067 AddEqualityNullCheck(); | 3081 AddEqualityNullCheck(); |
| 3068 } | 3082 } |
| 3069 } | 3083 } |
| 3070 ParseStatementSequence(); | 3084 ParseStatementSequence(); |
| 3071 end_token_pos = TokenPos(); | 3085 end_token_pos = TokenPos(); |
| 3072 ExpectToken(Token::kRBRACE); | 3086 ExpectToken(Token::kRBRACE); |
| 3073 } else if (CurrentToken() == Token::kARROW) { | 3087 } else if (CurrentToken() == Token::kARROW) { |
| 3074 ConsumeToken(); | 3088 ConsumeToken(); |
| 3075 if (String::Handle(I, func.name()).Equals( | 3089 if (String::Handle(I, func.name()).Equals( |
| 3076 Symbols::EqualOperator())) { | 3090 Symbols::EqualOperator())) { |
| 3077 const Class& owner = Class::Handle(I, func.Owner()); | 3091 const Class& owner = Class::Handle(I, func.Owner()); |
| 3078 if (!owner.IsObjectClass()) { | 3092 if (!owner.IsObjectClass()) { |
| 3079 AddEqualityNullCheck(); | 3093 AddEqualityNullCheck(); |
| 3080 } | 3094 } |
| 3081 } | 3095 } |
| 3082 const intptr_t expr_pos = TokenPos(); | 3096 const intptr_t expr_pos = TokenPos(); |
| 3083 AstNode* expr = ParseExpr(kAllowConst, kConsumeCascades); | 3097 AstNode* expr = ParseAwaitableExpr(kAllowConst, kConsumeCascades, NULL); |
| 3084 ASSERT(expr != NULL); | 3098 ASSERT(expr != NULL); |
| 3085 current_block_->statements->Add(new ReturnNode(expr_pos, expr)); | 3099 current_block_->statements->Add(new ReturnNode(expr_pos, expr)); |
| 3086 end_token_pos = TokenPos(); | 3100 end_token_pos = TokenPos(); |
| 3087 } else if (IsLiteral("native")) { | 3101 } else if (IsLiteral("native")) { |
| 3088 if (String::Handle(I, func.name()).Equals( | 3102 if (String::Handle(I, func.name()).Equals( |
| 3089 Symbols::EqualOperator())) { | 3103 Symbols::EqualOperator())) { |
| 3090 const Class& owner = Class::Handle(I, func.Owner()); | 3104 const Class& owner = Class::Handle(I, func.Owner()); |
| 3091 if (!owner.IsObjectClass()) { | 3105 if (!owner.IsObjectClass()) { |
| 3092 AddEqualityNullCheck(); | 3106 AddEqualityNullCheck(); |
| 3093 } | 3107 } |
| (...skipping 25 matching lines...) Expand all Loading... |
| 3119 SequenceNode* body = CloseBlock(); | 3133 SequenceNode* body = CloseBlock(); |
| 3120 if (func.IsAsyncFunction() && !func.is_async_closure()) { | 3134 if (func.IsAsyncFunction() && !func.is_async_closure()) { |
| 3121 body = CloseAsyncFunction(async_closure, body); | 3135 body = CloseAsyncFunction(async_closure, body); |
| 3122 async_closure.set_end_token_pos(end_token_pos); | 3136 async_closure.set_end_token_pos(end_token_pos); |
| 3123 } else if (func.is_async_closure()) { | 3137 } else if (func.is_async_closure()) { |
| 3124 body = CloseAsyncClosure(body); | 3138 body = CloseAsyncClosure(body); |
| 3125 } | 3139 } |
| 3126 current_block_->statements->Add(body); | 3140 current_block_->statements->Add(body); |
| 3127 innermost_function_ = saved_innermost_function.raw(); | 3141 innermost_function_ = saved_innermost_function.raw(); |
| 3128 last_used_try_index_ = saved_try_index; | 3142 last_used_try_index_ = saved_try_index; |
| 3129 await_is_keyword_ = saved_await_is_keyword; | |
| 3130 async_temp_scope_ = saved_async_temp_scope; | 3143 async_temp_scope_ = saved_async_temp_scope; |
| 3131 parsed_function()->set_saved_try_ctx(saved_saved_try_ctx); | 3144 parsed_function()->set_saved_try_ctx(saved_saved_try_ctx); |
| 3132 parsed_function()->set_async_saved_try_ctx_name( | 3145 parsed_function()->set_async_saved_try_ctx_name( |
| 3133 saved_async_saved_try_ctx_name); | 3146 saved_async_saved_try_ctx_name); |
| 3134 return CloseBlock(); | 3147 return CloseBlock(); |
| 3135 } | 3148 } |
| 3136 | 3149 |
| 3137 | 3150 |
| 3138 void Parser::AddEqualityNullCheck() { | 3151 void Parser::AddEqualityNullCheck() { |
| 3139 AstNode* argument = | 3152 AstNode* argument = |
| (...skipping 335 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3475 if (method->redirect_name != NULL) { | 3488 if (method->redirect_name != NULL) { |
| 3476 ReportError(method->name_pos, | 3489 ReportError(method->name_pos, |
| 3477 "Constructor with redirection may not have a function body"); | 3490 "Constructor with redirection may not have a function body"); |
| 3478 } | 3491 } |
| 3479 if (CurrentToken() == Token::kLBRACE) { | 3492 if (CurrentToken() == Token::kLBRACE) { |
| 3480 SkipBlock(); | 3493 SkipBlock(); |
| 3481 method_end_pos = TokenPos(); | 3494 method_end_pos = TokenPos(); |
| 3482 ExpectToken(Token::kRBRACE); | 3495 ExpectToken(Token::kRBRACE); |
| 3483 } else { | 3496 } else { |
| 3484 ConsumeToken(); | 3497 ConsumeToken(); |
| 3498 BoolScope allow_await(&this->await_is_keyword_, |
| 3499 async_modifier != RawFunction::kNoModifier); |
| 3485 SkipExpr(); | 3500 SkipExpr(); |
| 3486 method_end_pos = TokenPos(); | 3501 method_end_pos = TokenPos(); |
| 3487 ExpectSemicolon(); | 3502 ExpectSemicolon(); |
| 3488 } | 3503 } |
| 3489 } else if (IsLiteral("native")) { | 3504 } else if (IsLiteral("native")) { |
| 3490 if (method->has_abstract) { | 3505 if (method->has_abstract) { |
| 3491 ReportError(method->name_pos, | 3506 ReportError(method->name_pos, |
| 3492 "abstract method '%s' may not have a function body", | 3507 "abstract method '%s' may not have a function body", |
| 3493 method->name->ToCString()); | 3508 method->name->ToCString()); |
| 3494 } else if (method->IsConstructor() && method->has_const) { | 3509 } else if (method->IsConstructor() && method->has_const) { |
| (...skipping 1654 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 5149 bool is_native = false; | 5164 bool is_native = false; |
| 5150 if (is_external) { | 5165 if (is_external) { |
| 5151 function_end_pos = TokenPos(); | 5166 function_end_pos = TokenPos(); |
| 5152 ExpectSemicolon(); | 5167 ExpectSemicolon(); |
| 5153 } else if (CurrentToken() == Token::kLBRACE) { | 5168 } else if (CurrentToken() == Token::kLBRACE) { |
| 5154 SkipBlock(); | 5169 SkipBlock(); |
| 5155 function_end_pos = TokenPos(); | 5170 function_end_pos = TokenPos(); |
| 5156 ExpectToken(Token::kRBRACE); | 5171 ExpectToken(Token::kRBRACE); |
| 5157 } else if (CurrentToken() == Token::kARROW) { | 5172 } else if (CurrentToken() == Token::kARROW) { |
| 5158 ConsumeToken(); | 5173 ConsumeToken(); |
| 5174 BoolScope allow_await(&this->await_is_keyword_, |
| 5175 func_modifier != RawFunction::kNoModifier); |
| 5159 SkipExpr(); | 5176 SkipExpr(); |
| 5160 function_end_pos = TokenPos(); | 5177 function_end_pos = TokenPos(); |
| 5161 ExpectSemicolon(); | 5178 ExpectSemicolon(); |
| 5162 } else if (IsLiteral("native")) { | 5179 } else if (IsLiteral("native")) { |
| 5163 ParseNativeDeclaration(); | 5180 ParseNativeDeclaration(); |
| 5164 function_end_pos = TokenPos(); | 5181 function_end_pos = TokenPos(); |
| 5165 ExpectSemicolon(); | 5182 ExpectSemicolon(); |
| 5166 is_native = true; | 5183 is_native = true; |
| 5167 } else { | 5184 } else { |
| 5168 ReportError("function block expected"); | 5185 ReportError("function block expected"); |
| (...skipping 6638 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 11807 SkipType(true); | 11824 SkipType(true); |
| 11808 } | 11825 } |
| 11809 ExpectIdentifier("function name expected"); | 11826 ExpectIdentifier("function name expected"); |
| 11810 } | 11827 } |
| 11811 if (CurrentToken() == Token::kLPAREN) { | 11828 if (CurrentToken() == Token::kLPAREN) { |
| 11812 const bool allow_explicit_default_values = true; | 11829 const bool allow_explicit_default_values = true; |
| 11813 ParamList params; | 11830 ParamList params; |
| 11814 params.skipped = true; | 11831 params.skipped = true; |
| 11815 ParseFormalParameterList(allow_explicit_default_values, false, ¶ms); | 11832 ParseFormalParameterList(allow_explicit_default_values, false, ¶ms); |
| 11816 } | 11833 } |
| 11817 ParseFunctionModifier(); | 11834 RawFunction::AsyncModifier async_modifier = ParseFunctionModifier(); |
| 11835 BoolScope allow_await(&this->await_is_keyword_, |
| 11836 async_modifier != RawFunction::kNoModifier); |
| 11818 if (CurrentToken() == Token::kLBRACE) { | 11837 if (CurrentToken() == Token::kLBRACE) { |
| 11819 SkipBlock(); | 11838 SkipBlock(); |
| 11820 ExpectToken(Token::kRBRACE); | 11839 ExpectToken(Token::kRBRACE); |
| 11821 } else if (CurrentToken() == Token::kARROW) { | 11840 } else if (CurrentToken() == Token::kARROW) { |
| 11822 ConsumeToken(); | 11841 ConsumeToken(); |
| 11823 SkipExpr(); | 11842 SkipExpr(); |
| 11824 } | 11843 } |
| 11825 } | 11844 } |
| 11826 | 11845 |
| 11827 | 11846 |
| (...skipping 226 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 12054 SkipPrimary(); | 12073 SkipPrimary(); |
| 12055 SkipSelectors(); | 12074 SkipSelectors(); |
| 12056 if (IsIncrementOperator(CurrentToken())) { | 12075 if (IsIncrementOperator(CurrentToken())) { |
| 12057 ConsumeToken(); | 12076 ConsumeToken(); |
| 12058 } | 12077 } |
| 12059 } | 12078 } |
| 12060 | 12079 |
| 12061 | 12080 |
| 12062 void Parser::SkipUnaryExpr() { | 12081 void Parser::SkipUnaryExpr() { |
| 12063 if (IsPrefixOperator(CurrentToken()) || | 12082 if (IsPrefixOperator(CurrentToken()) || |
| 12064 IsIncrementOperator(CurrentToken())) { | 12083 IsIncrementOperator(CurrentToken()) || |
| 12084 IsAwaitKeyword()) { |
| 12065 ConsumeToken(); | 12085 ConsumeToken(); |
| 12066 SkipUnaryExpr(); | 12086 SkipUnaryExpr(); |
| 12067 } else { | 12087 } else { |
| 12068 SkipPostfixExpr(); | 12088 SkipPostfixExpr(); |
| 12069 } | 12089 } |
| 12070 } | 12090 } |
| 12071 | 12091 |
| 12072 | 12092 |
| 12073 void Parser::SkipBinaryExpr() { | 12093 void Parser::SkipBinaryExpr() { |
| 12074 SkipUnaryExpr(); | 12094 SkipUnaryExpr(); |
| (...skipping 54 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 12129 void Parser::SkipQualIdent() { | 12149 void Parser::SkipQualIdent() { |
| 12130 ASSERT(IsIdentifier()); | 12150 ASSERT(IsIdentifier()); |
| 12131 ConsumeToken(); | 12151 ConsumeToken(); |
| 12132 if (CurrentToken() == Token::kPERIOD) { | 12152 if (CurrentToken() == Token::kPERIOD) { |
| 12133 ConsumeToken(); // Consume the kPERIOD token. | 12153 ConsumeToken(); // Consume the kPERIOD token. |
| 12134 ExpectIdentifier("identifier expected after '.'"); | 12154 ExpectIdentifier("identifier expected after '.'"); |
| 12135 } | 12155 } |
| 12136 } | 12156 } |
| 12137 | 12157 |
| 12138 } // namespace dart | 12158 } // namespace dart |
| OLD | NEW |