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/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 Loading... | |
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 Loading... | |
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, ¶ms); | |
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(¶ms, 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(¶ms, 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 Loading... | |
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 Loading... | |
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, ¶ms); | |
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(¶ms, 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 Loading... | |
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 Loading... | |
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 Loading... | |
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 Loading... | |
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 |
OLD | NEW |