Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(498)

Side by Side Diff: runtime/vm/parser.cc

Issue 8591025: Fix parsing of factory calls (issue 500). (Closed) Base URL: http://dart.googlecode.com/svn/branches/bleeding_edge/dart/
Patch Set: Created 9 years, 1 month ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « no previous file | tests/co19/co19-runtime.status » ('j') | tests/co19/co19-runtime.status » ('J')
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright (c) 2011, the Dart project authors. Please see the AUTHORS file 1 // Copyright (c) 2011, 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 6447 matching lines...) Expand 10 before | Expand all | Expand 10 after
6458 intptr_t pos, Function& constructor, const TypeArguments& type_arguments) { 6458 intptr_t pos, Function& constructor, const TypeArguments& type_arguments) {
6459 if (!type_arguments.IsNull()) { 6459 if (!type_arguments.IsNull()) {
6460 Class& signature_class = Class::Handle(); 6460 Class& signature_class = Class::Handle();
6461 if (constructor.IsFactory()) { 6461 if (constructor.IsFactory()) {
6462 signature_class = constructor.signature_class(); 6462 signature_class = constructor.signature_class();
6463 } else { 6463 } else {
6464 signature_class = constructor.owner(); 6464 signature_class = constructor.owner();
6465 } 6465 }
6466 ASSERT(!signature_class.IsNull()); 6466 ASSERT(!signature_class.IsNull());
6467 ASSERT(signature_class.is_finalized()); 6467 ASSERT(signature_class.is_finalized());
6468 // Do not report the expected vs. actual number of type arguments, because
6469 // the type argument vector is flattened and raw types are allowed.
6468 if (type_arguments.Length() != signature_class.NumTypeArguments()) { 6470 if (type_arguments.Length() != signature_class.NumTypeArguments()) {
6469 ErrorMsg(pos, "incorrect number of type arguments, expected %d got %d", 6471 ErrorMsg(pos, "wrong number of type arguments passed to constructor");
6470 signature_class.NumTypeArguments(),
6471 type_arguments.Length());
6472 } 6472 }
6473 } 6473 }
6474 } 6474 }
6475 6475
6476 6476
6477 // Parse "[" [ expr { "," expr } ["," ] "]". 6477 // Parse "[" [ expr { "," expr } ["," ] "]".
6478 // Note: if the array literal is empty and the brackets have no whitespace 6478 // Note: if the array literal is empty and the brackets have no whitespace
6479 // between them, the scanner recognizes the opening and closing bracket 6479 // between them, the scanner recognizes the opening and closing bracket
6480 // as one token of type Token::kINDEX. 6480 // as one token of type Token::kINDEX.
6481 AstNode* Parser::ParseArrayLiteral(intptr_t type_pos, 6481 AstNode* Parser::ParseArrayLiteral(intptr_t type_pos,
(...skipping 262 matching lines...) Expand 10 before | Expand all | Expand 10 after
6744 if (CurrentToken() != Token::kIDENT) { 6744 if (CurrentToken() != Token::kIDENT) {
6745 ErrorMsg("type name expected"); 6745 ErrorMsg("type name expected");
6746 } 6746 }
6747 6747
6748 // The grammar allows for an optional ('.' identifier)?, which is a named 6748 // The grammar allows for an optional ('.' identifier)?, which is a named
6749 // constructor. For that reason, we cannot unconditionally call 6749 // constructor. For that reason, we cannot unconditionally call
6750 // ParseType(kMustResolve) after we see an identifier, because the named 6750 // ParseType(kMustResolve) after we see an identifier, because the named
6751 // constructor would be misinterpreted as a qualified type name. 6751 // constructor would be misinterpreted as a qualified type name.
6752 // TODO(regis): Revisit once we correctly support qualified identifiers. 6752 // TODO(regis): Revisit once we correctly support qualified identifiers.
6753 // For now, we inline a customized version of ParseType(kMustResolve). 6753 // For now, we inline a customized version of ParseType(kMustResolve).
6754 Type& type = Type::Handle();
6755 Class& type_class = Class::ZoneHandle();
6756 String& type_class_name = String::Handle();
6757 TypeArguments& type_arguments = TypeArguments::ZoneHandle();
6758 String* named_constructor = NULL;
6759 const intptr_t type_pos = token_index_; 6754 const intptr_t type_pos = token_index_;
6760 QualIdent type_name; 6755 QualIdent type_name;
6761 ParseQualIdent(&type_name); 6756 ParseQualIdent(&type_name);
6762 if (type_name.is_local_scope_ident) { 6757 if (type_name.is_local_scope_ident) {
6763 ErrorMsg(type_pos, "using '%s' in this context is invalid", 6758 ErrorMsg(type_pos, "using '%s' in this context is invalid",
6764 type_name.ident->ToCString()); 6759 type_name.ident->ToCString());
6765 } 6760 }
6761 String* named_constructor = NULL;
6766 if (CurrentToken() == Token::kPERIOD) { 6762 if (CurrentToken() == Token::kPERIOD) {
6767 ConsumeToken(); 6763 ConsumeToken();
6768 named_constructor = ExpectIdentifier("identifier expected after '.'"); 6764 named_constructor = ExpectIdentifier("identifier expected after '.'");
6769 } 6765 }
6770 const Class& scope_class = Class::Handle(TypeParametersScopeClass()); 6766 const Class& scope_class = Class::Handle(TypeParametersScopeClass());
6771 if (!scope_class.IsNull()) { 6767 if (!scope_class.IsNull()) {
6772 TypeParameter& type_parameter = TypeParameter::Handle(); 6768 TypeParameter& type_parameter = TypeParameter::Handle();
6773 if (type_name.lib_prefix != NULL) { 6769 if (type_name.lib_prefix != NULL) {
6774 // Check if qualifier is a type parameter in scope. 6770 // Check if qualifier is a type parameter in scope.
6775 type_parameter ^= scope_class.LookupTypeParameter(*type_name.qualifier); 6771 type_parameter ^= scope_class.LookupTypeParameter(*type_name.qualifier);
6776 if (!type_parameter.IsNull()) { 6772 if (!type_parameter.IsNull()) {
6777 ErrorMsg(type_pos, "type parameter '%s' cannot be used as qualifier", 6773 ErrorMsg(type_pos, "type parameter '%s' cannot be used as qualifier",
6778 String::Handle(type_parameter.Name()).ToCString()); 6774 String::Handle(type_parameter.Name()).ToCString());
6779 } 6775 }
6780 } 6776 }
6781 // Check if ident is a type parameter in scope. 6777 // Check if ident is a type parameter in scope.
6782 type_parameter = scope_class.LookupTypeParameter(*type_name.ident); 6778 type_parameter = scope_class.LookupTypeParameter(*type_name.ident);
6783 if (!type_parameter.IsNull()) { 6779 if (!type_parameter.IsNull()) {
6784 ErrorMsg(type_pos, "type parameter '%s' cannot be instantiated", 6780 ErrorMsg(type_pos, "type parameter '%s' cannot be instantiated",
6785 String::Handle(type_parameter.Name()).ToCString()); 6781 String::Handle(type_parameter.Name()).ToCString());
6786 } 6782 }
6787 } 6783 }
6784 Class& type_class = Class::ZoneHandle();
6788 type_class ^= LookupTypeClass(type_name, kMustResolve); 6785 type_class ^= LookupTypeClass(type_name, kMustResolve);
6786 String& type_class_name = String::Handle();
6789 type_class_name = type_class.Name(); 6787 type_class_name = type_class.Name();
6788 TypeArguments& type_arguments = TypeArguments::ZoneHandle();
6790 // Type arguments are not allowed after the optional constructor name. 6789 // Type arguments are not allowed after the optional constructor name.
6791 if (named_constructor == NULL) { 6790 if (named_constructor == NULL) {
6792 type_arguments = ParseTypeArguments(kMustResolve); 6791 type_arguments = ParseTypeArguments(kMustResolve);
6793 type = Type::NewParameterizedType(type_class, type_arguments);
6794 String& errmsg = String::Handle();
6795 type = ClassFinalizer::FinalizeAndCanonicalizeType(type, &errmsg);
6796 if (!errmsg.IsNull()) {
6797 ErrorMsg(errmsg.ToCString());
6798 }
6799 // The type argument vector may have been expanded with the type arguments
6800 // of the super type when finalizing the type.
6801 type_arguments = type.arguments();
6802 } 6792 }
6803 if ((named_constructor == NULL) && (CurrentToken() == Token::kPERIOD)) { 6793 if ((named_constructor == NULL) && (CurrentToken() == Token::kPERIOD)) {
6804 ConsumeToken(); 6794 ConsumeToken();
6805 named_constructor = ExpectIdentifier("name of constructor expected"); 6795 named_constructor = ExpectIdentifier("name of constructor expected");
6806 } 6796 }
6807 6797
6808 // Parse constructor parameters. 6798 // Parse constructor parameters.
6809 if (CurrentToken() != Token::kLPAREN) { 6799 if (CurrentToken() != Token::kLPAREN) {
6810 ErrorMsg("'(' expected"); 6800 ErrorMsg("'(' expected");
6811 } 6801 }
(...skipping 67 matching lines...) Expand 10 before | Expand all | Expand 10 after
6879 String::Handle(type_class.Name()).ToCString(), 6869 String::Handle(type_class.Name()).ToCString(),
6880 external_constructor_name.ToCString()); 6870 external_constructor_name.ToCString());
6881 } 6871 }
6882 if (!constructor.AreValidArguments(arguments_length, arguments->names())) { 6872 if (!constructor.AreValidArguments(arguments_length, arguments->names())) {
6883 ErrorMsg(new_pos, "invalid arguments passed to constructor '%s' " 6873 ErrorMsg(new_pos, "invalid arguments passed to constructor '%s' "
6884 "for class '%s'", 6874 "for class '%s'",
6885 external_constructor_name.ToCString(), 6875 external_constructor_name.ToCString(),
6886 String::Handle(type_class.Name()).ToCString()); 6876 String::Handle(type_class.Name()).ToCString());
6887 } 6877 }
6888 6878
6879 // Now that the constructor to be called is identified, finalize the type
6880 // argument vector to be passed.
6881 {
6882 Class& signature_class = Class::Handle();
6883 if (constructor.IsFactory()) {
6884 signature_class = constructor.signature_class();
6885 } else {
6886 signature_class = constructor.owner();
6887 ASSERT(signature_class.raw() == type_class.raw());
6888 }
6889 // TODO(regis): Temporary type should be allocated in new gen heap.
6890 Type& type = Type::Handle(
6891 Type::NewParameterizedType(signature_class, type_arguments));
6892 String& errmsg = String::Handle();
6893 type = ClassFinalizer::FinalizeAndCanonicalizeType(type, &errmsg);
6894 if (!errmsg.IsNull()) {
6895 ErrorMsg(errmsg.ToCString());
6896 }
6897 // The type argument vector may have been expanded with the type arguments
6898 // of the super type when finalizing the type.
6899 type_arguments = type.arguments();
6900 }
6901
6902 // Make the constructor call.
6889 AstNode* new_object = NULL; 6903 AstNode* new_object = NULL;
6890 if (is_const) { 6904 if (is_const) {
6891 if (!constructor.is_const()) { 6905 if (!constructor.is_const()) {
6892 ErrorMsg("'const' requires const constructor: '%s'", 6906 ErrorMsg("'const' requires const constructor: '%s'",
6893 String::Handle(constructor.name()).ToCString()); 6907 String::Handle(constructor.name()).ToCString());
6894 } 6908 }
6895 const Instance& const_instance = Instance::ZoneHandle( 6909 const Instance& const_instance = Instance::ZoneHandle(
6896 EvaluateConstConstructorCall(type_class, 6910 EvaluateConstConstructorCall(type_class,
6897 type_arguments, 6911 type_arguments,
6898 constructor, 6912 constructor,
6899 arguments)); 6913 arguments));
6900 if (const_instance.IsUnhandledException()) { 6914 if (const_instance.IsUnhandledException()) {
6901 new_object = CreateEvalConstConstructorThrow(new_pos, const_instance); 6915 new_object = CreateEvalConstConstructorThrow(new_pos, const_instance);
6902 } else { 6916 } else {
6903 new_object = new LiteralNode(new_pos, const_instance); 6917 new_object = new LiteralNode(new_pos, const_instance);
6904 } 6918 }
6905 } else { 6919 } else {
6906 CheckFunctionIsCallable(new_pos, constructor); 6920 CheckFunctionIsCallable(new_pos, constructor);
6921 CheckConstructorCallTypeArguments(new_pos, constructor, type_arguments);
6907 if (!type_arguments.IsNull() && 6922 if (!type_arguments.IsNull() &&
6908 !type_arguments.IsInstantiated() && 6923 !type_arguments.IsInstantiated() &&
6909 (current_block_->scope->function_level() > 0)) { 6924 (current_block_->scope->function_level() > 0)) {
6910 // Make sure that the instantiator is captured. 6925 // Make sure that the instantiator is captured.
6911 CaptureReceiver(); 6926 CaptureReceiver();
6912 } 6927 }
6913 CheckConstructorCallTypeArguments(new_pos, constructor, type_arguments);
6914 new_object = new ConstructorCallNode( 6928 new_object = new ConstructorCallNode(
6915 new_pos, type_arguments, constructor, arguments); 6929 new_pos, type_arguments, constructor, arguments);
6916 } 6930 }
6917 return new_object; 6931 return new_object;
6918 } 6932 }
6919 6933
6920 6934
6921 // A string literal consists of the concatenation of the next n tokens 6935 // A string literal consists of the concatenation of the next n tokens
6922 // that satisfy the EBNF grammar: 6936 // that satisfy the EBNF grammar:
6923 // literal = kSTRING {{ interpol }+ kSTRING } 6937 // literal = kSTRING {{ interpol }+ kSTRING }
(...skipping 424 matching lines...) Expand 10 before | Expand all | Expand 10 after
7348 } 7362 }
7349 7363
7350 7364
7351 void Parser::SkipNestedExpr() { 7365 void Parser::SkipNestedExpr() {
7352 const bool saved_mode = SetAllowFunctionLiterals(true); 7366 const bool saved_mode = SetAllowFunctionLiterals(true);
7353 SkipExpr(); 7367 SkipExpr();
7354 SetAllowFunctionLiterals(saved_mode); 7368 SetAllowFunctionLiterals(saved_mode);
7355 } 7369 }
7356 7370
7357 } // namespace dart 7371 } // namespace dart
OLDNEW
« no previous file with comments | « no previous file | tests/co19/co19-runtime.status » ('j') | tests/co19/co19-runtime.status » ('J')

Powered by Google App Engine
This is Rietveld 408576698