| OLD | NEW |
| 1 // Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file |
| 2 // for details. All rights reserved. Use of this source code is governed by a | 2 // for details. All rights reserved. Use of this source code is governed by a |
| 3 // BSD-style license that can be found in the LICENSE file. | 3 // BSD-style license that can be found in the LICENSE file. |
| 4 | 4 |
| 5 #include "vm/class_finalizer.h" | 5 #include "vm/class_finalizer.h" |
| 6 | 6 |
| 7 #include "vm/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 237 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 248 OS::Exit(255); | 248 OS::Exit(255); |
| 249 } | 249 } |
| 250 if (FLAG_trace_class_finalization) { | 250 if (FLAG_trace_class_finalization) { |
| 251 OS::Print("VerifyBootstrapClasses END.\n"); | 251 OS::Print("VerifyBootstrapClasses END.\n"); |
| 252 } | 252 } |
| 253 Isolate::Current()->heap()->Verify(); | 253 Isolate::Current()->heap()->Verify(); |
| 254 } | 254 } |
| 255 | 255 |
| 256 | 256 |
| 257 // Resolve unresolved_class in the library of cls, or return null. | 257 // Resolve unresolved_class in the library of cls, or return null. |
| 258 RawClass* ClassFinalizer::ResolveClass( | 258 RawClass* ClassFinalizer::ResolveClass(const Class& cls, |
| 259 const Class& cls, const UnresolvedClass& unresolved_class) { | 259 const UnresolvedClass& unresolved_class, |
| 260 Error* ambiguity_error) { |
| 260 const String& class_name = String::Handle(unresolved_class.ident()); | 261 const String& class_name = String::Handle(unresolved_class.ident()); |
| 261 Library& lib = Library::Handle(); | 262 Library& lib = Library::Handle(); |
| 262 Class& resolved_class = Class::Handle(); | 263 Class& resolved_class = Class::Handle(); |
| 263 if (unresolved_class.library_prefix() == LibraryPrefix::null()) { | 264 if (unresolved_class.library_prefix() == LibraryPrefix::null()) { |
| 264 lib = cls.library(); | 265 lib = cls.library(); |
| 265 ASSERT(!lib.IsNull()); | 266 ASSERT(!lib.IsNull()); |
| 266 resolved_class = lib.LookupClass(class_name); | 267 // TODO(regis): Call lib.LookupClass(class_name, ambiguity_error) instead |
| 268 // once it takes the ambiguity_error parameter. |
| 269 |
| 270 // First check if name is found in the local scope of the library. |
| 271 Object& obj = Object::Handle(lib.LookupLocalObject(class_name)); |
| 272 if (!obj.IsNull() && obj.IsClass()) { |
| 273 return Class::Cast(obj).raw(); |
| 274 } |
| 275 // Now check if class_name is found in any imported libs. |
| 276 String& first_lib_url = String::Handle(); |
| 277 Namespace& import = Namespace::Handle(); |
| 278 Library& import_lib = Library::Handle(); |
| 279 for (intptr_t i = 0; i < lib.num_imports(); i++) { |
| 280 import ^= lib.ImportAt(i); |
| 281 obj = import.Lookup(class_name); |
| 282 if (!obj.IsNull()) { |
| 283 import_lib = import.library(); |
| 284 if (!first_lib_url.IsNull()) { |
| 285 // Found duplicate definition. |
| 286 const Script& script = Script::Handle(cls.script()); |
| 287 if (first_lib_url.raw() == lib.url()) { |
| 288 *ambiguity_error = Parser::FormatErrorMsg( |
| 289 script, unresolved_class.token_pos(), "Error", |
| 290 "ambiguous reference to '%s', " |
| 291 "as library '%s' is imported multiple times", |
| 292 class_name.ToCString(), |
| 293 first_lib_url.ToCString()); |
| 294 } else { |
| 295 *ambiguity_error = Parser::FormatErrorMsg( |
| 296 script, unresolved_class.token_pos(), "Error", |
| 297 "ambiguous reference: " |
| 298 "'%s' is defined in library '%s' and also in '%s'", |
| 299 class_name.ToCString(), |
| 300 first_lib_url.ToCString(), |
| 301 String::Handle(lib.url()).ToCString()); |
| 302 } |
| 303 return Class::null(); |
| 304 } |
| 305 first_lib_url = lib.url(); |
| 306 if (obj.IsClass()) { |
| 307 resolved_class = Class::Cast(obj).raw(); |
| 308 } |
| 309 } |
| 310 } |
| 267 } else { | 311 } else { |
| 268 LibraryPrefix& lib_prefix = LibraryPrefix::Handle(); | 312 LibraryPrefix& lib_prefix = LibraryPrefix::Handle(); |
| 269 lib_prefix = unresolved_class.library_prefix(); | 313 lib_prefix = unresolved_class.library_prefix(); |
| 270 ASSERT(!lib_prefix.IsNull()); | 314 ASSERT(!lib_prefix.IsNull()); |
| 271 resolved_class = lib_prefix.LookupLocalClass(class_name); | 315 resolved_class = lib_prefix.LookupLocalClass(class_name); |
| 272 } | 316 } |
| 273 return resolved_class.raw(); | 317 return resolved_class.raw(); |
| 274 } | 318 } |
| 275 | 319 |
| 276 | 320 |
| (...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 310 OS::Print("Resolving redirecting factory: %s\n", | 354 OS::Print("Resolving redirecting factory: %s\n", |
| 311 String::Handle(factory.name()).ToCString()); | 355 String::Handle(factory.name()).ToCString()); |
| 312 } | 356 } |
| 313 ResolveType(cls, type, kCanonicalize); | 357 ResolveType(cls, type, kCanonicalize); |
| 314 type ^= FinalizeType(cls, type, kCanonicalize); | 358 type ^= FinalizeType(cls, type, kCanonicalize); |
| 315 factory.SetRedirectionType(type); | 359 factory.SetRedirectionType(type); |
| 316 if (type.IsMalformed()) { | 360 if (type.IsMalformed()) { |
| 317 ASSERT(factory.RedirectionTarget() == Function::null()); | 361 ASSERT(factory.RedirectionTarget() == Function::null()); |
| 318 return; | 362 return; |
| 319 } | 363 } |
| 364 ASSERT(!type.IsTypeParameter()); // Resolved in parser. |
| 365 if (type.IsDynamicType()) { |
| 366 // Replace the type with a malformed type and compile a throw when called. |
| 367 type = NewFinalizedMalformedType( |
| 368 Error::Handle(), // No previous error. |
| 369 cls, |
| 370 factory.token_pos(), |
| 371 kResolveTypeParameters, // No compile-time error. |
| 372 "factory may not redirect to 'dynamic'"); |
| 373 factory.SetRedirectionType(type); |
| 374 ASSERT(factory.RedirectionTarget() == Function::null()); |
| 375 return; |
| 376 } |
| 320 const Class& target_class = Class::Handle(type.type_class()); | 377 const Class& target_class = Class::Handle(type.type_class()); |
| 321 String& target_class_name = String::Handle(target_class.Name()); | 378 String& target_class_name = String::Handle(target_class.Name()); |
| 322 String& target_name = String::Handle( | 379 String& target_name = String::Handle( |
| 323 String::Concat(target_class_name, Symbols::Dot())); | 380 String::Concat(target_class_name, Symbols::Dot())); |
| 324 const String& identifier = String::Handle(factory.RedirectionIdentifier()); | 381 const String& identifier = String::Handle(factory.RedirectionIdentifier()); |
| 325 if (!identifier.IsNull()) { | 382 if (!identifier.IsNull()) { |
| 326 target_name = String::Concat(target_name, identifier); | 383 target_name = String::Concat(target_name, identifier); |
| 327 } | 384 } |
| 328 | 385 |
| 329 // Verify that the target constructor of the redirection exists. | 386 // Verify that the target constructor of the redirection exists. |
| 330 target = target_class.LookupConstructor(target_name); | 387 target = target_class.LookupConstructor(target_name); |
| 331 if (target.IsNull()) { | 388 if (target.IsNull()) { |
| 332 target = target_class.LookupFactory(target_name); | 389 target = target_class.LookupFactory(target_name); |
| 333 } | 390 } |
| 334 if (target.IsNull()) { | 391 if (target.IsNull()) { |
| 335 const String& user_visible_target_name = | 392 const String& user_visible_target_name = |
| 336 identifier.IsNull() ? target_class_name : target_name; | 393 identifier.IsNull() ? target_class_name : target_name; |
| 337 // Replace the type with a malformed type and compile a throw when called. | 394 // Replace the type with a malformed type and compile a throw when called. |
| 338 type = NewFinalizedMalformedType( | 395 type = NewFinalizedMalformedType( |
| 339 Error::Handle(), // No previous error. | 396 Error::Handle(), // No previous error. |
| 340 cls, | 397 cls, |
| 341 factory.token_pos(), | 398 factory.token_pos(), |
| 342 kTryResolve, // No compile-time error. | 399 kResolveTypeParameters, // No compile-time error. |
| 343 "class '%s' has no constructor or factory named '%s'", | 400 "class '%s' has no constructor or factory named '%s'", |
| 344 target_class_name.ToCString(), | 401 target_class_name.ToCString(), |
| 345 user_visible_target_name.ToCString()); | 402 user_visible_target_name.ToCString()); |
| 346 factory.SetRedirectionType(type); | 403 factory.SetRedirectionType(type); |
| 347 ASSERT(factory.RedirectionTarget() == Function::null()); | 404 ASSERT(factory.RedirectionTarget() == Function::null()); |
| 348 return; | 405 return; |
| 349 } | 406 } |
| 350 | 407 |
| 351 // Verify that the target is compatible with the redirecting factory. | 408 // Verify that the target is compatible with the redirecting factory. |
| 352 if (!target.HasCompatibleParametersWith(factory)) { | 409 if (!target.HasCompatibleParametersWith(factory)) { |
| 353 type = NewFinalizedMalformedType( | 410 type = NewFinalizedMalformedType( |
| 354 Error::Handle(), // No previous error. | 411 Error::Handle(), // No previous error. |
| 355 cls, | 412 cls, |
| 356 factory.token_pos(), | 413 factory.token_pos(), |
| 357 kTryResolve, // No compile-time error. | 414 kResolveTypeParameters, // No compile-time error. |
| 358 "constructor '%s' has incompatible parameters with " | 415 "constructor '%s' has incompatible parameters with " |
| 359 "redirecting factory '%s'", | 416 "redirecting factory '%s'", |
| 360 String::Handle(target.name()).ToCString(), | 417 String::Handle(target.name()).ToCString(), |
| 361 String::Handle(factory.name()).ToCString()); | 418 String::Handle(factory.name()).ToCString()); |
| 362 factory.SetRedirectionType(type); | 419 factory.SetRedirectionType(type); |
| 363 ASSERT(factory.RedirectionTarget() == Function::null()); | 420 ASSERT(factory.RedirectionTarget() == Function::null()); |
| 364 return; | 421 return; |
| 365 } | 422 } |
| 366 | 423 |
| 367 // Verify that the target is const if the the redirecting factory is const. | 424 // Verify that the target is const if the the redirecting factory is const. |
| (...skipping 62 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 430 if (!type.HasResolvedTypeClass()) { | 487 if (!type.HasResolvedTypeClass()) { |
| 431 // Type parameters are always resolved in the parser in the correct | 488 // Type parameters are always resolved in the parser in the correct |
| 432 // non-static scope or factory scope. That resolution scope is unknown here. | 489 // non-static scope or factory scope. That resolution scope is unknown here. |
| 433 // Being able to resolve a type parameter from class cls here would indicate | 490 // Being able to resolve a type parameter from class cls here would indicate |
| 434 // that the type parameter appeared in a static scope. Leaving the type as | 491 // that the type parameter appeared in a static scope. Leaving the type as |
| 435 // unresolved is the correct thing to do. | 492 // unresolved is the correct thing to do. |
| 436 | 493 |
| 437 // Lookup the type class. | 494 // Lookup the type class. |
| 438 const UnresolvedClass& unresolved_class = | 495 const UnresolvedClass& unresolved_class = |
| 439 UnresolvedClass::Handle(type.unresolved_class()); | 496 UnresolvedClass::Handle(type.unresolved_class()); |
| 497 Error& ambiguous_error = Error::Handle(); |
| 440 const Class& type_class = | 498 const Class& type_class = |
| 441 Class::Handle(ResolveClass(cls, unresolved_class)); | 499 Class::Handle(ResolveClass(cls, unresolved_class, &ambiguous_error)); |
| 442 | 500 |
| 443 // Replace unresolved class with resolved type class. | 501 // Replace unresolved class with resolved type class. |
| 444 const Type& parameterized_type = Type::Cast(type); | 502 const Type& parameterized_type = Type::Cast(type); |
| 445 if (!type_class.IsNull()) { | 503 if (!type_class.IsNull()) { |
| 446 parameterized_type.set_type_class(type_class); | 504 parameterized_type.set_type_class(type_class); |
| 447 } else { | 505 } else { |
| 448 // The type class could not be resolved. The type is malformed. | 506 // The type class could not be resolved. The type is malformed. |
| 449 FinalizeMalformedType(Error::Handle(), // No previous error. | 507 FinalizeMalformedType(ambiguous_error, // May be null. |
| 450 cls, parameterized_type, finalization, | 508 cls, parameterized_type, finalization, |
| 451 "cannot resolve class name '%s' from '%s'", | 509 "cannot resolve class name '%s' from '%s'", |
| 452 String::Handle(unresolved_class.Name()).ToCString(), | 510 String::Handle(unresolved_class.Name()).ToCString(), |
| 453 String::Handle(cls.Name()).ToCString()); | 511 String::Handle(cls.Name()).ToCString()); |
| 454 return; | 512 return; |
| 455 } | 513 } |
| 456 } | 514 } |
| 457 | 515 |
| 458 // Resolve type arguments, if any. | 516 // Resolve type arguments, if any. |
| 459 const AbstractTypeArguments& arguments = | 517 const AbstractTypeArguments& arguments = |
| (...skipping 403 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 863 // function type to refer to itself via its parameter types and result type. | 921 // function type to refer to itself via its parameter types and result type. |
| 864 if (type_class.IsSignatureClass()) { | 922 if (type_class.IsSignatureClass()) { |
| 865 // The class may be created while parsing a function body, after all | 923 // The class may be created while parsing a function body, after all |
| 866 // pending classes have already been finalized. | 924 // pending classes have already been finalized. |
| 867 FinalizeTypesInClass(type_class); | 925 FinalizeTypesInClass(type_class); |
| 868 } | 926 } |
| 869 | 927 |
| 870 // If a bound error occurred, return a BoundedType with a malformed bound. | 928 // If a bound error occurred, return a BoundedType with a malformed bound. |
| 871 // The malformed bound will be ignored in production mode. | 929 // The malformed bound will be ignored in production mode. |
| 872 if (!bound_error.IsNull()) { | 930 if (!bound_error.IsNull()) { |
| 873 FinalizationKind bound_finalization = kTryResolve; // No compile error. | 931 // No compile-time error during finalization. |
| 932 FinalizationKind bound_finalization = kResolveTypeParameters; |
| 874 if (FLAG_enable_type_checks || FLAG_error_on_malformed_type) { | 933 if (FLAG_enable_type_checks || FLAG_error_on_malformed_type) { |
| 875 bound_finalization = finalization; | 934 bound_finalization = finalization; |
| 876 } | 935 } |
| 877 const String& parameterized_type_name = String::Handle( | 936 const String& parameterized_type_name = String::Handle( |
| 878 parameterized_type.UserVisibleName()); | 937 parameterized_type.UserVisibleName()); |
| 879 const Type& malformed_bound = Type::Handle( | 938 const Type& malformed_bound = Type::Handle( |
| 880 NewFinalizedMalformedType(bound_error, | 939 NewFinalizedMalformedType(bound_error, |
| 881 cls, | 940 cls, |
| 882 parameterized_type.token_pos(), | 941 parameterized_type.token_pos(), |
| 883 bound_finalization, | 942 bound_finalization, |
| (...skipping 171 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1055 const Script& script = Script::Handle(cls.script()); | 1114 const Script& script = Script::Handle(cls.script()); |
| 1056 ReportError(script, field.token_pos(), | 1115 ReportError(script, field.token_pos(), |
| 1057 "field '%s' of class '%s' conflicts with method '%s' " | 1116 "field '%s' of class '%s' conflicts with method '%s' " |
| 1058 "of super class '%s'", | 1117 "of super class '%s'", |
| 1059 name.ToCString(), | 1118 name.ToCString(), |
| 1060 class_name.ToCString(), | 1119 class_name.ToCString(), |
| 1061 name.ToCString(), | 1120 name.ToCString(), |
| 1062 super_class_name.ToCString()); | 1121 super_class_name.ToCString()); |
| 1063 } | 1122 } |
| 1064 } | 1123 } |
| 1124 if ((FLAG_enable_type_checks || FLAG_error_on_malformed_type) && |
| 1125 field.is_static() && field.is_const() && |
| 1126 (field.value() != Object::null()) && |
| 1127 (field.value() != Object::sentinel().raw())) { |
| 1128 // The parser does not preset the value if the type is a type parameter or |
| 1129 // is parameterized unless the value is null. |
| 1130 Error& malformed_error = Error::Handle(); |
| 1131 if (type.IsMalformed()) { |
| 1132 malformed_error = type.malformed_error(); |
| 1133 } else { |
| 1134 ASSERT(type.IsInstantiated()); |
| 1135 } |
| 1136 const Instance& const_value = Instance::Handle(field.value()); |
| 1137 if (!malformed_error.IsNull() || |
| 1138 (!type.IsDynamicType() && |
| 1139 !const_value.IsInstanceOf(type, |
| 1140 AbstractTypeArguments::Handle(), |
| 1141 &malformed_error))) { |
| 1142 // If the failure is due to a malformed type error, display it instead. |
| 1143 if (!malformed_error.IsNull()) { |
| 1144 ReportError(malformed_error); |
| 1145 } else { |
| 1146 const AbstractType& const_value_type = AbstractType::Handle( |
| 1147 const_value.GetType()); |
| 1148 const String& const_value_type_name = String::Handle( |
| 1149 const_value_type.UserVisibleName()); |
| 1150 const String& type_name = String::Handle(type.UserVisibleName()); |
| 1151 const Script& script = Script::Handle(cls.script()); |
| 1152 ReportError(script, field.token_pos(), |
| 1153 "error initializing const field '%s': type '%s' is not a " |
| 1154 "subtype of type '%s'", |
| 1155 name.ToCString(), |
| 1156 const_value_type_name.ToCString(), |
| 1157 type_name.ToCString()); |
| 1158 } |
| 1159 } |
| 1160 } |
| 1065 } | 1161 } |
| 1066 // Collect interfaces, super interfaces, and super classes of this class. | 1162 // Collect interfaces, super interfaces, and super classes of this class. |
| 1067 const GrowableObjectArray& interfaces = | 1163 const GrowableObjectArray& interfaces = |
| 1068 GrowableObjectArray::Handle(GrowableObjectArray::New()); | 1164 GrowableObjectArray::Handle(GrowableObjectArray::New()); |
| 1069 CollectInterfaces(cls, interfaces); | 1165 CollectInterfaces(cls, interfaces); |
| 1070 // Include superclasses in list of interfaces and super interfaces. | 1166 // Include superclasses in list of interfaces and super interfaces. |
| 1071 super_class = cls.SuperClass(); | 1167 super_class = cls.SuperClass(); |
| 1072 while (!super_class.IsNull()) { | 1168 while (!super_class.IsNull()) { |
| 1073 interfaces.Add(super_class); | 1169 interfaces.Add(super_class); |
| 1074 CollectInterfaces(super_class, interfaces); | 1170 CollectInterfaces(super_class, interfaces); |
| (...skipping 627 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1702 // are lifted. | 1798 // are lifted. |
| 1703 const bool cls_belongs_to_core_lib = cls.library() == Library::CoreLibrary(); | 1799 const bool cls_belongs_to_core_lib = cls.library() == Library::CoreLibrary(); |
| 1704 | 1800 |
| 1705 // Resolve and check the super type and interfaces of cls. | 1801 // Resolve and check the super type and interfaces of cls. |
| 1706 visited->Add(cls_index); | 1802 visited->Add(cls_index); |
| 1707 AbstractType& interface = AbstractType::Handle(); | 1803 AbstractType& interface = AbstractType::Handle(); |
| 1708 Class& interface_class = Class::Handle(); | 1804 Class& interface_class = Class::Handle(); |
| 1709 | 1805 |
| 1710 // Resolve super type. Failures lead to a longjmp. | 1806 // Resolve super type. Failures lead to a longjmp. |
| 1711 ResolveType(cls, super_type, kCanonicalizeWellFormed); | 1807 ResolveType(cls, super_type, kCanonicalizeWellFormed); |
| 1808 if (super_type.IsDynamicType()) { |
| 1809 const Script& script = Script::Handle(cls.script()); |
| 1810 ReportError(script, cls.token_pos(), |
| 1811 "class '%s' may not extend 'dynamic'", |
| 1812 String::Handle(cls.Name()).ToCString()); |
| 1813 } |
| 1712 | 1814 |
| 1713 interface_class = super_type.type_class(); | 1815 interface_class = super_type.type_class(); |
| 1714 // If cls belongs to core lib or to core lib's implementation, restrictions | 1816 // If cls belongs to core lib or to core lib's implementation, restrictions |
| 1715 // about allowed interfaces are lifted. | 1817 // about allowed interfaces are lifted. |
| 1716 if (!cls_belongs_to_core_lib) { | 1818 if (!cls_belongs_to_core_lib) { |
| 1717 // Prevent extending core implementation classes. | 1819 // Prevent extending core implementation classes. |
| 1718 bool is_error = false; | 1820 bool is_error = false; |
| 1719 switch (interface_class.id()) { | 1821 switch (interface_class.id()) { |
| 1720 case kNumberCid: | 1822 case kNumberCid: |
| 1721 case kIntegerCid: // Class Integer, not int. | 1823 case kIntegerCid: // Class Integer, not int. |
| (...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1760 String::Handle(interface_class.Name()).ToCString()); | 1862 String::Handle(interface_class.Name()).ToCString()); |
| 1761 } | 1863 } |
| 1762 } | 1864 } |
| 1763 // Now resolve the super interfaces of the super type. | 1865 // Now resolve the super interfaces of the super type. |
| 1764 ResolveSuperTypeAndInterfaces(interface_class, visited); | 1866 ResolveSuperTypeAndInterfaces(interface_class, visited); |
| 1765 | 1867 |
| 1766 // Resolve interfaces. Failures lead to a longjmp. | 1868 // Resolve interfaces. Failures lead to a longjmp. |
| 1767 for (intptr_t i = 0; i < super_interfaces.Length(); i++) { | 1869 for (intptr_t i = 0; i < super_interfaces.Length(); i++) { |
| 1768 interface ^= super_interfaces.At(i); | 1870 interface ^= super_interfaces.At(i); |
| 1769 ResolveType(cls, interface, kCanonicalizeWellFormed); | 1871 ResolveType(cls, interface, kCanonicalizeWellFormed); |
| 1770 if (interface.IsTypeParameter()) { | 1872 ASSERT(!interface.IsTypeParameter()); // Should be detected by parser. |
| 1873 if (interface.IsDynamicType()) { |
| 1771 const Script& script = Script::Handle(cls.script()); | 1874 const Script& script = Script::Handle(cls.script()); |
| 1772 ReportError(script, cls.token_pos(), | 1875 ReportError(script, cls.token_pos(), |
| 1773 "type parameter '%s' cannot be used as interface", | 1876 "'dynamic' may not be used as interface"); |
| 1774 String::Handle(interface.Name()).ToCString()); | |
| 1775 } | 1877 } |
| 1776 interface_class = interface.type_class(); | 1878 interface_class = interface.type_class(); |
| 1777 if (interface_class.IsSignatureClass()) { | 1879 if (interface_class.IsSignatureClass()) { |
| 1778 const Script& script = Script::Handle(cls.script()); | 1880 const Script& script = Script::Handle(cls.script()); |
| 1779 ReportError(script, cls.token_pos(), | 1881 ReportError(script, cls.token_pos(), |
| 1780 "'%s' is used where an interface or class name is expected", | 1882 "'%s' is used where an interface or class name is expected", |
| 1781 String::Handle(interface_class.Name()).ToCString()); | 1883 String::Handle(interface_class.Name()).ToCString()); |
| 1782 } | 1884 } |
| 1783 // Verify that unless cls belongs to core lib, it cannot extend or implement | 1885 // Verify that unless cls belongs to core lib, it cannot extend or implement |
| 1784 // any of bool, num, int, double, String, Function, dynamic. | 1886 // any of bool, num, int, double, String, Function, dynamic. |
| (...skipping 250 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2035 expected_name ^= String::New("_offset"); | 2137 expected_name ^= String::New("_offset"); |
| 2036 ASSERT(String::EqualsIgnoringPrivateKey(name, expected_name)); | 2138 ASSERT(String::EqualsIgnoringPrivateKey(name, expected_name)); |
| 2037 field ^= fields_array.At(2); | 2139 field ^= fields_array.At(2); |
| 2038 ASSERT(field.Offset() == TypedDataView::length_offset()); | 2140 ASSERT(field.Offset() == TypedDataView::length_offset()); |
| 2039 name ^= field.name(); | 2141 name ^= field.name(); |
| 2040 ASSERT(name.Equals("length")); | 2142 ASSERT(name.Equals("length")); |
| 2041 #endif | 2143 #endif |
| 2042 } | 2144 } |
| 2043 | 2145 |
| 2044 } // namespace dart | 2146 } // namespace dart |
| OLD | NEW |