| 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/bootstrap.h" | 9 #include "vm/bootstrap.h" |
| 10 #include "vm/class_finalizer.h" | 10 #include "vm/class_finalizer.h" |
| (...skipping 21 matching lines...) Expand all Loading... |
| 32 #include "vm/tags.h" | 32 #include "vm/tags.h" |
| 33 #include "vm/timer.h" | 33 #include "vm/timer.h" |
| 34 #include "vm/zone.h" | 34 #include "vm/zone.h" |
| 35 | 35 |
| 36 namespace dart { | 36 namespace dart { |
| 37 | 37 |
| 38 DEFINE_FLAG(bool, enable_asserts, false, "Enable assert statements."); | 38 DEFINE_FLAG(bool, enable_asserts, false, "Enable assert statements."); |
| 39 DEFINE_FLAG(bool, enable_type_checks, false, "Enable type checks."); | 39 DEFINE_FLAG(bool, enable_type_checks, false, "Enable type checks."); |
| 40 DEFINE_FLAG(bool, trace_parser, false, "Trace parser operations."); | 40 DEFINE_FLAG(bool, trace_parser, false, "Trace parser operations."); |
| 41 DEFINE_FLAG(bool, warn_mixin_typedef, true, "Warning on legacy mixin typedef."); | 41 DEFINE_FLAG(bool, warn_mixin_typedef, true, "Warning on legacy mixin typedef."); |
| 42 DEFINE_FLAG(bool, enable_async, false, "Enable async operations."); | |
| 43 DECLARE_FLAG(bool, error_on_bad_type); | 42 DECLARE_FLAG(bool, error_on_bad_type); |
| 44 DECLARE_FLAG(bool, throw_on_javascript_int_overflow); | 43 DECLARE_FLAG(bool, throw_on_javascript_int_overflow); |
| 45 DECLARE_FLAG(bool, warn_on_javascript_compatibility); | 44 DECLARE_FLAG(bool, warn_on_javascript_compatibility); |
| 46 | 45 |
| 47 static void CheckedModeHandler(bool value) { | 46 static void CheckedModeHandler(bool value) { |
| 48 FLAG_enable_asserts = value; | 47 FLAG_enable_asserts = value; |
| 49 FLAG_enable_type_checks = value; | 48 FLAG_enable_type_checks = value; |
| 50 } | 49 } |
| 51 | 50 |
| 52 // --enable-checked-mode and --checked both enable checked mode which is | 51 // --enable-checked-mode and --checked both enable checked mode which is |
| (...skipping 2839 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2892 AstNode* guarded_block_statements = | 2891 AstNode* guarded_block_statements = |
| 2893 new IfNode(Scanner::kNoSourcePos, comparison, ctor_block, NULL); | 2892 new IfNode(Scanner::kNoSourcePos, comparison, ctor_block, NULL); |
| 2894 current_block_->statements->Add(guarded_block_statements); | 2893 current_block_->statements->Add(guarded_block_statements); |
| 2895 } | 2894 } |
| 2896 current_block_->statements->Add(new ReturnNode(func.end_token_pos())); | 2895 current_block_->statements->Add(new ReturnNode(func.end_token_pos())); |
| 2897 SequenceNode* statements = CloseBlock(); | 2896 SequenceNode* statements = CloseBlock(); |
| 2898 return statements; | 2897 return statements; |
| 2899 } | 2898 } |
| 2900 | 2899 |
| 2901 | 2900 |
| 2902 // TODO(mlippautz): Once we know where these classes should come from, adjust | |
| 2903 // how we get their definition. | |
| 2904 RawClass* Parser::GetClassForAsync(const String& class_name) { | |
| 2905 const Class& cls = Class::Handle(library_.LookupClass(class_name)); | |
| 2906 if (cls.IsNull()) { | |
| 2907 ReportError("async modifier requires dart:async to be imported"); | |
| 2908 } | |
| 2909 return cls.raw(); | |
| 2910 } | |
| 2911 | |
| 2912 | |
| 2913 // Parser is at the opening parenthesis of the formal parameter | 2901 // Parser is at the opening parenthesis of the formal parameter |
| 2914 // declaration of the function or constructor. | 2902 // declaration of the function or constructor. |
| 2915 // Parse the formal parameters and code. | 2903 // Parse the formal parameters and code. |
| 2916 SequenceNode* Parser::ParseFunc(const Function& func, | 2904 SequenceNode* Parser::ParseFunc(const Function& func, |
| 2917 Array* default_parameter_values) { | 2905 Array* default_parameter_values) { |
| 2918 TRACE_PARSER("ParseFunc"); | 2906 TRACE_PARSER("ParseFunc"); |
| 2919 Function& saved_innermost_function = | 2907 Function& saved_innermost_function = |
| 2920 Function::Handle(I, innermost_function().raw()); | 2908 Function::Handle(I, innermost_function().raw()); |
| 2921 innermost_function_ = func.raw(); | 2909 innermost_function_ = func.raw(); |
| 2922 | 2910 |
| 2923 // Save current try index. Try index starts at zero for each function. | 2911 // Save current try index. Try index starts at zero for each function. |
| 2924 intptr_t saved_try_index = last_used_try_index_; | 2912 intptr_t saved_try_index = last_used_try_index_; |
| 2925 last_used_try_index_ = 0; | 2913 last_used_try_index_ = 0; |
| 2926 | 2914 |
| 2927 intptr_t formal_params_pos = TokenPos(); | |
| 2928 // TODO(12455) : Need better validation mechanism. | 2915 // TODO(12455) : Need better validation mechanism. |
| 2929 | 2916 |
| 2930 if (func.IsConstructor()) { | 2917 if (func.IsConstructor()) { |
| 2931 SequenceNode* statements = ParseConstructor(func, default_parameter_values); | 2918 SequenceNode* statements = ParseConstructor(func, default_parameter_values); |
| 2932 innermost_function_ = saved_innermost_function.raw(); | 2919 innermost_function_ = saved_innermost_function.raw(); |
| 2933 last_used_try_index_ = saved_try_index; | 2920 last_used_try_index_ = saved_try_index; |
| 2934 return statements; | 2921 return statements; |
| 2935 } | 2922 } |
| 2936 | 2923 |
| 2937 ASSERT(!func.IsConstructor()); | 2924 ASSERT(!func.IsConstructor()); |
| (...skipping 14 matching lines...) Expand all Loading... |
| 2952 ASSERT(current_class().raw() == func.Owner()); | 2939 ASSERT(current_class().raw() == func.Owner()); |
| 2953 params.AddReceiver(ReceiverType(current_class()), func.token_pos()); | 2940 params.AddReceiver(ReceiverType(current_class()), func.token_pos()); |
| 2954 } else if (func.IsFactory()) { | 2941 } else if (func.IsFactory()) { |
| 2955 // The first parameter of a factory is the TypeArguments vector of | 2942 // The first parameter of a factory is the TypeArguments vector of |
| 2956 // the type of the instance to be allocated. | 2943 // the type of the instance to be allocated. |
| 2957 params.AddFinalParameter( | 2944 params.AddFinalParameter( |
| 2958 TokenPos(), | 2945 TokenPos(), |
| 2959 &Symbols::TypeArgumentsParameter(), | 2946 &Symbols::TypeArgumentsParameter(), |
| 2960 &Type::ZoneHandle(I, Type::DynamicType())); | 2947 &Type::ZoneHandle(I, Type::DynamicType())); |
| 2961 } | 2948 } |
| 2962 ASSERT((CurrentToken() == Token::kLPAREN) || | 2949 ASSERT((CurrentToken() == Token::kLPAREN) || func.IsGetterFunction()); |
| 2963 func.IsGetterFunction() || | |
| 2964 func.is_async_closure()); | |
| 2965 const bool allow_explicit_default_values = true; | 2950 const bool allow_explicit_default_values = true; |
| 2966 if (func.IsGetterFunction()) { | 2951 if (func.IsGetterFunction()) { |
| 2967 // Populate function scope with the formal parameters. Since in this case | 2952 // Populate function scope with the formal parameters. Since in this case |
| 2968 // we are compiling a getter this will at most populate the receiver. | 2953 // we are compiling a getter this will at most populate the receiver. |
| 2969 AddFormalParamsToScope(¶ms, current_block_->scope); | 2954 AddFormalParamsToScope(¶ms, current_block_->scope); |
| 2970 } else if (func.is_async_closure()) { | |
| 2971 AddFormalParamsToScope(¶ms, current_block_->scope); | |
| 2972 ASSERT(AbstractType::Handle(I, func.result_type()).IsResolved()); | |
| 2973 ASSERT(func.NumParameters() == params.parameters->length()); | |
| 2974 if (!Function::Handle(func.parent_function()).IsGetterFunction()) { | |
| 2975 // Parse away any formal parameters, as they are accessed as as context | |
| 2976 // variables. | |
| 2977 ParseFormalParameterList(allow_explicit_default_values, false, ¶ms); | |
| 2978 } | |
| 2979 } else { | 2955 } else { |
| 2980 ParseFormalParameterList(allow_explicit_default_values, false, ¶ms); | 2956 ParseFormalParameterList(allow_explicit_default_values, false, ¶ms); |
| 2981 | 2957 |
| 2982 // The number of parameters and their type are not yet set in local | 2958 // The number of parameters and their type are not yet set in local |
| 2983 // functions, since they are not 'top-level' parsed. | 2959 // functions, since they are not 'top-level' parsed. |
| 2984 if (func.IsLocalFunction()) { | 2960 if (func.IsLocalFunction()) { |
| 2985 AddFormalParamsToFunction(¶ms, func); | 2961 AddFormalParamsToFunction(¶ms, func); |
| 2986 } | 2962 } |
| 2987 SetupDefaultsForOptionalParams(¶ms, default_parameter_values); | 2963 SetupDefaultsForOptionalParams(¶ms, default_parameter_values); |
| 2988 ASSERT(AbstractType::Handle(I, func.result_type()).IsResolved()); | 2964 ASSERT(AbstractType::Handle(I, func.result_type()).IsResolved()); |
| (...skipping 20 matching lines...) Expand all Loading... |
| 3009 if (IsInstantiatorRequired()) { | 2985 if (IsInstantiatorRequired()) { |
| 3010 // Make sure that the receiver of the enclosing instance function | 2986 // Make sure that the receiver of the enclosing instance function |
| 3011 // (or implicit first parameter of an enclosing factory) is marked as | 2987 // (or implicit first parameter of an enclosing factory) is marked as |
| 3012 // captured if type checks are enabled, because they may access it to | 2988 // captured if type checks are enabled, because they may access it to |
| 3013 // instantiate types. | 2989 // instantiate types. |
| 3014 CaptureInstantiator(); | 2990 CaptureInstantiator(); |
| 3015 } | 2991 } |
| 3016 } | 2992 } |
| 3017 } | 2993 } |
| 3018 | 2994 |
| 3019 RawFunction::AsyncModifier func_modifier = ParseFunctionModifier(); | |
| 3020 func.set_modifier(func_modifier); | |
| 3021 | |
| 3022 OpenBlock(); // Open a nested scope for the outermost function block. | 2995 OpenBlock(); // Open a nested scope for the outermost function block. |
| 3023 | |
| 3024 Function& async_closure = Function::ZoneHandle(I); | |
| 3025 if (func.IsAsyncFunction() && !func.is_async_closure()) { | |
| 3026 async_closure = OpenAsyncFunction(formal_params_pos); | |
| 3027 } | |
| 3028 | |
| 3029 intptr_t end_token_pos = 0; | 2996 intptr_t end_token_pos = 0; |
| 3030 if (CurrentToken() == Token::kLBRACE) { | 2997 if (CurrentToken() == Token::kLBRACE) { |
| 3031 ConsumeToken(); | 2998 ConsumeToken(); |
| 3032 if (String::Handle(I, func.name()).Equals( | 2999 if (String::Handle(I, func.name()).Equals( |
| 3033 Symbols::EqualOperator())) { | 3000 Symbols::EqualOperator())) { |
| 3034 const Class& owner = Class::Handle(I, func.Owner()); | 3001 const Class& owner = Class::Handle(I, func.Owner()); |
| 3035 if (!owner.IsObjectClass()) { | 3002 if (!owner.IsObjectClass()) { |
| 3036 AddEqualityNullCheck(); | 3003 AddEqualityNullCheck(); |
| 3037 } | 3004 } |
| 3038 } | 3005 } |
| (...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3079 &func)); // Unpatched external function. | 3046 &func)); // Unpatched external function. |
| 3080 end_token_pos = TokenPos(); | 3047 end_token_pos = TokenPos(); |
| 3081 } else { | 3048 } else { |
| 3082 UnexpectedToken(); | 3049 UnexpectedToken(); |
| 3083 } | 3050 } |
| 3084 | 3051 |
| 3085 ASSERT(func.end_token_pos() == func.token_pos() || | 3052 ASSERT(func.end_token_pos() == func.token_pos() || |
| 3086 func.end_token_pos() == end_token_pos); | 3053 func.end_token_pos() == end_token_pos); |
| 3087 func.set_end_token_pos(end_token_pos); | 3054 func.set_end_token_pos(end_token_pos); |
| 3088 SequenceNode* body = CloseBlock(); | 3055 SequenceNode* body = CloseBlock(); |
| 3089 if (func.IsAsyncFunction() && !func.is_async_closure()) { | |
| 3090 body = CloseAsyncFunction(async_closure, body); | |
| 3091 } else if (func.is_async_closure()) { | |
| 3092 CloseAsyncClosure(body); | |
| 3093 } | |
| 3094 current_block_->statements->Add(body); | 3056 current_block_->statements->Add(body); |
| 3095 innermost_function_ = saved_innermost_function.raw(); | 3057 innermost_function_ = saved_innermost_function.raw(); |
| 3096 last_used_try_index_ = saved_try_index; | 3058 last_used_try_index_ = saved_try_index; |
| 3097 return CloseBlock(); | 3059 return CloseBlock(); |
| 3098 } | 3060 } |
| 3099 | 3061 |
| 3100 | 3062 |
| 3101 void Parser::AddEqualityNullCheck() { | 3063 void Parser::AddEqualityNullCheck() { |
| 3102 AstNode* argument = | 3064 AstNode* argument = |
| 3103 new LoadLocalNode(Scanner::kNoSourcePos, | 3065 new LoadLocalNode(Scanner::kNoSourcePos, |
| (...skipping 293 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3397 ASSERT((method->redirect_name == NULL) || method->IsConstructor()); | 3359 ASSERT((method->redirect_name == NULL) || method->IsConstructor()); |
| 3398 | 3360 |
| 3399 if (method->IsConstructor() && | 3361 if (method->IsConstructor() && |
| 3400 method->has_external && | 3362 method->has_external && |
| 3401 method->params.has_field_initializer) { | 3363 method->params.has_field_initializer) { |
| 3402 ReportError(method->name_pos, | 3364 ReportError(method->name_pos, |
| 3403 "external constructor '%s' may not have field initializers", | 3365 "external constructor '%s' may not have field initializers", |
| 3404 method->name->ToCString()); | 3366 method->name->ToCString()); |
| 3405 } | 3367 } |
| 3406 | 3368 |
| 3407 RawFunction::AsyncModifier async_modifier = ParseFunctionModifier(); | |
| 3408 if ((method->IsFactoryOrConstructor() || method->IsSetter()) && | |
| 3409 async_modifier != RawFunction::kNoModifier) { | |
| 3410 ReportError(method->name_pos, | |
| 3411 "%s '%s' may not be async", | |
| 3412 (method->IsSetter()) ? "setter" : "constructor", | |
| 3413 method->name->ToCString()); | |
| 3414 } | |
| 3415 | |
| 3416 intptr_t method_end_pos = TokenPos(); | 3369 intptr_t method_end_pos = TokenPos(); |
| 3417 if ((CurrentToken() == Token::kLBRACE) || | 3370 if ((CurrentToken() == Token::kLBRACE) || |
| 3418 (CurrentToken() == Token::kARROW)) { | 3371 (CurrentToken() == Token::kARROW)) { |
| 3419 if (method->has_abstract) { | 3372 if (method->has_abstract) { |
| 3420 ReportError(TokenPos(), | 3373 ReportError(TokenPos(), |
| 3421 "abstract method '%s' may not have a function body", | 3374 "abstract method '%s' may not have a function body", |
| 3422 method->name->ToCString()); | 3375 method->name->ToCString()); |
| 3423 } else if (method->has_external) { | 3376 } else if (method->has_external) { |
| 3424 ReportError(TokenPos(), | 3377 ReportError(TokenPos(), |
| 3425 "external %s '%s' may not have a function body", | 3378 "external %s '%s' may not have a function body", |
| (...skipping 94 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3520 method->has_static, | 3473 method->has_static, |
| 3521 method->has_const, | 3474 method->has_const, |
| 3522 method->has_abstract, | 3475 method->has_abstract, |
| 3523 method->has_external, | 3476 method->has_external, |
| 3524 method->has_native, | 3477 method->has_native, |
| 3525 current_class(), | 3478 current_class(), |
| 3526 method->decl_begin_pos)); | 3479 method->decl_begin_pos)); |
| 3527 func.set_result_type(*method->type); | 3480 func.set_result_type(*method->type); |
| 3528 func.set_end_token_pos(method_end_pos); | 3481 func.set_end_token_pos(method_end_pos); |
| 3529 func.set_is_redirecting(is_redirecting); | 3482 func.set_is_redirecting(is_redirecting); |
| 3530 func.set_modifier(async_modifier); | |
| 3531 if (method->has_native && library_.is_dart_scheme() && | 3483 if (method->has_native && library_.is_dart_scheme() && |
| 3532 library_.IsPrivate(*method->name)) { | 3484 library_.IsPrivate(*method->name)) { |
| 3533 func.set_is_visible(false); | 3485 func.set_is_visible(false); |
| 3534 } | 3486 } |
| 3535 if (method->IsFactoryOrConstructor() && library_.is_dart_scheme() && | 3487 if (method->IsFactoryOrConstructor() && library_.is_dart_scheme() && |
| 3536 library_.IsPrivate(*method->name)) { | 3488 library_.IsPrivate(*method->name)) { |
| 3537 func.set_is_visible(false); | 3489 func.set_is_visible(false); |
| 3538 } | 3490 } |
| 3539 if (method->metadata_pos > 0) { | 3491 if (method->metadata_pos > 0) { |
| 3540 library_.AddFunctionMetadata(func, method->metadata_pos); | 3492 library_.AddFunctionMetadata(func, method->metadata_pos); |
| (...skipping 1300 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4841 } else if (CurrentToken() == Token::kSEMICOLON) { | 4793 } else if (CurrentToken() == Token::kSEMICOLON) { |
| 4842 ConsumeToken(); | 4794 ConsumeToken(); |
| 4843 break; | 4795 break; |
| 4844 } else { | 4796 } else { |
| 4845 ExpectSemicolon(); // Reports error. | 4797 ExpectSemicolon(); // Reports error. |
| 4846 } | 4798 } |
| 4847 } | 4799 } |
| 4848 } | 4800 } |
| 4849 | 4801 |
| 4850 | 4802 |
| 4851 RawFunction::AsyncModifier Parser::ParseFunctionModifier() { | |
| 4852 if (FLAG_enable_async) { | |
| 4853 if (CurrentLiteral()->raw() == Symbols::Async().raw()) { | |
| 4854 ConsumeToken(); | |
| 4855 return RawFunction::kAsync; | |
| 4856 } | |
| 4857 } | |
| 4858 return RawFunction::kNoModifier; | |
| 4859 } | |
| 4860 | |
| 4861 | |
| 4862 void Parser::ParseTopLevelFunction(TopLevel* top_level, | 4803 void Parser::ParseTopLevelFunction(TopLevel* top_level, |
| 4863 intptr_t metadata_pos) { | 4804 intptr_t metadata_pos) { |
| 4864 TRACE_PARSER("ParseTopLevelFunction"); | 4805 TRACE_PARSER("ParseTopLevelFunction"); |
| 4865 const intptr_t decl_begin_pos = TokenPos(); | 4806 const intptr_t decl_begin_pos = TokenPos(); |
| 4866 AbstractType& result_type = Type::Handle(I, Type::DynamicType()); | 4807 AbstractType& result_type = Type::Handle(I, Type::DynamicType()); |
| 4867 const bool is_static = true; | 4808 const bool is_static = true; |
| 4868 bool is_external = false; | 4809 bool is_external = false; |
| 4869 bool is_patch = false; | 4810 bool is_patch = false; |
| 4870 if (is_patch_source() && | 4811 if (is_patch_source() && |
| 4871 (CurrentToken() == Token::kIDENT) && | 4812 (CurrentToken() == Token::kIDENT) && |
| (...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4905 } | 4846 } |
| 4906 // A setter named x= may co-exist with a function named x, thus we do | 4847 // A setter named x= may co-exist with a function named x, thus we do |
| 4907 // not need to check setters. | 4848 // not need to check setters. |
| 4908 | 4849 |
| 4909 CheckToken(Token::kLPAREN); | 4850 CheckToken(Token::kLPAREN); |
| 4910 const intptr_t function_pos = TokenPos(); | 4851 const intptr_t function_pos = TokenPos(); |
| 4911 ParamList params; | 4852 ParamList params; |
| 4912 const bool allow_explicit_default_values = true; | 4853 const bool allow_explicit_default_values = true; |
| 4913 ParseFormalParameterList(allow_explicit_default_values, false, ¶ms); | 4854 ParseFormalParameterList(allow_explicit_default_values, false, ¶ms); |
| 4914 | 4855 |
| 4915 RawFunction::AsyncModifier func_modifier = ParseFunctionModifier(); | |
| 4916 | |
| 4917 intptr_t function_end_pos = function_pos; | 4856 intptr_t function_end_pos = function_pos; |
| 4918 bool is_native = false; | 4857 bool is_native = false; |
| 4919 if (is_external) { | 4858 if (is_external) { |
| 4920 function_end_pos = TokenPos(); | 4859 function_end_pos = TokenPos(); |
| 4921 ExpectSemicolon(); | 4860 ExpectSemicolon(); |
| 4922 } else if (CurrentToken() == Token::kLBRACE) { | 4861 } else if (CurrentToken() == Token::kLBRACE) { |
| 4923 SkipBlock(); | 4862 SkipBlock(); |
| 4924 function_end_pos = TokenPos(); | 4863 function_end_pos = TokenPos(); |
| 4925 ExpectToken(Token::kRBRACE); | 4864 ExpectToken(Token::kRBRACE); |
| 4926 } else if (CurrentToken() == Token::kARROW) { | 4865 } else if (CurrentToken() == Token::kARROW) { |
| (...skipping 14 matching lines...) Expand all Loading... |
| 4941 RawFunction::kRegularFunction, | 4880 RawFunction::kRegularFunction, |
| 4942 is_static, | 4881 is_static, |
| 4943 /* is_const = */ false, | 4882 /* is_const = */ false, |
| 4944 /* is_abstract = */ false, | 4883 /* is_abstract = */ false, |
| 4945 is_external, | 4884 is_external, |
| 4946 is_native, | 4885 is_native, |
| 4947 current_class(), | 4886 current_class(), |
| 4948 decl_begin_pos)); | 4887 decl_begin_pos)); |
| 4949 func.set_result_type(result_type); | 4888 func.set_result_type(result_type); |
| 4950 func.set_end_token_pos(function_end_pos); | 4889 func.set_end_token_pos(function_end_pos); |
| 4951 func.set_modifier(func_modifier); | |
| 4952 if (is_native && library_.is_dart_scheme() && library_.IsPrivate(func_name)) { | 4890 if (is_native && library_.is_dart_scheme() && library_.IsPrivate(func_name)) { |
| 4953 func.set_is_visible(false); | 4891 func.set_is_visible(false); |
| 4954 } | 4892 } |
| 4955 AddFormalParamsToFunction(¶ms, func); | 4893 AddFormalParamsToFunction(¶ms, func); |
| 4956 top_level->functions.Add(func); | 4894 top_level->functions.Add(func); |
| 4957 if (!is_patch) { | 4895 if (!is_patch) { |
| 4958 library_.AddObject(func, func_name); | 4896 library_.AddObject(func, func_name); |
| 4959 } else { | 4897 } else { |
| 4960 library_.ReplaceObject(func, func_name); | 4898 library_.ReplaceObject(func, func_name); |
| 4961 } | 4899 } |
| (...skipping 82 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 5044 if (found && !is_patch) { | 4982 if (found && !is_patch) { |
| 5045 ReportError(name_pos, "%s for '%s' is already defined", | 4983 ReportError(name_pos, "%s for '%s' is already defined", |
| 5046 is_getter ? "getter" : "setter", | 4984 is_getter ? "getter" : "setter", |
| 5047 field_name->ToCString()); | 4985 field_name->ToCString()); |
| 5048 } else if (!found && is_patch) { | 4986 } else if (!found && is_patch) { |
| 5049 ReportError(name_pos, "missing %s for '%s' cannot be patched", | 4987 ReportError(name_pos, "missing %s for '%s' cannot be patched", |
| 5050 is_getter ? "getter" : "setter", | 4988 is_getter ? "getter" : "setter", |
| 5051 field_name->ToCString()); | 4989 field_name->ToCString()); |
| 5052 } | 4990 } |
| 5053 | 4991 |
| 5054 RawFunction::AsyncModifier func_modifier = ParseFunctionModifier(); | |
| 5055 | |
| 5056 intptr_t accessor_end_pos = accessor_pos; | 4992 intptr_t accessor_end_pos = accessor_pos; |
| 5057 bool is_native = false; | 4993 bool is_native = false; |
| 5058 if (is_external) { | 4994 if (is_external) { |
| 5059 accessor_end_pos = TokenPos(); | 4995 accessor_end_pos = TokenPos(); |
| 5060 ExpectSemicolon(); | 4996 ExpectSemicolon(); |
| 5061 } else if (CurrentToken() == Token::kLBRACE) { | 4997 } else if (CurrentToken() == Token::kLBRACE) { |
| 5062 SkipBlock(); | 4998 SkipBlock(); |
| 5063 accessor_end_pos = TokenPos(); | 4999 accessor_end_pos = TokenPos(); |
| 5064 ExpectToken(Token::kRBRACE); | 5000 ExpectToken(Token::kRBRACE); |
| 5065 } else if (CurrentToken() == Token::kARROW) { | 5001 } else if (CurrentToken() == Token::kARROW) { |
| (...skipping 15 matching lines...) Expand all Loading... |
| 5081 RawFunction::kSetterFunction, | 5017 RawFunction::kSetterFunction, |
| 5082 is_static, | 5018 is_static, |
| 5083 /* is_const = */ false, | 5019 /* is_const = */ false, |
| 5084 /* is_abstract = */ false, | 5020 /* is_abstract = */ false, |
| 5085 is_external, | 5021 is_external, |
| 5086 is_native, | 5022 is_native, |
| 5087 current_class(), | 5023 current_class(), |
| 5088 decl_begin_pos)); | 5024 decl_begin_pos)); |
| 5089 func.set_result_type(result_type); | 5025 func.set_result_type(result_type); |
| 5090 func.set_end_token_pos(accessor_end_pos); | 5026 func.set_end_token_pos(accessor_end_pos); |
| 5091 func.set_modifier(func_modifier); | |
| 5092 if (is_native && library_.is_dart_scheme() && | 5027 if (is_native && library_.is_dart_scheme() && |
| 5093 library_.IsPrivate(accessor_name)) { | 5028 library_.IsPrivate(accessor_name)) { |
| 5094 func.set_is_visible(false); | 5029 func.set_is_visible(false); |
| 5095 } | 5030 } |
| 5096 AddFormalParamsToFunction(¶ms, func); | 5031 AddFormalParamsToFunction(¶ms, func); |
| 5097 top_level->functions.Add(func); | 5032 top_level->functions.Add(func); |
| 5098 if (!is_patch) { | 5033 if (!is_patch) { |
| 5099 library_.AddObject(func, accessor_name); | 5034 library_.AddObject(func, accessor_name); |
| 5100 } else { | 5035 } else { |
| 5101 library_.ReplaceObject(func, accessor_name); | 5036 library_.ReplaceObject(func, accessor_name); |
| (...skipping 396 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 5498 // We are parsing a nested function while compiling the enclosing function. | 5433 // We are parsing a nested function while compiling the enclosing function. |
| 5499 outer_scope = | 5434 outer_scope = |
| 5500 new(I) LocalScope(current_block_->scope, | 5435 new(I) LocalScope(current_block_->scope, |
| 5501 current_block_->scope->function_level() + 1, | 5436 current_block_->scope->function_level() + 1, |
| 5502 0); | 5437 0); |
| 5503 } | 5438 } |
| 5504 ChainNewBlock(outer_scope); | 5439 ChainNewBlock(outer_scope); |
| 5505 } | 5440 } |
| 5506 | 5441 |
| 5507 | 5442 |
| 5508 RawFunction* Parser::OpenAsyncFunction(intptr_t formal_param_pos) { | |
| 5509 // Create the closure containing the old body of this function. | |
| 5510 Class& sig_cls = Class::ZoneHandle(I); | |
| 5511 Type& sig_type = Type::ZoneHandle(I); | |
| 5512 Function& closure = Function::ZoneHandle(I); | |
| 5513 String& sig = String::ZoneHandle(I); | |
| 5514 ParamList closure_params; | |
| 5515 closure_params.AddFinalParameter( | |
| 5516 formal_param_pos, | |
| 5517 &Symbols::ClosureParameter(), | |
| 5518 &Type::ZoneHandle(I, Type::DynamicType())); | |
| 5519 closure = Function::NewClosureFunction( | |
| 5520 Symbols::AnonymousClosure(), | |
| 5521 innermost_function(), | |
| 5522 formal_param_pos); | |
| 5523 AddFormalParamsToFunction(&closure_params, closure); | |
| 5524 closure.set_is_async_closure(true); | |
| 5525 closure.set_result_type(AbstractType::Handle(Type::DynamicType())); | |
| 5526 sig = closure.Signature(); | |
| 5527 sig_cls = library_.LookupLocalClass(sig); | |
| 5528 if (sig_cls.IsNull()) { | |
| 5529 sig_cls = Class::NewSignatureClass(sig, closure, script_, formal_param_pos); | |
| 5530 library_.AddClass(sig_cls); | |
| 5531 } | |
| 5532 closure.set_signature_class(sig_cls); | |
| 5533 sig_type = sig_cls.SignatureType(); | |
| 5534 if (!sig_type.IsFinalized()) { | |
| 5535 ClassFinalizer::FinalizeType( | |
| 5536 sig_cls, sig_type, ClassFinalizer::kCanonicalize); | |
| 5537 } | |
| 5538 ASSERT(AbstractType::Handle(I, closure.result_type()).IsResolved()); | |
| 5539 ASSERT(closure.NumParameters() == closure_params.parameters->length()); | |
| 5540 OpenFunctionBlock(closure); | |
| 5541 AddFormalParamsToScope(&closure_params, current_block_->scope); | |
| 5542 OpenBlock(); | |
| 5543 return closure.raw(); | |
| 5544 } | |
| 5545 | |
| 5546 | |
| 5547 SequenceNode* Parser::CloseBlock() { | 5443 SequenceNode* Parser::CloseBlock() { |
| 5548 SequenceNode* statements = current_block_->statements; | 5444 SequenceNode* statements = current_block_->statements; |
| 5549 if (current_block_->scope != NULL) { | 5445 if (current_block_->scope != NULL) { |
| 5550 // Record the begin and end token index of the scope. | 5446 // Record the begin and end token index of the scope. |
| 5551 ASSERT(statements != NULL); | 5447 ASSERT(statements != NULL); |
| 5552 current_block_->scope->set_begin_token_pos(statements->token_pos()); | 5448 current_block_->scope->set_begin_token_pos(statements->token_pos()); |
| 5553 current_block_->scope->set_end_token_pos(TokenPos()); | 5449 current_block_->scope->set_end_token_pos(TokenPos()); |
| 5554 } | 5450 } |
| 5555 current_block_ = current_block_->parent; | 5451 current_block_ = current_block_->parent; |
| 5556 return statements; | 5452 return statements; |
| 5557 } | 5453 } |
| 5558 | 5454 |
| 5559 | 5455 |
| 5560 SequenceNode* Parser::CloseAsyncFunction(const Function& closure, | |
| 5561 SequenceNode* closure_body) { | |
| 5562 ASSERT(!closure.IsNull()); | |
| 5563 ASSERT(closure_body != NULL); | |
| 5564 // The block for the async closure body has already been closed. Close the | |
| 5565 // corresponding function block. | |
| 5566 CloseBlock(); | |
| 5567 | |
| 5568 // Create and return a new future that executes a closure with the current | |
| 5569 // body. | |
| 5570 | |
| 5571 bool found = false; | |
| 5572 | |
| 5573 // No need to capture parameters or other variables, since they have already | |
| 5574 // been captured in the corresponding scope as the body has been parsed within | |
| 5575 // a nested block (contained in the async funtion's block). | |
| 5576 const Class& future = Class::ZoneHandle(I, | |
| 5577 GetClassForAsync(Symbols::Future())); | |
| 5578 ASSERT(!future.IsNull()); | |
| 5579 const Function& constructor = Function::ZoneHandle(I, | |
| 5580 future.LookupFunction(Symbols::FutureConstructor())); | |
| 5581 ASSERT(!constructor.IsNull()); | |
| 5582 const Class& completer = Class::ZoneHandle(I, | |
| 5583 GetClassForAsync(Symbols::Completer())); | |
| 5584 ASSERT(!completer.IsNull()); | |
| 5585 const Function& completer_constructor = Function::ZoneHandle(I, | |
| 5586 completer.LookupFunction(Symbols::CompleterConstructor())); | |
| 5587 ASSERT(!completer_constructor.IsNull()); | |
| 5588 | |
| 5589 // Add to AST: | |
| 5590 // var :async_op; | |
| 5591 // var :async_completer; | |
| 5592 LocalVariable* async_op_var = new (I) LocalVariable( | |
| 5593 Scanner::kNoSourcePos, | |
| 5594 Symbols::AsyncOperation(), | |
| 5595 Type::ZoneHandle(I, Type::DynamicType())); | |
| 5596 current_block_->scope->AddVariable(async_op_var); | |
| 5597 found = closure_body->scope()->CaptureVariable(Symbols::AsyncOperation()); | |
| 5598 ASSERT(found); | |
| 5599 LocalVariable* async_completer = new (I) LocalVariable( | |
| 5600 Scanner::kNoSourcePos, | |
| 5601 Symbols::AsyncCompleter(), | |
| 5602 Type::ZoneHandle(I, Type::DynamicType())); | |
| 5603 current_block_->scope->AddVariable(async_completer); | |
| 5604 found = closure_body->scope()->CaptureVariable(Symbols::AsyncCompleter()); | |
| 5605 ASSERT(found); | |
| 5606 | |
| 5607 // Add to AST: | |
| 5608 // :async_completer = new Completer(); | |
| 5609 ArgumentListNode* empty_args = new (I) ArgumentListNode( | |
| 5610 Scanner::kNoSourcePos); | |
| 5611 ConstructorCallNode* completer_constructor_node = new (I) ConstructorCallNode( | |
| 5612 Scanner::kNoSourcePos, | |
| 5613 TypeArguments::ZoneHandle(I), | |
| 5614 completer_constructor, | |
| 5615 empty_args); | |
| 5616 StoreLocalNode* store_completer = new (I) StoreLocalNode( | |
| 5617 Scanner::kNoSourcePos, | |
| 5618 async_completer, | |
| 5619 completer_constructor_node); | |
| 5620 current_block_->statements->Add(store_completer); | |
| 5621 | |
| 5622 // Add to AST: | |
| 5623 // :async_op = <closure>; (containing the original body) | |
| 5624 ClosureNode* cn = new(I) ClosureNode( | |
| 5625 Scanner::kNoSourcePos, closure, NULL, closure_body->scope()); | |
| 5626 StoreLocalNode* store_async_op = new (I) StoreLocalNode( | |
| 5627 Scanner::kNoSourcePos, | |
| 5628 async_op_var, | |
| 5629 cn); | |
| 5630 current_block_->statements->Add(store_async_op); | |
| 5631 | |
| 5632 // Add to AST: | |
| 5633 // new Future(:async_op); | |
| 5634 ArgumentListNode* arguments = new (I) ArgumentListNode(Scanner::kNoSourcePos); | |
| 5635 arguments->Add(new (I) LoadLocalNode( | |
| 5636 Scanner::kNoSourcePos, async_op_var)); | |
| 5637 ConstructorCallNode* future_node = new (I) ConstructorCallNode( | |
| 5638 Scanner::kNoSourcePos, TypeArguments::ZoneHandle(I), constructor, | |
| 5639 arguments); | |
| 5640 current_block_->statements->Add(future_node); | |
| 5641 | |
| 5642 // Add to AST: | |
| 5643 // return :async_completer.future; | |
| 5644 ReturnNode* return_node = new (I) ReturnNode( | |
| 5645 Scanner::kNoSourcePos, | |
| 5646 new (I) InstanceGetterNode( | |
| 5647 Scanner::kNoSourcePos, | |
| 5648 new (I) LoadLocalNode( | |
| 5649 Scanner::kNoSourcePos, | |
| 5650 async_completer), | |
| 5651 Symbols::CompleterFuture())); | |
| 5652 current_block_->statements->Add(return_node); | |
| 5653 return CloseBlock(); | |
| 5654 } | |
| 5655 | |
| 5656 | |
| 5657 void Parser::CloseAsyncClosure(SequenceNode* body) { | |
| 5658 ASSERT(body != NULL); | |
| 5659 // Replace an optional ReturnNode with the appropriate completer calls. | |
| 5660 intptr_t last_index = body->length() - 1; | |
| 5661 AstNode* last = NULL; | |
| 5662 if (last_index >= 0) { | |
| 5663 // Non-empty async closure. | |
| 5664 last = body->NodeAt(last_index); | |
| 5665 } | |
| 5666 ArgumentListNode* args = new (I) ArgumentListNode(Scanner::kNoSourcePos); | |
| 5667 LocalVariable* completer = body->scope()->LookupVariable( | |
| 5668 Symbols::AsyncCompleter(), false); | |
| 5669 ASSERT(completer != NULL); | |
| 5670 if (last != NULL && last->IsReturnNode()) { | |
| 5671 // Replace | |
| 5672 // return <expr>; | |
| 5673 // with | |
| 5674 // completer.complete(<expr>); | |
| 5675 args->Add(body->NodeAt(last_index)->AsReturnNode()->value()); | |
| 5676 body->ReplaceNodeAt(last_index, | |
| 5677 new (I) InstanceCallNode( | |
| 5678 Scanner::kNoSourcePos, | |
| 5679 new (I) LoadLocalNode(Scanner::kNoSourcePos, completer), | |
| 5680 Symbols::CompleterComplete(), | |
| 5681 args)); | |
| 5682 } else { | |
| 5683 // Add to AST: | |
| 5684 // completer.complete(); | |
| 5685 body->Add( | |
| 5686 new (I) InstanceCallNode( | |
| 5687 Scanner::kNoSourcePos, | |
| 5688 new (I) LoadLocalNode(Scanner::kNoSourcePos, completer), | |
| 5689 Symbols::CompleterComplete(), | |
| 5690 args)); | |
| 5691 } | |
| 5692 } | |
| 5693 | |
| 5694 | |
| 5695 // Set up default values for all optional parameters to the function. | 5456 // Set up default values for all optional parameters to the function. |
| 5696 void Parser::SetupDefaultsForOptionalParams(const ParamList* params, | 5457 void Parser::SetupDefaultsForOptionalParams(const ParamList* params, |
| 5697 Array* default_values) { | 5458 Array* default_values) { |
| 5698 if (params->num_optional_parameters > 0) { | 5459 if (params->num_optional_parameters > 0) { |
| 5699 // Build array of default parameter values. | 5460 // Build array of default parameter values. |
| 5700 ParamDesc* param = | 5461 ParamDesc* param = |
| 5701 params->parameters->data() + params->num_fixed_parameters; | 5462 params->parameters->data() + params->num_fixed_parameters; |
| 5702 *default_values = Array::New(params->num_optional_parameters); | 5463 *default_values = Array::New(params->num_optional_parameters); |
| 5703 for (int i = 0; i < params->num_optional_parameters; i++) { | 5464 for (int i = 0; i < params->num_optional_parameters; i++) { |
| 5704 ASSERT(param->default_value != NULL); | 5465 ASSERT(param->default_value != NULL); |
| (...skipping 755 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 6460 } else { | 6221 } else { |
| 6461 SetPosition(saved_pos); | 6222 SetPosition(saved_pos); |
| 6462 return false; | 6223 return false; |
| 6463 } | 6224 } |
| 6464 // Check parameter list and the following token. | 6225 // Check parameter list and the following token. |
| 6465 if (CurrentToken() == Token::kLPAREN) { | 6226 if (CurrentToken() == Token::kLPAREN) { |
| 6466 SkipToMatchingParenthesis(); | 6227 SkipToMatchingParenthesis(); |
| 6467 if ((CurrentToken() == Token::kLBRACE) || | 6228 if ((CurrentToken() == Token::kLBRACE) || |
| 6468 (CurrentToken() == Token::kARROW) || | 6229 (CurrentToken() == Token::kARROW) || |
| 6469 (is_top_level_ && IsLiteral("native")) || | 6230 (is_top_level_ && IsLiteral("native")) || |
| 6470 is_external || | 6231 is_external) { |
| 6471 (FLAG_enable_async && | |
| 6472 CurrentLiteral()->raw() == Symbols::Async().raw())) { | |
| 6473 SetPosition(saved_pos); | 6232 SetPosition(saved_pos); |
| 6474 return true; | 6233 return true; |
| 6475 } | 6234 } |
| 6476 } | 6235 } |
| 6477 SetPosition(saved_pos); | 6236 SetPosition(saved_pos); |
| 6478 return false; | 6237 return false; |
| 6479 } | 6238 } |
| 6480 | 6239 |
| 6481 | 6240 |
| 6482 bool Parser::IsTopLevelAccessor() { | 6241 bool Parser::IsTopLevelAccessor() { |
| (...skipping 4518 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 11001 SkipType(true); | 10760 SkipType(true); |
| 11002 } | 10761 } |
| 11003 ExpectIdentifier("function name expected"); | 10762 ExpectIdentifier("function name expected"); |
| 11004 } | 10763 } |
| 11005 if (CurrentToken() == Token::kLPAREN) { | 10764 if (CurrentToken() == Token::kLPAREN) { |
| 11006 const bool allow_explicit_default_values = true; | 10765 const bool allow_explicit_default_values = true; |
| 11007 ParamList params; | 10766 ParamList params; |
| 11008 params.skipped = true; | 10767 params.skipped = true; |
| 11009 ParseFormalParameterList(allow_explicit_default_values, false, ¶ms); | 10768 ParseFormalParameterList(allow_explicit_default_values, false, ¶ms); |
| 11010 } | 10769 } |
| 11011 ParseFunctionModifier(); | |
| 11012 if (CurrentToken() == Token::kLBRACE) { | 10770 if (CurrentToken() == Token::kLBRACE) { |
| 11013 SkipBlock(); | 10771 SkipBlock(); |
| 11014 ExpectToken(Token::kRBRACE); | 10772 ExpectToken(Token::kRBRACE); |
| 11015 } else if (CurrentToken() == Token::kARROW) { | 10773 } else if (CurrentToken() == Token::kARROW) { |
| 11016 ConsumeToken(); | 10774 ConsumeToken(); |
| 11017 SkipExpr(); | 10775 SkipExpr(); |
| 11018 } | 10776 } |
| 11019 } | 10777 } |
| 11020 | 10778 |
| 11021 | 10779 |
| 11022 // Skips function/method/constructor/getter/setter preambles until the formal | 10780 // Skips function/method/constructor/getter/setter preambles until the formal |
| 11023 // parameter list. It is enough to skip the tokens, since we have already | 10781 // parameter list. It is enough to skip the tokens, since we have already |
| 11024 // previously parsed the function. | 10782 // previously parsed the function. |
| 11025 void Parser::SkipFunctionPreamble() { | 10783 void Parser::SkipFunctionPreamble() { |
| 11026 while (true) { | 10784 while (true) { |
| 11027 const Token::Kind token = CurrentToken(); | 10785 const Token::Kind token = CurrentToken(); |
| 11028 if (token == Token::kLPAREN || | 10786 if (token == Token::kLPAREN || |
| 11029 token == Token::kARROW || | 10787 token == Token::kARROW || |
| 11030 token == Token::kSEMICOLON || | 10788 token == Token::kSEMICOLON || |
| 11031 token == Token::kLBRACE) { | 10789 token == Token::kLBRACE) { |
| 11032 return; | 10790 return; |
| 11033 } | 10791 } |
| 11034 // Case handles "native" keyword, but also return types of form | 10792 // Case handles "native" keyword, but also return types of form |
| 11035 // native.SomeType where native is the name of a library. | 10793 // native.SomeType where native is the name of a library. |
| 11036 if (token == Token::kIDENT && LookaheadToken(1) != Token::kPERIOD) { | 10794 if (token == Token::kIDENT && LookaheadToken(1) != Token::kPERIOD) { |
| 11037 if (CurrentLiteral()->raw() == Symbols::Native().raw() || | 10795 if (CurrentLiteral()->raw() == Symbols::Native().raw()) { |
| 11038 CurrentLiteral()->raw() == Symbols::Async().raw()) { | |
| 11039 return; | 10796 return; |
| 11040 } | 10797 } |
| 11041 } | 10798 } |
| 11042 ConsumeToken(); | 10799 ConsumeToken(); |
| 11043 } | 10800 } |
| 11044 } | 10801 } |
| 11045 | 10802 |
| 11046 | 10803 |
| 11047 void Parser::SkipListLiteral() { | 10804 void Parser::SkipListLiteral() { |
| 11048 if (CurrentToken() == Token::kINDEX) { | 10805 if (CurrentToken() == Token::kINDEX) { |
| (...skipping 274 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 11323 void Parser::SkipQualIdent() { | 11080 void Parser::SkipQualIdent() { |
| 11324 ASSERT(IsIdentifier()); | 11081 ASSERT(IsIdentifier()); |
| 11325 ConsumeToken(); | 11082 ConsumeToken(); |
| 11326 if (CurrentToken() == Token::kPERIOD) { | 11083 if (CurrentToken() == Token::kPERIOD) { |
| 11327 ConsumeToken(); // Consume the kPERIOD token. | 11084 ConsumeToken(); // Consume the kPERIOD token. |
| 11328 ExpectIdentifier("identifier expected after '.'"); | 11085 ExpectIdentifier("identifier expected after '.'"); |
| 11329 } | 11086 } |
| 11330 } | 11087 } |
| 11331 | 11088 |
| 11332 } // namespace dart | 11089 } // namespace dart |
| OLD | NEW |