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

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

Issue 9515011: Add support for malformed types and postpone some related errors from compile (Closed) Base URL: http://dart.googlecode.com/svn/branches/bleeding_edge/dart/
Patch Set: Created 8 years, 9 months 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 | Annotate | Revision Log
OLDNEW
1 // Copyright (c) 2011, the Dart project authors. Please see the AUTHORS file 1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file
2 // for details. All rights reserved. Use of this source code is governed by a 2 // for details. All rights reserved. Use of this source code is governed by a
3 // BSD-style license that can be found in the LICENSE file. 3 // BSD-style license that can be found in the LICENSE file.
4 4
5 #include "vm/class_finalizer.h" 5 #include "vm/class_finalizer.h"
6 6
7 #include "vm/flags.h" 7 #include "vm/flags.h"
8 #include "vm/heap.h" 8 #include "vm/heap.h"
9 #include "vm/isolate.h" 9 #include "vm/isolate.h"
10 #include "vm/longjump.h" 10 #include "vm/longjump.h"
11 #include "vm/object_store.h" 11 #include "vm/object_store.h"
12 #include "vm/parser.h" 12 #include "vm/parser.h"
13 13
14 namespace dart { 14 namespace dart {
15 15
16 DEFINE_FLAG(bool, print_classes, false, "Prints details about loaded classes."); 16 DEFINE_FLAG(bool, print_classes, false, "Prints details about loaded classes.");
17 DEFINE_FLAG(bool, trace_class_finalization, false, "Trace class finalization."); 17 DEFINE_FLAG(bool, trace_class_finalization, false, "Trace class finalization.");
18 DEFINE_FLAG(bool, trace_type_finalization, false, "Trace type finalization."); 18 DEFINE_FLAG(bool, trace_type_finalization, false, "Trace type finalization.");
19 DEFINE_FLAG(bool, verify_implements, false, 19 DEFINE_FLAG(bool, verify_implements, false,
20 "Verify that all classes implement their interface."); 20 "Verify that all classes implement their interface.");
21 DECLARE_FLAG(bool, enable_type_checks); 21 DECLARE_FLAG(bool, enable_type_checks);
22 DECLARE_FLAG(bool, silent_warnings);
23 DECLARE_FLAG(bool, warning_as_error);
24 22
25 void ClassFinalizer::AddPendingClasses( 23 void ClassFinalizer::AddPendingClasses(
26 const GrowableArray<const Class*>& classes) { 24 const GrowableArray<const Class*>& classes) {
27 if (!classes.is_empty()) { 25 if (!classes.is_empty()) {
28 ObjectStore* object_store = Isolate::Current()->object_store(); 26 ObjectStore* object_store = Isolate::Current()->object_store();
29 const Array& old_array = Array::Handle(object_store->pending_classes()); 27 const Array& old_array = Array::Handle(object_store->pending_classes());
30 const intptr_t old_length = old_array.Length(); 28 const intptr_t old_length = old_array.Length();
31 const int new_length = old_length + classes.length(); 29 const int new_length = old_length + classes.length();
32 const Array& new_array = Array::Handle(Array::Grow(old_array, new_length)); 30 const Array& new_array = Array::Handle(Array::Grow(old_array, new_length));
33 // Add new classes. 31 // Add new classes.
(...skipping 216 matching lines...) Expand 10 before | Expand all | Expand 10 after
250 err.ToErrorCString()); 248 err.ToErrorCString());
251 OS::Exit(255); 249 OS::Exit(255);
252 } 250 }
253 if (FLAG_trace_class_finalization) { 251 if (FLAG_trace_class_finalization) {
254 OS::Print("VerifyBootstrapClasses END.\n"); 252 OS::Print("VerifyBootstrapClasses END.\n");
255 } 253 }
256 Isolate::Current()->heap()->Verify(); 254 Isolate::Current()->heap()->Verify();
257 } 255 }
258 256
259 257
260 // Resolve unresolved_class in the library of cls. 258 // Resolve unresolved_class in the library of cls, or return null.
261 RawClass* ClassFinalizer::ResolveClass( 259 RawClass* ClassFinalizer::ResolveClass(
262 const Class& cls, const UnresolvedClass& unresolved_class) { 260 const Class& cls, const UnresolvedClass& unresolved_class) {
263 const String& class_name = String::Handle(unresolved_class.ident()); 261 const String& class_name = String::Handle(unresolved_class.ident());
264 Library& lib = Library::Handle(); 262 Library& lib = Library::Handle();
265 Class& resolved_class = Class::Handle(); 263 Class& resolved_class = Class::Handle();
266 if (unresolved_class.library_prefix() == LibraryPrefix::null()) { 264 if (unresolved_class.library_prefix() == LibraryPrefix::null()) {
267 lib = cls.library(); 265 lib = cls.library();
268 ASSERT(!lib.IsNull()); 266 ASSERT(!lib.IsNull());
269 resolved_class = lib.LookupClass(class_name); 267 resolved_class = lib.LookupClass(class_name);
270 } else { 268 } else {
271 LibraryPrefix& lib_prefix = LibraryPrefix::Handle(); 269 LibraryPrefix& lib_prefix = LibraryPrefix::Handle();
272 lib_prefix = unresolved_class.library_prefix(); 270 lib_prefix = unresolved_class.library_prefix();
273 ASSERT(!lib_prefix.IsNull()); 271 ASSERT(!lib_prefix.IsNull());
274 resolved_class = lib_prefix.LookupLocalClass(class_name); 272 resolved_class = lib_prefix.LookupLocalClass(class_name);
275 } 273 }
276 if (resolved_class.IsNull()) {
277 const Script& script = Script::Handle(cls.script());
278 ReportError(script, unresolved_class.token_index(),
279 "cannot resolve class name '%s' from '%s'.\n",
280 String::Handle(unresolved_class.Name()).ToCString(),
281 String::Handle(cls.Name()).ToCString());
282 }
283 return resolved_class.raw(); 274 return resolved_class.raw();
284 } 275 }
285 276
286 277
287 // Resolve unresolved supertype (String -> Class). 278 // Resolve unresolved supertype (String -> Class).
288 void ClassFinalizer::ResolveSuperType(const Class& cls) { 279 void ClassFinalizer::ResolveSuperType(const Class& cls) {
289 if (cls.is_finalized()) { 280 if (cls.is_finalized()) {
290 return; 281 return;
291 } 282 }
292 Type& super_type = Type::Handle(cls.super_type()); 283 Type& super_type = Type::Handle(cls.super_type());
293 if (super_type.IsNull()) { 284 if (super_type.IsNull()) {
294 return; 285 return;
295 } 286 }
296 // Resolve failures lead to a longjmp. 287 // Resolve failures lead to a longjmp.
297 ResolveType(cls, super_type); 288 ResolveType(cls, super_type, kFinalizeWellFormed);
298 const Class& super_class = Class::Handle(super_type.type_class()); 289 const Class& super_class = Class::Handle(super_type.type_class());
299 if (cls.is_interface() != super_class.is_interface()) { 290 if (cls.is_interface() != super_class.is_interface()) {
300 String& class_name = String::Handle(cls.Name()); 291 String& class_name = String::Handle(cls.Name());
301 String& super_class_name = String::Handle(super_class.Name()); 292 String& super_class_name = String::Handle(super_class.Name());
302 const Script& script = Script::Handle(cls.script()); 293 const Script& script = Script::Handle(cls.script());
303 ReportError(script, cls.token_index(), 294 ReportError(script, cls.token_index(),
304 "class '%s' and superclass '%s' are not " 295 "class '%s' and superclass '%s' are not "
305 "both classes or both interfaces.\n", 296 "both classes or both interfaces",
306 class_name.ToCString(), 297 class_name.ToCString(),
307 super_class_name.ToCString()); 298 super_class_name.ToCString());
308 } 299 }
309 // If cls belongs to core lib or to core lib's implementation, restrictions 300 // If cls belongs to core lib or to core lib's implementation, restrictions
310 // about allowed interfaces are lifted. 301 // about allowed interfaces are lifted.
311 if ((cls.library() != Library::CoreLibrary()) && 302 if ((cls.library() != Library::CoreLibrary()) &&
312 (cls.library() != Library::CoreImplLibrary())) { 303 (cls.library() != Library::CoreImplLibrary())) {
313 // Prevent extending core implementation classes Bool, Double, ObjectArray, 304 // Prevent extending core implementation classes Bool, Double, ObjectArray,
314 // ImmutableArray, GrowableObjectArray, IntegerImplementation, Smi, Mint, 305 // ImmutableArray, GrowableObjectArray, IntegerImplementation, Smi, Mint,
315 // BigInt, OneByteString, TwoByteString, FourByteString. 306 // BigInt, OneByteString, TwoByteString, FourByteString.
(...skipping 16 matching lines...) Expand all
332 (super_class.raw() == object_store->external_byte_array_class()) || 323 (super_class.raw() == object_store->external_byte_array_class()) ||
333 (super_class.raw() == integer_implementation_class.raw()) || 324 (super_class.raw() == integer_implementation_class.raw()) ||
334 (super_class.raw() == object_store->smi_class()) || 325 (super_class.raw() == object_store->smi_class()) ||
335 (super_class.raw() == object_store->mint_class()) || 326 (super_class.raw() == object_store->mint_class()) ||
336 (super_class.raw() == object_store->bigint_class()) || 327 (super_class.raw() == object_store->bigint_class()) ||
337 (super_class.raw() == object_store->one_byte_string_class()) || 328 (super_class.raw() == object_store->one_byte_string_class()) ||
338 (super_class.raw() == object_store->two_byte_string_class()) || 329 (super_class.raw() == object_store->two_byte_string_class()) ||
339 (super_class.raw() == object_store->four_byte_string_class())) { 330 (super_class.raw() == object_store->four_byte_string_class())) {
340 const Script& script = Script::Handle(cls.script()); 331 const Script& script = Script::Handle(cls.script());
341 ReportError(script, cls.token_index(), 332 ReportError(script, cls.token_index(),
342 "'%s' is not allowed to extend '%s'\n", 333 "'%s' is not allowed to extend '%s'",
343 String::Handle(cls.Name()).ToCString(), 334 String::Handle(cls.Name()).ToCString(),
344 String::Handle(super_class.Name()).ToCString()); 335 String::Handle(super_class.Name()).ToCString());
345 } 336 }
346 } 337 }
347 return; 338 return;
348 } 339 }
349 340
350 341
351 void ClassFinalizer::ResolveDefaultClass(const Class& interface) { 342 void ClassFinalizer::ResolveDefaultClass(const Class& interface) {
352 ASSERT(interface.is_interface()); 343 ASSERT(interface.is_interface());
353 if (interface.is_finalized() || 344 if (interface.is_finalized() ||
354 !interface.HasFactoryClass() || 345 !interface.HasFactoryClass() ||
355 interface.HasResolvedFactoryClass()) { 346 interface.HasResolvedFactoryClass()) {
356 return; 347 return;
357 } 348 }
358 const UnresolvedClass& unresolved_factory_class = 349 const UnresolvedClass& unresolved_factory_class =
359 UnresolvedClass::Handle(interface.UnresolvedFactoryClass()); 350 UnresolvedClass::Handle(interface.UnresolvedFactoryClass());
360 351
361 // Lookup the factory class. 352 // Lookup the factory class.
362 const Class& factory_class = 353 const Class& factory_class =
363 Class::Handle(ResolveClass(interface, unresolved_factory_class)); 354 Class::Handle(ResolveClass(interface, unresolved_factory_class));
364 ASSERT(!factory_class.IsNull()); 355 if (factory_class.IsNull()) {
356 const Script& script = Script::Handle(interface.script());
357 ReportError(script, unresolved_factory_class.token_index(),
358 "cannot resolve factory class name '%s' from '%s'",
359 String::Handle(unresolved_factory_class.Name()).ToCString(),
360 String::Handle(interface.Name()).ToCString());
361 }
365 if (factory_class.is_interface()) { 362 if (factory_class.is_interface()) {
366 const String& interface_name = String::Handle(interface.Name()); 363 const String& interface_name = String::Handle(interface.Name());
367 const String& factory_name = String::Handle(factory_class.Name()); 364 const String& factory_name = String::Handle(factory_class.Name());
368 const Script& script = Script::Handle(interface.script()); 365 const Script& script = Script::Handle(interface.script());
369 ReportError(script, unresolved_factory_class.token_index(), 366 ReportError(script, unresolved_factory_class.token_index(),
370 "default clause of interface '%s' names non-class '%s'.\n", 367 "default clause of interface '%s' names non-class '%s'",
371 interface_name.ToCString(), 368 interface_name.ToCString(),
372 factory_name.ToCString()); 369 factory_name.ToCString());
373 } 370 }
374 interface.set_factory_class(factory_class); 371 interface.set_factory_class(factory_class);
375 ResolveAndFinalizeUpperBounds(factory_class); 372 ResolveAndFinalizeUpperBounds(factory_class);
376 const Class& factory_signature_class = Class::Handle( 373 const Class& factory_signature_class = Class::Handle(
377 unresolved_factory_class.factory_signature_class()); 374 unresolved_factory_class.factory_signature_class());
378 ASSERT(!factory_signature_class.IsNull()); 375 ASSERT(!factory_signature_class.IsNull());
379 // If a type parameter list is included in the default factory clause (it 376 // If a type parameter list is included in the default factory clause (it
380 // can be omitted), verify that it matches the list of type parameters of 377 // can be omitted), verify that it matches the list of type parameters of
(...skipping 11 matching lines...) Expand all
392 if (!AbstractTypeArguments::AreEqual(expected_type_parameters, 389 if (!AbstractTypeArguments::AreEqual(expected_type_parameters,
393 actual_type_parameters) || 390 actual_type_parameters) ||
394 !AbstractTypeArguments::AreEqual(expected_type_parameter_bounds, 391 !AbstractTypeArguments::AreEqual(expected_type_parameter_bounds,
395 actual_type_parameter_bounds)) { 392 actual_type_parameter_bounds)) {
396 const String& interface_name = String::Handle(interface.Name()); 393 const String& interface_name = String::Handle(interface.Name());
397 const String& factory_name = String::Handle(factory_class.Name()); 394 const String& factory_name = String::Handle(factory_class.Name());
398 const Script& script = Script::Handle(interface.script()); 395 const Script& script = Script::Handle(interface.script());
399 ReportError(script, unresolved_factory_class.token_index(), 396 ReportError(script, unresolved_factory_class.token_index(),
400 "mismatch in number, names, or bounds of type parameters " 397 "mismatch in number, names, or bounds of type parameters "
401 "between default clause of interface '%s' and actual factory " 398 "between default clause of interface '%s' and actual factory "
402 "class '%s'.\n", 399 "class '%s'",
403 interface_name.ToCString(), 400 interface_name.ToCString(),
404 factory_name.ToCString()); 401 factory_name.ToCString());
405 } 402 }
406 } 403 }
407 // Verify that the type parameters of the factory class and of the interface 404 // Verify that the type parameters of the factory class and of the interface
408 // have identical names. 405 // have identical names.
409 const TypeArguments& interface_type_parameters = 406 const TypeArguments& interface_type_parameters =
410 TypeArguments::Handle(interface.type_parameters()); 407 TypeArguments::Handle(interface.type_parameters());
411 const TypeArguments& factory_type_parameters = 408 const TypeArguments& factory_type_parameters =
412 TypeArguments::Handle(factory_class.type_parameters()); 409 TypeArguments::Handle(factory_class.type_parameters());
413 if (!AbstractTypeArguments::AreEqual(interface_type_parameters, 410 if (!AbstractTypeArguments::AreEqual(interface_type_parameters,
414 factory_type_parameters)) { 411 factory_type_parameters)) {
415 const String& interface_name = String::Handle(interface.Name()); 412 const String& interface_name = String::Handle(interface.Name());
416 const String& factory_name = String::Handle(factory_class.Name()); 413 const String& factory_name = String::Handle(factory_class.Name());
417 const Script& script = Script::Handle(interface.script()); 414 const Script& script = Script::Handle(interface.script());
418 ReportError(script, unresolved_factory_class.token_index(), 415 ReportError(script, unresolved_factory_class.token_index(),
419 "mismatch in number or names of type parameters between " 416 "mismatch in number or names of type parameters between "
420 "interface '%s' and default factory class '%s'.\n", 417 "interface '%s' and default factory class '%s'",
421 interface_name.ToCString(), 418 interface_name.ToCString(),
422 factory_name.ToCString()); 419 factory_name.ToCString());
423 } 420 }
424 } 421 }
425 422
426 423
427 void ClassFinalizer::ResolveType(const Class& cls, const AbstractType& type) { 424 void ClassFinalizer::ResolveType(const Class& cls,
428 if (type.IsResolved()) { 425 const AbstractType& type,
426 TypeFinalization finalization) {
427 if (type.IsResolved() || type.IsFinalized()) {
429 return; 428 return;
430 } 429 }
431 if (FLAG_trace_type_finalization) { 430 if (FLAG_trace_type_finalization) {
432 OS::Print("Resolve type '%s'\n", String::Handle(type.Name()).ToCString()); 431 OS::Print("Resolve type '%s'\n", String::Handle(type.Name()).ToCString());
433 } 432 }
434 433
435 // Resolve the type class. 434 // Resolve the type class.
436 if (!type.HasResolvedTypeClass()) { 435 if (!type.HasResolvedTypeClass()) {
437 // Type parameters are always resolved in the parser in the correct 436 // Type parameters are always resolved in the parser in the correct
438 // non-static scope or factory scope. That resolution scope is unknown here. 437 // non-static scope or factory scope. That resolution scope is unknown here.
439 // Being able to resolve a type parameter from class cls here would indicate 438 // Being able to resolve a type parameter from class cls here would indicate
440 // that the type parameter appeared in a static scope. Leaving the type as 439 // that the type parameter appeared in a static scope. Leaving the type as
441 // unresolved is the correct thing to do. 440 // unresolved is the correct thing to do.
442 441
443 // Lookup the type class. 442 // Lookup the type class.
444 const UnresolvedClass& unresolved_class = 443 const UnresolvedClass& unresolved_class =
445 UnresolvedClass::Handle(type.unresolved_class()); 444 UnresolvedClass::Handle(type.unresolved_class());
446 const Class& type_class = 445 const Class& type_class =
447 Class::Handle(ResolveClass(cls, unresolved_class)); 446 Class::Handle(ResolveClass(cls, unresolved_class));
448 447
449 // Replace unresolved class with resolved type class. 448 // Replace unresolved class with resolved type class.
450 ASSERT(type.IsType()); 449 ASSERT(type.IsType());
451 Type& parameterized_type = Type::Handle(); 450 Type& parameterized_type = Type::Handle();
452 parameterized_type ^= type.raw(); 451 parameterized_type ^= type.raw();
453 parameterized_type.set_type_class(Object::Handle(type_class.raw())); 452 if (!type_class.IsNull()) {
453 parameterized_type.set_type_class(Object::Handle(type_class.raw()));
454 } else {
455 // The type class could not be resolved. The type is malformed.
456 FinalizeMalformedType(cls, parameterized_type, finalization,
457 "cannot resolve class name '%s' from '%s'",
458 String::Handle(unresolved_class.Name()).ToCString(),
459 String::Handle(cls.Name()).ToCString());
460 return;
461 }
454 } 462 }
455 463
456 // Resolve type arguments, if any. 464 // Resolve type arguments, if any.
457 const AbstractTypeArguments& arguments = 465 const AbstractTypeArguments& arguments =
458 AbstractTypeArguments::Handle(type.arguments()); 466 AbstractTypeArguments::Handle(type.arguments());
459 if (!arguments.IsNull()) { 467 if (!arguments.IsNull()) {
460 intptr_t num_arguments = arguments.Length(); 468 intptr_t num_arguments = arguments.Length();
461 AbstractType& type_argument = AbstractType::Handle(); 469 AbstractType& type_argument = AbstractType::Handle();
462 for (intptr_t i = 0; i < num_arguments; i++) { 470 for (intptr_t i = 0; i < num_arguments; i++) {
463 type_argument = arguments.TypeAt(i); 471 type_argument = arguments.TypeAt(i);
464 ResolveType(cls, type_argument); 472 ResolveType(cls, type_argument, finalization);
465 } 473 }
466 } 474 }
467 } 475 }
468 476
469 477
470 // Finalize the type argument vector 'arguments' of the type defined by the 478 // Finalize the type argument vector 'arguments' of the type defined by the
471 // class 'cls' parameterized with the type arguments 'cls_args'. 479 // class 'cls' parameterized with the type arguments 'cls_args'.
472 // The vector 'cls_args' is already initialized as a subvector at the correct 480 // The vector 'cls_args' is already initialized as a subvector at the correct
473 // position in the passed in 'arguments' vector. 481 // position in the passed in 'arguments' vector.
474 // The subvector 'cls_args' has length cls.NumTypeParameters() and starts at 482 // The subvector 'cls_args' has length cls.NumTypeParameters() and starts at
475 // offset cls.NumTypeArguments() - cls.NumTypeParameters() of the 'arguments' 483 // offset cls.NumTypeArguments() - cls.NumTypeParameters() of the 'arguments'
476 // vector. 484 // vector.
477 // Example: 485 // Example:
478 // Declared: class C<K, V> extends B<V> { ... } 486 // Declared: class C<K, V> extends B<V> { ... }
479 // class B<T> extends A<int> { ... } 487 // class B<T> extends A<int> { ... }
480 // Input: C<String, double> expressed as 488 // Input: C<String, double> expressed as
481 // cls = C, arguments = [null, null, String, double], 489 // cls = C, arguments = [null, null, String, double],
482 // i.e. cls_args = [String, double], offset = 2, length = 2. 490 // i.e. cls_args = [String, double], offset = 2, length = 2.
483 // Output: arguments = [int, double, String, double] 491 // Output: arguments = [int, double, String, double]
484 void ClassFinalizer::FinalizeTypeArguments( 492 void ClassFinalizer::FinalizeTypeArguments(
485 const Class& cls, const AbstractTypeArguments& arguments) { 493 const Class& cls,
494 const AbstractTypeArguments& arguments,
495 TypeFinalization finalization) {
486 ASSERT(arguments.Length() >= cls.NumTypeArguments()); 496 ASSERT(arguments.Length() >= cls.NumTypeArguments());
487 Type& super_type = Type::Handle(cls.super_type()); 497 Type& super_type = Type::Handle(cls.super_type());
488 if (!super_type.IsNull()) { 498 if (!super_type.IsNull()) {
489 super_type ^= FinalizeType(cls, super_type); 499 super_type ^= FinalizeType(cls, super_type, finalization);
490 cls.set_super_type(super_type); 500 cls.set_super_type(super_type);
491 const Class& super_class = Class::Handle(super_type.type_class()); 501 const Class& super_class = Class::Handle(super_type.type_class());
492 const AbstractTypeArguments& super_type_args = 502 const AbstractTypeArguments& super_type_args =
493 AbstractTypeArguments::Handle(super_type.arguments()); 503 AbstractTypeArguments::Handle(super_type.arguments());
494 const intptr_t num_super_type_params = super_class.NumTypeParameters(); 504 const intptr_t num_super_type_params = super_class.NumTypeParameters();
495 const intptr_t offset = super_class.NumTypeArguments(); 505 const intptr_t offset = super_class.NumTypeArguments();
496 const intptr_t super_offset = offset - num_super_type_params; 506 const intptr_t super_offset = offset - num_super_type_params;
497 ASSERT(offset == (cls.NumTypeArguments() - cls.NumTypeParameters())); 507 ASSERT(offset == (cls.NumTypeArguments() - cls.NumTypeParameters()));
498 AbstractType& super_type_arg = AbstractType::Handle(); 508 AbstractType& super_type_arg = AbstractType::Handle();
499 for (intptr_t i = 0; i < num_super_type_params; i++) { 509 for (intptr_t i = 0; i < num_super_type_params; i++) {
500 super_type_arg = super_type_args.TypeAt(super_offset + i); 510 super_type_arg = super_type_args.TypeAt(super_offset + i);
501 if (!super_type_arg.IsInstantiated()) { 511 if (!super_type_arg.IsInstantiated()) {
502 super_type_arg = super_type_arg.InstantiateFrom(arguments); 512 super_type_arg = super_type_arg.InstantiateFrom(arguments);
503 } 513 }
504 super_type_arg = super_type_arg.Canonicalize(); 514 super_type_arg = super_type_arg.Canonicalize();
505 arguments.SetTypeAt(super_offset + i, super_type_arg); 515 arguments.SetTypeAt(super_offset + i, super_type_arg);
506 } 516 }
507 FinalizeTypeArguments(super_class, arguments); 517 FinalizeTypeArguments(super_class, arguments, finalization);
508 } 518 }
509 } 519 }
510 520
511 521
512 RawAbstractType* ClassFinalizer::FinalizeType(const Class& cls, 522 RawAbstractType* ClassFinalizer::FinalizeType(const Class& cls,
513 const AbstractType& type) { 523 const AbstractType& type,
514 ASSERT(type.IsResolved()); 524 TypeFinalization finalization) {
515 if (type.IsFinalized()) { 525 if (type.IsFinalized()) {
516 return type.raw(); 526 return type.raw();
517 } 527 }
528 ASSERT(type.IsResolved());
529
518 if (FLAG_trace_type_finalization) { 530 if (FLAG_trace_type_finalization) {
519 OS::Print("Finalize type '%s'\n", String::Handle(type.Name()).ToCString()); 531 OS::Print("Finalize type '%s'\n", String::Handle(type.Name()).ToCString());
520 } 532 }
521 533
522 if (type.IsTypeParameter()) { 534 if (type.IsTypeParameter()) {
523 ASSERT(!cls.IsNull()); 535 ASSERT(!cls.IsNull());
524 TypeParameter& type_parameter = TypeParameter::Handle(); 536 TypeParameter& type_parameter = TypeParameter::Handle();
525 type_parameter ^= type.raw(); 537 type_parameter ^= type.raw();
526 // The index must reflect the position of this type parameter in the type 538 // The index must reflect the position of this type parameter in the type
527 // arguments vector of the enclosing class. The offset to add is the number 539 // arguments vector of the enclosing class. The offset to add is the number
528 // of type arguments in the super type, which is equal to the difference in 540 // of type arguments in the super type, which is equal to the difference in
529 // number of type arguments and type parameters of the enclosing class. 541 // number of type arguments and type parameters of the enclosing class.
530 const intptr_t offset = cls.NumTypeArguments() - cls.NumTypeParameters(); 542 const intptr_t offset = cls.NumTypeArguments() - cls.NumTypeParameters();
531 type_parameter.set_index(type_parameter.Index() + offset); 543 type_parameter.set_index(type_parameter.Index() + offset);
532 type_parameter.set_is_finalized(); 544 type_parameter.set_is_finalized();
533 // We do not canonicalize type parameters. 545 // We do not canonicalize type parameters.
534 return type_parameter.raw(); 546 return type_parameter.raw();
535 } 547 }
536 548
537 // At this point, we can only have a parameterized_type. 549 // At this point, we can only have a parameterized_type.
538 Type& parameterized_type = Type::Handle(); 550 Type& parameterized_type = Type::Handle();
539 parameterized_type ^= type.raw(); 551 parameterized_type ^= type.raw();
540 552
541 if (parameterized_type.IsBeingFinalized()) { 553 if (parameterized_type.IsBeingFinalized()) {
542 const Script& script = Script::Handle(cls.script()); 554 // Self reference detected. The type is malformed.
543 ReportError(script, parameterized_type.token_index(), 555 FinalizeMalformedType(
544 "type '%s' illegally refers to itself\n", 556 cls, parameterized_type, finalization,
545 String::Handle(parameterized_type.Name()).ToCString()); 557 "type '%s' illegally refers to itself",
558 String::Handle(parameterized_type.Name()).ToCString());
559 return parameterized_type.raw();
546 } 560 }
547 561
548 // Mark type as being finalized in order to detect illegal self reference. 562 // Mark type as being finalized in order to detect illegal self reference.
549 parameterized_type.set_is_being_finalized(); 563 parameterized_type.set_is_being_finalized();
550 564
551 // Finalize the current type arguments of the type, which are still the 565 // Finalize the current type arguments of the type, which are still the
552 // parsed type arguments. 566 // parsed type arguments.
553 AbstractTypeArguments& arguments = 567 AbstractTypeArguments& arguments =
554 AbstractTypeArguments::Handle(parameterized_type.arguments()); 568 AbstractTypeArguments::Handle(parameterized_type.arguments());
555 if (!arguments.IsNull()) { 569 if (!arguments.IsNull()) {
556 intptr_t num_arguments = arguments.Length(); 570 intptr_t num_arguments = arguments.Length();
557 for (intptr_t i = 0; i < num_arguments; i++) { 571 for (intptr_t i = 0; i < num_arguments; i++) {
558 AbstractType& type_argument = AbstractType::Handle(arguments.TypeAt(i)); 572 AbstractType& type_argument = AbstractType::Handle(arguments.TypeAt(i));
559 type_argument = FinalizeType(cls, type_argument); 573 type_argument = FinalizeType(cls, type_argument, finalization);
560 arguments.SetTypeAt(i, type_argument); 574 arguments.SetTypeAt(i, type_argument);
561 } 575 }
562 } 576 }
563 577
564 // The type class does not need to be finalized in order to finalize the type, 578 // The type class does not need to be finalized in order to finalize the type,
565 // however, it must at least be resolved (this was done as part of resolving 579 // however, it must at least be resolved (this was done as part of resolving
566 // the type itself, a precondition to calling FinalizeType) and the upper 580 // the type itself, a precondition to calling FinalizeType) and the upper
567 // bounds of its type parameters must be finalized (done here). 581 // bounds of its type parameters must be finalized (done here).
568 Class& type_class = Class::Handle(parameterized_type.type_class()); 582 Class& type_class = Class::Handle(parameterized_type.type_class());
569 583
570 // If the type class is a signature class, we are finalizing its signature 584 // If the type class is a signature class, we are finalizing its signature
571 // type, thereby finalizing the result type and parameter types of its 585 // type, thereby finalizing the result type and parameter types of its
572 // signature function. 586 // signature function.
573 // Do this before marking this type as finalized in order to detect cycles. 587 // Do this before marking this type as finalized in order to detect cycles.
574 if (type_class.IsSignatureClass()) { 588 if (type_class.IsSignatureClass()) {
575 // Signature classes are finalized upon creation. 589 // Signature classes are finalized upon creation.
576 ASSERT(type_class.is_finalized()); 590 ASSERT(type_class.is_finalized());
577 // Resolve and finalize the result and parameter types of the signature 591 // Resolve and finalize the result and parameter types of the signature
578 // function of this signature class. 592 // function of this signature class.
579 ResolveAndFinalizeSignature( 593 ResolveAndFinalizeSignature(
580 type_class, Function::Handle(type_class.signature_function())); 594 type_class, Function::Handle(type_class.signature_function()));
581 } 595 }
582 596
597 // Illegally self referencing function types may get finalized indirectly.
598 if (parameterized_type.IsFinalized()) {
599 ASSERT(parameterized_type.IsMalformed());
600 return parameterized_type.raw();
601 }
602
583 // The finalized type argument vector needs num_type_arguments types. 603 // The finalized type argument vector needs num_type_arguments types.
584 const intptr_t num_type_arguments = type_class.NumTypeArguments(); 604 const intptr_t num_type_arguments = type_class.NumTypeArguments();
585 // The type class has num_type_parameters type parameters. 605 // The type class has num_type_parameters type parameters.
586 const intptr_t num_type_parameters = type_class.NumTypeParameters(); 606 const intptr_t num_type_parameters = type_class.NumTypeParameters();
587 607
588 // Initialize the type argument vector. 608 // Initialize the type argument vector.
589 // Check the number of parsed type arguments, if any. 609 // Check the number of parsed type arguments, if any.
590 // Specifying no type arguments indicates a raw type, which is not an error. 610 // Specifying no type arguments indicates a raw type, which is not an error.
591 // However, type parameter bounds are checked below, even for a raw type. 611 // However, type parameter bounds are checked below, even for a raw type.
592 if (!arguments.IsNull() && (arguments.Length() != num_type_parameters)) { 612 if (!arguments.IsNull() && (arguments.Length() != num_type_parameters)) {
593 const Script& script = Script::Handle(cls.script()); 613 // Wrong number of type arguments. The type is malformed.
594 ReportError(script, type.token_index(), 614 FinalizeMalformedType(
595 "wrong number of type arguments in type '%s'\n", 615 cls, parameterized_type, finalization,
596 String::Handle(type.Name()).ToCString()); 616 "wrong number of type arguments in type '%s'",
617 String::Handle(parameterized_type.Name()).ToCString());
618 return parameterized_type.raw();
597 } 619 }
598 // The full type argument vector consists of the type arguments of the 620 // The full type argument vector consists of the type arguments of the
599 // super types of type_class, which may be initialized from the parsed 621 // super types of type_class, which may be initialized from the parsed
600 // type arguments, followed by the parsed type arguments. 622 // type arguments, followed by the parsed type arguments.
601 if (num_type_arguments > 0) { 623 if (num_type_arguments > 0) {
602 TypeArguments& full_arguments = TypeArguments::Handle( 624 TypeArguments& full_arguments = TypeArguments::Handle(
603 TypeArguments::New(num_type_arguments)); 625 TypeArguments::New(num_type_arguments));
604 // Copy the parsed type arguments at the correct offset in the full type 626 // Copy the parsed type arguments at the correct offset in the full type
605 // argument vector. 627 // argument vector.
606 const intptr_t offset = num_type_arguments - num_type_parameters; 628 const intptr_t offset = num_type_arguments - num_type_parameters;
607 AbstractType& type = AbstractType::Handle(Type::DynamicType()); 629 AbstractType& type = AbstractType::Handle(Type::DynamicType());
608 for (intptr_t i = 0; i < num_type_parameters; i++) { 630 for (intptr_t i = 0; i < num_type_parameters; i++) {
609 // If no type parameters were provided, a raw type is desired, so we 631 // If no type parameters were provided, a raw type is desired, so we
610 // create a vector of DynamicType. 632 // create a vector of DynamicType.
611 if (!arguments.IsNull()) { 633 if (!arguments.IsNull()) {
612 type = arguments.TypeAt(i); 634 type = arguments.TypeAt(i);
613 } 635 }
614 full_arguments.SetTypeAt(offset + i, type); 636 full_arguments.SetTypeAt(offset + i, type);
615 } 637 }
616 if (type_class.IsSignatureClass()) { 638 if (type_class.IsSignatureClass()) {
617 const Function& signature_fun = 639 const Function& signature_fun =
618 Function::Handle(type_class.signature_function()); 640 Function::Handle(type_class.signature_function());
619 ASSERT(!signature_fun.is_static()); 641 ASSERT(!signature_fun.is_static());
620 const Class& signature_fun_owner = Class::Handle(signature_fun.owner()); 642 const Class& signature_fun_owner = Class::Handle(signature_fun.owner());
621 FinalizeTypeArguments(signature_fun_owner, full_arguments); 643 FinalizeTypeArguments(signature_fun_owner, full_arguments, finalization);
622 } else { 644 } else {
623 FinalizeTypeArguments(type_class, full_arguments); 645 FinalizeTypeArguments(type_class, full_arguments, finalization);
624 } 646 }
625 // FinalizeTypeArguments can modify 'full_arguments', 647 // FinalizeTypeArguments can modify 'full_arguments',
626 // canonicalize afterwards. 648 // canonicalize afterwards.
627 full_arguments ^= full_arguments.Canonicalize(); 649 full_arguments ^= full_arguments.Canonicalize();
628 parameterized_type.set_arguments(full_arguments); 650 parameterized_type.set_arguments(full_arguments);
629 651
630 // Mark the type as finalized before finalizing the upper bounds, because 652 // Mark the type as finalized.
631 // cycles via upper bounds are legal at compile time.
632 parameterized_type.set_is_finalized(); 653 parameterized_type.set_is_finalized();
633 654
634 ResolveAndFinalizeUpperBounds(type_class);
635 // No need to verify the upper bounds of the finalized type arguments, since 655 // No need to verify the upper bounds of the finalized type arguments, since
636 // bound errors are static type errors, which are not reported by the VM. 656 // bound errors are static type errors, which are not reported by the VM.
637 } else { 657 } else {
638 parameterized_type.set_is_finalized(); 658 parameterized_type.set_is_finalized();
639 } 659 }
640 return parameterized_type.Canonicalize(); 660 return parameterized_type.Canonicalize();
641 } 661 }
642 662
643 663
644 void ClassFinalizer::ResolveAndFinalizeSignature(const Class& cls, 664 void ClassFinalizer::ResolveAndFinalizeSignature(const Class& cls,
645 const Function& function) { 665 const Function& function) {
646 // Resolve result type. 666 // Resolve result type.
647 AbstractType& type = AbstractType::Handle(function.result_type()); 667 AbstractType& type = AbstractType::Handle(function.result_type());
648 ResolveType(cls, type); 668 TypeFinalization result_finalization = kFinalize;
649 type = FinalizeType(cls, type); 669 if (function.IsFactory()) {
670 // The name of a factory must always be resolved to a class or interface.
671 // The parser sets the factory result type to a type with an unresolved
672 // class whose name matches the factory name.
673 result_finalization = kFinalizeWellFormed;
674 }
675 ResolveType(cls, type, result_finalization);
676 type = FinalizeType(cls, type, result_finalization);
650 function.set_result_type(type); 677 function.set_result_type(type);
651 // Resolve formal parameter types. 678 // Resolve formal parameter types.
652 const intptr_t num_parameters = function.NumberOfParameters(); 679 const intptr_t num_parameters = function.NumberOfParameters();
653 for (intptr_t i = 0; i < num_parameters; i++) { 680 for (intptr_t i = 0; i < num_parameters; i++) {
654 type = function.ParameterTypeAt(i); 681 type = function.ParameterTypeAt(i);
655 ResolveType(cls, type); 682 ResolveType(cls, type, kFinalize);
656 type = FinalizeType(cls, type); 683 type = FinalizeType(cls, type, kFinalize);
657 function.SetParameterTypeAt(i, type); 684 function.SetParameterTypeAt(i, type);
658 } 685 }
659 } 686 }
660 687
661 688
662 static RawClass* FindSuperOwnerOfInstanceMember(const Class& cls, 689 static RawClass* FindSuperOwnerOfInstanceMember(const Class& cls,
663 const String& name) { 690 const String& name) {
664 Class& super_class = Class::Handle(); 691 Class& super_class = Class::Handle();
665 Function& function = Function::Handle(); 692 Function& function = Function::Handle();
666 Field& field = Field::Handle(); 693 Field& field = Field::Handle();
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after
701 // Resolve and finalize the upper bounds of the type parameters of class cls. 728 // Resolve and finalize the upper bounds of the type parameters of class cls.
702 void ClassFinalizer::ResolveAndFinalizeUpperBounds(const Class& cls) { 729 void ClassFinalizer::ResolveAndFinalizeUpperBounds(const Class& cls) {
703 const intptr_t num_type_params = cls.NumTypeParameters(); 730 const intptr_t num_type_params = cls.NumTypeParameters();
704 AbstractType& bound = AbstractType::Handle(); 731 AbstractType& bound = AbstractType::Handle();
705 const AbstractTypeArguments& bounds = 732 const AbstractTypeArguments& bounds =
706 AbstractTypeArguments::Handle(cls.type_parameter_bounds()); 733 AbstractTypeArguments::Handle(cls.type_parameter_bounds());
707 ASSERT((bounds.IsNull() && (num_type_params == 0)) || 734 ASSERT((bounds.IsNull() && (num_type_params == 0)) ||
708 (bounds.Length() == num_type_params)); 735 (bounds.Length() == num_type_params));
709 for (intptr_t i = 0; i < num_type_params; i++) { 736 for (intptr_t i = 0; i < num_type_params; i++) {
710 bound = bounds.TypeAt(i); 737 bound = bounds.TypeAt(i);
711 ResolveType(cls, bound); 738 if (bound.IsDynamicType()) {
712 bound = FinalizeType(cls, bound); 739 continue;
740 }
741 ResolveType(cls, bound, kFinalize);
742 bound = FinalizeType(cls, bound, kFinalize);
713 bounds.SetTypeAt(i, bound); 743 bounds.SetTypeAt(i, bound);
714 } 744 }
715 } 745 }
716 746
717 747
718 void ClassFinalizer::ResolveAndFinalizeMemberTypes(const Class& cls) { 748 void ClassFinalizer::ResolveAndFinalizeMemberTypes(const Class& cls) {
719 // Note that getters and setters are explicitly listed as such in the list of 749 // Note that getters and setters are explicitly listed as such in the list of
720 // functions of a class, so we do not need to consider fields as implicitly 750 // functions of a class, so we do not need to consider fields as implicitly
721 // generating getters and setters. 751 // generating getters and setters.
722 // The only compile errors we report are therefore: 752 // The only compile errors we report are therefore:
723 // - a getter having the same name as a method (but not a getter) in a super 753 // - a getter having the same name as a method (but not a getter) in a super
724 // class or in a subclass. 754 // class or in a subclass.
725 // - a setter having the same name as a method (but not a setter) in a super 755 // - a setter having the same name as a method (but not a setter) in a super
726 // class or in a subclass. 756 // class or in a subclass.
727 // - a static field, instance field, or static method (but not an instance 757 // - a static field, instance field, or static method (but not an instance
728 // method) having the same name as an instance member in a super class. 758 // method) having the same name as an instance member in a super class.
729 759
730 // Resolve type of fields and check for conflicts in super classes. 760 // Resolve type of fields and check for conflicts in super classes.
731 Array& array = Array::Handle(cls.fields()); 761 Array& array = Array::Handle(cls.fields());
732 Field& field = Field::Handle(); 762 Field& field = Field::Handle();
733 AbstractType& type = AbstractType::Handle(); 763 AbstractType& type = AbstractType::Handle();
734 String& name = String::Handle(); 764 String& name = String::Handle();
735 Class& super_class = Class::Handle(); 765 Class& super_class = Class::Handle();
736 intptr_t num_fields = array.Length(); 766 intptr_t num_fields = array.Length();
737 for (intptr_t i = 0; i < num_fields; i++) { 767 for (intptr_t i = 0; i < num_fields; i++) {
738 field ^= array.At(i); 768 field ^= array.At(i);
739 type = field.type(); 769 type = field.type();
740 ResolveType(cls, type); 770 ResolveType(cls, type, kFinalize);
741 type = FinalizeType(cls, type); 771 type = FinalizeType(cls, type, kFinalize);
742 field.set_type(type); 772 field.set_type(type);
743 name = field.name(); 773 name = field.name();
744 super_class = FindSuperOwnerOfInstanceMember(cls, name); 774 super_class = FindSuperOwnerOfInstanceMember(cls, name);
745 if (!super_class.IsNull()) { 775 if (!super_class.IsNull()) {
746 const String& class_name = String::Handle(cls.Name()); 776 const String& class_name = String::Handle(cls.Name());
747 const String& super_class_name = String::Handle(super_class.Name()); 777 const String& super_class_name = String::Handle(super_class.Name());
748 const Script& script = Script::Handle(cls.script()); 778 const Script& script = Script::Handle(cls.script());
749 ReportError(script, field.token_index(), 779 ReportError(script, field.token_index(),
750 "field '%s' of class '%s' conflicts with instance " 780 "field '%s' of class '%s' conflicts with instance "
751 "member '%s' of super class '%s'.\n", 781 "member '%s' of super class '%s'",
752 name.ToCString(), 782 name.ToCString(),
753 class_name.ToCString(), 783 class_name.ToCString(),
754 name.ToCString(), 784 name.ToCString(),
755 super_class_name.ToCString()); 785 super_class_name.ToCString());
756 } 786 }
757 } 787 }
758 // Resolve function signatures and check for conflicts in super classes. 788 // Resolve function signatures and check for conflicts in super classes.
759 array = cls.functions(); 789 array = cls.functions();
760 Function& function = Function::Handle(); 790 Function& function = Function::Handle();
761 Function& overridden_function = Function::Handle(); 791 Function& overridden_function = Function::Handle();
762 intptr_t num_functions = array.Length(); 792 intptr_t num_functions = array.Length();
763 String& function_name = String::Handle(); 793 String& function_name = String::Handle();
764 for (intptr_t i = 0; i < num_functions; i++) { 794 for (intptr_t i = 0; i < num_functions; i++) {
765 function ^= array.At(i); 795 function ^= array.At(i);
766 ResolveAndFinalizeSignature(cls, function); 796 ResolveAndFinalizeSignature(cls, function);
767 function_name = function.name(); 797 function_name = function.name();
768 if (function.is_static()) { 798 if (function.is_static()) {
769 super_class = FindSuperOwnerOfInstanceMember(cls, function_name); 799 super_class = FindSuperOwnerOfInstanceMember(cls, function_name);
770 if (!super_class.IsNull()) { 800 if (!super_class.IsNull()) {
771 const String& class_name = String::Handle(cls.Name()); 801 const String& class_name = String::Handle(cls.Name());
772 const String& super_class_name = String::Handle(super_class.Name()); 802 const String& super_class_name = String::Handle(super_class.Name());
773 const Script& script = Script::Handle(cls.script()); 803 const Script& script = Script::Handle(cls.script());
774 ReportError(script, function.token_index(), 804 ReportError(script, function.token_index(),
775 "static function '%s' of class '%s' conflicts with " 805 "static function '%s' of class '%s' conflicts with "
776 "instance member '%s' of super class '%s'.\n", 806 "instance member '%s' of super class '%s'",
777 function_name.ToCString(), 807 function_name.ToCString(),
778 class_name.ToCString(), 808 class_name.ToCString(),
779 function_name.ToCString(), 809 function_name.ToCString(),
780 super_class_name.ToCString()); 810 super_class_name.ToCString());
781 } 811 }
782 } else { 812 } else {
783 // TODO(regis): This arity check is still being debated. Revisit. 813 // TODO(regis): This arity check is still being debated. Revisit.
784 super_class = cls.SuperClass(); 814 super_class = cls.SuperClass();
785 while (!super_class.IsNull()) { 815 while (!super_class.IsNull()) {
786 overridden_function = super_class.LookupDynamicFunction(function_name); 816 overridden_function = super_class.LookupDynamicFunction(function_name);
787 if (!overridden_function.IsNull() && 817 if (!overridden_function.IsNull() &&
788 !function.HasCompatibleParametersWith(overridden_function)) { 818 !function.HasCompatibleParametersWith(overridden_function)) {
789 // Function types are purposely not checked for subtyping. 819 // Function types are purposely not checked for subtyping.
790 const String& class_name = String::Handle(cls.Name()); 820 const String& class_name = String::Handle(cls.Name());
791 const String& super_class_name = String::Handle(super_class.Name()); 821 const String& super_class_name = String::Handle(super_class.Name());
792 const Script& script = Script::Handle(cls.script()); 822 const Script& script = Script::Handle(cls.script());
793 ReportError(script, function.token_index(), 823 ReportError(script, function.token_index(),
794 "class '%s' overrides function '%s' of super class '%s' " 824 "class '%s' overrides function '%s' of super class '%s' "
795 "with incompatible parameters.\n", 825 "with incompatible parameters",
796 class_name.ToCString(), 826 class_name.ToCString(),
797 function_name.ToCString(), 827 function_name.ToCString(),
798 super_class_name.ToCString()); 828 super_class_name.ToCString());
799 } 829 }
800 super_class = super_class.SuperClass(); 830 super_class = super_class.SuperClass();
801 } 831 }
802 } 832 }
803 if (function.kind() == RawFunction::kGetterFunction) { 833 if (function.kind() == RawFunction::kGetterFunction) {
804 name = Field::NameFromGetter(function_name); 834 name = Field::NameFromGetter(function_name);
805 super_class = FindSuperOwnerOfFunction(cls, name); 835 super_class = FindSuperOwnerOfFunction(cls, name);
806 if (!super_class.IsNull()) { 836 if (!super_class.IsNull()) {
807 const String& class_name = String::Handle(cls.Name()); 837 const String& class_name = String::Handle(cls.Name());
808 const String& super_class_name = String::Handle(super_class.Name()); 838 const String& super_class_name = String::Handle(super_class.Name());
809 const Script& script = Script::Handle(cls.script()); 839 const Script& script = Script::Handle(cls.script());
810 ReportError(script, function.token_index(), 840 ReportError(script, function.token_index(),
811 "getter '%s' of class '%s' conflicts with " 841 "getter '%s' of class '%s' conflicts with "
812 "function '%s' of super class '%s'.\n", 842 "function '%s' of super class '%s'",
813 name.ToCString(), 843 name.ToCString(),
814 class_name.ToCString(), 844 class_name.ToCString(),
815 name.ToCString(), 845 name.ToCString(),
816 super_class_name.ToCString()); 846 super_class_name.ToCString());
817 } 847 }
818 } else if (function.kind() == RawFunction::kSetterFunction) { 848 } else if (function.kind() == RawFunction::kSetterFunction) {
819 name = Field::NameFromSetter(function_name); 849 name = Field::NameFromSetter(function_name);
820 super_class = FindSuperOwnerOfFunction(cls, name); 850 super_class = FindSuperOwnerOfFunction(cls, name);
821 if (!super_class.IsNull()) { 851 if (!super_class.IsNull()) {
822 const String& class_name = String::Handle(cls.Name()); 852 const String& class_name = String::Handle(cls.Name());
823 const String& super_class_name = String::Handle(super_class.Name()); 853 const String& super_class_name = String::Handle(super_class.Name());
824 const Script& script = Script::Handle(cls.script()); 854 const Script& script = Script::Handle(cls.script());
825 ReportError(script, function.token_index(), 855 ReportError(script, function.token_index(),
826 "setter '%s' of class '%s' conflicts with " 856 "setter '%s' of class '%s' conflicts with "
827 "function '%s' of super class '%s'.\n", 857 "function '%s' of super class '%s'",
828 name.ToCString(), 858 name.ToCString(),
829 class_name.ToCString(), 859 class_name.ToCString(),
830 name.ToCString(), 860 name.ToCString(),
831 super_class_name.ToCString()); 861 super_class_name.ToCString());
832 } 862 }
833 } else { 863 } else {
834 name = Field::GetterName(function_name); 864 name = Field::GetterName(function_name);
835 super_class = FindSuperOwnerOfFunction(cls, name); 865 super_class = FindSuperOwnerOfFunction(cls, name);
836 if (!super_class.IsNull()) { 866 if (!super_class.IsNull()) {
837 const String& class_name = String::Handle(cls.Name()); 867 const String& class_name = String::Handle(cls.Name());
838 const String& super_class_name = String::Handle(super_class.Name()); 868 const String& super_class_name = String::Handle(super_class.Name());
839 const Script& script = Script::Handle(cls.script()); 869 const Script& script = Script::Handle(cls.script());
840 ReportError(script, function.token_index(), 870 ReportError(script, function.token_index(),
841 "function '%s' of class '%s' conflicts with " 871 "function '%s' of class '%s' conflicts with "
842 "getter '%s' of super class '%s'.\n", 872 "getter '%s' of super class '%s'",
843 function_name.ToCString(), 873 function_name.ToCString(),
844 class_name.ToCString(), 874 class_name.ToCString(),
845 function_name.ToCString(), 875 function_name.ToCString(),
846 super_class_name.ToCString()); 876 super_class_name.ToCString());
847 } 877 }
848 name = Field::SetterName(function_name); 878 name = Field::SetterName(function_name);
849 super_class = FindSuperOwnerOfFunction(cls, name); 879 super_class = FindSuperOwnerOfFunction(cls, name);
850 if (!super_class.IsNull()) { 880 if (!super_class.IsNull()) {
851 const String& class_name = String::Handle(cls.Name()); 881 const String& class_name = String::Handle(cls.Name());
852 const String& super_class_name = String::Handle(super_class.Name()); 882 const String& super_class_name = String::Handle(super_class.Name());
853 const Script& script = Script::Handle(cls.script()); 883 const Script& script = Script::Handle(cls.script());
854 ReportError(script, function.token_index(), 884 ReportError(script, function.token_index(),
855 "function '%s' of class '%s' conflicts with " 885 "function '%s' of class '%s' conflicts with "
856 "setter '%s' of super class '%s'.\n", 886 "setter '%s' of super class '%s'",
857 function_name.ToCString(), 887 function_name.ToCString(),
858 class_name.ToCString(), 888 class_name.ToCString(),
859 function_name.ToCString(), 889 function_name.ToCString(),
860 super_class_name.ToCString()); 890 super_class_name.ToCString());
861 } 891 }
862 } 892 }
863 } 893 }
864 } 894 }
865 895
866 896
867 void ClassFinalizer::FinalizeClass(const Class& cls, bool generating_snapshot) { 897 void ClassFinalizer::FinalizeClass(const Class& cls, bool generating_snapshot) {
868 if (cls.is_finalized()) { 898 if (cls.is_finalized()) {
869 return; 899 return;
870 } 900 }
871 if (FLAG_trace_class_finalization) { 901 if (FLAG_trace_class_finalization) {
872 OS::Print("Finalize %s\n", cls.ToCString()); 902 OS::Print("Finalize %s\n", cls.ToCString());
873 } 903 }
874 // Signature classes are finalized upon creation. 904 // Signature classes are finalized upon creation.
875 ASSERT(!cls.IsSignatureClass()); 905 ASSERT(!cls.IsSignatureClass());
876 if (!IsSuperCycleFree(cls)) { 906 if (!IsSuperCycleFree(cls)) {
877 const String& name = String::Handle(cls.Name()); 907 const String& name = String::Handle(cls.Name());
878 const Script& script = Script::Handle(cls.script()); 908 const Script& script = Script::Handle(cls.script());
879 ReportError(script, cls.token_index(), 909 ReportError(script, cls.token_index(),
880 "class '%s' has a cycle in its superclass relationship.\n", 910 "class '%s' has a cycle in its superclass relationship",
881 name.ToCString()); 911 name.ToCString());
882 } 912 }
883 GrowableArray<const Class*> visited; 913 GrowableArray<const Class*> visited;
884 ResolveInterfaces(cls, &visited); 914 ResolveInterfaces(cls, &visited);
885 Type& super_type = Type::Handle(cls.super_type()); 915 Type& super_type = Type::Handle(cls.super_type());
886 if (!super_type.IsNull()) { 916 if (!super_type.IsNull()) {
887 const Class& super_class = Class::Handle(super_type.type_class()); 917 const Class& super_class = Class::Handle(super_type.type_class());
888 // Finalize super class and super type. 918 // Finalize super class and super type.
889 FinalizeClass(super_class, generating_snapshot); 919 FinalizeClass(super_class, generating_snapshot);
890 super_type ^= FinalizeType(cls, super_type); 920 super_type ^= FinalizeType(cls, super_type, kFinalizeWellFormed);
891 cls.set_super_type(super_type); 921 cls.set_super_type(super_type);
892 } 922 }
893 if (cls.is_interface()) { 923 if (cls.is_interface()) {
894 if (cls.HasFactoryClass()) { 924 if (cls.HasFactoryClass()) {
895 const Class& factory_class = Class::Handle(cls.FactoryClass()); 925 const Class& factory_class = Class::Handle(cls.FactoryClass());
896 // Finalize factory class. 926 // Finalize factory class.
897 if (!factory_class.is_finalized()) { 927 if (!factory_class.is_finalized()) {
898 FinalizeClass(factory_class, generating_snapshot); 928 FinalizeClass(factory_class, generating_snapshot);
899 // Finalizing the factory class may indirectly finalize this interface. 929 // Finalizing the factory class may indirectly finalize this interface.
900 if (cls.is_finalized()) { 930 if (cls.is_finalized()) {
901 return; 931 return;
902 } 932 }
903 } 933 }
904 } 934 }
905 } 935 }
906 // Finalize interface types (but not necessarily interface classes). 936 // Finalize interface types (but not necessarily interface classes).
907 Array& interface_types = Array::Handle(cls.interfaces()); 937 Array& interface_types = Array::Handle(cls.interfaces());
908 AbstractType& interface_type = AbstractType::Handle(); 938 AbstractType& interface_type = AbstractType::Handle();
909 for (intptr_t i = 0; i < interface_types.Length(); i++) { 939 for (intptr_t i = 0; i < interface_types.Length(); i++) {
910 interface_type ^= interface_types.At(i); 940 interface_type ^= interface_types.At(i);
911 interface_type = FinalizeType(cls, interface_type); 941 interface_type = FinalizeType(cls, interface_type, kFinalizeWellFormed);
912 interface_types.SetAt(i, interface_type); 942 interface_types.SetAt(i, interface_type);
913 } 943 }
914 // Mark as finalized before resolving type parameter upper bounds and member 944 // Mark as finalized before resolving type parameter upper bounds and member
915 // types in order to break cycles. 945 // types in order to break cycles.
916 cls.Finalize(); 946 cls.Finalize();
917 ResolveAndFinalizeUpperBounds(cls); 947 ResolveAndFinalizeUpperBounds(cls);
918 ResolveAndFinalizeMemberTypes(cls); 948 ResolveAndFinalizeMemberTypes(cls);
919 // Run additional checks after all types are finalized. 949 // Run additional checks after all types are finalized.
920 if (cls.is_const()) { 950 if (cls.is_const()) {
921 CheckForLegalConstClass(cls); 951 CheckForLegalConstClass(cls);
(...skipping 83 matching lines...) Expand 10 before | Expand all | Expand 10 after
1005 // we found a loop. 1035 // we found a loop.
1006 void ClassFinalizer::ResolveInterfaces(const Class& cls, 1036 void ClassFinalizer::ResolveInterfaces(const Class& cls,
1007 GrowableArray<const Class*>* visited) { 1037 GrowableArray<const Class*>* visited) {
1008 ASSERT(visited != NULL); 1038 ASSERT(visited != NULL);
1009 for (int i = 0; i < visited->length(); i++) { 1039 for (int i = 0; i < visited->length(); i++) {
1010 if ((*visited)[i]->raw() == cls.raw()) { 1040 if ((*visited)[i]->raw() == cls.raw()) {
1011 // We have already visited interface class 'cls'. We found a cycle. 1041 // We have already visited interface class 'cls'. We found a cycle.
1012 const String& interface_name = String::Handle(cls.Name()); 1042 const String& interface_name = String::Handle(cls.Name());
1013 const Script& script = Script::Handle(cls.script()); 1043 const Script& script = Script::Handle(cls.script());
1014 ReportError(script, cls.token_index(), 1044 ReportError(script, cls.token_index(),
1015 "Cyclic reference found for interface '%s'\n", 1045 "cyclic reference found for interface '%s'",
1016 interface_name.ToCString()); 1046 interface_name.ToCString());
1017 } 1047 }
1018 } 1048 }
1019 1049
1020 // If the class/interface has no explicit interfaces, we are done. 1050 // If the class/interface has no explicit interfaces, we are done.
1021 Array& super_interfaces = Array::Handle(cls.interfaces()); 1051 Array& super_interfaces = Array::Handle(cls.interfaces());
1022 if (super_interfaces.Length() == 0) { 1052 if (super_interfaces.Length() == 0) {
1023 return; 1053 return;
1024 } 1054 }
1025 1055
1026 // If cls belongs to core lib or to core lib's implementation, restrictions 1056 // If cls belongs to core lib or to core lib's implementation, restrictions
1027 // about allowed interfaces are lifted. 1057 // about allowed interfaces are lifted.
1028 const bool cls_belongs_to_core_lib = 1058 const bool cls_belongs_to_core_lib =
1029 (cls.library() == Library::CoreLibrary()) || 1059 (cls.library() == Library::CoreLibrary()) ||
1030 (cls.library() == Library::CoreImplLibrary()); 1060 (cls.library() == Library::CoreImplLibrary());
1031 1061
1032 // Resolve and check the interfaces of cls. 1062 // Resolve and check the interfaces of cls.
1033 visited->Add(&cls); 1063 visited->Add(&cls);
1034 AbstractType& interface = AbstractType::Handle(); 1064 AbstractType& interface = AbstractType::Handle();
1035 for (intptr_t i = 0; i < super_interfaces.Length(); i++) { 1065 for (intptr_t i = 0; i < super_interfaces.Length(); i++) {
1036 interface ^= super_interfaces.At(i); 1066 interface ^= super_interfaces.At(i);
1037 ResolveType(cls, interface); 1067 ResolveType(cls, interface, kFinalizeWellFormed);
1038 if (interface.IsTypeParameter()) { 1068 if (interface.IsTypeParameter()) {
1039 const Script& script = Script::Handle(cls.script()); 1069 const Script& script = Script::Handle(cls.script());
1040 ReportError(script, cls.token_index(), 1070 ReportError(script, cls.token_index(),
1041 "Type parameter '%s' cannot be used as interface\n", 1071 "type parameter '%s' cannot be used as interface",
1042 String::Handle(interface.Name()).ToCString()); 1072 String::Handle(interface.Name()).ToCString());
1043 } 1073 }
1044 const Class& interface_class = Class::Handle(interface.type_class()); 1074 const Class& interface_class = Class::Handle(interface.type_class());
1045 if (!interface_class.is_interface()) { 1075 if (!interface_class.is_interface()) {
1046 const Script& script = Script::Handle(cls.script()); 1076 const Script& script = Script::Handle(cls.script());
1047 ReportError(script, cls.token_index(), 1077 ReportError(script, cls.token_index(),
1048 "Class '%s' is used where an interface is expected\n", 1078 "class '%s' is used where an interface is expected",
1049 String::Handle(interface_class.Name()).ToCString()); 1079 String::Handle(interface_class.Name()).ToCString());
1050 } 1080 }
1051 // Verify that unless cls belongs to core lib, it cannot extend or implement 1081 // Verify that unless cls belongs to core lib, it cannot extend or implement
1052 // any of bool, num, int, double, String, Function, Dynamic. 1082 // any of bool, num, int, double, String, Function, Dynamic.
1053 // The exception is signature classes, which are compiler generated and 1083 // The exception is signature classes, which are compiler generated and
1054 // represent a function type, therefore implementing the Function interface. 1084 // represent a function type, therefore implementing the Function interface.
1055 if (!cls_belongs_to_core_lib) { 1085 if (!cls_belongs_to_core_lib) {
1056 if (interface.IsBoolInterface() || 1086 if (interface.IsBoolInterface() ||
1057 interface.IsNumberInterface() || 1087 interface.IsNumberInterface() ||
1058 interface.IsIntInterface() || 1088 interface.IsIntInterface() ||
1059 interface.IsDoubleInterface() || 1089 interface.IsDoubleInterface() ||
1060 interface.IsStringInterface() || 1090 interface.IsStringInterface() ||
1061 (interface.IsFunctionInterface() && !cls.IsSignatureClass()) || 1091 (interface.IsFunctionInterface() && !cls.IsSignatureClass()) ||
1062 interface.IsDynamicType()) { 1092 interface.IsDynamicType()) {
1063 const Script& script = Script::Handle(cls.script()); 1093 const Script& script = Script::Handle(cls.script());
1064 ReportError(script, cls.token_index(), 1094 ReportError(script, cls.token_index(),
1065 "'%s' is not allowed to extend or implement '%s'\n", 1095 "'%s' is not allowed to extend or implement '%s'",
1066 String::Handle(cls.Name()).ToCString(), 1096 String::Handle(cls.Name()).ToCString(),
1067 String::Handle(interface_class.Name()).ToCString()); 1097 String::Handle(interface_class.Name()).ToCString());
1068 } 1098 }
1069 } 1099 }
1070 // Now resolve the super interfaces. 1100 // Now resolve the super interfaces.
1071 ResolveInterfaces(interface_class, visited); 1101 ResolveInterfaces(interface_class, visited);
1072 } 1102 }
1073 visited->RemoveLast(); 1103 visited->RemoveLast();
1074 } 1104 }
1075 1105
1076 1106
1077 // A class is marked as constant if it has one constant constructor. 1107 // A class is marked as constant if it has one constant constructor.
1078 // A constant class: 1108 // A constant class:
1079 // - may extend only const classes. 1109 // - may extend only const classes.
1080 // - has only const instance fields. 1110 // - has only const instance fields.
1081 // Note: we must check for cycles before checking for const properties. 1111 // Note: we must check for cycles before checking for const properties.
1082 void ClassFinalizer::CheckForLegalConstClass(const Class& cls) { 1112 void ClassFinalizer::CheckForLegalConstClass(const Class& cls) {
1083 ASSERT(cls.is_const()); 1113 ASSERT(cls.is_const());
1084 const Class& super = Class::Handle(cls.SuperClass()); 1114 const Class& super = Class::Handle(cls.SuperClass());
1085 if (!super.IsNull() && !super.is_const()) { 1115 if (!super.IsNull() && !super.is_const()) {
1086 String& name = String::Handle(super.Name()); 1116 String& name = String::Handle(super.Name());
1087 const Script& script = Script::Handle(cls.script()); 1117 const Script& script = Script::Handle(cls.script());
1088 ReportError(script, cls.token_index(), 1118 ReportError(script, cls.token_index(),
1089 "superclass '%s' must be const.\n", name.ToCString()); 1119 "superclass '%s' must be const", name.ToCString());
1090 } 1120 }
1091 const Array& fields_array = Array::Handle(cls.fields()); 1121 const Array& fields_array = Array::Handle(cls.fields());
1092 intptr_t len = fields_array.Length(); 1122 intptr_t len = fields_array.Length();
1093 Field& field = Field::Handle(); 1123 Field& field = Field::Handle();
1094 for (intptr_t i = 0; i < len; i++) { 1124 for (intptr_t i = 0; i < len; i++) {
1095 field ^= fields_array.At(i); 1125 field ^= fields_array.At(i);
1096 if (!field.is_static() && !field.is_final()) { 1126 if (!field.is_static() && !field.is_final()) {
1097 const String& class_name = String::Handle(cls.Name()); 1127 const String& class_name = String::Handle(cls.Name());
1098 const String& field_name = String::Handle(field.name()); 1128 const String& field_name = String::Handle(field.name());
1099 const Script& script = Script::Handle(cls.script()); 1129 const Script& script = Script::Handle(cls.script());
1100 ReportError(script, field.token_index(), 1130 ReportError(script, field.token_index(),
1101 "const class '%s' has non-final field '%s'\n", 1131 "const class '%s' has non-final field '%s'",
1102 class_name.ToCString(), field_name.ToCString()); 1132 class_name.ToCString(), field_name.ToCString());
1103 } 1133 }
1104 } 1134 }
1105 } 1135 }
1106 1136
1107 1137
1108 void ClassFinalizer::PrintClassInformation(const Class& cls) { 1138 void ClassFinalizer::PrintClassInformation(const Class& cls) {
1109 HANDLESCOPE(Isolate::Current()); 1139 HANDLESCOPE(Isolate::Current());
1110 const String& class_name = String::Handle(cls.Name()); 1140 const String& class_name = String::Handle(cls.Name());
1111 OS::Print("%s '%s'", 1141 OS::Print("%s '%s'",
(...skipping 24 matching lines...) Expand all
1136 const Array& fields_array = Array::Handle(cls.fields()); 1166 const Array& fields_array = Array::Handle(cls.fields());
1137 Field& field = Field::Handle(); 1167 Field& field = Field::Handle();
1138 len = fields_array.Length(); 1168 len = fields_array.Length();
1139 for (intptr_t i = 0; i < len; i++) { 1169 for (intptr_t i = 0; i < len; i++) {
1140 field ^= fields_array.At(i); 1170 field ^= fields_array.At(i);
1141 OS::Print(" %s\n", field.ToCString()); 1171 OS::Print(" %s\n", field.ToCString());
1142 } 1172 }
1143 } 1173 }
1144 1174
1145 1175
1176 void ClassFinalizer::FinalizeMalformedType(const Class& cls,
1177 const Type& type,
1178 TypeFinalization finalization,
1179 const char* format, ...) {
1180 va_list args;
1181 va_start(args, format);
1182 LanguageError& error = LanguageError::Handle();
1183 if ((finalization == kFinalizeWellFormed) || FLAG_enable_type_checks) {
1184 const Script& script = Script::Handle(cls.script());
1185 error ^=
1186 Parser::FormatError(script, type.token_index(), "Error", format, args);
1187 if (finalization == kFinalizeWellFormed) {
1188 ReportError(error);
1189 }
1190 }
1191 // Replace malformed type with Dynamic type.
1192 type.set_type_class(Class::Handle(Object::dynamic_class()));
1193 type.set_arguments(AbstractTypeArguments::Handle());
1194 if (FLAG_enable_type_checks) {
1195 // In checked mode, mark type as malformed.
1196 type.set_malformed_error(error);
1197 }
1198 type.set_is_finalized();
1199 type.Canonicalize();
1200 }
1201
1202
1203 void ClassFinalizer::ReportError(const Error& error) {
1204 Isolate::Current()->long_jump_base()->Jump(1, error);
1205 UNREACHABLE();
1206 }
1207
1208
1146 void ClassFinalizer::ReportError(const Script& script, 1209 void ClassFinalizer::ReportError(const Script& script,
1147 intptr_t token_index, 1210 intptr_t token_index,
1148 const char* format, ...) { 1211 const char* format, ...) {
1149 va_list args; 1212 va_list args;
1150 va_start(args, format); 1213 va_start(args, format);
1151 const Error& error = Error::Handle( 1214 const Error& error = Error::Handle(
1152 Parser::FormatError(script, token_index, "Error", format, args)); 1215 Parser::FormatError(script, token_index, "Error", format, args));
1153 Isolate::Current()->long_jump_base()->Jump(1, error); 1216 ReportError(error);
1154 UNREACHABLE();
1155 } 1217 }
1156 1218
1157 1219
1158 void ClassFinalizer::ReportError(const char* format, ...) { 1220 void ClassFinalizer::ReportError(const char* format, ...) {
1159 va_list args; 1221 va_list args;
1160 va_start(args, format); 1222 va_start(args, format);
1161 const Error& error = Error::Handle( 1223 const Error& error = Error::Handle(
1162 Parser::FormatError(Script::Handle(), -1, "Error", format, args)); 1224 Parser::FormatError(Script::Handle(), -1, "Error", format, args));
1163 va_end(args); 1225 va_end(args);
1164 Isolate::Current()->long_jump_base()->Jump(1, error); 1226 ReportError(error);
1165 UNREACHABLE();
1166 }
1167
1168
1169 void ClassFinalizer::ReportWarning(const Script& script,
1170 intptr_t token_index,
1171 const char* format, ...) {
1172 if (FLAG_silent_warnings) return;
1173 va_list args;
1174 va_start(args, format);
1175 const Error& error = Error::Handle(
1176 Parser::FormatError(script, token_index, "Warning", format, args));
1177 va_end(args);
1178 if (FLAG_warning_as_error) {
1179 Isolate::Current()->long_jump_base()->Jump(1, error);
1180 UNREACHABLE();
1181 } else {
1182 OS::Print("%s", error.ToErrorCString());
1183 }
1184 } 1227 }
1185 1228
1186 } // namespace dart 1229 } // namespace dart
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698