| 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;
 | 
|  }
 | 
| 
 |