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."); | |
42 DECLARE_FLAG(bool, error_on_bad_type); | 43 DECLARE_FLAG(bool, error_on_bad_type); |
43 DECLARE_FLAG(bool, throw_on_javascript_int_overflow); | 44 DECLARE_FLAG(bool, throw_on_javascript_int_overflow); |
44 DECLARE_FLAG(bool, warn_on_javascript_compatibility); | 45 DECLARE_FLAG(bool, warn_on_javascript_compatibility); |
45 | 46 |
46 static void CheckedModeHandler(bool value) { | 47 static void CheckedModeHandler(bool value) { |
47 FLAG_enable_asserts = value; | 48 FLAG_enable_asserts = value; |
48 FLAG_enable_type_checks = value; | 49 FLAG_enable_type_checks = value; |
49 } | 50 } |
50 | 51 |
51 // --enable-checked-mode and --checked both enable checked mode which is | 52 // --enable-checked-mode and --checked both enable checked mode which is |
(...skipping 2839 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
2891 AstNode* guarded_block_statements = | 2892 AstNode* guarded_block_statements = |
2892 new IfNode(Scanner::kNoSourcePos, comparison, ctor_block, NULL); | 2893 new IfNode(Scanner::kNoSourcePos, comparison, ctor_block, NULL); |
2893 current_block_->statements->Add(guarded_block_statements); | 2894 current_block_->statements->Add(guarded_block_statements); |
2894 } | 2895 } |
2895 current_block_->statements->Add(new ReturnNode(func.end_token_pos())); | 2896 current_block_->statements->Add(new ReturnNode(func.end_token_pos())); |
2896 SequenceNode* statements = CloseBlock(); | 2897 SequenceNode* statements = CloseBlock(); |
2897 return statements; | 2898 return statements; |
2898 } | 2899 } |
2899 | 2900 |
2900 | 2901 |
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"); | |
Ivan Posva
2014/07/29 21:10:33
dart:async needs to be imported without prefix, co
Michael Lippautz (Google)
2014/07/29 21:43:50
Yes, I will clarify the error when I reland this.
| |
2908 } | |
2909 return cls.raw(); | |
2910 } | |
2911 | |
2912 | |
2901 // Parser is at the opening parenthesis of the formal parameter | 2913 // Parser is at the opening parenthesis of the formal parameter |
2902 // declaration of the function or constructor. | 2914 // declaration of the function or constructor. |
2903 // Parse the formal parameters and code. | 2915 // Parse the formal parameters and code. |
2904 SequenceNode* Parser::ParseFunc(const Function& func, | 2916 SequenceNode* Parser::ParseFunc(const Function& func, |
2905 Array* default_parameter_values) { | 2917 Array* default_parameter_values) { |
2906 TRACE_PARSER("ParseFunc"); | 2918 TRACE_PARSER("ParseFunc"); |
2907 Function& saved_innermost_function = | 2919 Function& saved_innermost_function = |
2908 Function::Handle(I, innermost_function().raw()); | 2920 Function::Handle(I, innermost_function().raw()); |
2909 innermost_function_ = func.raw(); | 2921 innermost_function_ = func.raw(); |
2910 | 2922 |
2911 // Save current try index. Try index starts at zero for each function. | 2923 // Save current try index. Try index starts at zero for each function. |
2912 intptr_t saved_try_index = last_used_try_index_; | 2924 intptr_t saved_try_index = last_used_try_index_; |
2913 last_used_try_index_ = 0; | 2925 last_used_try_index_ = 0; |
2914 | 2926 |
2927 intptr_t formal_params_pos = TokenPos(); | |
2915 // TODO(12455) : Need better validation mechanism. | 2928 // TODO(12455) : Need better validation mechanism. |
2916 | 2929 |
2917 if (func.IsConstructor()) { | 2930 if (func.IsConstructor()) { |
2918 SequenceNode* statements = ParseConstructor(func, default_parameter_values); | 2931 SequenceNode* statements = ParseConstructor(func, default_parameter_values); |
2919 innermost_function_ = saved_innermost_function.raw(); | 2932 innermost_function_ = saved_innermost_function.raw(); |
2920 last_used_try_index_ = saved_try_index; | 2933 last_used_try_index_ = saved_try_index; |
2921 return statements; | 2934 return statements; |
2922 } | 2935 } |
2923 | 2936 |
2924 ASSERT(!func.IsConstructor()); | 2937 ASSERT(!func.IsConstructor()); |
(...skipping 14 matching lines...) Expand all Loading... | |
2939 ASSERT(current_class().raw() == func.Owner()); | 2952 ASSERT(current_class().raw() == func.Owner()); |
2940 params.AddReceiver(ReceiverType(current_class()), func.token_pos()); | 2953 params.AddReceiver(ReceiverType(current_class()), func.token_pos()); |
2941 } else if (func.IsFactory()) { | 2954 } else if (func.IsFactory()) { |
2942 // The first parameter of a factory is the TypeArguments vector of | 2955 // The first parameter of a factory is the TypeArguments vector of |
2943 // the type of the instance to be allocated. | 2956 // the type of the instance to be allocated. |
2944 params.AddFinalParameter( | 2957 params.AddFinalParameter( |
2945 TokenPos(), | 2958 TokenPos(), |
2946 &Symbols::TypeArgumentsParameter(), | 2959 &Symbols::TypeArgumentsParameter(), |
2947 &Type::ZoneHandle(I, Type::DynamicType())); | 2960 &Type::ZoneHandle(I, Type::DynamicType())); |
2948 } | 2961 } |
2949 ASSERT((CurrentToken() == Token::kLPAREN) || func.IsGetterFunction()); | 2962 ASSERT((CurrentToken() == Token::kLPAREN) || |
2963 func.IsGetterFunction() || | |
2964 func.is_async_closure()); | |
2950 const bool allow_explicit_default_values = true; | 2965 const bool allow_explicit_default_values = true; |
2951 if (func.IsGetterFunction()) { | 2966 if (func.IsGetterFunction()) { |
2952 // Populate function scope with the formal parameters. Since in this case | 2967 // Populate function scope with the formal parameters. Since in this case |
2953 // we are compiling a getter this will at most populate the receiver. | 2968 // we are compiling a getter this will at most populate the receiver. |
2954 AddFormalParamsToScope(¶ms, current_block_->scope); | 2969 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 } | |
2955 } else { | 2979 } else { |
2956 ParseFormalParameterList(allow_explicit_default_values, false, ¶ms); | 2980 ParseFormalParameterList(allow_explicit_default_values, false, ¶ms); |
2957 | 2981 |
2958 // The number of parameters and their type are not yet set in local | 2982 // The number of parameters and their type are not yet set in local |
2959 // functions, since they are not 'top-level' parsed. | 2983 // functions, since they are not 'top-level' parsed. |
2960 if (func.IsLocalFunction()) { | 2984 if (func.IsLocalFunction()) { |
2961 AddFormalParamsToFunction(¶ms, func); | 2985 AddFormalParamsToFunction(¶ms, func); |
2962 } | 2986 } |
2963 SetupDefaultsForOptionalParams(¶ms, default_parameter_values); | 2987 SetupDefaultsForOptionalParams(¶ms, default_parameter_values); |
2964 ASSERT(AbstractType::Handle(I, func.result_type()).IsResolved()); | 2988 ASSERT(AbstractType::Handle(I, func.result_type()).IsResolved()); |
(...skipping 20 matching lines...) Expand all Loading... | |
2985 if (IsInstantiatorRequired()) { | 3009 if (IsInstantiatorRequired()) { |
2986 // Make sure that the receiver of the enclosing instance function | 3010 // Make sure that the receiver of the enclosing instance function |
2987 // (or implicit first parameter of an enclosing factory) is marked as | 3011 // (or implicit first parameter of an enclosing factory) is marked as |
2988 // captured if type checks are enabled, because they may access it to | 3012 // captured if type checks are enabled, because they may access it to |
2989 // instantiate types. | 3013 // instantiate types. |
2990 CaptureInstantiator(); | 3014 CaptureInstantiator(); |
2991 } | 3015 } |
2992 } | 3016 } |
2993 } | 3017 } |
2994 | 3018 |
3019 RawFunction::AsyncModifier func_modifier = ParseFunctionModifier(); | |
3020 func.set_modifier(func_modifier); | |
3021 | |
2995 OpenBlock(); // Open a nested scope for the outermost function block. | 3022 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 | |
2996 intptr_t end_token_pos = 0; | 3029 intptr_t end_token_pos = 0; |
2997 if (CurrentToken() == Token::kLBRACE) { | 3030 if (CurrentToken() == Token::kLBRACE) { |
2998 ConsumeToken(); | 3031 ConsumeToken(); |
2999 if (String::Handle(I, func.name()).Equals( | 3032 if (String::Handle(I, func.name()).Equals( |
3000 Symbols::EqualOperator())) { | 3033 Symbols::EqualOperator())) { |
3001 const Class& owner = Class::Handle(I, func.Owner()); | 3034 const Class& owner = Class::Handle(I, func.Owner()); |
3002 if (!owner.IsObjectClass()) { | 3035 if (!owner.IsObjectClass()) { |
3003 AddEqualityNullCheck(); | 3036 AddEqualityNullCheck(); |
3004 } | 3037 } |
3005 } | 3038 } |
(...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
3046 &func)); // Unpatched external function. | 3079 &func)); // Unpatched external function. |
3047 end_token_pos = TokenPos(); | 3080 end_token_pos = TokenPos(); |
3048 } else { | 3081 } else { |
3049 UnexpectedToken(); | 3082 UnexpectedToken(); |
3050 } | 3083 } |
3051 | 3084 |
3052 ASSERT(func.end_token_pos() == func.token_pos() || | 3085 ASSERT(func.end_token_pos() == func.token_pos() || |
3053 func.end_token_pos() == end_token_pos); | 3086 func.end_token_pos() == end_token_pos); |
3054 func.set_end_token_pos(end_token_pos); | 3087 func.set_end_token_pos(end_token_pos); |
3055 SequenceNode* body = CloseBlock(); | 3088 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 } | |
3056 current_block_->statements->Add(body); | 3094 current_block_->statements->Add(body); |
3057 innermost_function_ = saved_innermost_function.raw(); | 3095 innermost_function_ = saved_innermost_function.raw(); |
3058 last_used_try_index_ = saved_try_index; | 3096 last_used_try_index_ = saved_try_index; |
3059 return CloseBlock(); | 3097 return CloseBlock(); |
3060 } | 3098 } |
3061 | 3099 |
3062 | 3100 |
3063 void Parser::AddEqualityNullCheck() { | 3101 void Parser::AddEqualityNullCheck() { |
3064 AstNode* argument = | 3102 AstNode* argument = |
3065 new LoadLocalNode(Scanner::kNoSourcePos, | 3103 new LoadLocalNode(Scanner::kNoSourcePos, |
(...skipping 293 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
3359 ASSERT((method->redirect_name == NULL) || method->IsConstructor()); | 3397 ASSERT((method->redirect_name == NULL) || method->IsConstructor()); |
3360 | 3398 |
3361 if (method->IsConstructor() && | 3399 if (method->IsConstructor() && |
3362 method->has_external && | 3400 method->has_external && |
3363 method->params.has_field_initializer) { | 3401 method->params.has_field_initializer) { |
3364 ReportError(method->name_pos, | 3402 ReportError(method->name_pos, |
3365 "external constructor '%s' may not have field initializers", | 3403 "external constructor '%s' may not have field initializers", |
3366 method->name->ToCString()); | 3404 method->name->ToCString()); |
3367 } | 3405 } |
3368 | 3406 |
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 | |
3369 intptr_t method_end_pos = TokenPos(); | 3416 intptr_t method_end_pos = TokenPos(); |
3370 if ((CurrentToken() == Token::kLBRACE) || | 3417 if ((CurrentToken() == Token::kLBRACE) || |
3371 (CurrentToken() == Token::kARROW)) { | 3418 (CurrentToken() == Token::kARROW)) { |
3372 if (method->has_abstract) { | 3419 if (method->has_abstract) { |
3373 ReportError(TokenPos(), | 3420 ReportError(TokenPos(), |
3374 "abstract method '%s' may not have a function body", | 3421 "abstract method '%s' may not have a function body", |
3375 method->name->ToCString()); | 3422 method->name->ToCString()); |
3376 } else if (method->has_external) { | 3423 } else if (method->has_external) { |
3377 ReportError(TokenPos(), | 3424 ReportError(TokenPos(), |
3378 "external %s '%s' may not have a function body", | 3425 "external %s '%s' may not have a function body", |
(...skipping 94 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
3473 method->has_static, | 3520 method->has_static, |
3474 method->has_const, | 3521 method->has_const, |
3475 method->has_abstract, | 3522 method->has_abstract, |
3476 method->has_external, | 3523 method->has_external, |
3477 method->has_native, | 3524 method->has_native, |
3478 current_class(), | 3525 current_class(), |
3479 method->decl_begin_pos)); | 3526 method->decl_begin_pos)); |
3480 func.set_result_type(*method->type); | 3527 func.set_result_type(*method->type); |
3481 func.set_end_token_pos(method_end_pos); | 3528 func.set_end_token_pos(method_end_pos); |
3482 func.set_is_redirecting(is_redirecting); | 3529 func.set_is_redirecting(is_redirecting); |
3530 func.set_modifier(async_modifier); | |
3483 if (method->has_native && library_.is_dart_scheme() && | 3531 if (method->has_native && library_.is_dart_scheme() && |
3484 library_.IsPrivate(*method->name)) { | 3532 library_.IsPrivate(*method->name)) { |
3485 func.set_is_visible(false); | 3533 func.set_is_visible(false); |
3486 } | 3534 } |
3487 if (method->IsFactoryOrConstructor() && library_.is_dart_scheme() && | 3535 if (method->IsFactoryOrConstructor() && library_.is_dart_scheme() && |
3488 library_.IsPrivate(*method->name)) { | 3536 library_.IsPrivate(*method->name)) { |
3489 func.set_is_visible(false); | 3537 func.set_is_visible(false); |
3490 } | 3538 } |
3491 if (method->metadata_pos > 0) { | 3539 if (method->metadata_pos > 0) { |
3492 library_.AddFunctionMetadata(func, method->metadata_pos); | 3540 library_.AddFunctionMetadata(func, method->metadata_pos); |
(...skipping 1300 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
4793 } else if (CurrentToken() == Token::kSEMICOLON) { | 4841 } else if (CurrentToken() == Token::kSEMICOLON) { |
4794 ConsumeToken(); | 4842 ConsumeToken(); |
4795 break; | 4843 break; |
4796 } else { | 4844 } else { |
4797 ExpectSemicolon(); // Reports error. | 4845 ExpectSemicolon(); // Reports error. |
4798 } | 4846 } |
4799 } | 4847 } |
4800 } | 4848 } |
4801 | 4849 |
4802 | 4850 |
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 | |
4803 void Parser::ParseTopLevelFunction(TopLevel* top_level, | 4862 void Parser::ParseTopLevelFunction(TopLevel* top_level, |
4804 intptr_t metadata_pos) { | 4863 intptr_t metadata_pos) { |
4805 TRACE_PARSER("ParseTopLevelFunction"); | 4864 TRACE_PARSER("ParseTopLevelFunction"); |
4806 const intptr_t decl_begin_pos = TokenPos(); | 4865 const intptr_t decl_begin_pos = TokenPos(); |
4807 AbstractType& result_type = Type::Handle(I, Type::DynamicType()); | 4866 AbstractType& result_type = Type::Handle(I, Type::DynamicType()); |
4808 const bool is_static = true; | 4867 const bool is_static = true; |
4809 bool is_external = false; | 4868 bool is_external = false; |
4810 bool is_patch = false; | 4869 bool is_patch = false; |
4811 if (is_patch_source() && | 4870 if (is_patch_source() && |
4812 (CurrentToken() == Token::kIDENT) && | 4871 (CurrentToken() == Token::kIDENT) && |
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
4846 } | 4905 } |
4847 // A setter named x= may co-exist with a function named x, thus we do | 4906 // A setter named x= may co-exist with a function named x, thus we do |
4848 // not need to check setters. | 4907 // not need to check setters. |
4849 | 4908 |
4850 CheckToken(Token::kLPAREN); | 4909 CheckToken(Token::kLPAREN); |
4851 const intptr_t function_pos = TokenPos(); | 4910 const intptr_t function_pos = TokenPos(); |
4852 ParamList params; | 4911 ParamList params; |
4853 const bool allow_explicit_default_values = true; | 4912 const bool allow_explicit_default_values = true; |
4854 ParseFormalParameterList(allow_explicit_default_values, false, ¶ms); | 4913 ParseFormalParameterList(allow_explicit_default_values, false, ¶ms); |
4855 | 4914 |
4915 RawFunction::AsyncModifier func_modifier = ParseFunctionModifier(); | |
4916 | |
4856 intptr_t function_end_pos = function_pos; | 4917 intptr_t function_end_pos = function_pos; |
4857 bool is_native = false; | 4918 bool is_native = false; |
4858 if (is_external) { | 4919 if (is_external) { |
4859 function_end_pos = TokenPos(); | 4920 function_end_pos = TokenPos(); |
4860 ExpectSemicolon(); | 4921 ExpectSemicolon(); |
4861 } else if (CurrentToken() == Token::kLBRACE) { | 4922 } else if (CurrentToken() == Token::kLBRACE) { |
4862 SkipBlock(); | 4923 SkipBlock(); |
4863 function_end_pos = TokenPos(); | 4924 function_end_pos = TokenPos(); |
4864 ExpectToken(Token::kRBRACE); | 4925 ExpectToken(Token::kRBRACE); |
4865 } else if (CurrentToken() == Token::kARROW) { | 4926 } else if (CurrentToken() == Token::kARROW) { |
(...skipping 14 matching lines...) Expand all Loading... | |
4880 RawFunction::kRegularFunction, | 4941 RawFunction::kRegularFunction, |
4881 is_static, | 4942 is_static, |
4882 /* is_const = */ false, | 4943 /* is_const = */ false, |
4883 /* is_abstract = */ false, | 4944 /* is_abstract = */ false, |
4884 is_external, | 4945 is_external, |
4885 is_native, | 4946 is_native, |
4886 current_class(), | 4947 current_class(), |
4887 decl_begin_pos)); | 4948 decl_begin_pos)); |
4888 func.set_result_type(result_type); | 4949 func.set_result_type(result_type); |
4889 func.set_end_token_pos(function_end_pos); | 4950 func.set_end_token_pos(function_end_pos); |
4951 func.set_modifier(func_modifier); | |
4890 if (is_native && library_.is_dart_scheme() && library_.IsPrivate(func_name)) { | 4952 if (is_native && library_.is_dart_scheme() && library_.IsPrivate(func_name)) { |
4891 func.set_is_visible(false); | 4953 func.set_is_visible(false); |
4892 } | 4954 } |
4893 AddFormalParamsToFunction(¶ms, func); | 4955 AddFormalParamsToFunction(¶ms, func); |
4894 top_level->functions.Add(func); | 4956 top_level->functions.Add(func); |
4895 if (!is_patch) { | 4957 if (!is_patch) { |
4896 library_.AddObject(func, func_name); | 4958 library_.AddObject(func, func_name); |
4897 } else { | 4959 } else { |
4898 library_.ReplaceObject(func, func_name); | 4960 library_.ReplaceObject(func, func_name); |
4899 } | 4961 } |
(...skipping 82 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
4982 if (found && !is_patch) { | 5044 if (found && !is_patch) { |
4983 ReportError(name_pos, "%s for '%s' is already defined", | 5045 ReportError(name_pos, "%s for '%s' is already defined", |
4984 is_getter ? "getter" : "setter", | 5046 is_getter ? "getter" : "setter", |
4985 field_name->ToCString()); | 5047 field_name->ToCString()); |
4986 } else if (!found && is_patch) { | 5048 } else if (!found && is_patch) { |
4987 ReportError(name_pos, "missing %s for '%s' cannot be patched", | 5049 ReportError(name_pos, "missing %s for '%s' cannot be patched", |
4988 is_getter ? "getter" : "setter", | 5050 is_getter ? "getter" : "setter", |
4989 field_name->ToCString()); | 5051 field_name->ToCString()); |
4990 } | 5052 } |
4991 | 5053 |
5054 RawFunction::AsyncModifier func_modifier = ParseFunctionModifier(); | |
5055 | |
4992 intptr_t accessor_end_pos = accessor_pos; | 5056 intptr_t accessor_end_pos = accessor_pos; |
4993 bool is_native = false; | 5057 bool is_native = false; |
4994 if (is_external) { | 5058 if (is_external) { |
4995 accessor_end_pos = TokenPos(); | 5059 accessor_end_pos = TokenPos(); |
4996 ExpectSemicolon(); | 5060 ExpectSemicolon(); |
4997 } else if (CurrentToken() == Token::kLBRACE) { | 5061 } else if (CurrentToken() == Token::kLBRACE) { |
4998 SkipBlock(); | 5062 SkipBlock(); |
4999 accessor_end_pos = TokenPos(); | 5063 accessor_end_pos = TokenPos(); |
5000 ExpectToken(Token::kRBRACE); | 5064 ExpectToken(Token::kRBRACE); |
5001 } else if (CurrentToken() == Token::kARROW) { | 5065 } else if (CurrentToken() == Token::kARROW) { |
(...skipping 15 matching lines...) Expand all Loading... | |
5017 RawFunction::kSetterFunction, | 5081 RawFunction::kSetterFunction, |
5018 is_static, | 5082 is_static, |
5019 /* is_const = */ false, | 5083 /* is_const = */ false, |
5020 /* is_abstract = */ false, | 5084 /* is_abstract = */ false, |
5021 is_external, | 5085 is_external, |
5022 is_native, | 5086 is_native, |
5023 current_class(), | 5087 current_class(), |
5024 decl_begin_pos)); | 5088 decl_begin_pos)); |
5025 func.set_result_type(result_type); | 5089 func.set_result_type(result_type); |
5026 func.set_end_token_pos(accessor_end_pos); | 5090 func.set_end_token_pos(accessor_end_pos); |
5091 func.set_modifier(func_modifier); | |
5027 if (is_native && library_.is_dart_scheme() && | 5092 if (is_native && library_.is_dart_scheme() && |
5028 library_.IsPrivate(accessor_name)) { | 5093 library_.IsPrivate(accessor_name)) { |
5029 func.set_is_visible(false); | 5094 func.set_is_visible(false); |
5030 } | 5095 } |
5031 AddFormalParamsToFunction(¶ms, func); | 5096 AddFormalParamsToFunction(¶ms, func); |
5032 top_level->functions.Add(func); | 5097 top_level->functions.Add(func); |
5033 if (!is_patch) { | 5098 if (!is_patch) { |
5034 library_.AddObject(func, accessor_name); | 5099 library_.AddObject(func, accessor_name); |
5035 } else { | 5100 } else { |
5036 library_.ReplaceObject(func, accessor_name); | 5101 library_.ReplaceObject(func, accessor_name); |
(...skipping 396 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
5433 // We are parsing a nested function while compiling the enclosing function. | 5498 // We are parsing a nested function while compiling the enclosing function. |
5434 outer_scope = | 5499 outer_scope = |
5435 new(I) LocalScope(current_block_->scope, | 5500 new(I) LocalScope(current_block_->scope, |
5436 current_block_->scope->function_level() + 1, | 5501 current_block_->scope->function_level() + 1, |
5437 0); | 5502 0); |
5438 } | 5503 } |
5439 ChainNewBlock(outer_scope); | 5504 ChainNewBlock(outer_scope); |
5440 } | 5505 } |
5441 | 5506 |
5442 | 5507 |
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 | |
5443 SequenceNode* Parser::CloseBlock() { | 5547 SequenceNode* Parser::CloseBlock() { |
5444 SequenceNode* statements = current_block_->statements; | 5548 SequenceNode* statements = current_block_->statements; |
5445 if (current_block_->scope != NULL) { | 5549 if (current_block_->scope != NULL) { |
5446 // Record the begin and end token index of the scope. | 5550 // Record the begin and end token index of the scope. |
5447 ASSERT(statements != NULL); | 5551 ASSERT(statements != NULL); |
5448 current_block_->scope->set_begin_token_pos(statements->token_pos()); | 5552 current_block_->scope->set_begin_token_pos(statements->token_pos()); |
5449 current_block_->scope->set_end_token_pos(TokenPos()); | 5553 current_block_->scope->set_end_token_pos(TokenPos()); |
5450 } | 5554 } |
5451 current_block_ = current_block_->parent; | 5555 current_block_ = current_block_->parent; |
5452 return statements; | 5556 return statements; |
5453 } | 5557 } |
5454 | 5558 |
5455 | 5559 |
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 | |
5456 // Set up default values for all optional parameters to the function. | 5695 // Set up default values for all optional parameters to the function. |
5457 void Parser::SetupDefaultsForOptionalParams(const ParamList* params, | 5696 void Parser::SetupDefaultsForOptionalParams(const ParamList* params, |
5458 Array* default_values) { | 5697 Array* default_values) { |
5459 if (params->num_optional_parameters > 0) { | 5698 if (params->num_optional_parameters > 0) { |
5460 // Build array of default parameter values. | 5699 // Build array of default parameter values. |
5461 ParamDesc* param = | 5700 ParamDesc* param = |
5462 params->parameters->data() + params->num_fixed_parameters; | 5701 params->parameters->data() + params->num_fixed_parameters; |
5463 *default_values = Array::New(params->num_optional_parameters); | 5702 *default_values = Array::New(params->num_optional_parameters); |
5464 for (int i = 0; i < params->num_optional_parameters; i++) { | 5703 for (int i = 0; i < params->num_optional_parameters; i++) { |
5465 ASSERT(param->default_value != NULL); | 5704 ASSERT(param->default_value != NULL); |
(...skipping 755 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
6221 } else { | 6460 } else { |
6222 SetPosition(saved_pos); | 6461 SetPosition(saved_pos); |
6223 return false; | 6462 return false; |
6224 } | 6463 } |
6225 // Check parameter list and the following token. | 6464 // Check parameter list and the following token. |
6226 if (CurrentToken() == Token::kLPAREN) { | 6465 if (CurrentToken() == Token::kLPAREN) { |
6227 SkipToMatchingParenthesis(); | 6466 SkipToMatchingParenthesis(); |
6228 if ((CurrentToken() == Token::kLBRACE) || | 6467 if ((CurrentToken() == Token::kLBRACE) || |
6229 (CurrentToken() == Token::kARROW) || | 6468 (CurrentToken() == Token::kARROW) || |
6230 (is_top_level_ && IsLiteral("native")) || | 6469 (is_top_level_ && IsLiteral("native")) || |
6231 is_external) { | 6470 is_external || |
6471 (FLAG_enable_async && | |
6472 CurrentLiteral()->raw() == Symbols::Async().raw())) { | |
6232 SetPosition(saved_pos); | 6473 SetPosition(saved_pos); |
6233 return true; | 6474 return true; |
6234 } | 6475 } |
6235 } | 6476 } |
6236 SetPosition(saved_pos); | 6477 SetPosition(saved_pos); |
6237 return false; | 6478 return false; |
6238 } | 6479 } |
6239 | 6480 |
6240 | 6481 |
6241 bool Parser::IsTopLevelAccessor() { | 6482 bool Parser::IsTopLevelAccessor() { |
(...skipping 4518 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
10760 SkipType(true); | 11001 SkipType(true); |
10761 } | 11002 } |
10762 ExpectIdentifier("function name expected"); | 11003 ExpectIdentifier("function name expected"); |
10763 } | 11004 } |
10764 if (CurrentToken() == Token::kLPAREN) { | 11005 if (CurrentToken() == Token::kLPAREN) { |
10765 const bool allow_explicit_default_values = true; | 11006 const bool allow_explicit_default_values = true; |
10766 ParamList params; | 11007 ParamList params; |
10767 params.skipped = true; | 11008 params.skipped = true; |
10768 ParseFormalParameterList(allow_explicit_default_values, false, ¶ms); | 11009 ParseFormalParameterList(allow_explicit_default_values, false, ¶ms); |
10769 } | 11010 } |
11011 ParseFunctionModifier(); | |
10770 if (CurrentToken() == Token::kLBRACE) { | 11012 if (CurrentToken() == Token::kLBRACE) { |
10771 SkipBlock(); | 11013 SkipBlock(); |
10772 ExpectToken(Token::kRBRACE); | 11014 ExpectToken(Token::kRBRACE); |
10773 } else if (CurrentToken() == Token::kARROW) { | 11015 } else if (CurrentToken() == Token::kARROW) { |
10774 ConsumeToken(); | 11016 ConsumeToken(); |
10775 SkipExpr(); | 11017 SkipExpr(); |
10776 } | 11018 } |
10777 } | 11019 } |
10778 | 11020 |
10779 | 11021 |
10780 // Skips function/method/constructor/getter/setter preambles until the formal | 11022 // Skips function/method/constructor/getter/setter preambles until the formal |
10781 // parameter list. It is enough to skip the tokens, since we have already | 11023 // parameter list. It is enough to skip the tokens, since we have already |
10782 // previously parsed the function. | 11024 // previously parsed the function. |
10783 void Parser::SkipFunctionPreamble() { | 11025 void Parser::SkipFunctionPreamble() { |
10784 while (true) { | 11026 while (true) { |
10785 const Token::Kind token = CurrentToken(); | 11027 const Token::Kind token = CurrentToken(); |
10786 if (token == Token::kLPAREN || | 11028 if (token == Token::kLPAREN || |
10787 token == Token::kARROW || | 11029 token == Token::kARROW || |
10788 token == Token::kSEMICOLON || | 11030 token == Token::kSEMICOLON || |
10789 token == Token::kLBRACE) { | 11031 token == Token::kLBRACE) { |
10790 return; | 11032 return; |
10791 } | 11033 } |
10792 // Case handles "native" keyword, but also return types of form | 11034 // Case handles "native" keyword, but also return types of form |
10793 // native.SomeType where native is the name of a library. | 11035 // native.SomeType where native is the name of a library. |
10794 if (token == Token::kIDENT && LookaheadToken(1) != Token::kPERIOD) { | 11036 if (token == Token::kIDENT && LookaheadToken(1) != Token::kPERIOD) { |
10795 if (CurrentLiteral()->raw() == Symbols::Native().raw()) { | 11037 if (CurrentLiteral()->raw() == Symbols::Native().raw() || |
11038 CurrentLiteral()->raw() == Symbols::Async().raw()) { | |
10796 return; | 11039 return; |
10797 } | 11040 } |
10798 } | 11041 } |
10799 ConsumeToken(); | 11042 ConsumeToken(); |
10800 } | 11043 } |
10801 } | 11044 } |
10802 | 11045 |
10803 | 11046 |
10804 void Parser::SkipListLiteral() { | 11047 void Parser::SkipListLiteral() { |
10805 if (CurrentToken() == Token::kINDEX) { | 11048 if (CurrentToken() == Token::kINDEX) { |
(...skipping 274 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
11080 void Parser::SkipQualIdent() { | 11323 void Parser::SkipQualIdent() { |
11081 ASSERT(IsIdentifier()); | 11324 ASSERT(IsIdentifier()); |
11082 ConsumeToken(); | 11325 ConsumeToken(); |
11083 if (CurrentToken() == Token::kPERIOD) { | 11326 if (CurrentToken() == Token::kPERIOD) { |
11084 ConsumeToken(); // Consume the kPERIOD token. | 11327 ConsumeToken(); // Consume the kPERIOD token. |
11085 ExpectIdentifier("identifier expected after '.'"); | 11328 ExpectIdentifier("identifier expected after '.'"); |
11086 } | 11329 } |
11087 } | 11330 } |
11088 | 11331 |
11089 } // namespace dart | 11332 } // namespace dart |
OLD | NEW |