Chromium Code Reviews| 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/bootstrap.h" | 9 #include "vm/bootstrap.h" |
| 10 #include "vm/class_finalizer.h" | 10 #include "vm/class_finalizer.h" |
| (...skipping 2800 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 2811 ConsumeToken(); | 2811 ConsumeToken(); |
| 2812 ParseStatementSequence(); | 2812 ParseStatementSequence(); |
| 2813 ExpectToken(Token::kRBRACE); | 2813 ExpectToken(Token::kRBRACE); |
| 2814 } else if (CurrentToken() == Token::kARROW) { | 2814 } else if (CurrentToken() == Token::kARROW) { |
| 2815 ErrorMsg("constructors may not return a value"); | 2815 ErrorMsg("constructors may not return a value"); |
| 2816 } else if (IsLiteral("native")) { | 2816 } else if (IsLiteral("native")) { |
| 2817 ErrorMsg("native constructors not supported"); | 2817 ErrorMsg("native constructors not supported"); |
| 2818 } else if (CurrentToken() == Token::kSEMICOLON) { | 2818 } else if (CurrentToken() == Token::kSEMICOLON) { |
| 2819 // Some constructors have no function body. | 2819 // Some constructors have no function body. |
| 2820 ConsumeToken(); | 2820 ConsumeToken(); |
| 2821 if (func.is_external()) { | |
| 2822 // Body of an external method contains a single throw. | |
| 2823 const String& function_name = String::ZoneHandle(func.name()); | |
| 2824 current_block_->statements->Add( | |
| 2825 ThrowNoSuchMethodError(TokenPos(), | |
| 2826 current_class(), | |
| 2827 function_name, | |
| 2828 NULL, // No arguments. | |
| 2829 InvocationMirror::kStatic, | |
| 2830 InvocationMirror::kMethod, | |
| 2831 NULL)); // No existing function. | |
| 2832 } | |
| 2821 } else { | 2833 } else { |
| 2822 UnexpectedToken(); | 2834 UnexpectedToken(); |
| 2823 } | 2835 } |
| 2824 | 2836 |
| 2825 SequenceNode* ctor_block = CloseBlock(); | 2837 SequenceNode* ctor_block = CloseBlock(); |
| 2826 if (ctor_block->length() > 0) { | 2838 if (ctor_block->length() > 0) { |
| 2827 // Generate guard around the constructor body code. | 2839 // Generate guard around the constructor body code. |
| 2828 LocalVariable* phase_param = LookupPhaseParameter(); | 2840 LocalVariable* phase_param = LookupPhaseParameter(); |
| 2829 AstNode* phase_value = | 2841 AstNode* phase_value = |
| 2830 new LoadLocalNode(Scanner::kNoSourcePos, phase_param); | 2842 new LoadLocalNode(Scanner::kNoSourcePos, phase_param); |
| (...skipping 346 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 3177 } | 3189 } |
| 3178 if (are_implicitly_final) { | 3190 if (are_implicitly_final) { |
| 3179 method->params.SetImplicitlyFinal(); | 3191 method->params.SetImplicitlyFinal(); |
| 3180 } | 3192 } |
| 3181 if (!method->IsGetter()) { | 3193 if (!method->IsGetter()) { |
| 3182 ParseFormalParameterList(allow_explicit_default_values, | 3194 ParseFormalParameterList(allow_explicit_default_values, |
| 3183 false, | 3195 false, |
| 3184 &method->params); | 3196 &method->params); |
| 3185 } | 3197 } |
| 3186 | 3198 |
| 3199 if (method->has_external && method->params.has_field_initializer) { | |
| 3200 ErrorMsg(method->name_pos, | |
| 3201 "external method '%s' may not have field initializers", | |
|
hausner
2014/05/07 23:45:42
The message is a bit misleading. If the external m
| |
| 3202 method->name->ToCString()); | |
| 3203 } | |
| 3204 | |
| 3187 // Now that we know the parameter list, we can distinguish between the | 3205 // Now that we know the parameter list, we can distinguish between the |
| 3188 // unary and binary operator -. | 3206 // unary and binary operator -. |
| 3189 if (method->has_operator) { | 3207 if (method->has_operator) { |
| 3190 if ((method->operator_token == Token::kSUB) && | 3208 if ((method->operator_token == Token::kSUB) && |
| 3191 (method->params.num_fixed_parameters == 1)) { | 3209 (method->params.num_fixed_parameters == 1)) { |
| 3192 // Patch up name for unary operator - so it does not clash with the | 3210 // Patch up name for unary operator - so it does not clash with the |
| 3193 // name for binary operator -. | 3211 // name for binary operator -. |
| 3194 method->operator_token = Token::kNEGATE; | 3212 method->operator_token = Token::kNEGATE; |
| 3195 *method->name = Symbols::New(Token::Str(Token::kNEGATE)); | 3213 *method->name = Symbols::New(Token::Str(Token::kNEGATE)); |
| 3196 } | 3214 } |
| (...skipping 54 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 3251 if (CurrentToken() == Token::kPERIOD) { | 3269 if (CurrentToken() == Token::kPERIOD) { |
| 3252 // Named constructor or factory. | 3270 // Named constructor or factory. |
| 3253 ConsumeToken(); | 3271 ConsumeToken(); |
| 3254 redirection_identifier = ExpectIdentifier("identifier expected")->raw(); | 3272 redirection_identifier = ExpectIdentifier("identifier expected")->raw(); |
| 3255 } | 3273 } |
| 3256 } else if (CurrentToken() == Token::kCOLON) { | 3274 } else if (CurrentToken() == Token::kCOLON) { |
| 3257 // Parse initializers. | 3275 // Parse initializers. |
| 3258 if (!method->IsConstructor()) { | 3276 if (!method->IsConstructor()) { |
| 3259 ErrorMsg("initializers only allowed on constructors"); | 3277 ErrorMsg("initializers only allowed on constructors"); |
| 3260 } | 3278 } |
| 3279 if (method->has_external) { | |
| 3280 ErrorMsg(method->name_pos, | |
| 3281 "external method '%s' may not have a initializers", | |
|
hausner
2014/05/07 23:45:42
If the external method is not a constructor, we sh
| |
| 3282 method->name->ToCString()); | |
| 3283 } | |
| 3261 if ((LookaheadToken(1) == Token::kTHIS) && | 3284 if ((LookaheadToken(1) == Token::kTHIS) && |
| 3262 ((LookaheadToken(2) == Token::kLPAREN) || | 3285 ((LookaheadToken(2) == Token::kLPAREN) || |
| 3263 LookaheadToken(4) == Token::kLPAREN)) { | 3286 LookaheadToken(4) == Token::kLPAREN)) { |
| 3264 // Redirected constructor: either this(...) or this.xxx(...). | 3287 // Redirected constructor: either this(...) or this.xxx(...). |
| 3265 is_redirecting = true; | 3288 is_redirecting = true; |
| 3266 if (method->params.has_field_initializer) { | 3289 if (method->params.has_field_initializer) { |
| 3267 // Constructors that redirect to another constructor must not | 3290 // Constructors that redirect to another constructor must not |
| 3268 // initialize any fields using field initializer parameters. | 3291 // initialize any fields using field initializer parameters. |
| 3269 ErrorMsg(formal_param_pos, "Redirecting constructor " | 3292 ErrorMsg(formal_param_pos, "Redirecting constructor " |
| 3270 "may not use field initializer parameters"); | 3293 "may not use field initializer parameters"); |
| (...skipping 7680 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 10951 void Parser::SkipQualIdent() { | 10974 void Parser::SkipQualIdent() { |
| 10952 ASSERT(IsIdentifier()); | 10975 ASSERT(IsIdentifier()); |
| 10953 ConsumeToken(); | 10976 ConsumeToken(); |
| 10954 if (CurrentToken() == Token::kPERIOD) { | 10977 if (CurrentToken() == Token::kPERIOD) { |
| 10955 ConsumeToken(); // Consume the kPERIOD token. | 10978 ConsumeToken(); // Consume the kPERIOD token. |
| 10956 ExpectIdentifier("identifier expected after '.'"); | 10979 ExpectIdentifier("identifier expected after '.'"); |
| 10957 } | 10980 } |
| 10958 } | 10981 } |
| 10959 | 10982 |
| 10960 } // namespace dart | 10983 } // namespace dart |
| OLD | NEW |