Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(21)

Side by Side Diff: runtime/vm/parser.cc

Issue 362153002: Transform functions marked as async (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: getters and setters Created 6 years, 5 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « runtime/vm/parser.h ('k') | runtime/vm/raw_object.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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
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
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
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(&params, current_block_->scope); 3014 AddFormalParamsToScope(&params, current_block_->scope);
3015 } else if (func.is_synthetic_container() && Function::Handle(
3016 func.parent_function()).IsGetterFunction()) {
3017 AddFormalParamsToScope(&params, 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(&params, 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, &params);
3025 // Parse them away.
2934 } else { 3026 } else {
2935 ParseFormalParameterList(allow_explicit_default_values, false, &params); 3027 ParseFormalParameterList(allow_explicit_default_values, false, &params);
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(&params, func); 3032 AddFormalParamsToFunction(&params, func);
2941 } 3033 }
2942 SetupDefaultsForOptionalParams(&params, default_parameter_values); 3034 SetupDefaultsForOptionalParams(&params, 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
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
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, &params, 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
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
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
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, &params); 4951 ParseFormalParameterList(allow_explicit_default_values, false, &params);
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
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(&params, func); 4995 AddFormalParamsToFunction(&params, 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
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
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(&params, func); 5138 AddFormalParamsToFunction(&params, 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
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
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
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
OLDNEW
« no previous file with comments | « runtime/vm/parser.h ('k') | runtime/vm/raw_object.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698