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

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

Issue 10979053: Change many instance creation errors from compile-time errors to dynamic errors (Closed) Base URL: http://dart.googlecode.com/svn/branches/bleeding_edge/dart/
Patch Set: Created 8 years, 2 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 | « runtime/vm/class_finalizer.h ('k') | runtime/vm/parser.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 444 matching lines...) Expand 10 before | Expand all | Expand 10 after
455 455
456 // Verify that the target constructor of the redirection exists. 456 // Verify that the target constructor of the redirection exists.
457 target = target_class.LookupConstructor(target_name); 457 target = target_class.LookupConstructor(target_name);
458 if (target.IsNull()) { 458 if (target.IsNull()) {
459 target = target_class.LookupFactory(target_name); 459 target = target_class.LookupFactory(target_name);
460 } 460 }
461 if (target.IsNull()) { 461 if (target.IsNull()) {
462 const String& user_visible_target_name = 462 const String& user_visible_target_name =
463 identifier.IsNull() ? target_class_name : target_name; 463 identifier.IsNull() ? target_class_name : target_name;
464 // Replace the type with a malformed type and compile a throw when called. 464 // Replace the type with a malformed type and compile a throw when called.
465 FinalizeMalformedType(Error::Handle(), // No previous error. 465 type = NewFinalizedMalformedType(
466 cls, type, kCanonicalize, 466 cls,
467 "class '%s' has no constructor or factory named '%s'", 467 factory.token_pos(),
468 target_class_name.ToCString(), 468 "class '%s' has no constructor or factory named '%s'",
469 user_visible_target_name.ToCString()); 469 target_class_name.ToCString(),
470 user_visible_target_name.ToCString());
470 factory.SetRedirectionType(type); 471 factory.SetRedirectionType(type);
471 ASSERT(factory.RedirectionTarget() == Function::null()); 472 ASSERT(factory.RedirectionTarget() == Function::null());
472 return; 473 return;
473 } 474 }
474 475
475 // Verify that the target is compatible with the redirecting factory. 476 // Verify that the target is compatible with the redirecting factory.
476 if (!target.HasCompatibleParametersWith(factory)) { 477 if (!target.HasCompatibleParametersWith(factory)) {
477 FinalizeMalformedType(Error::Handle(), // No previous error. 478 type = NewFinalizedMalformedType(
478 cls, type, kCanonicalize, 479 cls,
479 "constructor '%s' has incompatible parameters with " 480 factory.token_pos(),
480 "redirecting factory '%s'", 481 "constructor '%s' has incompatible parameters with "
481 String::Handle(target.name()).ToCString(), 482 "redirecting factory '%s'",
482 String::Handle(factory.name()).ToCString()); 483 String::Handle(target.name()).ToCString(),
484 String::Handle(factory.name()).ToCString());
483 factory.SetRedirectionType(type); 485 factory.SetRedirectionType(type);
484 ASSERT(factory.RedirectionTarget() == Function::null()); 486 ASSERT(factory.RedirectionTarget() == Function::null());
485 return; 487 return;
486 } 488 }
487 489
488 // Verify that the target is const if the the redirecting factory is const. 490 // Verify that the target is const if the the redirecting factory is const.
489 if (factory.is_const() && !target.is_const()) { 491 if (factory.is_const() && !target.is_const()) {
490 const Script& script = Script::Handle(cls.script()); 492 const Script& script = Script::Handle(cls.script());
491 ReportError(script, factory.token_pos(), 493 ReportError(script, factory.token_pos(),
492 "constructor '%s' must be const as required by redirecting" 494 "constructor '%s' must be const as required by redirecting"
(...skipping 972 matching lines...) Expand 10 before | Expand all | Expand 10 after
1465 } 1467 }
1466 const Array& fields_array = Array::Handle(cls.fields()); 1468 const Array& fields_array = Array::Handle(cls.fields());
1467 Field& field = Field::Handle(); 1469 Field& field = Field::Handle();
1468 len = fields_array.Length(); 1470 len = fields_array.Length();
1469 for (intptr_t i = 0; i < len; i++) { 1471 for (intptr_t i = 0; i < len; i++) {
1470 field ^= fields_array.At(i); 1472 field ^= fields_array.At(i);
1471 OS::Print(" %s\n", field.ToCString()); 1473 OS::Print(" %s\n", field.ToCString());
1472 } 1474 }
1473 } 1475 }
1474 1476
1475 1477 // Either report an error or mark the type as malformed.
1476 void ClassFinalizer::FinalizeMalformedType(const Error& prev_error, 1478 void ClassFinalizer::ReportMalformedType(const Error& prev_error,
1477 const Class& cls, 1479 const Class& cls,
1478 const Type& type, 1480 const Type& type,
1479 FinalizationKind finalization, 1481 FinalizationKind finalization,
1480 const char* format, ...) { 1482 const char* format,
1481 va_list args; 1483 va_list args) {
1482 va_start(args, format);
1483 LanguageError& error = LanguageError::Handle(); 1484 LanguageError& error = LanguageError::Handle();
1484 if (FLAG_enable_type_checks || 1485 if (FLAG_enable_type_checks ||
1485 !type.HasResolvedTypeClass() || 1486 !type.HasResolvedTypeClass() ||
1486 (finalization == kCanonicalizeWellFormed) || 1487 (finalization == kCanonicalizeWellFormed) ||
1487 FLAG_error_on_malformed_type) { 1488 FLAG_error_on_malformed_type) {
1488 const Script& script = Script::Handle(cls.script()); 1489 const Script& script = Script::Handle(cls.script());
1489 if (prev_error.IsNull()) { 1490 if (prev_error.IsNull()) {
1490 error ^= Parser::FormatError( 1491 error ^= Parser::FormatError(
1491 script, type.token_pos(), "Error", format, args); 1492 script, type.token_pos(), "Error", format, args);
1492 } else { 1493 } else {
(...skipping 20 matching lines...) Expand all
1513 type.set_is_finalized_instantiated(); 1514 type.set_is_finalized_instantiated();
1514 // Do not canonicalize malformed types, since they may not be resolved. 1515 // Do not canonicalize malformed types, since they may not be resolved.
1515 } else { 1516 } else {
1516 // The only case where the malformed type was already finalized is when its 1517 // The only case where the malformed type was already finalized is when its
1517 // type arguments are not within bounds. In that case, we have a prev_error. 1518 // type arguments are not within bounds. In that case, we have a prev_error.
1518 ASSERT(!prev_error.IsNull()); 1519 ASSERT(!prev_error.IsNull());
1519 } 1520 }
1520 } 1521 }
1521 1522
1522 1523
1524 RawType* ClassFinalizer::NewFinalizedMalformedType(const Class& cls,
1525 intptr_t type_pos,
1526 const char* format, ...) {
1527 va_list args;
1528 va_start(args, format);
1529 const String& no_name = String::Handle(Symbols::Empty());
1530 const UnresolvedClass& unresolved_class = UnresolvedClass::Handle(
1531 UnresolvedClass::New(LibraryPrefix::Handle(), no_name, type_pos));
1532 const Type& type = Type::Handle(
1533 Type::New(unresolved_class, TypeArguments::Handle(), type_pos));
1534 ReportMalformedType(Error::Handle(), cls, type, kTryResolve, format, args);
1535 va_end(args);
1536 ASSERT(type.IsMalformed());
1537 return type.raw();
1538 }
1539
1540
1541 void ClassFinalizer::FinalizeMalformedType(const Error& prev_error,
1542 const Class& cls,
1543 const Type& type,
1544 FinalizationKind finalization,
1545 const char* format, ...) {
1546 va_list args;
1547 va_start(args, format);
1548 ReportMalformedType(prev_error, cls, type, finalization, format, args);
1549 va_end(args);
1550 }
1551
1552
1523 void ClassFinalizer::ReportError(const Error& error) { 1553 void ClassFinalizer::ReportError(const Error& error) {
1524 Isolate::Current()->long_jump_base()->Jump(1, error); 1554 Isolate::Current()->long_jump_base()->Jump(1, error);
1525 UNREACHABLE(); 1555 UNREACHABLE();
1526 } 1556 }
1527 1557
1528 1558
1529 void ClassFinalizer::ReportError(const Script& script, 1559 void ClassFinalizer::ReportError(const Script& script,
1530 intptr_t token_pos, 1560 intptr_t token_pos,
1531 const char* format, ...) { 1561 const char* format, ...) {
1532 va_list args; 1562 va_list args;
1533 va_start(args, format); 1563 va_start(args, format);
1534 const Error& error = Error::Handle( 1564 const Error& error = Error::Handle(
1535 Parser::FormatError(script, token_pos, "Error", format, args)); 1565 Parser::FormatError(script, token_pos, "Error", format, args));
1566 va_end(args);
1536 ReportError(error); 1567 ReportError(error);
1537 } 1568 }
1538 1569
1539 1570
1540 void ClassFinalizer::ReportError(const char* format, ...) { 1571 void ClassFinalizer::ReportError(const char* format, ...) {
1541 va_list args; 1572 va_list args;
1542 va_start(args, format); 1573 va_start(args, format);
1543 const Error& error = Error::Handle( 1574 const Error& error = Error::Handle(
1544 Parser::FormatError(Script::Handle(), -1, "Error", format, args)); 1575 Parser::FormatError(Script::Handle(), -1, "Error", format, args));
1545 va_end(args); 1576 va_end(args);
1546 ReportError(error); 1577 ReportError(error);
1547 } 1578 }
1548 1579
1549 } // namespace dart 1580 } // namespace dart
OLDNEW
« no previous file with comments | « runtime/vm/class_finalizer.h ('k') | runtime/vm/parser.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698