| Index: runtime/vm/parser.cc
|
| ===================================================================
|
| --- runtime/vm/parser.cc (revision 12003)
|
| +++ runtime/vm/parser.cc (working copy)
|
| @@ -143,34 +143,38 @@
|
|
|
| void ParsedFunction::AllocateVariables() {
|
| LocalScope* scope = node_sequence()->scope();
|
| - const int fixed_parameter_count = function().num_fixed_parameters();
|
| - const int optional_parameter_count = function().num_optional_parameters();
|
| - int parameter_count = fixed_parameter_count + optional_parameter_count;
|
| + const intptr_t num_fixed_params = function().num_fixed_parameters();
|
| + const intptr_t num_opt_pos_params =
|
| + function().num_optional_positional_parameters();
|
| + const intptr_t num_opt_named_params =
|
| + function().num_optional_named_parameters();
|
| + const intptr_t num_opt_params = num_opt_pos_params + num_opt_named_params;
|
| + intptr_t num_params = num_fixed_params + num_opt_params;
|
| const bool is_native_instance_closure =
|
| function().is_native() && function().IsImplicitInstanceClosureFunction();
|
| // Compute start indices to parameters and locals, and the number of
|
| // parameters to copy.
|
| - if ((optional_parameter_count == 0) && !is_native_instance_closure) {
|
| - // Parameter i will be at fp[1 + parameter_count - i] and local variable
|
| + if ((num_opt_params == 0) && !is_native_instance_closure) {
|
| + // Parameter i will be at fp[1 + num_params - i] and local variable
|
| // j will be at fp[kFirstLocalSlotIndex - j].
|
| ASSERT(GetSavedArgumentsDescriptorVar() == NULL);
|
| - first_parameter_index_ = 1 + parameter_count;
|
| + first_parameter_index_ = 1 + num_params;
|
| first_stack_local_index_ = kFirstLocalSlotIndex;
|
| - copied_parameter_count_ = 0;
|
| + num_copied_params_ = 0;
|
| } else {
|
| // Parameter i will be at fp[kFirstLocalSlotIndex - i] and local variable
|
| - // j will be at fp[kFirstLocalSlotIndex - parameter_count - j].
|
| + // j will be at fp[kFirstLocalSlotIndex - num_params - j].
|
| // The saved argument descriptor variable must be allocated similarly to
|
| // a parameter, so that it gets both a frame slot and a context slot when
|
| // captured.
|
| if (GetSavedArgumentsDescriptorVar() != NULL) {
|
| - parameter_count += 1;
|
| + num_params += 1;
|
| }
|
| first_parameter_index_ = kFirstLocalSlotIndex;
|
| - first_stack_local_index_ = first_parameter_index_ - parameter_count;
|
| - copied_parameter_count_ = parameter_count;
|
| + first_stack_local_index_ = first_parameter_index_ - num_params;
|
| + num_copied_params_ = num_params;
|
| if (is_native_instance_closure) {
|
| - copied_parameter_count_ += 1;
|
| + num_copied_params_ += 1;
|
| first_parameter_index_ -= 1;
|
| first_stack_local_index_ -= 1;
|
| }
|
| @@ -181,7 +185,7 @@
|
| LocalScope* context_owner = NULL; // No context needed yet.
|
| int next_free_frame_index =
|
| scope->AllocateVariables(first_parameter_index_,
|
| - parameter_count,
|
| + num_params,
|
| first_stack_local_index_,
|
| scope,
|
| &context_owner);
|
| @@ -203,7 +207,7 @@
|
|
|
| // Frame indices are relative to the frame pointer and are decreasing.
|
| ASSERT(next_free_frame_index <= first_stack_local_index_);
|
| - stack_local_count_ = first_stack_local_index_ - next_free_frame_index;
|
| + num_stack_locals_ = first_stack_local_index_ - next_free_frame_index;
|
| }
|
|
|
|
|
| @@ -427,7 +431,8 @@
|
| void Clear() {
|
| num_fixed_parameters = 0;
|
| num_optional_parameters = 0;
|
| - has_named_optional_parameters = false;
|
| + has_optional_positional_parameters = false;
|
| + has_optional_named_parameters = false;
|
| has_field_initializer = false;
|
| implicitly_final = false;
|
| this->parameters = new ZoneGrowableArray<ParamDesc>();
|
| @@ -458,7 +463,8 @@
|
|
|
| int num_fixed_parameters;
|
| int num_optional_parameters;
|
| - bool has_named_optional_parameters; // Indicates use of the new syntax.
|
| + bool has_optional_positional_parameters;
|
| + bool has_optional_named_parameters;
|
| bool has_field_initializer;
|
| bool implicitly_final;
|
| ZoneGrowableArray<ParamDesc>* parameters;
|
| @@ -773,7 +779,7 @@
|
| TRACE_PARSER("ParseStaticConstGetter");
|
| ParamList params;
|
| ASSERT(func.num_fixed_parameters() == 0); // static.
|
| - ASSERT(func.num_optional_parameters() == 0);
|
| + ASSERT(!func.HasOptionalParameters());
|
| ASSERT(AbstractType::Handle(func.result_type()).IsResolved());
|
|
|
| // Build local scope for function and populate with the formal parameters.
|
| @@ -889,7 +895,7 @@
|
| ASSERT(current_class().raw() == func.Owner());
|
| params.AddReceiver(ReceiverType(TokenPos()));
|
| ASSERT(func.num_fixed_parameters() == 1); // receiver.
|
| - ASSERT(func.num_optional_parameters() == 0);
|
| + ASSERT(!func.HasOptionalParameters());
|
| ASSERT(AbstractType::Handle(func.result_type()).IsResolved());
|
|
|
| // Build local scope for function and populate with the formal parameters.
|
| @@ -938,7 +944,7 @@
|
| &String::ZoneHandle(Symbols::Value()),
|
| &field_type);
|
| ASSERT(func.num_fixed_parameters() == 2); // receiver, value.
|
| - ASSERT(func.num_optional_parameters() == 0);
|
| + ASSERT(!func.HasOptionalParameters());
|
| ASSERT(AbstractType::Handle(func.result_type()).IsVoidType());
|
|
|
| // Build local scope for function and populate with the formal parameters.
|
| @@ -1139,12 +1145,17 @@
|
| }
|
| }
|
|
|
| - if (CurrentToken() == Token::kASSIGN) {
|
| - if (!params->has_named_optional_parameters ||
|
| + if ((CurrentToken() == Token::kASSIGN) || (CurrentToken() == Token::kCOLON)) {
|
| + if ((!params->has_optional_positional_parameters &&
|
| + !params->has_optional_named_parameters) ||
|
| !allow_explicit_default_value) {
|
| ErrorMsg("parameter must not specify a default value");
|
| }
|
| - ConsumeToken();
|
| + if (params->has_optional_positional_parameters) {
|
| + ExpectToken(Token::kASSIGN);
|
| + } else {
|
| + ExpectToken(Token::kCOLON);
|
| + }
|
| params->num_optional_parameters++;
|
| if (is_top_level_) {
|
| // Skip default value parsing.
|
| @@ -1154,7 +1165,8 @@
|
| parameter.default_value = &const_value;
|
| }
|
| } else {
|
| - if (params->has_named_optional_parameters) {
|
| + if (params->has_optional_positional_parameters ||
|
| + params->has_optional_named_parameters) {
|
| // Implicit default value is null.
|
| params->num_optional_parameters++;
|
| parameter.default_value = &Object::ZoneHandle();
|
| @@ -1176,18 +1188,26 @@
|
| ASSERT(CurrentToken() == Token::kLPAREN);
|
|
|
| if (LookaheadToken(1) != Token::kRPAREN) {
|
| - // Parse positional parameters.
|
| + // Parse fixed parameters.
|
| ParseFormalParameters(allow_explicit_default_values, params);
|
| - if (params->has_named_optional_parameters) {
|
| - // Parse named optional parameters.
|
| + if (params->has_optional_positional_parameters ||
|
| + params->has_optional_named_parameters) {
|
| + // Parse optional parameters.
|
| ParseFormalParameters(allow_explicit_default_values, params);
|
| - if (CurrentToken() != Token::kRBRACK) {
|
| - ErrorMsg("',' or ']' expected");
|
| + if (params->has_optional_positional_parameters) {
|
| + if (CurrentToken() != Token::kRBRACK) {
|
| + ErrorMsg("',' or ']' expected");
|
| + }
|
| + } else {
|
| + if (CurrentToken() != Token::kRBRACE) {
|
| + ErrorMsg("',' or '}' expected");
|
| + }
|
| }
|
| - ExpectToken(Token::kRBRACK);
|
| + ConsumeToken(); // ']' or '}'.
|
| }
|
| if ((CurrentToken() != Token::kRPAREN) &&
|
| - !params->has_named_optional_parameters) {
|
| + !params->has_optional_positional_parameters &&
|
| + !params->has_optional_named_parameters) {
|
| ErrorMsg("',' or ')' expected");
|
| }
|
| } else {
|
| @@ -1197,18 +1217,26 @@
|
| }
|
|
|
|
|
| -// Parses a sequence of normal or named formal parameters.
|
| +// Parses a sequence of normal or optional formal parameters.
|
| void Parser::ParseFormalParameters(bool allow_explicit_default_values,
|
| ParamList* params) {
|
| TRACE_PARSER("ParseFormalParameters");
|
| do {
|
| ConsumeToken();
|
| - if (!params->has_named_optional_parameters &&
|
| + if (!params->has_optional_positional_parameters &&
|
| + !params->has_optional_named_parameters &&
|
| (CurrentToken() == Token::kLBRACK)) {
|
| - // End of normal parameters, start of named parameters.
|
| - params->has_named_optional_parameters = true;
|
| + // End of normal parameters, start of optional positional parameters.
|
| + params->has_optional_positional_parameters = true;
|
| return;
|
| }
|
| + if (!params->has_optional_positional_parameters &&
|
| + !params->has_optional_named_parameters &&
|
| + (CurrentToken() == Token::kLBRACE)) {
|
| + // End of normal parameters, start of optional named parameters.
|
| + params->has_optional_named_parameters = true;
|
| + return;
|
| + }
|
| ParseFormalParameter(allow_explicit_default_values, params);
|
| } while (CurrentToken() == Token::kCOMMA);
|
| }
|
| @@ -2748,7 +2776,8 @@
|
| expected_num_parameters = 2;
|
| }
|
| if ((member.params.num_optional_parameters > 0) ||
|
| - (member.params.has_named_optional_parameters) ||
|
| + member.params.has_optional_positional_parameters ||
|
| + member.params.has_optional_named_parameters ||
|
| (member.params.num_fixed_parameters != expected_num_parameters)) {
|
| // Subtract receiver when reporting number of expected arguments.
|
| ErrorMsg(member.name_pos, "operator %s expects %"Pd" argument(s)",
|
| @@ -4279,8 +4308,12 @@
|
| void Parser::AddFormalParamsToFunction(const ParamList* params,
|
| const Function& func) {
|
| ASSERT((params != NULL) && (params->parameters != NULL));
|
| - func.set_num_fixed_parameters(params->num_fixed_parameters);
|
| - func.set_num_optional_parameters(params->num_optional_parameters);
|
| + ASSERT((params->num_optional_parameters > 0) ==
|
| + (params->has_optional_positional_parameters ||
|
| + params->has_optional_named_parameters));
|
| + func.SetNumberOfParameters(params->num_fixed_parameters,
|
| + params->num_optional_parameters,
|
| + params->has_optional_positional_parameters);
|
| const int num_parameters = params->parameters->length();
|
| ASSERT(num_parameters == func.NumberOfParameters());
|
| func.set_parameter_types(Array::Handle(Array::New(num_parameters,
|
|
|