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 226 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
237 | 237 |
238 // For parsing a compilation unit. | 238 // For parsing a compilation unit. |
239 Parser::Parser(const Script& script, const Library& library, intptr_t token_pos) | 239 Parser::Parser(const Script& script, const Library& library, intptr_t token_pos) |
240 : isolate_(Isolate::Current()), | 240 : isolate_(Isolate::Current()), |
241 script_(Script::Handle(isolate_, script.raw())), | 241 script_(Script::Handle(isolate_, script.raw())), |
242 tokens_iterator_(TokenStream::Handle(isolate_, script.tokens()), | 242 tokens_iterator_(TokenStream::Handle(isolate_, script.tokens()), |
243 token_pos), | 243 token_pos), |
244 token_kind_(Token::kILLEGAL), | 244 token_kind_(Token::kILLEGAL), |
245 current_block_(NULL), | 245 current_block_(NULL), |
246 is_top_level_(false), | 246 is_top_level_(false), |
247 parsing_metadata_(false), | |
247 current_member_(NULL), | 248 current_member_(NULL), |
248 allow_function_literals_(true), | 249 allow_function_literals_(true), |
249 parsed_function_(NULL), | 250 parsed_function_(NULL), |
250 innermost_function_(Function::Handle(isolate_)), | 251 innermost_function_(Function::Handle(isolate_)), |
251 literal_token_(LiteralToken::Handle(isolate_)), | 252 literal_token_(LiteralToken::Handle(isolate_)), |
252 current_class_(Class::Handle(isolate_)), | 253 current_class_(Class::Handle(isolate_)), |
253 library_(Library::Handle(isolate_, library.raw())), | 254 library_(Library::Handle(isolate_, library.raw())), |
254 try_blocks_list_(NULL), | 255 try_blocks_list_(NULL), |
255 last_used_try_index_(0), | 256 last_used_try_index_(0), |
256 unregister_pending_function_(false) { | 257 unregister_pending_function_(false) { |
257 ASSERT(tokens_iterator_.IsValid()); | 258 ASSERT(tokens_iterator_.IsValid()); |
258 ASSERT(!library.IsNull()); | 259 ASSERT(!library.IsNull()); |
259 } | 260 } |
260 | 261 |
261 | 262 |
262 // For parsing a function. | 263 // For parsing a function. |
263 Parser::Parser(const Script& script, | 264 Parser::Parser(const Script& script, |
264 ParsedFunction* parsed_function, | 265 ParsedFunction* parsed_function, |
265 intptr_t token_position) | 266 intptr_t token_position) |
266 : isolate_(Isolate::Current()), | 267 : isolate_(Isolate::Current()), |
267 script_(Script::Handle(isolate_, script.raw())), | 268 script_(Script::Handle(isolate_, script.raw())), |
268 tokens_iterator_(TokenStream::Handle(isolate_, script.tokens()), | 269 tokens_iterator_(TokenStream::Handle(isolate_, script.tokens()), |
269 token_position), | 270 token_position), |
270 token_kind_(Token::kILLEGAL), | 271 token_kind_(Token::kILLEGAL), |
271 current_block_(NULL), | 272 current_block_(NULL), |
272 is_top_level_(false), | 273 is_top_level_(false), |
274 parsing_metadata_(false), | |
273 current_member_(NULL), | 275 current_member_(NULL), |
274 allow_function_literals_(true), | 276 allow_function_literals_(true), |
275 parsed_function_(parsed_function), | 277 parsed_function_(parsed_function), |
276 innermost_function_(Function::Handle(isolate_, | 278 innermost_function_(Function::Handle(isolate_, |
277 parsed_function->function().raw())), | 279 parsed_function->function().raw())), |
278 literal_token_(LiteralToken::Handle(isolate_)), | 280 literal_token_(LiteralToken::Handle(isolate_)), |
279 current_class_(Class::Handle(isolate_, | 281 current_class_(Class::Handle(isolate_, |
280 parsed_function->function().Owner())), | 282 parsed_function->function().Owner())), |
281 library_(Library::Handle(Class::Handle( | 283 library_(Library::Handle(Class::Handle( |
282 isolate_, | 284 isolate_, |
(...skipping 569 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
852 Isolate* isolate = Isolate::Current(); | 854 Isolate* isolate = Isolate::Current(); |
853 StackZone zone(isolate); | 855 StackZone zone(isolate); |
854 LongJump* base = isolate->long_jump_base(); | 856 LongJump* base = isolate->long_jump_base(); |
855 LongJump jump; | 857 LongJump jump; |
856 isolate->set_long_jump_base(&jump); | 858 isolate->set_long_jump_base(&jump); |
857 if (setjmp(*jump.Set()) == 0) { | 859 if (setjmp(*jump.Set()) == 0) { |
858 const Script& script = Script::Handle(cls.script()); | 860 const Script& script = Script::Handle(cls.script()); |
859 const Library& lib = Library::Handle(cls.library()); | 861 const Library& lib = Library::Handle(cls.library()); |
860 Parser parser(script, lib, token_pos); | 862 Parser parser(script, lib, token_pos); |
861 parser.set_current_class(cls); | 863 parser.set_current_class(cls); |
864 parser.set_parsing_metadata(true); | |
862 return parser.EvaluateMetadata(); | 865 return parser.EvaluateMetadata(); |
863 } else { | 866 } else { |
864 Error& error = Error::Handle(); | 867 Error& error = Error::Handle(); |
865 error = isolate->object_store()->sticky_error(); | 868 error = isolate->object_store()->sticky_error(); |
866 isolate->object_store()->clear_sticky_error(); | 869 isolate->object_store()->clear_sticky_error(); |
867 isolate->set_long_jump_base(base); | 870 isolate->set_long_jump_base(base); |
868 return error.raw(); | 871 return error.raw(); |
869 } | 872 } |
870 UNREACHABLE(); | 873 UNREACHABLE(); |
871 return Object::null(); | 874 return Object::null(); |
(...skipping 7368 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
8240 PrimaryNode* primary = node->AsPrimaryNode(); | 8243 PrimaryNode* primary = node->AsPrimaryNode(); |
8241 if (primary->primary().IsString()) { | 8244 if (primary->primary().IsString()) { |
8242 if (primary->IsSuper()) { | 8245 if (primary->IsSuper()) { |
8243 return primary; | 8246 return primary; |
8244 } | 8247 } |
8245 // In a static method, evaluation of an unresolved identifier causes a | 8248 // In a static method, evaluation of an unresolved identifier causes a |
8246 // NoSuchMethodError to be thrown. | 8249 // NoSuchMethodError to be thrown. |
8247 // In an instance method, we convert this into a getter call | 8250 // In an instance method, we convert this into a getter call |
8248 // for a field (which may be defined in a subclass.) | 8251 // for a field (which may be defined in a subclass.) |
8249 String& name = String::CheckedZoneHandle(primary->primary().raw()); | 8252 String& name = String::CheckedZoneHandle(primary->primary().raw()); |
8250 if (current_function().is_static() || | 8253 if (parsing_metadata_ || |
hausner
2013/11/19 00:07:24
Please add to the comment above why we distinguish
rmacnak
2013/11/19 01:01:24
Rewrote as a more intention-revealing error path a
| |
8254 current_function().is_static() || | |
8251 current_function().IsInFactoryScope()) { | 8255 current_function().IsInFactoryScope()) { |
8252 return new StaticGetterNode(primary->token_pos(), | 8256 return new StaticGetterNode(primary->token_pos(), |
8253 NULL, // No receiver. | 8257 NULL, // No receiver. |
8254 false, // Not a super getter. | 8258 false, // Not a super getter. |
8255 Class::ZoneHandle(current_class().raw()), | 8259 Class::ZoneHandle(current_class().raw()), |
8256 name); | 8260 name); |
8257 } else { | 8261 } else { |
8258 AstNode* receiver = LoadReceiver(primary->token_pos()); | 8262 AstNode* receiver = LoadReceiver(primary->token_pos()); |
8259 return CallGetter(node->token_pos(), receiver, name); | 8263 return CallGetter(node->token_pos(), receiver, name); |
8260 } | 8264 } |
8261 } | 8265 } |
8262 return primary; | 8266 return primary; |
8263 } | 8267 } |
8264 | 8268 |
8265 | 8269 |
8266 AstNode* Parser::LoadClosure(PrimaryNode* primary) { | 8270 AstNode* Parser::LoadClosure(PrimaryNode* primary) { |
8267 ASSERT(primary->primary().IsFunction()); | 8271 ASSERT(primary->primary().IsFunction()); |
8268 AstNode* closure = NULL; | 8272 AstNode* closure = NULL; |
8269 const Function& func = | 8273 const Function& func = |
8270 Function::CheckedZoneHandle(primary->primary().raw()); | 8274 Function::CheckedZoneHandle(primary->primary().raw()); |
8271 const String& funcname = String::ZoneHandle(func.name()); | 8275 const String& funcname = String::ZoneHandle(func.name()); |
8272 if (func.is_static()) { | 8276 if (func.is_static()) { |
8273 // Static function access. | 8277 // Static function access. |
8274 closure = CreateImplicitClosureNode(func, primary->token_pos(), NULL); | 8278 closure = CreateImplicitClosureNode(func, primary->token_pos(), NULL); |
8275 } else { | 8279 } else { |
8276 // Instance function access. | 8280 // Instance function access. |
8281 if (parsing_metadata_) { | |
8282 ErrorMsg(primary->token_pos(), | |
8283 "cannot access instance method '%s' from metadata", | |
8284 funcname.ToCString()); | |
8285 } | |
8277 if (current_function().is_static() || | 8286 if (current_function().is_static() || |
8278 current_function().IsInFactoryScope()) { | 8287 current_function().IsInFactoryScope()) { |
8279 ErrorMsg(primary->token_pos(), | 8288 ErrorMsg(primary->token_pos(), |
8280 "cannot access instance method '%s' from static method", | 8289 "cannot access instance method '%s' from static method", |
8281 funcname.ToCString()); | 8290 funcname.ToCString()); |
8282 } | 8291 } |
8283 AstNode* receiver = LoadReceiver(primary->token_pos()); | 8292 AstNode* receiver = LoadReceiver(primary->token_pos()); |
8284 closure = CallGetter(primary->token_pos(), receiver, funcname); | 8293 closure = CallGetter(primary->token_pos(), receiver, funcname); |
8285 } | 8294 } |
8286 return closure; | 8295 return closure; |
(...skipping 362 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
8649 // A found name is treated as accessed and possibly marked as captured. | 8658 // A found name is treated as accessed and possibly marked as captured. |
8650 const bool kTestOnly = false; | 8659 const bool kTestOnly = false; |
8651 return current_block_->scope->LookupVariable(ident, kTestOnly); | 8660 return current_block_->scope->LookupVariable(ident, kTestOnly); |
8652 } | 8661 } |
8653 | 8662 |
8654 | 8663 |
8655 void Parser::CheckInstanceFieldAccess(intptr_t field_pos, | 8664 void Parser::CheckInstanceFieldAccess(intptr_t field_pos, |
8656 const String& field_name) { | 8665 const String& field_name) { |
8657 // Fields are not accessible from a static function, except from a | 8666 // Fields are not accessible from a static function, except from a |
8658 // constructor, which is considered as non-static by the compiler. | 8667 // constructor, which is considered as non-static by the compiler. |
8668 if (parsing_metadata_) { | |
8669 ErrorMsg(field_pos, | |
8670 "cannot access instance field '%s' from metadata", | |
8671 field_name.ToCString()); | |
8672 } | |
8659 if (current_function().is_static()) { | 8673 if (current_function().is_static()) { |
8660 ErrorMsg(field_pos, | 8674 ErrorMsg(field_pos, |
8661 "cannot access instance field '%s' from a static function", | 8675 "cannot access instance field '%s' from a static function", |
8662 field_name.ToCString()); | 8676 field_name.ToCString()); |
8663 } | 8677 } |
8664 } | 8678 } |
8665 | 8679 |
8666 | 8680 |
8667 bool Parser::ParsingStaticMember() const { | 8681 bool Parser::ParsingStaticMember() const { |
8668 if (is_top_level_) { | 8682 if (is_top_level_) { |
(...skipping 2030 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
10699 void Parser::SkipQualIdent() { | 10713 void Parser::SkipQualIdent() { |
10700 ASSERT(IsIdentifier()); | 10714 ASSERT(IsIdentifier()); |
10701 ConsumeToken(); | 10715 ConsumeToken(); |
10702 if (CurrentToken() == Token::kPERIOD) { | 10716 if (CurrentToken() == Token::kPERIOD) { |
10703 ConsumeToken(); // Consume the kPERIOD token. | 10717 ConsumeToken(); // Consume the kPERIOD token. |
10704 ExpectIdentifier("identifier expected after '.'"); | 10718 ExpectIdentifier("identifier expected after '.'"); |
10705 } | 10719 } |
10706 } | 10720 } |
10707 | 10721 |
10708 } // namespace dart | 10722 } // namespace dart |
OLD | NEW |