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 7364 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
8236 } | 8239 } |
8237 PrimaryNode* primary = node->AsPrimaryNode(); | 8240 PrimaryNode* primary = node->AsPrimaryNode(); |
8238 if (primary->primary().IsString()) { | 8241 if (primary->primary().IsString()) { |
8239 if (primary->IsSuper()) { | 8242 if (primary->IsSuper()) { |
8240 return primary; | 8243 return primary; |
8241 } | 8244 } |
8242 // In a static method, evaluation of an unresolved identifier causes a | 8245 // In a static method, evaluation of an unresolved identifier causes a |
8243 // NoSuchMethodError to be thrown. | 8246 // NoSuchMethodError to be thrown. |
8244 // In an instance method, we convert this into a getter call | 8247 // In an instance method, we convert this into a getter call |
8245 // for a field (which may be defined in a subclass.) | 8248 // for a field (which may be defined in a subclass.) |
| 8249 // In metadata, an unresolved identifier cannot be a compile-time constant. |
8246 String& name = String::CheckedZoneHandle(primary->primary().raw()); | 8250 String& name = String::CheckedZoneHandle(primary->primary().raw()); |
| 8251 if (parsing_metadata_) { |
| 8252 ErrorMsg(primary->token_pos(), |
| 8253 "unresolved identifier '%s' is not a compile-time constant", |
| 8254 name.ToCString()); |
| 8255 } |
8247 if (current_function().is_static() || | 8256 if (current_function().is_static() || |
8248 current_function().IsInFactoryScope()) { | 8257 current_function().IsInFactoryScope()) { |
8249 return new StaticGetterNode(primary->token_pos(), | 8258 return new StaticGetterNode(primary->token_pos(), |
8250 NULL, // No receiver. | 8259 NULL, // No receiver. |
8251 false, // Not a super getter. | 8260 false, // Not a super getter. |
8252 Class::ZoneHandle(current_class().raw()), | 8261 Class::ZoneHandle(current_class().raw()), |
8253 name); | 8262 name); |
8254 } else { | 8263 } else { |
8255 AstNode* receiver = LoadReceiver(primary->token_pos()); | 8264 AstNode* receiver = LoadReceiver(primary->token_pos()); |
8256 return CallGetter(node->token_pos(), receiver, name); | 8265 return CallGetter(node->token_pos(), receiver, name); |
8257 } | 8266 } |
8258 } | 8267 } |
8259 return primary; | 8268 return primary; |
8260 } | 8269 } |
8261 | 8270 |
8262 | 8271 |
8263 AstNode* Parser::LoadClosure(PrimaryNode* primary) { | 8272 AstNode* Parser::LoadClosure(PrimaryNode* primary) { |
8264 ASSERT(primary->primary().IsFunction()); | 8273 ASSERT(primary->primary().IsFunction()); |
8265 AstNode* closure = NULL; | 8274 AstNode* closure = NULL; |
8266 const Function& func = | 8275 const Function& func = |
8267 Function::CheckedZoneHandle(primary->primary().raw()); | 8276 Function::CheckedZoneHandle(primary->primary().raw()); |
8268 const String& funcname = String::ZoneHandle(func.name()); | 8277 const String& funcname = String::ZoneHandle(func.name()); |
8269 if (func.is_static()) { | 8278 if (func.is_static()) { |
8270 // Static function access. | 8279 // Static function access. |
8271 closure = CreateImplicitClosureNode(func, primary->token_pos(), NULL); | 8280 closure = CreateImplicitClosureNode(func, primary->token_pos(), NULL); |
8272 } else { | 8281 } else { |
8273 // Instance function access. | 8282 // Instance function access. |
| 8283 if (parsing_metadata_) { |
| 8284 ErrorMsg(primary->token_pos(), |
| 8285 "cannot access instance method '%s' from metadata", |
| 8286 funcname.ToCString()); |
| 8287 } |
8274 if (current_function().is_static() || | 8288 if (current_function().is_static() || |
8275 current_function().IsInFactoryScope()) { | 8289 current_function().IsInFactoryScope()) { |
8276 ErrorMsg(primary->token_pos(), | 8290 ErrorMsg(primary->token_pos(), |
8277 "cannot access instance method '%s' from static method", | 8291 "cannot access instance method '%s' from static method", |
8278 funcname.ToCString()); | 8292 funcname.ToCString()); |
8279 } | 8293 } |
8280 AstNode* receiver = LoadReceiver(primary->token_pos()); | 8294 AstNode* receiver = LoadReceiver(primary->token_pos()); |
8281 closure = CallGetter(primary->token_pos(), receiver, funcname); | 8295 closure = CallGetter(primary->token_pos(), receiver, funcname); |
8282 } | 8296 } |
8283 return closure; | 8297 return closure; |
(...skipping 362 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
8646 // A found name is treated as accessed and possibly marked as captured. | 8660 // A found name is treated as accessed and possibly marked as captured. |
8647 const bool kTestOnly = false; | 8661 const bool kTestOnly = false; |
8648 return current_block_->scope->LookupVariable(ident, kTestOnly); | 8662 return current_block_->scope->LookupVariable(ident, kTestOnly); |
8649 } | 8663 } |
8650 | 8664 |
8651 | 8665 |
8652 void Parser::CheckInstanceFieldAccess(intptr_t field_pos, | 8666 void Parser::CheckInstanceFieldAccess(intptr_t field_pos, |
8653 const String& field_name) { | 8667 const String& field_name) { |
8654 // Fields are not accessible from a static function, except from a | 8668 // Fields are not accessible from a static function, except from a |
8655 // constructor, which is considered as non-static by the compiler. | 8669 // constructor, which is considered as non-static by the compiler. |
| 8670 if (parsing_metadata_) { |
| 8671 ErrorMsg(field_pos, |
| 8672 "cannot access instance field '%s' from metadata", |
| 8673 field_name.ToCString()); |
| 8674 } |
8656 if (current_function().is_static()) { | 8675 if (current_function().is_static()) { |
8657 ErrorMsg(field_pos, | 8676 ErrorMsg(field_pos, |
8658 "cannot access instance field '%s' from a static function", | 8677 "cannot access instance field '%s' from a static function", |
8659 field_name.ToCString()); | 8678 field_name.ToCString()); |
8660 } | 8679 } |
8661 } | 8680 } |
8662 | 8681 |
8663 | 8682 |
8664 bool Parser::ParsingStaticMember() const { | 8683 bool Parser::ParsingStaticMember() const { |
8665 if (is_top_level_) { | 8684 if (is_top_level_) { |
(...skipping 2007 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
10673 void Parser::SkipQualIdent() { | 10692 void Parser::SkipQualIdent() { |
10674 ASSERT(IsIdentifier()); | 10693 ASSERT(IsIdentifier()); |
10675 ConsumeToken(); | 10694 ConsumeToken(); |
10676 if (CurrentToken() == Token::kPERIOD) { | 10695 if (CurrentToken() == Token::kPERIOD) { |
10677 ConsumeToken(); // Consume the kPERIOD token. | 10696 ConsumeToken(); // Consume the kPERIOD token. |
10678 ExpectIdentifier("identifier expected after '.'"); | 10697 ExpectIdentifier("identifier expected after '.'"); |
10679 } | 10698 } |
10680 } | 10699 } |
10681 | 10700 |
10682 } // namespace dart | 10701 } // namespace dart |
OLD | NEW |