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

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

Issue 66033006: Check type bounds of redirecting factories (issue 14699). (Closed) Base URL: http://dart.googlecode.com/svn/branches/bleeding_edge/dart/
Patch Set: Created 7 years, 1 month 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/object.cc ('k') | tests/language/language_analyzer.status » ('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/parser.h" 5 #include "vm/parser.h"
6 6
7 #include "lib/invocation_mirror.h" 7 #include "lib/invocation_mirror.h"
8 #include "vm/bigint_operations.h" 8 #include "vm/bigint_operations.h"
9 #include "vm/bootstrap.h" 9 #include "vm/bootstrap.h"
10 #include "vm/class_finalizer.h" 10 #include "vm/class_finalizer.h"
(...skipping 1578 matching lines...) Expand 10 before | Expand all | Expand 10 after
1589 } 1589 }
1590 } else { 1590 } else {
1591 signature_function.set_signature_class(signature_class); 1591 signature_function.set_signature_class(signature_class);
1592 } 1592 }
1593 ASSERT(signature_function.signature_class() == signature_class.raw()); 1593 ASSERT(signature_function.signature_class() == signature_class.raw());
1594 Type& signature_type = Type::ZoneHandle(signature_class.SignatureType()); 1594 Type& signature_type = Type::ZoneHandle(signature_class.SignatureType());
1595 if (!is_top_level_ && !signature_type.IsFinalized()) { 1595 if (!is_top_level_ && !signature_type.IsFinalized()) {
1596 signature_type ^= ClassFinalizer::FinalizeType( 1596 signature_type ^= ClassFinalizer::FinalizeType(
1597 signature_class, signature_type, ClassFinalizer::kCanonicalize); 1597 signature_class, signature_type, ClassFinalizer::kCanonicalize);
1598 } 1598 }
1599 // A signature type itself cannot be malformed or malbounded, only its
1600 // signature function's result type or parameter types may be.
1601 ASSERT(!signature_type.IsMalformed());
1602 ASSERT(!signature_type.IsMalbounded());
1599 // The type of the parameter is now the signature type. 1603 // The type of the parameter is now the signature type.
1600 parameter.type = &signature_type; 1604 parameter.type = &signature_type;
1601 } 1605 }
1602 } 1606 }
1603 1607
1604 if ((CurrentToken() == Token::kASSIGN) || (CurrentToken() == Token::kCOLON)) { 1608 if ((CurrentToken() == Token::kASSIGN) || (CurrentToken() == Token::kCOLON)) {
1605 if ((!params->has_optional_positional_parameters && 1609 if ((!params->has_optional_positional_parameters &&
1606 !params->has_optional_named_parameters) || 1610 !params->has_optional_named_parameters) ||
1607 !allow_explicit_default_value) { 1611 !allow_explicit_default_value) {
1608 ErrorMsg("parameter must not specify a default value"); 1612 ErrorMsg("parameter must not specify a default value");
(...skipping 1551 matching lines...) Expand 10 before | Expand all | Expand 10 after
3160 if (!type.IsMalformed() && type.IsTypeParameter()) { 3164 if (!type.IsMalformed() && type.IsTypeParameter()) {
3161 // Replace the type with a malformed type and compile a throw when called. 3165 // Replace the type with a malformed type and compile a throw when called.
3162 redirection_type = ClassFinalizer::NewFinalizedMalformedType( 3166 redirection_type = ClassFinalizer::NewFinalizedMalformedType(
3163 Error::Handle(), // No previous error. 3167 Error::Handle(), // No previous error.
3164 script_, 3168 script_,
3165 type_pos, 3169 type_pos,
3166 "factory '%s' may not redirect to type parameter '%s'", 3170 "factory '%s' may not redirect to type parameter '%s'",
3167 method->name->ToCString(), 3171 method->name->ToCString(),
3168 String::Handle(type.UserVisibleName()).ToCString()); 3172 String::Handle(type.UserVisibleName()).ToCString());
3169 } else { 3173 } else {
3170 // TODO(regis): What if the redirection type is malbounded? 3174 // We handle malformed and malbounded redirection type at run time.
3171 redirection_type ^= type.raw(); 3175 redirection_type ^= type.raw();
3172 } 3176 }
3173 if (CurrentToken() == Token::kPERIOD) { 3177 if (CurrentToken() == Token::kPERIOD) {
3174 // Named constructor or factory. 3178 // Named constructor or factory.
3175 ConsumeToken(); 3179 ConsumeToken();
3176 redirection_identifier = ExpectIdentifier("identifier expected")->raw(); 3180 redirection_identifier = ExpectIdentifier("identifier expected")->raw();
3177 } 3181 }
3178 } else if (CurrentToken() == Token::kCOLON) { 3182 } else if (CurrentToken() == Token::kCOLON) {
3179 // Parse initializers. 3183 // Parse initializers.
3180 if (!method->IsConstructor()) { 3184 if (!method->IsConstructor()) {
(...skipping 2484 matching lines...) Expand 10 before | Expand all | Expand 10 after
5665 AbstractTypeArguments& signature_type_arguments = 5669 AbstractTypeArguments& signature_type_arguments =
5666 AbstractTypeArguments::Handle(signature_type.arguments()); 5670 AbstractTypeArguments::Handle(signature_type.arguments());
5667 5671
5668 if (!signature_type.IsFinalized()) { 5672 if (!signature_type.IsFinalized()) {
5669 signature_type ^= ClassFinalizer::FinalizeType( 5673 signature_type ^= ClassFinalizer::FinalizeType(
5670 signature_class, signature_type, ClassFinalizer::kCanonicalize); 5674 signature_class, signature_type, ClassFinalizer::kCanonicalize);
5671 5675
5672 // The call to ClassFinalizer::FinalizeType may have 5676 // The call to ClassFinalizer::FinalizeType may have
5673 // extended the vector of type arguments. 5677 // extended the vector of type arguments.
5674 signature_type_arguments = signature_type.arguments(); 5678 signature_type_arguments = signature_type.arguments();
5675 ASSERT(signature_type.IsMalformed() || 5679 ASSERT(signature_type_arguments.IsNull() ||
5676 signature_type_arguments.IsNull() ||
5677 (signature_type_arguments.Length() == 5680 (signature_type_arguments.Length() ==
5678 signature_class.NumTypeArguments())); 5681 signature_class.NumTypeArguments()));
5679 5682
5680 // The signature_class should not have changed. 5683 // The signature_class should not have changed.
5681 ASSERT(signature_type.IsMalformed() || 5684 ASSERT(signature_type.type_class() == signature_class.raw());
5682 (signature_type.type_class() == signature_class.raw()));
5683 } 5685 }
5684 5686
5687 // A signature type itself cannot be malformed or malbounded, only its
5688 // signature function's result type or parameter types may be.
5689 ASSERT(!signature_type.IsMalformed());
5690 ASSERT(!signature_type.IsMalbounded());
5691
5685 if (variable_name != NULL) { 5692 if (variable_name != NULL) {
5686 // Patch the function type of the variable now that the signature is known. 5693 // Patch the function type of the variable now that the signature is known.
5687 function_type.set_type_class(signature_class); 5694 function_type.set_type_class(signature_class);
5688 function_type.set_arguments(signature_type_arguments); 5695 function_type.set_arguments(signature_type_arguments);
5689 5696
5690 // Mark the function type as malformed if the signature type is malformed.
5691 if (signature_type.IsMalformed()) {
5692 const Error& error = Error::Handle(signature_type.malformed_error());
5693 function_type.set_malformed_error(error);
5694 }
5695 // TODO(regis): What if the signature is malbounded?
5696
5697 // The function type was initially marked as instantiated, but it may 5697 // The function type was initially marked as instantiated, but it may
5698 // actually be uninstantiated. 5698 // actually be uninstantiated.
5699 function_type.ResetIsFinalized(); 5699 function_type.ResetIsFinalized();
5700 5700
5701 // The function variable type should have been patched above. 5701 // The function variable type should have been patched above.
5702 ASSERT((function_variable == NULL) || 5702 ASSERT((function_variable == NULL) ||
5703 (function_variable->type().raw() == function_type.raw())); 5703 (function_variable->type().raw() == function_type.raw()));
5704 } 5704 }
5705 5705
5706 // The code generator does not compile the closure function when visiting 5706 // The code generator does not compile the closure function when visiting
(...skipping 4220 matching lines...) Expand 10 before | Expand all | Expand 10 after
9927 return ThrowNoSuchMethodError(call_pos, 9927 return ThrowNoSuchMethodError(call_pos,
9928 type_class, 9928 type_class,
9929 external_constructor_name, 9929 external_constructor_name,
9930 arguments, 9930 arguments,
9931 InvocationMirror::kConstructor, 9931 InvocationMirror::kConstructor,
9932 InvocationMirror::kMethod, 9932 InvocationMirror::kMethod,
9933 &constructor); 9933 &constructor);
9934 } else if (constructor.IsRedirectingFactory()) { 9934 } else if (constructor.IsRedirectingFactory()) {
9935 ClassFinalizer::ResolveRedirectingFactory(type_class, constructor); 9935 ClassFinalizer::ResolveRedirectingFactory(type_class, constructor);
9936 Type& redirect_type = Type::Handle(constructor.RedirectionType()); 9936 Type& redirect_type = Type::Handle(constructor.RedirectionType());
9937 if (!redirect_type.IsMalformed() && !redirect_type.IsInstantiated()) { 9937 Error& error = Error::Handle();
9938 if (!redirect_type.IsMalformed() && !redirect_type.IsMalbounded() &&
9939 !redirect_type.IsInstantiated()) {
9938 // The type arguments of the redirection type are instantiated from the 9940 // The type arguments of the redirection type are instantiated from the
9939 // type arguments of the parsed type of the 'new' or 'const' expression. 9941 // type arguments of the parsed type of the 'new' or 'const' expression.
9940 Error& malformed_error = Error::Handle(); 9942 redirect_type ^= redirect_type.InstantiateFrom(type_arguments, &error);
9941 redirect_type ^= redirect_type.InstantiateFrom(type_arguments, 9943 if (!error.IsNull()) {
9942 &malformed_error); 9944 redirect_type = ClassFinalizer::NewFinalizedMalformedType(
9943 if (!malformed_error.IsNull()) { 9945 error,
9944 redirect_type.set_malformed_error(malformed_error); 9946 script_,
9947 call_pos,
9948 "redirecting factory type '%s' cannot be instantiated",
9949 String::Handle(redirect_type.UserVisibleName()).ToCString());
9950 error = Error::null();
9945 } 9951 }
9946 } 9952 }
9947 if (redirect_type.IsMalformed()) { 9953 if (redirect_type.IsMalformed() ||
9954 redirect_type.IsMalboundedWithError(&error)) {
9948 if (is_const) { 9955 if (is_const) {
9949 ErrorMsg(Error::Handle(redirect_type.malformed_error())); 9956 if (redirect_type.IsMalformed()) {
9957 error = type.malformed_error();
9958 }
9959 ErrorMsg(error);
9950 } 9960 }
9951 return ThrowTypeError(redirect_type.token_pos(), redirect_type); 9961 return ThrowTypeError(redirect_type.token_pos(), redirect_type);
9952 } 9962 }
9953 if (FLAG_enable_type_checks && !redirect_type.IsSubtypeOf(type, NULL)) { 9963 if (FLAG_enable_type_checks && !redirect_type.IsSubtypeOf(type, NULL)) {
9954 // Additional type checking of the result is necessary. 9964 // Additional type checking of the result is necessary.
9955 type_bound = type.raw(); 9965 type_bound = type.raw();
9956 } 9966 }
9957 type = redirect_type.raw(); 9967 type = redirect_type.raw();
9958 type_class = type.type_class(); 9968 type_class = type.type_class();
9959 type_class_name = type_class.Name(); 9969 type_class_name = type_class.Name();
(...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after
10006 type_class, 10016 type_class,
10007 external_constructor_name, 10017 external_constructor_name,
10008 arguments, 10018 arguments,
10009 InvocationMirror::kConstructor, 10019 InvocationMirror::kConstructor,
10010 InvocationMirror::kMethod, 10020 InvocationMirror::kMethod,
10011 &constructor); 10021 &constructor);
10012 } 10022 }
10013 10023
10014 // Return a throw in case of a malformed type or report a compile-time error 10024 // Return a throw in case of a malformed type or report a compile-time error
10015 // if the constructor is const. 10025 // if the constructor is const.
10016 if (type.IsMalformed()) { 10026 Error& error = Error::Handle();
10027 if (type.IsMalformed() || type.IsMalboundedWithError(&error)) {
10017 if (is_const) { 10028 if (is_const) {
10018 const Error& error = Error::Handle(type.malformed_error()); 10029 if (type.IsMalformed()) {
10030 error = type.malformed_error();
10031 }
10019 ErrorMsg(error); 10032 ErrorMsg(error);
10020 } 10033 }
10021 return ThrowTypeError(type_pos, type); 10034 return ThrowTypeError(type_pos, type);
10022 } 10035 }
10023 type_arguments ^= type_arguments.Canonicalize(); 10036 type_arguments ^= type_arguments.Canonicalize();
10024 // Make the constructor call. 10037 // Make the constructor call.
10025 AstNode* new_object = NULL; 10038 AstNode* new_object = NULL;
10026 if (is_const) { 10039 if (is_const) {
10027 if (!constructor.is_const()) { 10040 if (!constructor.is_const()) {
10028 const String& external_constructor_name = 10041 const String& external_constructor_name =
(...skipping 703 matching lines...) Expand 10 before | Expand all | Expand 10 after
10732 void Parser::SkipQualIdent() { 10745 void Parser::SkipQualIdent() {
10733 ASSERT(IsIdentifier()); 10746 ASSERT(IsIdentifier());
10734 ConsumeToken(); 10747 ConsumeToken();
10735 if (CurrentToken() == Token::kPERIOD) { 10748 if (CurrentToken() == Token::kPERIOD) {
10736 ConsumeToken(); // Consume the kPERIOD token. 10749 ConsumeToken(); // Consume the kPERIOD token.
10737 ExpectIdentifier("identifier expected after '.'"); 10750 ExpectIdentifier("identifier expected after '.'");
10738 } 10751 }
10739 } 10752 }
10740 10753
10741 } // namespace dart 10754 } // namespace dart
OLDNEW
« no previous file with comments | « runtime/vm/object.cc ('k') | tests/language/language_analyzer.status » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698