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 |