OLD | NEW |
1 // Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2013, 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/class_finalizer.h" | 5 #include "vm/class_finalizer.h" |
6 | 6 |
7 #include "vm/code_generator.h" | 7 #include "vm/code_generator.h" |
8 #include "vm/flags.h" | 8 #include "vm/flags.h" |
9 #include "vm/heap.h" | 9 #include "vm/heap.h" |
10 #include "vm/isolate.h" | 10 #include "vm/isolate.h" |
(...skipping 60 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
71 } | 71 } |
72 finalized_super_classes->Add(cid); | 72 finalized_super_classes->Add(cid); |
73 const AbstractType& super_type = AbstractType::Handle(cls.super_type()); | 73 const AbstractType& super_type = AbstractType::Handle(cls.super_type()); |
74 AddSuperType(super_type, finalized_super_classes); | 74 AddSuperType(super_type, finalized_super_classes); |
75 } | 75 } |
76 | 76 |
77 | 77 |
78 // Use array instead of set since we expect very few subclassed classes | 78 // Use array instead of set since we expect very few subclassed classes |
79 // to occur. | 79 // to occur. |
80 static void CollectFinalizedSuperClasses( | 80 static void CollectFinalizedSuperClasses( |
81 const Class& cls_, GrowableArray<intptr_t>* finalized_super_classes) { | 81 const Class& cls_, |
| 82 GrowableArray<intptr_t>* finalized_super_classes) { |
82 Class& cls = Class::Handle(cls_.raw()); | 83 Class& cls = Class::Handle(cls_.raw()); |
83 AbstractType& super_type = Type::Handle(); | 84 AbstractType& super_type = Type::Handle(); |
84 super_type = cls.super_type(); | 85 super_type = cls.super_type(); |
85 if (!super_type.IsNull()) { | 86 if (!super_type.IsNull()) { |
86 if (!super_type.IsMalformed() && super_type.HasResolvedTypeClass()) { | 87 if (!super_type.IsMalformed() && super_type.HasResolvedTypeClass()) { |
87 cls ^= super_type.type_class(); | 88 cls ^= super_type.type_class(); |
88 if (cls.is_finalized()) { | 89 if (cls.is_finalized()) { |
89 AddSuperType(super_type, finalized_super_classes); | 90 AddSuperType(super_type, finalized_super_classes); |
90 } | 91 } |
91 } | 92 } |
92 } | 93 } |
93 } | 94 } |
94 | 95 |
95 | 96 |
96 static void CollectImmediateSuperInterfaces( | 97 static void CollectImmediateSuperInterfaces(const Class& cls, |
97 const Class& cls, GrowableArray<intptr_t>* cids) { | 98 GrowableArray<intptr_t>* cids) { |
98 const Array& interfaces = Array::Handle(cls.interfaces()); | 99 const Array& interfaces = Array::Handle(cls.interfaces()); |
99 Class& ifc = Class::Handle(); | 100 Class& ifc = Class::Handle(); |
100 AbstractType& type = AbstractType::Handle(); | 101 AbstractType& type = AbstractType::Handle(); |
101 for (intptr_t i = 0; i < interfaces.Length(); ++i) { | 102 for (intptr_t i = 0; i < interfaces.Length(); ++i) { |
102 type ^= interfaces.At(i); | 103 type ^= interfaces.At(i); |
103 if (type.IsMalformed()) continue; | 104 if (type.IsMalformed()) continue; |
104 if (!type.HasResolvedTypeClass()) continue; | 105 if (!type.HasResolvedTypeClass()) continue; |
105 ifc ^= type.type_class(); | 106 ifc ^= type.type_class(); |
106 for (intptr_t j = 0; j < cids->length(); ++j) { | 107 for (intptr_t j = 0; j < cids->length(); ++j) { |
107 if ((*cids)[j] == ifc.id()) { | 108 if ((*cids)[j] == ifc.id()) { |
(...skipping 57 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
165 } else { | 166 } else { |
166 return false; | 167 return false; |
167 } | 168 } |
168 UNREACHABLE(); | 169 UNREACHABLE(); |
169 return true; | 170 return true; |
170 } | 171 } |
171 | 172 |
172 | 173 |
173 // Adds all interfaces of cls into 'collected'. Duplicate entries may occur. | 174 // Adds all interfaces of cls into 'collected'. Duplicate entries may occur. |
174 // No cycles are allowed. | 175 // No cycles are allowed. |
175 void ClassFinalizer::CollectInterfaces( | 176 void ClassFinalizer::CollectInterfaces(const Class& cls, |
176 const Class& cls, GrowableArray<const Class*>* collected) { | 177 GrowableArray<const Class*>* collected) { |
177 Zone* zone = Thread::Current()->zone(); | 178 Zone* zone = Thread::Current()->zone(); |
178 const Array& interface_array = Array::Handle(zone, cls.interfaces()); | 179 const Array& interface_array = Array::Handle(zone, cls.interfaces()); |
179 AbstractType& interface = AbstractType::Handle(zone); | 180 AbstractType& interface = AbstractType::Handle(zone); |
180 Class& interface_class = Class::Handle(zone); | 181 Class& interface_class = Class::Handle(zone); |
181 for (intptr_t i = 0; i < interface_array.Length(); i++) { | 182 for (intptr_t i = 0; i < interface_array.Length(); i++) { |
182 interface ^= interface_array.At(i); | 183 interface ^= interface_array.At(i); |
183 interface_class = interface.type_class(); | 184 interface_class = interface.type_class(); |
184 collected->Add(&Class::ZoneHandle(zone, interface_class.raw())); | 185 collected->Add(&Class::ZoneHandle(zone, interface_class.raw())); |
185 CollectInterfaces(interface_class, collected); | 186 CollectInterfaces(interface_class, collected); |
186 } | 187 } |
(...skipping 76 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
263 const UnresolvedClass& unresolved_class = | 264 const UnresolvedClass& unresolved_class = |
264 UnresolvedClass::Handle(type.unresolved_class()); | 265 UnresolvedClass::Handle(type.unresolved_class()); |
265 const LibraryPrefix& prefix = | 266 const LibraryPrefix& prefix = |
266 LibraryPrefix::Handle(unresolved_class.library_prefix()); | 267 LibraryPrefix::Handle(unresolved_class.library_prefix()); |
267 return prefix.IsNull() || prefix.is_loaded(); | 268 return prefix.IsNull() || prefix.is_loaded(); |
268 } | 269 } |
269 | 270 |
270 | 271 |
271 // Resolve unresolved_class in the library of cls, or return null. | 272 // Resolve unresolved_class in the library of cls, or return null. |
272 RawClass* ClassFinalizer::ResolveClass( | 273 RawClass* ClassFinalizer::ResolveClass( |
273 const Class& cls, | 274 const Class& cls, |
274 const UnresolvedClass& unresolved_class) { | 275 const UnresolvedClass& unresolved_class) { |
275 const String& class_name = String::Handle(unresolved_class.ident()); | 276 const String& class_name = String::Handle(unresolved_class.ident()); |
276 Library& lib = Library::Handle(); | 277 Library& lib = Library::Handle(); |
277 Class& resolved_class = Class::Handle(); | 278 Class& resolved_class = Class::Handle(); |
278 if (unresolved_class.library_prefix() == LibraryPrefix::null()) { | 279 if (unresolved_class.library_prefix() == LibraryPrefix::null()) { |
279 lib = cls.library(); | 280 lib = cls.library(); |
280 ASSERT(!lib.IsNull()); | 281 ASSERT(!lib.IsNull()); |
281 resolved_class = lib.LookupClass(class_name); | 282 resolved_class = lib.LookupClass(class_name); |
282 } else { | 283 } else { |
283 LibraryPrefix& lib_prefix = LibraryPrefix::Handle(); | 284 LibraryPrefix& lib_prefix = LibraryPrefix::Handle(); |
284 lib_prefix = unresolved_class.library_prefix(); | 285 lib_prefix = unresolved_class.library_prefix(); |
285 ASSERT(!lib_prefix.IsNull()); | 286 ASSERT(!lib_prefix.IsNull()); |
286 resolved_class = lib_prefix.LookupClass(class_name); | 287 resolved_class = lib_prefix.LookupClass(class_name); |
287 } | 288 } |
288 return resolved_class.raw(); | 289 return resolved_class.raw(); |
289 } | 290 } |
290 | 291 |
291 | 292 |
292 | |
293 void ClassFinalizer::ResolveRedirectingFactory(const Class& cls, | 293 void ClassFinalizer::ResolveRedirectingFactory(const Class& cls, |
294 const Function& factory) { | 294 const Function& factory) { |
295 const Function& target = Function::Handle(factory.RedirectionTarget()); | 295 const Function& target = Function::Handle(factory.RedirectionTarget()); |
296 if (target.IsNull()) { | 296 if (target.IsNull()) { |
297 Type& type = Type::Handle(factory.RedirectionType()); | 297 Type& type = Type::Handle(factory.RedirectionType()); |
298 if (!type.IsMalformed() && IsLoaded(type)) { | 298 if (!type.IsMalformed() && IsLoaded(type)) { |
299 const GrowableObjectArray& visited_factories = | 299 const GrowableObjectArray& visited_factories = |
300 GrowableObjectArray::Handle(GrowableObjectArray::New()); | 300 GrowableObjectArray::Handle(GrowableObjectArray::New()); |
301 ResolveRedirectingFactoryTarget(cls, factory, visited_factories); | 301 ResolveRedirectingFactoryTarget(cls, factory, visited_factories); |
302 } | 302 } |
(...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
347 } | 347 } |
348 type ^= FinalizeType(cls, type, kCanonicalize); | 348 type ^= FinalizeType(cls, type, kCanonicalize); |
349 factory.SetRedirectionType(type); | 349 factory.SetRedirectionType(type); |
350 if (type.IsMalformedOrMalbounded()) { | 350 if (type.IsMalformedOrMalbounded()) { |
351 ASSERT(factory.RedirectionTarget() == Function::null()); | 351 ASSERT(factory.RedirectionTarget() == Function::null()); |
352 return; | 352 return; |
353 } | 353 } |
354 ASSERT(!type.IsTypeParameter()); // Resolved in parser. | 354 ASSERT(!type.IsTypeParameter()); // Resolved in parser. |
355 if (type.IsDynamicType()) { | 355 if (type.IsDynamicType()) { |
356 // Replace the type with a malformed type and compile a throw when called. | 356 // Replace the type with a malformed type and compile a throw when called. |
357 type = NewFinalizedMalformedType( | 357 type = NewFinalizedMalformedType(Error::Handle(), // No previous error. |
358 Error::Handle(), // No previous error. | 358 Script::Handle(cls.script()), |
359 Script::Handle(cls.script()), | 359 factory.token_pos(), |
360 factory.token_pos(), | 360 "factory may not redirect to 'dynamic'"); |
361 "factory may not redirect to 'dynamic'"); | |
362 factory.SetRedirectionType(type); | 361 factory.SetRedirectionType(type); |
363 ASSERT(factory.RedirectionTarget() == Function::null()); | 362 ASSERT(factory.RedirectionTarget() == Function::null()); |
364 return; | 363 return; |
365 } | 364 } |
366 const Class& target_class = Class::Handle(type.type_class()); | 365 const Class& target_class = Class::Handle(type.type_class()); |
367 String& target_class_name = String::Handle(target_class.Name()); | 366 String& target_class_name = String::Handle(target_class.Name()); |
368 String& target_name = String::Handle( | 367 String& target_name = |
369 String::Concat(target_class_name, Symbols::Dot())); | 368 String::Handle(String::Concat(target_class_name, Symbols::Dot())); |
370 const String& identifier = String::Handle(factory.RedirectionIdentifier()); | 369 const String& identifier = String::Handle(factory.RedirectionIdentifier()); |
371 if (!identifier.IsNull()) { | 370 if (!identifier.IsNull()) { |
372 target_name = String::Concat(target_name, identifier); | 371 target_name = String::Concat(target_name, identifier); |
373 } | 372 } |
374 | 373 |
375 // Verify that the target constructor of the redirection exists. | 374 // Verify that the target constructor of the redirection exists. |
376 target = target_class.LookupConstructor(target_name); | 375 target = target_class.LookupConstructor(target_name); |
377 if (target.IsNull()) { | 376 if (target.IsNull()) { |
378 target = target_class.LookupFactory(target_name); | 377 target = target_class.LookupFactory(target_name); |
379 } | 378 } |
380 if (target.IsNull()) { | 379 if (target.IsNull()) { |
381 const String& user_visible_target_name = | 380 const String& user_visible_target_name = |
382 identifier.IsNull() ? target_class_name : target_name; | 381 identifier.IsNull() ? target_class_name : target_name; |
383 // Replace the type with a malformed type and compile a throw when called. | 382 // Replace the type with a malformed type and compile a throw when called. |
384 type = NewFinalizedMalformedType( | 383 type = NewFinalizedMalformedType( |
385 Error::Handle(), // No previous error. | 384 Error::Handle(), // No previous error. |
386 Script::Handle(target_class.script()), | 385 Script::Handle(target_class.script()), factory.token_pos(), |
387 factory.token_pos(), | |
388 "class '%s' has no constructor or factory named '%s'", | 386 "class '%s' has no constructor or factory named '%s'", |
389 target_class_name.ToCString(), | 387 target_class_name.ToCString(), user_visible_target_name.ToCString()); |
390 user_visible_target_name.ToCString()); | |
391 factory.SetRedirectionType(type); | 388 factory.SetRedirectionType(type); |
392 ASSERT(factory.RedirectionTarget() == Function::null()); | 389 ASSERT(factory.RedirectionTarget() == Function::null()); |
393 return; | 390 return; |
394 } | 391 } |
395 | 392 |
396 if (Isolate::Current()->error_on_bad_override()) { | 393 if (Isolate::Current()->error_on_bad_override()) { |
397 // Verify that the target is compatible with the redirecting factory. | 394 // Verify that the target is compatible with the redirecting factory. |
398 Error& error = Error::Handle(); | 395 Error& error = Error::Handle(); |
399 if (!target.HasCompatibleParametersWith(factory, &error)) { | 396 if (!target.HasCompatibleParametersWith(factory, &error)) { |
400 const Script& script = Script::Handle(target_class.script()); | 397 const Script& script = Script::Handle(target_class.script()); |
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
434 Type& target_type = Type::Handle(target.RedirectionType()); | 431 Type& target_type = Type::Handle(target.RedirectionType()); |
435 Function& target_target = Function::Handle(target.RedirectionTarget()); | 432 Function& target_target = Function::Handle(target.RedirectionTarget()); |
436 if (target_target.IsNull()) { | 433 if (target_target.IsNull()) { |
437 ASSERT(target_type.IsMalformed()); | 434 ASSERT(target_type.IsMalformed()); |
438 } else { | 435 } else { |
439 // If the target type refers to type parameters, substitute them with the | 436 // If the target type refers to type parameters, substitute them with the |
440 // type arguments of the redirection type. | 437 // type arguments of the redirection type. |
441 if (!target_type.IsInstantiated()) { | 438 if (!target_type.IsInstantiated()) { |
442 const TypeArguments& type_args = TypeArguments::Handle(type.arguments()); | 439 const TypeArguments& type_args = TypeArguments::Handle(type.arguments()); |
443 Error& bound_error = Error::Handle(); | 440 Error& bound_error = Error::Handle(); |
444 target_type ^= target_type.InstantiateFrom( | 441 target_type ^= target_type.InstantiateFrom(type_args, &bound_error, NULL, |
445 type_args, &bound_error, NULL, NULL, Heap::kOld); | 442 NULL, Heap::kOld); |
446 if (bound_error.IsNull()) { | 443 if (bound_error.IsNull()) { |
447 target_type ^= FinalizeType(cls, target_type, kCanonicalize); | 444 target_type ^= FinalizeType(cls, target_type, kCanonicalize); |
448 } else { | 445 } else { |
449 ASSERT(target_type.IsInstantiated() && type_args.IsInstantiated()); | 446 ASSERT(target_type.IsInstantiated() && type_args.IsInstantiated()); |
450 const Script& script = Script::Handle(target_class.script()); | 447 const Script& script = Script::Handle(target_class.script()); |
451 FinalizeMalformedType(bound_error, script, target_type, | 448 FinalizeMalformedType(bound_error, script, target_type, |
452 "cannot resolve redirecting factory"); | 449 "cannot resolve redirecting factory"); |
453 target_target = Function::null(); | 450 target_target = Function::null(); |
454 } | 451 } |
455 } | 452 } |
(...skipping 21 matching lines...) Expand all Loading... |
477 // Lookup the type class if necessary. | 474 // Lookup the type class if necessary. |
478 Class& type_class = Class::Handle(); | 475 Class& type_class = Class::Handle(); |
479 if (type.HasResolvedTypeClass()) { | 476 if (type.HasResolvedTypeClass()) { |
480 type_class = type.type_class(); | 477 type_class = type.type_class(); |
481 } else { | 478 } else { |
482 const UnresolvedClass& unresolved_class = | 479 const UnresolvedClass& unresolved_class = |
483 UnresolvedClass::Handle(type.unresolved_class()); | 480 UnresolvedClass::Handle(type.unresolved_class()); |
484 type_class = ResolveClass(cls, unresolved_class); | 481 type_class = ResolveClass(cls, unresolved_class); |
485 if (type_class.IsNull()) { | 482 if (type_class.IsNull()) { |
486 // The type class could not be resolved. The type is malformed. | 483 // The type class could not be resolved. The type is malformed. |
487 FinalizeMalformedType( | 484 FinalizeMalformedType(Error::Handle(), // No previous error. |
488 Error::Handle(), // No previous error. | 485 Script::Handle(cls.script()), type, |
489 Script::Handle(cls.script()), | 486 "cannot resolve class '%s' from '%s'", |
490 type, | 487 String::Handle(unresolved_class.Name()).ToCString(), |
491 "cannot resolve class '%s' from '%s'", | 488 String::Handle(cls.Name()).ToCString()); |
492 String::Handle(unresolved_class.Name()).ToCString(), | |
493 String::Handle(cls.Name()).ToCString()); | |
494 return; | 489 return; |
495 } | 490 } |
496 // Replace unresolved class with resolved type class. | 491 // Replace unresolved class with resolved type class. |
497 type.set_type_class(type_class); | 492 type.set_type_class(type_class); |
498 } | 493 } |
499 // Promote the type to a function type in case its type class is a typedef. | 494 // Promote the type to a function type in case its type class is a typedef. |
500 // Note that the type may already be a function type if it was parsed as a | 495 // Note that the type may already be a function type if it was parsed as a |
501 // formal parameter function type. | 496 // formal parameter function type. |
502 if (!type.IsFunctionType() && | 497 if (!type.IsFunctionType() && type_class.IsTypedefClass() && |
503 type_class.IsTypedefClass() && | |
504 !type.IsMalformedOrMalbounded()) { | 498 !type.IsMalformedOrMalbounded()) { |
505 type.set_signature(Function::Handle(type_class.signature_function())); | 499 type.set_signature(Function::Handle(type_class.signature_function())); |
506 } | 500 } |
507 ASSERT(!type_class.IsTypedefClass() || | 501 ASSERT(!type_class.IsTypedefClass() || |
508 (type.signature() != Function::null())); | 502 (type.signature() != Function::null())); |
509 } | 503 } |
510 | 504 |
511 | 505 |
512 void ClassFinalizer::ResolveType(const Class& cls, const AbstractType& type) { | 506 void ClassFinalizer::ResolveType(const Class& cls, const AbstractType& type) { |
513 if (type.IsResolved()) { | 507 if (type.IsResolved()) { |
(...skipping 28 matching lines...) Expand all Loading... |
542 const Class& scope_class = Class::Handle(type.type_class()); | 536 const Class& scope_class = Class::Handle(type.type_class()); |
543 if (scope_class.IsTypedefClass()) { | 537 if (scope_class.IsTypedefClass()) { |
544 ResolveSignature(scope_class, signature); | 538 ResolveSignature(scope_class, signature); |
545 } else { | 539 } else { |
546 ResolveSignature(cls, signature); | 540 ResolveSignature(cls, signature); |
547 } | 541 } |
548 } | 542 } |
549 } | 543 } |
550 | 544 |
551 | 545 |
552 void ClassFinalizer::FinalizeTypeParameters( | 546 void ClassFinalizer::FinalizeTypeParameters(const Class& cls, |
553 const Class& cls, | 547 PendingTypes* pending_types) { |
554 PendingTypes* pending_types) { | |
555 if (FLAG_trace_type_finalization) { | 548 if (FLAG_trace_type_finalization) { |
556 THR_Print("Finalizing type parameters of '%s'\n", | 549 THR_Print("Finalizing type parameters of '%s'\n", |
557 String::Handle(cls.Name()).ToCString()); | 550 String::Handle(cls.Name()).ToCString()); |
558 } | 551 } |
559 if (cls.IsMixinApplication()) { | 552 if (cls.IsMixinApplication()) { |
560 // Setup the type parameters of the mixin application and finalize the | 553 // Setup the type parameters of the mixin application and finalize the |
561 // mixin type. | 554 // mixin type. |
562 ApplyMixinType(cls, pending_types); | 555 ApplyMixinType(cls, pending_types); |
563 } | 556 } |
564 // The type parameter bounds are not finalized here. | 557 // The type parameter bounds are not finalized here. |
565 const TypeArguments& type_parameters = | 558 const TypeArguments& type_parameters = |
566 TypeArguments::Handle(cls.type_parameters()); | 559 TypeArguments::Handle(cls.type_parameters()); |
567 if (!type_parameters.IsNull()) { | 560 if (!type_parameters.IsNull()) { |
568 TypeParameter& type_parameter = TypeParameter::Handle(); | 561 TypeParameter& type_parameter = TypeParameter::Handle(); |
569 const intptr_t num_types = type_parameters.Length(); | 562 const intptr_t num_types = type_parameters.Length(); |
570 for (intptr_t i = 0; i < num_types; i++) { | 563 for (intptr_t i = 0; i < num_types; i++) { |
571 type_parameter ^= type_parameters.TypeAt(i); | 564 type_parameter ^= type_parameters.TypeAt(i); |
572 type_parameter ^= FinalizeType( | 565 type_parameter ^= |
573 cls, type_parameter, kFinalize, pending_types); | 566 FinalizeType(cls, type_parameter, kFinalize, pending_types); |
574 type_parameters.SetTypeAt(i, type_parameter); | 567 type_parameters.SetTypeAt(i, type_parameter); |
575 } | 568 } |
576 } | 569 } |
577 } | 570 } |
578 | 571 |
579 | 572 |
580 // This function reports a compilation error if the recursive 'type' T being | 573 // This function reports a compilation error if the recursive 'type' T being |
581 // finalized is a non-contractive type, i.e. if the induced type set S of P is | 574 // finalized is a non-contractive type, i.e. if the induced type set S of P is |
582 // not finite, where P is the instantiation of T with its own type parameters. | 575 // not finite, where P is the instantiation of T with its own type parameters. |
583 // The induced type set S consists of the super types of any type in S as well | 576 // The induced type set S consists of the super types of any type in S as well |
584 // as the type arguments of any parameterized type in S. | 577 // as the type arguments of any parameterized type in S. |
585 // The Dart Language Specification does not disallow the declaration and use of | 578 // The Dart Language Specification does not disallow the declaration and use of |
586 // non-contractive types (this may change). They are nevertheless disallowed | 579 // non-contractive types (this may change). They are nevertheless disallowed |
587 // as an implementation restriction in the VM since they cause divergence. | 580 // as an implementation restriction in the VM since they cause divergence. |
588 // A non-contractive type can be detected by looking at the queue of types | 581 // A non-contractive type can be detected by looking at the queue of types |
589 // pending finalization that are mutually recursive with the checked type. | 582 // pending finalization that are mutually recursive with the checked type. |
590 void ClassFinalizer::CheckRecursiveType(const Class& cls, | 583 void ClassFinalizer::CheckRecursiveType(const Class& cls, |
591 const AbstractType& type, | 584 const AbstractType& type, |
592 PendingTypes* pending_types) { | 585 PendingTypes* pending_types) { |
593 Zone* zone = Thread::Current()->zone(); | 586 Zone* zone = Thread::Current()->zone(); |
594 if (FLAG_trace_type_finalization) { | 587 if (FLAG_trace_type_finalization) { |
595 THR_Print("Checking recursive type '%s': %s\n", | 588 THR_Print("Checking recursive type '%s': %s\n", |
596 String::Handle(type.Name()).ToCString(), | 589 String::Handle(type.Name()).ToCString(), type.ToCString()); |
597 type.ToCString()); | |
598 } | 590 } |
599 const Class& type_cls = Class::Handle(zone, type.type_class()); | 591 const Class& type_cls = Class::Handle(zone, type.type_class()); |
600 const TypeArguments& arguments = | 592 const TypeArguments& arguments = |
601 TypeArguments::Handle(zone, type.arguments()); | 593 TypeArguments::Handle(zone, type.arguments()); |
602 // A type can only be recursive via its type arguments. | 594 // A type can only be recursive via its type arguments. |
603 ASSERT(!arguments.IsNull()); | 595 ASSERT(!arguments.IsNull()); |
604 const intptr_t num_type_args = arguments.Length(); | 596 const intptr_t num_type_args = arguments.Length(); |
605 ASSERT(num_type_args > 0); | 597 ASSERT(num_type_args > 0); |
606 ASSERT(num_type_args == type_cls.NumTypeArguments()); | 598 ASSERT(num_type_args == type_cls.NumTypeArguments()); |
607 const intptr_t num_type_params = type_cls.NumTypeParameters(); | 599 const intptr_t num_type_params = type_cls.NumTypeParameters(); |
(...skipping 11 matching lines...) Expand all Loading... |
619 // uninstantiated type parameters. | 611 // uninstantiated type parameters. |
620 TypeArguments& pending_arguments = TypeArguments::Handle(zone); | 612 TypeArguments& pending_arguments = TypeArguments::Handle(zone); |
621 const intptr_t num_pending_types = pending_types->length(); | 613 const intptr_t num_pending_types = pending_types->length(); |
622 for (intptr_t i = num_pending_types - 1; i >= 0; i--) { | 614 for (intptr_t i = num_pending_types - 1; i >= 0; i--) { |
623 const AbstractType& pending_type = pending_types->At(i); | 615 const AbstractType& pending_type = pending_types->At(i); |
624 if (FLAG_trace_type_finalization) { | 616 if (FLAG_trace_type_finalization) { |
625 THR_Print(" Comparing with pending type '%s': %s\n", | 617 THR_Print(" Comparing with pending type '%s': %s\n", |
626 String::Handle(pending_type.Name()).ToCString(), | 618 String::Handle(pending_type.Name()).ToCString(), |
627 pending_type.ToCString()); | 619 pending_type.ToCString()); |
628 } | 620 } |
629 if ((pending_type.raw() != type.raw()) && | 621 if ((pending_type.raw() != type.raw()) && pending_type.IsType() && |
630 pending_type.IsType() && | |
631 (pending_type.type_class() == type_cls.raw())) { | 622 (pending_type.type_class() == type_cls.raw())) { |
632 pending_arguments = pending_type.arguments(); | 623 pending_arguments = pending_type.arguments(); |
633 if (!pending_arguments.IsSubvectorEquivalent(arguments, | 624 if (!pending_arguments.IsSubvectorEquivalent(arguments, first_type_param, |
634 first_type_param, | |
635 num_type_params) && | 625 num_type_params) && |
636 !pending_arguments.IsSubvectorInstantiated(first_type_param, | 626 !pending_arguments.IsSubvectorInstantiated(first_type_param, |
637 num_type_params)) { | 627 num_type_params)) { |
638 // Reject the non-contractive recursive type. | 628 // Reject the non-contractive recursive type. |
639 const String& type_name = String::Handle(zone, type.Name()); | 629 const String& type_name = String::Handle(zone, type.Name()); |
640 ReportError(cls, type.token_pos(), | 630 ReportError(cls, type.token_pos(), "illegal recursive type '%s'", |
641 "illegal recursive type '%s'", type_name.ToCString()); | 631 type_name.ToCString()); |
642 } | 632 } |
643 } | 633 } |
644 } | 634 } |
645 } | 635 } |
646 | 636 |
647 | 637 |
648 // Expand the type arguments of the given type and finalize its full type | 638 // Expand the type arguments of the given type and finalize its full type |
649 // argument vector. Return the number of type arguments (0 for a raw type). | 639 // argument vector. Return the number of type arguments (0 for a raw type). |
650 intptr_t ClassFinalizer::ExpandAndFinalizeTypeArguments( | 640 intptr_t ClassFinalizer::ExpandAndFinalizeTypeArguments( |
651 const Class& cls, | 641 const Class& cls, |
(...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
703 // type arguments, followed by the parsed type arguments. | 693 // type arguments, followed by the parsed type arguments. |
704 TypeArguments& full_arguments = TypeArguments::Handle(zone); | 694 TypeArguments& full_arguments = TypeArguments::Handle(zone); |
705 if (FLAG_reify && (num_type_arguments > 0)) { | 695 if (FLAG_reify && (num_type_arguments > 0)) { |
706 // If no type arguments were parsed and if the super types do not prepend | 696 // If no type arguments were parsed and if the super types do not prepend |
707 // type arguments to the vector, we can leave the vector as null. | 697 // type arguments to the vector, we can leave the vector as null. |
708 if (!arguments.IsNull() || (num_type_arguments > num_type_parameters)) { | 698 if (!arguments.IsNull() || (num_type_arguments > num_type_parameters)) { |
709 full_arguments = TypeArguments::New(num_type_arguments); | 699 full_arguments = TypeArguments::New(num_type_arguments); |
710 // Copy the parsed type arguments at the correct offset in the full type | 700 // Copy the parsed type arguments at the correct offset in the full type |
711 // argument vector. | 701 // argument vector. |
712 const intptr_t offset = num_type_arguments - num_type_parameters; | 702 const intptr_t offset = num_type_arguments - num_type_parameters; |
713 AbstractType& type_arg = | 703 AbstractType& type_arg = AbstractType::Handle(zone, Type::DynamicType()); |
714 AbstractType::Handle(zone, Type::DynamicType()); | |
715 // Leave the temporary type arguments at indices [0..offset[ as null. | 704 // Leave the temporary type arguments at indices [0..offset[ as null. |
716 for (intptr_t i = 0; i < num_type_parameters; i++) { | 705 for (intptr_t i = 0; i < num_type_parameters; i++) { |
717 // If no type parameters were provided, a raw type is desired, so we | 706 // If no type parameters were provided, a raw type is desired, so we |
718 // create a vector of dynamic. | 707 // create a vector of dynamic. |
719 if (!arguments.IsNull()) { | 708 if (!arguments.IsNull()) { |
720 type_arg = arguments.TypeAt(i); | 709 type_arg = arguments.TypeAt(i); |
721 // The parsed type_arg may or may not be finalized. | 710 // The parsed type_arg may or may not be finalized. |
722 } | 711 } |
723 full_arguments.SetTypeAt(offset + i, type_arg); | 712 full_arguments.SetTypeAt(offset + i, type_arg); |
724 } | 713 } |
(...skipping 13 matching lines...) Expand all Loading... |
738 if (type_arg.IsMalformed()) { | 727 if (type_arg.IsMalformed()) { |
739 // Malformed type arguments are mapped to dynamic. | 728 // Malformed type arguments are mapped to dynamic. |
740 type_arg = Type::DynamicType(); | 729 type_arg = Type::DynamicType(); |
741 } | 730 } |
742 full_arguments.SetTypeAt(offset + i, type_arg); | 731 full_arguments.SetTypeAt(offset + i, type_arg); |
743 } | 732 } |
744 } | 733 } |
745 if (offset > 0) { | 734 if (offset > 0) { |
746 TrailPtr instantiation_trail = new Trail(zone, 4); | 735 TrailPtr instantiation_trail = new Trail(zone, 4); |
747 Error& bound_error = Error::Handle(zone); | 736 Error& bound_error = Error::Handle(zone); |
748 FinalizeTypeArguments(type_class, full_arguments, offset, | 737 FinalizeTypeArguments(type_class, full_arguments, offset, &bound_error, |
749 &bound_error, pending_types, instantiation_trail); | 738 pending_types, instantiation_trail); |
750 } | 739 } |
751 if (full_arguments.IsRaw(0, num_type_arguments)) { | 740 if (full_arguments.IsRaw(0, num_type_arguments)) { |
752 // The parameterized_type is raw. Set its argument vector to null, which | 741 // The parameterized_type is raw. Set its argument vector to null, which |
753 // is more efficient in type tests. | 742 // is more efficient in type tests. |
754 full_arguments = TypeArguments::null(); | 743 full_arguments = TypeArguments::null(); |
755 } | 744 } |
756 type.set_arguments(full_arguments); | 745 type.set_arguments(full_arguments); |
757 } else { | 746 } else { |
758 ASSERT(full_arguments.IsNull()); // Use null vector for raw type. | 747 ASSERT(full_arguments.IsNull()); // Use null vector for raw type. |
759 } | 748 } |
(...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
802 // cls = C, arguments = [dynamic, String, double], | 791 // cls = C, arguments = [dynamic, String, double], |
803 // num_uninitialized_arguments = 1, | 792 // num_uninitialized_arguments = 1, |
804 // i.e. cls_args = [String, double], offset = 1, length = 2. | 793 // i.e. cls_args = [String, double], offset = 1, length = 2. |
805 // Output: arguments = [int, String, double] | 794 // Output: arguments = [int, String, double] |
806 // | 795 // |
807 // It is too early to canonicalize the type arguments of the vector, because | 796 // It is too early to canonicalize the type arguments of the vector, because |
808 // several type argument vectors may be mutually recursive and finalized at the | 797 // several type argument vectors may be mutually recursive and finalized at the |
809 // same time. Canonicalization happens when pending types are processed. | 798 // same time. Canonicalization happens when pending types are processed. |
810 // The trail is required to correctly instantiate a recursive type argument | 799 // The trail is required to correctly instantiate a recursive type argument |
811 // of the super type. | 800 // of the super type. |
812 void ClassFinalizer::FinalizeTypeArguments( | 801 void ClassFinalizer::FinalizeTypeArguments(const Class& cls, |
813 const Class& cls, | 802 const TypeArguments& arguments, |
814 const TypeArguments& arguments, | 803 intptr_t num_uninitialized_arguments, |
815 intptr_t num_uninitialized_arguments, | 804 Error* bound_error, |
816 Error* bound_error, | 805 PendingTypes* pending_types, |
817 PendingTypes* pending_types, | 806 TrailPtr instantiation_trail) { |
818 TrailPtr instantiation_trail) { | |
819 ASSERT(arguments.Length() >= cls.NumTypeArguments()); | 807 ASSERT(arguments.Length() >= cls.NumTypeArguments()); |
820 if (!cls.is_type_finalized()) { | 808 if (!cls.is_type_finalized()) { |
821 FinalizeTypeParameters(cls, pending_types); | 809 FinalizeTypeParameters(cls, pending_types); |
822 ResolveUpperBounds(cls); | 810 ResolveUpperBounds(cls); |
823 } | 811 } |
824 AbstractType& super_type = AbstractType::Handle(cls.super_type()); | 812 AbstractType& super_type = AbstractType::Handle(cls.super_type()); |
825 if (!super_type.IsNull()) { | 813 if (!super_type.IsNull()) { |
826 const Class& super_class = Class::Handle(super_type.type_class()); | 814 const Class& super_class = Class::Handle(super_type.type_class()); |
827 const intptr_t num_super_type_params = super_class.NumTypeParameters(); | 815 const intptr_t num_super_type_params = super_class.NumTypeParameters(); |
828 const intptr_t num_super_type_args = super_class.NumTypeArguments(); | 816 const intptr_t num_super_type_args = super_class.NumTypeArguments(); |
829 ASSERT(num_super_type_args == | 817 ASSERT(num_super_type_args == |
830 (cls.NumTypeArguments() - cls.NumOwnTypeArguments())); | 818 (cls.NumTypeArguments() - cls.NumOwnTypeArguments())); |
831 if (!super_type.IsFinalized() && !super_type.IsBeingFinalized()) { | 819 if (!super_type.IsFinalized() && !super_type.IsBeingFinalized()) { |
832 super_type ^= FinalizeType( | 820 super_type ^= FinalizeType(cls, super_type, kFinalize, pending_types); |
833 cls, super_type, kFinalize, pending_types); | |
834 cls.set_super_type(super_type); | 821 cls.set_super_type(super_type); |
835 } | 822 } |
836 TypeArguments& super_type_args = TypeArguments::Handle( | 823 TypeArguments& super_type_args = |
837 super_type.arguments()); | 824 TypeArguments::Handle(super_type.arguments()); |
838 // Offset of super type's type parameters in cls' type argument vector. | 825 // Offset of super type's type parameters in cls' type argument vector. |
839 const intptr_t super_offset = num_super_type_args - num_super_type_params; | 826 const intptr_t super_offset = num_super_type_args - num_super_type_params; |
840 AbstractType& super_type_arg = AbstractType::Handle(Type::DynamicType()); | 827 AbstractType& super_type_arg = AbstractType::Handle(Type::DynamicType()); |
841 for (intptr_t i = super_offset; i < num_uninitialized_arguments; i++) { | 828 for (intptr_t i = super_offset; i < num_uninitialized_arguments; i++) { |
842 if (!super_type_args.IsNull()) { | 829 if (!super_type_args.IsNull()) { |
843 super_type_arg = super_type_args.TypeAt(i); | 830 super_type_arg = super_type_args.TypeAt(i); |
844 if (!super_type_arg.IsTypeRef()) { | 831 if (!super_type_arg.IsTypeRef()) { |
845 if (super_type_arg.IsBeingFinalized()) { | 832 if (super_type_arg.IsBeingFinalized()) { |
846 ASSERT(super_type_arg.IsType()); | 833 ASSERT(super_type_arg.IsType()); |
847 CheckRecursiveType(cls, super_type_arg, pending_types); | 834 CheckRecursiveType(cls, super_type_arg, pending_types); |
848 if (FLAG_trace_type_finalization) { | 835 if (FLAG_trace_type_finalization) { |
849 THR_Print("Creating TypeRef '%s': '%s'\n", | 836 THR_Print("Creating TypeRef '%s': '%s'\n", |
850 String::Handle(super_type_arg.Name()).ToCString(), | 837 String::Handle(super_type_arg.Name()).ToCString(), |
851 super_type_arg.ToCString()); | 838 super_type_arg.ToCString()); |
852 } | 839 } |
853 super_type_arg = TypeRef::New(super_type_arg); | 840 super_type_arg = TypeRef::New(super_type_arg); |
854 super_type_args.SetTypeAt(i, super_type_arg); | 841 super_type_args.SetTypeAt(i, super_type_arg); |
855 } else { | 842 } else { |
856 if (!super_type_arg.IsFinalized()) { | 843 if (!super_type_arg.IsFinalized()) { |
857 super_type_arg ^= FinalizeType( | 844 super_type_arg ^= |
858 cls, super_type_arg, kFinalize, pending_types); | 845 FinalizeType(cls, super_type_arg, kFinalize, pending_types); |
859 super_type_args.SetTypeAt(i, super_type_arg); | 846 super_type_args.SetTypeAt(i, super_type_arg); |
860 // Note that super_type_arg may still not be finalized here, in | 847 // Note that super_type_arg may still not be finalized here, in |
861 // which case it is a TypeRef to a legal recursive type. | 848 // which case it is a TypeRef to a legal recursive type. |
862 } | 849 } |
863 } | 850 } |
864 } | 851 } |
865 // Instantiate super_type_arg with the current argument vector. | 852 // Instantiate super_type_arg with the current argument vector. |
866 if (!super_type_arg.IsInstantiated()) { | 853 if (!super_type_arg.IsInstantiated()) { |
867 if (FLAG_trace_type_finalization && super_type_arg.IsTypeRef()) { | 854 if (FLAG_trace_type_finalization && super_type_arg.IsTypeRef()) { |
868 AbstractType& ref_type = AbstractType::Handle( | 855 AbstractType& ref_type = |
869 TypeRef::Cast(super_type_arg).type()); | 856 AbstractType::Handle(TypeRef::Cast(super_type_arg).type()); |
870 THR_Print("Instantiating TypeRef '%s': '%s'\n" | 857 THR_Print( |
871 " instantiator: '%s'\n", | 858 "Instantiating TypeRef '%s': '%s'\n" |
872 String::Handle(super_type_arg.Name()).ToCString(), | 859 " instantiator: '%s'\n", |
873 ref_type.ToCString(), | 860 String::Handle(super_type_arg.Name()).ToCString(), |
874 arguments.ToCString()); | 861 ref_type.ToCString(), arguments.ToCString()); |
875 } | 862 } |
876 Error& error = Error::Handle(); | 863 Error& error = Error::Handle(); |
877 super_type_arg = super_type_arg.InstantiateFrom( | 864 super_type_arg = super_type_arg.InstantiateFrom( |
878 arguments, &error, instantiation_trail, NULL, Heap::kOld); | 865 arguments, &error, instantiation_trail, NULL, Heap::kOld); |
879 if (!error.IsNull()) { | 866 if (!error.IsNull()) { |
880 // InstantiateFrom does not report an error if the type is still | 867 // InstantiateFrom does not report an error if the type is still |
881 // uninstantiated. Instead, it will return a new BoundedType so | 868 // uninstantiated. Instead, it will return a new BoundedType so |
882 // that the check is postponed to run time. | 869 // that the check is postponed to run time. |
883 ASSERT(super_type_arg.IsInstantiated()); | 870 ASSERT(super_type_arg.IsInstantiated()); |
884 // Keep only the first bound error. | 871 // Keep only the first bound error. |
885 if (bound_error->IsNull()) { | 872 if (bound_error->IsNull()) { |
886 *bound_error = error.raw(); | 873 *bound_error = error.raw(); |
887 } | 874 } |
888 } | 875 } |
889 if (!super_type_arg.IsFinalized() && | 876 if (!super_type_arg.IsFinalized() && |
890 !super_type_arg.IsBeingFinalized()) { | 877 !super_type_arg.IsBeingFinalized()) { |
891 // The super_type_arg was instantiated from a type being finalized. | 878 // The super_type_arg was instantiated from a type being finalized. |
892 // We need to finish finalizing its type arguments. | 879 // We need to finish finalizing its type arguments. |
893 if (super_type_arg.IsTypeRef()) { | 880 if (super_type_arg.IsTypeRef()) { |
894 super_type_arg = TypeRef::Cast(super_type_arg).type(); | 881 super_type_arg = TypeRef::Cast(super_type_arg).type(); |
895 } | 882 } |
896 Type::Cast(super_type_arg).SetIsBeingFinalized(); | 883 Type::Cast(super_type_arg).SetIsBeingFinalized(); |
897 pending_types->Add(super_type_arg); | 884 pending_types->Add(super_type_arg); |
898 const Class& cls = Class::Handle(super_type_arg.type_class()); | 885 const Class& cls = Class::Handle(super_type_arg.type_class()); |
899 FinalizeTypeArguments( | 886 FinalizeTypeArguments( |
900 cls, | 887 cls, TypeArguments::Handle(super_type_arg.arguments()), |
901 TypeArguments::Handle(super_type_arg.arguments()), | 888 cls.NumTypeArguments() - cls.NumTypeParameters(), bound_error, |
902 cls.NumTypeArguments() - cls.NumTypeParameters(), | 889 pending_types, instantiation_trail); |
903 bound_error, | |
904 pending_types, | |
905 instantiation_trail); | |
906 Type::Cast(super_type_arg).SetIsFinalized(); | 890 Type::Cast(super_type_arg).SetIsFinalized(); |
907 } | 891 } |
908 } | 892 } |
909 } | 893 } |
910 arguments.SetTypeAt(i, super_type_arg); | 894 arguments.SetTypeAt(i, super_type_arg); |
911 } | 895 } |
912 FinalizeTypeArguments(super_class, arguments, super_offset, | 896 FinalizeTypeArguments(super_class, arguments, super_offset, bound_error, |
913 bound_error, pending_types, instantiation_trail); | 897 pending_types, instantiation_trail); |
914 } | 898 } |
915 } | 899 } |
916 | 900 |
917 | 901 |
918 // Check the type argument vector 'arguments' against the corresponding bounds | 902 // Check the type argument vector 'arguments' against the corresponding bounds |
919 // of the type parameters of class 'cls' and, recursively, of its superclasses. | 903 // of the type parameters of class 'cls' and, recursively, of its superclasses. |
920 // Replace a type argument that cannot be checked at compile time by a | 904 // Replace a type argument that cannot be checked at compile time by a |
921 // BoundedType, thereby postponing the bound check to run time. | 905 // BoundedType, thereby postponing the bound check to run time. |
922 // Return a bound error if a type argument is not within bound at compile time. | 906 // Return a bound error if a type argument is not within bound at compile time. |
923 void ClassFinalizer::CheckTypeArgumentBounds(const Class& cls, | 907 void ClassFinalizer::CheckTypeArgumentBounds(const Class& cls, |
(...skipping 69 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
993 // Shortcut the special case where we check a type parameter against its | 977 // Shortcut the special case where we check a type parameter against its |
994 // declared upper bound. | 978 // declared upper bound. |
995 if (error.IsNull() && | 979 if (error.IsNull() && |
996 !(type_arg.Equals(type_param) && | 980 !(type_arg.Equals(type_param) && |
997 instantiated_bound.Equals(declared_bound))) { | 981 instantiated_bound.Equals(declared_bound))) { |
998 // If type_arg is a type parameter, its declared bound may not be | 982 // If type_arg is a type parameter, its declared bound may not be |
999 // finalized yet. | 983 // finalized yet. |
1000 if (type_arg.IsTypeParameter()) { | 984 if (type_arg.IsTypeParameter()) { |
1001 const Class& type_arg_cls = Class::Handle( | 985 const Class& type_arg_cls = Class::Handle( |
1002 TypeParameter::Cast(type_arg).parameterized_class()); | 986 TypeParameter::Cast(type_arg).parameterized_class()); |
1003 AbstractType& bound = AbstractType::Handle( | 987 AbstractType& bound = |
1004 TypeParameter::Cast(type_arg).bound()); | 988 AbstractType::Handle(TypeParameter::Cast(type_arg).bound()); |
1005 if (!bound.IsFinalized() && !bound.IsBeingFinalized()) { | 989 if (!bound.IsFinalized() && !bound.IsBeingFinalized()) { |
1006 bound = FinalizeType(type_arg_cls, bound, kCanonicalize); | 990 bound = FinalizeType(type_arg_cls, bound, kCanonicalize); |
1007 TypeParameter::Cast(type_arg).set_bound(bound); | 991 TypeParameter::Cast(type_arg).set_bound(bound); |
1008 } | 992 } |
1009 } | 993 } |
1010 // This may be called only if type needs to be finalized, therefore | 994 // This may be called only if type needs to be finalized, therefore |
1011 // seems OK to allocate finalized types in old space. | 995 // seems OK to allocate finalized types in old space. |
1012 if (!type_param.CheckBound(type_arg, instantiated_bound, | 996 if (!type_param.CheckBound(type_arg, instantiated_bound, &error, NULL, |
1013 &error, NULL, Heap::kOld) && | 997 Heap::kOld) && |
1014 error.IsNull()) { | 998 error.IsNull()) { |
1015 // The bound cannot be checked at compile time; postpone to run time. | 999 // The bound cannot be checked at compile time; postpone to run time. |
1016 type_arg = BoundedType::New(type_arg, instantiated_bound, type_param); | 1000 type_arg = BoundedType::New(type_arg, instantiated_bound, type_param); |
1017 arguments.SetTypeAt(offset + i, type_arg); | 1001 arguments.SetTypeAt(offset + i, type_arg); |
1018 } | 1002 } |
1019 } | 1003 } |
1020 if (!error.IsNull() && bound_error->IsNull()) { | 1004 if (!error.IsNull() && bound_error->IsNull()) { |
1021 *bound_error = error.raw(); | 1005 *bound_error = error.raw(); |
1022 } | 1006 } |
1023 } | 1007 } |
(...skipping 25 matching lines...) Expand all Loading... |
1049 Error& bound_error = Error::Handle(zone); | 1033 Error& bound_error = Error::Handle(zone); |
1050 CheckTypeArgumentBounds(type_class, arguments, &bound_error); | 1034 CheckTypeArgumentBounds(type_class, arguments, &bound_error); |
1051 // CheckTypeArgumentBounds may have indirectly canonicalized this type. | 1035 // CheckTypeArgumentBounds may have indirectly canonicalized this type. |
1052 if (!type.IsCanonical()) { | 1036 if (!type.IsCanonical()) { |
1053 type.set_arguments(arguments); | 1037 type.set_arguments(arguments); |
1054 // If a bound error occurred, mark the type as malbounded. | 1038 // If a bound error occurred, mark the type as malbounded. |
1055 // The bound error will be ignored in production mode. | 1039 // The bound error will be ignored in production mode. |
1056 if (!bound_error.IsNull()) { | 1040 if (!bound_error.IsNull()) { |
1057 // No compile-time error during finalization. | 1041 // No compile-time error during finalization. |
1058 const String& type_name = String::Handle(zone, type.UserVisibleName()); | 1042 const String& type_name = String::Handle(zone, type.UserVisibleName()); |
1059 FinalizeMalboundedType(bound_error, | 1043 FinalizeMalboundedType( |
1060 Script::Handle(zone, cls.script()), | 1044 bound_error, Script::Handle(zone, cls.script()), type, |
1061 type, | 1045 "type '%s' has an out of bound type argument", type_name.ToCString()); |
1062 "type '%s' has an out of bound type argument", | |
1063 type_name.ToCString()); | |
1064 if (FLAG_trace_type_finalization) { | 1046 if (FLAG_trace_type_finalization) { |
1065 THR_Print("Marking type '%s' as malbounded: %s\n", | 1047 THR_Print("Marking type '%s' as malbounded: %s\n", |
1066 String::Handle(zone, type.Name()).ToCString(), | 1048 String::Handle(zone, type.Name()).ToCString(), |
1067 bound_error.ToErrorCString()); | 1049 bound_error.ToErrorCString()); |
1068 } | 1050 } |
1069 } | 1051 } |
1070 } | 1052 } |
1071 if (FLAG_trace_type_finalization) { | 1053 if (FLAG_trace_type_finalization) { |
1072 THR_Print("Done checking bounds of type '%s': %s\n", | 1054 THR_Print("Done checking bounds of type '%s': %s\n", |
1073 String::Handle(zone, type.Name()).ToCString(), | 1055 String::Handle(zone, type.Name()).ToCString(), type.ToCString()); |
1074 type.ToCString()); | |
1075 } | 1056 } |
1076 } | 1057 } |
1077 | 1058 |
1078 | 1059 |
1079 RawAbstractType* ClassFinalizer::FinalizeType( | 1060 RawAbstractType* ClassFinalizer::FinalizeType(const Class& cls, |
1080 const Class& cls, | 1061 const AbstractType& type, |
1081 const AbstractType& type, | 1062 FinalizationKind finalization, |
1082 FinalizationKind finalization, | 1063 PendingTypes* pending_types) { |
1083 PendingTypes* pending_types) { | |
1084 // Only the 'root' type of the graph can be canonicalized, after all depending | 1064 // Only the 'root' type of the graph can be canonicalized, after all depending |
1085 // types have been bound checked. | 1065 // types have been bound checked. |
1086 ASSERT((pending_types == NULL) || (finalization < kCanonicalize)); | 1066 ASSERT((pending_types == NULL) || (finalization < kCanonicalize)); |
1087 if (type.IsFinalized()) { | 1067 if (type.IsFinalized()) { |
1088 // Ensure type is canonical if canonicalization is requested, unless type is | 1068 // Ensure type is canonical if canonicalization is requested, unless type is |
1089 // malformed. | 1069 // malformed. |
1090 if ((finalization >= kCanonicalize) && | 1070 if ((finalization >= kCanonicalize) && !type.IsMalformed() && |
1091 !type.IsMalformed() && | 1071 !type.IsCanonical() && type.IsType()) { |
1092 !type.IsCanonical() && | |
1093 type.IsType()) { | |
1094 CheckTypeBounds(cls, type); | 1072 CheckTypeBounds(cls, type); |
1095 return type.Canonicalize(); | 1073 return type.Canonicalize(); |
1096 } | 1074 } |
1097 return type.raw(); | 1075 return type.raw(); |
1098 } | 1076 } |
1099 ASSERT(finalization >= kFinalize); | 1077 ASSERT(finalization >= kFinalize); |
1100 | 1078 |
1101 if (type.IsTypeRef()) { | 1079 if (type.IsTypeRef()) { |
1102 // The referenced type will be finalized later by the code that set the | 1080 // The referenced type will be finalized later by the code that set the |
1103 // is_being_finalized mark bit. | 1081 // is_being_finalized mark bit. |
(...skipping 88 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1192 if (scope_class.IsTypedefClass()) { | 1170 if (scope_class.IsTypedefClass()) { |
1193 FinalizeSignature(scope_class, signature); | 1171 FinalizeSignature(scope_class, signature); |
1194 } else { | 1172 } else { |
1195 FinalizeSignature(cls, signature); | 1173 FinalizeSignature(cls, signature); |
1196 } | 1174 } |
1197 } | 1175 } |
1198 | 1176 |
1199 if (FLAG_trace_type_finalization) { | 1177 if (FLAG_trace_type_finalization) { |
1200 THR_Print("Done finalizing type '%s' with %" Pd " type args: %s\n", | 1178 THR_Print("Done finalizing type '%s' with %" Pd " type args: %s\n", |
1201 String::Handle(zone, type.Name()).ToCString(), | 1179 String::Handle(zone, type.Name()).ToCString(), |
1202 num_expanded_type_arguments, | 1180 num_expanded_type_arguments, type.ToCString()); |
1203 type.ToCString()); | |
1204 } | 1181 } |
1205 | 1182 |
1206 if (finalization >= kCanonicalize) { | 1183 if (finalization >= kCanonicalize) { |
1207 if (FLAG_trace_type_finalization) { | 1184 if (FLAG_trace_type_finalization) { |
1208 THR_Print("Canonicalizing type '%s'\n", | 1185 THR_Print("Canonicalizing type '%s'\n", |
1209 String::Handle(zone, type.Name()).ToCString()); | 1186 String::Handle(zone, type.Name()).ToCString()); |
1210 AbstractType& canonical_type = | 1187 AbstractType& canonical_type = |
1211 AbstractType::Handle(zone, type.Canonicalize()); | 1188 AbstractType::Handle(zone, type.Canonicalize()); |
1212 THR_Print("Done canonicalizing type '%s'\n", | 1189 THR_Print("Done canonicalizing type '%s'\n", |
1213 String::Handle(zone, canonical_type.Name()).ToCString()); | 1190 String::Handle(zone, canonical_type.Name()).ToCString()); |
(...skipping 76 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1290 | 1267 |
1291 | 1268 |
1292 // Check if an instance method of same name exists in any super class. | 1269 // Check if an instance method of same name exists in any super class. |
1293 static RawClass* FindSuperOwnerOfFunction(const Class& cls, | 1270 static RawClass* FindSuperOwnerOfFunction(const Class& cls, |
1294 const String& name) { | 1271 const String& name) { |
1295 Class& super_class = Class::Handle(); | 1272 Class& super_class = Class::Handle(); |
1296 Function& function = Function::Handle(); | 1273 Function& function = Function::Handle(); |
1297 super_class = cls.SuperClass(); | 1274 super_class = cls.SuperClass(); |
1298 while (!super_class.IsNull()) { | 1275 while (!super_class.IsNull()) { |
1299 function = super_class.LookupFunction(name); | 1276 function = super_class.LookupFunction(name); |
1300 if (!function.IsNull() && | 1277 if (!function.IsNull() && !function.is_static() && |
1301 !function.is_static() && | |
1302 !function.IsMethodExtractor()) { | 1278 !function.IsMethodExtractor()) { |
1303 return super_class.raw(); | 1279 return super_class.raw(); |
1304 } | 1280 } |
1305 super_class = super_class.SuperClass(); | 1281 super_class = super_class.SuperClass(); |
1306 } | 1282 } |
1307 return Class::null(); | 1283 return Class::null(); |
1308 } | 1284 } |
1309 | 1285 |
1310 | 1286 |
1311 // Resolve the upper bounds of the type parameters of class cls. | 1287 // Resolve the upper bounds of the type parameters of class cls. |
(...skipping 78 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1390 name = field.name(); | 1366 name = field.name(); |
1391 if (field.is_static()) { | 1367 if (field.is_static()) { |
1392 getter_name = Field::GetterSymbol(name); | 1368 getter_name = Field::GetterSymbol(name); |
1393 super_class = FindSuperOwnerOfInstanceMember(cls, name, getter_name); | 1369 super_class = FindSuperOwnerOfInstanceMember(cls, name, getter_name); |
1394 if (!super_class.IsNull()) { | 1370 if (!super_class.IsNull()) { |
1395 const String& class_name = String::Handle(zone, cls.Name()); | 1371 const String& class_name = String::Handle(zone, cls.Name()); |
1396 const String& super_cls_name = String::Handle(zone, super_class.Name()); | 1372 const String& super_cls_name = String::Handle(zone, super_class.Name()); |
1397 ReportError(cls, field.token_pos(), | 1373 ReportError(cls, field.token_pos(), |
1398 "static field '%s' of class '%s' conflicts with " | 1374 "static field '%s' of class '%s' conflicts with " |
1399 "instance member '%s' of super class '%s'", | 1375 "instance member '%s' of super class '%s'", |
1400 name.ToCString(), | 1376 name.ToCString(), class_name.ToCString(), name.ToCString(), |
1401 class_name.ToCString(), | |
1402 name.ToCString(), | |
1403 super_cls_name.ToCString()); | 1377 super_cls_name.ToCString()); |
1404 } | 1378 } |
1405 // An implicit setter is not generated for a static field, therefore, we | 1379 // An implicit setter is not generated for a static field, therefore, we |
1406 // cannot rely on the code below handling the static setter case to report | 1380 // cannot rely on the code below handling the static setter case to report |
1407 // a conflict with an instance setter. So we check explicitly here. | 1381 // a conflict with an instance setter. So we check explicitly here. |
1408 setter_name = Field::SetterSymbol(name); | 1382 setter_name = Field::SetterSymbol(name); |
1409 super_class = FindSuperOwnerOfFunction(cls, setter_name); | 1383 super_class = FindSuperOwnerOfFunction(cls, setter_name); |
1410 if (!super_class.IsNull()) { | 1384 if (!super_class.IsNull()) { |
1411 const String& class_name = String::Handle(zone, cls.Name()); | 1385 const String& class_name = String::Handle(zone, cls.Name()); |
1412 const String& super_cls_name = String::Handle(zone, super_class.Name()); | 1386 const String& super_cls_name = String::Handle(zone, super_class.Name()); |
1413 ReportError(cls, field.token_pos(), | 1387 ReportError(cls, field.token_pos(), |
1414 "static field '%s' of class '%s' conflicts with " | 1388 "static field '%s' of class '%s' conflicts with " |
1415 "instance setter '%s=' of super class '%s'", | 1389 "instance setter '%s=' of super class '%s'", |
1416 name.ToCString(), | 1390 name.ToCString(), class_name.ToCString(), name.ToCString(), |
1417 class_name.ToCString(), | |
1418 name.ToCString(), | |
1419 super_cls_name.ToCString()); | 1391 super_cls_name.ToCString()); |
1420 } | 1392 } |
1421 | 1393 |
1422 } else { | 1394 } else { |
1423 // Instance field. Check whether the field overrides a method | 1395 // Instance field. Check whether the field overrides a method |
1424 // (but not getter). | 1396 // (but not getter). |
1425 super_class = FindSuperOwnerOfFunction(cls, name); | 1397 super_class = FindSuperOwnerOfFunction(cls, name); |
1426 if (!super_class.IsNull()) { | 1398 if (!super_class.IsNull()) { |
1427 const String& class_name = String::Handle(zone, cls.Name()); | 1399 const String& class_name = String::Handle(zone, cls.Name()); |
1428 const String& super_cls_name = String::Handle(zone, super_class.Name()); | 1400 const String& super_cls_name = String::Handle(zone, super_class.Name()); |
1429 ReportError(cls, field.token_pos(), | 1401 ReportError(cls, field.token_pos(), |
1430 "field '%s' of class '%s' conflicts with method '%s' " | 1402 "field '%s' of class '%s' conflicts with method '%s' " |
1431 "of super class '%s'", | 1403 "of super class '%s'", |
1432 name.ToCString(), | 1404 name.ToCString(), class_name.ToCString(), name.ToCString(), |
1433 class_name.ToCString(), | |
1434 name.ToCString(), | |
1435 super_cls_name.ToCString()); | 1405 super_cls_name.ToCString()); |
1436 } | 1406 } |
1437 } | 1407 } |
1438 if (field.is_static() && | 1408 if (field.is_static() && (field.StaticValue() != Object::null()) && |
1439 (field.StaticValue() != Object::null()) && | |
1440 (field.StaticValue() != Object::sentinel().raw())) { | 1409 (field.StaticValue() != Object::sentinel().raw())) { |
1441 // The parser does not preset the value if the type is a type parameter or | 1410 // The parser does not preset the value if the type is a type parameter or |
1442 // is parameterized unless the value is null. | 1411 // is parameterized unless the value is null. |
1443 Error& error = Error::Handle(zone); | 1412 Error& error = Error::Handle(zone); |
1444 if (type.IsMalformedOrMalbounded()) { | 1413 if (type.IsMalformedOrMalbounded()) { |
1445 error = type.error(); | 1414 error = type.error(); |
1446 } else { | 1415 } else { |
1447 ASSERT(type.IsInstantiated()); | 1416 ASSERT(type.IsInstantiated()); |
1448 } | 1417 } |
1449 const Instance& const_value = | 1418 const Instance& const_value = Instance::Handle(zone, field.StaticValue()); |
1450 Instance::Handle(zone, field.StaticValue()); | |
1451 if (!error.IsNull() || | 1419 if (!error.IsNull() || |
1452 (!type.IsDynamicType() && | 1420 (!type.IsDynamicType() && |
1453 !const_value.IsInstanceOf(type, | 1421 !const_value.IsInstanceOf(type, Object::null_type_arguments(), |
1454 Object::null_type_arguments(), | |
1455 &error))) { | 1422 &error))) { |
1456 if (Isolate::Current()->error_on_bad_type()) { | 1423 if (Isolate::Current()->error_on_bad_type()) { |
1457 const AbstractType& const_value_type = AbstractType::Handle( | 1424 const AbstractType& const_value_type = |
1458 zone, const_value.GetType()); | 1425 AbstractType::Handle(zone, const_value.GetType()); |
1459 const String& const_value_type_name = String::Handle( | 1426 const String& const_value_type_name = |
1460 zone, const_value_type.UserVisibleName()); | 1427 String::Handle(zone, const_value_type.UserVisibleName()); |
1461 const String& type_name = String::Handle( | 1428 const String& type_name = |
1462 zone, type.UserVisibleName()); | 1429 String::Handle(zone, type.UserVisibleName()); |
1463 ReportErrors(error, cls, field.token_pos(), | 1430 ReportErrors(error, cls, field.token_pos(), |
1464 "error initializing static %s field '%s': " | 1431 "error initializing static %s field '%s': " |
1465 "type '%s' is not a subtype of type '%s'", | 1432 "type '%s' is not a subtype of type '%s'", |
1466 field.is_const() ? "const" : "final", | 1433 field.is_const() ? "const" : "final", name.ToCString(), |
1467 name.ToCString(), | |
1468 const_value_type_name.ToCString(), | 1434 const_value_type_name.ToCString(), |
1469 type_name.ToCString()); | 1435 type_name.ToCString()); |
1470 } else { | 1436 } else { |
1471 // Do not report an error yet, even in checked mode, since the field | 1437 // Do not report an error yet, even in checked mode, since the field |
1472 // may not actually be used. | 1438 // may not actually be used. |
1473 // Also, we may be generating a snapshot in production mode that will | 1439 // Also, we may be generating a snapshot in production mode that will |
1474 // later be executed in checked mode, in which case an error needs to | 1440 // later be executed in checked mode, in which case an error needs to |
1475 // be reported, should the field be accessed. | 1441 // be reported, should the field be accessed. |
1476 // Therefore, we undo the optimization performed by the parser, i.e. | 1442 // Therefore, we undo the optimization performed by the parser, i.e. |
1477 // we create an implicit static final getter and reset the field value | 1443 // we create an implicit static final getter and reset the field value |
1478 // to the sentinel value. | 1444 // to the sentinel value. |
1479 const Function& getter = Function::Handle( | 1445 const Function& getter = Function::Handle( |
1480 zone, | 1446 zone, Function::New( |
1481 Function::New(getter_name, | 1447 getter_name, RawFunction::kImplicitStaticFinalGetter, |
1482 RawFunction::kImplicitStaticFinalGetter, | 1448 /* is_static = */ true, |
1483 /* is_static = */ true, | 1449 /* is_const = */ field.is_const(), |
1484 /* is_const = */ field.is_const(), | 1450 /* is_abstract = */ false, |
1485 /* is_abstract = */ false, | 1451 /* is_external = */ false, |
1486 /* is_external = */ false, | 1452 /* is_native = */ false, cls, field.token_pos())); |
1487 /* is_native = */ false, | |
1488 cls, | |
1489 field.token_pos())); | |
1490 getter.set_result_type(type); | 1453 getter.set_result_type(type); |
1491 getter.set_is_debuggable(false); | 1454 getter.set_is_debuggable(false); |
1492 cls.AddFunction(getter); | 1455 cls.AddFunction(getter); |
1493 field.SetStaticValue(Object::sentinel(), true); | 1456 field.SetStaticValue(Object::sentinel(), true); |
1494 } | 1457 } |
1495 } | 1458 } |
1496 } | 1459 } |
1497 } | 1460 } |
1498 // Collect interfaces, super interfaces, and super classes of this class. | 1461 // Collect interfaces, super interfaces, and super classes of this class. |
1499 GrowableArray<const Class*> interfaces(zone, 4); | 1462 GrowableArray<const Class*> interfaces(zone, 4); |
(...skipping 10 matching lines...) Expand all Loading... |
1510 array = cls.functions(); | 1473 array = cls.functions(); |
1511 Function& function = Function::Handle(zone); | 1474 Function& function = Function::Handle(zone); |
1512 Function& overridden_function = Function::Handle(zone); | 1475 Function& overridden_function = Function::Handle(zone); |
1513 const intptr_t num_functions = array.Length(); | 1476 const intptr_t num_functions = array.Length(); |
1514 Error& error = Error::Handle(zone); | 1477 Error& error = Error::Handle(zone); |
1515 for (intptr_t i = 0; i < num_functions; i++) { | 1478 for (intptr_t i = 0; i < num_functions; i++) { |
1516 function ^= array.At(i); | 1479 function ^= array.At(i); |
1517 FinalizeSignature(cls, function); | 1480 FinalizeSignature(cls, function); |
1518 name = function.name(); | 1481 name = function.name(); |
1519 // Report signature conflicts only. | 1482 // Report signature conflicts only. |
1520 if (Isolate::Current()->error_on_bad_override() && | 1483 if (Isolate::Current()->error_on_bad_override() && !function.is_static() && |
1521 !function.is_static() && !function.IsGenerativeConstructor()) { | 1484 !function.IsGenerativeConstructor()) { |
1522 // A constructor cannot override anything. | 1485 // A constructor cannot override anything. |
1523 for (intptr_t i = 0; i < interfaces.length(); i++) { | 1486 for (intptr_t i = 0; i < interfaces.length(); i++) { |
1524 const Class* super_class = interfaces.At(i); | 1487 const Class* super_class = interfaces.At(i); |
1525 // Finalize superclass since overrides check relies on all members | 1488 // Finalize superclass since overrides check relies on all members |
1526 // of the superclass to be finalized. | 1489 // of the superclass to be finalized. |
1527 FinalizeClass(*super_class); | 1490 FinalizeClass(*super_class); |
1528 overridden_function = super_class->LookupDynamicFunction(name); | 1491 overridden_function = super_class->LookupDynamicFunction(name); |
1529 if (!overridden_function.IsNull() && | 1492 if (!overridden_function.IsNull() && |
1530 !function.HasCompatibleParametersWith(overridden_function, | 1493 !function.HasCompatibleParametersWith(overridden_function, |
1531 &error)) { | 1494 &error)) { |
1532 const String& class_name = String::Handle(zone, cls.Name()); | 1495 const String& class_name = String::Handle(zone, cls.Name()); |
1533 const String& super_cls_name = | 1496 const String& super_cls_name = |
1534 String::Handle(zone, super_class->Name()); | 1497 String::Handle(zone, super_class->Name()); |
1535 ReportErrors(error, cls, function.token_pos(), | 1498 ReportErrors(error, cls, function.token_pos(), |
1536 "class '%s' overrides method '%s' of super " | 1499 "class '%s' overrides method '%s' of super " |
1537 "class '%s' with incompatible parameters", | 1500 "class '%s' with incompatible parameters", |
1538 class_name.ToCString(), | 1501 class_name.ToCString(), name.ToCString(), |
1539 name.ToCString(), | |
1540 super_cls_name.ToCString()); | 1502 super_cls_name.ToCString()); |
1541 } | 1503 } |
1542 } | 1504 } |
1543 } | 1505 } |
1544 if (function.IsSetterFunction() || function.IsImplicitSetterFunction()) { | 1506 if (function.IsSetterFunction() || function.IsImplicitSetterFunction()) { |
1545 if (function.is_static()) { | 1507 if (function.is_static()) { |
1546 super_class = FindSuperOwnerOfFunction(cls, name); | 1508 super_class = FindSuperOwnerOfFunction(cls, name); |
1547 if (!super_class.IsNull()) { | 1509 if (!super_class.IsNull()) { |
1548 const String& class_name = String::Handle(zone, cls.Name()); | 1510 const String& class_name = String::Handle(zone, cls.Name()); |
1549 const String& super_cls_name = | 1511 const String& super_cls_name = |
1550 String::Handle(zone, super_class.Name()); | 1512 String::Handle(zone, super_class.Name()); |
1551 ReportError(cls, function.token_pos(), | 1513 ReportError(cls, function.token_pos(), |
1552 "static setter '%s=' of class '%s' conflicts with " | 1514 "static setter '%s=' of class '%s' conflicts with " |
1553 "instance setter '%s=' of super class '%s'", | 1515 "instance setter '%s=' of super class '%s'", |
1554 name.ToCString(), | 1516 name.ToCString(), class_name.ToCString(), |
1555 class_name.ToCString(), | 1517 name.ToCString(), super_cls_name.ToCString()); |
1556 name.ToCString(), | |
1557 super_cls_name.ToCString()); | |
1558 } | 1518 } |
1559 } | 1519 } |
1560 continue; | 1520 continue; |
1561 } | 1521 } |
1562 if (function.IsGetterFunction() || function.IsImplicitGetterFunction()) { | 1522 if (function.IsGetterFunction() || function.IsImplicitGetterFunction()) { |
1563 getter_name = name.raw(); | 1523 getter_name = name.raw(); |
1564 name = Field::NameFromGetter(getter_name); | 1524 name = Field::NameFromGetter(getter_name); |
1565 } else { | 1525 } else { |
1566 getter_name = Field::GetterSymbol(name); | 1526 getter_name = Field::GetterSymbol(name); |
1567 } | 1527 } |
1568 if (function.is_static()) { | 1528 if (function.is_static()) { |
1569 super_class = FindSuperOwnerOfInstanceMember(cls, name, getter_name); | 1529 super_class = FindSuperOwnerOfInstanceMember(cls, name, getter_name); |
1570 if (!super_class.IsNull()) { | 1530 if (!super_class.IsNull()) { |
1571 const String& class_name = String::Handle(zone, cls.Name()); | 1531 const String& class_name = String::Handle(zone, cls.Name()); |
1572 const String& super_cls_name = String::Handle(zone, super_class.Name()); | 1532 const String& super_cls_name = String::Handle(zone, super_class.Name()); |
1573 ReportError(cls, function.token_pos(), | 1533 ReportError( |
1574 "static %s '%s' of class '%s' conflicts with " | 1534 cls, function.token_pos(), |
1575 "instance member '%s' of super class '%s'", | 1535 "static %s '%s' of class '%s' conflicts with " |
1576 (function.IsGetterFunction() || | 1536 "instance member '%s' of super class '%s'", |
1577 function.IsImplicitGetterFunction()) ? "getter" : "method", | 1537 (function.IsGetterFunction() || function.IsImplicitGetterFunction()) |
1578 name.ToCString(), | 1538 ? "getter" |
1579 class_name.ToCString(), | 1539 : "method", |
1580 name.ToCString(), | 1540 name.ToCString(), class_name.ToCString(), name.ToCString(), |
1581 super_cls_name.ToCString()); | 1541 super_cls_name.ToCString()); |
1582 } | 1542 } |
1583 if (function.IsRedirectingFactory()) { | 1543 if (function.IsRedirectingFactory()) { |
1584 // The function may be a still unresolved redirecting factory. Do not | 1544 // The function may be a still unresolved redirecting factory. Do not |
1585 // yet try to resolve it in order to avoid cycles in class finalization. | 1545 // yet try to resolve it in order to avoid cycles in class finalization. |
1586 // However, the redirection type should be finalized. | 1546 // However, the redirection type should be finalized. |
1587 // If the redirection type is from a deferred library and is not | 1547 // If the redirection type is from a deferred library and is not |
1588 // yet loaded, do not attempt to resolve. | 1548 // yet loaded, do not attempt to resolve. |
1589 Type& type = Type::Handle(zone, function.RedirectionType()); | 1549 Type& type = Type::Handle(zone, function.RedirectionType()); |
1590 if (IsLoaded(type)) { | 1550 if (IsLoaded(type)) { |
1591 type ^= FinalizeType(cls, type, kCanonicalize); | 1551 type ^= FinalizeType(cls, type, kCanonicalize); |
1592 function.SetRedirectionType(type); | 1552 function.SetRedirectionType(type); |
1593 } | 1553 } |
1594 } | 1554 } |
1595 } else if (function.IsGetterFunction() || | 1555 } else if (function.IsGetterFunction() || |
1596 function.IsImplicitGetterFunction()) { | 1556 function.IsImplicitGetterFunction()) { |
1597 super_class = FindSuperOwnerOfFunction(cls, name); | 1557 super_class = FindSuperOwnerOfFunction(cls, name); |
1598 if (!super_class.IsNull()) { | 1558 if (!super_class.IsNull()) { |
1599 const String& class_name = String::Handle(zone, cls.Name()); | 1559 const String& class_name = String::Handle(zone, cls.Name()); |
1600 const String& super_cls_name = String::Handle(zone, super_class.Name()); | 1560 const String& super_cls_name = String::Handle(zone, super_class.Name()); |
1601 ReportError(cls, function.token_pos(), | 1561 ReportError(cls, function.token_pos(), |
1602 "getter '%s' of class '%s' conflicts with " | 1562 "getter '%s' of class '%s' conflicts with " |
1603 "method '%s' of super class '%s'", | 1563 "method '%s' of super class '%s'", |
1604 name.ToCString(), | 1564 name.ToCString(), class_name.ToCString(), name.ToCString(), |
1605 class_name.ToCString(), | |
1606 name.ToCString(), | |
1607 super_cls_name.ToCString()); | 1565 super_cls_name.ToCString()); |
1608 } | 1566 } |
1609 } else if (!function.IsSetterFunction() && | 1567 } else if (!function.IsSetterFunction() && |
1610 !function.IsImplicitSetterFunction()) { | 1568 !function.IsImplicitSetterFunction()) { |
1611 // A function cannot conflict with a setter, since they cannot | 1569 // A function cannot conflict with a setter, since they cannot |
1612 // have the same name. Thus, we do not need to check setters. | 1570 // have the same name. Thus, we do not need to check setters. |
1613 super_class = FindSuperOwnerOfFunction(cls, getter_name); | 1571 super_class = FindSuperOwnerOfFunction(cls, getter_name); |
1614 if (!super_class.IsNull()) { | 1572 if (!super_class.IsNull()) { |
1615 const String& class_name = String::Handle(zone, cls.Name()); | 1573 const String& class_name = String::Handle(zone, cls.Name()); |
1616 const String& super_cls_name = String::Handle(zone, super_class.Name()); | 1574 const String& super_cls_name = String::Handle(zone, super_class.Name()); |
1617 ReportError(cls, function.token_pos(), | 1575 ReportError(cls, function.token_pos(), |
1618 "method '%s' of class '%s' conflicts with " | 1576 "method '%s' of class '%s' conflicts with " |
1619 "getter '%s' of super class '%s'", | 1577 "getter '%s' of super class '%s'", |
1620 name.ToCString(), | 1578 name.ToCString(), class_name.ToCString(), name.ToCString(), |
1621 class_name.ToCString(), | |
1622 name.ToCString(), | |
1623 super_cls_name.ToCString()); | 1579 super_cls_name.ToCString()); |
1624 } | 1580 } |
1625 } | 1581 } |
1626 } | 1582 } |
1627 } | 1583 } |
1628 | 1584 |
1629 | 1585 |
1630 // Clone the type parameters of the super class and of the mixin class of this | 1586 // Clone the type parameters of the super class and of the mixin class of this |
1631 // mixin application class and use them as the type parameters of this mixin | 1587 // mixin application class and use them as the type parameters of this mixin |
1632 // application class. Set the type arguments of the super type, of the mixin | 1588 // application class. Set the type arguments of the super type, of the mixin |
1633 // type (as well as of the interface type, which is identical to the mixin type) | 1589 // type (as well as of the interface type, which is identical to the mixin type) |
1634 // to refer to the respective type parameters of the mixin application class. | 1590 // to refer to the respective type parameters of the mixin application class. |
1635 // In other words, decorate this mixin application class with type parameters | 1591 // In other words, decorate this mixin application class with type parameters |
1636 // that forward to the super type and mixin type (and interface type). | 1592 // that forward to the super type and mixin type (and interface type). |
1637 // Example: | 1593 // Example: |
1638 // class S<T extends BT> { } | 1594 // class S<T extends BT> { } |
1639 // class M<T extends BT> { } | 1595 // class M<T extends BT> { } |
1640 // class C<E extends BE> extends S<E> with M<List<E>> { } | 1596 // class C<E extends BE> extends S<E> with M<List<E>> { } |
1641 // results in | 1597 // results in |
1642 // class S&M<T`, T extends BT> extends S<T`> implements M<T> { } | 1598 // class S&M<T`, T extends BT> extends S<T`> implements M<T> { } |
1643 // class C<E extends BE> extends S&M<E, List<E>> { } | 1599 // class C<E extends BE> extends S&M<E, List<E>> { } |
1644 // CloneMixinAppTypeParameters decorates class S&M with type parameters T` and | 1600 // CloneMixinAppTypeParameters decorates class S&M with type parameters T` and |
1645 // T, and use them as type arguments in S<T`> and M<T>. | 1601 // T, and use them as type arguments in S<T`> and M<T>. |
1646 // Note that the bound BT on T of S is not applied to T` of S&M. However, the | 1602 // Note that the bound BT on T of S is not applied to T` of S&M. However, the |
1647 // bound BT on T of M is applied to T of S&M. See comments below. | 1603 // bound BT on T of M is applied to T of S&M. See comments below. |
1648 void ClassFinalizer::CloneMixinAppTypeParameters(const Class& mixin_app_class) { | 1604 void ClassFinalizer::CloneMixinAppTypeParameters(const Class& mixin_app_class) { |
1649 ASSERT(mixin_app_class.type_parameters() == TypeArguments::null()); | 1605 ASSERT(mixin_app_class.type_parameters() == TypeArguments::null()); |
1650 Thread* thread = Thread::Current(); | 1606 Thread* thread = Thread::Current(); |
1651 Zone* zone = thread->zone(); | 1607 Zone* zone = thread->zone(); |
1652 const AbstractType& super_type = AbstractType::Handle(zone, | 1608 const AbstractType& super_type = |
1653 mixin_app_class.super_type()); | 1609 AbstractType::Handle(zone, mixin_app_class.super_type()); |
1654 ASSERT(super_type.IsResolved()); | 1610 ASSERT(super_type.IsResolved()); |
1655 const Class& super_class = Class::Handle(zone, super_type.type_class()); | 1611 const Class& super_class = Class::Handle(zone, super_type.type_class()); |
1656 const intptr_t num_super_type_params = super_class.NumTypeParameters(); | 1612 const intptr_t num_super_type_params = super_class.NumTypeParameters(); |
1657 const Type& mixin_type = Type::Handle(zone, mixin_app_class.mixin()); | 1613 const Type& mixin_type = Type::Handle(zone, mixin_app_class.mixin()); |
1658 const Class& mixin_class = Class::Handle(zone, mixin_type.type_class()); | 1614 const Class& mixin_class = Class::Handle(zone, mixin_type.type_class()); |
1659 const intptr_t num_mixin_type_params = mixin_class.NumTypeParameters(); | 1615 const intptr_t num_mixin_type_params = mixin_class.NumTypeParameters(); |
1660 | 1616 |
1661 // The mixin type (in raw form) should have been added to the interfaces | 1617 // The mixin type (in raw form) should have been added to the interfaces |
1662 // implemented by the mixin application class. This is necessary so that cycle | 1618 // implemented by the mixin application class. This is necessary so that cycle |
1663 // check works at compile time (type arguments are ignored) and so that | 1619 // check works at compile time (type arguments are ignored) and so that |
(...skipping 15 matching lines...) Expand all Loading... |
1679 for (intptr_t i = name.Length() - 1; i > 0; --i) { | 1635 for (intptr_t i = name.Length() - 1; i > 0; --i) { |
1680 if (name.CharAt(i) == '&') { | 1636 if (name.CharAt(i) == '&') { |
1681 if (name.CharAt(i - 1) == '&') { | 1637 if (name.CharAt(i - 1) == '&') { |
1682 share_type_params = true; | 1638 share_type_params = true; |
1683 } | 1639 } |
1684 break; | 1640 break; |
1685 } | 1641 } |
1686 } | 1642 } |
1687 } | 1643 } |
1688 | 1644 |
1689 const TypeArguments& cloned_type_params = TypeArguments::Handle(zone, | 1645 const TypeArguments& cloned_type_params = TypeArguments::Handle( |
| 1646 zone, |
1690 TypeArguments::New((share_type_params ? 0 : num_super_type_params) + | 1647 TypeArguments::New((share_type_params ? 0 : num_super_type_params) + |
1691 num_mixin_type_params)); | 1648 num_mixin_type_params)); |
1692 TypeParameter& param = TypeParameter::Handle(zone); | 1649 TypeParameter& param = TypeParameter::Handle(zone); |
1693 TypeParameter& cloned_param = TypeParameter::Handle(zone); | 1650 TypeParameter& cloned_param = TypeParameter::Handle(zone); |
1694 String& param_name = String::Handle(zone); | 1651 String& param_name = String::Handle(zone); |
1695 AbstractType& param_bound = AbstractType::Handle(zone); | 1652 AbstractType& param_bound = AbstractType::Handle(zone); |
1696 Function& null_function = Function::Handle(zone); | 1653 Function& null_function = Function::Handle(zone); |
1697 intptr_t cloned_index = 0; | 1654 intptr_t cloned_index = 0; |
1698 | 1655 |
1699 // First, clone the super class type parameters. Rename them so that | 1656 // First, clone the super class type parameters. Rename them so that |
1700 // there can be no name conflict between the parameters of the super | 1657 // there can be no name conflict between the parameters of the super |
1701 // class and the mixin class. | 1658 // class and the mixin class. |
1702 if (!share_type_params && (num_super_type_params > 0)) { | 1659 if (!share_type_params && (num_super_type_params > 0)) { |
1703 const TypeArguments& super_type_params = | 1660 const TypeArguments& super_type_params = |
1704 TypeArguments::Handle(zone, super_class.type_parameters()); | 1661 TypeArguments::Handle(zone, super_class.type_parameters()); |
1705 const TypeArguments& super_type_args = TypeArguments::Handle(zone, | 1662 const TypeArguments& super_type_args = TypeArguments::Handle( |
1706 TypeArguments::New(num_super_type_params)); | 1663 zone, TypeArguments::New(num_super_type_params)); |
1707 // The cloned super class type parameters do not need to repeat their | 1664 // The cloned super class type parameters do not need to repeat their |
1708 // bounds, since the bound checks will be performed at the super class | 1665 // bounds, since the bound checks will be performed at the super class |
1709 // level. As a consequence, if this mixin application is used itself as a | 1666 // level. As a consequence, if this mixin application is used itself as a |
1710 // mixin in another mixin application, the bounds will be ignored, which | 1667 // mixin in another mixin application, the bounds will be ignored, which |
1711 // is correct, because the other mixin application does not inherit from | 1668 // is correct, because the other mixin application does not inherit from |
1712 // the super class of its mixin. Note also that the other mixin | 1669 // the super class of its mixin. Note also that the other mixin |
1713 // application will only mixin the last mixin type listed in the first | 1670 // application will only mixin the last mixin type listed in the first |
1714 // mixin application it is mixing in. | 1671 // mixin application it is mixing in. |
1715 param_bound = thread->isolate()->object_store()->object_type(); | 1672 param_bound = thread->isolate()->object_store()->object_type(); |
1716 for (intptr_t i = 0; i < num_super_type_params; i++) { | 1673 for (intptr_t i = 0; i < num_super_type_params; i++) { |
1717 param ^= super_type_params.TypeAt(i); | 1674 param ^= super_type_params.TypeAt(i); |
1718 param_name = param.name(); | 1675 param_name = param.name(); |
1719 param_name = Symbols::FromConcat(thread, | 1676 param_name = |
1720 param_name, Symbols::Backtick()); | 1677 Symbols::FromConcat(thread, param_name, Symbols::Backtick()); |
1721 cloned_param = TypeParameter::New(mixin_app_class, | 1678 cloned_param = |
1722 null_function, | 1679 TypeParameter::New(mixin_app_class, null_function, cloned_index, |
1723 cloned_index, | 1680 param_name, param_bound, param.token_pos()); |
1724 param_name, | |
1725 param_bound, | |
1726 param.token_pos()); | |
1727 cloned_type_params.SetTypeAt(cloned_index, cloned_param); | 1681 cloned_type_params.SetTypeAt(cloned_index, cloned_param); |
1728 // Change the type arguments of the super type to refer to the | 1682 // Change the type arguments of the super type to refer to the |
1729 // cloned type parameters of the mixin application class. | 1683 // cloned type parameters of the mixin application class. |
1730 super_type_args.SetTypeAt(cloned_index, cloned_param); | 1684 super_type_args.SetTypeAt(cloned_index, cloned_param); |
1731 cloned_index++; | 1685 cloned_index++; |
1732 } | 1686 } |
1733 // The super type may have a BoundedType as type argument, but cannot be | 1687 // The super type may have a BoundedType as type argument, but cannot be |
1734 // a BoundedType itself. | 1688 // a BoundedType itself. |
1735 Type::Cast(super_type).set_arguments(super_type_args); | 1689 Type::Cast(super_type).set_arguments(super_type_args); |
1736 ASSERT(!super_type.IsFinalized()); | 1690 ASSERT(!super_type.IsFinalized()); |
1737 } | 1691 } |
1738 | 1692 |
1739 // Second, clone the type parameters of the mixin class. | 1693 // Second, clone the type parameters of the mixin class. |
1740 // We need to retain the parameter names of the mixin class | 1694 // We need to retain the parameter names of the mixin class |
1741 // since the code that will be compiled in the context of the | 1695 // since the code that will be compiled in the context of the |
1742 // mixin application class may refer to the type parameters | 1696 // mixin application class may refer to the type parameters |
1743 // with that name. We also retain the type parameter bounds. | 1697 // with that name. We also retain the type parameter bounds. |
1744 if (num_mixin_type_params > 0) { | 1698 if (num_mixin_type_params > 0) { |
1745 const TypeArguments& mixin_params = | 1699 const TypeArguments& mixin_params = |
1746 TypeArguments::Handle(zone, mixin_class.type_parameters()); | 1700 TypeArguments::Handle(zone, mixin_class.type_parameters()); |
1747 const intptr_t offset = | 1701 const intptr_t offset = |
1748 mixin_class.NumTypeArguments() - mixin_class.NumTypeParameters(); | 1702 mixin_class.NumTypeArguments() - mixin_class.NumTypeParameters(); |
1749 const TypeArguments& mixin_type_args = TypeArguments::Handle(zone, | 1703 const TypeArguments& mixin_type_args = TypeArguments::Handle( |
1750 TypeArguments::New(num_mixin_type_params)); | 1704 zone, TypeArguments::New(num_mixin_type_params)); |
1751 instantiator ^= TypeArguments::New(offset + num_mixin_type_params); | 1705 instantiator ^= TypeArguments::New(offset + num_mixin_type_params); |
1752 bool has_uninstantiated_bounds = false; | 1706 bool has_uninstantiated_bounds = false; |
1753 for (intptr_t i = 0; i < num_mixin_type_params; i++) { | 1707 for (intptr_t i = 0; i < num_mixin_type_params; i++) { |
1754 param ^= mixin_params.TypeAt(i); | 1708 param ^= mixin_params.TypeAt(i); |
1755 param_name = param.name(); | 1709 param_name = param.name(); |
1756 param_bound = param.bound(); // The bound will be adjusted below. | 1710 param_bound = param.bound(); // The bound will be adjusted below. |
1757 if (!param_bound.IsInstantiated()) { | 1711 if (!param_bound.IsInstantiated()) { |
1758 has_uninstantiated_bounds = true; | 1712 has_uninstantiated_bounds = true; |
1759 } | 1713 } |
1760 cloned_param = TypeParameter::New(mixin_app_class, | 1714 cloned_param = |
1761 null_function, | 1715 TypeParameter::New(mixin_app_class, null_function, |
1762 cloned_index, // Unfinalized index. | 1716 cloned_index, // Unfinalized index. |
1763 param_name, | 1717 param_name, param_bound, param.token_pos()); |
1764 param_bound, | |
1765 param.token_pos()); | |
1766 cloned_type_params.SetTypeAt(cloned_index, cloned_param); | 1718 cloned_type_params.SetTypeAt(cloned_index, cloned_param); |
1767 mixin_type_args.SetTypeAt(i, cloned_param); // Unfinalized length. | 1719 mixin_type_args.SetTypeAt(i, cloned_param); // Unfinalized length. |
1768 instantiator.SetTypeAt(offset + i, cloned_param); // Finalized length. | 1720 instantiator.SetTypeAt(offset + i, cloned_param); // Finalized length. |
1769 cloned_index++; | 1721 cloned_index++; |
1770 } | 1722 } |
1771 | 1723 |
1772 // Third, replace the type parameters appearing in the bounds of the mixin | 1724 // Third, replace the type parameters appearing in the bounds of the mixin |
1773 // type parameters, if any, by the cloned type parameters. This can be | 1725 // type parameters, if any, by the cloned type parameters. This can be |
1774 // done by instantiating each bound using the instantiator built above. | 1726 // done by instantiating each bound using the instantiator built above. |
1775 // If the mixin class extends a generic super class, its first finalized | 1727 // If the mixin class extends a generic super class, its first finalized |
1776 // type parameter has a non-zero index, therefore, the instantiator | 1728 // type parameter has a non-zero index, therefore, the instantiator |
1777 // requires shifting by the offset calculated above. | 1729 // requires shifting by the offset calculated above. |
1778 // Unfinalized type parameters replace finalized type parameters, which | 1730 // Unfinalized type parameters replace finalized type parameters, which |
1779 // is not a problem since they will get finalized shortly as the mixin | 1731 // is not a problem since they will get finalized shortly as the mixin |
1780 // application class gets finalized. | 1732 // application class gets finalized. |
1781 if (has_uninstantiated_bounds) { | 1733 if (has_uninstantiated_bounds) { |
1782 Error& bound_error = Error::Handle(zone); | 1734 Error& bound_error = Error::Handle(zone); |
1783 for (intptr_t i = 0; i < num_mixin_type_params; i++) { | 1735 for (intptr_t i = 0; i < num_mixin_type_params; i++) { |
1784 param ^= mixin_type_args.TypeAt(i); | 1736 param ^= mixin_type_args.TypeAt(i); |
1785 param_bound = param.bound(); | 1737 param_bound = param.bound(); |
1786 if (!param_bound.IsInstantiated()) { | 1738 if (!param_bound.IsInstantiated()) { |
1787 // Make sure the bound is finalized before instantiating it. | 1739 // Make sure the bound is finalized before instantiating it. |
1788 if (!param_bound.IsFinalized() && | 1740 if (!param_bound.IsFinalized() && !param_bound.IsBeingFinalized()) { |
1789 !param_bound.IsBeingFinalized()) { | |
1790 param_bound = | 1741 param_bound = |
1791 FinalizeType(mixin_app_class, param_bound, kCanonicalize); | 1742 FinalizeType(mixin_app_class, param_bound, kCanonicalize); |
1792 param.set_bound(param_bound); // In case part of recursive type. | 1743 param.set_bound(param_bound); // In case part of recursive type. |
1793 } | 1744 } |
1794 param_bound = param_bound.InstantiateFrom( | 1745 param_bound = param_bound.InstantiateFrom( |
1795 instantiator, &bound_error, NULL, NULL, Heap::kOld); | 1746 instantiator, &bound_error, NULL, NULL, Heap::kOld); |
1796 // The instantiator contains only TypeParameter objects and no | 1747 // The instantiator contains only TypeParameter objects and no |
1797 // BoundedType objects, so no bound error may occur. | 1748 // BoundedType objects, so no bound error may occur. |
1798 ASSERT(!param_bound.IsBoundedType()); | 1749 ASSERT(!param_bound.IsBoundedType()); |
1799 ASSERT(bound_error.IsNull()); | 1750 ASSERT(bound_error.IsNull()); |
(...skipping 95 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1895 This is done in the recursive call to CloneMixinAppTypeParameters and does not | 1846 This is done in the recursive call to CloneMixinAppTypeParameters and does not |
1896 require specific code in ApplyMixinAppAlias. | 1847 require specific code in ApplyMixinAppAlias. |
1897 */ | 1848 */ |
1898 void ClassFinalizer::ApplyMixinAppAlias(const Class& mixin_app_class, | 1849 void ClassFinalizer::ApplyMixinAppAlias(const Class& mixin_app_class, |
1899 const TypeArguments& instantiator) { | 1850 const TypeArguments& instantiator) { |
1900 // If this mixin alias is aliasing another mixin alias, another class | 1851 // If this mixin alias is aliasing another mixin alias, another class |
1901 // will be inserted via recursion. No need to check here. | 1852 // will be inserted via recursion. No need to check here. |
1902 // The mixin type may or may not be finalized yet. | 1853 // The mixin type may or may not be finalized yet. |
1903 Thread* thread = Thread::Current(); | 1854 Thread* thread = Thread::Current(); |
1904 Zone* zone = thread->zone(); | 1855 Zone* zone = thread->zone(); |
1905 AbstractType& super_type = AbstractType::Handle(zone, | 1856 AbstractType& super_type = |
1906 mixin_app_class.super_type()); | 1857 AbstractType::Handle(zone, mixin_app_class.super_type()); |
1907 const Type& mixin_type = Type::Handle(zone, mixin_app_class.mixin()); | 1858 const Type& mixin_type = Type::Handle(zone, mixin_app_class.mixin()); |
1908 const Class& mixin_class = Class::Handle(zone, mixin_type.type_class()); | 1859 const Class& mixin_class = Class::Handle(zone, mixin_type.type_class()); |
1909 ASSERT(mixin_class.is_mixin_app_alias()); | 1860 ASSERT(mixin_class.is_mixin_app_alias()); |
1910 const Class& aliased_mixin_app_class = Class::Handle(zone, | 1861 const Class& aliased_mixin_app_class = |
1911 mixin_class.SuperClass()); | 1862 Class::Handle(zone, mixin_class.SuperClass()); |
1912 // Note that the super class of aliased_mixin_app_class can itself be a | 1863 // Note that the super class of aliased_mixin_app_class can itself be a |
1913 // mixin application class (this happens if the alias is mixing more than one | 1864 // mixin application class (this happens if the alias is mixing more than one |
1914 // type). Instead of trying to recursively insert yet another class as the | 1865 // type). Instead of trying to recursively insert yet another class as the |
1915 // super class of this inserted class, we apply the composition rules of the | 1866 // super class of this inserted class, we apply the composition rules of the |
1916 // spec and only mixin the members of aliased_mixin_app_class, not those of | 1867 // spec and only mixin the members of aliased_mixin_app_class, not those of |
1917 // its super class. In other words, we only mixin the last mixin of the alias. | 1868 // its super class. In other words, we only mixin the last mixin of the alias. |
1918 const Type& aliased_mixin_type = Type::Handle(zone, | 1869 const Type& aliased_mixin_type = |
1919 aliased_mixin_app_class.mixin()); | 1870 Type::Handle(zone, aliased_mixin_app_class.mixin()); |
1920 // The name of the inserted mixin application class is the name of mixin | 1871 // The name of the inserted mixin application class is the name of mixin |
1921 // class name with a backtick added. | 1872 // class name with a backtick added. |
1922 String& inserted_class_name = String::Handle(zone, mixin_app_class.Name()); | 1873 String& inserted_class_name = String::Handle(zone, mixin_app_class.Name()); |
1923 inserted_class_name = String::Concat(inserted_class_name, | 1874 inserted_class_name = |
1924 Symbols::Backtick()); | 1875 String::Concat(inserted_class_name, Symbols::Backtick()); |
1925 const Library& library = Library::Handle(zone, mixin_app_class.library()); | 1876 const Library& library = Library::Handle(zone, mixin_app_class.library()); |
1926 Class& inserted_class = Class::Handle(zone, | 1877 Class& inserted_class = |
1927 library.LookupLocalClass(inserted_class_name)); | 1878 Class::Handle(zone, library.LookupLocalClass(inserted_class_name)); |
1928 if (inserted_class.IsNull()) { | 1879 if (inserted_class.IsNull()) { |
1929 inserted_class_name = Symbols::New(thread, inserted_class_name); | 1880 inserted_class_name = Symbols::New(thread, inserted_class_name); |
1930 const Script& script = Script::Handle(zone, mixin_app_class.script()); | 1881 const Script& script = Script::Handle(zone, mixin_app_class.script()); |
1931 inserted_class = Class::New( | 1882 inserted_class = Class::New(library, inserted_class_name, script, |
1932 library, inserted_class_name, script, mixin_app_class.token_pos()); | 1883 mixin_app_class.token_pos()); |
1933 inserted_class.set_is_synthesized_class(); | 1884 inserted_class.set_is_synthesized_class(); |
1934 library.AddClass(inserted_class); | 1885 library.AddClass(inserted_class); |
1935 | 1886 |
1936 if (FLAG_trace_class_finalization) { | 1887 if (FLAG_trace_class_finalization) { |
1937 THR_Print("Creating mixin application alias %s\n", | 1888 THR_Print("Creating mixin application alias %s\n", |
1938 inserted_class.ToCString()); | 1889 inserted_class.ToCString()); |
1939 } | 1890 } |
1940 | 1891 |
1941 // The super type of the inserted class is identical to the super type of | 1892 // The super type of the inserted class is identical to the super type of |
1942 // this mixin application class, except that it must refer to the type | 1893 // this mixin application class, except that it must refer to the type |
1943 // parameters of the inserted class rather than to those of the mixin | 1894 // parameters of the inserted class rather than to those of the mixin |
1944 // application class. | 1895 // application class. |
1945 // The type arguments of the super type will be set properly when calling | 1896 // The type arguments of the super type will be set properly when calling |
1946 // CloneMixinAppTypeParameters on the inserted class, as long as the super | 1897 // CloneMixinAppTypeParameters on the inserted class, as long as the super |
1947 // type class is set properly. | 1898 // type class is set properly. |
1948 inserted_class.set_super_type(super_type); // Super class only is used. | 1899 inserted_class.set_super_type(super_type); // Super class only is used. |
1949 | 1900 |
1950 // The mixin type and interface type must also be set before calling | 1901 // The mixin type and interface type must also be set before calling |
1951 // CloneMixinAppTypeParameters. | 1902 // CloneMixinAppTypeParameters. |
1952 // After FinalizeTypesInClass, if the mixin type and interface type are | 1903 // After FinalizeTypesInClass, if the mixin type and interface type are |
1953 // generic, their type arguments will refer to the type parameters of | 1904 // generic, their type arguments will refer to the type parameters of |
1954 // inserted_class. | 1905 // inserted_class. |
1955 const Type& inserted_class_mixin_type = Type::Handle(zone, | 1906 const Type& inserted_class_mixin_type = Type::Handle( |
1956 Type::New(Class::Handle(zone, aliased_mixin_type.type_class()), | 1907 zone, Type::New(Class::Handle(zone, aliased_mixin_type.type_class()), |
1957 Object::null_type_arguments(), | 1908 Object::null_type_arguments(), |
1958 aliased_mixin_type.token_pos())); | 1909 aliased_mixin_type.token_pos())); |
1959 inserted_class.set_mixin(inserted_class_mixin_type); | 1910 inserted_class.set_mixin(inserted_class_mixin_type); |
1960 // Add the mixin type to the list of interfaces that the mixin application | 1911 // Add the mixin type to the list of interfaces that the mixin application |
1961 // class implements. This is necessary so that cycle check work at | 1912 // class implements. This is necessary so that cycle check work at |
1962 // compile time (type arguments are ignored by that check). | 1913 // compile time (type arguments are ignored by that check). |
1963 const Array& interfaces = Array::Handle(Array::New(1)); | 1914 const Array& interfaces = Array::Handle(Array::New(1)); |
1964 interfaces.SetAt(0, inserted_class_mixin_type); | 1915 interfaces.SetAt(0, inserted_class_mixin_type); |
1965 ASSERT(inserted_class.interfaces() == Object::empty_array().raw()); | 1916 ASSERT(inserted_class.interfaces() == Object::empty_array().raw()); |
1966 inserted_class.set_interfaces(interfaces); | 1917 inserted_class.set_interfaces(interfaces); |
1967 // The type arguments of the interface, if any, will be set in | 1918 // The type arguments of the interface, if any, will be set in |
1968 // CloneMixinAppTypeParameters, which is called indirectly from | 1919 // CloneMixinAppTypeParameters, which is called indirectly from |
(...skipping 19 matching lines...) Expand all Loading... |
1988 ASSERT(mixin_app_class.SuperClass() == super_class.raw()); // Will change. | 1939 ASSERT(mixin_app_class.SuperClass() == super_class.raw()); // Will change. |
1989 const intptr_t num_super_type_params = super_class.NumTypeParameters(); | 1940 const intptr_t num_super_type_params = super_class.NumTypeParameters(); |
1990 AbstractType& type = AbstractType::Handle(zone); | 1941 AbstractType& type = AbstractType::Handle(zone); |
1991 // The instantiator is mapping finalized type parameters of mixin_class to | 1942 // The instantiator is mapping finalized type parameters of mixin_class to |
1992 // unfinalized type parameters of mixin_app_class. Therefore, the type | 1943 // unfinalized type parameters of mixin_app_class. Therefore, the type |
1993 // arguments of mixin_class_super_type must be finalized, since they get | 1944 // arguments of mixin_class_super_type must be finalized, since they get |
1994 // instantiated by this instantiator. Finalizing the types in mixin_class | 1945 // instantiated by this instantiator. Finalizing the types in mixin_class |
1995 // will finalize mixin_class_super_type. | 1946 // will finalize mixin_class_super_type. |
1996 // The aliased_mixin_type does not need to be finalized, but only resolved. | 1947 // The aliased_mixin_type does not need to be finalized, but only resolved. |
1997 ASSERT(aliased_mixin_type.IsResolved()); | 1948 ASSERT(aliased_mixin_type.IsResolved()); |
1998 const Class& aliased_mixin_type_class = Class::Handle(zone, | 1949 const Class& aliased_mixin_type_class = |
1999 aliased_mixin_type.type_class()); | 1950 Class::Handle(zone, aliased_mixin_type.type_class()); |
2000 FinalizeTypesInClass(mixin_class); | 1951 FinalizeTypesInClass(mixin_class); |
2001 const intptr_t num_aliased_mixin_type_params = | 1952 const intptr_t num_aliased_mixin_type_params = |
2002 aliased_mixin_type_class.NumTypeParameters(); | 1953 aliased_mixin_type_class.NumTypeParameters(); |
2003 ASSERT(inserted_class.NumTypeParameters() == | 1954 ASSERT(inserted_class.NumTypeParameters() == |
2004 (num_super_type_params + num_aliased_mixin_type_params)); | 1955 (num_super_type_params + num_aliased_mixin_type_params)); |
2005 const AbstractType& mixin_class_super_type = | 1956 const AbstractType& mixin_class_super_type = |
2006 AbstractType::Handle(zone, mixin_class.super_type()); | 1957 AbstractType::Handle(zone, mixin_class.super_type()); |
2007 ASSERT(mixin_class_super_type.IsFinalized()); | 1958 ASSERT(mixin_class_super_type.IsFinalized()); |
2008 // The aliased_mixin_type may be raw. | 1959 // The aliased_mixin_type may be raw. |
2009 const TypeArguments& mixin_class_super_type_args = | 1960 const TypeArguments& mixin_class_super_type_args = |
(...skipping 15 matching lines...) Expand all Loading... |
2025 // be instantiated separately. Instantiating a BoundedType would wrap | 1976 // be instantiated separately. Instantiating a BoundedType would wrap |
2026 // the BoundedType in another BoundedType. | 1977 // the BoundedType in another BoundedType. |
2027 if (type.IsBoundedType()) { | 1978 if (type.IsBoundedType()) { |
2028 bounded_type = BoundedType::Cast(type).type(); | 1979 bounded_type = BoundedType::Cast(type).type(); |
2029 bounded_type = bounded_type.InstantiateFrom( | 1980 bounded_type = bounded_type.InstantiateFrom( |
2030 instantiator, &bound_error, NULL, NULL, Heap::kOld); | 1981 instantiator, &bound_error, NULL, NULL, Heap::kOld); |
2031 // The instantiator contains only TypeParameter objects and no | 1982 // The instantiator contains only TypeParameter objects and no |
2032 // BoundedType objects, so no bound error may occur. | 1983 // BoundedType objects, so no bound error may occur. |
2033 ASSERT(bound_error.IsNull()); | 1984 ASSERT(bound_error.IsNull()); |
2034 upper_bound = BoundedType::Cast(type).bound(); | 1985 upper_bound = BoundedType::Cast(type).bound(); |
2035 upper_bound = upper_bound.InstantiateFrom( | 1986 upper_bound = upper_bound.InstantiateFrom(instantiator, &bound_error, |
2036 instantiator, &bound_error, NULL, NULL, Heap::kOld); | 1987 NULL, NULL, Heap::kOld); |
2037 ASSERT(bound_error.IsNull()); | 1988 ASSERT(bound_error.IsNull()); |
2038 type_parameter = BoundedType::Cast(type).type_parameter(); | 1989 type_parameter = BoundedType::Cast(type).type_parameter(); |
2039 // The type parameter that declared the bound does not change. | 1990 // The type parameter that declared the bound does not change. |
2040 type = BoundedType::New(bounded_type, upper_bound, type_parameter); | 1991 type = BoundedType::New(bounded_type, upper_bound, type_parameter); |
2041 } else { | 1992 } else { |
2042 type = type.InstantiateFrom( | 1993 type = type.InstantiateFrom(instantiator, &bound_error, NULL, NULL, |
2043 instantiator, &bound_error, NULL, NULL, Heap::kOld); | 1994 Heap::kOld); |
2044 ASSERT(bound_error.IsNull()); | 1995 ASSERT(bound_error.IsNull()); |
2045 } | 1996 } |
2046 } | 1997 } |
2047 new_mixin_type_args.SetTypeAt(i, type); | 1998 new_mixin_type_args.SetTypeAt(i, type); |
2048 } | 1999 } |
2049 } | 2000 } |
2050 TypeArguments& new_super_type_args = TypeArguments::Handle(zone); | 2001 TypeArguments& new_super_type_args = TypeArguments::Handle(zone); |
2051 if ((num_super_type_params + num_aliased_mixin_type_params) > 0) { | 2002 if ((num_super_type_params + num_aliased_mixin_type_params) > 0) { |
2052 new_super_type_args = TypeArguments::New(num_super_type_params + | 2003 new_super_type_args = TypeArguments::New(num_super_type_params + |
2053 num_aliased_mixin_type_params); | 2004 num_aliased_mixin_type_params); |
2054 const TypeArguments& type_params = | 2005 const TypeArguments& type_params = |
2055 TypeArguments::Handle(zone, mixin_app_class.type_parameters()); | 2006 TypeArguments::Handle(zone, mixin_app_class.type_parameters()); |
2056 for (intptr_t i = 0; i < num_super_type_params; i++) { | 2007 for (intptr_t i = 0; i < num_super_type_params; i++) { |
2057 type = type_params.TypeAt(i); | 2008 type = type_params.TypeAt(i); |
2058 new_super_type_args.SetTypeAt(i, type); | 2009 new_super_type_args.SetTypeAt(i, type); |
2059 } | 2010 } |
2060 for (intptr_t i = 0; i < num_aliased_mixin_type_params; i++) { | 2011 for (intptr_t i = 0; i < num_aliased_mixin_type_params; i++) { |
2061 if (new_mixin_type_args.IsNull()) { | 2012 if (new_mixin_type_args.IsNull()) { |
2062 type = Type::DynamicType(); | 2013 type = Type::DynamicType(); |
2063 } else { | 2014 } else { |
2064 type = new_mixin_type_args.TypeAt(i); | 2015 type = new_mixin_type_args.TypeAt(i); |
2065 } | 2016 } |
2066 new_super_type_args.SetTypeAt(num_super_type_params + i, type); | 2017 new_super_type_args.SetTypeAt(num_super_type_params + i, type); |
2067 } | 2018 } |
2068 } | 2019 } |
2069 super_type = Type::New(inserted_class, | 2020 super_type = Type::New(inserted_class, new_super_type_args, |
2070 new_super_type_args, | |
2071 mixin_app_class.token_pos()); | 2021 mixin_app_class.token_pos()); |
2072 mixin_app_class.set_super_type(super_type); | 2022 mixin_app_class.set_super_type(super_type); |
2073 | 2023 |
2074 // Mark this mixin application class as being an alias. | 2024 // Mark this mixin application class as being an alias. |
2075 mixin_app_class.set_is_mixin_app_alias(); | 2025 mixin_app_class.set_is_mixin_app_alias(); |
2076 ASSERT(!mixin_app_class.is_type_finalized()); | 2026 ASSERT(!mixin_app_class.is_type_finalized()); |
2077 ASSERT(!mixin_app_class.is_mixin_type_applied()); | 2027 ASSERT(!mixin_app_class.is_mixin_type_applied()); |
2078 if (FLAG_trace_class_finalization) { | 2028 if (FLAG_trace_class_finalization) { |
2079 THR_Print("Inserting class '%s' %s\n" | 2029 THR_Print( |
2080 " as super type '%s' with %" Pd " type args: %s\n" | 2030 "Inserting class '%s' %s\n" |
2081 " of mixin application alias '%s' %s\n", | 2031 " as super type '%s' with %" Pd |
2082 String::Handle(inserted_class.Name()).ToCString(), | 2032 " type args: %s\n" |
2083 TypeArguments::Handle( | 2033 " of mixin application alias '%s' %s\n", |
2084 inserted_class.type_parameters()).ToCString(), | 2034 String::Handle(inserted_class.Name()).ToCString(), |
2085 String::Handle(zone, super_type.Name()).ToCString(), | 2035 TypeArguments::Handle(inserted_class.type_parameters()).ToCString(), |
2086 num_super_type_params + num_aliased_mixin_type_params, | 2036 String::Handle(zone, super_type.Name()).ToCString(), |
2087 super_type.ToCString(), | 2037 num_super_type_params + num_aliased_mixin_type_params, |
2088 String::Handle(mixin_app_class.Name()).ToCString(), | 2038 super_type.ToCString(), |
2089 TypeArguments::Handle( | 2039 String::Handle(mixin_app_class.Name()).ToCString(), |
2090 mixin_app_class.type_parameters()).ToCString()); | 2040 TypeArguments::Handle(mixin_app_class.type_parameters()).ToCString()); |
2091 } | 2041 } |
2092 } | 2042 } |
2093 | 2043 |
2094 | 2044 |
2095 void ClassFinalizer::ApplyMixinType(const Class& mixin_app_class, | 2045 void ClassFinalizer::ApplyMixinType(const Class& mixin_app_class, |
2096 PendingTypes* pending_types) { | 2046 PendingTypes* pending_types) { |
2097 if (mixin_app_class.is_mixin_type_applied()) { | 2047 if (mixin_app_class.is_mixin_type_applied()) { |
2098 return; | 2048 return; |
2099 } | 2049 } |
2100 Type& mixin_type = Type::Handle(mixin_app_class.mixin()); | 2050 Type& mixin_type = Type::Handle(mixin_app_class.mixin()); |
(...skipping 19 matching lines...) Expand all Loading... |
2120 | 2070 |
2121 // Copy type parameters to mixin application class. | 2071 // Copy type parameters to mixin application class. |
2122 CloneMixinAppTypeParameters(mixin_app_class); | 2072 CloneMixinAppTypeParameters(mixin_app_class); |
2123 | 2073 |
2124 // Verify that no restricted class is used as a mixin by checking the | 2074 // Verify that no restricted class is used as a mixin by checking the |
2125 // interfaces of the mixin application class, which implements its mixin. | 2075 // interfaces of the mixin application class, which implements its mixin. |
2126 GrowableArray<intptr_t> visited_interfaces; | 2076 GrowableArray<intptr_t> visited_interfaces; |
2127 ResolveSuperTypeAndInterfaces(mixin_app_class, &visited_interfaces); | 2077 ResolveSuperTypeAndInterfaces(mixin_app_class, &visited_interfaces); |
2128 | 2078 |
2129 if (FLAG_trace_class_finalization) { | 2079 if (FLAG_trace_class_finalization) { |
2130 THR_Print("Done applying mixin type '%s' to class '%s' %s extending '%s'\n", | 2080 THR_Print( |
2131 String::Handle(mixin_type.Name()).ToCString(), | 2081 "Done applying mixin type '%s' to class '%s' %s extending '%s'\n", |
2132 String::Handle(mixin_app_class.Name()).ToCString(), | 2082 String::Handle(mixin_type.Name()).ToCString(), |
2133 TypeArguments::Handle( | 2083 String::Handle(mixin_app_class.Name()).ToCString(), |
2134 mixin_app_class.type_parameters()).ToCString(), | 2084 TypeArguments::Handle(mixin_app_class.type_parameters()).ToCString(), |
2135 AbstractType::Handle(mixin_app_class.super_type()).ToCString()); | 2085 AbstractType::Handle(mixin_app_class.super_type()).ToCString()); |
2136 } | 2086 } |
2137 // Mark the application class as having been applied its mixin type in order | 2087 // Mark the application class as having been applied its mixin type in order |
2138 // to avoid cycles while finalizing its mixin type. | 2088 // to avoid cycles while finalizing its mixin type. |
2139 mixin_app_class.set_is_mixin_type_applied(); | 2089 mixin_app_class.set_is_mixin_type_applied(); |
2140 // Finalize the mixin type, which may have been changed in case | 2090 // Finalize the mixin type, which may have been changed in case |
2141 // mixin_app_class is an alias. | 2091 // mixin_app_class is an alias. |
2142 mixin_type = mixin_app_class.mixin(); | 2092 mixin_type = mixin_app_class.mixin(); |
2143 ASSERT(!mixin_type.IsBeingFinalized()); | 2093 ASSERT(!mixin_type.IsBeingFinalized()); |
2144 mixin_type ^= | 2094 mixin_type ^= |
2145 FinalizeType(mixin_app_class, mixin_type, kFinalize, pending_types); | 2095 FinalizeType(mixin_app_class, mixin_type, kFinalize, pending_types); |
(...skipping 16 matching lines...) Expand all Loading... |
2162 const String& super_name = String::Handle(Z, super_class.Name()); | 2112 const String& super_name = String::Handle(Z, super_class.Name()); |
2163 const Array& functions = Array::Handle(Z, super_class.functions()); | 2113 const Array& functions = Array::Handle(Z, super_class.functions()); |
2164 const intptr_t num_functions = functions.Length(); | 2114 const intptr_t num_functions = functions.Length(); |
2165 Function& func = Function::Handle(Z); | 2115 Function& func = Function::Handle(Z); |
2166 for (intptr_t i = 0; i < num_functions; i++) { | 2116 for (intptr_t i = 0; i < num_functions; i++) { |
2167 func ^= functions.At(i); | 2117 func ^= functions.At(i); |
2168 if (func.IsGenerativeConstructor()) { | 2118 if (func.IsGenerativeConstructor()) { |
2169 // Build constructor name from mixin application class name | 2119 // Build constructor name from mixin application class name |
2170 // and name of cloned super class constructor. | 2120 // and name of cloned super class constructor. |
2171 const String& ctor_name = String::Handle(Z, func.name()); | 2121 const String& ctor_name = String::Handle(Z, func.name()); |
2172 String& clone_name = String::Handle(Z, | 2122 String& clone_name = |
2173 String::SubString(ctor_name, super_name.Length())); | 2123 String::Handle(Z, String::SubString(ctor_name, super_name.Length())); |
2174 clone_name = Symbols::FromConcat(T, mixin_name, clone_name); | 2124 clone_name = Symbols::FromConcat(T, mixin_name, clone_name); |
2175 | 2125 |
2176 if (FLAG_trace_class_finalization) { | 2126 if (FLAG_trace_class_finalization) { |
2177 THR_Print("Cloning constructor '%s' as '%s'\n", | 2127 THR_Print("Cloning constructor '%s' as '%s'\n", ctor_name.ToCString(), |
2178 ctor_name.ToCString(), | |
2179 clone_name.ToCString()); | 2128 clone_name.ToCString()); |
2180 } | 2129 } |
2181 | 2130 |
2182 // The owner of the forwarding constructor is the mixin application | 2131 // The owner of the forwarding constructor is the mixin application |
2183 // class. The source is the mixin class. The source may be needed | 2132 // class. The source is the mixin class. The source may be needed |
2184 // to parse field initializer expressions in the mixin class. | 2133 // to parse field initializer expressions in the mixin class. |
2185 const PatchClass& owner = | 2134 const PatchClass& owner = |
2186 PatchClass::Handle(Z, PatchClass::New(mixin_app, mixin_cls)); | 2135 PatchClass::Handle(Z, PatchClass::New(mixin_app, mixin_cls)); |
2187 | 2136 |
2188 const Function& clone = Function::Handle(Z, | 2137 const Function& clone = Function::Handle( |
2189 Function::New(clone_name, | 2138 Z, Function::New(clone_name, func.kind(), func.is_static(), |
2190 func.kind(), | 2139 false, // Not const. |
2191 func.is_static(), | 2140 false, // Not abstract. |
2192 false, // Not const. | 2141 false, // Not external. |
2193 false, // Not abstract. | 2142 false, // Not native. |
2194 false, // Not external. | 2143 owner, mixin_cls.token_pos())); |
2195 false, // Not native. | |
2196 owner, | |
2197 mixin_cls.token_pos())); | |
2198 clone.set_num_fixed_parameters(func.num_fixed_parameters()); | 2144 clone.set_num_fixed_parameters(func.num_fixed_parameters()); |
2199 clone.SetNumOptionalParameters(func.NumOptionalParameters(), | 2145 clone.SetNumOptionalParameters(func.NumOptionalParameters(), |
2200 func.HasOptionalPositionalParameters()); | 2146 func.HasOptionalPositionalParameters()); |
2201 clone.set_result_type(Object::dynamic_type()); | 2147 clone.set_result_type(Object::dynamic_type()); |
2202 clone.set_is_debuggable(false); | 2148 clone.set_is_debuggable(false); |
2203 | 2149 |
2204 const intptr_t num_parameters = func.NumParameters(); | 2150 const intptr_t num_parameters = func.NumParameters(); |
2205 // The cloned ctor shares the parameter names array with the | 2151 // The cloned ctor shares the parameter names array with the |
2206 // original. | 2152 // original. |
2207 const Array& parameter_names = Array::Handle(Z, func.parameter_names()); | 2153 const Array& parameter_names = Array::Handle(Z, func.parameter_names()); |
(...skipping 21 matching lines...) Expand all Loading... |
2229 // apply here. A new synthesized class representing the aliased mixin | 2175 // apply here. A new synthesized class representing the aliased mixin |
2230 // application class was inserted in the super chain of this mixin application | 2176 // application class was inserted in the super chain of this mixin application |
2231 // class. Members of the actual mixin class will be applied when visiting | 2177 // class. Members of the actual mixin class will be applied when visiting |
2232 // the mixin application class referring to the actual mixin. | 2178 // the mixin application class referring to the actual mixin. |
2233 ASSERT(!mixin_cls.is_mixin_app_alias() || | 2179 ASSERT(!mixin_cls.is_mixin_app_alias() || |
2234 Class::Handle(zone, cls.SuperClass()).IsMixinApplication()); | 2180 Class::Handle(zone, cls.SuperClass()).IsMixinApplication()); |
2235 // A default constructor will be created for the mixin app alias class. | 2181 // A default constructor will be created for the mixin app alias class. |
2236 | 2182 |
2237 if (FLAG_trace_class_finalization) { | 2183 if (FLAG_trace_class_finalization) { |
2238 THR_Print("Applying mixin members of %s to %s at pos %s\n", | 2184 THR_Print("Applying mixin members of %s to %s at pos %s\n", |
2239 mixin_cls.ToCString(), | 2185 mixin_cls.ToCString(), cls.ToCString(), |
2240 cls.ToCString(), | |
2241 cls.token_pos().ToCString()); | 2186 cls.token_pos().ToCString()); |
2242 } | 2187 } |
2243 | 2188 |
2244 const GrowableObjectArray& cloned_funcs = | 2189 const GrowableObjectArray& cloned_funcs = |
2245 GrowableObjectArray::Handle(zone, GrowableObjectArray::New()); | 2190 GrowableObjectArray::Handle(zone, GrowableObjectArray::New()); |
2246 | 2191 |
2247 CreateForwardingConstructors(cls, mixin_cls, cloned_funcs); | 2192 CreateForwardingConstructors(cls, mixin_cls, cloned_funcs); |
2248 | 2193 |
2249 Array& functions = Array::Handle(zone); | 2194 Array& functions = Array::Handle(zone); |
2250 Function& func = Function::Handle(zone); | 2195 Function& func = Function::Handle(zone); |
2251 // The parser creates the mixin application class with no functions. | 2196 // The parser creates the mixin application class with no functions. |
2252 ASSERT((functions = cls.functions(), functions.Length() == 0)); | 2197 ASSERT((functions = cls.functions(), functions.Length() == 0)); |
2253 // Now clone the functions from the mixin class. | 2198 // Now clone the functions from the mixin class. |
2254 functions = mixin_cls.functions(); | 2199 functions = mixin_cls.functions(); |
2255 const intptr_t num_functions = functions.Length(); | 2200 const intptr_t num_functions = functions.Length(); |
2256 for (intptr_t i = 0; i < num_functions; i++) { | 2201 for (intptr_t i = 0; i < num_functions; i++) { |
2257 func ^= functions.At(i); | 2202 func ^= functions.At(i); |
2258 if (func.IsGenerativeConstructor()) { | 2203 if (func.IsGenerativeConstructor()) { |
2259 // A mixin class must not have explicit constructors. | 2204 // A mixin class must not have explicit constructors. |
2260 if (!func.IsImplicitConstructor()) { | 2205 if (!func.IsImplicitConstructor()) { |
2261 const Script& script = Script::Handle(cls.script()); | 2206 const Script& script = Script::Handle(cls.script()); |
2262 const Error& error = Error::Handle( | 2207 const Error& error = Error::Handle(LanguageError::NewFormatted( |
2263 LanguageError::NewFormatted(Error::Handle(), | 2208 Error::Handle(), script, func.token_pos(), Report::AtLocation, |
2264 script, func.token_pos(), Report::AtLocation, | 2209 Report::kError, Heap::kNew, |
2265 Report::kError, Heap::kNew, | 2210 "constructor '%s' is illegal in mixin class %s", |
2266 "constructor '%s' is illegal in mixin class %s", | 2211 String::Handle(func.UserVisibleName()).ToCString(), |
2267 String::Handle(func.UserVisibleName()).ToCString(), | 2212 String::Handle(zone, mixin_cls.Name()).ToCString())); |
2268 String::Handle(zone, mixin_cls.Name()).ToCString())); | |
2269 | 2213 |
2270 ReportErrors(error, cls, cls.token_pos(), | 2214 ReportErrors(error, cls, cls.token_pos(), |
2271 "mixin class '%s' must not have constructors", | 2215 "mixin class '%s' must not have constructors", |
2272 String::Handle(zone, mixin_cls.Name()).ToCString()); | 2216 String::Handle(zone, mixin_cls.Name()).ToCString()); |
2273 } | 2217 } |
2274 continue; // Skip the implicit constructor. | 2218 continue; // Skip the implicit constructor. |
2275 } | 2219 } |
2276 if (!func.is_static() && | 2220 if (!func.is_static() && !func.IsMethodExtractor() && |
2277 !func.IsMethodExtractor() && | 2221 !func.IsNoSuchMethodDispatcher() && !func.IsInvokeFieldDispatcher()) { |
2278 !func.IsNoSuchMethodDispatcher() && | |
2279 !func.IsInvokeFieldDispatcher()) { | |
2280 func = func.Clone(cls); | 2222 func = func.Clone(cls); |
2281 cloned_funcs.Add(func); | 2223 cloned_funcs.Add(func); |
2282 } | 2224 } |
2283 } | 2225 } |
2284 functions = Array::MakeArray(cloned_funcs); | 2226 functions = Array::MakeArray(cloned_funcs); |
2285 cls.SetFunctions(functions); | 2227 cls.SetFunctions(functions); |
2286 | 2228 |
2287 // Now clone the fields from the mixin class. There should be no | 2229 // Now clone the fields from the mixin class. There should be no |
2288 // existing fields in the mixin application class. | 2230 // existing fields in the mixin application class. |
2289 ASSERT(Array::Handle(cls.fields()).Length() == 0); | 2231 ASSERT(Array::Handle(cls.fields()).Length() == 0); |
2290 const Array& fields = Array::Handle(zone, mixin_cls.fields()); | 2232 const Array& fields = Array::Handle(zone, mixin_cls.fields()); |
2291 const intptr_t num_fields = fields.Length(); | 2233 const intptr_t num_fields = fields.Length(); |
2292 Field& field = Field::Handle(zone); | 2234 Field& field = Field::Handle(zone); |
2293 GrowableArray<const Field*> cloned_fields(num_fields); | 2235 GrowableArray<const Field*> cloned_fields(num_fields); |
2294 for (intptr_t i = 0; i < num_fields; i++) { | 2236 for (intptr_t i = 0; i < num_fields; i++) { |
2295 field ^= fields.At(i); | 2237 field ^= fields.At(i); |
2296 // Static fields are shared between the mixin class and the mixin | 2238 // Static fields are shared between the mixin class and the mixin |
2297 // application class. | 2239 // application class. |
2298 if (!field.is_static()) { | 2240 if (!field.is_static()) { |
2299 const Field& cloned = Field::ZoneHandle(zone, field.Clone(cls)); | 2241 const Field& cloned = Field::ZoneHandle(zone, field.Clone(cls)); |
2300 cloned_fields.Add(&cloned); | 2242 cloned_fields.Add(&cloned); |
2301 } | 2243 } |
2302 } | 2244 } |
2303 cls.AddFields(cloned_fields); | 2245 cls.AddFields(cloned_fields); |
2304 | 2246 |
2305 if (FLAG_trace_class_finalization) { | 2247 if (FLAG_trace_class_finalization) { |
2306 THR_Print("Done applying mixin members of %s to %s\n", | 2248 THR_Print("Done applying mixin members of %s to %s\n", |
2307 mixin_cls.ToCString(), | 2249 mixin_cls.ToCString(), cls.ToCString()); |
2308 cls.ToCString()); | |
2309 } | 2250 } |
2310 } | 2251 } |
2311 | 2252 |
2312 | 2253 |
2313 void ClassFinalizer::FinalizeTypesInClass(const Class& cls) { | 2254 void ClassFinalizer::FinalizeTypesInClass(const Class& cls) { |
2314 Thread* thread = Thread::Current(); | 2255 Thread* thread = Thread::Current(); |
2315 HANDLESCOPE(thread); | 2256 HANDLESCOPE(thread); |
2316 if (cls.is_type_finalized()) { | 2257 if (cls.is_type_finalized()) { |
2317 return; | 2258 return; |
2318 } | 2259 } |
(...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2361 } | 2302 } |
2362 if (cls.IsTypedefClass()) { | 2303 if (cls.IsTypedefClass()) { |
2363 const Function& signature = Function::Handle(cls.signature_function()); | 2304 const Function& signature = Function::Handle(cls.signature_function()); |
2364 Type& type = Type::Handle(signature.SignatureType()); | 2305 Type& type = Type::Handle(signature.SignatureType()); |
2365 | 2306 |
2366 // Check for illegal self references. | 2307 // Check for illegal self references. |
2367 GrowableArray<intptr_t> visited_aliases; | 2308 GrowableArray<intptr_t> visited_aliases; |
2368 if (!IsTypedefCycleFree(cls, type, &visited_aliases)) { | 2309 if (!IsTypedefCycleFree(cls, type, &visited_aliases)) { |
2369 const String& name = String::Handle(cls.Name()); | 2310 const String& name = String::Handle(cls.Name()); |
2370 ReportError(cls, cls.token_pos(), | 2311 ReportError(cls, cls.token_pos(), |
2371 "typedef '%s' illegally refers to itself", | 2312 "typedef '%s' illegally refers to itself", name.ToCString()); |
2372 name.ToCString()); | |
2373 } | 2313 } |
2374 cls.set_is_type_finalized(); | 2314 cls.set_is_type_finalized(); |
2375 | 2315 |
2376 // Resolve and finalize the result and parameter types of the signature | 2316 // Resolve and finalize the result and parameter types of the signature |
2377 // function of this typedef class. | 2317 // function of this typedef class. |
2378 FinalizeSignature(cls, signature); // Does not modify signature type. | 2318 FinalizeSignature(cls, signature); // Does not modify signature type. |
2379 ASSERT(signature.SignatureType() == type.raw()); | 2319 ASSERT(signature.SignatureType() == type.raw()); |
2380 | 2320 |
2381 // Resolve and finalize the signature type of this typedef. | 2321 // Resolve and finalize the signature type of this typedef. |
2382 type ^= FinalizeType(cls, type, kCanonicalizeWellFormed); | 2322 type ^= FinalizeType(cls, type, kCanonicalizeWellFormed); |
(...skipping 107 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2490 const Class& mixin_app_class = Class::Handle(cls.SuperClass()); | 2430 const Class& mixin_app_class = Class::Handle(cls.SuperClass()); |
2491 const Type& mixin_type = Type::Handle(mixin_app_class.mixin()); | 2431 const Type& mixin_type = Type::Handle(mixin_app_class.mixin()); |
2492 const Class& mixin_cls = Class::Handle(mixin_type.type_class()); | 2432 const Class& mixin_cls = Class::Handle(mixin_type.type_class()); |
2493 | 2433 |
2494 CreateForwardingConstructors(cls, mixin_cls, cloned_funcs); | 2434 CreateForwardingConstructors(cls, mixin_cls, cloned_funcs); |
2495 const Array& functions = Array::Handle(Array::MakeArray(cloned_funcs)); | 2435 const Array& functions = Array::Handle(Array::MakeArray(cloned_funcs)); |
2496 cls.SetFunctions(functions); | 2436 cls.SetFunctions(functions); |
2497 } | 2437 } |
2498 // Every class should have at least a constructor, unless it is a top level | 2438 // Every class should have at least a constructor, unless it is a top level |
2499 // class or a typedef class. | 2439 // class or a typedef class. |
2500 ASSERT(cls.IsTopLevel() || | 2440 ASSERT(cls.IsTopLevel() || cls.IsTypedefClass() || |
2501 cls.IsTypedefClass() || | |
2502 (Array::Handle(cls.functions()).Length() > 0)); | 2441 (Array::Handle(cls.functions()).Length() > 0)); |
2503 // Resolve and finalize all member types. | 2442 // Resolve and finalize all member types. |
2504 ResolveAndFinalizeMemberTypes(cls); | 2443 ResolveAndFinalizeMemberTypes(cls); |
2505 // Run additional checks after all types are finalized. | 2444 // Run additional checks after all types are finalized. |
2506 if (cls.is_const()) { | 2445 if (cls.is_const()) { |
2507 CheckForLegalConstClass(cls); | 2446 CheckForLegalConstClass(cls); |
2508 } | 2447 } |
2509 if (FLAG_use_cha_deopt) { | 2448 if (FLAG_use_cha_deopt) { |
2510 GrowableArray<intptr_t> cids; | 2449 GrowableArray<intptr_t> cids; |
2511 CollectFinalizedSuperClasses(cls, &cids); | 2450 CollectFinalizedSuperClasses(cls, &cids); |
(...skipping 11 matching lines...) Expand all Loading... |
2523 // By allocating the instances programmatically, we save an implicit final | 2462 // By allocating the instances programmatically, we save an implicit final |
2524 // getter function object for each enumeration value and for the | 2463 // getter function object for each enumeration value and for the |
2525 // values field. We also don't have to generate the code for these getters | 2464 // values field. We also don't have to generate the code for these getters |
2526 // from thin air (no source code is available). | 2465 // from thin air (no source code is available). |
2527 void ClassFinalizer::AllocateEnumValues(const Class& enum_cls) { | 2466 void ClassFinalizer::AllocateEnumValues(const Class& enum_cls) { |
2528 Thread* thread = Thread::Current(); | 2467 Thread* thread = Thread::Current(); |
2529 Zone* zone = thread->zone(); | 2468 Zone* zone = thread->zone(); |
2530 const Field& index_field = | 2469 const Field& index_field = |
2531 Field::Handle(zone, enum_cls.LookupInstanceField(Symbols::Index())); | 2470 Field::Handle(zone, enum_cls.LookupInstanceField(Symbols::Index())); |
2532 ASSERT(!index_field.IsNull()); | 2471 ASSERT(!index_field.IsNull()); |
2533 const Field& name_field = Field::Handle(zone, | 2472 const Field& name_field = Field::Handle( |
2534 enum_cls.LookupInstanceFieldAllowPrivate(Symbols::_name())); | 2473 zone, enum_cls.LookupInstanceFieldAllowPrivate(Symbols::_name())); |
2535 ASSERT(!name_field.IsNull()); | 2474 ASSERT(!name_field.IsNull()); |
2536 const Field& values_field = | 2475 const Field& values_field = |
2537 Field::Handle(zone, enum_cls.LookupStaticField(Symbols::Values())); | 2476 Field::Handle(zone, enum_cls.LookupStaticField(Symbols::Values())); |
2538 ASSERT(!values_field.IsNull()); | 2477 ASSERT(!values_field.IsNull()); |
2539 ASSERT(Instance::Handle(zone, values_field.StaticValue()).IsArray()); | 2478 ASSERT(Instance::Handle(zone, values_field.StaticValue()).IsArray()); |
2540 Array& values_list = Array::Handle( | 2479 Array& values_list = |
2541 zone, Array::RawCast(values_field.StaticValue())); | 2480 Array::Handle(zone, Array::RawCast(values_field.StaticValue())); |
2542 | 2481 |
2543 const Array& fields = Array::Handle(zone, enum_cls.fields()); | 2482 const Array& fields = Array::Handle(zone, enum_cls.fields()); |
2544 Field& field = Field::Handle(zone); | 2483 Field& field = Field::Handle(zone); |
2545 Instance& ordinal_value = Instance::Handle(zone); | 2484 Instance& ordinal_value = Instance::Handle(zone); |
2546 Instance& enum_value = Instance::Handle(zone); | 2485 Instance& enum_value = Instance::Handle(zone); |
2547 | 2486 |
2548 const String& enum_name = String::Handle(enum_cls.ScrubbedName()); | 2487 const String& enum_name = String::Handle(enum_cls.ScrubbedName()); |
2549 const String& name_prefix = | 2488 const String& name_prefix = |
2550 String::Handle(String::Concat(enum_name, Symbols::Dot())); | 2489 String::Handle(String::Concat(enum_name, Symbols::Dot())); |
2551 | 2490 |
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2585 values_list ^= values_list.CheckAndCanonicalize(thread, &error_msg); | 2524 values_list ^= values_list.CheckAndCanonicalize(thread, &error_msg); |
2586 ASSERT(!values_list.IsNull()); | 2525 ASSERT(!values_list.IsNull()); |
2587 } | 2526 } |
2588 | 2527 |
2589 | 2528 |
2590 bool ClassFinalizer::IsSuperCycleFree(const Class& cls) { | 2529 bool ClassFinalizer::IsSuperCycleFree(const Class& cls) { |
2591 Class& test1 = Class::Handle(cls.raw()); | 2530 Class& test1 = Class::Handle(cls.raw()); |
2592 Class& test2 = Class::Handle(cls.SuperClass()); | 2531 Class& test2 = Class::Handle(cls.SuperClass()); |
2593 // A finalized class has been checked for cycles. | 2532 // A finalized class has been checked for cycles. |
2594 // Using the hare and tortoise algorithm for locating cycles. | 2533 // Using the hare and tortoise algorithm for locating cycles. |
2595 while (!test1.is_type_finalized() && | 2534 while (!test1.is_type_finalized() && !test2.IsNull() && |
2596 !test2.IsNull() && !test2.is_type_finalized()) { | 2535 !test2.is_type_finalized()) { |
2597 if (test1.raw() == test2.raw()) { | 2536 if (test1.raw() == test2.raw()) { |
2598 // Found a cycle. | 2537 // Found a cycle. |
2599 return false; | 2538 return false; |
2600 } | 2539 } |
2601 test1 = test1.SuperClass(); | 2540 test1 = test1.SuperClass(); |
2602 test2 = test2.SuperClass(); | 2541 test2 = test2.SuperClass(); |
2603 if (!test2.IsNull()) { | 2542 if (!test2.IsNull()) { |
2604 test2 = test2.SuperClass(); | 2543 test2 = test2.SuperClass(); |
2605 } | 2544 } |
2606 } | 2545 } |
(...skipping 12 matching lines...) Expand all Loading... |
2619 if (type.IsType() && !type.IsMalformed()) { | 2558 if (type.IsType() && !type.IsMalformed()) { |
2620 AbstractType& other_type = AbstractType::Handle(); | 2559 AbstractType& other_type = AbstractType::Handle(); |
2621 if (type.IsFunctionType()) { | 2560 if (type.IsFunctionType()) { |
2622 const Class& scope_class = Class::Handle(type.type_class()); | 2561 const Class& scope_class = Class::Handle(type.type_class()); |
2623 const Function& signature_function = | 2562 const Function& signature_function = |
2624 Function::Handle(Type::Cast(type).signature()); | 2563 Function::Handle(Type::Cast(type).signature()); |
2625 // The signature function of this function type may be a local signature | 2564 // The signature function of this function type may be a local signature |
2626 // function used in a formal parameter type of the typedef signature, but | 2565 // function used in a formal parameter type of the typedef signature, but |
2627 // not the typedef signature function itself, thus not qualifying as an | 2566 // not the typedef signature function itself, thus not qualifying as an |
2628 // illegal self reference. | 2567 // illegal self reference. |
2629 if (!scope_class.is_type_finalized() && | 2568 if (!scope_class.is_type_finalized() && scope_class.IsTypedefClass() && |
2630 scope_class.IsTypedefClass() && | |
2631 (scope_class.signature_function() == signature_function.raw())) { | 2569 (scope_class.signature_function() == signature_function.raw())) { |
2632 checking_typedef = true; | 2570 checking_typedef = true; |
2633 const intptr_t scope_class_id = scope_class.id(); | 2571 const intptr_t scope_class_id = scope_class.id(); |
2634 ASSERT(visited != NULL); | 2572 ASSERT(visited != NULL); |
2635 for (intptr_t i = 0; i < visited->length(); i++) { | 2573 for (intptr_t i = 0; i < visited->length(); i++) { |
2636 if ((*visited)[i] == scope_class_id) { | 2574 if ((*visited)[i] == scope_class_id) { |
2637 // We have already visited alias 'scope_class'. We found a cycle. | 2575 // We have already visited alias 'scope_class'. We found a cycle. |
2638 return false; | 2576 return false; |
2639 } | 2577 } |
2640 } | 2578 } |
(...skipping 127 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2768 const GrowableObjectArray& type_args = | 2706 const GrowableObjectArray& type_args = |
2769 GrowableObjectArray::Handle(zone, GrowableObjectArray::New()); | 2707 GrowableObjectArray::Handle(zone, GrowableObjectArray::New()); |
2770 AbstractType& mixin_super_type = | 2708 AbstractType& mixin_super_type = |
2771 AbstractType::Handle(zone, mixin_app_type.super_type()); | 2709 AbstractType::Handle(zone, mixin_app_type.super_type()); |
2772 ResolveType(cls, mixin_super_type); | 2710 ResolveType(cls, mixin_super_type); |
2773 ASSERT(mixin_super_type.HasResolvedTypeClass()); // Even if malformed. | 2711 ASSERT(mixin_super_type.HasResolvedTypeClass()); // Even if malformed. |
2774 if (mixin_super_type.IsMalformedOrMalbounded()) { | 2712 if (mixin_super_type.IsMalformedOrMalbounded()) { |
2775 ReportError(Error::Handle(zone, mixin_super_type.error())); | 2713 ReportError(Error::Handle(zone, mixin_super_type.error())); |
2776 } | 2714 } |
2777 if (mixin_super_type.IsDynamicType()) { | 2715 if (mixin_super_type.IsDynamicType()) { |
2778 ReportError(cls, cls.token_pos(), | 2716 ReportError(cls, cls.token_pos(), "class '%s' may not extend 'dynamic'", |
2779 "class '%s' may not extend 'dynamic'", | |
2780 String::Handle(zone, cls.Name()).ToCString()); | 2717 String::Handle(zone, cls.Name()).ToCString()); |
2781 } | 2718 } |
2782 // The super type may have a BoundedType as type argument, but cannot be | 2719 // The super type may have a BoundedType as type argument, but cannot be |
2783 // a BoundedType itself. | 2720 // a BoundedType itself. |
2784 CollectTypeArguments(cls, Type::Cast(mixin_super_type), type_args); | 2721 CollectTypeArguments(cls, Type::Cast(mixin_super_type), type_args); |
2785 AbstractType& mixin_type = AbstractType::Handle(zone); | 2722 AbstractType& mixin_type = AbstractType::Handle(zone); |
2786 Class& mixin_type_class = Class::Handle(zone); | 2723 Class& mixin_type_class = Class::Handle(zone); |
2787 Class& mixin_app_class = Class::Handle(zone); | 2724 Class& mixin_app_class = Class::Handle(zone); |
2788 String& mixin_app_class_name = String::Handle(zone); | 2725 String& mixin_app_class_name = String::Handle(zone); |
2789 String& mixin_type_class_name = String::Handle(zone); | 2726 String& mixin_type_class_name = String::Handle(zone); |
2790 AbstractType& super_type_arg = AbstractType::Handle(zone); | 2727 AbstractType& super_type_arg = AbstractType::Handle(zone); |
2791 AbstractType& mixin_type_arg = AbstractType::Handle(zone); | 2728 AbstractType& mixin_type_arg = AbstractType::Handle(zone); |
2792 const intptr_t depth = mixin_app_type.Depth(); | 2729 const intptr_t depth = mixin_app_type.Depth(); |
2793 for (intptr_t i = 0; i < depth; i++) { | 2730 for (intptr_t i = 0; i < depth; i++) { |
2794 mixin_type = mixin_app_type.MixinTypeAt(i); | 2731 mixin_type = mixin_app_type.MixinTypeAt(i); |
2795 ASSERT(!mixin_type.IsNull()); | 2732 ASSERT(!mixin_type.IsNull()); |
2796 ResolveType(cls, mixin_type); | 2733 ResolveType(cls, mixin_type); |
2797 ASSERT(mixin_type.HasResolvedTypeClass()); // Even if malformed. | 2734 ASSERT(mixin_type.HasResolvedTypeClass()); // Even if malformed. |
2798 ASSERT(mixin_type.IsType()); | 2735 ASSERT(mixin_type.IsType()); |
2799 const intptr_t num_super_type_args = type_args.Length(); | 2736 const intptr_t num_super_type_args = type_args.Length(); |
2800 CollectTypeArguments(cls, Type::Cast(mixin_type), type_args); | 2737 CollectTypeArguments(cls, Type::Cast(mixin_type), type_args); |
2801 | 2738 |
2802 // If the mixin type has identical type arguments as the super type, they | 2739 // If the mixin type has identical type arguments as the super type, they |
2803 // can share the same type parameters of the mixin application class, | 2740 // can share the same type parameters of the mixin application class, |
2804 // thereby allowing for further optimizations, such as instantiator vector | 2741 // thereby allowing for further optimizations, such as instantiator vector |
2805 // reuse or sharing of type arguments with the super class. | 2742 // reuse or sharing of type arguments with the super class. |
2806 bool share_type_params = (num_super_type_args > 0) && | 2743 bool share_type_params = (num_super_type_args > 0) && |
2807 (type_args.Length() == 2*num_super_type_args); | 2744 (type_args.Length() == 2 * num_super_type_args); |
2808 if (share_type_params) { | 2745 if (share_type_params) { |
2809 for (intptr_t i = 0; i < num_super_type_args; i++) { | 2746 for (intptr_t i = 0; i < num_super_type_args; i++) { |
2810 super_type_arg ^= type_args.At(i); | 2747 super_type_arg ^= type_args.At(i); |
2811 mixin_type_arg ^= type_args.At(num_super_type_args + i); | 2748 mixin_type_arg ^= type_args.At(num_super_type_args + i); |
2812 if (!super_type_arg.Equals(mixin_type_arg)) { | 2749 if (!super_type_arg.Equals(mixin_type_arg)) { |
2813 share_type_params = false; | 2750 share_type_params = false; |
2814 break; | 2751 break; |
2815 } | 2752 } |
2816 } | 2753 } |
2817 if (share_type_params) { | 2754 if (share_type_params) { |
2818 // Cut the type argument vector in half. | 2755 // Cut the type argument vector in half. |
2819 type_args.SetLength(num_super_type_args); | 2756 type_args.SetLength(num_super_type_args); |
2820 } | 2757 } |
2821 } | 2758 } |
2822 | 2759 |
2823 // The name of the mixin application class is a combination of | 2760 // The name of the mixin application class is a combination of |
2824 // the super class name and mixin class name. | 2761 // the super class name and mixin class name. |
2825 mixin_app_class_name = mixin_super_type.ClassName(); | 2762 mixin_app_class_name = mixin_super_type.ClassName(); |
2826 mixin_app_class_name = String::Concat(mixin_app_class_name, | 2763 mixin_app_class_name = |
2827 Symbols::Ampersand()); | 2764 String::Concat(mixin_app_class_name, Symbols::Ampersand()); |
2828 // If the type parameters are shared between the super type and the mixin | 2765 // If the type parameters are shared between the super type and the mixin |
2829 // type, use two ampersand symbols, so that the class has a different name | 2766 // type, use two ampersand symbols, so that the class has a different name |
2830 // and is not reused in a context where this optimization is not possible. | 2767 // and is not reused in a context where this optimization is not possible. |
2831 if (share_type_params) { | 2768 if (share_type_params) { |
2832 mixin_app_class_name = String::Concat(mixin_app_class_name, | 2769 mixin_app_class_name = |
2833 Symbols::Ampersand()); | 2770 String::Concat(mixin_app_class_name, Symbols::Ampersand()); |
2834 } | 2771 } |
2835 mixin_type_class_name = mixin_type.ClassName(); | 2772 mixin_type_class_name = mixin_type.ClassName(); |
2836 mixin_app_class_name = String::Concat(mixin_app_class_name, | 2773 mixin_app_class_name = |
2837 mixin_type_class_name); | 2774 String::Concat(mixin_app_class_name, mixin_type_class_name); |
2838 mixin_app_class = library.LookupLocalClass(mixin_app_class_name); | 2775 mixin_app_class = library.LookupLocalClass(mixin_app_class_name); |
2839 if (mixin_app_class.IsNull()) { | 2776 if (mixin_app_class.IsNull()) { |
2840 mixin_app_class_name = Symbols::New(thread, mixin_app_class_name); | 2777 mixin_app_class_name = Symbols::New(thread, mixin_app_class_name); |
2841 mixin_app_class = Class::New(library, | 2778 mixin_app_class = Class::New(library, mixin_app_class_name, script, |
2842 mixin_app_class_name, | |
2843 script, | |
2844 mixin_type.token_pos()); | 2779 mixin_type.token_pos()); |
2845 mixin_app_class.set_super_type(mixin_super_type); | 2780 mixin_app_class.set_super_type(mixin_super_type); |
2846 mixin_type_class = mixin_type.type_class(); | 2781 mixin_type_class = mixin_type.type_class(); |
2847 const Type& generic_mixin_type = Type::Handle(zone, | 2782 const Type& generic_mixin_type = Type::Handle( |
2848 Type::New(mixin_type_class, | 2783 zone, Type::New(mixin_type_class, Object::null_type_arguments(), |
2849 Object::null_type_arguments(), | 2784 mixin_type.token_pos())); |
2850 mixin_type.token_pos())); | |
2851 mixin_app_class.set_mixin(generic_mixin_type); | 2785 mixin_app_class.set_mixin(generic_mixin_type); |
2852 // Add the mixin type to the list of interfaces that the mixin application | 2786 // Add the mixin type to the list of interfaces that the mixin application |
2853 // class implements. This is necessary so that cycle check work at | 2787 // class implements. This is necessary so that cycle check work at |
2854 // compile time (type arguments are ignored by that check). | 2788 // compile time (type arguments are ignored by that check). |
2855 const Array& interfaces = Array::Handle(zone, Array::New(1)); | 2789 const Array& interfaces = Array::Handle(zone, Array::New(1)); |
2856 interfaces.SetAt(0, generic_mixin_type); | 2790 interfaces.SetAt(0, generic_mixin_type); |
2857 ASSERT(mixin_app_class.interfaces() == Object::empty_array().raw()); | 2791 ASSERT(mixin_app_class.interfaces() == Object::empty_array().raw()); |
2858 mixin_app_class.set_interfaces(interfaces); | 2792 mixin_app_class.set_interfaces(interfaces); |
2859 mixin_app_class.set_is_synthesized_class(); | 2793 mixin_app_class.set_is_synthesized_class(); |
2860 library.AddClass(mixin_app_class); | 2794 library.AddClass(mixin_app_class); |
2861 | 2795 |
2862 // No need to add the new class to pending_classes, since it will be | 2796 // No need to add the new class to pending_classes, since it will be |
2863 // processed via the super_type chain of a pending class. | 2797 // processed via the super_type chain of a pending class. |
2864 | 2798 |
2865 if (FLAG_trace_class_finalization) { | 2799 if (FLAG_trace_class_finalization) { |
2866 THR_Print("Creating mixin application %s\n", | 2800 THR_Print("Creating mixin application %s\n", |
2867 mixin_app_class.ToCString()); | 2801 mixin_app_class.ToCString()); |
2868 } | 2802 } |
2869 } | 2803 } |
2870 // This mixin application class becomes the type class of the super type of | 2804 // This mixin application class becomes the type class of the super type of |
2871 // the next mixin application class. It is however too early to provide the | 2805 // the next mixin application class. It is however too early to provide the |
2872 // correct super type arguments. We use the raw type for now. | 2806 // correct super type arguments. We use the raw type for now. |
2873 mixin_super_type = Type::New(mixin_app_class, | 2807 mixin_super_type = Type::New(mixin_app_class, Object::null_type_arguments(), |
2874 Object::null_type_arguments(), | |
2875 mixin_type.token_pos()); | 2808 mixin_type.token_pos()); |
2876 } | 2809 } |
2877 TypeArguments& mixin_app_args = TypeArguments::Handle(zone); | 2810 TypeArguments& mixin_app_args = TypeArguments::Handle(zone); |
2878 if (type_args.Length() > 0) { | 2811 if (type_args.Length() > 0) { |
2879 mixin_app_args = TypeArguments::New(type_args.Length()); | 2812 mixin_app_args = TypeArguments::New(type_args.Length()); |
2880 AbstractType& type_arg = AbstractType::Handle(zone); | 2813 AbstractType& type_arg = AbstractType::Handle(zone); |
2881 for (intptr_t i = 0; i < type_args.Length(); i++) { | 2814 for (intptr_t i = 0; i < type_args.Length(); i++) { |
2882 type_arg ^= type_args.At(i); | 2815 type_arg ^= type_args.At(i); |
2883 mixin_app_args.SetTypeAt(i, type_arg); | 2816 mixin_app_args.SetTypeAt(i, type_arg); |
2884 } | 2817 } |
(...skipping 13 matching lines...) Expand all Loading... |
2898 | 2831 |
2899 | 2832 |
2900 // Recursively walks the graph of explicitly declared super type and | 2833 // Recursively walks the graph of explicitly declared super type and |
2901 // interfaces, resolving unresolved super types and interfaces. | 2834 // interfaces, resolving unresolved super types and interfaces. |
2902 // Reports an error if there is an interface reference that cannot be | 2835 // Reports an error if there is an interface reference that cannot be |
2903 // resolved, or if there is a cycle in the graph. We detect cycles by | 2836 // resolved, or if there is a cycle in the graph. We detect cycles by |
2904 // remembering interfaces we've visited in each path through the | 2837 // remembering interfaces we've visited in each path through the |
2905 // graph. If we visit an interface a second time on a given path, | 2838 // graph. If we visit an interface a second time on a given path, |
2906 // we found a loop. | 2839 // we found a loop. |
2907 void ClassFinalizer::ResolveSuperTypeAndInterfaces( | 2840 void ClassFinalizer::ResolveSuperTypeAndInterfaces( |
2908 const Class& cls, GrowableArray<intptr_t>* visited) { | 2841 const Class& cls, |
| 2842 GrowableArray<intptr_t>* visited) { |
2909 if (cls.is_cycle_free()) { | 2843 if (cls.is_cycle_free()) { |
2910 return; | 2844 return; |
2911 } | 2845 } |
2912 ASSERT(visited != NULL); | 2846 ASSERT(visited != NULL); |
2913 if (FLAG_trace_class_finalization) { | 2847 if (FLAG_trace_class_finalization) { |
2914 THR_Print("Resolving super and interfaces: %s\n", cls.ToCString()); | 2848 THR_Print("Resolving super and interfaces: %s\n", cls.ToCString()); |
2915 } | 2849 } |
2916 Zone* zone = Thread::Current()->zone(); | 2850 Zone* zone = Thread::Current()->zone(); |
2917 const intptr_t cls_index = cls.id(); | 2851 const intptr_t cls_index = cls.id(); |
2918 for (intptr_t i = 0; i < visited->length(); i++) { | 2852 for (intptr_t i = 0; i < visited->length(); i++) { |
2919 if ((*visited)[i] == cls_index) { | 2853 if ((*visited)[i] == cls_index) { |
2920 // We have already visited class 'cls'. We found a cycle. | 2854 // We have already visited class 'cls'. We found a cycle. |
2921 const String& class_name = String::Handle(zone, cls.Name()); | 2855 const String& class_name = String::Handle(zone, cls.Name()); |
2922 ReportError(cls, cls.token_pos(), | 2856 ReportError(cls, cls.token_pos(), "cyclic reference found for class '%s'", |
2923 "cyclic reference found for class '%s'", | |
2924 class_name.ToCString()); | 2857 class_name.ToCString()); |
2925 } | 2858 } |
2926 } | 2859 } |
2927 | 2860 |
2928 // If the class/interface has no explicit super class/interfaces | 2861 // If the class/interface has no explicit super class/interfaces |
2929 // and is not a mixin application, we are done. | 2862 // and is not a mixin application, we are done. |
2930 AbstractType& super_type = AbstractType::Handle(zone, cls.super_type()); | 2863 AbstractType& super_type = AbstractType::Handle(zone, cls.super_type()); |
2931 Array& super_interfaces = Array::Handle(zone, cls.interfaces()); | 2864 Array& super_interfaces = Array::Handle(zone, cls.interfaces()); |
2932 if ((super_type.IsNull() || super_type.IsObjectType()) && | 2865 if ((super_type.IsNull() || super_type.IsObjectType()) && |
2933 (super_interfaces.Length() == 0)) { | 2866 (super_interfaces.Length() == 0)) { |
(...skipping 19 matching lines...) Expand all Loading... |
2953 visited->Add(cls_index); | 2886 visited->Add(cls_index); |
2954 AbstractType& interface = AbstractType::Handle(zone); | 2887 AbstractType& interface = AbstractType::Handle(zone); |
2955 Class& interface_class = Class::Handle(zone); | 2888 Class& interface_class = Class::Handle(zone); |
2956 | 2889 |
2957 // Resolve super type. Failures lead to a longjmp. | 2890 // Resolve super type. Failures lead to a longjmp. |
2958 ResolveType(cls, super_type); | 2891 ResolveType(cls, super_type); |
2959 if (super_type.IsMalformedOrMalbounded()) { | 2892 if (super_type.IsMalformedOrMalbounded()) { |
2960 ReportError(Error::Handle(zone, super_type.error())); | 2893 ReportError(Error::Handle(zone, super_type.error())); |
2961 } | 2894 } |
2962 if (super_type.IsDynamicType()) { | 2895 if (super_type.IsDynamicType()) { |
2963 ReportError(cls, cls.token_pos(), | 2896 ReportError(cls, cls.token_pos(), "class '%s' may not extend 'dynamic'", |
2964 "class '%s' may not extend 'dynamic'", | |
2965 String::Handle(zone, cls.Name()).ToCString()); | 2897 String::Handle(zone, cls.Name()).ToCString()); |
2966 } | 2898 } |
2967 interface_class = super_type.type_class(); | 2899 interface_class = super_type.type_class(); |
2968 if (interface_class.IsTypedefClass()) { | 2900 if (interface_class.IsTypedefClass()) { |
2969 ReportError(cls, cls.token_pos(), | 2901 ReportError(cls, cls.token_pos(), |
2970 "class '%s' may not extend function type alias '%s'", | 2902 "class '%s' may not extend function type alias '%s'", |
2971 String::Handle(zone, cls.Name()).ToCString(), | 2903 String::Handle(zone, cls.Name()).ToCString(), |
2972 String::Handle(zone, | 2904 String::Handle(zone, super_type.UserVisibleName()).ToCString()); |
2973 super_type.UserVisibleName()).ToCString()); | |
2974 } | 2905 } |
2975 if (interface_class.is_enum_class()) { | 2906 if (interface_class.is_enum_class()) { |
2976 ReportError(cls, cls.token_pos(), | 2907 ReportError(cls, cls.token_pos(), "class '%s' may not extend enum '%s'", |
2977 "class '%s' may not extend enum '%s'", | |
2978 String::Handle(zone, cls.Name()).ToCString(), | 2908 String::Handle(zone, cls.Name()).ToCString(), |
2979 String::Handle(zone, interface_class.Name()).ToCString()); | 2909 String::Handle(zone, interface_class.Name()).ToCString()); |
2980 } | 2910 } |
2981 | 2911 |
2982 // If cls belongs to core lib or to core lib's implementation, restrictions | 2912 // If cls belongs to core lib or to core lib's implementation, restrictions |
2983 // about allowed interfaces are lifted. | 2913 // about allowed interfaces are lifted. |
2984 if (!cls_belongs_to_core_lib) { | 2914 if (!cls_belongs_to_core_lib) { |
2985 // Prevent extending core implementation classes. | 2915 // Prevent extending core implementation classes. |
2986 bool is_error = false; | 2916 bool is_error = false; |
2987 switch (interface_class.id()) { | 2917 switch (interface_class.id()) { |
2988 case kNumberCid: | 2918 case kNumberCid: |
2989 case kIntegerCid: // Class Integer, not int. | 2919 case kIntegerCid: // Class Integer, not int. |
2990 case kSmiCid: | 2920 case kSmiCid: |
2991 case kMintCid: | 2921 case kMintCid: |
2992 case kBigintCid: | 2922 case kBigintCid: |
2993 case kDoubleCid: // Class Double, not double. | 2923 case kDoubleCid: // Class Double, not double. |
2994 case kOneByteStringCid: | 2924 case kOneByteStringCid: |
2995 case kTwoByteStringCid: | 2925 case kTwoByteStringCid: |
2996 case kExternalOneByteStringCid: | 2926 case kExternalOneByteStringCid: |
2997 case kExternalTwoByteStringCid: | 2927 case kExternalTwoByteStringCid: |
2998 case kBoolCid: | 2928 case kBoolCid: |
2999 case kNullCid: | 2929 case kNullCid: |
3000 case kArrayCid: | 2930 case kArrayCid: |
3001 case kImmutableArrayCid: | 2931 case kImmutableArrayCid: |
3002 case kGrowableObjectArrayCid: | 2932 case kGrowableObjectArrayCid: |
3003 #define DO_NOT_EXTEND_TYPED_DATA_CLASSES(clazz) \ | 2933 #define DO_NOT_EXTEND_TYPED_DATA_CLASSES(clazz) \ |
3004 case kTypedData##clazz##Cid: \ | 2934 case kTypedData##clazz##Cid: \ |
3005 case kTypedData##clazz##ViewCid: \ | 2935 case kTypedData##clazz##ViewCid: \ |
3006 case kExternalTypedData##clazz##Cid: | 2936 case kExternalTypedData##clazz##Cid: |
3007 CLASS_LIST_TYPED_DATA(DO_NOT_EXTEND_TYPED_DATA_CLASSES) | 2937 CLASS_LIST_TYPED_DATA(DO_NOT_EXTEND_TYPED_DATA_CLASSES) |
3008 #undef DO_NOT_EXTEND_TYPED_DATA_CLASSES | 2938 #undef DO_NOT_EXTEND_TYPED_DATA_CLASSES |
3009 case kByteDataViewCid: | 2939 case kByteDataViewCid: |
3010 case kWeakPropertyCid: | 2940 case kWeakPropertyCid: |
3011 is_error = true; | 2941 is_error = true; |
3012 break; | 2942 break; |
3013 default: { | 2943 default: { |
3014 // Special case: classes for which we don't have a known class id. | 2944 // Special case: classes for which we don't have a known class id. |
3015 if (super_type.IsDoubleType() || | 2945 if (super_type.IsDoubleType() || super_type.IsIntType() || |
3016 super_type.IsIntType() || | |
3017 super_type.IsStringType()) { | 2946 super_type.IsStringType()) { |
3018 is_error = true; | 2947 is_error = true; |
3019 } | 2948 } |
3020 break; | 2949 break; |
3021 } | 2950 } |
3022 } | 2951 } |
3023 if (is_error) { | 2952 if (is_error) { |
3024 const String& interface_name = String::Handle(zone, | 2953 const String& interface_name = |
3025 interface_class.Name()); | 2954 String::Handle(zone, interface_class.Name()); |
3026 ReportError(cls, cls.token_pos(), | 2955 ReportError(cls, cls.token_pos(), "'%s' is not allowed to extend '%s'", |
3027 "'%s' is not allowed to extend '%s'", | |
3028 String::Handle(zone, cls.Name()).ToCString(), | 2956 String::Handle(zone, cls.Name()).ToCString(), |
3029 interface_name.ToCString()); | 2957 interface_name.ToCString()); |
3030 } | 2958 } |
3031 } | 2959 } |
3032 // Now resolve the super interfaces of the super type. | 2960 // Now resolve the super interfaces of the super type. |
3033 ResolveSuperTypeAndInterfaces(interface_class, visited); | 2961 ResolveSuperTypeAndInterfaces(interface_class, visited); |
3034 | 2962 |
3035 // Resolve interfaces. Failures lead to a longjmp. | 2963 // Resolve interfaces. Failures lead to a longjmp. |
3036 for (intptr_t i = 0; i < super_interfaces.Length(); i++) { | 2964 for (intptr_t i = 0; i < super_interfaces.Length(); i++) { |
3037 interface ^= super_interfaces.At(i); | 2965 interface ^= super_interfaces.At(i); |
3038 ResolveType(cls, interface); | 2966 ResolveType(cls, interface); |
3039 ASSERT(!interface.IsTypeParameter()); // Should be detected by parser. | 2967 ASSERT(!interface.IsTypeParameter()); // Should be detected by parser. |
3040 // A malbounded interface is only reported when involved in a type test. | 2968 // A malbounded interface is only reported when involved in a type test. |
3041 if (interface.IsMalformed()) { | 2969 if (interface.IsMalformed()) { |
3042 ReportError(Error::Handle(zone, interface.error())); | 2970 ReportError(Error::Handle(zone, interface.error())); |
3043 } | 2971 } |
3044 if (interface.IsDynamicType()) { | 2972 if (interface.IsDynamicType()) { |
3045 ReportError(cls, cls.token_pos(), | 2973 ReportError(cls, cls.token_pos(), |
3046 "'dynamic' may not be used as interface"); | 2974 "'dynamic' may not be used as interface"); |
3047 } | 2975 } |
3048 interface_class = interface.type_class(); | 2976 interface_class = interface.type_class(); |
3049 if (interface_class.IsTypedefClass()) { | 2977 if (interface_class.IsTypedefClass()) { |
3050 const String& interface_name = String::Handle(zone, | 2978 const String& interface_name = |
3051 interface_class.Name()); | 2979 String::Handle(zone, interface_class.Name()); |
3052 ReportError(cls, cls.token_pos(), | 2980 ReportError(cls, cls.token_pos(), |
3053 "function type alias '%s' may not be used as interface", | 2981 "function type alias '%s' may not be used as interface", |
3054 interface_name.ToCString()); | 2982 interface_name.ToCString()); |
3055 } | 2983 } |
3056 if (interface_class.is_enum_class()) { | 2984 if (interface_class.is_enum_class()) { |
3057 const String& interface_name = String::Handle(zone, | 2985 const String& interface_name = |
3058 interface_class.Name()); | 2986 String::Handle(zone, interface_class.Name()); |
3059 ReportError(cls, cls.token_pos(), | 2987 ReportError(cls, cls.token_pos(), |
3060 "enum '%s' may not be used as interface", | 2988 "enum '%s' may not be used as interface", |
3061 interface_name.ToCString()); | 2989 interface_name.ToCString()); |
3062 } | 2990 } |
3063 // Verify that unless cls belongs to core lib, it cannot extend, implement, | 2991 // Verify that unless cls belongs to core lib, it cannot extend, implement, |
3064 // or mixin any of Null, bool, num, int, double, String, dynamic. | 2992 // or mixin any of Null, bool, num, int, double, String, dynamic. |
3065 if (!cls_belongs_to_core_lib) { | 2993 if (!cls_belongs_to_core_lib) { |
3066 if (interface.IsBoolType() || | 2994 if (interface.IsBoolType() || interface.IsNullType() || |
3067 interface.IsNullType() || | 2995 interface.IsNumberType() || interface.IsIntType() || |
3068 interface.IsNumberType() || | 2996 interface.IsDoubleType() || interface.IsStringType() || |
3069 interface.IsIntType() || | |
3070 interface.IsDoubleType() || | |
3071 interface.IsStringType() || | |
3072 interface.IsDynamicType()) { | 2997 interface.IsDynamicType()) { |
3073 const String& interface_name = String::Handle(zone, | 2998 const String& interface_name = |
3074 interface_class.Name()); | 2999 String::Handle(zone, interface_class.Name()); |
3075 if (cls.IsMixinApplication()) { | 3000 if (cls.IsMixinApplication()) { |
3076 ReportError(cls, cls.token_pos(), | 3001 ReportError(cls, cls.token_pos(), "illegal mixin of '%s'", |
3077 "illegal mixin of '%s'", | |
3078 interface_name.ToCString()); | 3002 interface_name.ToCString()); |
3079 } else { | 3003 } else { |
3080 ReportError(cls, cls.token_pos(), | 3004 ReportError(cls, cls.token_pos(), |
3081 "'%s' is not allowed to extend or implement '%s'", | 3005 "'%s' is not allowed to extend or implement '%s'", |
3082 String::Handle(zone, cls.Name()).ToCString(), | 3006 String::Handle(zone, cls.Name()).ToCString(), |
3083 interface_name.ToCString()); | 3007 interface_name.ToCString()); |
3084 } | 3008 } |
3085 } | 3009 } |
3086 } | 3010 } |
3087 interface_class.set_is_implemented(); | 3011 interface_class.set_is_implemented(); |
(...skipping 26 matching lines...) Expand all Loading... |
3114 } | 3038 } |
3115 | 3039 |
3116 | 3040 |
3117 void ClassFinalizer::PrintClassInformation(const Class& cls) { | 3041 void ClassFinalizer::PrintClassInformation(const Class& cls) { |
3118 Thread* thread = Thread::Current(); | 3042 Thread* thread = Thread::Current(); |
3119 HANDLESCOPE(thread); | 3043 HANDLESCOPE(thread); |
3120 const String& class_name = String::Handle(cls.Name()); | 3044 const String& class_name = String::Handle(cls.Name()); |
3121 THR_Print("class '%s'", class_name.ToCString()); | 3045 THR_Print("class '%s'", class_name.ToCString()); |
3122 const Library& library = Library::Handle(cls.library()); | 3046 const Library& library = Library::Handle(cls.library()); |
3123 if (!library.IsNull()) { | 3047 if (!library.IsNull()) { |
3124 THR_Print(" library '%s%s':\n", | 3048 THR_Print(" library '%s%s':\n", String::Handle(library.url()).ToCString(), |
3125 String::Handle(library.url()).ToCString(), | |
3126 String::Handle(library.private_key()).ToCString()); | 3049 String::Handle(library.private_key()).ToCString()); |
3127 } else { | 3050 } else { |
3128 THR_Print(" (null library):\n"); | 3051 THR_Print(" (null library):\n"); |
3129 } | 3052 } |
3130 const AbstractType& super_type = AbstractType::Handle(cls.super_type()); | 3053 const AbstractType& super_type = AbstractType::Handle(cls.super_type()); |
3131 if (super_type.IsNull()) { | 3054 if (super_type.IsNull()) { |
3132 THR_Print(" Super: NULL"); | 3055 THR_Print(" Super: NULL"); |
3133 } else { | 3056 } else { |
3134 const String& super_name = String::Handle(super_type.Name()); | 3057 const String& super_name = String::Handle(super_type.Name()); |
3135 THR_Print(" Super: %s", super_name.ToCString()); | 3058 THR_Print(" Super: %s", super_name.ToCString()); |
(...skipping 24 matching lines...) Expand all Loading... |
3160 THR_Print(" %s\n", field.ToCString()); | 3083 THR_Print(" %s\n", field.ToCString()); |
3161 } | 3084 } |
3162 } | 3085 } |
3163 | 3086 |
3164 // Either report an error or mark the type as malformed. | 3087 // Either report an error or mark the type as malformed. |
3165 void ClassFinalizer::MarkTypeMalformed(const Error& prev_error, | 3088 void ClassFinalizer::MarkTypeMalformed(const Error& prev_error, |
3166 const Script& script, | 3089 const Script& script, |
3167 const Type& type, | 3090 const Type& type, |
3168 const char* format, | 3091 const char* format, |
3169 va_list args) { | 3092 va_list args) { |
3170 LanguageError& error = LanguageError::Handle( | 3093 LanguageError& error = LanguageError::Handle(LanguageError::NewFormattedV( |
3171 LanguageError::NewFormattedV( | 3094 prev_error, script, type.token_pos(), Report::AtLocation, |
3172 prev_error, script, type.token_pos(), Report::AtLocation, | 3095 Report::kMalformedType, Heap::kOld, format, args)); |
3173 Report::kMalformedType, Heap::kOld, | |
3174 format, args)); | |
3175 if (Isolate::Current()->error_on_bad_type()) { | 3096 if (Isolate::Current()->error_on_bad_type()) { |
3176 ReportError(error); | 3097 ReportError(error); |
3177 } | 3098 } |
3178 type.set_error(error); | 3099 type.set_error(error); |
3179 // Make the type raw, since it may not be possible to | 3100 // Make the type raw, since it may not be possible to |
3180 // properly finalize its type arguments. | 3101 // properly finalize its type arguments. |
3181 type.set_type_class(Class::Handle(Object::dynamic_class())); | 3102 type.set_type_class(Class::Handle(Object::dynamic_class())); |
3182 type.set_arguments(Object::null_type_arguments()); | 3103 type.set_arguments(Object::null_type_arguments()); |
3183 if (!type.IsFinalized()) { | 3104 if (!type.IsFinalized()) { |
3184 type.SetIsFinalized(); | 3105 type.SetIsFinalized(); |
3185 // Do not canonicalize malformed types, since they contain an error field. | 3106 // Do not canonicalize malformed types, since they contain an error field. |
3186 } else { | 3107 } else { |
3187 // The only case where the malformed type was already finalized is when its | 3108 // The only case where the malformed type was already finalized is when its |
3188 // type arguments are not within bounds. In that case, we have a prev_error. | 3109 // type arguments are not within bounds. In that case, we have a prev_error. |
3189 ASSERT(!prev_error.IsNull()); | 3110 ASSERT(!prev_error.IsNull()); |
3190 } | 3111 } |
3191 } | 3112 } |
3192 | 3113 |
3193 | 3114 |
3194 RawType* ClassFinalizer::NewFinalizedMalformedType(const Error& prev_error, | 3115 RawType* ClassFinalizer::NewFinalizedMalformedType(const Error& prev_error, |
3195 const Script& script, | 3116 const Script& script, |
3196 TokenPosition type_pos, | 3117 TokenPosition type_pos, |
3197 const char* format, ...) { | 3118 const char* format, |
| 3119 ...) { |
3198 va_list args; | 3120 va_list args; |
3199 va_start(args, format); | 3121 va_start(args, format); |
3200 const UnresolvedClass& unresolved_class = UnresolvedClass::Handle( | 3122 const UnresolvedClass& unresolved_class = |
3201 UnresolvedClass::New(LibraryPrefix::Handle(), | 3123 UnresolvedClass::Handle(UnresolvedClass::New(LibraryPrefix::Handle(), |
3202 Symbols::Empty(), | 3124 Symbols::Empty(), type_pos)); |
3203 type_pos)); | |
3204 const Type& type = Type::Handle( | 3125 const Type& type = Type::Handle( |
3205 Type::New(unresolved_class, TypeArguments::Handle(), type_pos)); | 3126 Type::New(unresolved_class, TypeArguments::Handle(), type_pos)); |
3206 MarkTypeMalformed(prev_error, script, type, format, args); | 3127 MarkTypeMalformed(prev_error, script, type, format, args); |
3207 va_end(args); | 3128 va_end(args); |
3208 ASSERT(type.IsMalformed()); | 3129 ASSERT(type.IsMalformed()); |
3209 ASSERT(type.IsFinalized()); | 3130 ASSERT(type.IsFinalized()); |
3210 return type.raw(); | 3131 return type.raw(); |
3211 } | 3132 } |
3212 | 3133 |
3213 | 3134 |
3214 void ClassFinalizer::FinalizeMalformedType(const Error& prev_error, | 3135 void ClassFinalizer::FinalizeMalformedType(const Error& prev_error, |
3215 const Script& script, | 3136 const Script& script, |
3216 const Type& type, | 3137 const Type& type, |
3217 const char* format, ...) { | 3138 const char* format, |
| 3139 ...) { |
3218 va_list args; | 3140 va_list args; |
3219 va_start(args, format); | 3141 va_start(args, format); |
3220 MarkTypeMalformed(prev_error, script, type, format, args); | 3142 MarkTypeMalformed(prev_error, script, type, format, args); |
3221 va_end(args); | 3143 va_end(args); |
3222 } | 3144 } |
3223 | 3145 |
3224 | 3146 |
3225 void ClassFinalizer::FinalizeMalboundedType(const Error& prev_error, | 3147 void ClassFinalizer::FinalizeMalboundedType(const Error& prev_error, |
3226 const Script& script, | 3148 const Script& script, |
3227 const AbstractType& type, | 3149 const AbstractType& type, |
3228 const char* format, ...) { | 3150 const char* format, |
| 3151 ...) { |
3229 va_list args; | 3152 va_list args; |
3230 va_start(args, format); | 3153 va_start(args, format); |
3231 LanguageError& error = LanguageError::Handle( | 3154 LanguageError& error = LanguageError::Handle(LanguageError::NewFormattedV( |
3232 LanguageError::NewFormattedV( | 3155 prev_error, script, type.token_pos(), Report::AtLocation, |
3233 prev_error, script, type.token_pos(), Report::AtLocation, | 3156 Report::kMalboundedType, Heap::kOld, format, args)); |
3234 Report::kMalboundedType, Heap::kOld, | |
3235 format, args)); | |
3236 va_end(args); | 3157 va_end(args); |
3237 if (Isolate::Current()->error_on_bad_type()) { | 3158 if (Isolate::Current()->error_on_bad_type()) { |
3238 ReportError(error); | 3159 ReportError(error); |
3239 } | 3160 } |
3240 type.set_error(error); | 3161 type.set_error(error); |
3241 if (!type.IsFinalized()) { | 3162 if (!type.IsFinalized()) { |
3242 type.SetIsFinalized(); | 3163 type.SetIsFinalized(); |
3243 // Do not canonicalize malbounded types. | 3164 // Do not canonicalize malbounded types. |
3244 } | 3165 } |
3245 } | 3166 } |
3246 | 3167 |
3247 | 3168 |
3248 void ClassFinalizer::ReportError(const Error& error) { | 3169 void ClassFinalizer::ReportError(const Error& error) { |
3249 Report::LongJump(error); | 3170 Report::LongJump(error); |
3250 UNREACHABLE(); | 3171 UNREACHABLE(); |
3251 } | 3172 } |
3252 | 3173 |
3253 | 3174 |
3254 void ClassFinalizer::ReportErrors(const Error& prev_error, | 3175 void ClassFinalizer::ReportErrors(const Error& prev_error, |
3255 const Class& cls, | 3176 const Class& cls, |
3256 TokenPosition token_pos, | 3177 TokenPosition token_pos, |
3257 const char* format, ...) { | 3178 const char* format, |
| 3179 ...) { |
3258 va_list args; | 3180 va_list args; |
3259 va_start(args, format); | 3181 va_start(args, format); |
3260 const Script& script = Script::Handle(cls.script()); | 3182 const Script& script = Script::Handle(cls.script()); |
3261 Report::LongJumpV(prev_error, script, token_pos, format, args); | 3183 Report::LongJumpV(prev_error, script, token_pos, format, args); |
3262 va_end(args); | 3184 va_end(args); |
3263 UNREACHABLE(); | 3185 UNREACHABLE(); |
3264 } | 3186 } |
3265 | 3187 |
3266 | 3188 |
3267 void ClassFinalizer::ReportError(const Class& cls, | 3189 void ClassFinalizer::ReportError(const Class& cls, |
3268 TokenPosition token_pos, | 3190 TokenPosition token_pos, |
3269 const char* format, ...) { | 3191 const char* format, |
| 3192 ...) { |
3270 va_list args; | 3193 va_list args; |
3271 va_start(args, format); | 3194 va_start(args, format); |
3272 const Script& script = Script::Handle(cls.script()); | 3195 const Script& script = Script::Handle(cls.script()); |
3273 Report::MessageV(Report::kError, | 3196 Report::MessageV(Report::kError, script, token_pos, Report::AtLocation, |
3274 script, token_pos, Report::AtLocation, format, args); | 3197 format, args); |
3275 va_end(args); | 3198 va_end(args); |
3276 UNREACHABLE(); | 3199 UNREACHABLE(); |
3277 } | 3200 } |
3278 | 3201 |
3279 | 3202 |
3280 void ClassFinalizer::VerifyImplicitFieldOffsets() { | 3203 void ClassFinalizer::VerifyImplicitFieldOffsets() { |
3281 #ifdef DEBUG | 3204 #ifdef DEBUG |
3282 Thread* thread = Thread::Current(); | 3205 Thread* thread = Thread::Current(); |
3283 Isolate* isolate = thread->isolate(); | 3206 Isolate* isolate = thread->isolate(); |
3284 Zone* zone = thread->zone(); | 3207 Zone* zone = thread->zone(); |
3285 const ClassTable& class_table = *(isolate->class_table()); | 3208 const ClassTable& class_table = *(isolate->class_table()); |
3286 Class& cls = Class::Handle(zone); | 3209 Class& cls = Class::Handle(zone); |
3287 Array& fields_array = Array::Handle(zone); | 3210 Array& fields_array = Array::Handle(zone); |
3288 Field& field = Field::Handle(zone); | 3211 Field& field = Field::Handle(zone); |
3289 String& name = String::Handle(zone); | 3212 String& name = String::Handle(zone); |
3290 String& expected_name = String::Handle(zone); | 3213 String& expected_name = String::Handle(zone); |
3291 Error& error = Error::Handle(zone); | 3214 Error& error = Error::Handle(zone); |
3292 | 3215 |
3293 // First verify field offsets of all the TypedDataView classes. | 3216 // First verify field offsets of all the TypedDataView classes. |
3294 for (intptr_t cid = kTypedDataInt8ArrayViewCid; | 3217 for (intptr_t cid = kTypedDataInt8ArrayViewCid; |
3295 cid <= kTypedDataFloat32x4ArrayViewCid; | 3218 cid <= kTypedDataFloat32x4ArrayViewCid; cid++) { |
3296 cid++) { | |
3297 cls = class_table.At(cid); // Get the TypedDataView class. | 3219 cls = class_table.At(cid); // Get the TypedDataView class. |
3298 error = cls.EnsureIsFinalized(thread); | 3220 error = cls.EnsureIsFinalized(thread); |
3299 ASSERT(error.IsNull()); | 3221 ASSERT(error.IsNull()); |
3300 cls = cls.SuperClass(); // Get it's super class '_TypedListView'. | 3222 cls = cls.SuperClass(); // Get it's super class '_TypedListView'. |
3301 cls = cls.SuperClass(); | 3223 cls = cls.SuperClass(); |
3302 fields_array ^= cls.fields(); | 3224 fields_array ^= cls.fields(); |
3303 ASSERT(fields_array.Length() == TypedDataView::NumberOfFields()); | 3225 ASSERT(fields_array.Length() == TypedDataView::NumberOfFields()); |
3304 field ^= fields_array.At(0); | 3226 field ^= fields_array.At(0); |
3305 ASSERT(field.Offset() == TypedDataView::data_offset()); | 3227 ASSERT(field.Offset() == TypedDataView::data_offset()); |
3306 name ^= field.name(); | 3228 name ^= field.name(); |
(...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3345 ASSERT(fields_array.Length() == ByteBuffer::NumberOfFields()); | 3267 ASSERT(fields_array.Length() == ByteBuffer::NumberOfFields()); |
3346 field ^= fields_array.At(0); | 3268 field ^= fields_array.At(0); |
3347 ASSERT(field.Offset() == ByteBuffer::data_offset()); | 3269 ASSERT(field.Offset() == ByteBuffer::data_offset()); |
3348 name ^= field.name(); | 3270 name ^= field.name(); |
3349 expected_name ^= String::New("_data"); | 3271 expected_name ^= String::New("_data"); |
3350 ASSERT(String::EqualsIgnoringPrivateKey(name, expected_name)); | 3272 ASSERT(String::EqualsIgnoringPrivateKey(name, expected_name)); |
3351 #endif | 3273 #endif |
3352 } | 3274 } |
3353 | 3275 |
3354 } // namespace dart | 3276 } // namespace dart |
OLD | NEW |