| 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 "vm/bigint_operations.h" | 7 #include "vm/bigint_operations.h" |
| 8 #include "vm/class_finalizer.h" | 8 #include "vm/class_finalizer.h" |
| 9 #include "vm/compiler.h" | 9 #include "vm/compiler.h" |
| 10 #include "vm/compiler_stats.h" | 10 #include "vm/compiler_stats.h" |
| (...skipping 1896 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1907 SkipExpr(); | 1907 SkipExpr(); |
| 1908 SetAllowFunctionLiterals(true); | 1908 SetAllowFunctionLiterals(true); |
| 1909 } | 1909 } |
| 1910 } while (CurrentToken() == Token::kCOMMA); | 1910 } while (CurrentToken() == Token::kCOMMA); |
| 1911 } | 1911 } |
| 1912 | 1912 |
| 1913 | 1913 |
| 1914 void Parser::ParseQualIdent(QualIdent* qual_ident) { | 1914 void Parser::ParseQualIdent(QualIdent* qual_ident) { |
| 1915 ASSERT(IsIdentifier()); | 1915 ASSERT(IsIdentifier()); |
| 1916 if (!is_top_level_) { | 1916 if (!is_top_level_) { |
| 1917 AstNode* var_or_field = NULL; |
| 1917 bool is_local_ident = ResolveIdentInLocalScope(token_index_, | 1918 bool is_local_ident = ResolveIdentInLocalScope(token_index_, |
| 1918 *CurrentLiteral(), | 1919 *CurrentLiteral(), |
| 1919 NULL); | 1920 &var_or_field); |
| 1920 qual_ident->ident_pos = token_index_; | 1921 qual_ident->ident_pos = token_index_; |
| 1921 qual_ident->ident = CurrentLiteral(); | 1922 qual_ident->ident = CurrentLiteral(); |
| 1922 qual_ident->lib_prefix = NULL; | 1923 qual_ident->lib_prefix = NULL; |
| 1923 qual_ident->qualifier = NULL; | 1924 qual_ident->qualifier = NULL; |
| 1924 qual_ident->is_local_scope_ident = is_local_ident; | 1925 qual_ident->is_local_scope_ident = is_local_ident; |
| 1925 ConsumeToken(); | 1926 ConsumeToken(); |
| 1926 if (!is_local_ident && (CurrentToken() == Token::kPERIOD)) { | 1927 if (!is_local_ident && (CurrentToken() == Token::kPERIOD)) { |
| 1927 LibraryPrefix& lib_prefix = LibraryPrefix::ZoneHandle(); | 1928 LibraryPrefix& lib_prefix = LibraryPrefix::ZoneHandle(); |
| 1928 lib_prefix = current_class().LookupLibraryPrefix(*(qual_ident->ident)); | 1929 lib_prefix = current_class().LookupLibraryPrefix(*(qual_ident->ident)); |
| 1929 if (!lib_prefix.IsNull()) { | 1930 if (!lib_prefix.IsNull()) { |
| (...skipping 3122 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 5052 } | 5053 } |
| 5053 if (target->FunctionLevel() != current_block_->scope->function_level()) { | 5054 if (target->FunctionLevel() != current_block_->scope->function_level()) { |
| 5054 ErrorMsg(jump_pos, "'%s' target must be in same function context", | 5055 ErrorMsg(jump_pos, "'%s' target must be in same function context", |
| 5055 Token::Str(jump_kind)); | 5056 Token::Str(jump_kind)); |
| 5056 } | 5057 } |
| 5057 return new JumpNode(jump_pos, jump_kind, target); | 5058 return new JumpNode(jump_pos, jump_kind, target); |
| 5058 } | 5059 } |
| 5059 | 5060 |
| 5060 | 5061 |
| 5061 bool Parser::IsDefinedInLexicalScope(const String& ident) { | 5062 bool Parser::IsDefinedInLexicalScope(const String& ident) { |
| 5062 if (ResolveIdentInLocalScope(token_index_, ident, NULL)) { | 5063 AstNode* var_or_field = NULL; |
| 5064 if (ResolveIdentInLocalScope(token_index_, ident, &var_or_field)) { |
| 5063 return true; | 5065 return true; |
| 5064 } | 5066 } |
| 5065 Object& obj = Object::Handle(); | 5067 Object& obj = Object::Handle(); |
| 5066 obj = library_.LookupObject(ident); | 5068 obj = library_.LookupObject(ident); |
| 5067 return !obj.IsNull(); | 5069 return !obj.IsNull(); |
| 5068 } | 5070 } |
| 5069 | 5071 |
| 5070 | 5072 |
| 5071 AstNode* Parser::ParseStatement() { | 5073 AstNode* Parser::ParseStatement() { |
| 5072 TRACE_PARSER("ParseStatement"); | 5074 TRACE_PARSER("ParseStatement"); |
| (...skipping 1347 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 6420 return instance.raw(); | 6422 return instance.raw(); |
| 6421 } | 6423 } |
| 6422 | 6424 |
| 6423 | 6425 |
| 6424 // Do a lookup for the identifier in the block scope and the class scope | 6426 // Do a lookup for the identifier in the block scope and the class scope |
| 6425 // return true if the identifier is found, false otherwise. | 6427 // return true if the identifier is found, false otherwise. |
| 6426 // If node is non NULL return an AST node corresponding to the identifier. | 6428 // If node is non NULL return an AST node corresponding to the identifier. |
| 6427 bool Parser::ResolveIdentInLocalScope(intptr_t ident_pos, | 6429 bool Parser::ResolveIdentInLocalScope(intptr_t ident_pos, |
| 6428 const String &ident, | 6430 const String &ident, |
| 6429 AstNode** node) { | 6431 AstNode** node) { |
| 6432 ASSERT(node != NULL); |
| 6430 TRACE_PARSER("ResolveIdentInLocalScope"); | 6433 TRACE_PARSER("ResolveIdentInLocalScope"); |
| 6434 Isolate* isolate = Isolate::Current(); |
| 6431 // First try to find the identifier in the nested local scopes. | 6435 // First try to find the identifier in the nested local scopes. |
| 6432 LocalVariable* local = LookupLocalScope(ident); | 6436 LocalVariable* local = LookupLocalScope(ident); |
| 6433 if (local != NULL) { | 6437 if (local != NULL) { |
| 6434 if (node != NULL) { | 6438 *node = new LoadLocalNode(ident_pos, *local); |
| 6435 *node = new LoadLocalNode(ident_pos, *local); | |
| 6436 } | |
| 6437 return true; | 6439 return true; |
| 6438 } | 6440 } |
| 6439 | 6441 |
| 6440 // Try to find the identifier in the class scope. | 6442 // Try to find the identifier in the class scope. |
| 6441 Class& cls = Class::Handle(current_class().raw()); | 6443 Class& cls = Class::Handle(isolate, current_class().raw()); |
| 6442 Function& func = Function::Handle(); | 6444 Function& func = Function::Handle(isolate, Function::null()); |
| 6443 Field& field = Field::Handle(); | 6445 Field& field = Field::Handle(isolate, Field::null()); |
| 6446 String& accessor_name = String::Handle(isolate, String::null()); |
| 6444 while (!cls.IsNull()) { | 6447 while (!cls.IsNull()) { |
| 6445 // First check if a field exists. | 6448 // First check if a field exists. |
| 6446 field = cls.LookupInstanceField(ident); | 6449 field = cls.LookupField(ident); |
| 6447 if (!field.IsNull()) { | 6450 if (!field.IsNull()) { |
| 6448 if (node != NULL) { | 6451 if (!field.is_static()) { |
| 6449 CheckInstanceFieldAccess(ident_pos, ident); | 6452 CheckInstanceFieldAccess(ident_pos, ident); |
| 6450 *node = CallGetter(ident_pos, LoadReceiver(ident_pos), ident); | 6453 *node = CallGetter(ident_pos, LoadReceiver(ident_pos), ident); |
| 6451 } | 6454 } else { |
| 6452 return true; | |
| 6453 } | |
| 6454 field = cls.LookupStaticField(ident); | |
| 6455 if (!field.IsNull()) { | |
| 6456 if (node != NULL) { | |
| 6457 *node = GenerateStaticFieldLookup(field, ident_pos); | 6455 *node = GenerateStaticFieldLookup(field, ident_pos); |
| 6458 } | 6456 } |
| 6459 return true; | 6457 return true; |
| 6460 } | 6458 } |
| 6461 | 6459 |
| 6460 // Check if an instance/static function exists. |
| 6461 func = cls.LookupFunction(ident); |
| 6462 if (!func.IsNull() && |
| 6463 (func.IsDynamicFunction() || func.IsStaticFunction())) { |
| 6464 *node = new PrimaryNode(ident_pos, |
| 6465 Function::ZoneHandle(isolate, func.raw())); |
| 6466 return true; |
| 6467 } |
| 6468 |
| 6462 // Now check if a getter/setter method exists for it in which case | 6469 // Now check if a getter/setter method exists for it in which case |
| 6463 // it is still a field. | 6470 // it is still a field. |
| 6464 const String& getter_name = String::Handle(Field::GetterName(ident)); | 6471 accessor_name = Field::GetterName(ident); |
| 6465 func = cls.LookupDynamicFunction(getter_name); | 6472 func = cls.LookupFunction(accessor_name); |
| 6466 if (!func.IsNull()) { | 6473 if (!func.IsNull()) { |
| 6467 if (node != NULL) { | 6474 if (func.IsDynamicFunction()) { |
| 6468 CheckInstanceFieldAccess(ident_pos, ident); | 6475 CheckInstanceFieldAccess(ident_pos, ident); |
| 6469 ASSERT(AbstractType::Handle(func.result_type()).IsResolved()); | 6476 ASSERT(AbstractType::Handle(func.result_type()).IsResolved()); |
| 6470 *node = CallGetter(ident_pos, LoadReceiver(ident_pos), ident); | 6477 *node = CallGetter(ident_pos, LoadReceiver(ident_pos), ident); |
| 6471 } | 6478 return true; |
| 6472 return true; | 6479 } else if (func.IsStaticFunction()) { |
| 6473 } | |
| 6474 func = cls.LookupStaticFunction(getter_name); | |
| 6475 if (!func.IsNull()) { | |
| 6476 if (node != NULL) { | |
| 6477 ASSERT(AbstractType::Handle(func.result_type()).IsResolved()); | 6480 ASSERT(AbstractType::Handle(func.result_type()).IsResolved()); |
| 6478 *node = new StaticGetterNode(ident_pos, | 6481 *node = new StaticGetterNode(ident_pos, |
| 6479 Class::ZoneHandle(cls.raw()), | 6482 Class::ZoneHandle(isolate, cls.raw()), |
| 6480 ident); | 6483 ident); |
| 6484 return true; |
| 6481 } | 6485 } |
| 6482 return true; | |
| 6483 } | 6486 } |
| 6484 const String& setter_name = String::Handle(Field::SetterName(ident)); | 6487 accessor_name = Field::SetterName(ident); |
| 6485 func = cls.LookupDynamicFunction(setter_name); | 6488 func = cls.LookupFunction(accessor_name); |
| 6486 if (!func.IsNull()) { | 6489 if (!func.IsNull()) { |
| 6487 if (node != NULL) { | 6490 if (func.IsDynamicFunction()) { |
| 6488 // We create a getter node even though a getter doesn't exist as | 6491 // We create a getter node even though a getter doesn't exist as |
| 6489 // it could be followed by an assignment which will convert it to | 6492 // it could be followed by an assignment which will convert it to |
| 6490 // a setter node. If there is no assignment we will get an error | 6493 // a setter node. If there is no assignment we will get an error |
| 6491 // when we try to invoke the getter. | 6494 // when we try to invoke the getter. |
| 6492 CheckInstanceFieldAccess(ident_pos, ident); | 6495 CheckInstanceFieldAccess(ident_pos, ident); |
| 6493 ASSERT(AbstractType::Handle(func.result_type()).IsResolved()); | 6496 ASSERT(AbstractType::Handle(func.result_type()).IsResolved()); |
| 6494 *node = CallGetter(ident_pos, LoadReceiver(ident_pos), ident); | 6497 *node = CallGetter(ident_pos, LoadReceiver(ident_pos), ident); |
| 6495 } | 6498 return true; |
| 6496 return true; | 6499 } else if (func.IsStaticFunction()) { |
| 6497 } | |
| 6498 func = cls.LookupStaticFunction(setter_name); | |
| 6499 if (!func.IsNull()) { | |
| 6500 if (node != NULL) { | |
| 6501 // We create a getter node even though a getter doesn't exist as | 6500 // We create a getter node even though a getter doesn't exist as |
| 6502 // it could be followed by an assignment which will convert it to | 6501 // it could be followed by an assignment which will convert it to |
| 6503 // a setter node. If there is no assignment we will get an error | 6502 // a setter node. If there is no assignment we will get an error |
| 6504 // when we try to invoke the getter. | 6503 // when we try to invoke the getter. |
| 6505 *node = new StaticGetterNode(ident_pos, | 6504 *node = new StaticGetterNode(ident_pos, |
| 6506 Class::ZoneHandle(cls.raw()), | 6505 Class::ZoneHandle(isolate, cls.raw()), |
| 6507 ident); | 6506 ident); |
| 6507 return true; |
| 6508 } | 6508 } |
| 6509 return true; | |
| 6510 } | 6509 } |
| 6511 | 6510 |
| 6512 // Check if an instance/static function exists. | |
| 6513 func = cls.LookupDynamicFunction(ident); | |
| 6514 if (func.IsNull()) { | |
| 6515 func = cls.LookupStaticFunction(ident); | |
| 6516 } | |
| 6517 if (!func.IsNull()) { | |
| 6518 if (node != NULL) { | |
| 6519 *node = new PrimaryNode(ident_pos, Function::ZoneHandle(func.raw())); | |
| 6520 } | |
| 6521 return true; | |
| 6522 } | |
| 6523 cls = cls.SuperClass(); | 6511 cls = cls.SuperClass(); |
| 6524 } | 6512 } |
| 6525 if (node != NULL) { | 6513 *node = NULL; |
| 6526 *node = NULL; | |
| 6527 } | |
| 6528 return false; // Not an unqualified identifier. | 6514 return false; // Not an unqualified identifier. |
| 6529 } | 6515 } |
| 6530 | 6516 |
| 6531 | 6517 |
| 6532 // Do a lookup for the identifier in the library scope of the specified | 6518 // Do a lookup for the identifier in the library scope of the specified |
| 6533 // library. If resolve_locally is true the lookup does not consider | 6519 // library. If resolve_locally is true the lookup does not consider |
| 6534 // the libraries imported by it for the lookup. | 6520 // the libraries imported by it for the lookup. |
| 6535 AstNode* Parser::ResolveIdentInLibraryScope(const Library& lib, | 6521 AstNode* Parser::ResolveIdentInLibraryScope(const Library& lib, |
| 6536 const QualIdent& qual_ident, | 6522 const QualIdent& qual_ident, |
| 6537 bool resolve_locally) { | 6523 bool resolve_locally) { |
| (...skipping 1222 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 7760 } | 7746 } |
| 7761 | 7747 |
| 7762 | 7748 |
| 7763 void Parser::SkipNestedExpr() { | 7749 void Parser::SkipNestedExpr() { |
| 7764 const bool saved_mode = SetAllowFunctionLiterals(true); | 7750 const bool saved_mode = SetAllowFunctionLiterals(true); |
| 7765 SkipExpr(); | 7751 SkipExpr(); |
| 7766 SetAllowFunctionLiterals(saved_mode); | 7752 SetAllowFunctionLiterals(saved_mode); |
| 7767 } | 7753 } |
| 7768 | 7754 |
| 7769 } // namespace dart | 7755 } // namespace dart |
| OLD | NEW |