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

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

Issue 9665013: Generate a dynamic type error when creating an instance with a bound error. (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
« no previous file with comments | « runtime/lib/error.dart ('k') | runtime/vm/object.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 509 matching lines...) Expand 10 before | Expand all | Expand 10 after
520 } 520 }
521 521
522 522
523 RawAbstractType* ClassFinalizer::FinalizeType(const Class& cls, 523 RawAbstractType* ClassFinalizer::FinalizeType(const Class& cls,
524 const AbstractType& type, 524 const AbstractType& type,
525 FinalizationKind finalization) { 525 FinalizationKind finalization) {
526 if (type.IsFinalized()) { 526 if (type.IsFinalized()) {
527 return type.raw(); 527 return type.raw();
528 } 528 }
529 ASSERT(type.IsResolved()); 529 ASSERT(type.IsResolved());
530 ASSERT((finalization == kFinalize) || (finalization == kFinalizeWellFormed));
530 531
531 if (FLAG_trace_type_finalization) { 532 if (FLAG_trace_type_finalization) {
532 OS::Print("Finalize type '%s'\n", String::Handle(type.Name()).ToCString()); 533 OS::Print("Finalize type '%s'\n", String::Handle(type.Name()).ToCString());
533 } 534 }
534 535
535 if (type.IsTypeParameter()) { 536 if (type.IsTypeParameter()) {
536 ASSERT(!cls.IsNull()); 537 ASSERT(!cls.IsNull());
537 TypeParameter& type_parameter = TypeParameter::Handle(); 538 TypeParameter& type_parameter = TypeParameter::Handle();
538 type_parameter ^= type.raw(); 539 type_parameter ^= type.raw();
539 // The index must reflect the position of this type parameter in the type 540 // The index must reflect the position of this type parameter in the type
(...skipping 121 matching lines...) Expand 10 before | Expand all | Expand 10 after
661 ResolveAndFinalizeUpperBounds(type_class); 662 ResolveAndFinalizeUpperBounds(type_class);
662 Error& malformed_error = Error::Handle(); 663 Error& malformed_error = Error::Handle();
663 // Pass the full type argument vector as the bounds instantiator. 664 // Pass the full type argument vector as the bounds instantiator.
664 if (!full_arguments.IsWithinBoundsOf(type_class, 665 if (!full_arguments.IsWithinBoundsOf(type_class,
665 full_arguments, 666 full_arguments,
666 &malformed_error)) { 667 &malformed_error)) {
667 ASSERT(!malformed_error.IsNull()); 668 ASSERT(!malformed_error.IsNull());
668 // The type argument vector of the type is not within bounds. The type 669 // The type argument vector of the type is not within bounds. The type
669 // is malformed. Prepend malformed_error to new malformed type error in 670 // is malformed. Prepend malformed_error to new malformed type error in
670 // order to report both locations. 671 // order to report both locations.
672 // Note that malformed bounds never result in a compile time error, even
673 // in checked mode. Therefore, overwrite finalization with kFinalize
674 // when finalizing the malformed type.
671 FinalizeMalformedType( 675 FinalizeMalformedType(
672 malformed_error, 676 malformed_error,
673 cls, parameterized_type, finalization, 677 cls, parameterized_type, kFinalize,
674 "type arguments of type '%s' are not within bounds", 678 "type arguments of type '%s' are not within bounds",
675 String::Handle(parameterized_type.Name()).ToCString()); 679 String::Handle(parameterized_type.Name()).ToCString());
676 return parameterized_type.raw(); 680 return parameterized_type.raw();
677 } 681 }
678 } 682 }
679 } else { 683 } else {
680 parameterized_type.set_is_finalized(); 684 parameterized_type.set_is_finalized();
681 } 685 }
682 return parameterized_type.Canonicalize(); 686 return parameterized_type.Canonicalize();
683 } 687 }
684 688
685 689
686 void ClassFinalizer::ResolveAndFinalizeSignature(const Class& cls, 690 void ClassFinalizer::ResolveAndFinalizeSignature(const Class& cls,
687 const Function& function) { 691 const Function& function) {
688 // Resolve result type. 692 // Resolve result type.
689 AbstractType& type = AbstractType::Handle(function.result_type()); 693 AbstractType& type = AbstractType::Handle(function.result_type());
690 FinalizationKind result_finalization = kFinalize; 694 FinalizationKind result_finalization = kFinalize;
691 if (function.IsFactory()) { 695 if (function.IsFactory()) {
692 // The name of a factory must always be resolved to a class or interface. 696 // The name of a factory must always be resolved to a class or interface.
693 // The parser sets the factory result type to a type with an unresolved 697 // The parser sets the factory result type to a type with an unresolved
694 // class whose name matches the factory name. 698 // class whose name matches the factory name.
695 result_finalization = kFinalizeWellFormed; 699 result_finalization = kFinalizeWellFormed;
700 // TODO(regis): Gilad asks if this compile-time error could be relaxed.
701 // The result type of such a factory method would simply be malformed.
696 } 702 }
697 ResolveType(cls, type, result_finalization); 703 ResolveType(cls, type, result_finalization);
698 type = FinalizeType(cls, type, result_finalization); 704 type = FinalizeType(cls, type, result_finalization);
699 function.set_result_type(type); 705 function.set_result_type(type);
700 // Resolve formal parameter types. 706 // Resolve formal parameter types.
701 const intptr_t num_parameters = function.NumberOfParameters(); 707 const intptr_t num_parameters = function.NumberOfParameters();
702 for (intptr_t i = 0; i < num_parameters; i++) { 708 for (intptr_t i = 0; i < num_parameters; i++) {
703 type = function.ParameterTypeAt(i); 709 type = function.ParameterTypeAt(i);
704 ResolveType(cls, type, kFinalize); 710 ResolveType(cls, type, kFinalize);
705 type = FinalizeType(cls, type, kFinalize); 711 type = FinalizeType(cls, type, kFinalize);
(...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after
750 // Resolve and finalize the upper bounds of the type parameters of class cls. 756 // Resolve and finalize the upper bounds of the type parameters of class cls.
751 void ClassFinalizer::ResolveAndFinalizeUpperBounds(const Class& cls) { 757 void ClassFinalizer::ResolveAndFinalizeUpperBounds(const Class& cls) {
752 const intptr_t num_type_params = cls.NumTypeParameters(); 758 const intptr_t num_type_params = cls.NumTypeParameters();
753 AbstractType& bound = AbstractType::Handle(); 759 AbstractType& bound = AbstractType::Handle();
754 const AbstractTypeArguments& bounds = 760 const AbstractTypeArguments& bounds =
755 AbstractTypeArguments::Handle(cls.type_parameter_bounds()); 761 AbstractTypeArguments::Handle(cls.type_parameter_bounds());
756 ASSERT((bounds.IsNull() && (num_type_params == 0)) || 762 ASSERT((bounds.IsNull() && (num_type_params == 0)) ||
757 (bounds.Length() == num_type_params)); 763 (bounds.Length() == num_type_params));
758 for (intptr_t i = 0; i < num_type_params; i++) { 764 for (intptr_t i = 0; i < num_type_params; i++) {
759 bound = bounds.TypeAt(i); 765 bound = bounds.TypeAt(i);
760 if (bound.IsDynamicType()) { 766 if (bound.IsFinalized()) {
761 continue; 767 continue;
762 } 768 }
763 ResolveType(cls, bound, kFinalize); 769 ResolveType(cls, bound, kFinalize);
764 bound = FinalizeType(cls, bound, kFinalize); 770 bound = FinalizeType(cls, bound, kFinalize);
765 bounds.SetTypeAt(i, bound); 771 bounds.SetTypeAt(i, bound);
766 } 772 }
767 } 773 }
768 774
769 775
770 void ClassFinalizer::ResolveAndFinalizeMemberTypes(const Class& cls) { 776 void ClassFinalizer::ResolveAndFinalizeMemberTypes(const Class& cls) {
(...skipping 435 matching lines...) Expand 10 before | Expand all | Expand 10 after
1206 error ^= Parser::FormatError( 1212 error ^= Parser::FormatError(
1207 script, type.token_index(), "Error", format, args); 1213 script, type.token_index(), "Error", format, args);
1208 } else { 1214 } else {
1209 error ^= Parser::FormatErrorWithAppend( 1215 error ^= Parser::FormatErrorWithAppend(
1210 prev_error, script, type.token_index(), "Error", format, args); 1216 prev_error, script, type.token_index(), "Error", format, args);
1211 } 1217 }
1212 if (finalization == kFinalizeWellFormed) { 1218 if (finalization == kFinalizeWellFormed) {
1213 ReportError(error); 1219 ReportError(error);
1214 } 1220 }
1215 } 1221 }
1216 // Replace malformed type with Dynamic type.
1217 type.set_type_class(Class::Handle(Object::dynamic_class()));
1218 type.set_arguments(AbstractTypeArguments::Handle());
1219 if (FLAG_enable_type_checks) { 1222 if (FLAG_enable_type_checks) {
1220 // In checked mode, mark type as malformed. 1223 // In checked mode, mark type as malformed.
1221 type.set_malformed_error(error); 1224 type.set_malformed_error(error);
1225 } else {
1226 // In production mode, replace malformed type with Dynamic type.
1227 type.set_type_class(Class::Handle(Object::dynamic_class()));
1228 type.set_arguments(AbstractTypeArguments::Handle());
1222 } 1229 }
1223 if (!type.IsFinalized()) { 1230 if (!type.IsFinalized()) {
1224 type.set_is_finalized(); 1231 type.set_is_finalized();
1225 type.Canonicalize(); 1232 // Do not canonicalize malformed types, since they may not be resolved.
1226 } else { 1233 } else {
1227 // The only case where the malformed type was already finalized is when its 1234 // The only case where the malformed type was already finalized is when its
1228 // type arguments are not within bounds. In that case, we have a prev_error. 1235 // type arguments are not within bounds. In that case, we have a prev_error.
1229 ASSERT(!prev_error.IsNull()); 1236 ASSERT(!prev_error.IsNull());
1230 } 1237 }
1231 } 1238 }
1232 1239
1233 1240
1234 void ClassFinalizer::ReportError(const Error& error) { 1241 void ClassFinalizer::ReportError(const Error& error) {
1235 Isolate::Current()->long_jump_base()->Jump(1, error); 1242 Isolate::Current()->long_jump_base()->Jump(1, error);
(...skipping 15 matching lines...) Expand all
1251 void ClassFinalizer::ReportError(const char* format, ...) { 1258 void ClassFinalizer::ReportError(const char* format, ...) {
1252 va_list args; 1259 va_list args;
1253 va_start(args, format); 1260 va_start(args, format);
1254 const Error& error = Error::Handle( 1261 const Error& error = Error::Handle(
1255 Parser::FormatError(Script::Handle(), -1, "Error", format, args)); 1262 Parser::FormatError(Script::Handle(), -1, "Error", format, args));
1256 va_end(args); 1263 va_end(args);
1257 ReportError(error); 1264 ReportError(error);
1258 } 1265 }
1259 1266
1260 } // namespace dart 1267 } // namespace dart
OLDNEW
« no previous file with comments | « runtime/lib/error.dart ('k') | runtime/vm/object.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698