Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file |
| 2 // for details. All rights reserved. Use of this source code is governed by a | 2 // for details. All rights reserved. Use of this source code is governed by a |
| 3 // BSD-style license that can be found in the LICENSE file. | 3 // BSD-style license that can be found in the LICENSE file. |
| 4 | 4 |
| 5 #include "vm/parser.h" | 5 #include "vm/parser.h" |
| 6 | 6 |
| 7 #include "vm/bigint_operations.h" | 7 #include "vm/bigint_operations.h" |
| 8 #include "vm/class_finalizer.h" | 8 #include "vm/class_finalizer.h" |
| 9 #include "vm/compiler.h" | 9 #include "vm/compiler.h" |
| 10 #include "vm/compiler_stats.h" | 10 #include "vm/compiler_stats.h" |
| (...skipping 268 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 279 : script_(script), | 279 : script_(script), |
| 280 tokens_iterator_(TokenStream::Handle(script.tokens()), token_position), | 280 tokens_iterator_(TokenStream::Handle(script.tokens()), token_position), |
| 281 token_kind_(Token::kILLEGAL), | 281 token_kind_(Token::kILLEGAL), |
| 282 current_block_(NULL), | 282 current_block_(NULL), |
| 283 is_top_level_(false), | 283 is_top_level_(false), |
| 284 current_member_(NULL), | 284 current_member_(NULL), |
| 285 allow_function_literals_(true), | 285 allow_function_literals_(true), |
| 286 current_function_(function), | 286 current_function_(function), |
| 287 innermost_function_(Function::Handle(function.raw())), | 287 innermost_function_(Function::Handle(function.raw())), |
| 288 current_class_(Class::Handle(current_function_.Owner())), | 288 current_class_(Class::Handle(current_function_.Owner())), |
| 289 library_(Library::Handle(current_class_.library())), | 289 library_(Library::Handle(Class::Handle(function.origin()).library())), |
| 290 try_blocks_list_(NULL), | 290 try_blocks_list_(NULL), |
| 291 expression_temp_(NULL), | 291 expression_temp_(NULL), |
| 292 saved_current_context_(NULL) { | 292 saved_current_context_(NULL) { |
| 293 ASSERT(tokens_iterator_.IsValid()); | 293 ASSERT(tokens_iterator_.IsValid()); |
| 294 ASSERT(!function.IsNull()); | 294 ASSERT(!function.IsNull()); |
| 295 if (FLAG_enable_type_checks) { | 295 if (FLAG_enable_type_checks) { |
| 296 EnsureExpressionTemp(); | 296 EnsureExpressionTemp(); |
| 297 } | 297 } |
| 298 } | 298 } |
| 299 | 299 |
| (...skipping 1518 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1818 if (!f.is_static() && f.has_initializer()) { | 1818 if (!f.is_static() && f.has_initializer()) { |
| 1819 Field& field = Field::ZoneHandle(); | 1819 Field& field = Field::ZoneHandle(); |
| 1820 field ^= fields.At(i); | 1820 field ^= fields.At(i); |
| 1821 if (field.is_final()) { | 1821 if (field.is_final()) { |
| 1822 // Final fields with initializer expression may not be initialized | 1822 // Final fields with initializer expression may not be initialized |
| 1823 // again by constructors. Remember that this field is already | 1823 // again by constructors. Remember that this field is already |
| 1824 // initialized. | 1824 // initialized. |
| 1825 initialized_fields->Add(&field); | 1825 initialized_fields->Add(&field); |
| 1826 } | 1826 } |
| 1827 intptr_t field_pos = field.token_pos(); | 1827 intptr_t field_pos = field.token_pos(); |
| 1828 if (current_class().raw() != field.origin()) { | |
| 1829 const Class& origin_class = Class::Handle(field.origin()); | |
| 1830 if (origin_class.library() != library_.raw()) { | |
| 1831 ErrorMsg("Cannot handle initialized mixin field '%s'" | |
| 1832 "from imported library\n", field.ToCString()); | |
| 1833 } | |
| 1834 } | |
| 1828 SetPosition(field_pos); | 1835 SetPosition(field_pos); |
| 1829 ASSERT(IsIdentifier()); | 1836 ASSERT(IsIdentifier()); |
| 1830 ConsumeToken(); | 1837 ConsumeToken(); |
| 1831 ExpectToken(Token::kASSIGN); | 1838 ExpectToken(Token::kASSIGN); |
| 1832 | 1839 |
| 1833 AstNode* init_expr = NULL; | 1840 AstNode* init_expr = NULL; |
| 1834 if (field.is_const()) { | 1841 if (field.is_const()) { |
| 1835 init_expr = ParseConstExpr(); | 1842 init_expr = ParseConstExpr(); |
| 1836 } else { | 1843 } else { |
| 1837 init_expr = ParseExpr(kAllowConst, kConsumeCascades); | 1844 init_expr = ParseExpr(kAllowConst, kConsumeCascades); |
| (...skipping 172 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 2010 SequenceNode* Parser::ParseConstructor(const Function& func, | 2017 SequenceNode* Parser::ParseConstructor(const Function& func, |
| 2011 Array& default_parameter_values) { | 2018 Array& default_parameter_values) { |
| 2012 TRACE_PARSER("ParseConstructor"); | 2019 TRACE_PARSER("ParseConstructor"); |
| 2013 ASSERT(func.IsConstructor()); | 2020 ASSERT(func.IsConstructor()); |
| 2014 ASSERT(!func.IsFactory()); | 2021 ASSERT(!func.IsFactory()); |
| 2015 ASSERT(!func.is_static()); | 2022 ASSERT(!func.is_static()); |
| 2016 ASSERT(!func.IsLocalFunction()); | 2023 ASSERT(!func.IsLocalFunction()); |
| 2017 const Class& cls = Class::Handle(func.Owner()); | 2024 const Class& cls = Class::Handle(func.Owner()); |
| 2018 ASSERT(!cls.IsNull()); | 2025 ASSERT(!cls.IsNull()); |
| 2019 | 2026 |
| 2020 if (CurrentToken() == Token::kCLASS) { | 2027 if (func.IsImplicitConstructor()) { |
| 2021 // Special case: implicit constructor. | 2028 // Special case: implicit constructor. |
| 2022 // The parser adds an implicit default constructor when a class | 2029 // The parser adds an implicit default constructor when a class |
| 2023 // does not have any explicit constructor or factory (see | 2030 // does not have any explicit constructor or factory (see |
| 2024 // Parser::AddImplicitConstructor). The token position of this implicit | 2031 // Parser::AddImplicitConstructor). |
| 2025 // constructor points to the 'class' keyword, which is followed | |
| 2026 // by the name of the class (which is also the constructor name). | |
| 2027 // There is no source text to parse. We just build the | 2032 // There is no source text to parse. We just build the |
| 2028 // sequence node by hand. | 2033 // sequence node by hand. |
| 2029 return MakeImplicitConstructor(func); | 2034 return MakeImplicitConstructor(func); |
| 2030 } | 2035 } |
| 2031 | 2036 |
| 2032 OpenFunctionBlock(func); | 2037 OpenFunctionBlock(func); |
| 2033 ParamList params; | 2038 ParamList params; |
| 2034 const bool allow_explicit_default_values = true; | 2039 const bool allow_explicit_default_values = true; |
| 2035 ASSERT(CurrentToken() == Token::kLPAREN); | 2040 ASSERT(CurrentToken() == Token::kLPAREN); |
| 2036 | 2041 |
| (...skipping 1184 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 3221 const intptr_t type_pos = TokenPos(); | 3226 const intptr_t type_pos = TokenPos(); |
| 3222 const AbstractType& type = AbstractType::Handle( | 3227 const AbstractType& type = AbstractType::Handle( |
| 3223 ParseType(ClassFinalizer::kTryResolve)); | 3228 ParseType(ClassFinalizer::kTryResolve)); |
| 3224 if (type.IsTypeParameter()) { | 3229 if (type.IsTypeParameter()) { |
| 3225 ErrorMsg(type_pos, | 3230 ErrorMsg(type_pos, |
| 3226 "class '%s' may not extend type parameter '%s'", | 3231 "class '%s' may not extend type parameter '%s'", |
| 3227 class_name.ToCString(), | 3232 class_name.ToCString(), |
| 3228 String::Handle(type.UserVisibleName()).ToCString()); | 3233 String::Handle(type.UserVisibleName()).ToCString()); |
| 3229 } | 3234 } |
| 3230 super_type ^= type.raw(); | 3235 super_type ^= type.raw(); |
| 3236 if (CurrentToken() == Token::kWITH) { | |
| 3237 super_type = ParseMixins(super_type); | |
| 3238 } | |
| 3231 } else { | 3239 } else { |
| 3232 // No extends clause: Implicitly extend Object. | 3240 // No extends clause: implicitly extend Object. |
| 3233 super_type = Type::ObjectType(); | 3241 super_type = Type::ObjectType(); |
| 3234 } | 3242 } |
| 3235 ASSERT(!super_type.IsNull()); | 3243 ASSERT(!super_type.IsNull()); |
| 3236 cls.set_super_type(super_type); | 3244 cls.set_super_type(super_type); |
| 3237 | 3245 |
| 3238 if (CurrentToken() == Token::kIMPLEMENTS) { | 3246 if (CurrentToken() == Token::kIMPLEMENTS) { |
| 3239 Array& interfaces = Array::Handle(); | 3247 Array& interfaces = Array::Handle(); |
| 3240 const intptr_t interfaces_pos = TokenPos(); | 3248 const intptr_t interfaces_pos = TokenPos(); |
| 3241 interfaces = ParseInterfaceList(super_type); | 3249 interfaces = ParseInterfaceList(super_type); |
| 3242 AddInterfaces(interfaces_pos, cls, interfaces); | 3250 AddInterfaces(interfaces_pos, cls, interfaces); |
| 3243 } | 3251 } |
| 3244 | 3252 |
| 3245 ExpectToken(Token::kLBRACE); | 3253 ExpectToken(Token::kLBRACE); |
| 3246 ClassDesc members(cls, class_name, false, class_pos); | 3254 ClassDesc members(cls, class_name, false, class_pos); |
| 3247 while (CurrentToken() != Token::kRBRACE) { | 3255 while (CurrentToken() != Token::kRBRACE) { |
| 3248 SkipMetadata(); | 3256 SkipMetadata(); |
| 3249 ParseClassMemberDefinition(&members); | 3257 ParseClassMemberDefinition(&members); |
| 3250 } | 3258 } |
| 3251 ExpectToken(Token::kRBRACE); | 3259 ExpectToken(Token::kRBRACE); |
| 3252 | 3260 |
| 3253 if (is_abstract) { | 3261 if (is_abstract) { |
| 3254 cls.set_is_abstract(); | 3262 cls.set_is_abstract(); |
| 3255 } | 3263 } |
| 3256 | 3264 |
| 3257 // Add an implicit constructor if no explicit constructor is present. No | |
| 3258 // implicit constructors are needed for patch classes. | |
| 3259 if (!members.has_constructor() && !is_patch) { | |
| 3260 AddImplicitConstructor(&members); | |
| 3261 } | |
| 3262 CheckConstructors(&members); | 3265 CheckConstructors(&members); |
| 3263 | 3266 |
| 3267 // Need to compute this here since MakeArray() will clear the | |
| 3268 // functions array in members. | |
| 3269 const bool need_implicit_constructor = | |
| 3270 !members.has_constructor() && !is_patch; | |
| 3271 | |
| 3264 Array& array = Array::Handle(); | 3272 Array& array = Array::Handle(); |
| 3265 array = Array::MakeArray(members.fields()); | 3273 array = Array::MakeArray(members.fields()); |
| 3266 cls.SetFields(array); | 3274 cls.SetFields(array); |
| 3267 | 3275 |
| 3268 // Creating a new array for functions marks the class as parsed. | 3276 // Creating a new array for functions marks the class as parsed. |
| 3269 array = Array::MakeArray(members.functions()); | 3277 array = Array::MakeArray(members.functions()); |
| 3270 cls.SetFunctions(array); | 3278 cls.SetFunctions(array); |
| 3271 | 3279 |
| 3280 // Add an implicit constructor if no explicit constructor is present. | |
| 3281 // No implicit constructors are needed for patch classes. | |
| 3282 if (need_implicit_constructor) { | |
| 3283 AddImplicitConstructor(cls); | |
| 3284 } | |
| 3285 | |
| 3272 if (!is_patch) { | 3286 if (!is_patch) { |
| 3273 pending_classes.Add(cls, Heap::kOld); | 3287 pending_classes.Add(cls, Heap::kOld); |
| 3274 } else { | 3288 } else { |
| 3275 // Apply the changes to the patched class looked up above. | 3289 // Apply the changes to the patched class looked up above. |
| 3276 ASSERT(obj.raw() == library_.LookupLocalObject(class_name)); | 3290 ASSERT(obj.raw() == library_.LookupLocalObject(class_name)); |
| 3277 // The patched class must not be finalized yet. | 3291 // The patched class must not be finalized yet. |
| 3278 ASSERT(!Class::Cast(obj).is_finalized()); | 3292 ASSERT(!Class::Cast(obj).is_finalized()); |
| 3279 const char* err_msg = Class::Cast(obj).ApplyPatch(cls); | 3293 const char* err_msg = Class::Cast(obj).ApplyPatch(cls); |
| 3280 if (err_msg != NULL) { | 3294 if (err_msg != NULL) { |
| 3281 ErrorMsg(classname_pos, "applying patch failed with '%s'", err_msg); | 3295 ErrorMsg(classname_pos, "applying patch failed with '%s'", err_msg); |
| 3282 } | 3296 } |
| 3283 } | 3297 } |
| 3284 } | 3298 } |
| 3285 | 3299 |
| 3286 | 3300 |
| 3287 // Add an implicit constructor if no explicit constructor is present. | 3301 // Add an implicit constructor to the given class. |
| 3288 void Parser::AddImplicitConstructor(ClassDesc* class_desc) { | 3302 void Parser::AddImplicitConstructor(const Class& cls) { |
| 3289 // The implicit constructor is unnamed, has no explicit parameter, | 3303 // The implicit constructor is unnamed, has no explicit parameter. |
| 3290 // and contains a supercall in the initializer list. | 3304 String& ctor_name = String::ZoneHandle(cls.Name()); |
| 3291 String& ctor_name = String::ZoneHandle( | 3305 ctor_name = String::Concat(ctor_name, Symbols::Dot()); |
| 3292 String::Concat(class_desc->class_name(), Symbols::Dot())); | |
| 3293 ctor_name = Symbols::New(ctor_name); | 3306 ctor_name = Symbols::New(ctor_name); |
| 3294 // The token position for the implicit constructor is the 'class' | 3307 // To indicate that this is an implicit constructor, we set the |
| 3295 // keyword of the constructor's class. | 3308 // token position is the same as the token position of the class. |
| 3296 Function& ctor = Function::Handle( | 3309 Function& ctor = Function::Handle( |
| 3297 Function::New(ctor_name, | 3310 Function::New(ctor_name, |
| 3298 RawFunction::kConstructor, | 3311 RawFunction::kConstructor, |
| 3299 /* is_static = */ false, | 3312 /* is_static = */ false, |
| 3300 /* is_const = */ false, | 3313 /* is_const = */ false, |
| 3301 /* is_abstract = */ false, | 3314 /* is_abstract = */ false, |
| 3302 /* is_external = */ false, | 3315 /* is_external = */ false, |
| 3303 current_class(), | 3316 cls, |
| 3304 class_desc->token_pos())); | 3317 cls.token_pos())); |
| 3305 ParamList params; | 3318 ParamList params; |
| 3306 // Add implicit 'this' parameter. | 3319 // Add implicit 'this' parameter. We don't care about the specific type |
| 3307 ASSERT(current_class().raw() == ctor.Owner()); | 3320 // and just specify dynamic. |
| 3308 params.AddReceiver(ReceiverType(TokenPos())); | 3321 const Type& receiver_type = Type::Handle(Type::DynamicType()); |
| 3322 params.AddReceiver(&receiver_type); | |
| 3309 // Add implicit parameter for construction phase. | 3323 // Add implicit parameter for construction phase. |
| 3310 params.AddFinalParameter(TokenPos(), | 3324 params.AddFinalParameter(cls.token_pos(), |
| 3311 &Symbols::PhaseParameter(), | 3325 &Symbols::PhaseParameter(), |
| 3312 &Type::ZoneHandle(Type::SmiType())); | 3326 &Type::ZoneHandle(Type::SmiType())); |
| 3313 | 3327 |
| 3314 AddFormalParamsToFunction(¶ms, ctor); | 3328 AddFormalParamsToFunction(¶ms, ctor); |
| 3315 // The body of the constructor cannot modify the type of the constructed | 3329 // The body of the constructor cannot modify the type of the constructed |
| 3316 // instance, which is passed in as the receiver. | 3330 // instance, which is passed in as the receiver. |
| 3317 ctor.set_result_type(*((*params.parameters)[0].type)); | 3331 ctor.set_result_type(receiver_type); |
| 3318 class_desc->AddFunction(ctor); | 3332 cls.AddFunction(ctor); |
| 3319 } | 3333 } |
| 3320 | 3334 |
| 3321 | 3335 |
| 3322 // Check for cycles in constructor redirection. Also check whether a | 3336 // Check for cycles in constructor redirection. Also check whether a |
| 3323 // named constructor collides with the name of another class member. | 3337 // named constructor collides with the name of another class member. |
| 3324 void Parser::CheckConstructors(ClassDesc* class_desc) { | 3338 void Parser::CheckConstructors(ClassDesc* class_desc) { |
| 3325 // Check for cycles in constructor redirection. | 3339 // Check for cycles in constructor redirection. |
| 3326 const GrowableArray<MemberDesc>& members = class_desc->members(); | 3340 const GrowableArray<MemberDesc>& members = class_desc->members(); |
| 3327 for (int i = 0; i < members.length(); i++) { | 3341 for (int i = 0; i < members.length(); i++) { |
| 3328 MemberDesc* member = &members[i]; | 3342 MemberDesc* member = &members[i]; |
| (...skipping 24 matching lines...) Expand all Loading... | |
| 3353 // which the current one redirects, we ignore the unresolved | 3367 // which the current one redirects, we ignore the unresolved |
| 3354 // reference. We'll catch it later when the constructor gets | 3368 // reference. We'll catch it later when the constructor gets |
| 3355 // compiled. | 3369 // compiled. |
| 3356 ctors.Add(member); | 3370 ctors.Add(member); |
| 3357 member = class_desc->LookupMember(*member->redirect_name); | 3371 member = class_desc->LookupMember(*member->redirect_name); |
| 3358 } | 3372 } |
| 3359 } | 3373 } |
| 3360 } | 3374 } |
| 3361 | 3375 |
| 3362 | 3376 |
| 3377 void Parser::ParseMixinTypedef(const GrowableObjectArray& pending_classes) { | |
| 3378 TRACE_PARSER("ParseMixinTypedef"); | |
| 3379 const intptr_t classname_pos = TokenPos(); | |
| 3380 String& class_name = *ExpectUserDefinedTypeIdentifier("class name expected"); | |
| 3381 if (FLAG_trace_parser) { | |
| 3382 OS::Print("toplevel parsing typedef class '%s'\n", class_name.ToCString()); | |
| 3383 } | |
| 3384 const Object& obj = Object::Handle(library_.LookupLocalObject(class_name)); | |
| 3385 if (!obj.IsNull()) { | |
| 3386 ErrorMsg(classname_pos, "'%s' is already defined", | |
| 3387 class_name.ToCString()); | |
| 3388 } | |
| 3389 const Class& mixin_application = | |
| 3390 Class::Handle(Class::New(class_name, script_, classname_pos)); | |
| 3391 library_.AddClass(mixin_application); | |
| 3392 set_current_class(mixin_application); | |
| 3393 ParseTypeParameters(mixin_application); | |
| 3394 ExpectToken(Token::kASSIGN); | |
| 3395 | |
| 3396 if (CurrentToken() == Token::kABSTRACT) { | |
| 3397 mixin_application.set_is_abstract(); | |
| 3398 ConsumeToken(); | |
| 3399 } | |
| 3400 | |
| 3401 const intptr_t supertype_pos = TokenPos(); | |
| 3402 const AbstractType& type = | |
| 3403 AbstractType::Handle(ParseType(ClassFinalizer::kTryResolve)); | |
| 3404 if (type.IsTypeParameter()) { | |
| 3405 ErrorMsg(supertype_pos, | |
| 3406 "class '%s' may not extend type parameter '%s'", | |
| 3407 class_name.ToCString(), | |
| 3408 String::Handle(type.UserVisibleName()).ToCString()); | |
| 3409 } | |
| 3410 Type& mixin_super_type = Type::Handle(); | |
| 3411 mixin_super_type ^= type.raw(); | |
| 3412 | |
| 3413 if (CurrentToken() != Token::kWITH) { | |
| 3414 ErrorMsg("mixin application 'with Type' expected"); | |
| 3415 } | |
| 3416 | |
| 3417 Type& mixin_application_type = Type::Handle(ParseMixins(mixin_super_type)); | |
| 3418 // The result of ParseMixins() is a chain of super classes that is the | |
| 3419 // result of the mixin composition 'S with M1, M2, ...'. The mixin | |
| 3420 // application classes are anonymous (i.e. not registered in the current | |
| 3421 // library). We steal the super type and mixin type from the bottom of | |
| 3422 // the chain and add it to the named mixin application class. The bottom | |
| 3423 // anonymous class in the chain is thrown away. | |
| 3424 const Class& anon_mixin_app_class = | |
| 3425 Class::Handle(mixin_application_type.type_class()); | |
| 3426 mixin_application.set_super_type( | |
| 3427 Type::Handle(anon_mixin_app_class.super_type())); | |
| 3428 mixin_application.set_mixin(Type::Handle(anon_mixin_app_class.mixin())); | |
| 3429 const Array& interfaces = Array::Handle(anon_mixin_app_class.interfaces()); | |
| 3430 mixin_application.set_interfaces(interfaces); | |
| 3431 AddImplicitConstructor(mixin_application); | |
| 3432 | |
| 3433 if (CurrentToken() == Token::kIMPLEMENTS) { | |
| 3434 Array& interfaces = Array::Handle(); | |
| 3435 const intptr_t interfaces_pos = TokenPos(); | |
| 3436 const Type& super_type = Type::Handle(mixin_application.super_type()); | |
| 3437 interfaces = ParseInterfaceList(super_type); | |
| 3438 AddInterfaces(interfaces_pos, mixin_application, interfaces); | |
| 3439 } | |
| 3440 | |
| 3441 pending_classes.Add(mixin_application, Heap::kOld); | |
| 3442 ExpectSemicolon(); | |
| 3443 } | |
| 3444 | |
| 3445 | |
| 3363 // Look ahead to detect if we are seeing ident [ TypeParameters ] "(". | 3446 // Look ahead to detect if we are seeing ident [ TypeParameters ] "(". |
| 3364 // We need this lookahead to distinguish between the optional return type | 3447 // We need this lookahead to distinguish between the optional return type |
| 3365 // and the alias name of a function type alias. | 3448 // and the alias name of a function type alias. |
| 3366 // Token position remains unchanged. | 3449 // Token position remains unchanged. |
| 3367 bool Parser::IsFunctionTypeAliasName() { | 3450 bool Parser::IsFunctionTypeAliasName() { |
| 3368 if (IsIdentifier() && (LookaheadToken(1) == Token::kLPAREN)) { | 3451 if (IsIdentifier() && (LookaheadToken(1) == Token::kLPAREN)) { |
| 3369 return true; | 3452 return true; |
| 3370 } | 3453 } |
| 3371 const intptr_t saved_pos = TokenPos(); | 3454 const intptr_t saved_pos = TokenPos(); |
| 3372 bool is_alias_name = false; | 3455 bool is_alias_name = false; |
| 3373 if (IsIdentifier() && (LookaheadToken(1) == Token::kLT)) { | 3456 if (IsIdentifier() && (LookaheadToken(1) == Token::kLT)) { |
| 3374 ConsumeToken(); | 3457 ConsumeToken(); |
| 3375 if (TryParseTypeParameter() && (CurrentToken() == Token::kLPAREN)) { | 3458 if (TryParseTypeParameter() && (CurrentToken() == Token::kLPAREN)) { |
| 3376 is_alias_name = true; | 3459 is_alias_name = true; |
| 3377 } | 3460 } |
| 3378 } | 3461 } |
| 3379 SetPosition(saved_pos); | 3462 SetPosition(saved_pos); |
| 3380 return is_alias_name; | 3463 return is_alias_name; |
| 3381 } | 3464 } |
| 3382 | 3465 |
| 3383 | 3466 |
| 3384 void Parser::ParseFunctionTypeAlias( | 3467 // Look ahead to detect if we are seeing ident [ TypeParameters ] "=". |
| 3385 const GrowableObjectArray& pending_classes) { | 3468 // Token position remains unchanged. |
| 3386 TRACE_PARSER("ParseFunctionTypeAlias"); | 3469 bool Parser::IsMixinTypedef() { |
| 3470 if (IsIdentifier() && (LookaheadToken(1) == Token::kASSIGN)) { | |
| 3471 return true; | |
| 3472 } | |
| 3473 const intptr_t saved_pos = TokenPos(); | |
| 3474 bool is_mixin_def = false; | |
| 3475 if (IsIdentifier() && (LookaheadToken(1) == Token::kLT)) { | |
| 3476 ConsumeToken(); | |
| 3477 if (TryParseTypeParameter() && (CurrentToken() == Token::kASSIGN)) { | |
| 3478 is_mixin_def = true; | |
| 3479 } | |
| 3480 } | |
| 3481 SetPosition(saved_pos); | |
| 3482 return is_mixin_def; | |
| 3483 } | |
| 3484 | |
| 3485 | |
| 3486 void Parser::ParseTypedef(const GrowableObjectArray& pending_classes) { | |
| 3487 TRACE_PARSER("ParseTypedef"); | |
| 3387 ExpectToken(Token::kTYPEDEF); | 3488 ExpectToken(Token::kTYPEDEF); |
| 3388 | 3489 |
| 3490 if (IsMixinTypedef()) { | |
| 3491 ParseMixinTypedef(pending_classes); | |
| 3492 return; | |
| 3493 } | |
| 3494 | |
| 3389 // Parse the result type of the function type. | 3495 // Parse the result type of the function type. |
| 3390 AbstractType& result_type = Type::Handle(Type::DynamicType()); | 3496 AbstractType& result_type = Type::Handle(Type::DynamicType()); |
| 3391 if (CurrentToken() == Token::kVOID) { | 3497 if (CurrentToken() == Token::kVOID) { |
| 3392 ConsumeToken(); | 3498 ConsumeToken(); |
| 3393 result_type = Type::VoidType(); | 3499 result_type = Type::VoidType(); |
| 3394 } else if (!IsFunctionTypeAliasName()) { | 3500 } else if (!IsFunctionTypeAliasName()) { |
| 3395 // Type annotations in typedef are never ignored, even in unchecked mode. | 3501 // Type annotations in typedef are never ignored, even in unchecked mode. |
| 3396 // Wait until we have an owner class before resolving the result type. | 3502 // Wait until we have an owner class before resolving the result type. |
| 3397 result_type = ParseType(ClassFinalizer::kDoNotResolve); | 3503 result_type = ParseType(ClassFinalizer::kDoNotResolve); |
| 3398 } | 3504 } |
| (...skipping 261 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 3660 return NewTypeArguments(types); | 3766 return NewTypeArguments(types); |
| 3661 } | 3767 } |
| 3662 } | 3768 } |
| 3663 return TypeArguments::null(); | 3769 return TypeArguments::null(); |
| 3664 } | 3770 } |
| 3665 | 3771 |
| 3666 | 3772 |
| 3667 // Parse and return an array of interface types. | 3773 // Parse and return an array of interface types. |
| 3668 RawArray* Parser::ParseInterfaceList(const Type& super_type) { | 3774 RawArray* Parser::ParseInterfaceList(const Type& super_type) { |
| 3669 TRACE_PARSER("ParseInterfaceList"); | 3775 TRACE_PARSER("ParseInterfaceList"); |
| 3670 ASSERT((CurrentToken() == Token::kIMPLEMENTS) || | 3776 ASSERT(CurrentToken() == Token::kIMPLEMENTS); |
| 3671 (CurrentToken() == Token::kEXTENDS)); | |
| 3672 const GrowableObjectArray& interfaces = | 3777 const GrowableObjectArray& interfaces = |
| 3673 GrowableObjectArray::Handle(GrowableObjectArray::New()); | 3778 GrowableObjectArray::Handle(GrowableObjectArray::New()); |
| 3674 String& interface_name = String::Handle(); | 3779 String& interface_name = String::Handle(); |
| 3675 AbstractType& interface = AbstractType::Handle(); | 3780 AbstractType& interface = AbstractType::Handle(); |
| 3676 String& other_name = String::Handle(); | 3781 String& other_name = String::Handle(); |
| 3677 AbstractType& other_interface = AbstractType::Handle(); | 3782 AbstractType& other_interface = AbstractType::Handle(); |
| 3678 const String& super_type_name = String::Handle(super_type.Name()); | 3783 const String& super_type_name = String::Handle(super_type.Name()); |
| 3679 do { | 3784 do { |
| 3680 ConsumeToken(); | 3785 ConsumeToken(); |
| 3681 intptr_t interface_pos = TokenPos(); | 3786 intptr_t interface_pos = TokenPos(); |
| 3682 interface = ParseType(ClassFinalizer::kTryResolve); | 3787 interface = ParseType(ClassFinalizer::kTryResolve); |
| 3683 interface_name = interface.UserVisibleName(); | 3788 interface_name = interface.UserVisibleName(); |
| 3684 if (interface_name.Equals(super_type_name)) { | 3789 if (interface_name.Equals(super_type_name)) { |
| 3790 // TODO(hausner): I think this check is not necessary. There is | |
| 3791 // no such restriction. If the check is removed, the 'super_type' | |
| 3792 // parameter to this function can be eliminated. | |
| 3685 ErrorMsg(interface_pos, "class may not extend and implement '%s'", | 3793 ErrorMsg(interface_pos, "class may not extend and implement '%s'", |
| 3686 interface_name.ToCString()); | 3794 interface_name.ToCString()); |
| 3687 } | 3795 } |
| 3688 for (int i = 0; i < interfaces.Length(); i++) { | 3796 for (int i = 0; i < interfaces.Length(); i++) { |
| 3689 other_interface ^= interfaces.At(i); | 3797 other_interface ^= interfaces.At(i); |
| 3690 other_name = other_interface.Name(); | 3798 other_name = other_interface.Name(); |
| 3691 if (interface_name.Equals(other_name)) { | 3799 if (interface_name.Equals(other_name)) { |
| 3692 ErrorMsg(interface_pos, "duplicate interface '%s'", | 3800 ErrorMsg(interface_pos, "duplicate interface '%s'", |
| 3693 interface_name.ToCString()); | 3801 interface_name.ToCString()); |
| 3694 } | 3802 } |
| 3695 } | 3803 } |
| 3696 interfaces.Add(interface); | 3804 interfaces.Add(interface); |
| 3697 } while (CurrentToken() == Token::kCOMMA); | 3805 } while (CurrentToken() == Token::kCOMMA); |
| 3698 return Array::MakeArray(interfaces); | 3806 return Array::MakeArray(interfaces); |
| 3699 } | 3807 } |
| 3700 | 3808 |
| 3701 | 3809 |
| 3810 RawType* Parser::ParseMixins(const Type& super_type) { | |
| 3811 TRACE_PARSER("ParseMixins"); | |
| 3812 ASSERT(CurrentToken() == Token::kWITH); | |
| 3813 | |
| 3814 // TODO(hausner): Remove this restriction. | |
| 3815 if (super_type.arguments() != AbstractTypeArguments::null()) { | |
| 3816 ErrorMsg(super_type.token_pos(), | |
| 3817 "super class of mixin may not have type arguments"); | |
| 3818 } | |
| 3819 | |
| 3820 AbstractType& mixin_type = AbstractType::Handle(); | |
| 3821 AbstractTypeArguments& mixin_type_arguments = | |
| 3822 AbstractTypeArguments::Handle(); | |
| 3823 Class& mixin_application = Class::Handle(); | |
| 3824 Type& mixin_application_type = Type::Handle(); | |
| 3825 Type& mixin_super_type = Type::Handle(super_type.raw()); | |
| 3826 Array& mixin_application_interfaces = Array::Handle(); | |
| 3827 const TypeArguments& no_type_arguments = TypeArguments::Handle(); | |
| 3828 do { | |
| 3829 ConsumeToken(); | |
| 3830 const intptr_t mixin_pos = TokenPos(); | |
| 3831 mixin_type = ParseType(ClassFinalizer::kTryResolve); | |
| 3832 if (mixin_type.IsTypeParameter()) { | |
| 3833 ErrorMsg(mixin_pos, | |
| 3834 "mixin type '%s' may not be a type parameter", | |
| 3835 String::Handle(mixin_type.UserVisibleName()).ToCString()); | |
| 3836 } | |
| 3837 // TODO(hausner): Remove this check once we handle mixins with type | |
| 3838 // arguments. | |
| 3839 mixin_type_arguments = mixin_type.arguments(); | |
| 3840 if (!mixin_type_arguments.IsNull()) { | |
| 3841 ErrorMsg(mixin_pos, | |
| 3842 "mixin type '%s' may not have type arguments", | |
| 3843 String::Handle(mixin_type.UserVisibleName()).ToCString()); | |
| 3844 } | |
|
siva
2013/02/13 01:34:37
How do you handle 'S with M,N,M' or 'S with M,M' i
hausner
2013/02/13 19:58:14
I discussed that with Gilad. He says it's perfectl
| |
| 3845 | |
| 3846 // The name of the mixin application class is a combination of | |
| 3847 // the superclass and mixin class. | |
| 3848 String& mixin_app_name = String::Handle(); | |
| 3849 mixin_app_name = mixin_super_type.Name(); | |
| 3850 mixin_app_name = String::Concat(mixin_app_name, | |
| 3851 String::Handle(String::New("&"))); | |
|
siva
2013/02/13 01:34:37
Maybe add a Symbols::Ampersand() method similar to
hausner
2013/02/13 19:58:14
I thought about this and didn't think this is used
| |
| 3852 mixin_app_name = String::Concat(mixin_app_name, | |
| 3853 String::Handle(mixin_type.Name())); | |
| 3854 mixin_app_name = Symbols::New(mixin_app_name); | |
| 3855 | |
| 3856 mixin_application = Class::New(mixin_app_name, script_, mixin_pos); | |
| 3857 mixin_application.set_super_type(mixin_super_type); | |
| 3858 mixin_application.set_mixin(Type::Cast(mixin_type)); | |
| 3859 mixin_application.set_library(library_); | |
| 3860 AddImplicitConstructor(mixin_application); | |
| 3861 // Add the mixin type to the interfaces that the mixin application | |
| 3862 // class implements. This is necessary so that type tests work. | |
| 3863 mixin_application_interfaces = Array::New(1); | |
| 3864 mixin_application_interfaces.SetAt(0, mixin_type); | |
| 3865 mixin_application.set_interfaces(mixin_application_interfaces); | |
| 3866 | |
| 3867 // TODO(hausner): Need to support type arguments. | |
| 3868 mixin_application_type = Type::New(mixin_application, | |
| 3869 no_type_arguments, | |
| 3870 Scanner::kDummyTokenIndex); | |
| 3871 mixin_super_type = mixin_application_type.raw(); | |
| 3872 } while (CurrentToken() == Token::kCOMMA); | |
| 3873 return mixin_application_type.raw(); | |
| 3874 } | |
| 3875 | |
| 3876 | |
| 3702 // Add 'interface' to 'interface_list' if it is not already in the list. | 3877 // Add 'interface' to 'interface_list' if it is not already in the list. |
| 3703 // An error is reported if the interface conflicts with an interface already in | 3878 // An error is reported if the interface conflicts with an interface already in |
| 3704 // the list with the same class and same type arguments. | 3879 // the list with the same class and same type arguments. |
| 3705 void Parser::AddInterfaceIfUnique(intptr_t interfaces_pos, | 3880 void Parser::AddInterfaceIfUnique(intptr_t interfaces_pos, |
| 3706 const GrowableObjectArray& interface_list, | 3881 const GrowableObjectArray& interface_list, |
| 3707 const AbstractType& interface) { | 3882 const AbstractType& interface) { |
| 3708 String& interface_name = String::Handle(interface.Name()); | 3883 String& interface_name = String::Handle(interface.Name()); |
| 3709 String& existing_interface_name = String::Handle(); | 3884 String& existing_interface_name = String::Handle(); |
| 3710 AbstractType& other_interface = AbstractType::Handle(); | 3885 AbstractType& other_interface = AbstractType::Handle(); |
| 3711 for (intptr_t i = 0; i < interface_list.Length(); i++) { | 3886 for (intptr_t i = 0; i < interface_list.Length(); i++) { |
| (...skipping 714 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 4426 } | 4601 } |
| 4427 | 4602 |
| 4428 while (true) { | 4603 while (true) { |
| 4429 set_current_class(Class::Handle()); // No current class. | 4604 set_current_class(Class::Handle()); // No current class. |
| 4430 SkipMetadata(); | 4605 SkipMetadata(); |
| 4431 if (CurrentToken() == Token::kCLASS) { | 4606 if (CurrentToken() == Token::kCLASS) { |
| 4432 ParseClassDefinition(pending_classes); | 4607 ParseClassDefinition(pending_classes); |
| 4433 } else if ((CurrentToken() == Token::kTYPEDEF) && | 4608 } else if ((CurrentToken() == Token::kTYPEDEF) && |
| 4434 (LookaheadToken(1) != Token::kLPAREN)) { | 4609 (LookaheadToken(1) != Token::kLPAREN)) { |
| 4435 set_current_class(toplevel_class); | 4610 set_current_class(toplevel_class); |
| 4436 ParseFunctionTypeAlias(pending_classes); | 4611 ParseTypedef(pending_classes); |
| 4437 } else if ((CurrentToken() == Token::kABSTRACT) && | 4612 } else if ((CurrentToken() == Token::kABSTRACT) && |
| 4438 (LookaheadToken(1) == Token::kCLASS)) { | 4613 (LookaheadToken(1) == Token::kCLASS)) { |
| 4439 ParseClassDefinition(pending_classes); | 4614 ParseClassDefinition(pending_classes); |
| 4440 } else if (is_patch_source() && IsLiteral("patch") && | 4615 } else if (is_patch_source() && IsLiteral("patch") && |
| 4441 (LookaheadToken(1) == Token::kCLASS)) { | 4616 (LookaheadToken(1) == Token::kCLASS)) { |
| 4442 ParseClassDefinition(pending_classes); | 4617 ParseClassDefinition(pending_classes); |
| 4443 } else { | 4618 } else { |
| 4444 set_current_class(toplevel_class); | 4619 set_current_class(toplevel_class); |
| 4445 if (IsVariableDeclaration()) { | 4620 if (IsVariableDeclaration()) { |
| 4446 ParseTopLevelVariable(&top_level); | 4621 ParseTopLevelVariable(&top_level); |
| (...skipping 4996 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 9443 CurrentToken() == Token::kLBRACE) { | 9618 CurrentToken() == Token::kLBRACE) { |
| 9444 primary = ParseCompoundLiteral(); | 9619 primary = ParseCompoundLiteral(); |
| 9445 } else if (CurrentToken() == Token::kSUPER) { | 9620 } else if (CurrentToken() == Token::kSUPER) { |
| 9446 if (current_function().is_static()) { | 9621 if (current_function().is_static()) { |
| 9447 ErrorMsg("cannot access superclass from static method"); | 9622 ErrorMsg("cannot access superclass from static method"); |
| 9448 } | 9623 } |
| 9449 if (current_class().SuperClass() == Class::null()) { | 9624 if (current_class().SuperClass() == Class::null()) { |
| 9450 ErrorMsg("class '%s' does not have a superclass", | 9625 ErrorMsg("class '%s' does not have a superclass", |
| 9451 String::Handle(current_class().Name()).ToCString()); | 9626 String::Handle(current_class().Name()).ToCString()); |
| 9452 } | 9627 } |
| 9628 if (current_class().mixin() != Type::null()) { | |
| 9629 const Type& mixin_type = Type::Handle(current_class().mixin()); | |
| 9630 if (mixin_type.type_class() == current_function().origin()) { | |
| 9631 ErrorMsg("class '%s' may not use super " | |
| 9632 "because it is used as mixin class", | |
| 9633 String::Handle(current_class().Name()).ToCString()); | |
| 9634 } | |
| 9635 } | |
| 9453 ConsumeToken(); | 9636 ConsumeToken(); |
| 9454 if (CurrentToken() == Token::kPERIOD) { | 9637 if (CurrentToken() == Token::kPERIOD) { |
| 9455 ConsumeToken(); | 9638 ConsumeToken(); |
| 9456 const String& ident = *ExpectIdentifier("identifier expected"); | 9639 const String& ident = *ExpectIdentifier("identifier expected"); |
| 9457 if (CurrentToken() == Token::kLPAREN) { | 9640 if (CurrentToken() == Token::kLPAREN) { |
| 9458 primary = ParseSuperCall(ident); | 9641 primary = ParseSuperCall(ident); |
| 9459 } else { | 9642 } else { |
| 9460 primary = ParseSuperFieldAccess(ident); | 9643 primary = ParseSuperFieldAccess(ident); |
| 9461 } | 9644 } |
| 9462 } else if ((CurrentToken() == Token::kLBRACK) || | 9645 } else if ((CurrentToken() == Token::kLBRACK) || |
| (...skipping 321 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 9784 void Parser::SkipQualIdent() { | 9967 void Parser::SkipQualIdent() { |
| 9785 ASSERT(IsIdentifier()); | 9968 ASSERT(IsIdentifier()); |
| 9786 ConsumeToken(); | 9969 ConsumeToken(); |
| 9787 if (CurrentToken() == Token::kPERIOD) { | 9970 if (CurrentToken() == Token::kPERIOD) { |
| 9788 ConsumeToken(); // Consume the kPERIOD token. | 9971 ConsumeToken(); // Consume the kPERIOD token. |
| 9789 ExpectIdentifier("identifier expected after '.'"); | 9972 ExpectIdentifier("identifier expected after '.'"); |
| 9790 } | 9973 } |
| 9791 } | 9974 } |
| 9792 | 9975 |
| 9793 } // namespace dart | 9976 } // namespace dart |
| OLD | NEW |