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

Side by Side Diff: vm/class_finalizer.cc

Issue 10632009: Make the parser agnostic to the TokenStream implementation. This is the first step towards compacti… (Closed) Base URL: http://dart.googlecode.com/svn/branches/bleeding_edge/dart/runtime/
Patch Set: Created 8 years, 6 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
« no previous file with comments | « vm/ast_printer.cc ('k') | vm/code_generator_ia32.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) 2012, the Dart project authors. Please see the AUTHORS file 1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file
2 // for details. All rights reserved. Use of this source code is governed by a 2 // for details. All rights reserved. Use of this source code is governed by a
3 // BSD-style license that can be found in the LICENSE file. 3 // BSD-style license that can be found in the LICENSE file.
4 4
5 #include "vm/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"
(...skipping 307 matching lines...) Expand 10 before | Expand all | Expand 10 after
318 if (super_type.IsNull()) { 318 if (super_type.IsNull()) {
319 return; 319 return;
320 } 320 }
321 // Resolve failures lead to a longjmp. 321 // Resolve failures lead to a longjmp.
322 ResolveType(cls, super_type, kFinalizeWellFormed); 322 ResolveType(cls, super_type, kFinalizeWellFormed);
323 const Class& super_class = Class::Handle(super_type.type_class()); 323 const Class& super_class = Class::Handle(super_type.type_class());
324 if (cls.is_interface() != super_class.is_interface()) { 324 if (cls.is_interface() != super_class.is_interface()) {
325 String& class_name = String::Handle(cls.Name()); 325 String& class_name = String::Handle(cls.Name());
326 String& super_class_name = String::Handle(super_class.Name()); 326 String& super_class_name = String::Handle(super_class.Name());
327 const Script& script = Script::Handle(cls.script()); 327 const Script& script = Script::Handle(cls.script());
328 ReportError(script, cls.token_index(), 328 ReportError(script, cls.token_pos(),
329 "class '%s' and superclass '%s' are not " 329 "class '%s' and superclass '%s' are not "
330 "both classes or both interfaces", 330 "both classes or both interfaces",
331 class_name.ToCString(), 331 class_name.ToCString(),
332 super_class_name.ToCString()); 332 super_class_name.ToCString());
333 } 333 }
334 // If cls belongs to core lib or to core lib's implementation, restrictions 334 // If cls belongs to core lib or to core lib's implementation, restrictions
335 // about allowed interfaces are lifted. 335 // about allowed interfaces are lifted.
336 if ((cls.library() != Library::CoreLibrary()) && 336 if ((cls.library() != Library::CoreLibrary()) &&
337 (cls.library() != Library::CoreImplLibrary())) { 337 (cls.library() != Library::CoreImplLibrary())) {
338 // Prevent extending core implementation classes Bool, Double, ObjectArray, 338 // Prevent extending core implementation classes Bool, Double, ObjectArray,
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after
374 (super_class.raw() == object_store->external_float32_array_class()) || 374 (super_class.raw() == object_store->external_float32_array_class()) ||
375 (super_class.raw() == object_store->external_float64_array_class()) || 375 (super_class.raw() == object_store->external_float64_array_class()) ||
376 (super_class.raw() == integer_implementation_class.raw()) || 376 (super_class.raw() == integer_implementation_class.raw()) ||
377 (super_class.raw() == object_store->smi_class()) || 377 (super_class.raw() == object_store->smi_class()) ||
378 (super_class.raw() == object_store->mint_class()) || 378 (super_class.raw() == object_store->mint_class()) ||
379 (super_class.raw() == object_store->bigint_class()) || 379 (super_class.raw() == object_store->bigint_class()) ||
380 (super_class.raw() == object_store->one_byte_string_class()) || 380 (super_class.raw() == object_store->one_byte_string_class()) ||
381 (super_class.raw() == object_store->two_byte_string_class()) || 381 (super_class.raw() == object_store->two_byte_string_class()) ||
382 (super_class.raw() == object_store->four_byte_string_class())) { 382 (super_class.raw() == object_store->four_byte_string_class())) {
383 const Script& script = Script::Handle(cls.script()); 383 const Script& script = Script::Handle(cls.script());
384 ReportError(script, cls.token_index(), 384 ReportError(script, cls.token_pos(),
385 "'%s' is not allowed to extend '%s'", 385 "'%s' is not allowed to extend '%s'",
386 String::Handle(cls.Name()).ToCString(), 386 String::Handle(cls.Name()).ToCString(),
387 String::Handle(super_class.Name()).ToCString()); 387 String::Handle(super_class.Name()).ToCString());
388 } 388 }
389 } 389 }
390 return; 390 return;
391 } 391 }
392 392
393 393
394 void ClassFinalizer::ResolveFactoryClass(const Class& interface) { 394 void ClassFinalizer::ResolveFactoryClass(const Class& interface) {
395 ASSERT(interface.is_interface()); 395 ASSERT(interface.is_interface());
396 if (interface.is_finalized() || 396 if (interface.is_finalized() ||
397 !interface.HasFactoryClass() || 397 !interface.HasFactoryClass() ||
398 interface.HasResolvedFactoryClass()) { 398 interface.HasResolvedFactoryClass()) {
399 return; 399 return;
400 } 400 }
401 const UnresolvedClass& unresolved_factory_class = 401 const UnresolvedClass& unresolved_factory_class =
402 UnresolvedClass::Handle(interface.UnresolvedFactoryClass()); 402 UnresolvedClass::Handle(interface.UnresolvedFactoryClass());
403 403
404 // Lookup the factory class. 404 // Lookup the factory class.
405 const Class& factory_class = 405 const Class& factory_class =
406 Class::Handle(ResolveClass(interface, unresolved_factory_class)); 406 Class::Handle(ResolveClass(interface, unresolved_factory_class));
407 if (factory_class.IsNull()) { 407 if (factory_class.IsNull()) {
408 const Script& script = Script::Handle(interface.script()); 408 const Script& script = Script::Handle(interface.script());
409 ReportError(script, unresolved_factory_class.token_index(), 409 ReportError(script, unresolved_factory_class.token_pos(),
410 "cannot resolve factory class name '%s' from '%s'", 410 "cannot resolve factory class name '%s' from '%s'",
411 String::Handle(unresolved_factory_class.Name()).ToCString(), 411 String::Handle(unresolved_factory_class.Name()).ToCString(),
412 String::Handle(interface.Name()).ToCString()); 412 String::Handle(interface.Name()).ToCString());
413 } 413 }
414 if (factory_class.is_interface()) { 414 if (factory_class.is_interface()) {
415 const String& interface_name = String::Handle(interface.Name()); 415 const String& interface_name = String::Handle(interface.Name());
416 const String& factory_name = String::Handle(factory_class.Name()); 416 const String& factory_name = String::Handle(factory_class.Name());
417 const Script& script = Script::Handle(interface.script()); 417 const Script& script = Script::Handle(interface.script());
418 ReportError(script, unresolved_factory_class.token_index(), 418 ReportError(script, unresolved_factory_class.token_pos(),
419 "default clause of interface '%s' names non-class '%s'", 419 "default clause of interface '%s' names non-class '%s'",
420 interface_name.ToCString(), 420 interface_name.ToCString(),
421 factory_name.ToCString()); 421 factory_name.ToCString());
422 } 422 }
423 interface.set_factory_class(factory_class); 423 interface.set_factory_class(factory_class);
424 // It is not necessary to finalize the bounds before comparing them between 424 // It is not necessary to finalize the bounds before comparing them between
425 // the expected and actual factory class. 425 // the expected and actual factory class.
426 const Class& factory_signature_class = Class::Handle( 426 const Class& factory_signature_class = Class::Handle(
427 unresolved_factory_class.factory_signature_class()); 427 unresolved_factory_class.factory_signature_class());
428 ASSERT(!factory_signature_class.IsNull()); 428 ASSERT(!factory_signature_class.IsNull());
429 // If a type parameter list is included in the default factory clause (it 429 // If a type parameter list is included in the default factory clause (it
430 // can be omitted), verify that it matches the list of type parameters of 430 // can be omitted), verify that it matches the list of type parameters of
431 // the factory class in number, names, and bounds. 431 // the factory class in number, names, and bounds.
432 if (factory_signature_class.NumTypeParameters() > 0) { 432 if (factory_signature_class.NumTypeParameters() > 0) {
433 const TypeArguments& expected_type_parameters = 433 const TypeArguments& expected_type_parameters =
434 TypeArguments::Handle(factory_signature_class.type_parameters()); 434 TypeArguments::Handle(factory_signature_class.type_parameters());
435 const TypeArguments& actual_type_parameters = 435 const TypeArguments& actual_type_parameters =
436 TypeArguments::Handle(factory_class.type_parameters()); 436 TypeArguments::Handle(factory_class.type_parameters());
437 const TypeArguments& expected_type_parameter_bounds = 437 const TypeArguments& expected_type_parameter_bounds =
438 TypeArguments::Handle(factory_signature_class.type_parameter_bounds()); 438 TypeArguments::Handle(factory_signature_class.type_parameter_bounds());
439 const TypeArguments& actual_type_parameter_bounds = 439 const TypeArguments& actual_type_parameter_bounds =
440 TypeArguments::Handle(factory_class.type_parameter_bounds()); 440 TypeArguments::Handle(factory_class.type_parameter_bounds());
441 if (!AbstractTypeArguments::AreIdentical(expected_type_parameters, 441 if (!AbstractTypeArguments::AreIdentical(expected_type_parameters,
442 actual_type_parameters) || 442 actual_type_parameters) ||
443 !AbstractTypeArguments::AreIdentical(expected_type_parameter_bounds, 443 !AbstractTypeArguments::AreIdentical(expected_type_parameter_bounds,
444 actual_type_parameter_bounds)) { 444 actual_type_parameter_bounds)) {
445 const String& interface_name = String::Handle(interface.Name()); 445 const String& interface_name = String::Handle(interface.Name());
446 const String& factory_name = String::Handle(factory_class.Name()); 446 const String& factory_name = String::Handle(factory_class.Name());
447 const Script& script = Script::Handle(interface.script()); 447 const Script& script = Script::Handle(interface.script());
448 ReportError(script, unresolved_factory_class.token_index(), 448 ReportError(script, unresolved_factory_class.token_pos(),
449 "mismatch in number, names, or bounds of type parameters " 449 "mismatch in number, names, or bounds of type parameters "
450 "between default clause of interface '%s' and actual factory " 450 "between default clause of interface '%s' and actual factory "
451 "class '%s'", 451 "class '%s'",
452 interface_name.ToCString(), 452 interface_name.ToCString(),
453 factory_name.ToCString()); 453 factory_name.ToCString());
454 } 454 }
455 } 455 }
456 // Verify that the type parameters of the factory class and of the interface 456 // Verify that the type parameters of the factory class and of the interface
457 // have identical names. 457 // have identical names.
458 const TypeArguments& interface_type_parameters = 458 const TypeArguments& interface_type_parameters =
459 TypeArguments::Handle(interface.type_parameters()); 459 TypeArguments::Handle(interface.type_parameters());
460 const TypeArguments& factory_type_parameters = 460 const TypeArguments& factory_type_parameters =
461 TypeArguments::Handle(factory_class.type_parameters()); 461 TypeArguments::Handle(factory_class.type_parameters());
462 if (!AbstractTypeArguments::AreIdentical(interface_type_parameters, 462 if (!AbstractTypeArguments::AreIdentical(interface_type_parameters,
463 factory_type_parameters)) { 463 factory_type_parameters)) {
464 const String& interface_name = String::Handle(interface.Name()); 464 const String& interface_name = String::Handle(interface.Name());
465 const String& factory_name = String::Handle(factory_class.Name()); 465 const String& factory_name = String::Handle(factory_class.Name());
466 const Script& script = Script::Handle(interface.script()); 466 const Script& script = Script::Handle(interface.script());
467 ReportError(script, unresolved_factory_class.token_index(), 467 ReportError(script, unresolved_factory_class.token_pos(),
468 "mismatch in number or names of type parameters between " 468 "mismatch in number or names of type parameters between "
469 "interface '%s' and default factory class '%s'", 469 "interface '%s' and default factory class '%s'",
470 interface_name.ToCString(), 470 interface_name.ToCString(),
471 factory_name.ToCString()); 471 factory_name.ToCString());
472 } 472 }
473 } 473 }
474 474
475 475
476 void ClassFinalizer::ResolveType(const Class& cls, 476 void ClassFinalizer::ResolveType(const Class& cls,
477 const AbstractType& type, 477 const AbstractType& type,
(...skipping 467 matching lines...) Expand 10 before | Expand all | Expand 10 after
945 type = field.type(); 945 type = field.type();
946 ResolveType(cls, type, kFinalize); 946 ResolveType(cls, type, kFinalize);
947 type = FinalizeType(cls, type, kFinalize); 947 type = FinalizeType(cls, type, kFinalize);
948 field.set_type(type); 948 field.set_type(type);
949 name = field.name(); 949 name = field.name();
950 super_class = FindSuperOwnerOfInstanceMember(cls, name); 950 super_class = FindSuperOwnerOfInstanceMember(cls, name);
951 if (!super_class.IsNull()) { 951 if (!super_class.IsNull()) {
952 const String& class_name = String::Handle(cls.Name()); 952 const String& class_name = String::Handle(cls.Name());
953 const String& super_class_name = String::Handle(super_class.Name()); 953 const String& super_class_name = String::Handle(super_class.Name());
954 const Script& script = Script::Handle(cls.script()); 954 const Script& script = Script::Handle(cls.script());
955 ReportError(script, field.token_index(), 955 ReportError(script, field.token_pos(),
956 "field '%s' of class '%s' conflicts with instance " 956 "field '%s' of class '%s' conflicts with instance "
957 "member '%s' of super class '%s'", 957 "member '%s' of super class '%s'",
958 name.ToCString(), 958 name.ToCString(),
959 class_name.ToCString(), 959 class_name.ToCString(),
960 name.ToCString(), 960 name.ToCString(),
961 super_class_name.ToCString()); 961 super_class_name.ToCString());
962 } 962 }
963 } 963 }
964 // Collect interfaces, super interfaces, and super classes of this class. 964 // Collect interfaces, super interfaces, and super classes of this class.
965 const GrowableObjectArray& interfaces = 965 const GrowableObjectArray& interfaces =
(...skipping 15 matching lines...) Expand all
981 for (intptr_t i = 0; i < num_functions; i++) { 981 for (intptr_t i = 0; i < num_functions; i++) {
982 function ^= array.At(i); 982 function ^= array.At(i);
983 ResolveAndFinalizeSignature(cls, function); 983 ResolveAndFinalizeSignature(cls, function);
984 function_name = function.name(); 984 function_name = function.name();
985 if (function.is_static()) { 985 if (function.is_static()) {
986 super_class = FindSuperOwnerOfInstanceMember(cls, function_name); 986 super_class = FindSuperOwnerOfInstanceMember(cls, function_name);
987 if (!super_class.IsNull()) { 987 if (!super_class.IsNull()) {
988 const String& class_name = String::Handle(cls.Name()); 988 const String& class_name = String::Handle(cls.Name());
989 const String& super_class_name = String::Handle(super_class.Name()); 989 const String& super_class_name = String::Handle(super_class.Name());
990 const Script& script = Script::Handle(cls.script()); 990 const Script& script = Script::Handle(cls.script());
991 ReportError(script, function.token_index(), 991 ReportError(script, function.token_pos(),
992 "static function '%s' of class '%s' conflicts with " 992 "static function '%s' of class '%s' conflicts with "
993 "instance member '%s' of super class '%s'", 993 "instance member '%s' of super class '%s'",
994 function_name.ToCString(), 994 function_name.ToCString(),
995 class_name.ToCString(), 995 class_name.ToCString(),
996 function_name.ToCString(), 996 function_name.ToCString(),
997 super_class_name.ToCString()); 997 super_class_name.ToCString());
998 } 998 }
999 } else { 999 } else {
1000 for (int i = 0; i < interfaces.Length(); i++) { 1000 for (int i = 0; i < interfaces.Length(); i++) {
1001 super_class ^= interfaces.At(i); 1001 super_class ^= interfaces.At(i);
1002 overridden_function = super_class.LookupDynamicFunction(function_name); 1002 overridden_function = super_class.LookupDynamicFunction(function_name);
1003 if (!overridden_function.IsNull() && 1003 if (!overridden_function.IsNull() &&
1004 !function.HasCompatibleParametersWith(overridden_function)) { 1004 !function.HasCompatibleParametersWith(overridden_function)) {
1005 // Function types are purposely not checked for subtyping. 1005 // Function types are purposely not checked for subtyping.
1006 const String& class_name = String::Handle(cls.Name()); 1006 const String& class_name = String::Handle(cls.Name());
1007 const String& super_class_name = String::Handle(super_class.Name()); 1007 const String& super_class_name = String::Handle(super_class.Name());
1008 const Script& script = Script::Handle(cls.script()); 1008 const Script& script = Script::Handle(cls.script());
1009 ReportError(script, function.token_index(), 1009 ReportError(script, function.token_pos(),
1010 "class '%s' overrides function '%s' of %s '%s' " 1010 "class '%s' overrides function '%s' of %s '%s' "
1011 "with incompatible parameters", 1011 "with incompatible parameters",
1012 class_name.ToCString(), 1012 class_name.ToCString(),
1013 function_name.ToCString(), 1013 function_name.ToCString(),
1014 super_class.is_interface() ? "interface" : "super class", 1014 super_class.is_interface() ? "interface" : "super class",
1015 super_class_name.ToCString()); 1015 super_class_name.ToCString());
1016 } 1016 }
1017 } 1017 }
1018 } 1018 }
1019 if (function.kind() == RawFunction::kGetterFunction) { 1019 if (function.kind() == RawFunction::kGetterFunction) {
1020 name = Field::NameFromGetter(function_name); 1020 name = Field::NameFromGetter(function_name);
1021 super_class = FindSuperOwnerOfFunction(cls, name); 1021 super_class = FindSuperOwnerOfFunction(cls, name);
1022 if (!super_class.IsNull()) { 1022 if (!super_class.IsNull()) {
1023 const String& class_name = String::Handle(cls.Name()); 1023 const String& class_name = String::Handle(cls.Name());
1024 const String& super_class_name = String::Handle(super_class.Name()); 1024 const String& super_class_name = String::Handle(super_class.Name());
1025 const Script& script = Script::Handle(cls.script()); 1025 const Script& script = Script::Handle(cls.script());
1026 ReportError(script, function.token_index(), 1026 ReportError(script, function.token_pos(),
1027 "getter '%s' of class '%s' conflicts with " 1027 "getter '%s' of class '%s' conflicts with "
1028 "function '%s' of super class '%s'", 1028 "function '%s' of super class '%s'",
1029 name.ToCString(), 1029 name.ToCString(),
1030 class_name.ToCString(), 1030 class_name.ToCString(),
1031 name.ToCString(), 1031 name.ToCString(),
1032 super_class_name.ToCString()); 1032 super_class_name.ToCString());
1033 } 1033 }
1034 } else if (function.kind() == RawFunction::kSetterFunction) { 1034 } else if (function.kind() == RawFunction::kSetterFunction) {
1035 name = Field::NameFromSetter(function_name); 1035 name = Field::NameFromSetter(function_name);
1036 super_class = FindSuperOwnerOfFunction(cls, name); 1036 super_class = FindSuperOwnerOfFunction(cls, name);
1037 if (!super_class.IsNull()) { 1037 if (!super_class.IsNull()) {
1038 const String& class_name = String::Handle(cls.Name()); 1038 const String& class_name = String::Handle(cls.Name());
1039 const String& super_class_name = String::Handle(super_class.Name()); 1039 const String& super_class_name = String::Handle(super_class.Name());
1040 const Script& script = Script::Handle(cls.script()); 1040 const Script& script = Script::Handle(cls.script());
1041 ReportError(script, function.token_index(), 1041 ReportError(script, function.token_pos(),
1042 "setter '%s' of class '%s' conflicts with " 1042 "setter '%s' of class '%s' conflicts with "
1043 "function '%s' of super class '%s'", 1043 "function '%s' of super class '%s'",
1044 name.ToCString(), 1044 name.ToCString(),
1045 class_name.ToCString(), 1045 class_name.ToCString(),
1046 name.ToCString(), 1046 name.ToCString(),
1047 super_class_name.ToCString()); 1047 super_class_name.ToCString());
1048 } 1048 }
1049 } else { 1049 } else {
1050 name = Field::GetterName(function_name); 1050 name = Field::GetterName(function_name);
1051 super_class = FindSuperOwnerOfFunction(cls, name); 1051 super_class = FindSuperOwnerOfFunction(cls, name);
1052 if (!super_class.IsNull()) { 1052 if (!super_class.IsNull()) {
1053 const String& class_name = String::Handle(cls.Name()); 1053 const String& class_name = String::Handle(cls.Name());
1054 const String& super_class_name = String::Handle(super_class.Name()); 1054 const String& super_class_name = String::Handle(super_class.Name());
1055 const Script& script = Script::Handle(cls.script()); 1055 const Script& script = Script::Handle(cls.script());
1056 ReportError(script, function.token_index(), 1056 ReportError(script, function.token_pos(),
1057 "function '%s' of class '%s' conflicts with " 1057 "function '%s' of class '%s' conflicts with "
1058 "getter '%s' of super class '%s'", 1058 "getter '%s' of super class '%s'",
1059 function_name.ToCString(), 1059 function_name.ToCString(),
1060 class_name.ToCString(), 1060 class_name.ToCString(),
1061 function_name.ToCString(), 1061 function_name.ToCString(),
1062 super_class_name.ToCString()); 1062 super_class_name.ToCString());
1063 } 1063 }
1064 name = Field::SetterName(function_name); 1064 name = Field::SetterName(function_name);
1065 super_class = FindSuperOwnerOfFunction(cls, name); 1065 super_class = FindSuperOwnerOfFunction(cls, name);
1066 if (!super_class.IsNull()) { 1066 if (!super_class.IsNull()) {
1067 const String& class_name = String::Handle(cls.Name()); 1067 const String& class_name = String::Handle(cls.Name());
1068 const String& super_class_name = String::Handle(super_class.Name()); 1068 const String& super_class_name = String::Handle(super_class.Name());
1069 const Script& script = Script::Handle(cls.script()); 1069 const Script& script = Script::Handle(cls.script());
1070 ReportError(script, function.token_index(), 1070 ReportError(script, function.token_pos(),
1071 "function '%s' of class '%s' conflicts with " 1071 "function '%s' of class '%s' conflicts with "
1072 "setter '%s' of super class '%s'", 1072 "setter '%s' of super class '%s'",
1073 function_name.ToCString(), 1073 function_name.ToCString(),
1074 class_name.ToCString(), 1074 class_name.ToCString(),
1075 function_name.ToCString(), 1075 function_name.ToCString(),
1076 super_class_name.ToCString()); 1076 super_class_name.ToCString());
1077 } 1077 }
1078 } 1078 }
1079 } 1079 }
1080 } 1080 }
1081 1081
1082 1082
1083 void ClassFinalizer::FinalizeClass(const Class& cls, bool generating_snapshot) { 1083 void ClassFinalizer::FinalizeClass(const Class& cls, bool generating_snapshot) {
1084 if (cls.is_finalized()) { 1084 if (cls.is_finalized()) {
1085 return; 1085 return;
1086 } 1086 }
1087 if (FLAG_trace_class_finalization) { 1087 if (FLAG_trace_class_finalization) {
1088 OS::Print("Finalize %s\n", cls.ToCString()); 1088 OS::Print("Finalize %s\n", cls.ToCString());
1089 } 1089 }
1090 if (!IsSuperCycleFree(cls)) { 1090 if (!IsSuperCycleFree(cls)) {
1091 const String& name = String::Handle(cls.Name()); 1091 const String& name = String::Handle(cls.Name());
1092 const Script& script = Script::Handle(cls.script()); 1092 const Script& script = Script::Handle(cls.script());
1093 ReportError(script, cls.token_index(), 1093 ReportError(script, cls.token_pos(),
1094 "class '%s' has a cycle in its superclass relationship", 1094 "class '%s' has a cycle in its superclass relationship",
1095 name.ToCString()); 1095 name.ToCString());
1096 } 1096 }
1097 GrowableArray<intptr_t> visited_interfaces; 1097 GrowableArray<intptr_t> visited_interfaces;
1098 ResolveInterfaces(cls, &visited_interfaces); 1098 ResolveInterfaces(cls, &visited_interfaces);
1099 // Finalize super class. 1099 // Finalize super class.
1100 const Class& super_class = Class::Handle(cls.SuperClass()); 1100 const Class& super_class = Class::Handle(cls.SuperClass());
1101 if (!super_class.IsNull()) { 1101 if (!super_class.IsNull()) {
1102 FinalizeClass(super_class, generating_snapshot); 1102 FinalizeClass(super_class, generating_snapshot);
1103 } 1103 }
1104 // Finalize type parameters before finalizing the super type. 1104 // Finalize type parameters before finalizing the super type.
1105 FinalizeTypeParameters(cls); 1105 FinalizeTypeParameters(cls);
1106 // Finalize super type. 1106 // Finalize super type.
1107 Type& super_type = Type::Handle(cls.super_type()); 1107 Type& super_type = Type::Handle(cls.super_type());
1108 if (!super_type.IsNull()) { 1108 if (!super_type.IsNull()) {
1109 super_type ^= FinalizeType(cls, super_type, kFinalizeWellFormed); 1109 super_type ^= FinalizeType(cls, super_type, kFinalizeWellFormed);
1110 cls.set_super_type(super_type); 1110 cls.set_super_type(super_type);
1111 } 1111 }
1112 // Signature classes are finalized upon creation, except function type 1112 // Signature classes are finalized upon creation, except function type
1113 // aliases. 1113 // aliases.
1114 if (cls.IsSignatureClass()) { 1114 if (cls.IsSignatureClass()) {
1115 ASSERT(!cls.IsCanonicalSignatureClass()); 1115 ASSERT(!cls.IsCanonicalSignatureClass());
1116 // Check for illegal self references. 1116 // Check for illegal self references.
1117 GrowableArray<intptr_t> visited_aliases; 1117 GrowableArray<intptr_t> visited_aliases;
1118 if (!IsAliasCycleFree(cls, &visited_aliases)) { 1118 if (!IsAliasCycleFree(cls, &visited_aliases)) {
1119 const String& name = String::Handle(cls.Name()); 1119 const String& name = String::Handle(cls.Name());
1120 const Script& script = Script::Handle(cls.script()); 1120 const Script& script = Script::Handle(cls.script());
1121 ReportError(script, cls.token_index(), 1121 ReportError(script, cls.token_pos(),
1122 "typedef '%s' illegally refers to itself", 1122 "typedef '%s' illegally refers to itself",
1123 name.ToCString()); 1123 name.ToCString());
1124 } 1124 }
1125 cls.Finalize(); 1125 cls.Finalize();
1126 return; 1126 return;
1127 } 1127 }
1128 // Finalize factory class, if any. 1128 // Finalize factory class, if any.
1129 if (cls.is_interface()) { 1129 if (cls.is_interface()) {
1130 if (cls.HasFactoryClass()) { 1130 if (cls.HasFactoryClass()) {
1131 const Class& factory_class = Class::Handle(cls.FactoryClass()); 1131 const Class& factory_class = Class::Handle(cls.FactoryClass());
(...skipping 24 matching lines...) Expand all
1156 CheckForLegalConstClass(cls); 1156 CheckForLegalConstClass(cls);
1157 } 1157 }
1158 // Check to ensure we don't have classes with native fields in libraries 1158 // Check to ensure we don't have classes with native fields in libraries
1159 // which do not have a native resolver. 1159 // which do not have a native resolver.
1160 if (!generating_snapshot && cls.num_native_fields() != 0) { 1160 if (!generating_snapshot && cls.num_native_fields() != 0) {
1161 const Library& lib = Library::Handle(cls.library()); 1161 const Library& lib = Library::Handle(cls.library());
1162 if (lib.native_entry_resolver() == NULL) { 1162 if (lib.native_entry_resolver() == NULL) {
1163 const String& cls_name = String::Handle(cls.Name()); 1163 const String& cls_name = String::Handle(cls.Name());
1164 const String& lib_name = String::Handle(lib.url()); 1164 const String& lib_name = String::Handle(lib.url());
1165 const Script& script = Script::Handle(cls.script()); 1165 const Script& script = Script::Handle(cls.script());
1166 ReportError(script, cls.token_index(), 1166 ReportError(script, cls.token_pos(),
1167 "class '%s' is trying to extend a native fields class, " 1167 "class '%s' is trying to extend a native fields class, "
1168 "but library '%s' has no native resolvers", 1168 "but library '%s' has no native resolvers",
1169 cls_name.ToCString(), lib_name.ToCString()); 1169 cls_name.ToCString(), lib_name.ToCString());
1170 } 1170 }
1171 } 1171 }
1172 } 1172 }
1173 1173
1174 1174
1175 bool ClassFinalizer::IsSuperCycleFree(const Class& cls) { 1175 bool ClassFinalizer::IsSuperCycleFree(const Class& cls) {
1176 Class& test1 = Class::Handle(cls.raw()); 1176 Class& test1 = Class::Handle(cls.raw());
(...skipping 108 matching lines...) Expand 10 before | Expand all | Expand 10 after
1285 // we found a loop. 1285 // we found a loop.
1286 void ClassFinalizer::ResolveInterfaces(const Class& cls, 1286 void ClassFinalizer::ResolveInterfaces(const Class& cls,
1287 GrowableArray<intptr_t>* visited) { 1287 GrowableArray<intptr_t>* visited) {
1288 ASSERT(visited != NULL); 1288 ASSERT(visited != NULL);
1289 const intptr_t cls_index = cls.id(); 1289 const intptr_t cls_index = cls.id();
1290 for (int i = 0; i < visited->length(); i++) { 1290 for (int i = 0; i < visited->length(); i++) {
1291 if ((*visited)[i] == cls_index) { 1291 if ((*visited)[i] == cls_index) {
1292 // We have already visited interface class 'cls'. We found a cycle. 1292 // We have already visited interface class 'cls'. We found a cycle.
1293 const String& interface_name = String::Handle(cls.Name()); 1293 const String& interface_name = String::Handle(cls.Name());
1294 const Script& script = Script::Handle(cls.script()); 1294 const Script& script = Script::Handle(cls.script());
1295 ReportError(script, cls.token_index(), 1295 ReportError(script, cls.token_pos(),
1296 "cyclic reference found for interface '%s'", 1296 "cyclic reference found for interface '%s'",
1297 interface_name.ToCString()); 1297 interface_name.ToCString());
1298 } 1298 }
1299 } 1299 }
1300 1300
1301 // If the class/interface has no explicit interfaces, we are done. 1301 // If the class/interface has no explicit interfaces, we are done.
1302 Array& super_interfaces = Array::Handle(cls.interfaces()); 1302 Array& super_interfaces = Array::Handle(cls.interfaces());
1303 if (super_interfaces.Length() == 0) { 1303 if (super_interfaces.Length() == 0) {
1304 return; 1304 return;
1305 } 1305 }
1306 1306
1307 // If cls belongs to core lib or to core lib's implementation, restrictions 1307 // If cls belongs to core lib or to core lib's implementation, restrictions
1308 // about allowed interfaces are lifted. 1308 // about allowed interfaces are lifted.
1309 const bool cls_belongs_to_core_lib = 1309 const bool cls_belongs_to_core_lib =
1310 (cls.library() == Library::CoreLibrary()) || 1310 (cls.library() == Library::CoreLibrary()) ||
1311 (cls.library() == Library::CoreImplLibrary()); 1311 (cls.library() == Library::CoreImplLibrary());
1312 1312
1313 // Resolve and check the interfaces of cls. 1313 // Resolve and check the interfaces of cls.
1314 visited->Add(cls_index); 1314 visited->Add(cls_index);
1315 AbstractType& interface = AbstractType::Handle(); 1315 AbstractType& interface = AbstractType::Handle();
1316 Class& interface_class = Class::Handle(); 1316 Class& interface_class = Class::Handle();
1317 for (intptr_t i = 0; i < super_interfaces.Length(); i++) { 1317 for (intptr_t i = 0; i < super_interfaces.Length(); i++) {
1318 interface ^= super_interfaces.At(i); 1318 interface ^= super_interfaces.At(i);
1319 ResolveType(cls, interface, kFinalizeWellFormed); 1319 ResolveType(cls, interface, kFinalizeWellFormed);
1320 if (interface.IsTypeParameter()) { 1320 if (interface.IsTypeParameter()) {
1321 const Script& script = Script::Handle(cls.script()); 1321 const Script& script = Script::Handle(cls.script());
1322 ReportError(script, cls.token_index(), 1322 ReportError(script, cls.token_pos(),
1323 "type parameter '%s' cannot be used as interface", 1323 "type parameter '%s' cannot be used as interface",
1324 String::Handle(interface.Name()).ToCString()); 1324 String::Handle(interface.Name()).ToCString());
1325 } 1325 }
1326 interface_class = interface.type_class(); 1326 interface_class = interface.type_class();
1327 if (interface_class.IsSignatureClass()) { 1327 if (interface_class.IsSignatureClass()) {
1328 const Script& script = Script::Handle(cls.script()); 1328 const Script& script = Script::Handle(cls.script());
1329 ReportError(script, cls.token_index(), 1329 ReportError(script, cls.token_pos(),
1330 "'%s' is used where an interface or class name is expected", 1330 "'%s' is used where an interface or class name is expected",
1331 String::Handle(interface_class.Name()).ToCString()); 1331 String::Handle(interface_class.Name()).ToCString());
1332 } 1332 }
1333 // Verify that unless cls belongs to core lib, it cannot extend or implement 1333 // Verify that unless cls belongs to core lib, it cannot extend or implement
1334 // any of bool, num, int, double, String, Function, Dynamic. 1334 // any of bool, num, int, double, String, Function, Dynamic.
1335 // The exception is signature classes, which are compiler generated and 1335 // The exception is signature classes, which are compiler generated and
1336 // represent a function type, therefore implementing the Function interface. 1336 // represent a function type, therefore implementing the Function interface.
1337 if (!cls_belongs_to_core_lib) { 1337 if (!cls_belongs_to_core_lib) {
1338 if (interface.IsBoolInterface() || 1338 if (interface.IsBoolInterface() ||
1339 interface.IsNumberInterface() || 1339 interface.IsNumberInterface() ||
1340 interface.IsIntInterface() || 1340 interface.IsIntInterface() ||
1341 interface.IsDoubleInterface() || 1341 interface.IsDoubleInterface() ||
1342 interface.IsStringInterface() || 1342 interface.IsStringInterface() ||
1343 (interface.IsFunctionInterface() && !cls.IsSignatureClass()) || 1343 (interface.IsFunctionInterface() && !cls.IsSignatureClass()) ||
1344 interface.IsDynamicType()) { 1344 interface.IsDynamicType()) {
1345 const Script& script = Script::Handle(cls.script()); 1345 const Script& script = Script::Handle(cls.script());
1346 ReportError(script, cls.token_index(), 1346 ReportError(script, cls.token_pos(),
1347 "'%s' is not allowed to extend or implement '%s'", 1347 "'%s' is not allowed to extend or implement '%s'",
1348 String::Handle(cls.Name()).ToCString(), 1348 String::Handle(cls.Name()).ToCString(),
1349 String::Handle(interface_class.Name()).ToCString()); 1349 String::Handle(interface_class.Name()).ToCString());
1350 } 1350 }
1351 } 1351 }
1352 // Now resolve the super interfaces. 1352 // Now resolve the super interfaces.
1353 ResolveInterfaces(interface_class, visited); 1353 ResolveInterfaces(interface_class, visited);
1354 } 1354 }
1355 visited->RemoveLast(); 1355 visited->RemoveLast();
1356 } 1356 }
1357 1357
1358 1358
1359 // A class is marked as constant if it has one constant constructor. 1359 // A class is marked as constant if it has one constant constructor.
1360 // A constant class: 1360 // A constant class:
1361 // - may extend only const classes. 1361 // - may extend only const classes.
1362 // - has only const instance fields. 1362 // - has only const instance fields.
1363 // Note: we must check for cycles before checking for const properties. 1363 // Note: we must check for cycles before checking for const properties.
1364 void ClassFinalizer::CheckForLegalConstClass(const Class& cls) { 1364 void ClassFinalizer::CheckForLegalConstClass(const Class& cls) {
1365 ASSERT(cls.is_const()); 1365 ASSERT(cls.is_const());
1366 const Class& super = Class::Handle(cls.SuperClass()); 1366 const Class& super = Class::Handle(cls.SuperClass());
1367 if (!super.IsNull() && !super.is_const()) { 1367 if (!super.IsNull() && !super.is_const()) {
1368 String& name = String::Handle(super.Name()); 1368 String& name = String::Handle(super.Name());
1369 const Script& script = Script::Handle(cls.script()); 1369 const Script& script = Script::Handle(cls.script());
1370 ReportError(script, cls.token_index(), 1370 ReportError(script, cls.token_pos(),
1371 "superclass '%s' must be const", name.ToCString()); 1371 "superclass '%s' must be const", name.ToCString());
1372 } 1372 }
1373 const Array& fields_array = Array::Handle(cls.fields()); 1373 const Array& fields_array = Array::Handle(cls.fields());
1374 intptr_t len = fields_array.Length(); 1374 intptr_t len = fields_array.Length();
1375 Field& field = Field::Handle(); 1375 Field& field = Field::Handle();
1376 for (intptr_t i = 0; i < len; i++) { 1376 for (intptr_t i = 0; i < len; i++) {
1377 field ^= fields_array.At(i); 1377 field ^= fields_array.At(i);
1378 if (!field.is_static() && !field.is_final()) { 1378 if (!field.is_static() && !field.is_final()) {
1379 const String& class_name = String::Handle(cls.Name()); 1379 const String& class_name = String::Handle(cls.Name());
1380 const String& field_name = String::Handle(field.name()); 1380 const String& field_name = String::Handle(field.name());
1381 const Script& script = Script::Handle(cls.script()); 1381 const Script& script = Script::Handle(cls.script());
1382 ReportError(script, field.token_index(), 1382 ReportError(script, field.token_pos(),
1383 "const class '%s' has non-final field '%s'", 1383 "const class '%s' has non-final field '%s'",
1384 class_name.ToCString(), field_name.ToCString()); 1384 class_name.ToCString(), field_name.ToCString());
1385 } 1385 }
1386 } 1386 }
1387 } 1387 }
1388 1388
1389 1389
1390 void ClassFinalizer::PrintClassInformation(const Class& cls) { 1390 void ClassFinalizer::PrintClassInformation(const Class& cls) {
1391 HANDLESCOPE(Isolate::Current()); 1391 HANDLESCOPE(Isolate::Current());
1392 const String& class_name = String::Handle(cls.Name()); 1392 const String& class_name = String::Handle(cls.Name());
(...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after
1443 const char* format, ...) { 1443 const char* format, ...) {
1444 va_list args; 1444 va_list args;
1445 va_start(args, format); 1445 va_start(args, format);
1446 LanguageError& error = LanguageError::Handle(); 1446 LanguageError& error = LanguageError::Handle();
1447 if (FLAG_enable_type_checks || 1447 if (FLAG_enable_type_checks ||
1448 !type.HasResolvedTypeClass() || 1448 !type.HasResolvedTypeClass() ||
1449 (finalization == kFinalizeWellFormed)) { 1449 (finalization == kFinalizeWellFormed)) {
1450 const Script& script = Script::Handle(cls.script()); 1450 const Script& script = Script::Handle(cls.script());
1451 if (prev_error.IsNull()) { 1451 if (prev_error.IsNull()) {
1452 error ^= Parser::FormatError( 1452 error ^= Parser::FormatError(
1453 script, type.token_index(), "Error", format, args); 1453 script, type.token_pos(), "Error", format, args);
1454 } else { 1454 } else {
1455 error ^= Parser::FormatErrorWithAppend( 1455 error ^= Parser::FormatErrorWithAppend(
1456 prev_error, script, type.token_index(), "Error", format, args); 1456 prev_error, script, type.token_pos(), "Error", format, args);
1457 } 1457 }
1458 if (finalization == kFinalizeWellFormed) { 1458 if (finalization == kFinalizeWellFormed) {
1459 ReportError(error); 1459 ReportError(error);
1460 } 1460 }
1461 } 1461 }
1462 if (FLAG_enable_type_checks || !type.HasResolvedTypeClass()) { 1462 if (FLAG_enable_type_checks || !type.HasResolvedTypeClass()) {
1463 // In check mode, always mark the type as malformed. 1463 // In check mode, always mark the type as malformed.
1464 // In production mode, mark the type as malformed only if its type class is 1464 // In production mode, mark the type as malformed only if its type class is
1465 // not resolved. 1465 // not resolved.
1466 type.set_malformed_error(error); 1466 type.set_malformed_error(error);
(...skipping 14 matching lines...) Expand all
1481 } 1481 }
1482 1482
1483 1483
1484 void ClassFinalizer::ReportError(const Error& error) { 1484 void ClassFinalizer::ReportError(const Error& error) {
1485 Isolate::Current()->long_jump_base()->Jump(1, error); 1485 Isolate::Current()->long_jump_base()->Jump(1, error);
1486 UNREACHABLE(); 1486 UNREACHABLE();
1487 } 1487 }
1488 1488
1489 1489
1490 void ClassFinalizer::ReportError(const Script& script, 1490 void ClassFinalizer::ReportError(const Script& script,
1491 intptr_t token_index, 1491 intptr_t token_pos,
1492 const char* format, ...) { 1492 const char* format, ...) {
1493 va_list args; 1493 va_list args;
1494 va_start(args, format); 1494 va_start(args, format);
1495 const Error& error = Error::Handle( 1495 const Error& error = Error::Handle(
1496 Parser::FormatError(script, token_index, "Error", format, args)); 1496 Parser::FormatError(script, token_pos, "Error", format, args));
1497 ReportError(error); 1497 ReportError(error);
1498 } 1498 }
1499 1499
1500 1500
1501 void ClassFinalizer::ReportError(const char* format, ...) { 1501 void ClassFinalizer::ReportError(const char* format, ...) {
1502 va_list args; 1502 va_list args;
1503 va_start(args, format); 1503 va_start(args, format);
1504 const Error& error = Error::Handle( 1504 const Error& error = Error::Handle(
1505 Parser::FormatError(Script::Handle(), -1, "Error", format, args)); 1505 Parser::FormatError(Script::Handle(), -1, "Error", format, args));
1506 va_end(args); 1506 va_end(args);
1507 ReportError(error); 1507 ReportError(error);
1508 } 1508 }
1509 1509
1510 } // namespace dart 1510 } // namespace dart
OLDNEW
« no previous file with comments | « vm/ast_printer.cc ('k') | vm/code_generator_ia32.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698