Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(341)

Side by Side Diff: runtime/vm/class_finalizer.cc

Issue 2481873005: clang-format runtime/vm (Closed)
Patch Set: Merge Created 4 years, 1 month ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « runtime/vm/class_finalizer.h ('k') | runtime/vm/class_finalizer_test.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
OLDNEW
« no previous file with comments | « runtime/vm/class_finalizer.h ('k') | runtime/vm/class_finalizer_test.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698