Chromium Code Reviews| 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; |
| } |