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 |