Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(394)

Unified Diff: runtime/vm/parser.cc

Issue 22685007: Implement updated method overriding rules in the vm. (Closed) Base URL: http://dart.googlecode.com/svn/branches/bleeding_edge/dart/
Patch Set: Created 7 years, 4 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
Index: runtime/vm/parser.cc
===================================================================
--- runtime/vm/parser.cc (revision 25979)
+++ 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(&params, 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(&params, 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);
siva 2013/08/12 02:56:43 Why Isolate:Current() and not the cached isolate?
regis 2013/08/12 17:45:27 This function is now static.
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;
}

Powered by Google App Engine
This is Rietveld 408576698