| 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 273 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 284 : script_(script), | 284 : script_(script), |
| 285 tokens_iterator_(TokenStream::Handle(script.tokens()), token_position), | 285 tokens_iterator_(TokenStream::Handle(script.tokens()), token_position), |
| 286 token_kind_(Token::kILLEGAL), | 286 token_kind_(Token::kILLEGAL), |
| 287 current_block_(NULL), | 287 current_block_(NULL), |
| 288 is_top_level_(false), | 288 is_top_level_(false), |
| 289 current_member_(NULL), | 289 current_member_(NULL), |
| 290 allow_function_literals_(true), | 290 allow_function_literals_(true), |
| 291 parsed_function_(parsed_function), | 291 parsed_function_(parsed_function), |
| 292 innermost_function_(Function::Handle(parsed_function->function().raw())), | 292 innermost_function_(Function::Handle(parsed_function->function().raw())), |
| 293 current_class_(Class::Handle(parsed_function->function().Owner())), | 293 current_class_(Class::Handle(parsed_function->function().Owner())), |
| 294 library_(Library::Handle(current_class_.library())), | 294 library_(Library::Handle(Class::Handle( |
| 295 parsed_function->function().origin()).library())), |
| 295 try_blocks_list_(NULL) { | 296 try_blocks_list_(NULL) { |
| 296 ASSERT(tokens_iterator_.IsValid()); | 297 ASSERT(tokens_iterator_.IsValid()); |
| 297 ASSERT(!current_function().IsNull()); | 298 ASSERT(!current_function().IsNull()); |
| 298 if (FLAG_enable_type_checks) { | 299 if (FLAG_enable_type_checks) { |
| 299 EnsureExpressionTemp(); | 300 EnsureExpressionTemp(); |
| 300 } | 301 } |
| 301 } | 302 } |
| 302 | 303 |
| 303 | 304 |
| 304 bool Parser::SetAllowFunctionLiterals(bool value) { | 305 bool Parser::SetAllowFunctionLiterals(bool value) { |
| (...skipping 1529 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1834 if (!f.is_static() && f.has_initializer()) { | 1835 if (!f.is_static() && f.has_initializer()) { |
| 1835 Field& field = Field::ZoneHandle(); | 1836 Field& field = Field::ZoneHandle(); |
| 1836 field ^= fields.At(i); | 1837 field ^= fields.At(i); |
| 1837 if (field.is_final()) { | 1838 if (field.is_final()) { |
| 1838 // Final fields with initializer expression may not be initialized | 1839 // Final fields with initializer expression may not be initialized |
| 1839 // again by constructors. Remember that this field is already | 1840 // again by constructors. Remember that this field is already |
| 1840 // initialized. | 1841 // initialized. |
| 1841 initialized_fields->Add(&field); | 1842 initialized_fields->Add(&field); |
| 1842 } | 1843 } |
| 1843 intptr_t field_pos = field.token_pos(); | 1844 intptr_t field_pos = field.token_pos(); |
| 1845 if (current_class().raw() != field.origin()) { |
| 1846 const Class& origin_class = Class::Handle(field.origin()); |
| 1847 if (origin_class.library() != library_.raw()) { |
| 1848 ErrorMsg("Cannot handle initialized mixin field '%s'" |
| 1849 "from imported library\n", field.ToCString()); |
| 1850 } |
| 1851 } |
| 1844 SetPosition(field_pos); | 1852 SetPosition(field_pos); |
| 1845 ASSERT(IsIdentifier()); | 1853 ASSERT(IsIdentifier()); |
| 1846 ConsumeToken(); | 1854 ConsumeToken(); |
| 1847 ExpectToken(Token::kASSIGN); | 1855 ExpectToken(Token::kASSIGN); |
| 1848 | 1856 |
| 1849 AstNode* init_expr = NULL; | 1857 AstNode* init_expr = NULL; |
| 1850 if (field.is_const()) { | 1858 if (field.is_const()) { |
| 1851 init_expr = ParseConstExpr(); | 1859 init_expr = ParseConstExpr(); |
| 1852 } else { | 1860 } else { |
| 1853 init_expr = ParseExpr(kAllowConst, kConsumeCascades); | 1861 init_expr = ParseExpr(kAllowConst, kConsumeCascades); |
| (...skipping 172 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2026 SequenceNode* Parser::ParseConstructor(const Function& func, | 2034 SequenceNode* Parser::ParseConstructor(const Function& func, |
| 2027 Array& default_parameter_values) { | 2035 Array& default_parameter_values) { |
| 2028 TRACE_PARSER("ParseConstructor"); | 2036 TRACE_PARSER("ParseConstructor"); |
| 2029 ASSERT(func.IsConstructor()); | 2037 ASSERT(func.IsConstructor()); |
| 2030 ASSERT(!func.IsFactory()); | 2038 ASSERT(!func.IsFactory()); |
| 2031 ASSERT(!func.is_static()); | 2039 ASSERT(!func.is_static()); |
| 2032 ASSERT(!func.IsLocalFunction()); | 2040 ASSERT(!func.IsLocalFunction()); |
| 2033 const Class& cls = Class::Handle(func.Owner()); | 2041 const Class& cls = Class::Handle(func.Owner()); |
| 2034 ASSERT(!cls.IsNull()); | 2042 ASSERT(!cls.IsNull()); |
| 2035 | 2043 |
| 2036 if (CurrentToken() == Token::kCLASS) { | 2044 if (func.IsImplicitConstructor()) { |
| 2037 // Special case: implicit constructor. | 2045 // Special case: implicit constructor. |
| 2038 // The parser adds an implicit default constructor when a class | 2046 // The parser adds an implicit default constructor when a class |
| 2039 // does not have any explicit constructor or factory (see | 2047 // does not have any explicit constructor or factory (see |
| 2040 // Parser::AddImplicitConstructor). The token position of this implicit | 2048 // Parser::AddImplicitConstructor). |
| 2041 // constructor points to the 'class' keyword, which is followed | |
| 2042 // by the name of the class (which is also the constructor name). | |
| 2043 // There is no source text to parse. We just build the | 2049 // There is no source text to parse. We just build the |
| 2044 // sequence node by hand. | 2050 // sequence node by hand. |
| 2045 return MakeImplicitConstructor(func); | 2051 return MakeImplicitConstructor(func); |
| 2046 } | 2052 } |
| 2047 | 2053 |
| 2048 OpenFunctionBlock(func); | 2054 OpenFunctionBlock(func); |
| 2049 ParamList params; | 2055 ParamList params; |
| 2050 const bool allow_explicit_default_values = true; | 2056 const bool allow_explicit_default_values = true; |
| 2051 ASSERT(CurrentToken() == Token::kLPAREN); | 2057 ASSERT(CurrentToken() == Token::kLPAREN); |
| 2052 | 2058 |
| (...skipping 1184 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3237 const intptr_t type_pos = TokenPos(); | 3243 const intptr_t type_pos = TokenPos(); |
| 3238 const AbstractType& type = AbstractType::Handle( | 3244 const AbstractType& type = AbstractType::Handle( |
| 3239 ParseType(ClassFinalizer::kTryResolve)); | 3245 ParseType(ClassFinalizer::kTryResolve)); |
| 3240 if (type.IsTypeParameter()) { | 3246 if (type.IsTypeParameter()) { |
| 3241 ErrorMsg(type_pos, | 3247 ErrorMsg(type_pos, |
| 3242 "class '%s' may not extend type parameter '%s'", | 3248 "class '%s' may not extend type parameter '%s'", |
| 3243 class_name.ToCString(), | 3249 class_name.ToCString(), |
| 3244 String::Handle(type.UserVisibleName()).ToCString()); | 3250 String::Handle(type.UserVisibleName()).ToCString()); |
| 3245 } | 3251 } |
| 3246 super_type ^= type.raw(); | 3252 super_type ^= type.raw(); |
| 3253 if (CurrentToken() == Token::kWITH) { |
| 3254 super_type = ParseMixins(super_type); |
| 3255 } |
| 3247 } else { | 3256 } else { |
| 3248 // No extends clause: Implicitly extend Object. | 3257 // No extends clause: implicitly extend Object. |
| 3249 super_type = Type::ObjectType(); | 3258 super_type = Type::ObjectType(); |
| 3250 } | 3259 } |
| 3251 ASSERT(!super_type.IsNull()); | 3260 ASSERT(!super_type.IsNull()); |
| 3252 cls.set_super_type(super_type); | 3261 cls.set_super_type(super_type); |
| 3253 | 3262 |
| 3254 if (CurrentToken() == Token::kIMPLEMENTS) { | 3263 if (CurrentToken() == Token::kIMPLEMENTS) { |
| 3255 Array& interfaces = Array::Handle(); | 3264 Array& interfaces = Array::Handle(); |
| 3256 const intptr_t interfaces_pos = TokenPos(); | 3265 const intptr_t interfaces_pos = TokenPos(); |
| 3257 interfaces = ParseInterfaceList(super_type); | 3266 interfaces = ParseInterfaceList(super_type); |
| 3258 AddInterfaces(interfaces_pos, cls, interfaces); | 3267 AddInterfaces(interfaces_pos, cls, interfaces); |
| 3259 } | 3268 } |
| 3260 | 3269 |
| 3261 ExpectToken(Token::kLBRACE); | 3270 ExpectToken(Token::kLBRACE); |
| 3262 ClassDesc members(cls, class_name, false, class_pos); | 3271 ClassDesc members(cls, class_name, false, class_pos); |
| 3263 while (CurrentToken() != Token::kRBRACE) { | 3272 while (CurrentToken() != Token::kRBRACE) { |
| 3264 SkipMetadata(); | 3273 SkipMetadata(); |
| 3265 ParseClassMemberDefinition(&members); | 3274 ParseClassMemberDefinition(&members); |
| 3266 } | 3275 } |
| 3267 ExpectToken(Token::kRBRACE); | 3276 ExpectToken(Token::kRBRACE); |
| 3268 | 3277 |
| 3269 if (is_abstract) { | 3278 if (is_abstract) { |
| 3270 cls.set_is_abstract(); | 3279 cls.set_is_abstract(); |
| 3271 } | 3280 } |
| 3272 | 3281 |
| 3273 // Add an implicit constructor if no explicit constructor is present. No | |
| 3274 // implicit constructors are needed for patch classes. | |
| 3275 if (!members.has_constructor() && !is_patch) { | |
| 3276 AddImplicitConstructor(&members); | |
| 3277 } | |
| 3278 CheckConstructors(&members); | 3282 CheckConstructors(&members); |
| 3279 | 3283 |
| 3284 // Need to compute this here since MakeArray() will clear the |
| 3285 // functions array in members. |
| 3286 const bool need_implicit_constructor = |
| 3287 !members.has_constructor() && !is_patch; |
| 3288 |
| 3280 Array& array = Array::Handle(); | 3289 Array& array = Array::Handle(); |
| 3281 array = Array::MakeArray(members.fields()); | 3290 array = Array::MakeArray(members.fields()); |
| 3282 cls.SetFields(array); | 3291 cls.SetFields(array); |
| 3283 | 3292 |
| 3284 // Creating a new array for functions marks the class as parsed. | 3293 // Creating a new array for functions marks the class as parsed. |
| 3285 array = Array::MakeArray(members.functions()); | 3294 array = Array::MakeArray(members.functions()); |
| 3286 cls.SetFunctions(array); | 3295 cls.SetFunctions(array); |
| 3287 | 3296 |
| 3297 // Add an implicit constructor if no explicit constructor is present. |
| 3298 // No implicit constructors are needed for patch classes. |
| 3299 if (need_implicit_constructor) { |
| 3300 AddImplicitConstructor(cls); |
| 3301 } |
| 3302 |
| 3288 if (!is_patch) { | 3303 if (!is_patch) { |
| 3289 pending_classes.Add(cls, Heap::kOld); | 3304 pending_classes.Add(cls, Heap::kOld); |
| 3290 } else { | 3305 } else { |
| 3291 // Apply the changes to the patched class looked up above. | 3306 // Apply the changes to the patched class looked up above. |
| 3292 ASSERT(obj.raw() == library_.LookupLocalObject(class_name)); | 3307 ASSERT(obj.raw() == library_.LookupLocalObject(class_name)); |
| 3293 // The patched class must not be finalized yet. | 3308 // The patched class must not be finalized yet. |
| 3294 ASSERT(!Class::Cast(obj).is_finalized()); | 3309 ASSERT(!Class::Cast(obj).is_finalized()); |
| 3295 const char* err_msg = Class::Cast(obj).ApplyPatch(cls); | 3310 const char* err_msg = Class::Cast(obj).ApplyPatch(cls); |
| 3296 if (err_msg != NULL) { | 3311 if (err_msg != NULL) { |
| 3297 ErrorMsg(classname_pos, "applying patch failed with '%s'", err_msg); | 3312 ErrorMsg(classname_pos, "applying patch failed with '%s'", err_msg); |
| 3298 } | 3313 } |
| 3299 } | 3314 } |
| 3300 } | 3315 } |
| 3301 | 3316 |
| 3302 | 3317 |
| 3303 // Add an implicit constructor if no explicit constructor is present. | 3318 // Add an implicit constructor to the given class. |
| 3304 void Parser::AddImplicitConstructor(ClassDesc* class_desc) { | 3319 void Parser::AddImplicitConstructor(const Class& cls) { |
| 3305 // The implicit constructor is unnamed, has no explicit parameter, | 3320 // The implicit constructor is unnamed, has no explicit parameter. |
| 3306 // and contains a supercall in the initializer list. | 3321 String& ctor_name = String::ZoneHandle(cls.Name()); |
| 3307 String& ctor_name = String::ZoneHandle( | 3322 ctor_name = String::Concat(ctor_name, Symbols::Dot()); |
| 3308 String::Concat(class_desc->class_name(), Symbols::Dot())); | |
| 3309 ctor_name = Symbols::New(ctor_name); | 3323 ctor_name = Symbols::New(ctor_name); |
| 3310 // The token position for the implicit constructor is the 'class' | 3324 // To indicate that this is an implicit constructor, we set the |
| 3311 // keyword of the constructor's class. | 3325 // token position is the same as the token position of the class. |
| 3312 Function& ctor = Function::Handle( | 3326 Function& ctor = Function::Handle( |
| 3313 Function::New(ctor_name, | 3327 Function::New(ctor_name, |
| 3314 RawFunction::kConstructor, | 3328 RawFunction::kConstructor, |
| 3315 /* is_static = */ false, | 3329 /* is_static = */ false, |
| 3316 /* is_const = */ false, | 3330 /* is_const = */ false, |
| 3317 /* is_abstract = */ false, | 3331 /* is_abstract = */ false, |
| 3318 /* is_external = */ false, | 3332 /* is_external = */ false, |
| 3319 current_class(), | 3333 cls, |
| 3320 class_desc->token_pos())); | 3334 cls.token_pos())); |
| 3321 ParamList params; | 3335 ParamList params; |
| 3322 // Add implicit 'this' parameter. | 3336 // Add implicit 'this' parameter. We don't care about the specific type |
| 3323 ASSERT(current_class().raw() == ctor.Owner()); | 3337 // and just specify dynamic. |
| 3324 params.AddReceiver(ReceiverType(TokenPos())); | 3338 const Type& receiver_type = Type::Handle(Type::DynamicType()); |
| 3339 params.AddReceiver(&receiver_type); |
| 3325 // Add implicit parameter for construction phase. | 3340 // Add implicit parameter for construction phase. |
| 3326 params.AddFinalParameter(TokenPos(), | 3341 params.AddFinalParameter(cls.token_pos(), |
| 3327 &Symbols::PhaseParameter(), | 3342 &Symbols::PhaseParameter(), |
| 3328 &Type::ZoneHandle(Type::SmiType())); | 3343 &Type::ZoneHandle(Type::SmiType())); |
| 3329 | 3344 |
| 3330 AddFormalParamsToFunction(¶ms, ctor); | 3345 AddFormalParamsToFunction(¶ms, ctor); |
| 3331 // The body of the constructor cannot modify the type of the constructed | 3346 // The body of the constructor cannot modify the type of the constructed |
| 3332 // instance, which is passed in as the receiver. | 3347 // instance, which is passed in as the receiver. |
| 3333 ctor.set_result_type(*((*params.parameters)[0].type)); | 3348 ctor.set_result_type(receiver_type); |
| 3334 class_desc->AddFunction(ctor); | 3349 cls.AddFunction(ctor); |
| 3335 } | 3350 } |
| 3336 | 3351 |
| 3337 | 3352 |
| 3338 // Check for cycles in constructor redirection. Also check whether a | 3353 // Check for cycles in constructor redirection. Also check whether a |
| 3339 // named constructor collides with the name of another class member. | 3354 // named constructor collides with the name of another class member. |
| 3340 void Parser::CheckConstructors(ClassDesc* class_desc) { | 3355 void Parser::CheckConstructors(ClassDesc* class_desc) { |
| 3341 // Check for cycles in constructor redirection. | 3356 // Check for cycles in constructor redirection. |
| 3342 const GrowableArray<MemberDesc>& members = class_desc->members(); | 3357 const GrowableArray<MemberDesc>& members = class_desc->members(); |
| 3343 for (int i = 0; i < members.length(); i++) { | 3358 for (int i = 0; i < members.length(); i++) { |
| 3344 MemberDesc* member = &members[i]; | 3359 MemberDesc* member = &members[i]; |
| (...skipping 24 matching lines...) Expand all Loading... |
| 3369 // which the current one redirects, we ignore the unresolved | 3384 // which the current one redirects, we ignore the unresolved |
| 3370 // reference. We'll catch it later when the constructor gets | 3385 // reference. We'll catch it later when the constructor gets |
| 3371 // compiled. | 3386 // compiled. |
| 3372 ctors.Add(member); | 3387 ctors.Add(member); |
| 3373 member = class_desc->LookupMember(*member->redirect_name); | 3388 member = class_desc->LookupMember(*member->redirect_name); |
| 3374 } | 3389 } |
| 3375 } | 3390 } |
| 3376 } | 3391 } |
| 3377 | 3392 |
| 3378 | 3393 |
| 3394 void Parser::ParseMixinTypedef(const GrowableObjectArray& pending_classes) { |
| 3395 TRACE_PARSER("ParseMixinTypedef"); |
| 3396 const intptr_t classname_pos = TokenPos(); |
| 3397 String& class_name = *ExpectUserDefinedTypeIdentifier("class name expected"); |
| 3398 if (FLAG_trace_parser) { |
| 3399 OS::Print("toplevel parsing typedef class '%s'\n", class_name.ToCString()); |
| 3400 } |
| 3401 const Object& obj = Object::Handle(library_.LookupLocalObject(class_name)); |
| 3402 if (!obj.IsNull()) { |
| 3403 ErrorMsg(classname_pos, "'%s' is already defined", |
| 3404 class_name.ToCString()); |
| 3405 } |
| 3406 const Class& mixin_application = |
| 3407 Class::Handle(Class::New(class_name, script_, classname_pos)); |
| 3408 library_.AddClass(mixin_application); |
| 3409 set_current_class(mixin_application); |
| 3410 ParseTypeParameters(mixin_application); |
| 3411 ExpectToken(Token::kASSIGN); |
| 3412 |
| 3413 if (CurrentToken() == Token::kABSTRACT) { |
| 3414 mixin_application.set_is_abstract(); |
| 3415 ConsumeToken(); |
| 3416 } |
| 3417 |
| 3418 const intptr_t supertype_pos = TokenPos(); |
| 3419 const AbstractType& type = |
| 3420 AbstractType::Handle(ParseType(ClassFinalizer::kTryResolve)); |
| 3421 if (type.IsTypeParameter()) { |
| 3422 ErrorMsg(supertype_pos, |
| 3423 "class '%s' may not extend type parameter '%s'", |
| 3424 class_name.ToCString(), |
| 3425 String::Handle(type.UserVisibleName()).ToCString()); |
| 3426 } |
| 3427 Type& mixin_super_type = Type::Handle(); |
| 3428 mixin_super_type ^= type.raw(); |
| 3429 |
| 3430 if (CurrentToken() != Token::kWITH) { |
| 3431 ErrorMsg("mixin application 'with Type' expected"); |
| 3432 } |
| 3433 |
| 3434 Type& mixin_application_type = Type::Handle(ParseMixins(mixin_super_type)); |
| 3435 // The result of ParseMixins() is a chain of super classes that is the |
| 3436 // result of the mixin composition 'S with M1, M2, ...'. The mixin |
| 3437 // application classes are anonymous (i.e. not registered in the current |
| 3438 // library). We steal the super type and mixin type from the bottom of |
| 3439 // the chain and add it to the named mixin application class. The bottom |
| 3440 // anonymous class in the chain is thrown away. |
| 3441 const Class& anon_mixin_app_class = |
| 3442 Class::Handle(mixin_application_type.type_class()); |
| 3443 mixin_application.set_super_type( |
| 3444 Type::Handle(anon_mixin_app_class.super_type())); |
| 3445 mixin_application.set_mixin(Type::Handle(anon_mixin_app_class.mixin())); |
| 3446 const Array& interfaces = Array::Handle(anon_mixin_app_class.interfaces()); |
| 3447 mixin_application.set_interfaces(interfaces); |
| 3448 AddImplicitConstructor(mixin_application); |
| 3449 |
| 3450 if (CurrentToken() == Token::kIMPLEMENTS) { |
| 3451 Array& interfaces = Array::Handle(); |
| 3452 const intptr_t interfaces_pos = TokenPos(); |
| 3453 const Type& super_type = Type::Handle(mixin_application.super_type()); |
| 3454 interfaces = ParseInterfaceList(super_type); |
| 3455 AddInterfaces(interfaces_pos, mixin_application, interfaces); |
| 3456 } |
| 3457 |
| 3458 pending_classes.Add(mixin_application, Heap::kOld); |
| 3459 ExpectSemicolon(); |
| 3460 } |
| 3461 |
| 3462 |
| 3379 // Look ahead to detect if we are seeing ident [ TypeParameters ] "(". | 3463 // Look ahead to detect if we are seeing ident [ TypeParameters ] "(". |
| 3380 // We need this lookahead to distinguish between the optional return type | 3464 // We need this lookahead to distinguish between the optional return type |
| 3381 // and the alias name of a function type alias. | 3465 // and the alias name of a function type alias. |
| 3382 // Token position remains unchanged. | 3466 // Token position remains unchanged. |
| 3383 bool Parser::IsFunctionTypeAliasName() { | 3467 bool Parser::IsFunctionTypeAliasName() { |
| 3384 if (IsIdentifier() && (LookaheadToken(1) == Token::kLPAREN)) { | 3468 if (IsIdentifier() && (LookaheadToken(1) == Token::kLPAREN)) { |
| 3385 return true; | 3469 return true; |
| 3386 } | 3470 } |
| 3387 const intptr_t saved_pos = TokenPos(); | 3471 const intptr_t saved_pos = TokenPos(); |
| 3388 bool is_alias_name = false; | 3472 bool is_alias_name = false; |
| 3389 if (IsIdentifier() && (LookaheadToken(1) == Token::kLT)) { | 3473 if (IsIdentifier() && (LookaheadToken(1) == Token::kLT)) { |
| 3390 ConsumeToken(); | 3474 ConsumeToken(); |
| 3391 if (TryParseTypeParameter() && (CurrentToken() == Token::kLPAREN)) { | 3475 if (TryParseTypeParameter() && (CurrentToken() == Token::kLPAREN)) { |
| 3392 is_alias_name = true; | 3476 is_alias_name = true; |
| 3393 } | 3477 } |
| 3394 } | 3478 } |
| 3395 SetPosition(saved_pos); | 3479 SetPosition(saved_pos); |
| 3396 return is_alias_name; | 3480 return is_alias_name; |
| 3397 } | 3481 } |
| 3398 | 3482 |
| 3399 | 3483 |
| 3400 void Parser::ParseFunctionTypeAlias( | 3484 // Look ahead to detect if we are seeing ident [ TypeParameters ] "=". |
| 3401 const GrowableObjectArray& pending_classes) { | 3485 // Token position remains unchanged. |
| 3402 TRACE_PARSER("ParseFunctionTypeAlias"); | 3486 bool Parser::IsMixinTypedef() { |
| 3487 if (IsIdentifier() && (LookaheadToken(1) == Token::kASSIGN)) { |
| 3488 return true; |
| 3489 } |
| 3490 const intptr_t saved_pos = TokenPos(); |
| 3491 bool is_mixin_def = false; |
| 3492 if (IsIdentifier() && (LookaheadToken(1) == Token::kLT)) { |
| 3493 ConsumeToken(); |
| 3494 if (TryParseTypeParameter() && (CurrentToken() == Token::kASSIGN)) { |
| 3495 is_mixin_def = true; |
| 3496 } |
| 3497 } |
| 3498 SetPosition(saved_pos); |
| 3499 return is_mixin_def; |
| 3500 } |
| 3501 |
| 3502 |
| 3503 void Parser::ParseTypedef(const GrowableObjectArray& pending_classes) { |
| 3504 TRACE_PARSER("ParseTypedef"); |
| 3403 ExpectToken(Token::kTYPEDEF); | 3505 ExpectToken(Token::kTYPEDEF); |
| 3404 | 3506 |
| 3507 if (IsMixinTypedef()) { |
| 3508 ParseMixinTypedef(pending_classes); |
| 3509 return; |
| 3510 } |
| 3511 |
| 3405 // Parse the result type of the function type. | 3512 // Parse the result type of the function type. |
| 3406 AbstractType& result_type = Type::Handle(Type::DynamicType()); | 3513 AbstractType& result_type = Type::Handle(Type::DynamicType()); |
| 3407 if (CurrentToken() == Token::kVOID) { | 3514 if (CurrentToken() == Token::kVOID) { |
| 3408 ConsumeToken(); | 3515 ConsumeToken(); |
| 3409 result_type = Type::VoidType(); | 3516 result_type = Type::VoidType(); |
| 3410 } else if (!IsFunctionTypeAliasName()) { | 3517 } else if (!IsFunctionTypeAliasName()) { |
| 3411 // Type annotations in typedef are never ignored, even in unchecked mode. | 3518 // Type annotations in typedef are never ignored, even in unchecked mode. |
| 3412 // Wait until we have an owner class before resolving the result type. | 3519 // Wait until we have an owner class before resolving the result type. |
| 3413 result_type = ParseType(ClassFinalizer::kDoNotResolve); | 3520 result_type = ParseType(ClassFinalizer::kDoNotResolve); |
| 3414 } | 3521 } |
| (...skipping 261 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3676 return NewTypeArguments(types); | 3783 return NewTypeArguments(types); |
| 3677 } | 3784 } |
| 3678 } | 3785 } |
| 3679 return TypeArguments::null(); | 3786 return TypeArguments::null(); |
| 3680 } | 3787 } |
| 3681 | 3788 |
| 3682 | 3789 |
| 3683 // Parse and return an array of interface types. | 3790 // Parse and return an array of interface types. |
| 3684 RawArray* Parser::ParseInterfaceList(const Type& super_type) { | 3791 RawArray* Parser::ParseInterfaceList(const Type& super_type) { |
| 3685 TRACE_PARSER("ParseInterfaceList"); | 3792 TRACE_PARSER("ParseInterfaceList"); |
| 3686 ASSERT((CurrentToken() == Token::kIMPLEMENTS) || | 3793 ASSERT(CurrentToken() == Token::kIMPLEMENTS); |
| 3687 (CurrentToken() == Token::kEXTENDS)); | |
| 3688 const GrowableObjectArray& interfaces = | 3794 const GrowableObjectArray& interfaces = |
| 3689 GrowableObjectArray::Handle(GrowableObjectArray::New()); | 3795 GrowableObjectArray::Handle(GrowableObjectArray::New()); |
| 3690 String& interface_name = String::Handle(); | 3796 String& interface_name = String::Handle(); |
| 3691 AbstractType& interface = AbstractType::Handle(); | 3797 AbstractType& interface = AbstractType::Handle(); |
| 3692 String& other_name = String::Handle(); | 3798 String& other_name = String::Handle(); |
| 3693 AbstractType& other_interface = AbstractType::Handle(); | 3799 AbstractType& other_interface = AbstractType::Handle(); |
| 3694 const String& super_type_name = String::Handle(super_type.Name()); | 3800 const String& super_type_name = String::Handle(super_type.Name()); |
| 3695 do { | 3801 do { |
| 3696 ConsumeToken(); | 3802 ConsumeToken(); |
| 3697 intptr_t interface_pos = TokenPos(); | 3803 intptr_t interface_pos = TokenPos(); |
| 3698 interface = ParseType(ClassFinalizer::kTryResolve); | 3804 interface = ParseType(ClassFinalizer::kTryResolve); |
| 3699 interface_name = interface.UserVisibleName(); | 3805 interface_name = interface.UserVisibleName(); |
| 3700 if (interface_name.Equals(super_type_name)) { | 3806 if (interface_name.Equals(super_type_name)) { |
| 3807 // TODO(hausner): I think this check is not necessary. There is |
| 3808 // no such restriction. If the check is removed, the 'super_type' |
| 3809 // parameter to this function can be eliminated. |
| 3701 ErrorMsg(interface_pos, "class may not extend and implement '%s'", | 3810 ErrorMsg(interface_pos, "class may not extend and implement '%s'", |
| 3702 interface_name.ToCString()); | 3811 interface_name.ToCString()); |
| 3703 } | 3812 } |
| 3704 for (int i = 0; i < interfaces.Length(); i++) { | 3813 for (int i = 0; i < interfaces.Length(); i++) { |
| 3705 other_interface ^= interfaces.At(i); | 3814 other_interface ^= interfaces.At(i); |
| 3706 other_name = other_interface.Name(); | 3815 other_name = other_interface.Name(); |
| 3707 if (interface_name.Equals(other_name)) { | 3816 if (interface_name.Equals(other_name)) { |
| 3708 ErrorMsg(interface_pos, "duplicate interface '%s'", | 3817 ErrorMsg(interface_pos, "duplicate interface '%s'", |
| 3709 interface_name.ToCString()); | 3818 interface_name.ToCString()); |
| 3710 } | 3819 } |
| 3711 } | 3820 } |
| 3712 interfaces.Add(interface); | 3821 interfaces.Add(interface); |
| 3713 } while (CurrentToken() == Token::kCOMMA); | 3822 } while (CurrentToken() == Token::kCOMMA); |
| 3714 return Array::MakeArray(interfaces); | 3823 return Array::MakeArray(interfaces); |
| 3715 } | 3824 } |
| 3716 | 3825 |
| 3717 | 3826 |
| 3827 RawType* Parser::ParseMixins(const Type& super_type) { |
| 3828 TRACE_PARSER("ParseMixins"); |
| 3829 ASSERT(CurrentToken() == Token::kWITH); |
| 3830 |
| 3831 // TODO(hausner): Remove this restriction. |
| 3832 if (super_type.arguments() != AbstractTypeArguments::null()) { |
| 3833 ErrorMsg(super_type.token_pos(), |
| 3834 "super class of mixin may not have type arguments"); |
| 3835 } |
| 3836 |
| 3837 AbstractType& mixin_type = AbstractType::Handle(); |
| 3838 AbstractTypeArguments& mixin_type_arguments = |
| 3839 AbstractTypeArguments::Handle(); |
| 3840 Class& mixin_application = Class::Handle(); |
| 3841 Type& mixin_application_type = Type::Handle(); |
| 3842 Type& mixin_super_type = Type::Handle(super_type.raw()); |
| 3843 Array& mixin_application_interfaces = Array::Handle(); |
| 3844 const TypeArguments& no_type_arguments = TypeArguments::Handle(); |
| 3845 do { |
| 3846 ConsumeToken(); |
| 3847 const intptr_t mixin_pos = TokenPos(); |
| 3848 mixin_type = ParseType(ClassFinalizer::kTryResolve); |
| 3849 if (mixin_type.IsTypeParameter()) { |
| 3850 ErrorMsg(mixin_pos, |
| 3851 "mixin type '%s' may not be a type parameter", |
| 3852 String::Handle(mixin_type.UserVisibleName()).ToCString()); |
| 3853 } |
| 3854 // TODO(hausner): Remove this check once we handle mixins with type |
| 3855 // arguments. |
| 3856 mixin_type_arguments = mixin_type.arguments(); |
| 3857 if (!mixin_type_arguments.IsNull()) { |
| 3858 ErrorMsg(mixin_pos, |
| 3859 "mixin type '%s' may not have type arguments", |
| 3860 String::Handle(mixin_type.UserVisibleName()).ToCString()); |
| 3861 } |
| 3862 |
| 3863 // The name of the mixin application class is a combination of |
| 3864 // the superclass and mixin class. |
| 3865 String& mixin_app_name = String::Handle(); |
| 3866 mixin_app_name = mixin_super_type.Name(); |
| 3867 mixin_app_name = String::Concat(mixin_app_name, Symbols::Ampersand()); |
| 3868 mixin_app_name = String::Concat(mixin_app_name, |
| 3869 String::Handle(mixin_type.Name())); |
| 3870 mixin_app_name = Symbols::New(mixin_app_name); |
| 3871 |
| 3872 mixin_application = Class::New(mixin_app_name, script_, mixin_pos); |
| 3873 mixin_application.set_super_type(mixin_super_type); |
| 3874 mixin_application.set_mixin(Type::Cast(mixin_type)); |
| 3875 mixin_application.set_library(library_); |
| 3876 AddImplicitConstructor(mixin_application); |
| 3877 // Add the mixin type to the interfaces that the mixin application |
| 3878 // class implements. This is necessary so that type tests work. |
| 3879 mixin_application_interfaces = Array::New(1); |
| 3880 mixin_application_interfaces.SetAt(0, mixin_type); |
| 3881 mixin_application.set_interfaces(mixin_application_interfaces); |
| 3882 |
| 3883 // TODO(hausner): Need to support type arguments. |
| 3884 mixin_application_type = Type::New(mixin_application, |
| 3885 no_type_arguments, |
| 3886 Scanner::kDummyTokenIndex); |
| 3887 mixin_super_type = mixin_application_type.raw(); |
| 3888 } while (CurrentToken() == Token::kCOMMA); |
| 3889 return mixin_application_type.raw(); |
| 3890 } |
| 3891 |
| 3892 |
| 3718 // Add 'interface' to 'interface_list' if it is not already in the list. | 3893 // Add 'interface' to 'interface_list' if it is not already in the list. |
| 3719 // An error is reported if the interface conflicts with an interface already in | 3894 // An error is reported if the interface conflicts with an interface already in |
| 3720 // the list with the same class and same type arguments. | 3895 // the list with the same class and same type arguments. |
| 3721 void Parser::AddInterfaceIfUnique(intptr_t interfaces_pos, | 3896 void Parser::AddInterfaceIfUnique(intptr_t interfaces_pos, |
| 3722 const GrowableObjectArray& interface_list, | 3897 const GrowableObjectArray& interface_list, |
| 3723 const AbstractType& interface) { | 3898 const AbstractType& interface) { |
| 3724 String& interface_name = String::Handle(interface.Name()); | 3899 String& interface_name = String::Handle(interface.Name()); |
| 3725 String& existing_interface_name = String::Handle(); | 3900 String& existing_interface_name = String::Handle(); |
| 3726 AbstractType& other_interface = AbstractType::Handle(); | 3901 AbstractType& other_interface = AbstractType::Handle(); |
| 3727 for (intptr_t i = 0; i < interface_list.Length(); i++) { | 3902 for (intptr_t i = 0; i < interface_list.Length(); i++) { |
| (...skipping 714 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4442 } | 4617 } |
| 4443 | 4618 |
| 4444 while (true) { | 4619 while (true) { |
| 4445 set_current_class(Class::Handle()); // No current class. | 4620 set_current_class(Class::Handle()); // No current class. |
| 4446 SkipMetadata(); | 4621 SkipMetadata(); |
| 4447 if (CurrentToken() == Token::kCLASS) { | 4622 if (CurrentToken() == Token::kCLASS) { |
| 4448 ParseClassDefinition(pending_classes); | 4623 ParseClassDefinition(pending_classes); |
| 4449 } else if ((CurrentToken() == Token::kTYPEDEF) && | 4624 } else if ((CurrentToken() == Token::kTYPEDEF) && |
| 4450 (LookaheadToken(1) != Token::kLPAREN)) { | 4625 (LookaheadToken(1) != Token::kLPAREN)) { |
| 4451 set_current_class(toplevel_class); | 4626 set_current_class(toplevel_class); |
| 4452 ParseFunctionTypeAlias(pending_classes); | 4627 ParseTypedef(pending_classes); |
| 4453 } else if ((CurrentToken() == Token::kABSTRACT) && | 4628 } else if ((CurrentToken() == Token::kABSTRACT) && |
| 4454 (LookaheadToken(1) == Token::kCLASS)) { | 4629 (LookaheadToken(1) == Token::kCLASS)) { |
| 4455 ParseClassDefinition(pending_classes); | 4630 ParseClassDefinition(pending_classes); |
| 4456 } else if (is_patch_source() && IsLiteral("patch") && | 4631 } else if (is_patch_source() && IsLiteral("patch") && |
| 4457 (LookaheadToken(1) == Token::kCLASS)) { | 4632 (LookaheadToken(1) == Token::kCLASS)) { |
| 4458 ParseClassDefinition(pending_classes); | 4633 ParseClassDefinition(pending_classes); |
| 4459 } else { | 4634 } else { |
| 4460 set_current_class(toplevel_class); | 4635 set_current_class(toplevel_class); |
| 4461 if (IsVariableDeclaration()) { | 4636 if (IsVariableDeclaration()) { |
| 4462 ParseTopLevelVariable(&top_level); | 4637 ParseTopLevelVariable(&top_level); |
| (...skipping 5005 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 9468 CurrentToken() == Token::kLBRACE) { | 9643 CurrentToken() == Token::kLBRACE) { |
| 9469 primary = ParseCompoundLiteral(); | 9644 primary = ParseCompoundLiteral(); |
| 9470 } else if (CurrentToken() == Token::kSUPER) { | 9645 } else if (CurrentToken() == Token::kSUPER) { |
| 9471 if (current_function().is_static()) { | 9646 if (current_function().is_static()) { |
| 9472 ErrorMsg("cannot access superclass from static method"); | 9647 ErrorMsg("cannot access superclass from static method"); |
| 9473 } | 9648 } |
| 9474 if (current_class().SuperClass() == Class::null()) { | 9649 if (current_class().SuperClass() == Class::null()) { |
| 9475 ErrorMsg("class '%s' does not have a superclass", | 9650 ErrorMsg("class '%s' does not have a superclass", |
| 9476 String::Handle(current_class().Name()).ToCString()); | 9651 String::Handle(current_class().Name()).ToCString()); |
| 9477 } | 9652 } |
| 9653 if (current_class().mixin() != Type::null()) { |
| 9654 const Type& mixin_type = Type::Handle(current_class().mixin()); |
| 9655 if (mixin_type.type_class() == current_function().origin()) { |
| 9656 ErrorMsg("class '%s' may not use super " |
| 9657 "because it is used as mixin class", |
| 9658 String::Handle(current_class().Name()).ToCString()); |
| 9659 } |
| 9660 } |
| 9478 ConsumeToken(); | 9661 ConsumeToken(); |
| 9479 if (CurrentToken() == Token::kPERIOD) { | 9662 if (CurrentToken() == Token::kPERIOD) { |
| 9480 ConsumeToken(); | 9663 ConsumeToken(); |
| 9481 const String& ident = *ExpectIdentifier("identifier expected"); | 9664 const String& ident = *ExpectIdentifier("identifier expected"); |
| 9482 if (CurrentToken() == Token::kLPAREN) { | 9665 if (CurrentToken() == Token::kLPAREN) { |
| 9483 primary = ParseSuperCall(ident); | 9666 primary = ParseSuperCall(ident); |
| 9484 } else { | 9667 } else { |
| 9485 primary = ParseSuperFieldAccess(ident); | 9668 primary = ParseSuperFieldAccess(ident); |
| 9486 } | 9669 } |
| 9487 } else if ((CurrentToken() == Token::kLBRACK) || | 9670 } else if ((CurrentToken() == Token::kLBRACK) || |
| (...skipping 321 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 9809 void Parser::SkipQualIdent() { | 9992 void Parser::SkipQualIdent() { |
| 9810 ASSERT(IsIdentifier()); | 9993 ASSERT(IsIdentifier()); |
| 9811 ConsumeToken(); | 9994 ConsumeToken(); |
| 9812 if (CurrentToken() == Token::kPERIOD) { | 9995 if (CurrentToken() == Token::kPERIOD) { |
| 9813 ConsumeToken(); // Consume the kPERIOD token. | 9996 ConsumeToken(); // Consume the kPERIOD token. |
| 9814 ExpectIdentifier("identifier expected after '.'"); | 9997 ExpectIdentifier("identifier expected after '.'"); |
| 9815 } | 9998 } |
| 9816 } | 9999 } |
| 9817 | 10000 |
| 9818 } // namespace dart | 10001 } // namespace dart |
| OLD | NEW |