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 2818 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
2870 AstNode* guarded_block_statements = | 2871 AstNode* guarded_block_statements = |
2871 new IfNode(Scanner::kNoSourcePos, comparison, ctor_block, NULL); | 2872 new IfNode(Scanner::kNoSourcePos, comparison, ctor_block, NULL); |
2872 current_block_->statements->Add(guarded_block_statements); | 2873 current_block_->statements->Add(guarded_block_statements); |
2873 } | 2874 } |
2874 current_block_->statements->Add(new ReturnNode(func.end_token_pos())); | 2875 current_block_->statements->Add(new ReturnNode(func.end_token_pos())); |
2875 SequenceNode* statements = CloseBlock(); | 2876 SequenceNode* statements = CloseBlock(); |
2876 return statements; | 2877 return statements; |
2877 } | 2878 } |
2878 | 2879 |
2879 | 2880 |
2881 SequenceNode* Parser::BuildAsyncFuture( | |
2882 SequenceNode* body, ParamList* params, intptr_t saved_pos) { | |
2883 const Class& future = Class::ZoneHandle(I, | |
2884 library_.LookupClass(String::Handle(String::New("Future")))); | |
hausner
2014/07/11 20:18:40
As mentioned in another place, we need to make sur
Michael Lippautz (Google)
2014/07/11 23:40:45
Done.
| |
2885 ASSERT(!future.IsNull()); | |
2886 const Function& constructor = Function::ZoneHandle(I, | |
2887 future.LookupFunction(String::Handle(String::New("Future.")))); | |
2888 ASSERT(!constructor.IsNull()); | |
2889 // Create the closure containing the body of this function. | |
2890 Class& sig_cls = Class::ZoneHandle(I); | |
2891 Type& sig_type = Type::ZoneHandle(I); | |
2892 Function& closure = Function::ZoneHandle(I); | |
2893 String& sig = String::ZoneHandle(I); | |
2894 ParamList closure_params; | |
2895 closure_params.AddFinalParameter( | |
2896 saved_pos, | |
2897 &Symbols::ClosureParameter(), | |
2898 &Type::ZoneHandle(I, Type::DynamicType())); | |
2899 closure = Function::NewClosureFunction( | |
2900 Symbols::AnonymousClosure(), | |
2901 innermost_function(), | |
2902 saved_pos); | |
2903 AddFormalParamsToFunction(&closure_params, closure); | |
2904 closure.set_is_synthetic_container(true); | |
hausner
2014/07/11 20:18:40
Thinking about how to name things: isn't the "oute
Michael Lippautz (Google)
2014/07/11 23:40:45
The outer function contains the synthesized body,
hausner
2014/07/12 00:05:24
I can't think of a better name, don't like skip_pa
Michael Lippautz (Google)
2014/07/14 20:22:48
async_closure() it is
| |
2905 // TODO(mlippautz): Result type should be the originally declared result type. | |
hausner
2014/07/11 20:18:40
Not sure what the result type really should be. Th
Michael Lippautz (Google)
2014/07/11 23:40:45
Clarified the TODO a bit. Leaving for now as we ne
| |
2906 closure.set_result_type(AbstractType::Handle(Type::DynamicType())); | |
2907 sig = closure.Signature(); | |
2908 sig_cls = library_.LookupLocalClass(sig); | |
2909 if (sig_cls.IsNull()) { | |
2910 sig_cls = Class::NewSignatureClass(sig, closure, script_, saved_pos); | |
2911 library_.AddClass(sig_cls); | |
2912 } | |
2913 closure.set_signature_class(sig_cls); | |
2914 sig_type = sig_cls.SignatureType(); | |
2915 if (!sig_type.IsFinalized()) { | |
2916 ClassFinalizer::FinalizeType( | |
2917 sig_cls, sig_type, ClassFinalizer::kCanonicalize); | |
2918 } | |
2919 ASSERT(AbstractType::Handle(I, closure.result_type()).IsResolved()); | |
2920 ASSERT(closure.NumParameters() == closure_params.parameters->length()); | |
2921 OpenFunctionBlock(closure); | |
2922 AddFormalParamsToScope(&closure_params, current_block_->scope); | |
2923 LocalScope* cur_scope = current_block_->scope; | |
2924 String& var_name = String::ZoneHandle(I); | |
2925 bool var_captured = false; | |
2926 // Capture parameters of the enclosing function. | |
2927 for (intptr_t i = 0; i < params->parameters->length(); i++) { | |
2928 ParamDesc& param_desc = (*params->parameters)[i]; | |
2929 var_name = param_desc.var->name().raw(); | |
2930 // Ignore implicit closure parameter, but capture 'this' from any enclosing | |
2931 // methods. | |
2932 if (var_name.Equals(Symbols::ClosureParameter())) { | |
2933 continue; | |
2934 } | |
2935 var_captured = cur_scope->CaptureVariable(var_name); | |
2936 ASSERT(var_captured); | |
2937 } | |
2938 LocalScope* body_scope = body->scope(); | |
2939 // Capture all variables that have already been captured by the enclosing | |
hausner
2014/07/11 20:18:40
Captured _by_ the enclosing function, or variables
Michael Lippautz (Google)
2014/07/11 23:40:45
We re-capture variables (into the scope of the clo
| |
2940 // function. | |
2941 for (intptr_t j = 0; j < body->scope()->num_variables(); j++) { | |
2942 if (body_scope->VariableAt(j)->is_captured()) { | |
2943 var_captured = | |
2944 cur_scope->CaptureVariable(body_scope->VariableAt(j)->name()); | |
2945 ASSERT(var_captured); | |
2946 } | |
2947 } | |
2948 ClosureNode* cn = new(I) ClosureNode(saved_pos, closure, NULL, cur_scope); | |
2949 ArgumentListNode* arguments = new (I) ArgumentListNode(saved_pos); | |
2950 arguments->Add(cn); | |
2951 ConstructorCallNode* ccn = new (I) ConstructorCallNode( | |
2952 saved_pos, TypeArguments::ZoneHandle(I), constructor, arguments); | |
2953 ReturnNode* rn = new (I) ReturnNode(saved_pos, ccn); | |
hausner
2014/07/11 20:18:40
You should use Scanner::kNoSourcePos for synthesiz
Michael Lippautz (Google)
2014/07/11 23:40:45
Done.
| |
2954 current_block_->statements->Add(rn); | |
2955 return CloseBlock(); | |
2956 } | |
2957 | |
2958 | |
2880 // Parser is at the opening parenthesis of the formal parameter | 2959 // Parser is at the opening parenthesis of the formal parameter |
2881 // declaration of the function or constructor. | 2960 // declaration of the function or constructor. |
2882 // Parse the formal parameters and code. | 2961 // Parse the formal parameters and code. |
2883 SequenceNode* Parser::ParseFunc(const Function& func, | 2962 SequenceNode* Parser::ParseFunc(const Function& func, |
2884 Array* default_parameter_values) { | 2963 Array* default_parameter_values) { |
2885 TRACE_PARSER("ParseFunc"); | 2964 TRACE_PARSER("ParseFunc"); |
2886 Function& saved_innermost_function = | 2965 Function& saved_innermost_function = |
2887 Function::Handle(I, innermost_function().raw()); | 2966 Function::Handle(I, innermost_function().raw()); |
2888 innermost_function_ = func.raw(); | 2967 innermost_function_ = func.raw(); |
2889 | 2968 |
2890 // Save current try index. Try index starts at zero for each function. | 2969 // Save current try index. Try index starts at zero for each function. |
2891 intptr_t saved_try_index = last_used_try_index_; | 2970 intptr_t saved_try_index = last_used_try_index_; |
2892 last_used_try_index_ = 0; | 2971 last_used_try_index_ = 0; |
2893 | 2972 |
2973 intptr_t saved_pos = TokenPos(); | |
hausner
2014/07/11 20:18:40
Nit: please name the variable after what it points
Michael Lippautz (Google)
2014/07/11 23:40:45
Done.
| |
2894 // TODO(12455) : Need better validation mechanism. | 2974 // TODO(12455) : Need better validation mechanism. |
2895 | 2975 |
2896 if (func.IsConstructor()) { | 2976 if (func.IsConstructor()) { |
2897 SequenceNode* statements = ParseConstructor(func, default_parameter_values); | 2977 SequenceNode* statements = ParseConstructor(func, default_parameter_values); |
2898 innermost_function_ = saved_innermost_function.raw(); | 2978 innermost_function_ = saved_innermost_function.raw(); |
2899 last_used_try_index_ = saved_try_index; | 2979 last_used_try_index_ = saved_try_index; |
2900 return statements; | 2980 return statements; |
2901 } | 2981 } |
2902 | 2982 |
2903 ASSERT(!func.IsConstructor()); | 2983 ASSERT(!func.IsConstructor()); |
(...skipping 14 matching lines...) Expand all Loading... | |
2918 ASSERT(current_class().raw() == func.Owner()); | 2998 ASSERT(current_class().raw() == func.Owner()); |
2919 params.AddReceiver(ReceiverType(current_class()), func.token_pos()); | 2999 params.AddReceiver(ReceiverType(current_class()), func.token_pos()); |
2920 } else if (func.IsFactory()) { | 3000 } else if (func.IsFactory()) { |
2921 // The first parameter of a factory is the TypeArguments vector of | 3001 // The first parameter of a factory is the TypeArguments vector of |
2922 // the type of the instance to be allocated. | 3002 // the type of the instance to be allocated. |
2923 params.AddFinalParameter( | 3003 params.AddFinalParameter( |
2924 TokenPos(), | 3004 TokenPos(), |
2925 &Symbols::TypeArgumentsParameter(), | 3005 &Symbols::TypeArgumentsParameter(), |
2926 &Type::ZoneHandle(I, Type::DynamicType())); | 3006 &Type::ZoneHandle(I, Type::DynamicType())); |
2927 } | 3007 } |
2928 ASSERT((CurrentToken() == Token::kLPAREN) || func.IsGetterFunction()); | 3008 ASSERT((CurrentToken() == Token::kLPAREN) || func.IsGetterFunction() || |
3009 func.is_synthetic_container()); | |
2929 const bool allow_explicit_default_values = true; | 3010 const bool allow_explicit_default_values = true; |
2930 if (func.IsGetterFunction()) { | 3011 if (func.IsGetterFunction()) { |
2931 // Populate function scope with the formal parameters. Since in this case | 3012 // Populate function scope with the formal parameters. Since in this case |
2932 // we are compiling a getter this will at most populate the receiver. | 3013 // we are compiling a getter this will at most populate the receiver. |
2933 AddFormalParamsToScope(¶ms, current_block_->scope); | 3014 AddFormalParamsToScope(¶ms, current_block_->scope); |
3015 } else if (func.is_synthetic_container() && Function::Handle( | |
3016 func.parent_function()).IsGetterFunction()) { | |
3017 AddFormalParamsToScope(¶ms, current_block_->scope); | |
3018 ASSERT(AbstractType::Handle(I, func.result_type()).IsResolved()); | |
3019 ASSERT(func.NumParameters() == params.parameters->length()); | |
3020 } else if (func.is_synthetic_container()) { | |
3021 AddFormalParamsToScope(¶ms, current_block_->scope); | |
3022 ASSERT(AbstractType::Handle(I, func.result_type()).IsResolved()); | |
3023 ASSERT(func.NumParameters() == params.parameters->length()); | |
3024 ParseFormalParameterList(allow_explicit_default_values, false, ¶ms); | |
3025 // Parse them away. | |
2934 } else { | 3026 } else { |
2935 ParseFormalParameterList(allow_explicit_default_values, false, ¶ms); | 3027 ParseFormalParameterList(allow_explicit_default_values, false, ¶ms); |
2936 | 3028 |
2937 // The number of parameters and their type are not yet set in local | 3029 // The number of parameters and their type are not yet set in local |
2938 // functions, since they are not 'top-level' parsed. | 3030 // functions, since they are not 'top-level' parsed. |
2939 if (func.IsLocalFunction()) { | 3031 if (func.IsLocalFunction()) { |
2940 AddFormalParamsToFunction(¶ms, func); | 3032 AddFormalParamsToFunction(¶ms, func); |
2941 } | 3033 } |
2942 SetupDefaultsForOptionalParams(¶ms, default_parameter_values); | 3034 SetupDefaultsForOptionalParams(¶ms, default_parameter_values); |
2943 ASSERT(AbstractType::Handle(I, func.result_type()).IsResolved()); | 3035 ASSERT(AbstractType::Handle(I, func.result_type()).IsResolved()); |
(...skipping 20 matching lines...) Expand all Loading... | |
2964 if (IsInstantiatorRequired()) { | 3056 if (IsInstantiatorRequired()) { |
2965 // Make sure that the receiver of the enclosing instance function | 3057 // Make sure that the receiver of the enclosing instance function |
2966 // (or implicit first parameter of an enclosing factory) is marked as | 3058 // (or implicit first parameter of an enclosing factory) is marked as |
2967 // captured if type checks are enabled, because they may access it to | 3059 // captured if type checks are enabled, because they may access it to |
2968 // instantiate types. | 3060 // instantiate types. |
2969 CaptureInstantiator(); | 3061 CaptureInstantiator(); |
2970 } | 3062 } |
2971 } | 3063 } |
2972 } | 3064 } |
2973 | 3065 |
3066 intptr_t async_type = ParseAsyncSpecifier(); | |
3067 if (async_type == 1) { | |
3068 func.set_modifier(RawFunction::kAsync); | |
3069 } | |
3070 | |
2974 OpenBlock(); // Open a nested scope for the outermost function block. | 3071 OpenBlock(); // Open a nested scope for the outermost function block. |
2975 intptr_t end_token_pos = 0; | 3072 intptr_t end_token_pos = 0; |
2976 if (CurrentToken() == Token::kLBRACE) { | 3073 if (CurrentToken() == Token::kLBRACE) { |
2977 ConsumeToken(); | 3074 ConsumeToken(); |
2978 if (String::Handle(I, func.name()).Equals( | 3075 if (String::Handle(I, func.name()).Equals( |
2979 Symbols::EqualOperator())) { | 3076 Symbols::EqualOperator())) { |
2980 const Class& owner = Class::Handle(I, func.Owner()); | 3077 const Class& owner = Class::Handle(I, func.Owner()); |
2981 if (!owner.IsObjectClass()) { | 3078 if (!owner.IsObjectClass()) { |
2982 AddEqualityNullCheck(); | 3079 AddEqualityNullCheck(); |
2983 } | 3080 } |
(...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
3025 &func)); // Unpatched external function. | 3122 &func)); // Unpatched external function. |
3026 end_token_pos = TokenPos(); | 3123 end_token_pos = TokenPos(); |
3027 } else { | 3124 } else { |
3028 UnexpectedToken(); | 3125 UnexpectedToken(); |
3029 } | 3126 } |
3030 | 3127 |
3031 ASSERT(func.end_token_pos() == func.token_pos() || | 3128 ASSERT(func.end_token_pos() == func.token_pos() || |
3032 func.end_token_pos() == end_token_pos); | 3129 func.end_token_pos() == end_token_pos); |
3033 func.set_end_token_pos(end_token_pos); | 3130 func.set_end_token_pos(end_token_pos); |
3034 SequenceNode* body = CloseBlock(); | 3131 SequenceNode* body = CloseBlock(); |
3132 if (func.IsAsyncFunction() && !func.is_synthetic_container()) { | |
3133 body = BuildAsyncFuture(body, ¶ms, saved_pos); | |
3134 } | |
3035 current_block_->statements->Add(body); | 3135 current_block_->statements->Add(body); |
3036 innermost_function_ = saved_innermost_function.raw(); | 3136 innermost_function_ = saved_innermost_function.raw(); |
3037 last_used_try_index_ = saved_try_index; | 3137 last_used_try_index_ = saved_try_index; |
3038 return CloseBlock(); | 3138 return CloseBlock(); |
3039 } | 3139 } |
3040 | 3140 |
3041 | 3141 |
3042 void Parser::AddEqualityNullCheck() { | 3142 void Parser::AddEqualityNullCheck() { |
3043 AstNode* argument = | 3143 AstNode* argument = |
3044 new LoadLocalNode(Scanner::kNoSourcePos, | 3144 new LoadLocalNode(Scanner::kNoSourcePos, |
(...skipping 293 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
3338 ASSERT((method->redirect_name == NULL) || method->IsConstructor()); | 3438 ASSERT((method->redirect_name == NULL) || method->IsConstructor()); |
3339 | 3439 |
3340 if (method->IsConstructor() && | 3440 if (method->IsConstructor() && |
3341 method->has_external && | 3441 method->has_external && |
3342 method->params.has_field_initializer) { | 3442 method->params.has_field_initializer) { |
3343 ReportError(method->name_pos, | 3443 ReportError(method->name_pos, |
3344 "external constructor '%s' may not have field initializers", | 3444 "external constructor '%s' may not have field initializers", |
3345 method->name->ToCString()); | 3445 method->name->ToCString()); |
3346 } | 3446 } |
3347 | 3447 |
3448 ParseAsyncSpecifier(); | |
3449 | |
3348 intptr_t method_end_pos = TokenPos(); | 3450 intptr_t method_end_pos = TokenPos(); |
3349 if ((CurrentToken() == Token::kLBRACE) || | 3451 if ((CurrentToken() == Token::kLBRACE) || |
3350 (CurrentToken() == Token::kARROW)) { | 3452 (CurrentToken() == Token::kARROW)) { |
3351 if (method->has_abstract) { | 3453 if (method->has_abstract) { |
3352 ReportError(TokenPos(), | 3454 ReportError(TokenPos(), |
3353 "abstract method '%s' may not have a function body", | 3455 "abstract method '%s' may not have a function body", |
3354 method->name->ToCString()); | 3456 method->name->ToCString()); |
3355 } else if (method->has_external) { | 3457 } else if (method->has_external) { |
3356 ReportError(TokenPos(), | 3458 ReportError(TokenPos(), |
3357 "external %s '%s' may not have a function body", | 3459 "external %s '%s' may not have a function body", |
(...skipping 1414 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
4772 } else if (CurrentToken() == Token::kSEMICOLON) { | 4874 } else if (CurrentToken() == Token::kSEMICOLON) { |
4773 ConsumeToken(); | 4875 ConsumeToken(); |
4774 break; | 4876 break; |
4775 } else { | 4877 } else { |
4776 ExpectSemicolon(); // Reports error. | 4878 ExpectSemicolon(); // Reports error. |
4777 } | 4879 } |
4778 } | 4880 } |
4779 } | 4881 } |
4780 | 4882 |
4781 | 4883 |
4884 intptr_t Parser::ParseAsyncSpecifier() { | |
hausner
2014/07/11 20:18:41
What does the integer return value mean. Should pr
Michael Lippautz (Google)
2014/07/11 23:40:45
Return value is now RawFunction::Modifier. This ca
| |
4885 if (FLAG_enable_async) { | |
4886 if (IsLiteral("async")) { | |
4887 const Class& future = Class::Handle(library_.LookupClass( | |
4888 String::Handle(String::New("Future")))); | |
4889 if (future.IsNull()) { | |
4890 ReportError("async modifier requires dart:async to be imported"); | |
hausner
2014/07/11 20:18:41
I think we need to have a discussion with Gilad wh
Michael Lippautz (Google)
2014/07/11 23:40:45
Factored out. We still bomb until we know what to
| |
4891 } | |
4892 ConsumeToken(); | |
4893 return 1; | |
4894 } | |
4895 } | |
4896 return 0; | |
4897 } | |
4898 | |
4899 | |
4782 void Parser::ParseTopLevelFunction(TopLevel* top_level, | 4900 void Parser::ParseTopLevelFunction(TopLevel* top_level, |
4783 intptr_t metadata_pos) { | 4901 intptr_t metadata_pos) { |
4784 TRACE_PARSER("ParseTopLevelFunction"); | 4902 TRACE_PARSER("ParseTopLevelFunction"); |
4785 const intptr_t decl_begin_pos = TokenPos(); | 4903 const intptr_t decl_begin_pos = TokenPos(); |
4786 AbstractType& result_type = Type::Handle(I, Type::DynamicType()); | 4904 AbstractType& result_type = Type::Handle(I, Type::DynamicType()); |
4787 const bool is_static = true; | 4905 const bool is_static = true; |
4788 bool is_external = false; | 4906 bool is_external = false; |
4789 bool is_patch = false; | 4907 bool is_patch = false; |
4790 if (is_patch_source() && | 4908 if (is_patch_source() && |
4791 (CurrentToken() == Token::kIDENT) && | 4909 (CurrentToken() == Token::kIDENT) && |
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
4825 } | 4943 } |
4826 // A setter named x= may co-exist with a function named x, thus we do | 4944 // A setter named x= may co-exist with a function named x, thus we do |
4827 // not need to check setters. | 4945 // not need to check setters. |
4828 | 4946 |
4829 CheckToken(Token::kLPAREN); | 4947 CheckToken(Token::kLPAREN); |
4830 const intptr_t function_pos = TokenPos(); | 4948 const intptr_t function_pos = TokenPos(); |
4831 ParamList params; | 4949 ParamList params; |
4832 const bool allow_explicit_default_values = true; | 4950 const bool allow_explicit_default_values = true; |
4833 ParseFormalParameterList(allow_explicit_default_values, false, ¶ms); | 4951 ParseFormalParameterList(allow_explicit_default_values, false, ¶ms); |
4834 | 4952 |
4953 intptr_t async_type = ParseAsyncSpecifier(); | |
4954 | |
4835 intptr_t function_end_pos = function_pos; | 4955 intptr_t function_end_pos = function_pos; |
4836 bool is_native = false; | 4956 bool is_native = false; |
4837 if (is_external) { | 4957 if (is_external) { |
4838 function_end_pos = TokenPos(); | 4958 function_end_pos = TokenPos(); |
4839 ExpectSemicolon(); | 4959 ExpectSemicolon(); |
4840 } else if (CurrentToken() == Token::kLBRACE) { | 4960 } else if (CurrentToken() == Token::kLBRACE) { |
4841 SkipBlock(); | 4961 SkipBlock(); |
4842 function_end_pos = TokenPos(); | 4962 function_end_pos = TokenPos(); |
4843 ExpectToken(Token::kRBRACE); | 4963 ExpectToken(Token::kRBRACE); |
4844 } else if (CurrentToken() == Token::kARROW) { | 4964 } else if (CurrentToken() == Token::kARROW) { |
(...skipping 14 matching lines...) Expand all Loading... | |
4859 RawFunction::kRegularFunction, | 4979 RawFunction::kRegularFunction, |
4860 is_static, | 4980 is_static, |
4861 /* is_const = */ false, | 4981 /* is_const = */ false, |
4862 /* is_abstract = */ false, | 4982 /* is_abstract = */ false, |
4863 is_external, | 4983 is_external, |
4864 is_native, | 4984 is_native, |
4865 current_class(), | 4985 current_class(), |
4866 decl_begin_pos)); | 4986 decl_begin_pos)); |
4867 func.set_result_type(result_type); | 4987 func.set_result_type(result_type); |
4868 func.set_end_token_pos(function_end_pos); | 4988 func.set_end_token_pos(function_end_pos); |
4989 if (async_type == 1) { | |
4990 func.set_modifier(RawFunction::kAsync); | |
4991 } | |
4869 if (is_native && library_.is_dart_scheme() && library_.IsPrivate(func_name)) { | 4992 if (is_native && library_.is_dart_scheme() && library_.IsPrivate(func_name)) { |
4870 func.set_is_visible(false); | 4993 func.set_is_visible(false); |
4871 } | 4994 } |
4872 AddFormalParamsToFunction(¶ms, func); | 4995 AddFormalParamsToFunction(¶ms, func); |
4873 top_level->functions.Add(func); | 4996 top_level->functions.Add(func); |
4874 if (!is_patch) { | 4997 if (!is_patch) { |
4875 library_.AddObject(func, func_name); | 4998 library_.AddObject(func, func_name); |
4876 } else { | 4999 } else { |
4877 library_.ReplaceObject(func, func_name); | 5000 library_.ReplaceObject(func, func_name); |
4878 } | 5001 } |
(...skipping 82 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
4961 if (found && !is_patch) { | 5084 if (found && !is_patch) { |
4962 ReportError(name_pos, "%s for '%s' is already defined", | 5085 ReportError(name_pos, "%s for '%s' is already defined", |
4963 is_getter ? "getter" : "setter", | 5086 is_getter ? "getter" : "setter", |
4964 field_name->ToCString()); | 5087 field_name->ToCString()); |
4965 } else if (!found && is_patch) { | 5088 } else if (!found && is_patch) { |
4966 ReportError(name_pos, "missing %s for '%s' cannot be patched", | 5089 ReportError(name_pos, "missing %s for '%s' cannot be patched", |
4967 is_getter ? "getter" : "setter", | 5090 is_getter ? "getter" : "setter", |
4968 field_name->ToCString()); | 5091 field_name->ToCString()); |
4969 } | 5092 } |
4970 | 5093 |
5094 intptr_t async_type = ParseAsyncSpecifier(); | |
5095 | |
4971 intptr_t accessor_end_pos = accessor_pos; | 5096 intptr_t accessor_end_pos = accessor_pos; |
4972 bool is_native = false; | 5097 bool is_native = false; |
4973 if (is_external) { | 5098 if (is_external) { |
4974 accessor_end_pos = TokenPos(); | 5099 accessor_end_pos = TokenPos(); |
4975 ExpectSemicolon(); | 5100 ExpectSemicolon(); |
4976 } else if (CurrentToken() == Token::kLBRACE) { | 5101 } else if (CurrentToken() == Token::kLBRACE) { |
4977 SkipBlock(); | 5102 SkipBlock(); |
4978 accessor_end_pos = TokenPos(); | 5103 accessor_end_pos = TokenPos(); |
4979 ExpectToken(Token::kRBRACE); | 5104 ExpectToken(Token::kRBRACE); |
4980 } else if (CurrentToken() == Token::kARROW) { | 5105 } else if (CurrentToken() == Token::kARROW) { |
(...skipping 15 matching lines...) Expand all Loading... | |
4996 RawFunction::kSetterFunction, | 5121 RawFunction::kSetterFunction, |
4997 is_static, | 5122 is_static, |
4998 /* is_const = */ false, | 5123 /* is_const = */ false, |
4999 /* is_abstract = */ false, | 5124 /* is_abstract = */ false, |
5000 is_external, | 5125 is_external, |
5001 is_native, | 5126 is_native, |
5002 current_class(), | 5127 current_class(), |
5003 decl_begin_pos)); | 5128 decl_begin_pos)); |
5004 func.set_result_type(result_type); | 5129 func.set_result_type(result_type); |
5005 func.set_end_token_pos(accessor_end_pos); | 5130 func.set_end_token_pos(accessor_end_pos); |
5131 if (async_type == 1) { | |
5132 func.set_modifier(RawFunction::kAsync); | |
5133 } | |
5006 if (is_native && library_.is_dart_scheme() && | 5134 if (is_native && library_.is_dart_scheme() && |
5007 library_.IsPrivate(accessor_name)) { | 5135 library_.IsPrivate(accessor_name)) { |
5008 func.set_is_visible(false); | 5136 func.set_is_visible(false); |
5009 } | 5137 } |
5010 AddFormalParamsToFunction(¶ms, func); | 5138 AddFormalParamsToFunction(¶ms, func); |
5011 top_level->functions.Add(func); | 5139 top_level->functions.Add(func); |
5012 if (!is_patch) { | 5140 if (!is_patch) { |
5013 library_.AddObject(func, accessor_name); | 5141 library_.AddObject(func, accessor_name); |
5014 } else { | 5142 } else { |
5015 library_.ReplaceObject(func, accessor_name); | 5143 library_.ReplaceObject(func, accessor_name); |
(...skipping 1184 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
6200 } else { | 6328 } else { |
6201 SetPosition(saved_pos); | 6329 SetPosition(saved_pos); |
6202 return false; | 6330 return false; |
6203 } | 6331 } |
6204 // Check parameter list and the following token. | 6332 // Check parameter list and the following token. |
6205 if (CurrentToken() == Token::kLPAREN) { | 6333 if (CurrentToken() == Token::kLPAREN) { |
6206 SkipToMatchingParenthesis(); | 6334 SkipToMatchingParenthesis(); |
6207 if ((CurrentToken() == Token::kLBRACE) || | 6335 if ((CurrentToken() == Token::kLBRACE) || |
6208 (CurrentToken() == Token::kARROW) || | 6336 (CurrentToken() == Token::kARROW) || |
6209 (is_top_level_ && IsLiteral("native")) || | 6337 (is_top_level_ && IsLiteral("native")) || |
6210 is_external) { | 6338 is_external || |
6339 (FLAG_enable_async && IsLiteral("async"))) { | |
hausner
2014/07/11 20:18:40
You should create a new Symbol for "async" (in sym
Michael Lippautz (Google)
2014/07/11 23:40:45
Done.
| |
6211 SetPosition(saved_pos); | 6340 SetPosition(saved_pos); |
6212 return true; | 6341 return true; |
6213 } | 6342 } |
6214 } | 6343 } |
6215 SetPosition(saved_pos); | 6344 SetPosition(saved_pos); |
6216 return false; | 6345 return false; |
6217 } | 6346 } |
6218 | 6347 |
6219 | 6348 |
6220 bool Parser::IsTopLevelAccessor() { | 6349 bool Parser::IsTopLevelAccessor() { |
(...skipping 4505 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
10726 } | 10855 } |
10727 ASSERT(result.IsInstance()); | 10856 ASSERT(result.IsInstance()); |
10728 Instance& value = Instance::ZoneHandle(I); | 10857 Instance& value = Instance::ZoneHandle(I); |
10729 value ^= result.raw(); | 10858 value ^= result.raw(); |
10730 value = TryCanonicalize(value, TokenPos()); | 10859 value = TryCanonicalize(value, TokenPos()); |
10731 return value; | 10860 return value; |
10732 } | 10861 } |
10733 } | 10862 } |
10734 | 10863 |
10735 | 10864 |
10736 void Parser::SkipFunctionLiteral() { | 10865 void Parser::SkipFunctionLiteral() { |
hausner
2014/07/11 20:18:40
You probably need to handle the async specifiers h
Michael Lippautz (Google)
2014/07/11 23:40:45
Done.
| |
10737 if (IsIdentifier()) { | 10866 if (IsIdentifier()) { |
10738 if (LookaheadToken(1) != Token::kLPAREN) { | 10867 if (LookaheadToken(1) != Token::kLPAREN) { |
10739 SkipType(true); | 10868 SkipType(true); |
10740 } | 10869 } |
10741 ExpectIdentifier("function name expected"); | 10870 ExpectIdentifier("function name expected"); |
10742 } | 10871 } |
10743 if (CurrentToken() == Token::kLPAREN) { | 10872 if (CurrentToken() == Token::kLPAREN) { |
10744 const bool allow_explicit_default_values = true; | 10873 const bool allow_explicit_default_values = true; |
10745 ParamList params; | 10874 ParamList params; |
10746 params.skipped = true; | 10875 params.skipped = true; |
(...skipping 312 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
11059 void Parser::SkipQualIdent() { | 11188 void Parser::SkipQualIdent() { |
11060 ASSERT(IsIdentifier()); | 11189 ASSERT(IsIdentifier()); |
11061 ConsumeToken(); | 11190 ConsumeToken(); |
11062 if (CurrentToken() == Token::kPERIOD) { | 11191 if (CurrentToken() == Token::kPERIOD) { |
11063 ConsumeToken(); // Consume the kPERIOD token. | 11192 ConsumeToken(); // Consume the kPERIOD token. |
11064 ExpectIdentifier("identifier expected after '.'"); | 11193 ExpectIdentifier("identifier expected after '.'"); |
11065 } | 11194 } |
11066 } | 11195 } |
11067 | 11196 |
11068 } // namespace dart | 11197 } // namespace dart |
OLD | NEW |