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(¶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); |
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; |
} |