| 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 "vm/bigint_operations.h" | 8 #include "vm/bigint_operations.h" |
| 9 #include "vm/class_finalizer.h" | 9 #include "vm/class_finalizer.h" |
| 10 #include "vm/compiler.h" | 10 #include "vm/compiler.h" |
| (...skipping 246 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 257 Parser::Parser(const Script& script, const Library& library, intptr_t token_pos) | 257 Parser::Parser(const Script& script, const Library& library, intptr_t token_pos) |
| 258 : script_(Script::Handle(script.raw())), | 258 : script_(Script::Handle(script.raw())), |
| 259 tokens_iterator_(TokenStream::Handle(script.tokens()), token_pos), | 259 tokens_iterator_(TokenStream::Handle(script.tokens()), token_pos), |
| 260 token_kind_(Token::kILLEGAL), | 260 token_kind_(Token::kILLEGAL), |
| 261 current_block_(NULL), | 261 current_block_(NULL), |
| 262 is_top_level_(false), | 262 is_top_level_(false), |
| 263 current_member_(NULL), | 263 current_member_(NULL), |
| 264 allow_function_literals_(true), | 264 allow_function_literals_(true), |
| 265 parsed_function_(NULL), | 265 parsed_function_(NULL), |
| 266 innermost_function_(Function::Handle()), | 266 innermost_function_(Function::Handle()), |
| 267 literal_token_(LiteralToken::Handle()), |
| 267 current_class_(Class::Handle()), | 268 current_class_(Class::Handle()), |
| 268 library_(Library::Handle(library.raw())), | 269 library_(Library::Handle(library.raw())), |
| 269 try_blocks_list_(NULL) { | 270 try_blocks_list_(NULL) { |
| 270 ASSERT(tokens_iterator_.IsValid()); | 271 ASSERT(tokens_iterator_.IsValid()); |
| 271 ASSERT(!library.IsNull()); | 272 ASSERT(!library.IsNull()); |
| 272 } | 273 } |
| 273 | 274 |
| 274 | 275 |
| 275 // For parsing a function. | 276 // For parsing a function. |
| 276 Parser::Parser(const Script& script, | 277 Parser::Parser(const Script& script, |
| 277 ParsedFunction* parsed_function, | 278 ParsedFunction* parsed_function, |
| 278 intptr_t token_position) | 279 intptr_t token_position) |
| 279 : script_(Script::Handle(script.raw())), | 280 : script_(Script::Handle(script.raw())), |
| 280 tokens_iterator_(TokenStream::Handle(script.tokens()), token_position), | 281 tokens_iterator_(TokenStream::Handle(script.tokens()), token_position), |
| 281 token_kind_(Token::kILLEGAL), | 282 token_kind_(Token::kILLEGAL), |
| 282 current_block_(NULL), | 283 current_block_(NULL), |
| 283 is_top_level_(false), | 284 is_top_level_(false), |
| 284 current_member_(NULL), | 285 current_member_(NULL), |
| 285 allow_function_literals_(true), | 286 allow_function_literals_(true), |
| 286 parsed_function_(parsed_function), | 287 parsed_function_(parsed_function), |
| 287 innermost_function_(Function::Handle(parsed_function->function().raw())), | 288 innermost_function_(Function::Handle(parsed_function->function().raw())), |
| 289 literal_token_(LiteralToken::Handle()), |
| 288 current_class_(Class::Handle(parsed_function->function().Owner())), | 290 current_class_(Class::Handle(parsed_function->function().Owner())), |
| 289 library_(Library::Handle(Class::Handle( | 291 library_(Library::Handle(Class::Handle( |
| 290 parsed_function->function().origin()).library())), | 292 parsed_function->function().origin()).library())), |
| 291 try_blocks_list_(NULL) { | 293 try_blocks_list_(NULL) { |
| 292 ASSERT(tokens_iterator_.IsValid()); | 294 ASSERT(tokens_iterator_.IsValid()); |
| 293 ASSERT(!current_function().IsNull()); | 295 ASSERT(!current_function().IsNull()); |
| 294 if (FLAG_enable_type_checks) { | 296 if (FLAG_enable_type_checks) { |
| 295 EnsureExpressionTemp(); | 297 EnsureExpressionTemp(); |
| 296 } | 298 } |
| 297 } | 299 } |
| (...skipping 72 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 370 | 372 |
| 371 | 373 |
| 372 String* Parser::CurrentLiteral() const { | 374 String* Parser::CurrentLiteral() const { |
| 373 String& result = String::ZoneHandle(); | 375 String& result = String::ZoneHandle(); |
| 374 result = tokens_iterator_.CurrentLiteral(); | 376 result = tokens_iterator_.CurrentLiteral(); |
| 375 return &result; | 377 return &result; |
| 376 } | 378 } |
| 377 | 379 |
| 378 | 380 |
| 379 RawDouble* Parser::CurrentDoubleLiteral() const { | 381 RawDouble* Parser::CurrentDoubleLiteral() const { |
| 380 LiteralToken& token = LiteralToken::Handle(); | 382 literal_token_ ^= tokens_iterator_.CurrentToken(); |
| 381 token ^= tokens_iterator_.CurrentToken(); | 383 ASSERT(literal_token_.kind() == Token::kDOUBLE); |
| 382 ASSERT(token.kind() == Token::kDOUBLE); | 384 return Double::RawCast(literal_token_.value()); |
| 383 return reinterpret_cast<RawDouble*>(token.value()); | |
| 384 } | 385 } |
| 385 | 386 |
| 386 | 387 |
| 387 RawInteger* Parser::CurrentIntegerLiteral() const { | 388 RawInteger* Parser::CurrentIntegerLiteral() const { |
| 388 LiteralToken& token = LiteralToken::Handle(); | 389 literal_token_ ^= tokens_iterator_.CurrentToken(); |
| 389 token ^= tokens_iterator_.CurrentToken(); | 390 ASSERT(literal_token_.kind() == Token::kINTEGER); |
| 390 ASSERT(token.kind() == Token::kINTEGER); | 391 return Integer::RawCast(literal_token_.value()); |
| 391 return reinterpret_cast<RawInteger*>(token.value()); | |
| 392 } | 392 } |
| 393 | 393 |
| 394 | 394 |
| 395 // A QualIdent is an optionally qualified identifier. | 395 // A QualIdent is an optionally qualified identifier. |
| 396 struct QualIdent { | 396 struct QualIdent { |
| 397 QualIdent() { | 397 QualIdent() { |
| 398 Clear(); | 398 Clear(); |
| 399 } | 399 } |
| 400 void Clear() { | 400 void Clear() { |
| 401 lib_prefix = NULL; | 401 lib_prefix = NULL; |
| (...skipping 4026 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4428 ParseLibraryImportExport(); | 4428 ParseLibraryImportExport(); |
| 4429 metadata_pos = TokenPos(); | 4429 metadata_pos = TokenPos(); |
| 4430 SkipMetadata(); | 4430 SkipMetadata(); |
| 4431 } | 4431 } |
| 4432 // Core lib has not been explicitly imported, so we implicitly | 4432 // Core lib has not been explicitly imported, so we implicitly |
| 4433 // import it here. | 4433 // import it here. |
| 4434 if (!library_.ImportsCorelib()) { | 4434 if (!library_.ImportsCorelib()) { |
| 4435 Library& core_lib = Library::Handle(Library::CoreLibrary()); | 4435 Library& core_lib = Library::Handle(Library::CoreLibrary()); |
| 4436 ASSERT(!core_lib.IsNull()); | 4436 ASSERT(!core_lib.IsNull()); |
| 4437 const Namespace& core_ns = Namespace::Handle( | 4437 const Namespace& core_ns = Namespace::Handle( |
| 4438 Namespace::New(core_lib, Array::Handle(), Array::Handle())); | 4438 Namespace::New(core_lib, Array::null_object(), Array::null_object())); |
| 4439 library_.AddImport(core_ns); | 4439 library_.AddImport(core_ns); |
| 4440 } | 4440 } |
| 4441 while (CurrentToken() == Token::kPART) { | 4441 while (CurrentToken() == Token::kPART) { |
| 4442 ParseLibraryPart(); | 4442 ParseLibraryPart(); |
| 4443 metadata_pos = TokenPos(); | 4443 metadata_pos = TokenPos(); |
| 4444 SkipMetadata(); | 4444 SkipMetadata(); |
| 4445 } | 4445 } |
| 4446 SetPosition(metadata_pos); | 4446 SetPosition(metadata_pos); |
| 4447 } | 4447 } |
| 4448 | 4448 |
| (...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4484 Class::New(Symbols::TopLevel(), script_, TokenPos())); | 4484 Class::New(Symbols::TopLevel(), script_, TokenPos())); |
| 4485 toplevel_class.set_library(library_); | 4485 toplevel_class.set_library(library_); |
| 4486 | 4486 |
| 4487 if (is_library_source() || is_patch_source()) { | 4487 if (is_library_source() || is_patch_source()) { |
| 4488 ParseLibraryDefinition(); | 4488 ParseLibraryDefinition(); |
| 4489 } else if (is_part_source()) { | 4489 } else if (is_part_source()) { |
| 4490 ParsePartHeader(); | 4490 ParsePartHeader(); |
| 4491 } | 4491 } |
| 4492 | 4492 |
| 4493 while (true) { | 4493 while (true) { |
| 4494 set_current_class(Class::Handle()); // No current class. | 4494 set_current_class(Class::null_object()); // No current class. |
| 4495 SkipMetadata(); | 4495 SkipMetadata(); |
| 4496 if (CurrentToken() == Token::kCLASS) { | 4496 if (CurrentToken() == Token::kCLASS) { |
| 4497 ParseClassDeclaration(pending_classes); | 4497 ParseClassDeclaration(pending_classes); |
| 4498 } else if ((CurrentToken() == Token::kTYPEDEF) && | 4498 } else if ((CurrentToken() == Token::kTYPEDEF) && |
| 4499 (LookaheadToken(1) != Token::kLPAREN)) { | 4499 (LookaheadToken(1) != Token::kLPAREN)) { |
| 4500 set_current_class(toplevel_class); | 4500 set_current_class(toplevel_class); |
| 4501 ParseTypedef(pending_classes); | 4501 ParseTypedef(pending_classes); |
| 4502 } else if ((CurrentToken() == Token::kABSTRACT) && | 4502 } else if ((CurrentToken() == Token::kABSTRACT) && |
| 4503 (LookaheadToken(1) == Token::kCLASS)) { | 4503 (LookaheadToken(1) == Token::kCLASS)) { |
| 4504 ParseClassDeclaration(pending_classes); | 4504 ParseClassDeclaration(pending_classes); |
| (...skipping 3580 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 8085 ASSERT(func.kind() == RawFunction::kConstImplicitGetter); | 8085 ASSERT(func.kind() == RawFunction::kConstImplicitGetter); |
| 8086 Object& const_value = Object::Handle( | 8086 Object& const_value = Object::Handle( |
| 8087 DartEntry::InvokeFunction(func, Object::empty_array())); | 8087 DartEntry::InvokeFunction(func, Object::empty_array())); |
| 8088 if (const_value.IsError()) { | 8088 if (const_value.IsError()) { |
| 8089 const Error& error = Error::Cast(const_value); | 8089 const Error& error = Error::Cast(const_value); |
| 8090 if (error.IsUnhandledException()) { | 8090 if (error.IsUnhandledException()) { |
| 8091 // An exception may not occur in every parse attempt, i.e., the | 8091 // An exception may not occur in every parse attempt, i.e., the |
| 8092 // generated AST is not deterministic. Therefore mark the function as | 8092 // generated AST is not deterministic. Therefore mark the function as |
| 8093 // not optimizable. | 8093 // not optimizable. |
| 8094 current_function().set_is_optimizable(false); | 8094 current_function().set_is_optimizable(false); |
| 8095 field.set_value(Instance::Handle()); | 8095 field.set_value(Instance::null_object()); |
| 8096 // It is a compile-time error if evaluation of a compile-time constant | 8096 // It is a compile-time error if evaluation of a compile-time constant |
| 8097 // would raise an exception. | 8097 // would raise an exception. |
| 8098 AppendErrorMsg(error, TokenPos(), | 8098 AppendErrorMsg(error, TokenPos(), |
| 8099 "error initializing const field '%s'", | 8099 "error initializing const field '%s'", |
| 8100 String::Handle(field.name()).ToCString()); | 8100 String::Handle(field.name()).ToCString()); |
| 8101 } else { | 8101 } else { |
| 8102 Isolate::Current()->long_jump_base()->Jump(1, error); | 8102 Isolate::Current()->long_jump_base()->Jump(1, error); |
| 8103 } | 8103 } |
| 8104 } | 8104 } |
| 8105 ASSERT(const_value.IsNull() || const_value.IsInstance()); | 8105 ASSERT(const_value.IsNull() || const_value.IsInstance()); |
| (...skipping 563 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 8669 return Type::DynamicType(); | 8669 return Type::DynamicType(); |
| 8670 } | 8670 } |
| 8671 AbstractType& type = AbstractType::Handle( | 8671 AbstractType& type = AbstractType::Handle( |
| 8672 Type::New(type_class, type_arguments, type_name.ident_pos)); | 8672 Type::New(type_class, type_arguments, type_name.ident_pos)); |
| 8673 // In production mode, malformed type arguments are mapped to dynamic. | 8673 // In production mode, malformed type arguments are mapped to dynamic. |
| 8674 // In checked mode, a type with malformed type arguments is malformed. | 8674 // In checked mode, a type with malformed type arguments is malformed. |
| 8675 if (FLAG_enable_type_checks && !malformed_error.IsNull()) { | 8675 if (FLAG_enable_type_checks && !malformed_error.IsNull()) { |
| 8676 Type& parameterized_type = Type::Handle(); | 8676 Type& parameterized_type = Type::Handle(); |
| 8677 parameterized_type ^= type.raw(); | 8677 parameterized_type ^= type.raw(); |
| 8678 parameterized_type.set_type_class(Class::Handle(Object::dynamic_class())); | 8678 parameterized_type.set_type_class(Class::Handle(Object::dynamic_class())); |
| 8679 parameterized_type.set_arguments(AbstractTypeArguments::Handle()); | 8679 parameterized_type.set_arguments( |
| 8680 AbstractTypeArguments::null_object()); |
| 8680 parameterized_type.set_malformed_error(malformed_error); | 8681 parameterized_type.set_malformed_error(malformed_error); |
| 8681 } | 8682 } |
| 8682 if (finalization >= ClassFinalizer::kTryResolve) { | 8683 if (finalization >= ClassFinalizer::kTryResolve) { |
| 8683 ResolveTypeFromClass(current_class(), finalization, &type); | 8684 ResolveTypeFromClass(current_class(), finalization, &type); |
| 8684 if (finalization >= ClassFinalizer::kCanonicalize) { | 8685 if (finalization >= ClassFinalizer::kCanonicalize) { |
| 8685 type ^= ClassFinalizer::FinalizeType(current_class(), type, finalization); | 8686 type ^= ClassFinalizer::FinalizeType(current_class(), type, finalization); |
| 8686 } | 8687 } |
| 8687 } | 8688 } |
| 8688 return type.raw(); | 8689 return type.raw(); |
| 8689 } | 8690 } |
| (...skipping 1269 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 9959 void Parser::SkipQualIdent() { | 9960 void Parser::SkipQualIdent() { |
| 9960 ASSERT(IsIdentifier()); | 9961 ASSERT(IsIdentifier()); |
| 9961 ConsumeToken(); | 9962 ConsumeToken(); |
| 9962 if (CurrentToken() == Token::kPERIOD) { | 9963 if (CurrentToken() == Token::kPERIOD) { |
| 9963 ConsumeToken(); // Consume the kPERIOD token. | 9964 ConsumeToken(); // Consume the kPERIOD token. |
| 9964 ExpectIdentifier("identifier expected after '.'"); | 9965 ExpectIdentifier("identifier expected after '.'"); |
| 9965 } | 9966 } |
| 9966 } | 9967 } |
| 9967 | 9968 |
| 9968 } // namespace dart | 9969 } // namespace dart |
| OLD | NEW |