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 1989 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2000 } | 2000 } |
2001 super_op = new StaticCallNode(operator_pos, super_operator, op_arguments); | 2001 super_op = new StaticCallNode(operator_pos, super_operator, op_arguments); |
2002 if (negate_result) { | 2002 if (negate_result) { |
2003 super_op = new UnaryOpNode(operator_pos, Token::kNOT, super_op); | 2003 super_op = new UnaryOpNode(operator_pos, Token::kNOT, super_op); |
2004 } | 2004 } |
2005 } | 2005 } |
2006 return super_op; | 2006 return super_op; |
2007 } | 2007 } |
2008 | 2008 |
2009 | 2009 |
2010 AstNode* Parser::CreateImplicitClosureNode(const Function& func, | 2010 ClosureNode* Parser::CreateImplicitClosureNode(const Function& func, |
2011 intptr_t token_pos, | 2011 intptr_t token_pos, |
2012 AstNode* receiver) { | 2012 AstNode* receiver) { |
2013 Function& implicit_closure_function = | 2013 Function& implicit_closure_function = |
2014 Function::ZoneHandle(func.ImplicitClosureFunction()); | 2014 Function::ZoneHandle(func.ImplicitClosureFunction()); |
2015 if (receiver != NULL) { | 2015 if (receiver != NULL) { |
2016 // If we create an implicit instance closure from inside a closure of a | 2016 // If we create an implicit instance closure from inside a closure of a |
2017 // parameterized class, make sure that the receiver is captured as | 2017 // parameterized class, make sure that the receiver is captured as |
2018 // instantiator. | 2018 // instantiator. |
2019 if (current_block_->scope->function_level() > 0) { | 2019 if (current_block_->scope->function_level() > 0) { |
2020 const Class& signature_class = Class::Handle( | 2020 const Class& signature_class = Class::Handle( |
2021 implicit_closure_function.signature_class()); | 2021 implicit_closure_function.signature_class()); |
2022 if (signature_class.NumTypeParameters() > 0) { | 2022 if (signature_class.NumTypeParameters() > 0) { |
(...skipping 6010 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
8033 ErrorMsg("expression expected after throw"); | 8033 ErrorMsg("expression expected after throw"); |
8034 } | 8034 } |
8035 AstNode* expr = ParseExpr(require_compiletime_const, consume_cascades); | 8035 AstNode* expr = ParseExpr(require_compiletime_const, consume_cascades); |
8036 return new ThrowNode(expr_pos, expr, NULL); | 8036 return new ThrowNode(expr_pos, expr, NULL); |
8037 } | 8037 } |
8038 AstNode* expr = ParseConditionalExpr(); | 8038 AstNode* expr = ParseConditionalExpr(); |
8039 if (!Token::IsAssignmentOperator(CurrentToken())) { | 8039 if (!Token::IsAssignmentOperator(CurrentToken())) { |
8040 if ((CurrentToken() == Token::kCASCADE) && consume_cascades) { | 8040 if ((CurrentToken() == Token::kCASCADE) && consume_cascades) { |
8041 return ParseCascades(expr); | 8041 return ParseCascades(expr); |
8042 } | 8042 } |
8043 expr = LiteralIfStaticConst(expr); | |
8044 if (require_compiletime_const) { | 8043 if (require_compiletime_const) { |
8045 expr = FoldConstExpr(expr_pos, expr); | 8044 expr = FoldConstExpr(expr_pos, expr); |
| 8045 } else { |
| 8046 expr = LiteralIfStaticConst(expr); |
8046 } | 8047 } |
8047 return expr; | 8048 return expr; |
8048 } | 8049 } |
8049 // Assignment expressions. | 8050 // Assignment expressions. |
8050 if (!IsLegalAssignableSyntax(expr, TokenPos())) { | 8051 if (!IsLegalAssignableSyntax(expr, TokenPos())) { |
8051 ErrorMsg(expr_pos, "expression is not assignable"); | 8052 ErrorMsg(expr_pos, "expression is not assignable"); |
8052 } | 8053 } |
8053 const Token::Kind assignment_op = CurrentToken(); | 8054 const Token::Kind assignment_op = CurrentToken(); |
8054 const intptr_t assignment_pos = TokenPos(); | 8055 const intptr_t assignment_pos = TokenPos(); |
8055 ConsumeToken(); | 8056 ConsumeToken(); |
(...skipping 329 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
8385 // for a field (which may be defined in a subclass.) | 8386 // for a field (which may be defined in a subclass.) |
8386 // In metadata, an unresolved identifier cannot be a compile-time constant. | 8387 // In metadata, an unresolved identifier cannot be a compile-time constant. |
8387 String& name = String::CheckedZoneHandle(primary->primary().raw()); | 8388 String& name = String::CheckedZoneHandle(primary->primary().raw()); |
8388 if (parsing_metadata_) { | 8389 if (parsing_metadata_) { |
8389 ErrorMsg(primary->token_pos(), | 8390 ErrorMsg(primary->token_pos(), |
8390 "unresolved identifier '%s' is not a compile-time constant", | 8391 "unresolved identifier '%s' is not a compile-time constant", |
8391 name.ToCString()); | 8392 name.ToCString()); |
8392 } | 8393 } |
8393 if (current_function().is_static() || | 8394 if (current_function().is_static() || |
8394 current_function().IsInFactoryScope()) { | 8395 current_function().IsInFactoryScope()) { |
8395 return new StaticGetterNode(primary->token_pos(), | 8396 StaticGetterNode* getter = |
8396 NULL, // No receiver. | 8397 new StaticGetterNode(primary->token_pos(), |
8397 false, // Not a super getter. | 8398 NULL, // No receiver. |
8398 Class::ZoneHandle(current_class().raw()), | 8399 false, // Not a super getter. |
8399 name); | 8400 Class::ZoneHandle(current_class().raw()), |
| 8401 name); |
| 8402 getter->set_is_deferred(primary->is_deferred_reference()); |
| 8403 return getter; |
8400 } else { | 8404 } else { |
8401 AstNode* receiver = LoadReceiver(primary->token_pos()); | 8405 AstNode* receiver = LoadReceiver(primary->token_pos()); |
8402 return CallGetter(node->token_pos(), receiver, name); | 8406 return CallGetter(node->token_pos(), receiver, name); |
8403 } | 8407 } |
8404 } | 8408 } |
8405 return primary; | 8409 return primary; |
8406 } | 8410 } |
8407 | 8411 |
8408 | 8412 |
8409 AstNode* Parser::LoadClosure(PrimaryNode* primary) { | 8413 AstNode* Parser::LoadClosure(PrimaryNode* primary) { |
8410 ASSERT(primary->primary().IsFunction()); | 8414 ASSERT(primary->primary().IsFunction()); |
8411 AstNode* closure = NULL; | |
8412 const Function& func = | 8415 const Function& func = |
8413 Function::CheckedZoneHandle(primary->primary().raw()); | 8416 Function::CheckedZoneHandle(primary->primary().raw()); |
8414 const String& funcname = String::ZoneHandle(func.name()); | 8417 const String& funcname = String::ZoneHandle(func.name()); |
8415 if (func.is_static()) { | 8418 if (func.is_static()) { |
8416 // Static function access. | 8419 // Static function access. |
8417 closure = CreateImplicitClosureNode(func, primary->token_pos(), NULL); | 8420 ClosureNode* closure = |
| 8421 CreateImplicitClosureNode(func, primary->token_pos(), NULL); |
| 8422 closure->set_is_deferred(primary->is_deferred_reference()); |
| 8423 return closure; |
8418 } else { | 8424 } else { |
8419 // Instance function access. | 8425 // Instance function access. |
8420 if (parsing_metadata_) { | 8426 if (parsing_metadata_) { |
8421 ErrorMsg(primary->token_pos(), | 8427 ErrorMsg(primary->token_pos(), |
8422 "cannot access instance method '%s' from metadata", | 8428 "cannot access instance method '%s' from metadata", |
8423 funcname.ToCString()); | 8429 funcname.ToCString()); |
8424 } | 8430 } |
8425 if (current_function().is_static() || | 8431 if (current_function().is_static() || |
8426 current_function().IsInFactoryScope()) { | 8432 current_function().IsInFactoryScope()) { |
8427 ErrorMsg(primary->token_pos(), | 8433 ErrorMsg(primary->token_pos(), |
8428 "cannot access instance method '%s' from static method", | 8434 "cannot access instance method '%s' from static method", |
8429 funcname.ToCString()); | 8435 funcname.ToCString()); |
8430 } | 8436 } |
8431 AstNode* receiver = LoadReceiver(primary->token_pos()); | 8437 AstNode* receiver = LoadReceiver(primary->token_pos()); |
8432 closure = CallGetter(primary->token_pos(), receiver, funcname); | 8438 return CallGetter(primary->token_pos(), receiver, funcname); |
8433 } | 8439 } |
8434 return closure; | 8440 UNREACHABLE(); |
| 8441 return NULL; |
8435 } | 8442 } |
8436 | 8443 |
8437 | 8444 |
8438 AstNode* Parser::ParseSelectors(AstNode* primary, bool is_cascade) { | 8445 AstNode* Parser::ParseSelectors(AstNode* primary, bool is_cascade) { |
8439 AstNode* left = primary; | 8446 AstNode* left = primary; |
8440 while (true) { | 8447 while (true) { |
8441 AstNode* selector = NULL; | 8448 AstNode* selector = NULL; |
8442 if (CurrentToken() == Token::kPERIOD) { | 8449 if (CurrentToken() == Token::kPERIOD) { |
8443 ConsumeToken(); | 8450 ConsumeToken(); |
8444 if (left->IsPrimaryNode()) { | 8451 if (left->IsPrimaryNode()) { |
(...skipping 808 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
9253 if (prefix.is_loaded()) { | 9260 if (prefix.is_loaded()) { |
9254 obj = prefix.LookupObject(ident); | 9261 obj = prefix.LookupObject(ident); |
9255 } else { | 9262 } else { |
9256 // Remember that this function depends on an import prefix of an | 9263 // Remember that this function depends on an import prefix of an |
9257 // unloaded deferred library. Note that parsed_function() can be | 9264 // unloaded deferred library. Note that parsed_function() can be |
9258 // NULL when parsing expressions outside the scope of a function. | 9265 // NULL when parsing expressions outside the scope of a function. |
9259 if (parsed_function() != NULL) { | 9266 if (parsed_function() != NULL) { |
9260 parsed_function()->AddDeferredPrefix(prefix); | 9267 parsed_function()->AddDeferredPrefix(prefix); |
9261 } | 9268 } |
9262 } | 9269 } |
| 9270 const bool is_deferred = prefix.is_deferred_load(); |
9263 if (obj.IsNull()) { | 9271 if (obj.IsNull()) { |
9264 // Unresolved prefixed primary identifier. | 9272 // Unresolved prefixed primary identifier. |
9265 return NULL; | 9273 return NULL; |
9266 } else if (obj.IsClass()) { | 9274 } else if (obj.IsClass()) { |
9267 const Class& cls = Class::Cast(obj); | 9275 const Class& cls = Class::Cast(obj); |
9268 return new PrimaryNode(ident_pos, Class::ZoneHandle(cls.raw())); | 9276 PrimaryNode* primary = |
| 9277 new PrimaryNode(ident_pos, Class::ZoneHandle(cls.raw())); |
| 9278 primary->set_is_deferred(is_deferred); |
| 9279 return primary; |
9269 } else if (obj.IsField()) { | 9280 } else if (obj.IsField()) { |
9270 const Field& field = Field::Cast(obj); | 9281 const Field& field = Field::Cast(obj); |
9271 ASSERT(field.is_static()); | 9282 ASSERT(field.is_static()); |
9272 return GenerateStaticFieldLookup(field, ident_pos); | 9283 AstNode* get_field = GenerateStaticFieldLookup(field, ident_pos); |
| 9284 ASSERT(get_field != NULL); |
| 9285 ASSERT(get_field->IsLoadStaticFieldNode() || |
| 9286 get_field->IsStaticGetterNode()); |
| 9287 if (get_field->IsLoadStaticFieldNode()) { |
| 9288 get_field->AsLoadStaticFieldNode()->set_is_deferred(is_deferred); |
| 9289 } else if (get_field->IsStaticGetterNode()) { |
| 9290 get_field->AsStaticGetterNode()->set_is_deferred(is_deferred); |
| 9291 } |
| 9292 return get_field; |
9273 } else if (obj.IsFunction()) { | 9293 } else if (obj.IsFunction()) { |
9274 const Function& func = Function::Cast(obj); | 9294 const Function& func = Function::Cast(obj); |
9275 ASSERT(func.is_static()); | 9295 ASSERT(func.is_static()); |
9276 if (func.IsGetterFunction() || func.IsSetterFunction()) { | 9296 if (func.IsGetterFunction() || func.IsSetterFunction()) { |
9277 return new StaticGetterNode(ident_pos, | 9297 StaticGetterNode* getter = |
9278 /* receiver */ NULL, | 9298 new StaticGetterNode(ident_pos, |
9279 /* is_super_getter */ false, | 9299 /* receiver */ NULL, |
9280 Class::ZoneHandle(func.Owner()), | 9300 /* is_super_getter */ false, |
9281 ident); | 9301 Class::ZoneHandle(func.Owner()), |
9282 | 9302 ident); |
| 9303 getter->set_is_deferred(is_deferred); |
| 9304 return getter; |
9283 } else { | 9305 } else { |
9284 return new PrimaryNode(ident_pos, Function::ZoneHandle(func.raw())); | 9306 PrimaryNode* primary = |
| 9307 new PrimaryNode(ident_pos, Function::ZoneHandle(func.raw())); |
| 9308 primary->set_is_deferred(is_deferred); |
| 9309 return primary; |
9285 } | 9310 } |
9286 } | 9311 } |
9287 // All possible object types are handled above. | 9312 // All possible object types are handled above. |
9288 UNREACHABLE(); | 9313 UNREACHABLE(); |
9289 return NULL; | 9314 return NULL; |
9290 } | 9315 } |
9291 | 9316 |
9292 | 9317 |
9293 // Resolve identifier. Issue an error message if | 9318 // Resolve identifier. Issue an error message if |
9294 // the ident refers to a method and allow_closure_names is false. | 9319 // the ident refers to a method and allow_closure_names is false. |
(...skipping 1585 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
10880 void Parser::SkipQualIdent() { | 10905 void Parser::SkipQualIdent() { |
10881 ASSERT(IsIdentifier()); | 10906 ASSERT(IsIdentifier()); |
10882 ConsumeToken(); | 10907 ConsumeToken(); |
10883 if (CurrentToken() == Token::kPERIOD) { | 10908 if (CurrentToken() == Token::kPERIOD) { |
10884 ConsumeToken(); // Consume the kPERIOD token. | 10909 ConsumeToken(); // Consume the kPERIOD token. |
10885 ExpectIdentifier("identifier expected after '.'"); | 10910 ExpectIdentifier("identifier expected after '.'"); |
10886 } | 10911 } |
10887 } | 10912 } |
10888 | 10913 |
10889 } // namespace dart | 10914 } // namespace dart |
OLD | NEW |