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

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

Issue 19669010: Fix generic mixins (issue 11803). (Closed) Base URL: http://dart.googlecode.com/svn/branches/bleeding_edge/dart/
Patch Set: Created 7 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
« no previous file with comments | « no previous file | tests/language/language.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) 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 1239 matching lines...) Expand 10 before | Expand all | Expand 10 after
1250 class_name.ToCString(), 1250 class_name.ToCString(),
1251 function_name.ToCString(), 1251 function_name.ToCString(),
1252 super_class_name.ToCString()); 1252 super_class_name.ToCString());
1253 } 1253 }
1254 } 1254 }
1255 } 1255 }
1256 } 1256 }
1257 1257
1258 1258
1259 // Copy the type parameters of the super and mixin classes to the 1259 // Copy the type parameters of the super and mixin classes to the
1260 // mixin application class. Change type arguments of super type to 1260 // mixin application class. Change type arguments of super type and of
1261 // refer to the respective type parameters of the mixin application 1261 // interfaces to refer to the respective type parameters of the mixin
1262 // class. 1262 // application class.
1263 void ClassFinalizer::CloneTypeParameters(const Class& mixapp_class) { 1263 void ClassFinalizer::CloneTypeParameters(const Class& mixapp_class) {
1264 ASSERT(mixapp_class.NumTypeParameters() == 0); 1264 ASSERT(mixapp_class.NumTypeParameters() == 0);
1265 1265
1266 const AbstractType& super_type = 1266 const AbstractType& super_type =
1267 AbstractType::Handle(mixapp_class.super_type()); 1267 AbstractType::Handle(mixapp_class.super_type());
1268 ASSERT(super_type.IsResolved()); 1268 ASSERT(super_type.IsResolved());
1269 const Class& super_class = Class::Handle(super_type.type_class()); 1269 const Class& super_class = Class::Handle(super_type.type_class());
1270 const Type& mixin_type = Type::Handle(mixapp_class.mixin()); 1270 const Type& mixin_type = Type::Handle(mixapp_class.mixin());
1271 const Class& mixin_class = Class::Handle(mixin_type.type_class()); 1271 const Class& mixin_class = Class::Handle(mixin_type.type_class());
1272 const int num_super_parameters = super_class.NumTypeParameters(); 1272 const int num_super_parameters = super_class.NumTypeParameters();
(...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after
1311 param.token_pos()); 1311 param.token_pos());
1312 cloned_type_params.SetTypeAt(cloned_index, cloned_param); 1312 cloned_type_params.SetTypeAt(cloned_index, cloned_param);
1313 // Change the type arguments of the super type to refer to the 1313 // Change the type arguments of the super type to refer to the
1314 // cloned type parameters of the mixin application class. 1314 // cloned type parameters of the mixin application class.
1315 super_type_args.SetTypeAt(cloned_index, cloned_param); 1315 super_type_args.SetTypeAt(cloned_index, cloned_param);
1316 cloned_index++; 1316 cloned_index++;
1317 } 1317 }
1318 // TODO(hausner): May need to handle BoundedType here. 1318 // TODO(hausner): May need to handle BoundedType here.
1319 ASSERT(super_type.IsType()); 1319 ASSERT(super_type.IsType());
1320 Type::Cast(super_type).set_arguments(super_type_args); 1320 Type::Cast(super_type).set_arguments(super_type_args);
1321 ASSERT(!super_type.IsFinalized());
1321 } 1322 }
1322 1323
1323 // Second, clone the type parameters of the mixin class. 1324 // Second, clone the type parameters of the mixin class.
1324 // We need to retain the parameter names of the mixin class 1325 // We need to retain the parameter names of the mixin class
1325 // since the code that will be compiled in the context of the 1326 // since the code that will be compiled in the context of the
1326 // mixin application class may refer to the type parameters 1327 // mixin application class may refer to the type parameters
1327 // with that name. 1328 // with that name.
1328 if (num_mixin_parameters > 0) { 1329 if (num_mixin_parameters > 0) {
1329 const TypeArguments& mixin_params = 1330 const TypeArguments& mixin_params =
1330 TypeArguments::Handle(mixin_class.type_parameters()); 1331 TypeArguments::Handle(mixin_class.type_parameters());
1332 const TypeArguments& interface_type_args = TypeArguments::Handle(
1333 TypeArguments::New(num_mixin_parameters));
1331 for (int i = 0; i < num_mixin_parameters; i++) { 1334 for (int i = 0; i < num_mixin_parameters; i++) {
1332 param ^= mixin_params.TypeAt(i); 1335 param ^= mixin_params.TypeAt(i);
1333 param_name = param.name(); 1336 param_name = param.name();
1334 param_bound = param.bound(); 1337 param_bound = param.bound();
1335 1338
1336 // TODO(hausner): handle type bounds. 1339 // TODO(hausner): handle type bounds.
1337 if (!param_bound.IsObjectType()) { 1340 if (!param_bound.IsObjectType()) {
1338 const Script& script = Script::Handle(mixapp_class.script()); 1341 const Script& script = Script::Handle(mixapp_class.script());
1339 ReportError(script, param.token_pos(), 1342 ReportError(script, param.token_pos(),
1340 "type parameter '%s': type bounds not yet" 1343 "type parameter '%s': type bounds not yet"
1341 " implemented for mixins\n", 1344 " implemented for mixins\n",
1342 param_name.ToCString()); 1345 param_name.ToCString());
1343 } 1346 }
1344 cloned_param = TypeParameter::New(mixapp_class, 1347 cloned_param = TypeParameter::New(mixapp_class,
1345 cloned_index, 1348 cloned_index,
1346 param_name, 1349 param_name,
1347 param_bound, 1350 param_bound,
1348 param.token_pos()); 1351 param.token_pos());
1349 cloned_type_params.SetTypeAt(cloned_index, cloned_param); 1352 cloned_type_params.SetTypeAt(cloned_index, cloned_param);
1353 interface_type_args.SetTypeAt(i, cloned_param);
1350 cloned_index++; 1354 cloned_index++;
1351 } 1355 }
1356
1357 // Lastly, change the type arguments of the single interface type to
1358 // refer to the cloned type parameters of the mixin application class.
1359 Array& interface_types = Array::Handle(mixapp_class.interfaces());
1360 ASSERT(interface_types.Length() == 1);
1361 AbstractType& interface_type = AbstractType::Handle();
1362 interface_type ^= interface_types.At(0);
1363 ASSERT(interface_type.IsResolved());
1364 // TODO(hausner): May need to handle BoundedType here.
1365 ASSERT(interface_type.IsType());
1366 Type::Cast(interface_type).set_arguments(interface_type_args);
1367 ASSERT(!interface_type.IsFinalized());
1352 } 1368 }
1353 mixapp_class.set_type_parameters(cloned_type_params); 1369 mixapp_class.set_type_parameters(cloned_type_params);
1354 } 1370 }
1355 1371
1356 1372
1357 void ClassFinalizer::ApplyMixinTypes(const Class& cls) { 1373 void ClassFinalizer::ApplyMixinTypes(const Class& cls) {
1358 const Type& mixin_type = Type::Handle(cls.mixin()); 1374 const Type& mixin_type = Type::Handle(cls.mixin());
1359 ASSERT(!mixin_type.IsNull()); 1375 ASSERT(!mixin_type.IsNull());
1360 ASSERT(mixin_type.HasResolvedTypeClass()); 1376 ASSERT(mixin_type.HasResolvedTypeClass());
1361 const Class& mixin_cls = Class::Handle(mixin_type.type_class()); 1377 const Class& mixin_cls = Class::Handle(mixin_type.type_class());
1362 1378
1363 if (FLAG_trace_class_finalization) { 1379 if (FLAG_trace_class_finalization) {
1364 OS::Print("Applying mixin type '%s' to '%s' at pos %"Pd"\n", 1380 OS::Print("Applying mixin type '%s' to '%s' at pos %"Pd"\n",
1365 String::Handle(mixin_cls.Name()).ToCString(), 1381 String::Handle(mixin_type.Name()).ToCString(),
1366 cls.ToCString(), 1382 cls.ToCString(),
1367 cls.token_pos()); 1383 cls.token_pos());
1368 } 1384 }
1369 1385
1370 // Check that the super class of the mixin class is extending 1386 // Check that the super class of the mixin class is extending
1371 // class Object. 1387 // class Object.
1372 const AbstractType& mixin_super_type = 1388 const AbstractType& mixin_super_type =
1373 AbstractType::Handle(mixin_cls.super_type()); 1389 AbstractType::Handle(mixin_cls.super_type());
1374 if (!mixin_super_type.IsObjectType()) { 1390 if (!mixin_super_type.IsObjectType()) {
1375 const Script& script = Script::Handle(cls.script()); 1391 const Script& script = Script::Handle(cls.script());
1376 const String& class_name = String::Handle(mixin_cls.Name()); 1392 const String& class_name = String::Handle(mixin_cls.Name());
1377 ReportError(script, cls.token_pos(), 1393 ReportError(script, cls.token_pos(),
1378 "mixin class %s must extend class Object", 1394 "mixin class %s must extend class Object",
1379 class_name.ToCString()); 1395 class_name.ToCString());
1380 } 1396 }
1381 1397
1382 // Copy type parameters to mixin application class. 1398 // Copy type parameters to mixin application class.
1383 CloneTypeParameters(cls); 1399 CloneTypeParameters(cls);
1384 1400
1385 if (FLAG_trace_class_finalization) { 1401 if (FLAG_trace_class_finalization) {
1386 OS::Print("done mixin type appl %s %s extending '%s'\n", 1402 OS::Print("Done applying mixin type '%s' to class %s %s extending '%s'\n",
1403 String::Handle(mixin_type.Name()).ToCString(),
1387 String::Handle(cls.Name()).ToCString(), 1404 String::Handle(cls.Name()).ToCString(),
1388 TypeArguments::Handle(cls.type_parameters()).ToCString(), 1405 TypeArguments::Handle(cls.type_parameters()).ToCString(),
1389 AbstractType::Handle(cls.super_type()).ToCString()); 1406 AbstractType::Handle(cls.super_type()).ToCString());
1390 } 1407 }
1391 } 1408 }
1392 1409
1393 1410
1394 void ClassFinalizer::CreateForwardingConstructors( 1411 void ClassFinalizer::CreateForwardingConstructors(
1395 const Class& mixin_app, 1412 const Class& mixin_app,
1396 const GrowableObjectArray& cloned_funcs) { 1413 const GrowableObjectArray& cloned_funcs) {
(...skipping 791 matching lines...) Expand 10 before | Expand all | Expand 10 after
2188 expected_name ^= String::New("_offset"); 2205 expected_name ^= String::New("_offset");
2189 ASSERT(String::EqualsIgnoringPrivateKey(name, expected_name)); 2206 ASSERT(String::EqualsIgnoringPrivateKey(name, expected_name));
2190 field ^= fields_array.At(2); 2207 field ^= fields_array.At(2);
2191 ASSERT(field.Offset() == TypedDataView::length_offset()); 2208 ASSERT(field.Offset() == TypedDataView::length_offset());
2192 name ^= field.name(); 2209 name ^= field.name();
2193 ASSERT(name.Equals("length")); 2210 ASSERT(name.Equals("length"));
2194 #endif 2211 #endif
2195 } 2212 }
2196 2213
2197 } // namespace dart 2214 } // namespace dart
OLDNEW
« no previous file with comments | « no previous file | tests/language/language.status » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698