Index: runtime/vm/parser.cc |
=================================================================== |
--- runtime/vm/parser.cc (revision 11998) |
+++ 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, |