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

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

Issue 10696013: Consider upper bounds of type parameters in type checks. (Closed) Base URL: http://dart.googlecode.com/svn/branches/bleeding_edge/dart/
Patch Set: Created 8 years, 5 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
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 "vm/bigint_operations.h" 7 #include "vm/bigint_operations.h"
8 #include "vm/class_finalizer.h" 8 #include "vm/class_finalizer.h"
9 #include "vm/compiler.h" 9 #include "vm/compiler.h"
10 #include "vm/compiler_stats.h" 10 #include "vm/compiler_stats.h"
(...skipping 3155 matching lines...) Expand 10 before | Expand all | Expand 10 after
3166 Class::New(String::Handle(String::NewSymbol(":factory_signature")), 3166 Class::New(String::Handle(String::NewSymbol(":factory_signature")),
3167 script_, 3167 script_,
3168 factory_name.ident_pos)); 3168 factory_name.ident_pos));
3169 factory_class.set_library(library_); 3169 factory_class.set_library(library_);
3170 factory_class.set_is_finalized(); 3170 factory_class.set_is_finalized();
3171 ParseTypeParameters(factory_class); 3171 ParseTypeParameters(factory_class);
3172 unresolved_factory_class.set_factory_signature_class(factory_class); 3172 unresolved_factory_class.set_factory_signature_class(factory_class);
3173 interface.set_factory_class(unresolved_factory_class); 3173 interface.set_factory_class(unresolved_factory_class);
3174 // If a type parameter list is included in the default factory clause (it 3174 // If a type parameter list is included in the default factory clause (it
3175 // can be omitted), verify that it matches the list of type parameters of 3175 // can be omitted), verify that it matches the list of type parameters of
3176 // the interface in number and names. 3176 // the interface in number and names, but not necessarily in bounds.
3177 if (factory_class.NumTypeParameters() > 0) { 3177 if (factory_class.NumTypeParameters() > 0) {
3178 const bool check_type_parameter_bounds = false;
3178 if (!AbstractTypeArguments::AreIdentical( 3179 if (!AbstractTypeArguments::AreIdentical(
3179 AbstractTypeArguments::Handle(interface.type_parameters()), 3180 AbstractTypeArguments::Handle(interface.type_parameters()),
3180 AbstractTypeArguments::Handle(factory_class.type_parameters()))) { 3181 AbstractTypeArguments::Handle(factory_class.type_parameters()),
3182 check_type_parameter_bounds)) {
hausner 2012/06/27 19:59:40 Indentation
regis 2012/06/27 20:06:50 I think the indentation is correct.
3181 const String& interface_name = String::Handle(interface.Name()); 3183 const String& interface_name = String::Handle(interface.Name());
3182 ErrorMsg(factory_name.ident_pos, 3184 ErrorMsg(factory_name.ident_pos,
3183 "mismatch in number or names of type parameters between " 3185 "mismatch in number or names of type parameters between "
3184 "interface '%s' and default factory class '%s'.\n", 3186 "interface '%s' and default factory class '%s'.\n",
3185 interface_name.ToCString(), 3187 interface_name.ToCString(),
3186 factory_name.ident->ToCString()); 3188 factory_name.ident->ToCString());
3187 } 3189 }
3188 } 3190 }
3189 } 3191 }
3190 3192
(...skipping 69 matching lines...) Expand 10 before | Expand all | Expand 10 after
3260 SkipTypeArguments(); 3262 SkipTypeArguments();
3261 } 3263 }
3262 } 3264 }
3263 3265
3264 3266
3265 void Parser::ParseTypeParameters(const Class& cls) { 3267 void Parser::ParseTypeParameters(const Class& cls) {
3266 TRACE_PARSER("ParseTypeParameters"); 3268 TRACE_PARSER("ParseTypeParameters");
3267 if (CurrentToken() == Token::kLT) { 3269 if (CurrentToken() == Token::kLT) {
3268 const GrowableObjectArray& type_parameters_array = 3270 const GrowableObjectArray& type_parameters_array =
3269 GrowableObjectArray::Handle(GrowableObjectArray::New()); 3271 GrowableObjectArray::Handle(GrowableObjectArray::New());
3270 const GrowableObjectArray& bounds_array =
3271 GrowableObjectArray::Handle(GrowableObjectArray::New());
3272 intptr_t index = 0; 3272 intptr_t index = 0;
3273 TypeParameter& type_parameter = TypeParameter::Handle(); 3273 TypeParameter& type_parameter = TypeParameter::Handle();
3274 TypeParameter& existing_type_parameter = TypeParameter::Handle(); 3274 TypeParameter& existing_type_parameter = TypeParameter::Handle();
3275 String& existing_type_parameter_name = String::Handle(); 3275 String& existing_type_parameter_name = String::Handle();
3276 AbstractType& bound = Type::Handle(); 3276 AbstractType& type_parameter_bound = Type::Handle();
3277 do { 3277 do {
3278 ConsumeToken(); 3278 ConsumeToken();
3279 if (CurrentToken() != Token::kIDENT) { 3279 if (CurrentToken() != Token::kIDENT) {
3280 ErrorMsg("type parameter name expected"); 3280 ErrorMsg("type parameter name expected");
3281 } 3281 }
3282 String& type_parameter_name = *CurrentLiteral(); 3282 String& type_parameter_name = *CurrentLiteral();
3283 type_parameter = TypeParameter::New(cls, 3283 const intptr_t type_parameter_pos = TokenPos();
3284 index,
3285 type_parameter_name,
3286 TokenPos());
3287 // Check for duplicate type parameters. 3284 // Check for duplicate type parameters.
3288 for (intptr_t i = 0; i < index; i++) { 3285 for (intptr_t i = 0; i < index; i++) {
3289 existing_type_parameter ^= type_parameters_array.At(i); 3286 existing_type_parameter ^= type_parameters_array.At(i);
3290 existing_type_parameter_name = existing_type_parameter.Name(); 3287 existing_type_parameter_name = existing_type_parameter.Name();
3291 if (existing_type_parameter_name.Equals(type_parameter_name)) { 3288 if (existing_type_parameter_name.Equals(type_parameter_name)) {
3292 ErrorMsg("duplicate type parameter '%s'", 3289 ErrorMsg("duplicate type parameter '%s'",
3293 type_parameter_name.ToCString()); 3290 type_parameter_name.ToCString());
3294 } 3291 }
3295 } 3292 }
3296 ConsumeToken(); 3293 ConsumeToken();
3297 bound = Type::DynamicType();
3298 if (CurrentToken() == Token::kEXTENDS) { 3294 if (CurrentToken() == Token::kEXTENDS) {
3299 ConsumeToken(); 3295 ConsumeToken();
3300 // A bound may refer to the owner of the type parameter it applies to, 3296 // A bound may refer to the owner of the type parameter it applies to,
3301 // i.e. to the class or interface currently being parsed. 3297 // i.e. to the class or interface currently being parsed.
3302 // Postpone resolution in order to avoid resolving the class and its 3298 // Postpone resolution in order to avoid resolving the class and its
3303 // type parameters, as they are not fully parsed yet. 3299 // type parameters, as they are not fully parsed yet.
3304 bound = ParseType(ClassFinalizer::kDoNotResolve); 3300 type_parameter_bound = ParseType(ClassFinalizer::kDoNotResolve);
3301 } else {
3302 type_parameter_bound = Type::DynamicType();
3305 } 3303 }
3304 type_parameter = TypeParameter::New(cls,
3305 index,
3306 type_parameter_name,
3307 type_parameter_bound,
3308 type_parameter_pos);
3306 type_parameters_array.Add(type_parameter); 3309 type_parameters_array.Add(type_parameter);
3307 bounds_array.Add(bound);
3308 index++; 3310 index++;
3309 } while (CurrentToken() == Token::kCOMMA); 3311 } while (CurrentToken() == Token::kCOMMA);
3310 Token::Kind token = CurrentToken(); 3312 Token::Kind token = CurrentToken();
3311 if ((token == Token::kGT) || (token == Token::kSHR)) { 3313 if ((token == Token::kGT) || (token == Token::kSHR)) {
3312 ConsumeRightAngleBracket(); 3314 ConsumeRightAngleBracket();
3313 } else { 3315 } else {
3314 ErrorMsg("right angle bracket expected"); 3316 ErrorMsg("right angle bracket expected");
3315 } 3317 }
3316 const TypeArguments& type_parameters = 3318 const TypeArguments& type_parameters =
3317 TypeArguments::Handle(NewTypeArguments(type_parameters_array)); 3319 TypeArguments::Handle(NewTypeArguments(type_parameters_array));
3318 const TypeArguments& bounds =
3319 TypeArguments::Handle(NewTypeArguments(bounds_array));
3320 cls.set_type_parameters(type_parameters); 3320 cls.set_type_parameters(type_parameters);
3321 cls.set_type_parameter_bounds(bounds);
3322 // Try to resolve the upper bounds, which will at least resolve the 3321 // Try to resolve the upper bounds, which will at least resolve the
3323 // referenced type parameters. 3322 // referenced type parameters.
3324 const intptr_t num_types = bounds.Length(); 3323 const intptr_t num_types = type_parameters.Length();
3325 for (intptr_t i = 0; i < num_types; i++) { 3324 for (intptr_t i = 0; i < num_types; i++) {
3326 bound = bounds.TypeAt(i); 3325 type_parameter ^= type_parameters.TypeAt(i);
3327 ResolveTypeFromClass(cls, ClassFinalizer::kTryResolve, &bound); 3326 type_parameter_bound = type_parameter.bound();
3328 bounds.SetTypeAt(i, bound); 3327 ResolveTypeFromClass(cls,
3328 ClassFinalizer::kTryResolve,
3329 &type_parameter_bound);
3330 type_parameter.set_bound(type_parameter_bound);
3329 } 3331 }
3330 } 3332 }
3331 } 3333 }
3332 3334
3333 3335
3334 RawAbstractTypeArguments* Parser::ParseTypeArguments( 3336 RawAbstractTypeArguments* Parser::ParseTypeArguments(
3335 Error* malformed_error, 3337 Error* malformed_error,
3336 ClassFinalizer::FinalizationKind finalization) { 3338 ClassFinalizer::FinalizationKind finalization) {
3337 TRACE_PARSER("ParseTypeArguments"); 3339 TRACE_PARSER("ParseTypeArguments");
3338 if (CurrentToken() == Token::kLT) { 3340 if (CurrentToken() == Token::kLT) {
(...skipping 5292 matching lines...) Expand 10 before | Expand all | Expand 10 after
8631 void Parser::SkipQualIdent() { 8633 void Parser::SkipQualIdent() {
8632 ASSERT(IsIdentifier()); 8634 ASSERT(IsIdentifier());
8633 ConsumeToken(); 8635 ConsumeToken();
8634 if (CurrentToken() == Token::kPERIOD) { 8636 if (CurrentToken() == Token::kPERIOD) {
8635 ConsumeToken(); // Consume the kPERIOD token. 8637 ConsumeToken(); // Consume the kPERIOD token.
8636 ExpectIdentifier("identifier expected after '.'"); 8638 ExpectIdentifier("identifier expected after '.'");
8637 } 8639 }
8638 } 8640 }
8639 8641
8640 } // namespace dart 8642 } // namespace dart
OLDNEW
« runtime/vm/object.cc ('K') | « runtime/vm/object.cc ('k') | runtime/vm/raw_object.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698