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

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

Issue 1255063005: Constructor tear-off closures (Closed) Base URL: https://github.com/dart-lang/sdk.git@master
Patch Set: Skip tearoff test in analyzer and dart2js Created 5 years, 4 months 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
« no previous file with comments | « runtime/vm/parser.h ('k') | runtime/vm/symbols.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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/ast_transformer.h" 9 #include "vm/ast_transformer.h"
10 #include "vm/bootstrap.h" 10 #include "vm/bootstrap.h"
(...skipping 813 matching lines...) Expand 10 before | Expand all | Expand 10 after
824 Error& error = Error::Handle(); 824 Error& error = Error::Handle();
825 error = isolate->object_store()->sticky_error(); 825 error = isolate->object_store()->sticky_error();
826 isolate->object_store()->clear_sticky_error(); 826 isolate->object_store()->clear_sticky_error();
827 return error.raw(); 827 return error.raw();
828 } 828 }
829 UNREACHABLE(); 829 UNREACHABLE();
830 return Object::null(); 830 return Object::null();
831 } 831 }
832 832
833 833
834 bool Parser::ParseFormalParameters(const Function& func, ParamList* params) {
835 ASSERT(!func.IsNull());
836 // This is currently only used for constructors. To handle all kinds
837 // of functions, special cases for getters and posibly other kinds
regis 2015/08/03 21:51:35 possibly
hausner 2015/08/03 22:52:16 Done.
838 // need to be added.
839 ASSERT(func.kind() == RawFunction::kConstructor);
840 ASSERT(!func.IsRedirectingFactory());
841 // Implicit constructors have no source, no user-defined formal parameters.
842 if (func.IsImplicitConstructor()) {
843 return true;
844 }
845 LongJumpScope jump;
846 if (setjmp(*jump.Set()) == 0) {
847 const Script& script = Script::Handle(func.script());
srdjan 2015/08/03 23:27:30 Handle(isolate(), ...)
hausner 2015/08/03 23:52:21 This is in a static method, so isolate() is not av
848 const Class& owner = Class::Handle(func.Owner());
849 ASSERT(!owner.IsNull());
850 ParsedFunction* parsed_function =
851 new ParsedFunction(Thread::Current(), Function::ZoneHandle(func.raw()));
852 Parser parser(script, parsed_function, func.token_pos());
853 parser.SkipFunctionPreamble();
854 parser.ParseFormalParameterList(true, true, params);
855 return true;
856 } else {
857 Thread::Current()->isolate()->object_store()->clear_sticky_error();
srdjan 2015/08/03 23:27:30 Parser has isolate_ field: isolate()->object_store
hausner 2015/08/03 23:52:21 same here.
858 params->Clear();
859 return false;
860 }
861 UNREACHABLE();
862 return false;
863 }
864
865
834 void Parser::ParseFunction(ParsedFunction* parsed_function) { 866 void Parser::ParseFunction(ParsedFunction* parsed_function) {
835 Isolate* isolate = parsed_function->isolate(); 867 Isolate* isolate = parsed_function->isolate();
836 Zone* zone = parsed_function->zone(); 868 Zone* zone = parsed_function->zone();
837 CSTAT_TIMER_SCOPE(isolate, parser_timer); 869 CSTAT_TIMER_SCOPE(isolate, parser_timer);
838 INC_STAT(isolate, num_functions_compiled, 1); 870 INC_STAT(isolate, num_functions_compiled, 1);
839 ASSERT(isolate->long_jump_base()->IsSafeToJump()); 871 ASSERT(isolate->long_jump_base()->IsSafeToJump());
840 ASSERT(parsed_function != NULL); 872 ASSERT(parsed_function != NULL);
841 const Function& func = parsed_function->function(); 873 const Function& func = parsed_function->function();
842 const Script& script = Script::Handle(zone, func.script()); 874 const Script& script = Script::Handle(zone, func.script());
843 Parser parser(script, parsed_function, func.token_pos()); 875 Parser parser(script, parsed_function, func.token_pos());
844 SequenceNode* node_sequence = NULL; 876 SequenceNode* node_sequence = NULL;
845 Array& default_parameter_values = Array::ZoneHandle(zone, Array::null()); 877 Array& default_parameter_values = Array::ZoneHandle(zone, Array::null());
846 switch (func.kind()) { 878 switch (func.kind()) {
847 case RawFunction::kClosureFunction: 879 case RawFunction::kClosureFunction:
848 if (func.IsImplicitClosureFunction()) { 880 if (func.IsImplicitClosureFunction()) {
849 node_sequence = 881 node_sequence =
850 parser.ParseImplicitClosure(func, &default_parameter_values); 882 parser.ParseImplicitClosure(func, &default_parameter_values);
851 break; 883 break;
852 } 884 }
885 if (func.IsConstructorClosureFunction()) {
886 node_sequence =
887 parser.ParseConstructorClosure(func, &default_parameter_values);
888 break;
889 }
853 // Fall-through: Handle non-implicit closures. 890 // Fall-through: Handle non-implicit closures.
854 case RawFunction::kRegularFunction: 891 case RawFunction::kRegularFunction:
855 case RawFunction::kGetterFunction: 892 case RawFunction::kGetterFunction:
856 case RawFunction::kSetterFunction: 893 case RawFunction::kSetterFunction:
857 case RawFunction::kConstructor: 894 case RawFunction::kConstructor:
858 // The call to a redirecting factory is redirected. 895 // The call to a redirecting factory is redirected.
859 ASSERT(!func.IsRedirectingFactory()); 896 ASSERT(!func.IsRedirectingFactory());
860 if (!func.IsImplicitConstructor()) { 897 if (!func.IsImplicitConstructor()) {
861 parser.SkipFunctionPreamble(); 898 parser.SkipFunctionPreamble();
862 } 899 }
(...skipping 412 matching lines...) Expand 10 before | Expand all | Expand 10 after
1275 1312
1276 EnsureExpressionTemp(); 1313 EnsureExpressionTemp();
1277 StoreInstanceFieldNode* store_field = 1314 StoreInstanceFieldNode* store_field =
1278 new StoreInstanceFieldNode(ident_pos, receiver, field, value); 1315 new StoreInstanceFieldNode(ident_pos, receiver, field, value);
1279 current_block_->statements->Add(store_field); 1316 current_block_->statements->Add(store_field);
1280 current_block_->statements->Add(new ReturnNode(Scanner::kNoSourcePos)); 1317 current_block_->statements->Add(new ReturnNode(Scanner::kNoSourcePos));
1281 return CloseBlock(); 1318 return CloseBlock();
1282 } 1319 }
1283 1320
1284 1321
1322 SequenceNode* Parser::ParseConstructorClosure(const Function& func,
1323 Array* default_values) {
1324 TRACE_PARSER("ParseConstructorClosure");
1325 const intptr_t token_pos = func.token_pos();
1326
1327 Function& constructor = Function::ZoneHandle(Z);
1328 TypeArguments& type_args = TypeArguments::ZoneHandle(Z);
1329 ParseConstructorClosurization(&constructor, &type_args);
1330 ASSERT(!constructor.IsNull());
1331
1332 ParamList params;
1333 // The first parameter of the closure function is the implicit closure
1334 // argument.
1335 params.AddFinalParameter(token_pos,
1336 &Symbols::ClosureParameter(),
1337 &Type::ZoneHandle(Z, Type::DynamicType()));
1338 bool params_ok = ParseFormalParameters(constructor, &params);
1339 if (!params_ok) {
1340 UNREACHABLE();
regis 2015/08/03 21:51:35 Is this leftover debug code?
hausner 2015/08/03 22:52:16 It's a case that should never happen, because the
1341 }
1342 SetupDefaultsForOptionalParams(&params, default_values);
1343 ASSERT(func.num_fixed_parameters() == params.num_fixed_parameters);
1344 ASSERT(func.NumOptionalParameters() == params.num_optional_parameters);
1345
1346 OpenFunctionBlock(func);
1347 LocalScope* scope = current_block_->scope;
1348 AddFormalParamsToScope(&params, scope);
1349
1350 ArgumentListNode* ctor_args = new ArgumentListNode(token_pos);
1351 // Skip implicit closure parameter at 0.
1352 for (intptr_t i = 1; i < func.NumParameters(); i++) {
1353 ctor_args->Add(new LoadLocalNode(token_pos, scope->VariableAt(i)));
1354 }
1355
1356 if (func.HasOptionalNamedParameters()) {
1357 const Array& arg_names =
1358 Array::ZoneHandle(Array::New(func.NumOptionalParameters()));
1359 for (intptr_t i = 0; i < arg_names.Length(); i++) {
1360 intptr_t index = func.num_fixed_parameters() + i;
1361 arg_names.SetAt(i, String::Handle(func.ParameterNameAt(index)));
1362 }
1363 ctor_args->set_names(arg_names);
1364 }
1365
1366 AstNode* new_object =
1367 CreateConstructorCallNode(token_pos, type_args, constructor, ctor_args);
1368 ReturnNode* return_node = new ReturnNode(token_pos, new_object);
1369 current_block_->statements->Add(return_node);
1370 return CloseBlock();
1371 }
1372
1373
1285 SequenceNode* Parser::ParseImplicitClosure(const Function& func, 1374 SequenceNode* Parser::ParseImplicitClosure(const Function& func,
1286 Array* default_values) { 1375 Array* default_values) {
1287 TRACE_PARSER("ParseImplicitClosure"); 1376 TRACE_PARSER("ParseImplicitClosure");
1288 intptr_t token_pos = func.token_pos(); 1377 intptr_t token_pos = func.token_pos();
1289 1378
1290 OpenFunctionBlock(func); 1379 OpenFunctionBlock(func);
1291 1380
1292 ParamList params; 1381 ParamList params;
1293 params.AddFinalParameter( 1382 params.AddFinalParameter(
1294 token_pos, 1383 token_pos,
(...skipping 6180 matching lines...) Expand 10 before | Expand all | Expand 10 after
7475 ASSERT(current_class().is_finalized()); 7564 ASSERT(current_class().is_finalized());
7476 7565
7477 // Make sure that the instantiator is captured. 7566 // Make sure that the instantiator is captured.
7478 if ((signature_class.NumTypeParameters() > 0) && 7567 if ((signature_class.NumTypeParameters() > 0) &&
7479 (current_block_->scope->function_level() > 0)) { 7568 (current_block_->scope->function_level() > 0)) {
7480 CaptureInstantiator(); 7569 CaptureInstantiator();
7481 } 7570 }
7482 7571
7483 // Since the signature type is cached by the signature class, it may have 7572 // Since the signature type is cached by the signature class, it may have
7484 // been finalized already. 7573 // been finalized already.
7485 Type& signature_type = Type::Handle(Z, 7574 Type& signature_type =
7486 signature_class.SignatureType()); 7575 Type::Handle(Z, signature_class.SignatureType());
7487 TypeArguments& signature_type_arguments = TypeArguments::Handle(Z, 7576 TypeArguments& signature_type_arguments =
7488 signature_type.arguments()); 7577 TypeArguments::Handle(Z, signature_type.arguments());
7489 7578
7490 if (!signature_type.IsFinalized()) { 7579 if (!signature_type.IsFinalized()) {
7491 signature_type ^= ClassFinalizer::FinalizeType( 7580 signature_type ^= ClassFinalizer::FinalizeType(
7492 signature_class, signature_type, ClassFinalizer::kCanonicalize); 7581 signature_class, signature_type, ClassFinalizer::kCanonicalize);
7493 7582
7494 // The call to ClassFinalizer::FinalizeType may have 7583 // The call to ClassFinalizer::FinalizeType may have
7495 // extended the vector of type arguments. 7584 // extended the vector of type arguments.
7496 signature_type_arguments = signature_type.arguments(); 7585 signature_type_arguments = signature_type.arguments();
7497 ASSERT(signature_type_arguments.IsNull() || 7586 ASSERT(signature_type_arguments.IsNull() ||
7498 (signature_type_arguments.Length() == 7587 (signature_type_arguments.Length() ==
(...skipping 5253 matching lines...) Expand 10 before | Expand all | Expand 10 after
12752 ReportErrors(Error::Cast(result), 12841 ReportErrors(Error::Cast(result),
12753 script_, symbol_pos, 12842 script_, symbol_pos,
12754 "error executing const Symbol constructor"); 12843 "error executing const Symbol constructor");
12755 } 12844 }
12756 const Instance& instance = Instance::Cast(result); 12845 const Instance& instance = Instance::Cast(result);
12757 return new(Z) LiteralNode(symbol_pos, 12846 return new(Z) LiteralNode(symbol_pos,
12758 Instance::ZoneHandle(Z, instance.raw())); 12847 Instance::ZoneHandle(Z, instance.raw()));
12759 } 12848 }
12760 12849
12761 12850
12851 RawFunction* Parser::BuildConstructorClosureFunction(const Function& ctr,
12852 intptr_t token_pos) {
12853 ASSERT(ctr.kind() == RawFunction::kConstructor);
12854 String& closure_name = String::Handle(Z, ctr.name());
12855 closure_name = Symbols::FromConcat(Symbols::ConstructorClosurePrefix(),
12856 closure_name);
12857 ParamList params;
12858 params.AddFinalParameter(token_pos,
12859 &Symbols::ClosureParameter(),
12860 &Type::ZoneHandle(Z, Type::DynamicType()));
12861
12862 ParseFormalParameters(ctr, &params);
12863 Function& closure = Function::Handle(Z);
12864 closure = Function::NewClosureFunction(closure_name,
12865 innermost_function(),
12866 token_pos);
12867 closure.set_is_generated_body(true);
12868 closure.set_result_type(AbstractType::Handle(Type::DynamicType()));
12869 AddFormalParamsToFunction(&params, closure);
12870
12871 // Create and set the signature class of the closure.
12872 const String& sig = String::Handle(Z, closure.Signature());
12873 Class& sig_cls = Class::Handle(Z, library_.LookupLocalClass(sig));
12874 if (sig_cls.IsNull()) {
12875 sig_cls = Class::NewSignatureClass(sig, closure, script_, token_pos);
12876 library_.AddClass(sig_cls);
12877 }
12878 closure.set_signature_class(sig_cls);
12879 const Type& sig_type = Type::Handle(Z, sig_cls.SignatureType());
12880 if (!sig_type.IsFinalized()) {
regis 2015/08/03 21:51:35 Better make sure we are not top level parsing, or
hausner 2015/08/03 22:52:16 Done.
12881 ClassFinalizer::FinalizeType(sig_cls,
12882 sig_type,
12883 ClassFinalizer::kCanonicalize);
12884 }
12885 return closure.raw();
12886 }
12887
12888
12762 static String& BuildConstructorName(const String& type_class_name, 12889 static String& BuildConstructorName(const String& type_class_name,
12763 const String* named_constructor) { 12890 const String* named_constructor) {
12764 // By convention, the static function implementing a named constructor 'C' 12891 // By convention, the static function implementing a named constructor 'C'
12765 // for class 'A' is labeled 'A.C', and the static function implementing the 12892 // for class 'A' is labeled 'A.C', and the static function implementing the
12766 // unnamed constructor for class 'A' is labeled 'A.'. 12893 // unnamed constructor for class 'A' is labeled 'A.'.
12767 // This convention prevents users from explicitly calling constructors. 12894 // This convention prevents users from explicitly calling constructors.
12768 String& constructor_name = 12895 String& constructor_name =
12769 String::Handle(String::Concat(type_class_name, Symbols::Dot())); 12896 String::Handle(String::Concat(type_class_name, Symbols::Dot()));
12770 if (named_constructor != NULL) { 12897 if (named_constructor != NULL) {
12771 constructor_name = String::Concat(constructor_name, *named_constructor); 12898 constructor_name = String::Concat(constructor_name, *named_constructor);
12772 } 12899 }
12773 return constructor_name; 12900 return constructor_name;
12774 } 12901 }
12775 12902
12776 12903
12904 // Parse a primary expression of the form new T# or new T#m.
12905 // Current token position is after the keyword new. Extracts the
12906 // anonymous or named constructor and type arguments.
12907 // Note that type type T has already been parsed before
12908 // (by ParseNewOperator()) and is guaranteed to be well-formed,
12909 // and the constructor is known to exist.
12910 void Parser::ParseConstructorClosurization(Function* constructor,
12911 TypeArguments* type_arguments) {
12912 *constructor = Function::null();
12913 *type_arguments = TypeArguments::null();
12914 const Token::Kind la3 = LookaheadToken(3);
12915 const bool consume_unresolved_prefix =
12916 (la3 == Token::kLT) || (la3 == Token::kPERIOD) || (la3 == Token::kHASH);
12917 LibraryPrefix& prefix = LibraryPrefix::ZoneHandle(Z);
12918 AbstractType& type = AbstractType::Handle(Z,
12919 ParseType(ClassFinalizer::kCanonicalizeWellFormed,
12920 true, // allow deferred type
12921 consume_unresolved_prefix,
12922 &prefix));
12923 // A constructor tear-off closure can only have been created for a
12924 // type that is loaded.
12925 ASSERT(prefix.IsNull() || prefix.is_loaded());
12926 ASSERT(!type.IsMalformed() && !type.IsTypeParameter());
12927 ExpectToken(Token::kHASH);
12928 String* named_constructor = NULL;
12929 if (IsIdentifier()) {
12930 named_constructor = CurrentLiteral();
12931 ConsumeToken();
12932 }
12933 // Resolve the type and optional identifier to a constructor or factory.
12934 Class& type_class = Class::Handle(Z, type.type_class());
12935 String& type_class_name = String::Handle(Z, type_class.Name());
12936 *type_arguments = type.arguments();
12937 String& constructor_name =
12938 BuildConstructorName(type_class_name, named_constructor);
12939 *constructor = type_class.LookupConstructor(constructor_name);
12940 if (constructor->IsNull()) {
12941 *constructor = type_class.LookupFactory(constructor_name);
12942 ASSERT(!constructor->IsNull());
12943 if (constructor->IsRedirectingFactory()) {
12944 ClassFinalizer::ResolveRedirectingFactory(type_class, *constructor);
12945 type = constructor->RedirectionType();
12946 ASSERT(!type.IsMalformedOrMalbounded());
12947 if (!type.IsInstantiated()) {
12948 Error& error = Error::Handle(Z);
12949 type ^= type.InstantiateFrom(*type_arguments, &error);
12950 ASSERT(error.IsNull());
12951 }
12952 *type_arguments = type.arguments();
12953 *constructor = constructor->RedirectionTarget();
12954 }
12955 }
12956 }
12957
12958
12777 AstNode* Parser::ParseNewOperator(Token::Kind op_kind) { 12959 AstNode* Parser::ParseNewOperator(Token::Kind op_kind) {
12778 TRACE_PARSER("ParseNewOperator"); 12960 TRACE_PARSER("ParseNewOperator");
12779 const intptr_t new_pos = TokenPos(); 12961 const intptr_t new_pos = TokenPos();
12780 ASSERT((op_kind == Token::kNEW) || (op_kind == Token::kCONST)); 12962 ASSERT((op_kind == Token::kNEW) || (op_kind == Token::kCONST));
12781 bool is_const = (op_kind == Token::kCONST); 12963 bool is_const = (op_kind == Token::kCONST);
12782 if (!IsIdentifier()) { 12964 if (!IsIdentifier()) {
12783 ReportError("type name expected"); 12965 ReportError("type name expected");
12784 } 12966 }
12785 intptr_t type_pos = TokenPos(); 12967 intptr_t type_pos = TokenPos();
12786 // Can't allocate const objects of a deferred type. 12968 // Can't allocate const objects of a deferred type.
12787 const bool allow_deferred_type = !is_const; 12969 const bool allow_deferred_type = !is_const;
12788 const Token::Kind la3 = LookaheadToken(3); 12970 const Token::Kind la3 = LookaheadToken(3);
12789 const bool consume_unresolved_prefix = 12971 const bool consume_unresolved_prefix =
12790 (la3 == Token::kLT) || (la3 == Token::kPERIOD) || (la3 == Token::kHASH); 12972 (la3 == Token::kLT) || (la3 == Token::kPERIOD) || (la3 == Token::kHASH);
12791 12973
12792 LibraryPrefix& prefix = LibraryPrefix::ZoneHandle(Z); 12974 LibraryPrefix& prefix = LibraryPrefix::ZoneHandle(Z);
12793 AbstractType& type = AbstractType::Handle(Z, 12975 AbstractType& type = AbstractType::Handle(Z,
12794 ParseType(ClassFinalizer::kCanonicalizeWellFormed, 12976 ParseType(ClassFinalizer::kCanonicalizeWellFormed,
12795 allow_deferred_type, 12977 allow_deferred_type,
12796 consume_unresolved_prefix, 12978 consume_unresolved_prefix,
12797 &prefix)); 12979 &prefix));
12798 if (CurrentToken() == Token::kHASH) { 12980
12799 ReportError("constructor closurization not yet supported");
12800 }
12801 if (FLAG_load_deferred_eagerly && 12981 if (FLAG_load_deferred_eagerly &&
12802 !prefix.IsNull() && prefix.is_deferred_load() && !prefix.is_loaded()) { 12982 !prefix.IsNull() && prefix.is_deferred_load() && !prefix.is_loaded()) {
12803 // Add runtime check. 12983 // Add runtime check.
12804 Type& malformed_type = Type::Handle(Z); 12984 Type& malformed_type = Type::Handle(Z);
12805 malformed_type = ClassFinalizer::NewFinalizedMalformedType( 12985 malformed_type = ClassFinalizer::NewFinalizedMalformedType(
12806 Error::Handle(Z), // No previous error. 12986 Error::Handle(Z), // No previous error.
12807 script_, 12987 script_,
12808 type_pos, 12988 type_pos,
12809 "deferred type '%s.%s' is not yet loaded", 12989 "deferred type '%s.%s' is not yet loaded",
12810 String::Handle(Z, prefix.name()).ToCString(), 12990 String::Handle(Z, prefix.name()).ToCString(),
(...skipping 17 matching lines...) Expand all
12828 String::Handle(Z, type.UserVisibleName()).ToCString() : 13008 String::Handle(Z, type.UserVisibleName()).ToCString() :
12829 "dynamic"); 13009 "dynamic");
12830 } 13010 }
12831 // Attempting to instantiate an enum type is a compile-time error. 13011 // Attempting to instantiate an enum type is a compile-time error.
12832 Class& type_class = Class::Handle(Z, type.type_class()); 13012 Class& type_class = Class::Handle(Z, type.type_class());
12833 if (type_class.is_enum_class()) { 13013 if (type_class.is_enum_class()) {
12834 ReportError(new_pos, "enum type '%s' can not be instantiated", 13014 ReportError(new_pos, "enum type '%s' can not be instantiated",
12835 String::Handle(Z, type_class.Name()).ToCString()); 13015 String::Handle(Z, type_class.Name()).ToCString());
12836 } 13016 }
12837 13017
12838 // The grammar allows for an optional ('.' identifier)? after the type, which 13018 // The type can be followed by an optional named constructor identifier.
12839 // is a named constructor. Note that we tell ParseType() above not to 13019 // Note that we tell ParseType() above not to consume it as part of
12840 // consume it as part of a misinterpreted qualified identifier. Only a 13020 // a misinterpreted qualified identifier. Only a valid library
12841 // valid library prefix is accepted as qualifier. 13021 // prefix is accepted as qualifier.
12842 String* named_constructor = NULL; 13022 String* named_constructor = NULL;
12843 if (CurrentToken() == Token::kPERIOD) { 13023 const bool is_tearoff_expression = (CurrentToken() == Token::kHASH);
13024 if (is_tearoff_expression) {
13025 if (is_const) {
13026 ReportError("tear-off closure not allowed with const allocation");
13027 }
13028 ConsumeToken();
13029 if (IsIdentifier()) {
13030 named_constructor = ExpectIdentifier("name of constructor expected");
13031 }
13032 } else if (CurrentToken() == Token::kPERIOD) {
12844 ConsumeToken(); 13033 ConsumeToken();
12845 named_constructor = ExpectIdentifier("name of constructor expected"); 13034 named_constructor = ExpectIdentifier("name of constructor expected");
12846 } 13035 }
12847 13036
12848 // Parse constructor parameters. 13037 // Parse constructor parameters.
12849 CheckToken(Token::kLPAREN);
12850 intptr_t call_pos = TokenPos(); 13038 intptr_t call_pos = TokenPos();
12851 ArgumentListNode* arguments = ParseActualParameters(NULL, is_const); 13039 ArgumentListNode* arguments = NULL;
13040 if (!is_tearoff_expression) {
13041 CheckToken(Token::kLPAREN);
13042 call_pos = TokenPos();
13043 arguments = ParseActualParameters(NULL, is_const);
13044 } else {
13045 // Allocate dummy node with no arguments so we don't have to deal
13046 // with the NULL corner case below.
13047 arguments = new(Z) ArgumentListNode(TokenPos());
13048 }
12852 13049
12853 // Parsing is complete, so we can return a throw in case of a malformed or 13050 // Parsing is complete, so we can return a throw in case of a malformed or
12854 // malbounded type or report a compile-time error if the constructor is const. 13051 // malbounded type or report a compile-time error if the constructor is const.
12855 if (type.IsMalformedOrMalbounded()) { 13052 if (type.IsMalformedOrMalbounded()) {
12856 if (is_const) { 13053 if (is_const) {
12857 const Error& error = Error::Handle(Z, type.error()); 13054 const Error& error = Error::Handle(Z, type.error());
12858 ReportError(error); 13055 ReportError(error);
12859 } 13056 }
12860 return ThrowTypeError(type_pos, type); 13057 return ThrowTypeError(type_pos, type);
12861 } 13058 }
(...skipping 97 matching lines...) Expand 10 before | Expand all | Expand 10 after
12959 type_arguments = type.arguments(); 13156 type_arguments = type.arguments();
12960 constructor = constructor.RedirectionTarget(); 13157 constructor = constructor.RedirectionTarget();
12961 constructor_name = constructor.name(); 13158 constructor_name = constructor.name();
12962 ASSERT(!constructor.IsNull()); 13159 ASSERT(!constructor.IsNull());
12963 } 13160 }
12964 if (constructor.IsFactory()) { 13161 if (constructor.IsFactory()) {
12965 // A factory does not have the implicit 'phase' parameter. 13162 // A factory does not have the implicit 'phase' parameter.
12966 arguments_length -= 1; 13163 arguments_length -= 1;
12967 } 13164 }
12968 } 13165 }
13166 ASSERT(!constructor.IsNull());
12969 13167
12970 // It is ok to call a factory method of an abstract class, but it is 13168 // It is ok to call a factory method of an abstract class, but it is
12971 // a dynamic error to instantiate an abstract class. 13169 // a dynamic error to instantiate an abstract class.
12972 ASSERT(!constructor.IsNull());
12973 if (type_class.is_abstract() && !constructor.IsFactory()) { 13170 if (type_class.is_abstract() && !constructor.IsFactory()) {
12974 // Evaluate arguments before throwing. 13171 // Evaluate arguments before throwing.
12975 LetNode* result = new(Z) LetNode(call_pos); 13172 LetNode* result = new(Z) LetNode(call_pos);
12976 for (intptr_t i = 0; i < arguments->length(); ++i) { 13173 for (intptr_t i = 0; i < arguments->length(); ++i) {
12977 result->AddNode(arguments->NodeAt(i)); 13174 result->AddNode(arguments->NodeAt(i));
12978 } 13175 }
12979 ArgumentListNode* error_arguments = new(Z) ArgumentListNode(type_pos); 13176 ArgumentListNode* error_arguments = new(Z) ArgumentListNode(type_pos);
12980 error_arguments->Add(new(Z) LiteralNode( 13177 error_arguments->Add(new(Z) LiteralNode(
12981 TokenPos(), Integer::ZoneHandle(Z, Integer::New(type_pos)))); 13178 TokenPos(), Integer::ZoneHandle(Z, Integer::New(type_pos))));
12982 error_arguments->Add(new(Z) LiteralNode( 13179 error_arguments->Add(new(Z) LiteralNode(
12983 TokenPos(), String::ZoneHandle(Z, type_class_name.raw()))); 13180 TokenPos(), String::ZoneHandle(Z, type_class_name.raw())));
12984 result->AddNode( 13181 result->AddNode(
12985 MakeStaticCall(Symbols::AbstractClassInstantiationError(), 13182 MakeStaticCall(Symbols::AbstractClassInstantiationError(),
12986 Library::PrivateCoreLibName(Symbols::ThrowNew()), 13183 Library::PrivateCoreLibName(Symbols::ThrowNew()),
12987 error_arguments)); 13184 error_arguments));
12988 return result; 13185 return result;
12989 } 13186 }
13187
13188 type_arguments ^= type_arguments.Canonicalize();
13189
13190 if (is_tearoff_expression) {
13191 const Function& tearoff_func = Function::ZoneHandle(Z,
13192 BuildConstructorClosureFunction(constructor, new_pos));
13193
13194 // Local functions normally get parsed when the enclosing function is
13195 // compiled. Since constructor tearoff closures don't get parsed here,
13196 // we need to duplicate some of the side effects of parsing, namely
13197 // creating a function scope, and capturing the instantiator of the
13198 // enclosing function if necessary.
13199 OpenFunctionBlock(tearoff_func);
13200 // If there are type arguments in the tearoff expression that are
13201 // not yet instantiated, capture the instantiator.
13202 if (IsInstantiatorRequired() &&
13203 !type_arguments.IsNull() && !type_arguments.IsInstantiated()) {
13204 CaptureInstantiator();
13205 }
13206 SequenceNode* tearoff_body = CloseBlock();
13207 ClosureNode* closure_obj =
13208 new(Z) ClosureNode(new_pos, tearoff_func, NULL, tearoff_body->scope());
13209 return closure_obj;
13210 }
13211
13212 ASSERT(!is_tearoff_expression);
12990 String& error_message = String::Handle(Z); 13213 String& error_message = String::Handle(Z);
12991 if (!constructor.AreValidArguments(arguments_length, 13214 if (!constructor.AreValidArguments(arguments_length,
12992 arguments->names(), 13215 arguments->names(),
12993 &error_message)) { 13216 &error_message)) {
12994 const String& external_constructor_name = 13217 const String& external_constructor_name =
12995 (named_constructor ? constructor_name : type_class_name); 13218 (named_constructor ? constructor_name : type_class_name);
12996 if (is_const) { 13219 if (is_const) {
12997 ReportError(call_pos, 13220 ReportError(call_pos,
12998 "invalid arguments passed to constructor '%s' " 13221 "invalid arguments passed to constructor '%s' "
12999 "for class '%s': %s", 13222 "for class '%s': %s",
(...skipping 11 matching lines...) Expand all
13011 } 13234 }
13012 13235
13013 // Return a throw in case of a malformed or malbounded type or report a 13236 // Return a throw in case of a malformed or malbounded type or report a
13014 // compile-time error if the constructor is const. 13237 // compile-time error if the constructor is const.
13015 if (type.IsMalformedOrMalbounded()) { 13238 if (type.IsMalformedOrMalbounded()) {
13016 if (is_const) { 13239 if (is_const) {
13017 ReportError(Error::Handle(Z, type.error())); 13240 ReportError(Error::Handle(Z, type.error()));
13018 } 13241 }
13019 return ThrowTypeError(type_pos, type); 13242 return ThrowTypeError(type_pos, type);
13020 } 13243 }
13021 type_arguments ^= type_arguments.Canonicalize(); 13244
13022 // Make the constructor call. 13245 // Make the constructor call.
13023 AstNode* new_object = NULL; 13246 AstNode* new_object = NULL;
13024 if (is_const) { 13247 if (is_const) {
13025 if (!constructor.is_const()) { 13248 if (!constructor.is_const()) {
13026 const String& external_constructor_name = 13249 const String& external_constructor_name =
13027 (named_constructor ? constructor_name : type_class_name); 13250 (named_constructor ? constructor_name : type_class_name);
13028 ReportError("non-const constructor '%s' cannot be used in " 13251 ReportError("non-const constructor '%s' cannot be used in "
13029 "const object creation", 13252 "const object creation",
13030 external_constructor_name.ToCString()); 13253 external_constructor_name.ToCString());
13031 } 13254 }
(...skipping 780 matching lines...) Expand 10 before | Expand all | Expand 10 after
13812 void Parser::SkipQualIdent() { 14035 void Parser::SkipQualIdent() {
13813 ASSERT(IsIdentifier()); 14036 ASSERT(IsIdentifier());
13814 ConsumeToken(); 14037 ConsumeToken();
13815 if (CurrentToken() == Token::kPERIOD) { 14038 if (CurrentToken() == Token::kPERIOD) {
13816 ConsumeToken(); // Consume the kPERIOD token. 14039 ConsumeToken(); // Consume the kPERIOD token.
13817 ExpectIdentifier("identifier expected after '.'"); 14040 ExpectIdentifier("identifier expected after '.'");
13818 } 14041 }
13819 } 14042 }
13820 14043
13821 } // namespace dart 14044 } // namespace dart
OLDNEW
« no previous file with comments | « runtime/vm/parser.h ('k') | runtime/vm/symbols.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698