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

Side by Side Diff: sdk/lib/_internal/lib/js_mirrors.dart

Issue 51113013: Reapply "Substitute types in generic superclasses and interfaces." . (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Addressed comments. 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
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 library dart._js_mirrors; 5 library dart._js_mirrors;
6 6
7 import 'dart:async'; 7 import 'dart:async';
8 import 'dart:collection' show UnmodifiableListView; 8 import 'dart:collection' show UnmodifiableListView;
9 import 'dart:mirrors'; 9 import 'dart:mirrors';
10 10
(...skipping 189 matching lines...) Expand 10 before | Expand all | Expand 10 after
200 code ^= 17 * simpleName.hashCode; 200 code ^= 17 * simpleName.hashCode;
201 code ^= 19 * owner.hashCode; 201 code ^= 19 * owner.hashCode;
202 return code; 202 return code;
203 } 203 }
204 204
205 String get _prettyName => 'TypeVariableMirror'; 205 String get _prettyName => 'TypeVariableMirror';
206 206
207 TypeMirror get upperBound { 207 TypeMirror get upperBound {
208 if (_cachedUpperBound != null) return _cachedUpperBound; 208 if (_cachedUpperBound != null) return _cachedUpperBound;
209 return _cachedUpperBound = typeMirrorFromRuntimeTypeRepresentation( 209 return _cachedUpperBound = typeMirrorFromRuntimeTypeRepresentation(
210 JS('', 'init.metadata[#]', _typeVariable.bound)); 210 owner, getMetadata(_typeVariable.bound));
211 } 211 }
212 } 212 }
213 213
214 class JsTypeMirror extends JsDeclarationMirror implements TypeMirror { 214 class JsTypeMirror extends JsDeclarationMirror implements TypeMirror {
215 JsTypeMirror(Symbol simpleName) 215 JsTypeMirror(Symbol simpleName)
216 : super(simpleName); 216 : super(simpleName);
217 217
218 String get _prettyName => 'TypeMirror'; 218 String get _prettyName => 'TypeMirror';
219 219
220 DeclarationMirror get owner => null; 220 DeclarationMirror get owner => null;
(...skipping 274 matching lines...) Expand 10 before | Expand all | Expand 10 after
495 // Remove the angle brackets enclosing the type arguments. 495 // Remove the angle brackets enclosing the type arguments.
496 mangledName.substring(typeArgIndex + 1, mangledName.length - 1)); 496 mangledName.substring(typeArgIndex + 1, mangledName.length - 1));
497 JsCache.update(classMirrors, mangledName, mirror); 497 JsCache.update(classMirrors, mangledName, mirror);
498 return mirror; 498 return mirror;
499 } 499 }
500 var constructorOrInterceptor = 500 var constructorOrInterceptor =
501 Primitives.getConstructorOrInterceptor(mangledName); 501 Primitives.getConstructorOrInterceptor(mangledName);
502 if (constructorOrInterceptor == null) { 502 if (constructorOrInterceptor == null) {
503 int index = JS('int|Null', 'init.functionAliases[#]', mangledName); 503 int index = JS('int|Null', 'init.functionAliases[#]', mangledName);
504 if (index != null) { 504 if (index != null) {
505 mirror = new JsTypedefMirror( 505 mirror = new JsTypedefMirror(symbol, mangledName, getMetadata(index));
506 symbol, mangledName, JS('=Object', 'init.metadata[#]', index));
507 JsCache.update(classMirrors, mangledName, mirror); 506 JsCache.update(classMirrors, mangledName, mirror);
508 return mirror; 507 return mirror;
509 } 508 }
510 // Probably an intercepted class. 509 // Probably an intercepted class.
511 // TODO(ahe): How to handle intercepted classes? 510 // TODO(ahe): How to handle intercepted classes?
512 throw new UnsupportedError('Cannot find class for: ${n(symbol)}'); 511 throw new UnsupportedError('Cannot find class for: ${n(symbol)}');
513 } 512 }
514 var constructor = (constructorOrInterceptor is Interceptor) 513 var constructor = (constructorOrInterceptor is Interceptor)
515 ? JS('', '#.constructor', constructorOrInterceptor) 514 ? JS('', '#.constructor', constructorOrInterceptor)
516 : constructorOrInterceptor; 515 : constructorOrInterceptor;
(...skipping 224 matching lines...) Expand 10 before | Expand all | Expand 10 after
741 String mangledName = 740 String mangledName =
742 JS('String|Null', '#[#]', methodsWithOptionalArguments, '*$name'); 741 JS('String|Null', '#[#]', methodsWithOptionalArguments, '*$name');
743 if (mangledName == null) { 742 if (mangledName == null) {
744 // TODO(ahe): Invoke noSuchMethod. 743 // TODO(ahe): Invoke noSuchMethod.
745 throw new UnimplementedNoSuchMethodError( 744 throw new UnimplementedNoSuchMethodError(
746 'Invoking noSuchMethod with named arguments not implemented'); 745 'Invoking noSuchMethod with named arguments not implemented');
747 } 746 }
748 var defaultValueIndices = 747 var defaultValueIndices =
749 JS('List|Null', '#[#].\$defaultValues', reflectee, mangledName); 748 JS('List|Null', '#[#].\$defaultValues', reflectee, mangledName);
750 var defaultValues = 749 var defaultValues =
751 defaultValueIndices.map((int i) => JS('', 'init.metadata[#]', i)) 750 defaultValueIndices.map((int i) => getMetadata(i))
752 .iterator; 751 .iterator;
753 var defaultArguments = new Map(); 752 var defaultArguments = new Map();
754 reflectiveName = mangledNames[mangledName]; 753 reflectiveName = mangledNames[mangledName];
755 var reflectiveNames = reflectiveName.split(':'); 754 var reflectiveNames = reflectiveName.split(':');
756 int requiredPositionalArgumentCount = 755 int requiredPositionalArgumentCount =
757 int.parse(reflectiveNames.elementAt(1)); 756 int.parse(reflectiveNames.elementAt(1));
758 positionalArguments = new List.from(positionalArguments); 757 positionalArguments = new List.from(positionalArguments);
759 // Check the number of positional arguments is valid. 758 // Check the number of positional arguments is valid.
760 if (requiredPositionalArgumentCount != positionalArguments.length) { 759 if (requiredPositionalArgumentCount != positionalArguments.length) {
761 // TODO(ahe): Invoke noSuchMethod. 760 // TODO(ahe): Invoke noSuchMethod.
(...skipping 113 matching lines...) Expand 10 before | Expand all | Expand 10 after
875 * to JsCLassMirror that returns an empty list since it represents original 874 * to JsCLassMirror that returns an empty list since it represents original
876 * declarations and classes that are not generic. 875 * declarations and classes that are not generic.
877 */ 876 */
878 class JsTypeBoundClassMirror extends JsDeclarationMirror implements ClassMirror { 877 class JsTypeBoundClassMirror extends JsDeclarationMirror implements ClassMirror {
879 final JsClassMirror _class; 878 final JsClassMirror _class;
880 879
881 /** 880 /**
882 * When instantiated this field will hold a string representing the list of 881 * When instantiated this field will hold a string representing the list of
883 * type arguments for the class, i.e. what is inside the outermost angle 882 * type arguments for the class, i.e. what is inside the outermost angle
884 * brackets. Then, when get typeArguments is called the first time, the string 883 * brackets. Then, when get typeArguments is called the first time, the string
885 * is parsed into the actual list of TypeMirrors, and the field is overridden 884 * is parsed into the actual list of TypeMirrors, and stored in
886 * with this value. 885 * [_cachedTypeArguments]. Due to type substitution of for instance
886 * superclasses the mangled name of the class and hence this string is needed
887 * after [_cachedTypeArguments] has been computed.
887 * 888 *
888 * If an integer is encountered as a type argument, it represents the type 889 * If an integer is encountered as a type argument, it represents the type
889 * variable at the corresponding entry in [emitter.globalMetadata]. 890 * variable at the corresponding entry in [emitter.globalMetadata].
890 */ 891 */
891 var _typeArguments; 892 String _typeArguments;
892 893
894 UnmodifiableListView<TypeMirror> _cachedTypeArguments;
893 Map<Symbol, VariableMirror> _cachedVariables; 895 Map<Symbol, VariableMirror> _cachedVariables;
894 Map<Symbol, MethodMirror> _cachedGetters; 896 Map<Symbol, MethodMirror> _cachedGetters;
895 Map<Symbol, MethodMirror> _cachedSetters; 897 Map<Symbol, MethodMirror> _cachedSetters;
896 Map<Symbol, MethodMirror> _cachedMethodsMap; 898 Map<Symbol, MethodMirror> _cachedMethodsMap;
897 List<JsMethodMirror> _cachedMethods; 899 List<JsMethodMirror> _cachedMethods;
900 ClassMirror _superclass;
901 List<ClassMirror> _cachedSuperinterfaces;
898 902
899 JsTypeBoundClassMirror(JsClassMirror originalDeclaration, this._typeArguments) 903 JsTypeBoundClassMirror(JsClassMirror originalDeclaration, this._typeArguments)
900 : _class = originalDeclaration, 904 : _class = originalDeclaration,
901 super(originalDeclaration.simpleName); 905 super(originalDeclaration.simpleName);
902 906
903 String get _prettyName => 'ClassMirror'; 907 String get _prettyName => 'ClassMirror';
904 908 String get _mangledName => '${_class._mangledName}<$_typeArguments>';
909
905 List<TypeVariableMirror> get typeVariables => _class.typeVariables; 910 List<TypeVariableMirror> get typeVariables => _class.typeVariables;
906 911
907 List<TypeMirror> get typeArguments { 912 List<TypeMirror> get typeArguments {
908 if (_typeArguments is! String) return _typeArguments; 913 if (_cachedTypeArguments != null) return _cachedTypeArguments;
909 List result = new List(); 914 List result = new List();
910 915
911 addTypeArgument(String typeArgument) { 916 addTypeArgument(String typeArgument) {
912 int parsedIndex = int.parse(typeArgument, onError: (_) => -1); 917 int parsedIndex = int.parse(typeArgument, onError: (_) => -1);
913 if (parsedIndex == -1) { 918 if (parsedIndex == -1) {
914 result.add(reflectClassByMangledName(typeArgument.trim())); 919 result.add(reflectClassByMangledName(typeArgument.trim()));
915 } else { 920 } else {
916 TypeVariable typeVariable = JS('', 'init.metadata[#]', parsedIndex); 921 TypeVariable typeVariable = getMetadata(parsedIndex);
917 TypeMirror owner = reflectClass(typeVariable.owner); 922 TypeMirror owner = reflectClass(typeVariable.owner);
918 TypeVariableMirror typeMirror = 923 TypeVariableMirror typeMirror =
919 new JsTypeVariableMirror(typeVariable, owner); 924 new JsTypeVariableMirror(typeVariable, owner);
920 result.add(typeMirror); 925 result.add(typeMirror);
921 } 926 }
922 } 927 }
923 928
924 if (_typeArguments.indexOf('<') == -1) { 929 if (_typeArguments.indexOf('<') == -1) {
925 _typeArguments.split(',').forEach((t) => addTypeArgument(t)); 930 _typeArguments.split(',').forEach((t) => addTypeArgument(t));
926 } else { 931 } else {
(...skipping 16 matching lines...) Expand all
943 } else { 948 } else {
944 addTypeArgument(currentTypeArgument); 949 addTypeArgument(currentTypeArgument);
945 currentTypeArgument = ''; 950 currentTypeArgument = '';
946 } 951 }
947 } else { 952 } else {
948 currentTypeArgument += character; 953 currentTypeArgument += character;
949 } 954 }
950 } 955 }
951 addTypeArgument(currentTypeArgument); 956 addTypeArgument(currentTypeArgument);
952 } 957 }
953 return _typeArguments = new UnmodifiableListView(result); 958 return _cachedTypeArguments = new UnmodifiableListView(result);
954 } 959 }
955 960
956 Map<Symbol, MethodMirror> get constructors => _class.constructors; 961 Map<Symbol, MethodMirror> get constructors => _class.constructors;
957 962
958 List<JsMethodMirror> get _methods { 963 List<JsMethodMirror> get _methods {
959 if (_cachedMethods != null) return _cachedMethods; 964 if (_cachedMethods != null) return _cachedMethods;
960 return _cachedMethods =_class._getMethodsWithOwner(this); 965 return _cachedMethods =_class._getMethodsWithOwner(this);
961 } 966 }
962 967
963 Map<Symbol, MethodMirror> get methods { 968 Map<Symbol, MethodMirror> get methods {
(...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after
1010 [Map<Symbol, dynamic> namedArguments]) { 1015 [Map<Symbol, dynamic> namedArguments]) {
1011 return _class.newInstanceAsync(constructorName, 1016 return _class.newInstanceAsync(constructorName,
1012 positionalArguments, 1017 positionalArguments,
1013 namedArguments); 1018 namedArguments);
1014 } 1019 }
1015 1020
1016 JsLibraryMirror get owner => _class.owner; 1021 JsLibraryMirror get owner => _class.owner;
1017 1022
1018 List<InstanceMirror> get metadata => _class.metadata; 1023 List<InstanceMirror> get metadata => _class.metadata;
1019 1024
1020 ClassMirror get superclass => _class.superclass; 1025 ClassMirror get superclass {
1026 if (_superclass != null) return _superclass;
1027
1028 List<int> typeInformation =
1029 JS('List|Null', 'init.typeInformation[#]', _class._mangledName);
1030 assert(typeInformation != null);
1031 var type = getMetadata(typeInformation[0]);
1032 return _superclass = typeMirrorFromRuntimeTypeRepresentation(this, type);
1033 }
1021 1034
1022 InstanceMirror invoke(Symbol memberName, 1035 InstanceMirror invoke(Symbol memberName,
1023 List positionalArguments, 1036 List positionalArguments,
1024 [Map<Symbol,dynamic> namedArguments]) { 1037 [Map<Symbol,dynamic> namedArguments]) {
1025 return _class.invoke(memberName, positionalArguments, namedArguments); 1038 return _class.invoke(memberName, positionalArguments, namedArguments);
1026 } 1039 }
1027 1040
1028 bool get isOriginalDeclaration => false; 1041 bool get isOriginalDeclaration => false;
1029 1042
1030 ClassMirror get originalDeclaration => _class; 1043 ClassMirror get originalDeclaration => _class;
1031 1044
1032 List<ClassMirror> get superinterfaces => _class.superinterfaces; 1045 List<ClassMirror> get superinterfaces {
1046 if (_cachedSuperinterfaces != null) return _cachedSuperinterfaces;
1047 return _cachedSuperinterfaces = _class._getSuperinterfacesWithOwner(this);
1048 }
1033 1049
1034 Future<InstanceMirror> getFieldAsync(Symbol fieldName) { 1050 Future<InstanceMirror> getFieldAsync(Symbol fieldName) {
1035 return _class.getFieldAsync(fieldName); 1051 return _class.getFieldAsync(fieldName);
1036 } 1052 }
1037 1053
1038 bool get hasReflectedType => _class.hasReflectedType; 1054 bool get hasReflectedType => _class.hasReflectedType;
1039 1055
1040 Future<InstanceMirror> invokeAsync(Symbol memberName, 1056 Future<InstanceMirror> invokeAsync(Symbol memberName,
1041 List positionalArguments, 1057 List positionalArguments,
1042 [Map<Symbol, dynamic> namedArguments]) { 1058 [Map<Symbol, dynamic> namedArguments]) {
(...skipping 307 matching lines...) Expand 10 before | Expand all | Expand 10 after
1350 if (_cachedMetadata != null) return _cachedMetadata; 1366 if (_cachedMetadata != null) return _cachedMetadata;
1351 if (_metadata == null) { 1367 if (_metadata == null) {
1352 _metadata = extractMetadata(JS('', '#.prototype', _jsConstructor)); 1368 _metadata = extractMetadata(JS('', '#.prototype', _jsConstructor));
1353 } 1369 }
1354 return _cachedMetadata = 1370 return _cachedMetadata =
1355 new UnmodifiableListView<InstanceMirror>(_metadata.map(reflect)); 1371 new UnmodifiableListView<InstanceMirror>(_metadata.map(reflect));
1356 } 1372 }
1357 1373
1358 ClassMirror get superclass { 1374 ClassMirror get superclass {
1359 if (_superclass == null) { 1375 if (_superclass == null) {
1360 var superclassName = _fieldsDescriptor.split(';')[0]; 1376 List<int> typeInformation =
1361 var mixins = superclassName.split('+'); 1377 JS('List|Null', 'init.typeInformation[#]', _mangledName);
1362 if (mixins.length > 1) { 1378 if (typeInformation != null) {
1363 if (mixins.length != 2) { 1379 var type = getMetadata(typeInformation[0]);
1364 throw new RuntimeError('Strange mixin: $_fieldsDescriptor'); 1380 _superclass = typeMirrorFromRuntimeTypeRepresentation(this, type);
1381 } else {
1382 var superclassName = _fieldsDescriptor.split(';')[0];
1383 // TODO(zarah): Remove special handing of mixins.
1384 var mixins = superclassName.split('+');
1385 if (mixins.length > 1) {
1386 if (mixins.length != 2) {
1387 throw new RuntimeError('Strange mixin: $_fieldsDescriptor');
1388 }
1389 _superclass = reflectClassByMangledName(mixins[0]);
1390 } else {
1391 // Use _superclass == this to represent class with no superclass
1392 // (Object).
1393 _superclass = (superclassName == '')
1394 ? this : reflectClassByMangledName(superclassName);
1395 }
1365 } 1396 }
1366 _superclass = reflectClassByMangledName(mixins[0]);
1367 } else {
1368 // Use _superclass == this to represent class with no superclass (Object ).
1369 _superclass = (superclassName == '')
1370 ? this : reflectClassByMangledName(superclassName);
1371 } 1397 }
1372 }
1373 return _superclass == this ? null : _superclass; 1398 return _superclass == this ? null : _superclass;
1374 } 1399 }
1375 1400
1376 InstanceMirror invoke(Symbol memberName, 1401 InstanceMirror invoke(Symbol memberName,
1377 List positionalArguments, 1402 List positionalArguments,
1378 [Map<Symbol,dynamic> namedArguments]) { 1403 [Map<Symbol,dynamic> namedArguments]) {
1379 // Mirror API gotcha: Calling [invoke] on a ClassMirror means invoke a 1404 // Mirror API gotcha: Calling [invoke] on a ClassMirror means invoke a
1380 // static method. 1405 // static method.
1381 1406
1382 if (namedArguments != null && !namedArguments.isEmpty) { 1407 if (namedArguments != null && !namedArguments.isEmpty) {
1383 throw new UnsupportedError('Named arguments are not implemented.'); 1408 throw new UnsupportedError('Named arguments are not implemented.');
1384 } 1409 }
1385 JsMethodMirror mirror = methods[memberName]; 1410 JsMethodMirror mirror = methods[memberName];
1386 if (mirror == null || !mirror.isStatic) { 1411 if (mirror == null || !mirror.isStatic) {
1387 // TODO(ahe): What receiver to use? 1412 // TODO(ahe): What receiver to use?
1388 throw new NoSuchMethodError( 1413 throw new NoSuchMethodError(
1389 this, memberName, positionalArguments, namedArguments); 1414 this, memberName, positionalArguments, namedArguments);
1390 } 1415 }
1391 if (!mirror.canInvokeReflectively()) { 1416 if (!mirror.canInvokeReflectively()) {
1392 throwInvalidReflectionError(n(memberName)); 1417 throwInvalidReflectionError(n(memberName));
1393 } 1418 }
1394 return reflect(mirror._invoke(positionalArguments, namedArguments)); 1419 return reflect(mirror._invoke(positionalArguments, namedArguments));
1395 } 1420 }
1396 1421
1397 bool get isOriginalDeclaration => true; 1422 bool get isOriginalDeclaration => true;
1398 1423
1399 ClassMirror get originalDeclaration => this; 1424 ClassMirror get originalDeclaration => this;
1400 1425
1426 List<ClassMirror> _getSuperinterfacesWithOwner(DeclarationMirror owner) {
1427 List<int> typeInformation =
1428 JS('List|Null', 'init.typeInformation[#]', _mangledName);
1429 List<ClassMirror> result = const <ClassMirror>[];
1430 if (typeInformation != null) {
1431 ClassMirror lookupType(int i) {
1432 var type = getMetadata(i);
1433 return typeMirrorFromRuntimeTypeRepresentation(owner, type);
1434 }
1435
1436 //We skip the first since it is the supertype.
1437 result = typeInformation.skip(1).map(lookupType).toList();
1438 }
1439
1440 return new UnmodifiableListView<ClassMirror>(result);
1441 }
1442
1401 List<ClassMirror> get superinterfaces { 1443 List<ClassMirror> get superinterfaces {
1402 if (_cachedSuperinterfaces != null) return _cachedSuperinterfaces; 1444 if (_cachedSuperinterfaces != null) return _cachedSuperinterfaces;
1403 List<int> interfaces = JS('List|Null', 'init.interfaces[#]', _mangledName); 1445 return _cachedSuperinterfaces = _getSuperinterfacesWithOwner(this);
1404 var result = const [];
1405 if (interfaces != null) {
1406 ClassMirror lookupType(int i) {
1407 var type = JS('=Object', 'init.metadata[#]', i);
1408 return typeMirrorFromRuntimeTypeRepresentation(type);
1409 }
1410 result = interfaces.map(lookupType).toList();
1411 }
1412 return _cachedSuperinterfaces =
1413 new UnmodifiableListView<ClassMirror>(result);
1414 } 1446 }
1415 1447
1416 List<TypeVariableMirror> get typeVariables { 1448 List<TypeVariableMirror> get typeVariables {
1417 if (_cachedTypeVariables != null) return _cachedTypeVariables; 1449 if (_cachedTypeVariables != null) return _cachedTypeVariables;
1418 List result = new List(); 1450 List result = new List();
1419 List typeVariables = 1451 List typeVariables =
1420 JS('JSExtendableArray|Null', '#.prototype["<>"]', _jsConstructor); 1452 JS('JSExtendableArray|Null', '#.prototype["<>"]', _jsConstructor);
1421 if (typeVariables == null) return result; 1453 if (typeVariables == null) return result;
1422 for (int i = 0; i < typeVariables.length; i++) { 1454 for (int i = 0; i < typeVariables.length; i++) {
1423 TypeVariable typeVariable = JS('', 'init.metadata[#]', typeVariables[i]); 1455 TypeVariable typeVariable = getMetadata(typeVariables[i]);
1424 result.add(new JsTypeVariableMirror(typeVariable, this)); 1456 result.add(new JsTypeVariableMirror(typeVariable, this));
1425 } 1457 }
1426 return _cachedTypeVariables = new UnmodifiableListView(result); 1458 return _cachedTypeVariables = new UnmodifiableListView(result);
1427 } 1459 }
1428 1460
1429 List<TypeMirror> get typeArguments => const <TypeMirror>[]; 1461 List<TypeMirror> get typeArguments => const <TypeMirror>[];
1430 } 1462 }
1431 1463
1432 class JsVariableMirror extends JsDeclarationMirror implements VariableMirror { 1464 class JsVariableMirror extends JsDeclarationMirror implements VariableMirror {
1433 static final int REFLECTION_MARKER = 45; 1465 static final int REFLECTION_MARKER = 45;
(...skipping 222 matching lines...) Expand 10 before | Expand all | Expand 10 after
1656 } 1688 }
1657 1689
1658 bool canInvokeReflectively() { 1690 bool canInvokeReflectively() {
1659 return hasReflectableProperty(_jsFunction); 1691 return hasReflectableProperty(_jsFunction);
1660 } 1692 }
1661 1693
1662 DeclarationMirror get owner => _owner; 1694 DeclarationMirror get owner => _owner;
1663 1695
1664 TypeMirror get returnType { 1696 TypeMirror get returnType {
1665 metadata; // Compute _returnType as a side-effect of extracting metadata. 1697 metadata; // Compute _returnType as a side-effect of extracting metadata.
1666 return computeTypeMirror(owner, _returnType); 1698 return typeMirrorFromRuntimeTypeRepresentation(owner, _returnType);
1667 } 1699 }
1668 1700
1669 List<InstanceMirror> get metadata { 1701 List<InstanceMirror> get metadata {
1670 if (_metadata == null) { 1702 if (_metadata == null) {
1671 var raw = extractMetadata(_jsFunction); 1703 var raw = extractMetadata(_jsFunction);
1672 var formals = new List(_parameterCount); 1704 var formals = new List(_parameterCount);
1673 if (!raw.isEmpty) { 1705 if (!raw.isEmpty) {
1674 _returnType = raw[0]; 1706 _returnType = raw[0];
1675 int parameterLength = 1 + _parameterCount * 2; 1707 int parameterLength = 1 + _parameterCount * 2;
1676 int formalsCount = 0; 1708 int formalsCount = 0;
(...skipping 78 matching lines...) Expand 10 before | Expand all | Expand 10 after
1755 final DeclarationMirror owner; 1787 final DeclarationMirror owner;
1756 // A JS object representing the type. 1788 // A JS object representing the type.
1757 final _type; 1789 final _type;
1758 1790
1759 JsParameterMirror(String unmangledName, this.owner, this._type) 1791 JsParameterMirror(String unmangledName, this.owner, this._type)
1760 : super(s(unmangledName)); 1792 : super(s(unmangledName));
1761 1793
1762 String get _prettyName => 'ParameterMirror'; 1794 String get _prettyName => 'ParameterMirror';
1763 1795
1764 TypeMirror get type { 1796 TypeMirror get type {
1765 return computeTypeMirror(owner, _type); 1797 return typeMirrorFromRuntimeTypeRepresentation(owner, _type);
1766 } 1798 }
1767 1799
1768 // Only true for static fields, never for a parameter. 1800 // Only true for static fields, never for a parameter.
1769 bool get isStatic => false; 1801 bool get isStatic => false;
1770 1802
1771 // TODO(ahe): Implement this. 1803 // TODO(ahe): Implement this.
1772 bool get isFinal => false; 1804 bool get isFinal => false;
1773 1805
1774 // TODO(ahe): Implement this. 1806 // TODO(ahe): Implement this.
1775 bool get isOptional => false; 1807 bool get isOptional => false;
(...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after
1816 bool get _isVoid => JS('bool', '!!#.void', _typeData); 1848 bool get _isVoid => JS('bool', '!!#.void', _typeData);
1817 1849
1818 bool get _hasArguments => JS('bool', '"args" in #', _typeData); 1850 bool get _hasArguments => JS('bool', '"args" in #', _typeData);
1819 List get _arguments => JS('JSExtendableArray', '#.args', _typeData); 1851 List get _arguments => JS('JSExtendableArray', '#.args', _typeData);
1820 1852
1821 bool get _hasOptionalArguments => JS('bool', '"opt" in #', _typeData); 1853 bool get _hasOptionalArguments => JS('bool', '"opt" in #', _typeData);
1822 List get _optionalArguments => JS('JSExtendableArray', '#.opt', _typeData); 1854 List get _optionalArguments => JS('JSExtendableArray', '#.opt', _typeData);
1823 1855
1824 bool get _hasNamedArguments => JS('bool', '"named" in #', _typeData); 1856 bool get _hasNamedArguments => JS('bool', '"named" in #', _typeData);
1825 get _namedArguments => JS('=Object', '#.named', _typeData); 1857 get _namedArguments => JS('=Object', '#.named', _typeData);
1858 bool get isOriginalDeclaration => true;
1826 1859
1827 TypeMirror get returnType { 1860 TypeMirror get returnType {
1828 if (_cachedReturnType != null) return _cachedReturnType; 1861 if (_cachedReturnType != null) return _cachedReturnType;
1829 if (_isVoid) return _cachedReturnType = JsMirrorSystem._voidType; 1862 if (_isVoid) return _cachedReturnType = JsMirrorSystem._voidType;
1830 if (!_hasReturnType) return _cachedReturnType = JsMirrorSystem._dynamicType; 1863 if (!_hasReturnType) return _cachedReturnType = JsMirrorSystem._dynamicType;
1831 return _cachedReturnType = 1864 return _cachedReturnType =
1832 typeMirrorFromRuntimeTypeRepresentation(_returnType); 1865 typeMirrorFromRuntimeTypeRepresentation(this, _returnType);
1833 } 1866 }
1834 1867
1835 List<ParameterMirror> get parameters { 1868 List<ParameterMirror> get parameters {
1836 if (_cachedParameters != null) return _cachedParameters; 1869 if (_cachedParameters != null) return _cachedParameters;
1837 List result = []; 1870 List result = [];
1838 int parameterCount = 0; 1871 int parameterCount = 0;
1839 if (_hasArguments) { 1872 if (_hasArguments) {
1840 for (var type in _arguments) { 1873 for (var type in _arguments) {
1841 result.add( 1874 result.add(
1842 new JsParameterMirror('argument${parameterCount++}', this, type)); 1875 new JsParameterMirror('argument${parameterCount++}', this, type));
(...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after
1895 s += 'void'; 1928 s += 'void';
1896 } else if (_hasReturnType) { 1929 } else if (_hasReturnType) {
1897 s += runtimeTypeToString(_returnType); 1930 s += runtimeTypeToString(_returnType);
1898 } else { 1931 } else {
1899 s += 'dynamic'; 1932 s += 'dynamic';
1900 } 1933 }
1901 return _cachedToString = "$s'"; 1934 return _cachedToString = "$s'";
1902 } 1935 }
1903 } 1936 }
1904 1937
1905 TypeMirror typeMirrorFromRuntimeTypeRepresentation(type) { 1938 int findTypeVariableIndex(List<TypeVariableMirror> typeVariables, String name) {
1906 if (type == null) return JsMirrorSystem._dynamicType; 1939 for (int i = 0; i < typeVariables.length; i++) {
1907 String representation = runtimeTypeToString(type); 1940 if (typeVariables[i].simpleName == s(name)) {
1908 if (representation == null) return reflectClass(Function); 1941 return i;
1909 return reflectType(createRuntimeType(representation)); 1942 }
1943 }
1944 throw new ArgumentError('Type variable not present in list.');
1910 } 1945 }
1911 1946
1912 TypeMirror computeTypeMirror(DeclarationMirror owner, var type) { 1947 getMetadata(int index) => JS('', 'init.metadata[#]', index);
1913 if (type is! int) { 1948
1914 return typeMirrorFromRuntimeTypeRepresentation(type); 1949 TypeMirror typeMirrorFromRuntimeTypeRepresentation(
1915 } 1950 DeclarationMirror owner,
1916 1951 var /*int|List|JsFunction*/ type) {
1917 ClassMirror ownerClass; 1952 ClassMirror ownerClass;
1918 DeclarationMirror context = owner; 1953 DeclarationMirror context = owner;
1919 while(context != null) { 1954 while(context != null) {
1920 if (context is ClassMirror) { 1955 if (context is ClassMirror) {
1921 ownerClass = context; 1956 ownerClass = context;
1922 break; 1957 break;
1923 } 1958 }
1924 context = context.owner; 1959 context = context.owner;
1925 } 1960 }
1926 1961
1927 TypeVariable typeVariable = JS('', 'init.metadata[#]', type); 1962 String representation;
1928 Symbol name = new Symbol(typeVariable.name); 1963 if (type == null){
1929 List<TypeVariableMirror> typeVariables = ownerClass.typeVariables; 1964 return JsMirrorSystem._dynamicType;
1930 for (int i = 0; i < typeVariables.length; i++) { 1965 } else if (ownerClass == null) {
1931 if (typeVariables[i].simpleName == name) { 1966 representation = runtimeTypeToString(type);
1932 if (ownerClass.isOriginalDeclaration) { 1967 } else if (ownerClass.isOriginalDeclaration) {
1933 return typeVariables[i]; 1968 if (type is int) {
1934 } else { 1969 // [type] represents a type variable so in the context of an original
1935 return ownerClass.typeArguments[i]; 1970 // declaration the corresponding type variable should be returned.
1936 } 1971 TypeVariable typeVariable = getMetadata(type);
1972 List<TypeVariableMirror> typeVariables = ownerClass.typeVariables;
1973 int index = findTypeVariableIndex(typeVariables, typeVariable.name);
1974 return typeVariables[index];
1975 } else {
1976 // Nested type variables will be retrieved lazily (the integer
1977 // representation is kept in the string) so they are not processed here.
1978 representation = runtimeTypeToString(type);
1937 } 1979 }
1980 } else {
1981 String substituteTypeVariable(int index) {
1982 TypeVariable typeVariable = getMetadata(index);
1983 int variableIndex =
1984 findTypeVariableIndex(ownerClass.typeVariables, typeVariable.name);
1985 var typeArgument = ownerClass.typeArguments[variableIndex];
1986 assert(typeArgument is JsClassMirror ||
1987 typeArgument is JsTypeBoundClassMirror);
1988 return typeArgument._mangledName;
1989 }
1990 representation =
1991 runtimeTypeToString(type, onTypeVariable: substituteTypeVariable);
1938 } 1992 }
1993 if (representation != null) {
1994 return reflectType(createRuntimeType(representation));
1995 }
1996 return reflectClass(Function);
1939 } 1997 }
1940 1998
1941 Symbol computeQualifiedName(DeclarationMirror owner, Symbol simpleName) { 1999 Symbol computeQualifiedName(DeclarationMirror owner, Symbol simpleName) {
1942 if (owner == null) return simpleName; 2000 if (owner == null) return simpleName;
1943 String ownerName = n(owner.qualifiedName); 2001 String ownerName = n(owner.qualifiedName);
1944 return s('$ownerName.${n(simpleName)}'); 2002 return s('$ownerName.${n(simpleName)}');
1945 } 2003 }
1946 2004
1947 List extractMetadata(victim) { 2005 List extractMetadata(victim) {
1948 preserveMetadata(); 2006 preserveMetadata();
1949 var metadataFunction = JS('', '#["@"]', victim); 2007 var metadataFunction = JS('', '#["@"]', victim);
1950 if (metadataFunction != null) return JS('', '#()', metadataFunction); 2008 if (metadataFunction != null) return JS('', '#()', metadataFunction);
1951 if (JS('String', 'typeof #', victim) != 'function') return const []; 2009 if (JS('String', 'typeof #', victim) != 'function') return const [];
1952 String source = JS('String', 'Function.prototype.toString.call(#)', victim); 2010 String source = JS('String', 'Function.prototype.toString.call(#)', victim);
1953 int index = source.lastIndexOf(new RegExp('"[0-9,]*";?[ \n\r]*}')); 2011 int index = source.lastIndexOf(new RegExp('"[0-9,]*";?[ \n\r]*}'));
1954 if (index == -1) return const []; 2012 if (index == -1) return const [];
1955 index++; 2013 index++;
1956 int endQuote = source.indexOf('"', index); 2014 int endQuote = source.indexOf('"', index);
1957 return source.substring(index, endQuote).split(',').map(int.parse).map( 2015 return source.substring(index, endQuote).split(',').map(int.parse).map(
1958 (int i) => JS('', 'init.metadata[#]', i)).toList(); 2016 (int i) => getMetadata(i)).toList();
1959 } 2017 }
1960 2018
1961 List<JsVariableMirror> parseCompactFieldSpecification( 2019 List<JsVariableMirror> parseCompactFieldSpecification(
1962 JsDeclarationMirror owner, 2020 JsDeclarationMirror owner,
1963 fieldSpecification, 2021 fieldSpecification,
1964 bool isStatic, 2022 bool isStatic,
1965 List<Mirror> result) { 2023 List<Mirror> result) {
1966 List fieldsMetadata = null; 2024 List fieldsMetadata = null;
1967 List<String> fieldNames; 2025 List<String> fieldNames;
1968 if (fieldSpecification is List) { 2026 if (fieldSpecification is List) {
(...skipping 101 matching lines...) Expand 10 before | Expand all | Expand 10 after
2070 2128
2071 // TODO(ahe): Remove this class and call noSuchMethod instead. 2129 // TODO(ahe): Remove this class and call noSuchMethod instead.
2072 class UnimplementedNoSuchMethodError extends Error 2130 class UnimplementedNoSuchMethodError extends Error
2073 implements NoSuchMethodError { 2131 implements NoSuchMethodError {
2074 final String _message; 2132 final String _message;
2075 2133
2076 UnimplementedNoSuchMethodError(this._message); 2134 UnimplementedNoSuchMethodError(this._message);
2077 2135
2078 String toString() => "Unsupported operation: $_message"; 2136 String toString() => "Unsupported operation: $_message";
2079 } 2137 }
OLDNEW
« no previous file with comments | « sdk/lib/_internal/compiler/implementation/js_emitter/reflection_data_parser.dart ('k') | sdk/lib/_internal/lib/js_rti.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698