| Index: runtime/vm/parser.cc
|
| ===================================================================
|
| --- runtime/vm/parser.cc (revision 26025)
|
| +++ runtime/vm/parser.cc (working copy)
|
| @@ -456,7 +456,7 @@
|
| this->parameters->Add(param);
|
| }
|
|
|
| - void AddReceiver(const Type* receiver_type, intptr_t token_pos) {
|
| + void AddReceiver(const AbstractType* receiver_type, intptr_t token_pos) {
|
| ASSERT(this->parameters->is_empty());
|
| AddFinalParameter(token_pos, &Symbols::This(), receiver_type);
|
| }
|
| @@ -1016,7 +1016,7 @@
|
| // func.token_pos() points to the name of the field.
|
| intptr_t ident_pos = func.token_pos();
|
| ASSERT(current_class().raw() == func.Owner());
|
| - params.AddReceiver(ReceiverType(), ident_pos);
|
| + params.AddReceiver(ReceiverType(current_class()), ident_pos);
|
| ASSERT(func.num_fixed_parameters() == 1); // receiver.
|
| ASSERT(!func.HasOptionalParameters());
|
| ASSERT(AbstractType::Handle(func.result_type()).IsResolved());
|
| @@ -1060,7 +1060,7 @@
|
|
|
| ParamList params;
|
| ASSERT(current_class().raw() == func.Owner());
|
| - params.AddReceiver(ReceiverType(), ident_pos);
|
| + params.AddReceiver(ReceiverType(current_class()), ident_pos);
|
| params.AddFinalParameter(ident_pos,
|
| &Symbols::Value(),
|
| &field_type);
|
| @@ -1093,7 +1093,7 @@
|
| const intptr_t ident_pos = func.token_pos();
|
| ASSERT(func.token_pos() == 0);
|
| ASSERT(current_class().raw() == func.Owner());
|
| - params.AddReceiver(ReceiverType(), ident_pos);
|
| + params.AddReceiver(ReceiverType(current_class()), ident_pos);
|
| ASSERT(func.num_fixed_parameters() == 1); // Receiver.
|
| ASSERT(!func.HasOptionalParameters());
|
|
|
| @@ -1123,7 +1123,7 @@
|
| ParamList params;
|
| // Receiver first.
|
| intptr_t token_pos = func.token_pos();
|
| - params.AddReceiver(ReceiverType(), token_pos);
|
| + params.AddReceiver(ReceiverType(current_class()), token_pos);
|
| // Remaining positional parameters.
|
| intptr_t i = 1;
|
| for (; i < desc.PositionalCount(); ++i) {
|
| @@ -2283,20 +2283,16 @@
|
|
|
| SequenceNode* Parser::MakeImplicitConstructor(const Function& func) {
|
| ASSERT(func.IsConstructor());
|
| + ASSERT(func.Owner() == current_class().raw());
|
| const intptr_t ctor_pos = TokenPos();
|
| OpenFunctionBlock(func);
|
| - const Class& cls = Class::Handle(func.Owner());
|
|
|
| LocalVariable* receiver = new LocalVariable(
|
| - ctor_pos,
|
| - Symbols::This(),
|
| - Type::ZoneHandle(Type::DynamicType()));
|
| + ctor_pos, Symbols::This(), *ReceiverType(current_class()));
|
| current_block_->scope->AddVariable(receiver);
|
|
|
| LocalVariable* phase_parameter = new LocalVariable(
|
| - ctor_pos,
|
| - Symbols::PhaseParameter(),
|
| - Type::ZoneHandle(Type::SmiType()));
|
| + ctor_pos, Symbols::PhaseParameter(), Type::ZoneHandle(Type::SmiType()));
|
| current_block_->scope->AddVariable(phase_parameter);
|
|
|
| // Parse expressions of instance fields that have an explicit
|
| @@ -2304,7 +2300,8 @@
|
| // The receiver must not be visible to field initializer expressions.
|
| receiver->set_invisible(true);
|
| GrowableArray<Field*> initialized_fields;
|
| - ParseInitializedInstanceFields(cls, receiver, &initialized_fields);
|
| + ParseInitializedInstanceFields(
|
| + current_class(), receiver, &initialized_fields);
|
| receiver->set_invisible(false);
|
|
|
| // If the class of this implicit constructor is a mixin application class,
|
| @@ -2313,7 +2310,7 @@
|
| // expressions and then calls the respective super constructor with
|
| // the same name and number of parameters.
|
| ArgumentListNode* forwarding_args = NULL;
|
| - if (cls.mixin() != Type::null()) {
|
| + if (current_class().mixin() != Type::null()) {
|
| // At this point we don't support forwarding constructors
|
| // that have optional parameters because we don't know the default
|
| // values of the optional parameters. We would have to compile the super
|
| @@ -2339,8 +2336,8 @@
|
| }
|
| }
|
|
|
| - GenerateSuperConstructorCall(cls, receiver, forwarding_args);
|
| - CheckConstFieldsInitialized(cls);
|
| + GenerateSuperConstructorCall(current_class(), receiver, forwarding_args);
|
| + CheckConstFieldsInitialized(current_class());
|
|
|
| // Empty constructor body.
|
| SequenceNode* statements = CloseBlock();
|
| @@ -2388,7 +2385,7 @@
|
| // Add implicit receiver parameter which is passed the allocated
|
| // but uninitialized instance to construct.
|
| ASSERT(current_class().raw() == func.Owner());
|
| - params.AddReceiver(ReceiverType(), func.token_pos());
|
| + params.AddReceiver(ReceiverType(current_class()), func.token_pos());
|
|
|
| // Add implicit parameter for construction phase.
|
| params.AddFinalParameter(
|
| @@ -2648,7 +2645,7 @@
|
| } else if (!func.is_static()) {
|
| // Static functions do not have a receiver.
|
| ASSERT(current_class().raw() == func.Owner());
|
| - params.AddReceiver(ReceiverType(), func.token_pos());
|
| + params.AddReceiver(ReceiverType(current_class()), func.token_pos());
|
| } else if (func.IsFactory()) {
|
| // The first parameter of a factory is the AbstractTypeArguments vector of
|
| // the type of the instance to be allocated.
|
| @@ -2870,7 +2867,7 @@
|
| // The first parameter of a factory is the AbstractTypeArguments vector of
|
| // the type of the instance to be allocated.
|
| if (!method->has_static || method->IsConstructor()) {
|
| - method->params.AddReceiver(ReceiverType(), formal_param_pos);
|
| + method->params.AddReceiver(ReceiverType(current_class()), formal_param_pos);
|
| } else if (method->IsFactory()) {
|
| method->params.AddFinalParameter(
|
| formal_param_pos,
|
| @@ -3221,7 +3218,7 @@
|
| field->name_pos);
|
| ParamList params;
|
| ASSERT(current_class().raw() == getter.Owner());
|
| - params.AddReceiver(ReceiverType(), field->name_pos);
|
| + params.AddReceiver(ReceiverType(current_class()), field->name_pos);
|
| getter.set_result_type(*field->type);
|
| AddFormalParamsToFunction(¶ms, getter);
|
| members->AddFunction(getter);
|
| @@ -3237,7 +3234,7 @@
|
| field->name_pos);
|
| ParamList params;
|
| ASSERT(current_class().raw() == setter.Owner());
|
| - params.AddReceiver(ReceiverType(), field->name_pos);
|
| + params.AddReceiver(ReceiverType(current_class()), field->name_pos);
|
| params.AddFinalParameter(TokenPos(),
|
| &Symbols::Value(),
|
| field->type);
|
| @@ -3368,22 +3365,26 @@
|
| ErrorMsg(member.name_pos, "factory name must be '%s'",
|
| members->class_name().ToCString());
|
| }
|
| - // Do not bypass class resolution by using current_class() directly, since
|
| - // it may be a patch class.
|
| - const Object& result_type_class = Object::Handle(
|
| - UnresolvedClass::New(LibraryPrefix::Handle(),
|
| - *member.name,
|
| - member.name_pos));
|
| - // The type arguments of the result type are the type parameters of the
|
| - // current class. Note that in the case of a patch class, they are copied
|
| - // from the class being patched.
|
| - member.type = &Type::ZoneHandle(Type::New(
|
| - result_type_class,
|
| - TypeArguments::Handle(current_class().type_parameters()),
|
| - member.name_pos));
|
| } else if (member.has_static) {
|
| ErrorMsg(member.name_pos, "constructor cannot be static");
|
| }
|
| + if (member.type != NULL) {
|
| + ErrorMsg(member.name_pos, "constructor must not specify return type");
|
| + }
|
| + // Do not bypass class resolution by using current_class() directly, since
|
| + // it may be a patch class.
|
| + const Object& result_type_class = Object::Handle(
|
| + UnresolvedClass::New(LibraryPrefix::Handle(),
|
| + *member.name,
|
| + member.name_pos));
|
| + // The type arguments of the result type are the type parameters of the
|
| + // current class. Note that in the case of a patch class, they are copied
|
| + // from the class being patched.
|
| + member.type = &Type::ZoneHandle(Type::New(
|
| + result_type_class,
|
| + TypeArguments::Handle(current_class().type_parameters()),
|
| + member.name_pos));
|
| +
|
| // We must be dealing with a constructor or named constructor.
|
| member.kind = RawFunction::kConstructor;
|
| *member.name = String::Concat(*member.name, Symbols::Dot());
|
| @@ -3395,18 +3396,7 @@
|
| }
|
| // Ensure that names are symbols.
|
| *member.name = Symbols::New(*member.name);
|
| - if (member.type == NULL) {
|
| - ASSERT(!member.has_factory);
|
| - // The body of the constructor cannot modify the type arguments of the
|
| - // constructed instance, which is passed in as a hidden parameter.
|
| - // Therefore, there is no need to set the result type to be checked.
|
| - member.type = &Type::ZoneHandle(Type::DynamicType());
|
| - } else {
|
| - // The type can only be already set in the factory case.
|
| - if (!member.has_factory) {
|
| - ErrorMsg(member.name_pos, "constructor must not specify return type");
|
| - }
|
| - }
|
| +
|
| if (CurrentToken() != Token::kLPAREN) {
|
| ErrorMsg("left parenthesis expected");
|
| }
|
| @@ -3690,9 +3680,9 @@
|
| // The patched class must not be finalized yet.
|
| const Class& orig_class = Class::Cast(obj);
|
| ASSERT(!orig_class.is_finalized());
|
| - const char* err_msg = orig_class.ApplyPatch(cls);
|
| - if (err_msg != NULL) {
|
| - ErrorMsg(class_pos, "applying patch failed with '%s'", err_msg);
|
| + Error& error = Error::Handle();
|
| + if (!orig_class.ApplyPatch(cls, &error)) {
|
| + AppendErrorMsg(error, class_pos, "applying patch failed");
|
| }
|
| }
|
| }
|
| @@ -3719,10 +3709,9 @@
|
| ctor.set_end_token_pos(ctor.token_pos());
|
|
|
| ParamList params;
|
| - // Add implicit 'this' parameter. We don't care about the specific type
|
| - // and just specify dynamic.
|
| - const Type& receiver_type = Type::Handle(Type::DynamicType());
|
| - params.AddReceiver(&receiver_type, cls.token_pos());
|
| + // Add implicit 'this' parameter.
|
| + const AbstractType* receiver_type = ReceiverType(cls);
|
| + params.AddReceiver(receiver_type, cls.token_pos());
|
| // Add implicit parameter for construction phase.
|
| params.AddFinalParameter(cls.token_pos(),
|
| &Symbols::PhaseParameter(),
|
| @@ -3731,7 +3720,7 @@
|
| AddFormalParamsToFunction(¶ms, ctor);
|
| // The body of the constructor cannot modify the type of the constructed
|
| // instance, which is passed in as the receiver.
|
| - ctor.set_result_type(receiver_type);
|
| + ctor.set_result_type(*receiver_type);
|
| cls.AddFunction(ctor);
|
| }
|
|
|
| @@ -3822,7 +3811,9 @@
|
| mixin_application.set_super_type(type);
|
| mixin_application.set_is_synthesized_class();
|
|
|
| - AddImplicitConstructor(mixin_application);
|
| + // This mixin application typedef needs an implicit constructor, but it is
|
| + // too early to call 'AddImplicitConstructor(mixin_application)' here,
|
| + // because this class should be lazily compiled.
|
| if (CurrentToken() == Token::kIMPLEMENTS) {
|
| ParseInterfaceList(mixin_application);
|
| }
|
| @@ -4960,7 +4951,10 @@
|
| params->has_optional_named_parameters));
|
| if (!Utils::IsInt(16, params->num_fixed_parameters) ||
|
| !Utils::IsInt(16, params->num_optional_parameters)) {
|
| - ErrorMsg(func.token_pos(), "too many formal parameters");
|
| + const Script& script = Script::Handle(Class::Handle(func.Owner()).script());
|
| + const Error& error = Error::Handle(FormatErrorMsg(
|
| + script, func.token_pos(), "Error", "too many formal parameters"));
|
| + ErrorMsg(error);
|
| }
|
| func.set_num_fixed_parameters(params->num_fixed_parameters);
|
| func.SetNumOptionalParameters(params->num_optional_parameters,
|
| @@ -4973,7 +4967,6 @@
|
| Heap::kOld)));
|
| for (int i = 0; i < num_parameters; i++) {
|
| ParamDesc& param_desc = (*params->parameters)[i];
|
| - ASSERT(is_top_level_ || param_desc.type->IsResolved());
|
| func.SetParameterTypeAt(i, *param_desc.type);
|
| func.SetParameterNameAt(i, *param_desc.name);
|
| }
|
| @@ -6940,7 +6933,7 @@
|
|
|
|
|
| void Parser::ErrorMsg(const Error& error) {
|
| - isolate()->long_jump_base()->Jump(1, error);
|
| + Isolate::Current()->long_jump_base()->Jump(1, error);
|
| UNREACHABLE();
|
| }
|
|
|
| @@ -8353,17 +8346,18 @@
|
| }
|
|
|
|
|
| -const Type* Parser::ReceiverType() const {
|
| - ASSERT(!current_class().IsNull());
|
| +const AbstractType* Parser::ReceiverType(const Class& cls) {
|
| + ASSERT(!cls.IsNull());
|
| TypeArguments& type_arguments = TypeArguments::Handle();
|
| - if (current_class().NumTypeParameters() > 0) {
|
| - type_arguments = current_class().type_parameters();
|
| + if (cls.NumTypeParameters() > 0) {
|
| + type_arguments = cls.type_parameters();
|
| }
|
| - Type& type = Type::ZoneHandle(
|
| - Type::New(current_class(), type_arguments, current_class().token_pos()));
|
| - if (!is_top_level_ || current_class().is_type_finalized()) {
|
| + AbstractType& type = AbstractType::ZoneHandle(
|
| + Type::New(cls, type_arguments, cls.token_pos()));
|
| + if (cls.is_type_finalized()) {
|
| type ^= ClassFinalizer::FinalizeType(
|
| - current_class(), type, ClassFinalizer::kCanonicalizeWellFormed);
|
| + cls, type, ClassFinalizer::kCanonicalizeWellFormed);
|
| + // Note that the receiver type may now be a malbounded type.
|
| }
|
| return &type;
|
| }
|
|
|