Chromium Code Reviews| 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 |