| Index: runtime/vm/parser.cc
|
| diff --git a/runtime/vm/parser.cc b/runtime/vm/parser.cc
|
| index 447c7bb61a84285c4c31b04506a1a260629e500c..4ddfbe16344fa7648348e23757e62d11fc34b8b5 100644
|
| --- a/runtime/vm/parser.cc
|
| +++ b/runtime/vm/parser.cc
|
| @@ -432,12 +432,14 @@ struct ParamDesc {
|
| name_pos(0),
|
| name(NULL),
|
| default_value(NULL),
|
| + metadata(NULL),
|
| is_final(false),
|
| is_field_initializer(false) { }
|
| const AbstractType* type;
|
| intptr_t name_pos;
|
| const String* name;
|
| const Object* default_value; // NULL if not an optional parameter.
|
| + const Object* metadata; // NULL if no metadata or metadata not evaluated.
|
| bool is_final;
|
| bool is_field_initializer;
|
| };
|
| @@ -778,17 +780,25 @@ RawObject* Parser::ParseFunctionParameters(const Function& func) {
|
| parser.set_current_class(owner);
|
| parser.SkipFunctionPreamble();
|
| ParamList params;
|
| - parser.ParseFormalParameterList(true, ¶ms);
|
| + parser.ParseFormalParameterList(true, true, ¶ms);
|
| ParamDesc* param = params.parameters->data();
|
| const int param_cnt = params.num_fixed_parameters +
|
| params.num_optional_parameters;
|
| - Array& param_descriptor = Array::Handle(isolate, Array::New(param_cnt * 2));
|
| - for (int i = 0, j = 0; i < param_cnt; i++, j += 2) {
|
| - param_descriptor.SetAt(j, param[i].is_final ? Bool::True() :
|
| - Bool::False());
|
| - param_descriptor.SetAt(j + 1,
|
| + const Array& param_descriptor =
|
| + Array::Handle(Array::New(param_cnt * kParameterEntrySize));
|
| + for (int i = 0, j = 0; i < param_cnt; i++, j += kParameterEntrySize) {
|
| + param_descriptor.SetAt(j + kParameterIsFinalOffset,
|
| + param[i].is_final ? Bool::True() : Bool::False());
|
| + param_descriptor.SetAt(j + kParameterDefaultValueOffset,
|
| (param[i].default_value == NULL) ? Object::null_instance() :
|
| *(param[i].default_value));
|
| + const Object* metadata = param[i].metadata;
|
| + if ((metadata != NULL) && (*metadata).IsError()) {
|
| + return (*metadata).raw(); // Error evaluating the metadata.
|
| + }
|
| + param_descriptor.SetAt(j + kParameterMetadataOffset,
|
| + (param[i].metadata == NULL) ? Object::null_instance() :
|
| + *(param[i].metadata));
|
| }
|
| isolate->set_long_jump_base(base);
|
| return param_descriptor.raw();
|
| @@ -1366,13 +1376,19 @@ void Parser::SkipBlock() {
|
|
|
|
|
| void Parser::ParseFormalParameter(bool allow_explicit_default_value,
|
| + bool evaluate_metadata,
|
| ParamList* params) {
|
| TRACE_PARSER("ParseFormalParameter");
|
| ParamDesc parameter;
|
| bool var_seen = false;
|
| bool this_seen = false;
|
|
|
| - SkipMetadata();
|
| + if (evaluate_metadata && (CurrentToken() == Token::kAT)) {
|
| + parameter.metadata = &Array::ZoneHandle(EvaluateMetadata());
|
| + } else {
|
| + SkipMetadata();
|
| + }
|
| +
|
| if (CurrentToken() == Token::kFINAL) {
|
| ConsumeToken();
|
| parameter.is_final = true;
|
| @@ -1472,7 +1488,7 @@ void Parser::ParseFormalParameter(bool allow_explicit_default_value,
|
| &Type::ZoneHandle(Type::DynamicType()));
|
|
|
| const bool no_explicit_default_values = false;
|
| - ParseFormalParameterList(no_explicit_default_values, &func_params);
|
| + ParseFormalParameterList(no_explicit_default_values, false, &func_params);
|
|
|
| // The field 'is_static' has no meaning for signature functions.
|
| const Function& signature_function = Function::Handle(
|
| @@ -1556,6 +1572,7 @@ void Parser::ParseFormalParameter(bool allow_explicit_default_value,
|
|
|
| // Parses a sequence of normal or optional formal parameters.
|
| void Parser::ParseFormalParameters(bool allow_explicit_default_values,
|
| + bool evaluate_metadata,
|
| ParamList* params) {
|
| TRACE_PARSER("ParseFormalParameters");
|
| do {
|
| @@ -1574,23 +1591,30 @@ void Parser::ParseFormalParameters(bool allow_explicit_default_values,
|
| params->has_optional_named_parameters = true;
|
| return;
|
| }
|
| - ParseFormalParameter(allow_explicit_default_values, params);
|
| + ParseFormalParameter(allow_explicit_default_values,
|
| + evaluate_metadata,
|
| + params);
|
| } while (CurrentToken() == Token::kCOMMA);
|
| }
|
|
|
|
|
| void Parser::ParseFormalParameterList(bool allow_explicit_default_values,
|
| + bool evaluate_metadata,
|
| ParamList* params) {
|
| TRACE_PARSER("ParseFormalParameterList");
|
| ASSERT(CurrentToken() == Token::kLPAREN);
|
|
|
| if (LookaheadToken(1) != Token::kRPAREN) {
|
| // Parse fixed parameters.
|
| - ParseFormalParameters(allow_explicit_default_values, params);
|
| + ParseFormalParameters(allow_explicit_default_values,
|
| + evaluate_metadata,
|
| + params);
|
| if (params->has_optional_positional_parameters ||
|
| params->has_optional_named_parameters) {
|
| // Parse optional parameters.
|
| - ParseFormalParameters(allow_explicit_default_values, params);
|
| + ParseFormalParameters(allow_explicit_default_values,
|
| + evaluate_metadata,
|
| + params);
|
| if (params->has_optional_positional_parameters) {
|
| if (CurrentToken() != Token::kRBRACK) {
|
| ErrorMsg("',' or ']' expected");
|
| @@ -2481,7 +2505,7 @@ SequenceNode* Parser::ParseConstructor(const Function& func,
|
| if (func.is_const()) {
|
| params.SetImplicitlyFinal();
|
| }
|
| - ParseFormalParameterList(allow_explicit_default_values, ¶ms);
|
| + ParseFormalParameterList(allow_explicit_default_values, false, ¶ms);
|
|
|
| SetupDefaultsForOptionalParams(¶ms, default_parameter_values);
|
| ASSERT(AbstractType::Handle(func.result_type()).IsResolved());
|
| @@ -2737,7 +2761,7 @@ SequenceNode* Parser::ParseFunc(const Function& func,
|
| // we are compiling a getter this will at most populate the receiver.
|
| AddFormalParamsToScope(¶ms, current_block_->scope);
|
| } else {
|
| - ParseFormalParameterList(allow_explicit_default_values, ¶ms);
|
| + ParseFormalParameterList(allow_explicit_default_values, false, ¶ms);
|
|
|
| // The number of parameters and their type are not yet set in local
|
| // functions, since they are not 'top-level' parsed.
|
| @@ -2968,7 +2992,9 @@ void Parser::ParseMethodOrConstructor(ClassDesc* members, MemberDesc* method) {
|
| method->params.SetImplicitlyFinal();
|
| }
|
| if (!method->IsGetter()) {
|
| - ParseFormalParameterList(allow_explicit_default_values, &method->params);
|
| + ParseFormalParameterList(allow_explicit_default_values,
|
| + false,
|
| + &method->params);
|
| }
|
|
|
| // Now that we know the parameter list, we can distinguish between the
|
| @@ -4025,7 +4051,7 @@ void Parser::ParseTypedef(const GrowableObjectArray& pending_classes,
|
| &Type::ZoneHandle(Type::DynamicType()));
|
|
|
| const bool no_explicit_default_values = false;
|
| - ParseFormalParameterList(no_explicit_default_values, &func_params);
|
| + ParseFormalParameterList(no_explicit_default_values, false, &func_params);
|
| ExpectSemicolon();
|
| // The field 'is_static' has no meaning for signature functions.
|
| Function& signature_function = Function::Handle(
|
| @@ -4474,7 +4500,7 @@ void Parser::ParseTopLevelFunction(TopLevel* top_level,
|
| const intptr_t function_pos = TokenPos();
|
| ParamList params;
|
| const bool allow_explicit_default_values = true;
|
| - ParseFormalParameterList(allow_explicit_default_values, ¶ms);
|
| + ParseFormalParameterList(allow_explicit_default_values, false, ¶ms);
|
|
|
| intptr_t function_end_pos = function_pos;
|
| if (is_external) {
|
| @@ -4563,7 +4589,7 @@ void Parser::ParseTopLevelAccessor(TopLevel* top_level,
|
|
|
| if (!is_getter) {
|
| const bool allow_explicit_default_values = true;
|
| - ParseFormalParameterList(allow_explicit_default_values, ¶ms);
|
| + ParseFormalParameterList(allow_explicit_default_values, false, ¶ms);
|
| }
|
| String& accessor_name = String::ZoneHandle();
|
| int expected_num_parameters = -1;
|
| @@ -10185,7 +10211,7 @@ void Parser::SkipFunctionLiteral() {
|
| const bool allow_explicit_default_values = true;
|
| ParamList params;
|
| params.skipped = true;
|
| - ParseFormalParameterList(allow_explicit_default_values, ¶ms);
|
| + ParseFormalParameterList(allow_explicit_default_values, false, ¶ms);
|
| }
|
| if (CurrentToken() == Token::kLBRACE) {
|
| SkipBlock();
|
|
|