| 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 #include "vm/flags.h" | 6 #include "vm/flags.h" |
| 7 | 7 |
| 8 #ifndef DART_PRECOMPILED | 8 #ifndef DART_PRECOMPILED |
| 9 | 9 |
| 10 #include "lib/invocation_mirror.h" | 10 #include "lib/invocation_mirror.h" |
| (...skipping 30 matching lines...) Expand all Loading... |
| 41 namespace dart { | 41 namespace dart { |
| 42 | 42 |
| 43 DEFINE_FLAG(bool, enable_debug_break, false, "Allow use of break \"message\"."); | 43 DEFINE_FLAG(bool, enable_debug_break, false, "Allow use of break \"message\"."); |
| 44 DEFINE_FLAG(bool, enable_mirrors, true, | 44 DEFINE_FLAG(bool, enable_mirrors, true, |
| 45 "Disable to make importing dart:mirrors an error."); | 45 "Disable to make importing dart:mirrors an error."); |
| 46 DEFINE_FLAG(bool, load_deferred_eagerly, false, | 46 DEFINE_FLAG(bool, load_deferred_eagerly, false, |
| 47 "Load deferred libraries eagerly."); | 47 "Load deferred libraries eagerly."); |
| 48 DEFINE_FLAG(bool, trace_parser, false, "Trace parser operations."); | 48 DEFINE_FLAG(bool, trace_parser, false, "Trace parser operations."); |
| 49 DEFINE_FLAG(bool, warn_mixin_typedef, true, "Warning on legacy mixin typedef."); | 49 DEFINE_FLAG(bool, warn_mixin_typedef, true, "Warning on legacy mixin typedef."); |
| 50 DEFINE_FLAG(bool, link_natives_lazily, false, "Link native calls lazily"); | 50 DEFINE_FLAG(bool, link_natives_lazily, false, "Link native calls lazily"); |
| 51 DEFINE_FLAG(bool, move_super, true, "Move super initializer to end of list."); | |
| 52 DEFINE_FLAG(bool, conditional_directives, false, | 51 DEFINE_FLAG(bool, conditional_directives, false, |
| 53 "Enable conditional directives"); | 52 "Enable conditional directives"); |
| 54 DEFINE_FLAG(bool, warn_super, false, | 53 DEFINE_FLAG(bool, warn_super, false, |
| 55 "Warning if super initializer not last in initializer list."); | 54 "Warning if super initializer not last in initializer list."); |
| 56 | 55 |
| 57 DECLARE_FLAG(bool, lazy_dispatchers); | 56 DECLARE_FLAG(bool, lazy_dispatchers); |
| 58 DECLARE_FLAG(bool, load_deferred_eagerly); | 57 DECLARE_FLAG(bool, load_deferred_eagerly); |
| 59 DECLARE_FLAG(bool, profile_vm); | 58 DECLARE_FLAG(bool, profile_vm); |
| 60 DECLARE_FLAG(bool, throw_on_javascript_int_overflow); | 59 DECLARE_FLAG(bool, throw_on_javascript_int_overflow); |
| 61 DECLARE_FLAG(bool, warn_on_javascript_compatibility); | 60 DECLARE_FLAG(bool, warn_on_javascript_compatibility); |
| (...skipping 883 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 945 const Script& script = Script::Handle(zone, func.script()); | 944 const Script& script = Script::Handle(zone, func.script()); |
| 946 Parser parser(script, parsed_function, func.token_pos()); | 945 Parser parser(script, parsed_function, func.token_pos()); |
| 947 if (tds.enabled()) { | 946 if (tds.enabled()) { |
| 948 tds.SetNumArguments(1); | 947 tds.SetNumArguments(1); |
| 949 tds.CopyArgument(0, "function", String::Handle(func.name()).ToCString()); | 948 tds.CopyArgument(0, "function", String::Handle(func.name()).ToCString()); |
| 950 } | 949 } |
| 951 SequenceNode* node_sequence = NULL; | 950 SequenceNode* node_sequence = NULL; |
| 952 switch (func.kind()) { | 951 switch (func.kind()) { |
| 953 case RawFunction::kClosureFunction: | 952 case RawFunction::kClosureFunction: |
| 954 if (func.IsImplicitClosureFunction()) { | 953 if (func.IsImplicitClosureFunction()) { |
| 955 node_sequence = | 954 node_sequence = parser.ParseImplicitClosure(func); |
| 956 parser.ParseImplicitClosure(func); | |
| 957 break; | 955 break; |
| 958 } | 956 } |
| 959 if (func.IsConstructorClosureFunction()) { | 957 if (func.IsConstructorClosureFunction()) { |
| 960 node_sequence = | 958 node_sequence = parser.ParseConstructorClosure(func); |
| 961 parser.ParseConstructorClosure(func); | |
| 962 break; | 959 break; |
| 963 } | 960 } |
| 964 // Fall-through: Handle non-implicit closures. | 961 // Fall-through: Handle non-implicit closures. |
| 965 case RawFunction::kRegularFunction: | 962 case RawFunction::kRegularFunction: |
| 966 case RawFunction::kGetterFunction: | 963 case RawFunction::kGetterFunction: |
| 967 case RawFunction::kSetterFunction: | 964 case RawFunction::kSetterFunction: |
| 968 case RawFunction::kConstructor: | 965 case RawFunction::kConstructor: |
| 969 // The call to a redirecting factory is redirected. | 966 // The call to a redirecting factory is redirected. |
| 970 ASSERT(!func.IsRedirectingFactory()); | 967 ASSERT(!func.IsRedirectingFactory()); |
| 971 if (!func.IsImplicitConstructor()) { | 968 if (!func.IsImplicitConstructor()) { |
| (...skipping 392 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1364 SequenceNode* Parser::ParseConstructorClosure(const Function& func) { | 1361 SequenceNode* Parser::ParseConstructorClosure(const Function& func) { |
| 1365 TRACE_PARSER("ParseConstructorClosure"); | 1362 TRACE_PARSER("ParseConstructorClosure"); |
| 1366 const intptr_t token_pos = func.token_pos(); | 1363 const intptr_t token_pos = func.token_pos(); |
| 1367 | 1364 |
| 1368 Function& constructor = Function::ZoneHandle(Z); | 1365 Function& constructor = Function::ZoneHandle(Z); |
| 1369 TypeArguments& type_args = TypeArguments::ZoneHandle(Z); | 1366 TypeArguments& type_args = TypeArguments::ZoneHandle(Z); |
| 1370 ParseConstructorClosurization(&constructor, &type_args); | 1367 ParseConstructorClosurization(&constructor, &type_args); |
| 1371 ASSERT(!constructor.IsNull()); | 1368 ASSERT(!constructor.IsNull()); |
| 1372 | 1369 |
| 1373 ParamList params; | 1370 ParamList params; |
| 1374 // The first parameter of the closure function is the implicit closure | 1371 // The first parameter of the closure function is the |
| 1375 // argument. | 1372 // implicit closure argument. |
| 1376 params.AddFinalParameter(token_pos, | 1373 params.AddFinalParameter(token_pos, |
| 1377 &Symbols::ClosureParameter(), | 1374 &Symbols::ClosureParameter(), |
| 1378 &Object::dynamic_type()); | 1375 &Object::dynamic_type()); |
| 1379 bool params_ok = ParseFormalParameters(constructor, ¶ms); | 1376 bool params_ok = ParseFormalParameters(constructor, ¶ms); |
| 1380 USE(params_ok); | 1377 USE(params_ok); |
| 1381 ASSERT(params_ok); | 1378 ASSERT(params_ok); |
| 1382 // Per language spec, the type of the closure parameters is dynamic. | 1379 // Per language spec, the type of the closure parameters is dynamic. |
| 1383 // Replace the types parsed from the constructor. | 1380 // Replace the types parsed from the constructor. |
| 1384 params.EraseParameterTypes(); | 1381 params.EraseParameterTypes(); |
| 1385 | 1382 |
| (...skipping 981 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2367 } | 2364 } |
| 2368 return new(Z) StaticGetterNode( | 2365 return new(Z) StaticGetterNode( |
| 2369 field_pos, implicit_argument, super_class, field_name); | 2366 field_pos, implicit_argument, super_class, field_name); |
| 2370 } | 2367 } |
| 2371 | 2368 |
| 2372 | 2369 |
| 2373 StaticCallNode* Parser::GenerateSuperConstructorCall( | 2370 StaticCallNode* Parser::GenerateSuperConstructorCall( |
| 2374 const Class& cls, | 2371 const Class& cls, |
| 2375 intptr_t supercall_pos, | 2372 intptr_t supercall_pos, |
| 2376 LocalVariable* receiver, | 2373 LocalVariable* receiver, |
| 2377 AstNode* phase_parameter, | |
| 2378 ArgumentListNode* forwarding_args) { | 2374 ArgumentListNode* forwarding_args) { |
| 2379 const Class& super_class = Class::Handle(Z, cls.SuperClass()); | 2375 const Class& super_class = Class::Handle(Z, cls.SuperClass()); |
| 2380 // Omit the implicit super() if there is no super class (i.e. | 2376 // Omit the implicit super() if there is no super class (i.e. |
| 2381 // we're not compiling class Object), or if the super class is an | 2377 // we're not compiling class Object), or if the super class is an |
| 2382 // artificially generated "wrapper class" that has no constructor. | 2378 // artificially generated "wrapper class" that has no constructor. |
| 2383 if (super_class.IsNull() || | 2379 if (super_class.IsNull() || |
| 2384 (super_class.num_native_fields() > 0 && | 2380 (super_class.num_native_fields() > 0 && |
| 2385 Class::Handle(Z, super_class.SuperClass()).IsObjectClass())) { | 2381 Class::Handle(Z, super_class.SuperClass()).IsObjectClass())) { |
| 2386 return NULL; | 2382 return NULL; |
| 2387 } | 2383 } |
| 2388 String& super_ctor_name = String::Handle(Z, super_class.Name()); | 2384 String& super_ctor_name = String::Handle(Z, super_class.Name()); |
| 2389 super_ctor_name = Symbols::FromConcat(super_ctor_name, Symbols::Dot()); | 2385 super_ctor_name = Symbols::FromConcat(super_ctor_name, Symbols::Dot()); |
| 2390 | 2386 |
| 2391 ArgumentListNode* arguments = new ArgumentListNode(supercall_pos); | 2387 ArgumentListNode* arguments = new ArgumentListNode(supercall_pos); |
| 2392 // Implicit 'this' parameter is the first argument. | 2388 // Implicit 'this' parameter is the first argument. |
| 2393 AstNode* implicit_argument = new LoadLocalNode(supercall_pos, receiver); | 2389 AstNode* implicit_argument = new LoadLocalNode(supercall_pos, receiver); |
| 2394 arguments->Add(implicit_argument); | 2390 arguments->Add(implicit_argument); |
| 2395 // Implicit construction phase parameter is second argument. | |
| 2396 arguments->Add(phase_parameter); | |
| 2397 | 2391 |
| 2398 // If this is a super call in a forwarding constructor, add the user- | 2392 // If this is a super call in a forwarding constructor, add the user- |
| 2399 // defined arguments to the super call and adjust the the super | 2393 // defined arguments to the super call and adjust the the super |
| 2400 // constructor name to the respective named constructor if necessary. | 2394 // constructor name to the respective named constructor if necessary. |
| 2401 if (forwarding_args != NULL) { | 2395 if (forwarding_args != NULL) { |
| 2402 for (int i = 0; i < forwarding_args->length(); i++) { | 2396 for (int i = 0; i < forwarding_args->length(); i++) { |
| 2403 arguments->Add(forwarding_args->NodeAt(i)); | 2397 arguments->Add(forwarding_args->NodeAt(i)); |
| 2404 } | 2398 } |
| 2405 String& ctor_name = String::Handle(Z, current_function().name()); | 2399 String& ctor_name = String::Handle(Z, current_function().name()); |
| 2406 String& class_name = String::Handle(Z, cls.Name()); | 2400 String& class_name = String::Handle(Z, cls.Name()); |
| (...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2452 ConsumeToken(); | 2446 ConsumeToken(); |
| 2453 ctor_name = Symbols::FromConcat( | 2447 ctor_name = Symbols::FromConcat( |
| 2454 ctor_name, *ExpectIdentifier("constructor name expected")); | 2448 ctor_name, *ExpectIdentifier("constructor name expected")); |
| 2455 } | 2449 } |
| 2456 CheckToken(Token::kLPAREN, "parameter list expected"); | 2450 CheckToken(Token::kLPAREN, "parameter list expected"); |
| 2457 | 2451 |
| 2458 ArgumentListNode* arguments = new ArgumentListNode(supercall_pos); | 2452 ArgumentListNode* arguments = new ArgumentListNode(supercall_pos); |
| 2459 // 'this' parameter is the first argument to super class constructor. | 2453 // 'this' parameter is the first argument to super class constructor. |
| 2460 AstNode* implicit_argument = new LoadLocalNode(supercall_pos, receiver); | 2454 AstNode* implicit_argument = new LoadLocalNode(supercall_pos, receiver); |
| 2461 arguments->Add(implicit_argument); | 2455 arguments->Add(implicit_argument); |
| 2462 // Second implicit parameter is the construction phase. We optimistically | 2456 |
| 2463 // assume that we can execute both the super initializer and the super | |
| 2464 // constructor body. We may later change this to only execute the | |
| 2465 // super initializer. | |
| 2466 AstNode* phase_parameter = | |
| 2467 new LiteralNode(supercall_pos, | |
| 2468 Smi::ZoneHandle(Z, Smi::New(Function::kCtorPhaseAll))); | |
| 2469 arguments->Add(phase_parameter); | |
| 2470 // 'this' parameter must not be accessible to the other super call arguments. | 2457 // 'this' parameter must not be accessible to the other super call arguments. |
| 2471 receiver->set_invisible(true); | 2458 receiver->set_invisible(true); |
| 2472 ParseActualParameters(arguments, kAllowConst); | 2459 ParseActualParameters(arguments, kAllowConst); |
| 2473 receiver->set_invisible(false); | 2460 receiver->set_invisible(false); |
| 2474 | 2461 |
| 2475 // Resolve the constructor. | 2462 // Resolve the constructor. |
| 2476 const Function& super_ctor = Function::ZoneHandle(Z, | 2463 const Function& super_ctor = Function::ZoneHandle(Z, |
| 2477 super_class.LookupConstructor(ctor_name)); | 2464 super_class.LookupConstructor(ctor_name)); |
| 2478 if (super_ctor.IsNull()) { | 2465 if (super_ctor.IsNull()) { |
| 2479 ReportError(supercall_pos, | 2466 ReportError(supercall_pos, |
| (...skipping 307 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2787 AstNode* init_statement = | 2774 AstNode* init_statement = |
| 2788 ParseInitializer(cls, receiver, initialized_fields); | 2775 ParseInitializer(cls, receiver, initialized_fields); |
| 2789 super_init_is_last = false; | 2776 super_init_is_last = false; |
| 2790 current_block_->statements->Add(init_statement); | 2777 current_block_->statements->Add(init_statement); |
| 2791 } | 2778 } |
| 2792 } while (CurrentToken() == Token::kCOMMA); | 2779 } while (CurrentToken() == Token::kCOMMA); |
| 2793 } | 2780 } |
| 2794 if (super_init_call == NULL) { | 2781 if (super_init_call == NULL) { |
| 2795 // Generate implicit super() if we haven't seen an explicit super call | 2782 // Generate implicit super() if we haven't seen an explicit super call |
| 2796 // or constructor redirection. | 2783 // or constructor redirection. |
| 2797 AstNode* phase_parameter = new LiteralNode( | 2784 super_init_call = |
| 2798 TokenPos(), Smi::ZoneHandle(Z, Smi::New(Function::kCtorPhaseAll))); | 2785 GenerateSuperConstructorCall(cls, TokenPos(), receiver, NULL); |
| 2799 super_init_call = GenerateSuperConstructorCall( | |
| 2800 cls, TokenPos(), receiver, phase_parameter, NULL); | |
| 2801 if (super_init_call != NULL) { | 2786 if (super_init_call != NULL) { |
| 2802 super_init_index = current_block_->statements->length(); | 2787 super_init_index = current_block_->statements->length(); |
| 2803 current_block_->statements->Add(super_init_call); | 2788 current_block_->statements->Add(super_init_call); |
| 2804 super_init_is_last = true; | 2789 super_init_is_last = true; |
| 2805 } | 2790 } |
| 2806 } | 2791 } |
| 2807 if (FLAG_move_super && (super_init_call != NULL) && !super_init_is_last) { | 2792 if ((super_init_call != NULL) && !super_init_is_last) { |
| 2808 // If the super initializer call is not at the end of the initializer | 2793 // If the super initializer call is not at the end of the initializer |
| 2809 // list, implicitly move it to the end. The actual parameter values | 2794 // list, implicitly move it to the end. The actual parameter values |
| 2810 // are evaluated at the original position in the list and preserved | 2795 // are evaluated at the original position in the list and preserved |
| 2811 // in temporary variables. (The following initializer expressions | 2796 // in temporary variables. (The following initializer expressions |
| 2812 // could have side effects that alter the arguments to the super | 2797 // could have side effects that alter the arguments to the super |
| 2813 // initializer.) E.g: | 2798 // initializer.) E.g: |
| 2814 // A(x) : super(x), f = x++ { ... } | 2799 // A(x) : super(x), f = x++ { ... } |
| 2815 // is transformed to: | 2800 // is transformed to: |
| 2816 // A(x) : temp = x, f = x++, super(temp) { ... } | 2801 // A(x) : temp = x, f = x++, super(temp) { ... } |
| 2817 if (FLAG_warn_super) { | 2802 if (FLAG_warn_super) { |
| 2818 ReportWarning("Super initializer not at end"); | 2803 ReportWarning("Super initializer not at end"); |
| 2819 } | 2804 } |
| 2820 ASSERT(super_init_index >= 0); | 2805 ASSERT(super_init_index >= 0); |
| 2821 ArgumentListNode* ctor_args = super_init_call->arguments(); | 2806 ArgumentListNode* ctor_args = super_init_call->arguments(); |
| 2822 LetNode* saved_args = new(Z) LetNode(super_init_call->token_pos()); | 2807 LetNode* saved_args = new(Z) LetNode(super_init_call->token_pos()); |
| 2823 // The super initializer call has at least 2 arguments: the | 2808 // The super initializer call has at least 1 arguments: the |
| 2824 // implicit receiver, and the hidden construction phase. | 2809 // implicit receiver. |
| 2825 ASSERT(ctor_args->length() >= 2); | 2810 ASSERT(ctor_args->length() >= 1); |
| 2826 for (int i = 2; i < ctor_args->length(); i++) { | 2811 for (int i = 1; i < ctor_args->length(); i++) { |
| 2827 AstNode* arg = ctor_args->NodeAt(i); | 2812 AstNode* arg = ctor_args->NodeAt(i); |
| 2828 LocalVariable* temp = CreateTempConstVariable(arg->token_pos(), "sca"); | 2813 LocalVariable* temp = CreateTempConstVariable(arg->token_pos(), "sca"); |
| 2829 AstNode* save_temp = new(Z) StoreLocalNode(arg->token_pos(), temp, arg); | 2814 AstNode* save_temp = new(Z) StoreLocalNode(arg->token_pos(), temp, arg); |
| 2830 saved_args->AddNode(save_temp); | 2815 saved_args->AddNode(save_temp); |
| 2831 ctor_args->SetNodeAt(i, new(Z) LoadLocalNode(arg->token_pos(), temp)); | 2816 ctor_args->SetNodeAt(i, new(Z) LoadLocalNode(arg->token_pos(), temp)); |
| 2832 } | 2817 } |
| 2833 current_block_->statements->ReplaceNodeAt(super_init_index, saved_args); | 2818 current_block_->statements->ReplaceNodeAt(super_init_index, saved_args); |
| 2834 current_block_->statements->Add(super_init_call); | 2819 current_block_->statements->Add(super_init_call); |
| 2835 } | 2820 } |
| 2836 CheckFieldsInitialized(cls); | 2821 CheckFieldsInitialized(cls); |
| (...skipping 15 matching lines...) Expand all Loading... |
| 2852 ConsumeToken(); | 2837 ConsumeToken(); |
| 2853 pieces.Add(*ExpectIdentifier("constructor name expected")); | 2838 pieces.Add(*ExpectIdentifier("constructor name expected")); |
| 2854 } | 2839 } |
| 2855 ctor_name = Symbols::FromConcatAll(pieces); | 2840 ctor_name = Symbols::FromConcatAll(pieces); |
| 2856 CheckToken(Token::kLPAREN, "parameter list expected"); | 2841 CheckToken(Token::kLPAREN, "parameter list expected"); |
| 2857 | 2842 |
| 2858 ArgumentListNode* arguments = new ArgumentListNode(call_pos); | 2843 ArgumentListNode* arguments = new ArgumentListNode(call_pos); |
| 2859 // 'this' parameter is the first argument to constructor. | 2844 // 'this' parameter is the first argument to constructor. |
| 2860 AstNode* implicit_argument = new LoadLocalNode(call_pos, receiver); | 2845 AstNode* implicit_argument = new LoadLocalNode(call_pos, receiver); |
| 2861 arguments->Add(implicit_argument); | 2846 arguments->Add(implicit_argument); |
| 2862 // Construction phase parameter is second argument. | 2847 |
| 2863 LocalVariable* phase_param = LookupPhaseParameter(); | |
| 2864 ASSERT(phase_param != NULL); | |
| 2865 AstNode* phase_argument = new LoadLocalNode(call_pos, phase_param); | |
| 2866 arguments->Add(phase_argument); | |
| 2867 receiver->set_invisible(true); | 2848 receiver->set_invisible(true); |
| 2868 ParseActualParameters(arguments, kAllowConst); | 2849 ParseActualParameters(arguments, kAllowConst); |
| 2869 receiver->set_invisible(false); | 2850 receiver->set_invisible(false); |
| 2870 // Resolve the constructor. | 2851 // Resolve the constructor. |
| 2871 const Function& redirect_ctor = Function::ZoneHandle(Z, | 2852 const Function& redirect_ctor = Function::ZoneHandle(Z, |
| 2872 cls.LookupConstructor(ctor_name)); | 2853 cls.LookupConstructor(ctor_name)); |
| 2873 if (redirect_ctor.IsNull()) { | 2854 if (redirect_ctor.IsNull()) { |
| 2874 ReportError(call_pos, "constructor '%s' not found", ctor_name.ToCString()); | 2855 ReportError(call_pos, "constructor '%s' not found", ctor_name.ToCString()); |
| 2875 } | 2856 } |
| 2876 String& error_message = String::Handle(Z); | 2857 String& error_message = String::Handle(Z); |
| (...skipping 13 matching lines...) Expand all Loading... |
| 2890 SequenceNode* Parser::MakeImplicitConstructor(const Function& func) { | 2871 SequenceNode* Parser::MakeImplicitConstructor(const Function& func) { |
| 2891 ASSERT(func.IsGenerativeConstructor()); | 2872 ASSERT(func.IsGenerativeConstructor()); |
| 2892 ASSERT(func.Owner() == current_class().raw()); | 2873 ASSERT(func.Owner() == current_class().raw()); |
| 2893 const intptr_t ctor_pos = TokenPos(); | 2874 const intptr_t ctor_pos = TokenPos(); |
| 2894 OpenFunctionBlock(func); | 2875 OpenFunctionBlock(func); |
| 2895 | 2876 |
| 2896 LocalVariable* receiver = new LocalVariable( | 2877 LocalVariable* receiver = new LocalVariable( |
| 2897 Scanner::kNoSourcePos, Symbols::This(), *ReceiverType(current_class())); | 2878 Scanner::kNoSourcePos, Symbols::This(), *ReceiverType(current_class())); |
| 2898 current_block_->scope->InsertParameterAt(0, receiver); | 2879 current_block_->scope->InsertParameterAt(0, receiver); |
| 2899 | 2880 |
| 2900 LocalVariable* phase_parameter = | |
| 2901 new LocalVariable(Scanner::kNoSourcePos, | |
| 2902 Symbols::PhaseParameter(), | |
| 2903 Type::ZoneHandle(Z, Type::SmiType())); | |
| 2904 current_block_->scope->InsertParameterAt(1, phase_parameter); | |
| 2905 | |
| 2906 // Parse expressions of instance fields that have an explicit | 2881 // Parse expressions of instance fields that have an explicit |
| 2907 // initializer expression. | 2882 // initializer expression. |
| 2908 // The receiver must not be visible to field initializer expressions. | 2883 // The receiver must not be visible to field initializer expressions. |
| 2909 receiver->set_invisible(true); | 2884 receiver->set_invisible(true); |
| 2910 GrowableArray<Field*> initialized_fields; | 2885 GrowableArray<Field*> initialized_fields; |
| 2911 ParseInitializedInstanceFields( | 2886 ParseInitializedInstanceFields( |
| 2912 current_class(), receiver, &initialized_fields); | 2887 current_class(), receiver, &initialized_fields); |
| 2913 receiver->set_invisible(false); | 2888 receiver->set_invisible(false); |
| 2914 | 2889 |
| 2915 // If the class of this implicit constructor is a mixin application alias, | 2890 // If the class of this implicit constructor is a mixin application alias, |
| (...skipping 19 matching lines...) Expand all Loading... |
| 2935 "cannot generate an implicit mixin application constructor " | 2910 "cannot generate an implicit mixin application constructor " |
| 2936 "forwarding to a super class constructor with optional " | 2911 "forwarding to a super class constructor with optional " |
| 2937 "parameters; add a constructor without optional parameters " | 2912 "parameters; add a constructor without optional parameters " |
| 2938 "to class '%s' that redirects to the constructor with " | 2913 "to class '%s' that redirects to the constructor with " |
| 2939 "optional parameters and invoke it via super from a " | 2914 "optional parameters and invoke it via super from a " |
| 2940 "constructor of the class extending the mixin application", | 2915 "constructor of the class extending the mixin application", |
| 2941 String::Handle(Z, super_class.Name()).ToCString()); | 2916 String::Handle(Z, super_class.Name()).ToCString()); |
| 2942 } | 2917 } |
| 2943 | 2918 |
| 2944 // Prepare user-defined arguments to be forwarded to super call. | 2919 // Prepare user-defined arguments to be forwarded to super call. |
| 2945 // The first user-defined argument is at position 2. | 2920 // The first user-defined argument is at position 1. |
| 2946 forwarding_args = new ArgumentListNode(Scanner::kNoSourcePos); | 2921 forwarding_args = new ArgumentListNode(Scanner::kNoSourcePos); |
| 2947 for (int i = 2; i < func.NumParameters(); i++) { | 2922 for (int i = 1; i < func.NumParameters(); i++) { |
| 2948 LocalVariable* param = new LocalVariable( | 2923 LocalVariable* param = new LocalVariable( |
| 2949 Scanner::kNoSourcePos, | 2924 Scanner::kNoSourcePos, |
| 2950 String::ZoneHandle(Z, func.ParameterNameAt(i)), | 2925 String::ZoneHandle(Z, func.ParameterNameAt(i)), |
| 2951 Object::dynamic_type()); | 2926 Object::dynamic_type()); |
| 2952 current_block_->scope->InsertParameterAt(i, param); | 2927 current_block_->scope->InsertParameterAt(i, param); |
| 2953 forwarding_args->Add(new LoadLocalNode(Scanner::kNoSourcePos, param)); | 2928 forwarding_args->Add(new LoadLocalNode(Scanner::kNoSourcePos, param)); |
| 2954 } | 2929 } |
| 2955 } | 2930 } |
| 2956 | 2931 |
| 2957 AstNode* super_call = GenerateSuperConstructorCall( | 2932 AstNode* super_call = GenerateSuperConstructorCall( |
| 2958 current_class(), | 2933 current_class(), |
| 2959 Scanner::kNoSourcePos, | 2934 Scanner::kNoSourcePos, |
| 2960 receiver, | 2935 receiver, |
| 2961 new LoadLocalNode(Scanner::kNoSourcePos, phase_parameter), | |
| 2962 forwarding_args); | 2936 forwarding_args); |
| 2963 if (super_call != NULL) { | 2937 if (super_call != NULL) { |
| 2964 current_block_->statements->Add(super_call); | 2938 current_block_->statements->Add(super_call); |
| 2965 } | 2939 } |
| 2966 CheckFieldsInitialized(current_class()); | 2940 CheckFieldsInitialized(current_class()); |
| 2967 | 2941 |
| 2968 // Empty constructor body. | 2942 // Empty constructor body. |
| 2969 current_block_->statements->Add(new ReturnNode(Scanner::kNoSourcePos)); | 2943 current_block_->statements->Add(new ReturnNode(Scanner::kNoSourcePos)); |
| 2970 SequenceNode* statements = CloseBlock(); | 2944 SequenceNode* statements = CloseBlock(); |
| 2971 return statements; | 2945 return statements; |
| (...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3014 OpenFunctionBlock(func); | 2988 OpenFunctionBlock(func); |
| 3015 ParamList params; | 2989 ParamList params; |
| 3016 const bool allow_explicit_default_values = true; | 2990 const bool allow_explicit_default_values = true; |
| 3017 ASSERT(CurrentToken() == Token::kLPAREN); | 2991 ASSERT(CurrentToken() == Token::kLPAREN); |
| 3018 | 2992 |
| 3019 // Add implicit receiver parameter which is passed the allocated | 2993 // Add implicit receiver parameter which is passed the allocated |
| 3020 // but uninitialized instance to construct. | 2994 // but uninitialized instance to construct. |
| 3021 ASSERT(current_class().raw() == func.Owner()); | 2995 ASSERT(current_class().raw() == func.Owner()); |
| 3022 params.AddReceiver(ReceiverType(current_class()), func.token_pos()); | 2996 params.AddReceiver(ReceiverType(current_class()), func.token_pos()); |
| 3023 | 2997 |
| 3024 // Add implicit parameter for construction phase. | |
| 3025 params.AddFinalParameter( | |
| 3026 TokenPos(), | |
| 3027 &Symbols::PhaseParameter(), | |
| 3028 &Type::ZoneHandle(Z, Type::SmiType())); | |
| 3029 | |
| 3030 if (func.is_const()) { | 2998 if (func.is_const()) { |
| 3031 params.SetImplicitlyFinal(); | 2999 params.SetImplicitlyFinal(); |
| 3032 } | 3000 } |
| 3033 ParseFormalParameterList(allow_explicit_default_values, false, ¶ms); | 3001 ParseFormalParameterList(allow_explicit_default_values, false, ¶ms); |
| 3034 | 3002 |
| 3035 SetupDefaultsForOptionalParams(params); | 3003 SetupDefaultsForOptionalParams(params); |
| 3036 ASSERT(AbstractType::Handle(Z, func.result_type()).IsResolved()); | 3004 ASSERT(AbstractType::Handle(Z, func.result_type()).IsResolved()); |
| 3037 ASSERT(func.NumParameters() == params.parameters->length()); | 3005 ASSERT(func.NumParameters() == params.parameters->length()); |
| 3038 | 3006 |
| 3039 // Now populate function scope with the formal parameters. | 3007 // Now populate function scope with the formal parameters. |
| (...skipping 19 matching lines...) Expand all Loading... |
| 3059 // storing values. We make the formal parameters temporarily invisible | 3027 // storing values. We make the formal parameters temporarily invisible |
| 3060 // while parsing the instance field initializer expressions. | 3028 // while parsing the instance field initializer expressions. |
| 3061 params.SetInvisible(true); | 3029 params.SetInvisible(true); |
| 3062 ParseInitializedInstanceFields(cls, receiver, &initialized_fields); | 3030 ParseInitializedInstanceFields(cls, receiver, &initialized_fields); |
| 3063 // Make the parameters (which are in the outer scope) visible again. | 3031 // Make the parameters (which are in the outer scope) visible again. |
| 3064 params.SetInvisible(false); | 3032 params.SetInvisible(false); |
| 3065 } | 3033 } |
| 3066 | 3034 |
| 3067 // Turn formal field parameters into field initializers. | 3035 // Turn formal field parameters into field initializers. |
| 3068 if (params.has_field_initializer) { | 3036 if (params.has_field_initializer) { |
| 3069 // First two parameters are implicit receiver and phase. | 3037 // The first parameter is the implicit receiver. |
| 3070 ASSERT(params.parameters->length() >= 2); | 3038 ASSERT(params.parameters->length() >= 1); |
| 3071 for (int i = 2; i < params.parameters->length(); i++) { | 3039 for (int i = 1; i < params.parameters->length(); i++) { |
| 3072 ParamDesc& param = (*params.parameters)[i]; | 3040 ParamDesc& param = (*params.parameters)[i]; |
| 3073 if (param.is_field_initializer) { | 3041 if (param.is_field_initializer) { |
| 3074 const String& field_name = *param.name; | 3042 const String& field_name = *param.name; |
| 3075 Field& field = | 3043 Field& field = |
| 3076 Field::ZoneHandle(Z, cls.LookupInstanceField(field_name)); | 3044 Field::ZoneHandle(Z, cls.LookupInstanceField(field_name)); |
| 3077 if (field.IsNull()) { | 3045 if (field.IsNull()) { |
| 3078 ReportError(param.name_pos, | 3046 ReportError(param.name_pos, |
| 3079 "unresolved reference to instance field '%s'", | 3047 "unresolved reference to instance field '%s'", |
| 3080 field_name.ToCString()); | 3048 field_name.ToCString()); |
| 3081 } | 3049 } |
| (...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3118 } | 3086 } |
| 3119 } | 3087 } |
| 3120 | 3088 |
| 3121 if (is_redirecting_constructor) { | 3089 if (is_redirecting_constructor) { |
| 3122 ParseConstructorRedirection(cls, receiver); | 3090 ParseConstructorRedirection(cls, receiver); |
| 3123 } else { | 3091 } else { |
| 3124 ParseInitializers(cls, receiver, &initialized_fields); | 3092 ParseInitializers(cls, receiver, &initialized_fields); |
| 3125 } | 3093 } |
| 3126 | 3094 |
| 3127 SequenceNode* init_statements = CloseBlock(); | 3095 SequenceNode* init_statements = CloseBlock(); |
| 3128 if (FLAG_move_super) { | 3096 current_block_->statements->Add(init_statements); |
| 3129 // Ignore the phase parameter. | |
| 3130 current_block_->statements->Add(init_statements); | |
| 3131 } else if (is_redirecting_constructor) { | |
| 3132 // A redirecting super constructor simply passes the phase parameter on to | |
| 3133 // the target which executes the corresponding phase. | |
| 3134 current_block_->statements->Add(init_statements); | |
| 3135 } else if (init_statements->length() > 0) { | |
| 3136 // Generate guard around the initializer code. | |
| 3137 LocalVariable* phase_param = LookupPhaseParameter(); | |
| 3138 AstNode* phase_value = new | |
| 3139 LoadLocalNode(Scanner::kNoSourcePos, phase_param); | |
| 3140 AstNode* phase_check = new BinaryOpNode( | |
| 3141 Scanner::kNoSourcePos, Token::kBIT_AND, phase_value, | |
| 3142 new LiteralNode(Scanner::kNoSourcePos, | |
| 3143 Smi::ZoneHandle(Z, Smi::New(Function::kCtorPhaseInit)))); | |
| 3144 AstNode* comparison = | |
| 3145 new ComparisonNode(Scanner::kNoSourcePos, | |
| 3146 Token::kNE_STRICT, | |
| 3147 phase_check, | |
| 3148 new LiteralNode(TokenPos(), | |
| 3149 Smi::ZoneHandle(Z, Smi::New(0)))); | |
| 3150 AstNode* guarded_init_statements = | |
| 3151 new IfNode(Scanner::kNoSourcePos, | |
| 3152 comparison, | |
| 3153 init_statements, | |
| 3154 NULL); | |
| 3155 current_block_->statements->Add(guarded_init_statements); | |
| 3156 } | |
| 3157 | 3097 |
| 3158 // Parsing of initializers done. Now we parse the constructor body | 3098 // Parsing of initializers done. Now we parse the constructor body. |
| 3159 // and add the implicit super call to the super constructor's body | |
| 3160 // if necessary. | |
| 3161 StaticCallNode* super_call = NULL; | |
| 3162 // Look for the super initializer call in the sequence of initializer | |
| 3163 // statements. If it exists and is not the last initializer statement, | |
| 3164 // we need to create an implicit super call to the super constructor's | |
| 3165 // body. | |
| 3166 // Thus, iterate over all but the last initializer to see whether | |
| 3167 // it's a super constructor call. | |
| 3168 for (int i = 0; i < init_statements->length() - 1; i++) { | |
| 3169 if (init_statements->NodeAt(i)->IsStaticCallNode()) { | |
| 3170 StaticCallNode* static_call = | |
| 3171 init_statements->NodeAt(i)->AsStaticCallNode(); | |
| 3172 if (static_call->function().IsGenerativeConstructor()) { | |
| 3173 super_call = static_call; | |
| 3174 break; | |
| 3175 } | |
| 3176 } | |
| 3177 } | |
| 3178 if (super_call != NULL) { | |
| 3179 ASSERT(!FLAG_move_super); | |
| 3180 // Generate an implicit call to the super constructor's body. | |
| 3181 // We need to patch the super _initializer_ call so that it | |
| 3182 // saves the evaluated actual arguments in temporary variables. | |
| 3183 // The temporary variables are necessary so that the argument | |
| 3184 // expressions are not evaluated twice. | |
| 3185 // Note: we should never get here in the case of a redirecting | |
| 3186 // constructor. In that case, the call to the target constructor | |
| 3187 // is the "super call" and is implicitly at the end of the | |
| 3188 // initializer list. | |
| 3189 ASSERT(!is_redirecting_constructor); | |
| 3190 ArgumentListNode* ctor_args = super_call->arguments(); | |
| 3191 // The super initializer call has at least 2 arguments: the | |
| 3192 // implicit receiver, and the hidden construction phase. | |
| 3193 ASSERT(ctor_args->length() >= 2); | |
| 3194 for (int i = 2; i < ctor_args->length(); i++) { | |
| 3195 AstNode* arg = ctor_args->NodeAt(i); | |
| 3196 if (!IsSimpleLocalOrLiteralNode(arg)) { | |
| 3197 LocalVariable* temp = CreateTempConstVariable(arg->token_pos(), "sca"); | |
| 3198 AstNode* save_temp = new StoreLocalNode(arg->token_pos(), temp, arg); | |
| 3199 ctor_args->SetNodeAt(i, save_temp); | |
| 3200 } | |
| 3201 } | |
| 3202 } | |
| 3203 OpenBlock(); // Block to collect constructor body nodes. | 3099 OpenBlock(); // Block to collect constructor body nodes. |
| 3204 intptr_t body_pos = TokenPos(); | |
| 3205 | |
| 3206 // Insert the implicit super call to the super constructor body. | |
| 3207 if (super_call != NULL) { | |
| 3208 ASSERT(!FLAG_move_super); | |
| 3209 ArgumentListNode* initializer_args = super_call->arguments(); | |
| 3210 const Function& super_ctor = super_call->function(); | |
| 3211 // Patch the initializer call so it only executes the super initializer. | |
| 3212 initializer_args->SetNodeAt(1, new LiteralNode( | |
| 3213 body_pos, Smi::ZoneHandle(Z, Smi::New(Function::kCtorPhaseInit)))); | |
| 3214 | |
| 3215 ArgumentListNode* super_call_args = new ArgumentListNode(body_pos); | |
| 3216 // First argument is the receiver. | |
| 3217 super_call_args->Add(new LoadLocalNode(body_pos, receiver)); | |
| 3218 // Second argument is the construction phase argument. | |
| 3219 AstNode* phase_parameter = new(Z) LiteralNode( | |
| 3220 body_pos, Smi::ZoneHandle(Z, Smi::New(Function::kCtorPhaseBody))); | |
| 3221 super_call_args->Add(phase_parameter); | |
| 3222 super_call_args->set_names(initializer_args->names()); | |
| 3223 for (int i = 2; i < initializer_args->length(); i++) { | |
| 3224 AstNode* arg = initializer_args->NodeAt(i); | |
| 3225 if (arg->IsLiteralNode()) { | |
| 3226 LiteralNode* lit = arg->AsLiteralNode(); | |
| 3227 super_call_args->Add(new LiteralNode(body_pos, lit->literal())); | |
| 3228 } else { | |
| 3229 ASSERT(arg->IsLoadLocalNode() || arg->IsStoreLocalNode()); | |
| 3230 if (arg->IsLoadLocalNode()) { | |
| 3231 const LocalVariable& temp = arg->AsLoadLocalNode()->local(); | |
| 3232 super_call_args->Add(new LoadLocalNode(body_pos, &temp)); | |
| 3233 } else if (arg->IsStoreLocalNode()) { | |
| 3234 const LocalVariable& temp = arg->AsStoreLocalNode()->local(); | |
| 3235 super_call_args->Add(new LoadLocalNode(body_pos, &temp)); | |
| 3236 } | |
| 3237 } | |
| 3238 } | |
| 3239 ASSERT(super_ctor.AreValidArguments(super_call_args->length(), | |
| 3240 super_call_args->names(), | |
| 3241 NULL)); | |
| 3242 current_block_->statements->Add( | |
| 3243 new StaticCallNode(body_pos, super_ctor, super_call_args)); | |
| 3244 } | |
| 3245 | |
| 3246 if (CurrentToken() == Token::kLBRACE) { | 3100 if (CurrentToken() == Token::kLBRACE) { |
| 3247 // We checked in the top-level parse phase that a redirecting | 3101 // We checked in the top-level parse phase that a redirecting |
| 3248 // constructor does not have a body. | 3102 // constructor does not have a body. |
| 3249 ASSERT(!is_redirecting_constructor); | 3103 ASSERT(!is_redirecting_constructor); |
| 3250 ConsumeToken(); | 3104 ConsumeToken(); |
| 3251 ParseStatementSequence(); | 3105 ParseStatementSequence(); |
| 3252 ExpectToken(Token::kRBRACE); | 3106 ExpectToken(Token::kRBRACE); |
| 3253 } else if (CurrentToken() == Token::kARROW) { | 3107 } else if (CurrentToken() == Token::kARROW) { |
| 3254 ReportError("constructors may not return a value"); | 3108 ReportError("constructors may not return a value"); |
| 3255 } else if (IsSymbol(Symbols::Native())) { | 3109 } else if (IsSymbol(Symbols::Native())) { |
| (...skipping 12 matching lines...) Expand all Loading... |
| 3268 InvocationMirror::kStatic, | 3122 InvocationMirror::kStatic, |
| 3269 InvocationMirror::kMethod, | 3123 InvocationMirror::kMethod, |
| 3270 NULL)); // No existing function. | 3124 NULL)); // No existing function. |
| 3271 } | 3125 } |
| 3272 } else { | 3126 } else { |
| 3273 UnexpectedToken(); | 3127 UnexpectedToken(); |
| 3274 } | 3128 } |
| 3275 | 3129 |
| 3276 SequenceNode* ctor_block = CloseBlock(); | 3130 SequenceNode* ctor_block = CloseBlock(); |
| 3277 if (ctor_block->length() > 0) { | 3131 if (ctor_block->length() > 0) { |
| 3278 if (FLAG_move_super) { | 3132 current_block_->statements->Add(ctor_block); |
| 3279 // Ignore the phase parameter. | |
| 3280 current_block_->statements->Add(ctor_block); | |
| 3281 } else { | |
| 3282 // Generate guard around the constructor body code. | |
| 3283 LocalVariable* phase_param = LookupPhaseParameter(); | |
| 3284 AstNode* phase_value = | |
| 3285 new LoadLocalNode(Scanner::kNoSourcePos, phase_param); | |
| 3286 AstNode* phase_check = | |
| 3287 new BinaryOpNode(Scanner::kNoSourcePos, Token::kBIT_AND, | |
| 3288 phase_value, | |
| 3289 new LiteralNode(Scanner::kNoSourcePos, | |
| 3290 Smi::ZoneHandle(Smi::New(Function::kCtorPhaseBody)))); | |
| 3291 AstNode* comparison = | |
| 3292 new ComparisonNode(Scanner::kNoSourcePos, | |
| 3293 Token::kNE_STRICT, | |
| 3294 phase_check, | |
| 3295 new LiteralNode(body_pos, | |
| 3296 Smi::ZoneHandle(Smi::New(0)))); | |
| 3297 AstNode* guarded_block_statements = | |
| 3298 new IfNode(Scanner::kNoSourcePos, comparison, ctor_block, NULL); | |
| 3299 current_block_->statements->Add(guarded_block_statements); | |
| 3300 } | |
| 3301 } | 3133 } |
| 3302 current_block_->statements->Add(new ReturnNode(func.end_token_pos())); | 3134 current_block_->statements->Add(new ReturnNode(func.end_token_pos())); |
| 3303 SequenceNode* statements = CloseBlock(); | 3135 SequenceNode* statements = CloseBlock(); |
| 3304 return statements; | 3136 return statements; |
| 3305 } | 3137 } |
| 3306 | 3138 |
| 3307 | 3139 |
| 3308 // Parser is at the opening parenthesis of the formal parameter | 3140 // Parser is at the opening parenthesis of the formal parameter |
| 3309 // declaration of the function or constructor. | 3141 // declaration of the function or constructor. |
| 3310 // Parse the formal parameters and code. | 3142 // Parse the formal parameters and code. |
| (...skipping 399 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3710 // The first parameter of a factory is the TypeArguments vector of | 3542 // The first parameter of a factory is the TypeArguments vector of |
| 3711 // the type of the instance to be allocated. | 3543 // the type of the instance to be allocated. |
| 3712 if (!method->has_static || method->IsConstructor()) { | 3544 if (!method->has_static || method->IsConstructor()) { |
| 3713 method->params.AddReceiver(ReceiverType(current_class()), formal_param_pos); | 3545 method->params.AddReceiver(ReceiverType(current_class()), formal_param_pos); |
| 3714 } else if (method->IsFactory()) { | 3546 } else if (method->IsFactory()) { |
| 3715 method->params.AddFinalParameter( | 3547 method->params.AddFinalParameter( |
| 3716 formal_param_pos, | 3548 formal_param_pos, |
| 3717 &Symbols::TypeArgumentsParameter(), | 3549 &Symbols::TypeArgumentsParameter(), |
| 3718 &Object::dynamic_type()); | 3550 &Object::dynamic_type()); |
| 3719 } | 3551 } |
| 3720 // Constructors have an implicit parameter for the construction phase. | |
| 3721 if (method->IsConstructor()) { | |
| 3722 method->params.AddFinalParameter( | |
| 3723 TokenPos(), | |
| 3724 &Symbols::PhaseParameter(), | |
| 3725 &Type::ZoneHandle(Z, Type::SmiType())); | |
| 3726 } | |
| 3727 if (are_implicitly_final) { | 3552 if (are_implicitly_final) { |
| 3728 method->params.SetImplicitlyFinal(); | 3553 method->params.SetImplicitlyFinal(); |
| 3729 } | 3554 } |
| 3730 if (!method->IsGetter()) { | 3555 if (!method->IsGetter()) { |
| 3731 ParseFormalParameterList(allow_explicit_default_values, | 3556 ParseFormalParameterList(allow_explicit_default_values, |
| 3732 false, | 3557 false, |
| 3733 &method->params); | 3558 &method->params); |
| 3734 } | 3559 } |
| 3735 | 3560 |
| 3736 // Now that we know the parameter list, we can distinguish between the | 3561 // Now that we know the parameter list, we can distinguish between the |
| (...skipping 1216 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4953 ctor.set_end_token_pos(ctor.token_pos()); | 4778 ctor.set_end_token_pos(ctor.token_pos()); |
| 4954 ctor.set_is_debuggable(false); | 4779 ctor.set_is_debuggable(false); |
| 4955 if (library_.is_dart_scheme() && library_.IsPrivate(ctor_name)) { | 4780 if (library_.is_dart_scheme() && library_.IsPrivate(ctor_name)) { |
| 4956 ctor.set_is_reflectable(false); | 4781 ctor.set_is_reflectable(false); |
| 4957 } | 4782 } |
| 4958 | 4783 |
| 4959 ParamList params; | 4784 ParamList params; |
| 4960 // Add implicit 'this' parameter. | 4785 // Add implicit 'this' parameter. |
| 4961 const AbstractType* receiver_type = ReceiverType(cls); | 4786 const AbstractType* receiver_type = ReceiverType(cls); |
| 4962 params.AddReceiver(receiver_type, cls.token_pos()); | 4787 params.AddReceiver(receiver_type, cls.token_pos()); |
| 4963 // Add implicit parameter for construction phase. | |
| 4964 params.AddFinalParameter(cls.token_pos(), | |
| 4965 &Symbols::PhaseParameter(), | |
| 4966 &Type::ZoneHandle(Z, Type::SmiType())); | |
| 4967 | 4788 |
| 4968 AddFormalParamsToFunction(¶ms, ctor); | 4789 AddFormalParamsToFunction(¶ms, ctor); |
| 4969 // The body of the constructor cannot modify the type of the constructed | 4790 // The body of the constructor cannot modify the type of the constructed |
| 4970 // instance, which is passed in as the receiver. | 4791 // instance, which is passed in as the receiver. |
| 4971 ctor.set_result_type(*receiver_type); | 4792 ctor.set_result_type(*receiver_type); |
| 4972 cls.AddFunction(ctor); | 4793 cls.AddFunction(ctor); |
| 4973 } | 4794 } |
| 4974 | 4795 |
| 4975 | 4796 |
| 4976 // Check for cycles in constructor redirection. | 4797 // Check for cycles in constructor redirection. |
| (...skipping 2506 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 7483 | 7304 |
| 7484 | 7305 |
| 7485 LocalVariable* Parser::LookupTypeArgumentsParameter(LocalScope* from_scope, | 7306 LocalVariable* Parser::LookupTypeArgumentsParameter(LocalScope* from_scope, |
| 7486 bool test_only) { | 7307 bool test_only) { |
| 7487 ASSERT(current_function().IsInFactoryScope()); | 7308 ASSERT(current_function().IsInFactoryScope()); |
| 7488 return from_scope->LookupVariable(Symbols::TypeArgumentsParameter(), | 7309 return from_scope->LookupVariable(Symbols::TypeArgumentsParameter(), |
| 7489 test_only); | 7310 test_only); |
| 7490 } | 7311 } |
| 7491 | 7312 |
| 7492 | 7313 |
| 7493 LocalVariable* Parser::LookupPhaseParameter() { | |
| 7494 const bool kTestOnly = false; | |
| 7495 return current_block_->scope->LookupVariable(Symbols::PhaseParameter(), | |
| 7496 kTestOnly); | |
| 7497 } | |
| 7498 | |
| 7499 | |
| 7500 void Parser::CaptureInstantiator() { | 7314 void Parser::CaptureInstantiator() { |
| 7501 ASSERT(current_block_->scope->function_level() > 0); | 7315 ASSERT(current_block_->scope->function_level() > 0); |
| 7502 const String* variable_name = current_function().IsInFactoryScope() ? | 7316 const String* variable_name = current_function().IsInFactoryScope() ? |
| 7503 &Symbols::TypeArgumentsParameter() : &Symbols::This(); | 7317 &Symbols::TypeArgumentsParameter() : &Symbols::This(); |
| 7504 current_block_->scope->CaptureVariable( | 7318 current_block_->scope->CaptureVariable( |
| 7505 current_block_->scope->LookupVariable(*variable_name, true)); | 7319 current_block_->scope->LookupVariable(*variable_name, true)); |
| 7506 } | 7320 } |
| 7507 | 7321 |
| 7508 | 7322 |
| 7509 AstNode* Parser::LoadReceiver(intptr_t token_pos) { | 7323 AstNode* Parser::LoadReceiver(intptr_t token_pos) { |
| (...skipping 4741 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 12251 field_ref_pos, NULL, field_owner, field_name); | 12065 field_ref_pos, NULL, field_owner, field_name); |
| 12252 } | 12066 } |
| 12253 | 12067 |
| 12254 | 12068 |
| 12255 RawObject* Parser::EvaluateConstConstructorCall( | 12069 RawObject* Parser::EvaluateConstConstructorCall( |
| 12256 const Class& type_class, | 12070 const Class& type_class, |
| 12257 const TypeArguments& type_arguments, | 12071 const TypeArguments& type_arguments, |
| 12258 const Function& constructor, | 12072 const Function& constructor, |
| 12259 ArgumentListNode* arguments) { | 12073 ArgumentListNode* arguments) { |
| 12260 // Factories have one extra argument: the type arguments. | 12074 // Factories have one extra argument: the type arguments. |
| 12261 // Constructors have 2 extra arguments: rcvr and construction phase. | 12075 // Constructors have 1 extra arguments: receiver. |
| 12262 const int kNumExtraArgs = constructor.IsFactory() ? 1 : 2; | 12076 const int kNumExtraArgs = 1; |
| 12263 const int num_arguments = arguments->length() + kNumExtraArgs; | 12077 const int num_arguments = arguments->length() + kNumExtraArgs; |
| 12264 const Array& arg_values = | 12078 const Array& arg_values = |
| 12265 Array::Handle(Z, Array::New(num_arguments, Heap::kOld)); | 12079 Array::Handle(Z, Array::New(num_arguments, Heap::kOld)); |
| 12266 Instance& instance = Instance::Handle(Z); | 12080 Instance& instance = Instance::Handle(Z); |
| 12267 if (!constructor.IsFactory()) { | 12081 if (!constructor.IsFactory()) { |
| 12268 instance = Instance::New(type_class, Heap::kOld); | 12082 instance = Instance::New(type_class, Heap::kOld); |
| 12269 if (!type_arguments.IsNull()) { | 12083 if (!type_arguments.IsNull()) { |
| 12270 if (!type_arguments.IsInstantiated()) { | 12084 if (!type_arguments.IsInstantiated()) { |
| 12271 ReportError("type must be constant in const constructor"); | 12085 ReportError("type must be constant in const constructor"); |
| 12272 } | 12086 } |
| 12273 instance.SetTypeArguments( | 12087 instance.SetTypeArguments( |
| 12274 TypeArguments::Handle(Z, type_arguments.Canonicalize())); | 12088 TypeArguments::Handle(Z, type_arguments.Canonicalize())); |
| 12275 } | 12089 } |
| 12276 arg_values.SetAt(0, instance); | 12090 arg_values.SetAt(0, instance); |
| 12277 arg_values.SetAt(1, Smi::Handle(Z, Smi::New(Function::kCtorPhaseAll))); | |
| 12278 } else { | 12091 } else { |
| 12279 // Prepend type_arguments to list of arguments to factory. | 12092 // Prepend type_arguments to list of arguments to factory. |
| 12280 ASSERT(type_arguments.IsZoneHandle()); | 12093 ASSERT(type_arguments.IsZoneHandle()); |
| 12281 arg_values.SetAt(0, type_arguments); | 12094 arg_values.SetAt(0, type_arguments); |
| 12282 } | 12095 } |
| 12283 for (int i = 0; i < arguments->length(); i++) { | 12096 for (int i = 0; i < arguments->length(); i++) { |
| 12284 AstNode* arg = arguments->NodeAt(i); | 12097 AstNode* arg = arguments->NodeAt(i); |
| 12285 // Arguments have been evaluated to a literal value already. | 12098 // Arguments have been evaluated to a literal value already. |
| 12286 ASSERT(arg->IsLiteralNode()); | 12099 ASSERT(arg->IsLiteralNode()); |
| 12287 arg_values.SetAt((i + kNumExtraArgs), arg->AsLiteralNode()->literal()); | 12100 arg_values.SetAt((i + kNumExtraArgs), arg->AsLiteralNode()->literal()); |
| (...skipping 1211 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 13499 return ThrowTypeError(type_pos, type); | 13312 return ThrowTypeError(type_pos, type); |
| 13500 } | 13313 } |
| 13501 | 13314 |
| 13502 // Resolve the type and optional identifier to a constructor or factory. | 13315 // Resolve the type and optional identifier to a constructor or factory. |
| 13503 String& type_class_name = String::Handle(Z, type_class.Name()); | 13316 String& type_class_name = String::Handle(Z, type_class.Name()); |
| 13504 TypeArguments& type_arguments = | 13317 TypeArguments& type_arguments = |
| 13505 TypeArguments::ZoneHandle(Z, type.arguments()); | 13318 TypeArguments::ZoneHandle(Z, type.arguments()); |
| 13506 | 13319 |
| 13507 // A constructor has an implicit 'this' parameter (instance to construct) | 13320 // A constructor has an implicit 'this' parameter (instance to construct) |
| 13508 // and a factory has an implicit 'this' parameter (type_arguments). | 13321 // and a factory has an implicit 'this' parameter (type_arguments). |
| 13509 // A constructor has a second implicit 'phase' parameter. | 13322 intptr_t arguments_length = arguments->length() + 1; |
| 13510 intptr_t arguments_length = arguments->length() + 2; | |
| 13511 | 13323 |
| 13512 // An additional type check of the result of a redirecting factory may be | 13324 // An additional type check of the result of a redirecting factory may be |
| 13513 // required. | 13325 // required. |
| 13514 AbstractType& type_bound = AbstractType::ZoneHandle(Z); | 13326 AbstractType& type_bound = AbstractType::ZoneHandle(Z); |
| 13515 | 13327 |
| 13516 // Make sure that an appropriate constructor exists. | 13328 // Make sure that an appropriate constructor exists. |
| 13517 String& constructor_name = | 13329 String& constructor_name = |
| 13518 BuildConstructorName(type_class_name, named_constructor); | 13330 BuildConstructorName(type_class_name, named_constructor); |
| 13519 Function& constructor = Function::ZoneHandle(Z, | 13331 Function& constructor = Function::ZoneHandle(Z, |
| 13520 type_class.LookupConstructor(constructor_name)); | 13332 type_class.LookupConstructor(constructor_name)); |
| (...skipping 77 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 13598 type_bound = type.raw(); | 13410 type_bound = type.raw(); |
| 13599 } | 13411 } |
| 13600 type = redirect_type.raw(); | 13412 type = redirect_type.raw(); |
| 13601 type_class = type.type_class(); | 13413 type_class = type.type_class(); |
| 13602 type_class_name = type_class.Name(); | 13414 type_class_name = type_class.Name(); |
| 13603 type_arguments = type.arguments(); | 13415 type_arguments = type.arguments(); |
| 13604 constructor = constructor.RedirectionTarget(); | 13416 constructor = constructor.RedirectionTarget(); |
| 13605 constructor_name = constructor.name(); | 13417 constructor_name = constructor.name(); |
| 13606 ASSERT(!constructor.IsNull()); | 13418 ASSERT(!constructor.IsNull()); |
| 13607 } | 13419 } |
| 13608 if (constructor.IsFactory()) { | |
| 13609 // A factory does not have the implicit 'phase' parameter. | |
| 13610 arguments_length -= 1; | |
| 13611 } | |
| 13612 } | 13420 } |
| 13613 ASSERT(!constructor.IsNull()); | 13421 ASSERT(!constructor.IsNull()); |
| 13614 | 13422 |
| 13615 // It is ok to call a factory method of an abstract class, but it is | 13423 // It is ok to call a factory method of an abstract class, but it is |
| 13616 // a dynamic error to instantiate an abstract class. | 13424 // a dynamic error to instantiate an abstract class. |
| 13617 if (type_class.is_abstract() && !constructor.IsFactory()) { | 13425 if (type_class.is_abstract() && !constructor.IsFactory()) { |
| 13618 // Evaluate arguments before throwing. | 13426 // Evaluate arguments before throwing. |
| 13619 LetNode* result = new(Z) LetNode(call_pos); | 13427 LetNode* result = new(Z) LetNode(call_pos); |
| 13620 for (intptr_t i = 0; i < arguments->length(); ++i) { | 13428 for (intptr_t i = 0; i < arguments->length(); ++i) { |
| 13621 result->AddNode(arguments->NodeAt(i)); | 13429 result->AddNode(arguments->NodeAt(i)); |
| (...skipping 955 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 14577 const ArgumentListNode& function_args, | 14385 const ArgumentListNode& function_args, |
| 14578 const LocalVariable* temp_for_last_arg, | 14386 const LocalVariable* temp_for_last_arg, |
| 14579 bool is_super_invocation) { | 14387 bool is_super_invocation) { |
| 14580 UNREACHABLE(); | 14388 UNREACHABLE(); |
| 14581 return NULL; | 14389 return NULL; |
| 14582 } | 14390 } |
| 14583 | 14391 |
| 14584 } // namespace dart | 14392 } // namespace dart |
| 14585 | 14393 |
| 14586 #endif // DART_PRECOMPILED | 14394 #endif // DART_PRECOMPILED |
| OLD | NEW |