Chromium Code Reviews| OLD | NEW |
|---|---|
| 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 190 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 201 code ^= 17 * simpleName.hashCode; | 201 code ^= 17 * simpleName.hashCode; |
| 202 code ^= 19 * owner.hashCode; | 202 code ^= 19 * owner.hashCode; |
| 203 return code; | 203 return code; |
| 204 } | 204 } |
| 205 | 205 |
| 206 String get _prettyName => 'TypeVariableMirror'; | 206 String get _prettyName => 'TypeVariableMirror'; |
| 207 | 207 |
| 208 TypeMirror get upperBound { | 208 TypeMirror get upperBound { |
| 209 if (_cachedUpperBound != null) return _cachedUpperBound; | 209 if (_cachedUpperBound != null) return _cachedUpperBound; |
| 210 return _cachedUpperBound = typeMirrorFromRuntimeTypeRepresentation( | 210 return _cachedUpperBound = typeMirrorFromRuntimeTypeRepresentation( |
| 211 JS('', 'init.metadata[#]', _typeVariable.bound)); | 211 owner, getMetadata(_typeVariable.bound)); |
| 212 } | 212 } |
| 213 } | 213 } |
| 214 | 214 |
| 215 class JsTypeMirror extends JsDeclarationMirror implements TypeMirror { | 215 class JsTypeMirror extends JsDeclarationMirror implements TypeMirror { |
| 216 JsTypeMirror(Symbol simpleName) | 216 JsTypeMirror(Symbol simpleName) |
| 217 : super(simpleName); | 217 : super(simpleName); |
| 218 | 218 |
| 219 String get _prettyName => 'TypeMirror'; | 219 String get _prettyName => 'TypeMirror'; |
| 220 | 220 |
| 221 DeclarationMirror get owner => null; | 221 DeclarationMirror get owner => null; |
| (...skipping 274 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 496 // Remove the angle brackets enclosing the type arguments. | 496 // Remove the angle brackets enclosing the type arguments. |
| 497 mangledName.substring(typeArgIndex + 1, mangledName.length - 1)); | 497 mangledName.substring(typeArgIndex + 1, mangledName.length - 1)); |
| 498 JsCache.update(classMirrors, mangledName, mirror); | 498 JsCache.update(classMirrors, mangledName, mirror); |
| 499 return mirror; | 499 return mirror; |
| 500 } | 500 } |
| 501 var constructorOrInterceptor = | 501 var constructorOrInterceptor = |
| 502 Primitives.getConstructorOrInterceptor(mangledName); | 502 Primitives.getConstructorOrInterceptor(mangledName); |
| 503 if (constructorOrInterceptor == null) { | 503 if (constructorOrInterceptor == null) { |
| 504 int index = JS('int|Null', 'init.functionAliases[#]', mangledName); | 504 int index = JS('int|Null', 'init.functionAliases[#]', mangledName); |
| 505 if (index != null) { | 505 if (index != null) { |
| 506 mirror = new JsTypedefMirror( | 506 mirror = new JsTypedefMirror(symbol, mangledName, getMetadata(index)); |
| 507 symbol, mangledName, JS('=Object', 'init.metadata[#]', index)); | |
| 508 JsCache.update(classMirrors, mangledName, mirror); | 507 JsCache.update(classMirrors, mangledName, mirror); |
| 509 return mirror; | 508 return mirror; |
| 510 } | 509 } |
| 511 // Probably an intercepted class. | 510 // Probably an intercepted class. |
| 512 // TODO(ahe): How to handle intercepted classes? | 511 // TODO(ahe): How to handle intercepted classes? |
| 513 throw new UnsupportedError('Cannot find class for: ${n(symbol)}'); | 512 throw new UnsupportedError('Cannot find class for: ${n(symbol)}'); |
| 514 } | 513 } |
| 515 var constructor = (constructorOrInterceptor is Interceptor) | 514 var constructor = (constructorOrInterceptor is Interceptor) |
| 516 ? JS('', '#.constructor', constructorOrInterceptor) | 515 ? JS('', '#.constructor', constructorOrInterceptor) |
| 517 : constructorOrInterceptor; | 516 : constructorOrInterceptor; |
| (...skipping 219 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 737 String mangledName = | 736 String mangledName = |
| 738 JS('String|Null', '#[#]', methodsWithOptionalArguments, '*$name'); | 737 JS('String|Null', '#[#]', methodsWithOptionalArguments, '*$name'); |
| 739 if (mangledName == null) { | 738 if (mangledName == null) { |
| 740 // TODO(ahe): Invoke noSuchMethod. | 739 // TODO(ahe): Invoke noSuchMethod. |
| 741 throw new UnimplementedNoSuchMethodError( | 740 throw new UnimplementedNoSuchMethodError( |
| 742 'Invoking noSuchMethod with named arguments not implemented'); | 741 'Invoking noSuchMethod with named arguments not implemented'); |
| 743 } | 742 } |
| 744 var defaultValueIndices = | 743 var defaultValueIndices = |
| 745 JS('List|Null', '#[#].\$defaultValues', reflectee, mangledName); | 744 JS('List|Null', '#[#].\$defaultValues', reflectee, mangledName); |
| 746 var defaultValues = | 745 var defaultValues = |
| 747 defaultValueIndices.map((int i) => JS('', 'init.metadata[#]', i)) | 746 defaultValueIndices.map((int i) => getMetadata(i)) |
| 748 .iterator; | 747 .iterator; |
| 749 var defaultArguments = new Map(); | 748 var defaultArguments = new Map(); |
| 750 reflectiveName = mangledNames[mangledName]; | 749 reflectiveName = mangledNames[mangledName]; |
| 751 var reflectiveNames = reflectiveName.split(':'); | 750 var reflectiveNames = reflectiveName.split(':'); |
| 752 int requiredPositionalArgumentCount = | 751 int requiredPositionalArgumentCount = |
| 753 int.parse(reflectiveNames.elementAt(1)); | 752 int.parse(reflectiveNames.elementAt(1)); |
| 754 positionalArguments = new List.from(positionalArguments); | 753 positionalArguments = new List.from(positionalArguments); |
| 755 // Check the number of positional arguments is valid. | 754 // Check the number of positional arguments is valid. |
| 756 if (requiredPositionalArgumentCount != positionalArguments.length) { | 755 if (requiredPositionalArgumentCount != positionalArguments.length) { |
| 757 // TODO(ahe): Invoke noSuchMethod. | 756 // TODO(ahe): Invoke noSuchMethod. |
| (...skipping 126 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 884 * If an integer is encountered as a type argument, it represents the type | 883 * If an integer is encountered as a type argument, it represents the type |
| 885 * variable at the corresponding entry in [emitter.globalMetadata]. | 884 * variable at the corresponding entry in [emitter.globalMetadata]. |
| 886 */ | 885 */ |
| 887 var _typeArguments; | 886 var _typeArguments; |
| 888 | 887 |
| 889 Map<Symbol, VariableMirror> _cachedVariables; | 888 Map<Symbol, VariableMirror> _cachedVariables; |
| 890 Map<Symbol, MethodMirror> _cachedGetters; | 889 Map<Symbol, MethodMirror> _cachedGetters; |
| 891 Map<Symbol, MethodMirror> _cachedSetters; | 890 Map<Symbol, MethodMirror> _cachedSetters; |
| 892 Map<Symbol, MethodMirror> _cachedMethodsMap; | 891 Map<Symbol, MethodMirror> _cachedMethodsMap; |
| 893 List<JsMethodMirror> _cachedMethods; | 892 List<JsMethodMirror> _cachedMethods; |
| 893 ClassMirror _superclass; | |
| 894 List<ClassMirror> _cachedSuperinterfaces; | |
| 894 | 895 |
| 895 JsTypeBoundClassMirror(JsClassMirror originalDeclaration, this._typeArguments) | 896 JsTypeBoundClassMirror(JsClassMirror originalDeclaration, this._typeArguments) |
| 896 : _class = originalDeclaration, | 897 : _class = originalDeclaration, |
| 897 super(originalDeclaration.simpleName); | 898 super(originalDeclaration.simpleName); |
| 898 | 899 |
| 899 String get _prettyName => 'ClassMirror'; | 900 String get _prettyName => 'ClassMirror'; |
| 900 | 901 |
| 901 List<TypeVariableMirror> get typeVariables => _class.typeVariables; | 902 List<TypeVariableMirror> get typeVariables => _class.typeVariables; |
| 902 | 903 |
| 903 List<TypeMirror> get typeArguments { | 904 List<TypeMirror> get typeArguments { |
| 904 if (_typeArguments is! String) return _typeArguments; | 905 if (_typeArguments is! String) return _typeArguments; |
| 905 List result = new List(); | 906 List result = new List(); |
| 906 | 907 |
| 907 addTypeArgument(String typeArgument) { | 908 addTypeArgument(String typeArgument) { |
| 908 int parsedIndex = int.parse(typeArgument, onError: (_) => -1); | 909 int parsedIndex = int.parse(typeArgument, onError: (_) => -1); |
| 909 if (parsedIndex == -1) { | 910 if (parsedIndex == -1) { |
| 910 result.add(reflectClassByMangledName(typeArgument.trim())); | 911 result.add(reflectClassByMangledName(typeArgument.trim())); |
| 911 } else { | 912 } else { |
| 912 TypeVariable typeVariable = JS('', 'init.metadata[#]', parsedIndex); | 913 TypeVariable typeVariable = getMetadata(parsedIndex); |
| 913 TypeMirror owner = reflectClass(typeVariable.owner); | 914 TypeMirror owner = reflectClass(typeVariable.owner); |
| 914 TypeVariableMirror typeMirror = | 915 TypeVariableMirror typeMirror = |
| 915 new JsTypeVariableMirror(typeVariable, owner); | 916 new JsTypeVariableMirror(typeVariable, owner); |
| 916 result.add(typeMirror); | 917 result.add(typeMirror); |
| 917 } | 918 } |
| 918 } | 919 } |
| 919 | 920 |
| 920 if (_typeArguments.indexOf('<') == -1) { | 921 if (_typeArguments.indexOf('<') == -1) { |
| 921 _typeArguments.split(',').forEach((t) => addTypeArgument(t)); | 922 _typeArguments.split(',').forEach((t) => addTypeArgument(t)); |
| 922 } else { | 923 } else { |
| (...skipping 83 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1006 [Map<Symbol, dynamic> namedArguments]) { | 1007 [Map<Symbol, dynamic> namedArguments]) { |
| 1007 return _class.newInstanceAsync(constructorName, | 1008 return _class.newInstanceAsync(constructorName, |
| 1008 positionalArguments, | 1009 positionalArguments, |
| 1009 namedArguments); | 1010 namedArguments); |
| 1010 } | 1011 } |
| 1011 | 1012 |
| 1012 JsLibraryMirror get owner => _class.owner; | 1013 JsLibraryMirror get owner => _class.owner; |
| 1013 | 1014 |
| 1014 List<InstanceMirror> get metadata => _class.metadata; | 1015 List<InstanceMirror> get metadata => _class.metadata; |
| 1015 | 1016 |
| 1016 ClassMirror get superclass => _class.superclass; | 1017 ClassMirror get superclass { |
| 1018 if (_superclass != null) return _superclass; | |
| 1019 | |
| 1020 List<int> typeInformation = | |
| 1021 JS('List|Null', 'init.typeInformation[#]', _class._mangledName); | |
| 1022 assert(typeInformation != null); | |
| 1023 var type = getMetadata(typeInformation[0]); | |
| 1024 return _superclass = typeMirrorFromRuntimeTypeRepresentation(this, type); | |
| 1025 } | |
| 1017 | 1026 |
| 1018 InstanceMirror invoke(Symbol memberName, | 1027 InstanceMirror invoke(Symbol memberName, |
| 1019 List positionalArguments, | 1028 List positionalArguments, |
| 1020 [Map<Symbol,dynamic> namedArguments]) { | 1029 [Map<Symbol,dynamic> namedArguments]) { |
| 1021 return _class.invoke(memberName, positionalArguments, namedArguments); | 1030 return _class.invoke(memberName, positionalArguments, namedArguments); |
| 1022 } | 1031 } |
| 1023 | 1032 |
| 1024 bool get isOriginalDeclaration => false; | 1033 bool get isOriginalDeclaration => false; |
| 1025 | 1034 |
| 1026 ClassMirror get originalDeclaration => _class; | 1035 ClassMirror get originalDeclaration => _class; |
| 1027 | 1036 |
| 1028 List<ClassMirror> get superinterfaces => _class.superinterfaces; | 1037 List<ClassMirror> get superinterfaces { |
| 1038 if (_cachedSuperinterfaces != null) return _cachedSuperinterfaces; | |
| 1039 return _cachedSuperinterfaces = _class._getSuperinterfacesWithOwner(this); | |
| 1040 } | |
| 1029 | 1041 |
| 1030 Future<InstanceMirror> getFieldAsync(Symbol fieldName) { | 1042 Future<InstanceMirror> getFieldAsync(Symbol fieldName) { |
| 1031 return _class.getFieldAsync(fieldName); | 1043 return _class.getFieldAsync(fieldName); |
| 1032 } | 1044 } |
| 1033 | 1045 |
| 1034 bool get hasReflectedType => _class.hasReflectedType; | 1046 bool get hasReflectedType => _class.hasReflectedType; |
| 1035 | 1047 |
| 1036 Future<InstanceMirror> invokeAsync(Symbol memberName, | 1048 Future<InstanceMirror> invokeAsync(Symbol memberName, |
| 1037 List positionalArguments, | 1049 List positionalArguments, |
| 1038 [Map<Symbol, dynamic> namedArguments]) { | 1050 [Map<Symbol, dynamic> namedArguments]) { |
| (...skipping 307 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1346 if (_cachedMetadata != null) return _cachedMetadata; | 1358 if (_cachedMetadata != null) return _cachedMetadata; |
| 1347 if (_metadata == null) { | 1359 if (_metadata == null) { |
| 1348 _metadata = extractMetadata(JS('', '#.prototype', _jsConstructor)); | 1360 _metadata = extractMetadata(JS('', '#.prototype', _jsConstructor)); |
| 1349 } | 1361 } |
| 1350 return _cachedMetadata = | 1362 return _cachedMetadata = |
| 1351 new UnmodifiableListView<InstanceMirror>(_metadata.map(reflect)); | 1363 new UnmodifiableListView<InstanceMirror>(_metadata.map(reflect)); |
| 1352 } | 1364 } |
| 1353 | 1365 |
| 1354 ClassMirror get superclass { | 1366 ClassMirror get superclass { |
| 1355 if (_superclass == null) { | 1367 if (_superclass == null) { |
| 1356 var superclassName = _fieldsDescriptor.split(';')[0]; | 1368 List<int> typeInformation = |
| 1357 var mixins = superclassName.split('+'); | 1369 JS('List|Null', 'init.typeInformation[#]', _mangledName); |
| 1358 if (mixins.length > 1) { | 1370 if (typeInformation != null) { |
| 1359 if (mixins.length != 2) { | 1371 var type = getMetadata(typeInformation[0]); |
| 1360 throw new RuntimeError('Strange mixin: $_fieldsDescriptor'); | 1372 _superclass = typeMirrorFromRuntimeTypeRepresentation(this, type); |
| 1361 } | |
| 1362 _superclass = reflectClassByMangledName(mixins[0]); | |
| 1363 } else { | 1373 } else { |
| 1364 // Use _superclass == this to represent class with no superclass (Object ). | 1374 // Use _superclass == this to represent class with no superclass |
| 1365 _superclass = (superclassName == '') | 1375 // (Object). |
| 1366 ? this : reflectClassByMangledName(superclassName); | 1376 _superclass = this; |
| 1367 } | 1377 } |
| 1368 } | 1378 } |
| 1369 return _superclass == this ? null : _superclass; | 1379 return _superclass == this ? null : _superclass; |
| 1370 } | 1380 } |
| 1371 | 1381 |
| 1372 InstanceMirror invoke(Symbol memberName, | 1382 InstanceMirror invoke(Symbol memberName, |
| 1373 List positionalArguments, | 1383 List positionalArguments, |
| 1374 [Map<Symbol,dynamic> namedArguments]) { | 1384 [Map<Symbol,dynamic> namedArguments]) { |
| 1375 // Mirror API gotcha: Calling [invoke] on a ClassMirror means invoke a | 1385 // Mirror API gotcha: Calling [invoke] on a ClassMirror means invoke a |
| 1376 // static method. | 1386 // static method. |
| (...skipping 10 matching lines...) Expand all Loading... | |
| 1387 if (!mirror.canInvokeReflectively()) { | 1397 if (!mirror.canInvokeReflectively()) { |
| 1388 throwInvalidReflectionError(n(memberName)); | 1398 throwInvalidReflectionError(n(memberName)); |
| 1389 } | 1399 } |
| 1390 return reflect(mirror._invoke(positionalArguments, namedArguments)); | 1400 return reflect(mirror._invoke(positionalArguments, namedArguments)); |
| 1391 } | 1401 } |
| 1392 | 1402 |
| 1393 bool get isOriginalDeclaration => true; | 1403 bool get isOriginalDeclaration => true; |
| 1394 | 1404 |
| 1395 ClassMirror get originalDeclaration => this; | 1405 ClassMirror get originalDeclaration => this; |
| 1396 | 1406 |
| 1407 List<ClassMirror> _getSuperinterfacesWithOwner(DeclarationMirror owner) { | |
| 1408 List<int> typeInformation = | |
| 1409 JS('List|Null', 'init.typeInformation[#]', _mangledName); | |
| 1410 List<ClassMirror> result = const <ClassMirror>[]; | |
| 1411 if (typeInformation != null) { | |
| 1412 ClassMirror lookupType(int i) { | |
| 1413 var type = getMetadata(i); | |
| 1414 return typeMirrorFromRuntimeTypeRepresentation(owner, type); | |
| 1415 } | |
| 1416 | |
| 1417 //We skip the first since it is the supertype. | |
| 1418 result = typeInformation.skip(1).map(lookupType).toList(); | |
| 1419 } | |
| 1420 | |
| 1421 return new UnmodifiableListView<ClassMirror>(result); | |
| 1422 } | |
| 1423 | |
| 1397 List<ClassMirror> get superinterfaces { | 1424 List<ClassMirror> get superinterfaces { |
| 1398 if (_cachedSuperinterfaces != null) return _cachedSuperinterfaces; | 1425 if (_cachedSuperinterfaces != null) return _cachedSuperinterfaces; |
| 1399 List<int> interfaces = JS('List|Null', 'init.interfaces[#]', _mangledName); | 1426 return _cachedSuperinterfaces = _getSuperinterfacesWithOwner(this); |
| 1400 var result = const []; | |
| 1401 if (interfaces != null) { | |
| 1402 ClassMirror lookupType(int i) { | |
| 1403 var type = JS('=Object', 'init.metadata[#]', i); | |
| 1404 return typeMirrorFromRuntimeTypeRepresentation(type); | |
| 1405 } | |
| 1406 result = interfaces.map(lookupType).toList(); | |
| 1407 } | |
| 1408 return _cachedSuperinterfaces = | |
| 1409 new UnmodifiableListView<ClassMirror>(result); | |
| 1410 } | 1427 } |
| 1411 | 1428 |
| 1412 List<TypeVariableMirror> get typeVariables { | 1429 List<TypeVariableMirror> get typeVariables { |
| 1413 if (_cachedTypeVariables != null) return _cachedTypeVariables; | 1430 if (_cachedTypeVariables != null) return _cachedTypeVariables; |
| 1414 List result = new List(); | 1431 List result = new List(); |
| 1415 List typeVariables = | 1432 List typeVariables = |
| 1416 JS('JSExtendableArray|Null', '#.prototype["<>"]', _jsConstructor); | 1433 JS('JSExtendableArray|Null', '#.prototype["<>"]', _jsConstructor); |
| 1417 if (typeVariables == null) return result; | 1434 if (typeVariables == null) return result; |
| 1418 for (int i = 0; i < typeVariables.length; i++) { | 1435 for (int i = 0; i < typeVariables.length; i++) { |
| 1419 TypeVariable typeVariable = JS('', 'init.metadata[#]', typeVariables[i]); | 1436 TypeVariable typeVariable = getMetadata(typeVariables[i]); |
| 1420 result.add(new JsTypeVariableMirror(typeVariable, this)); | 1437 result.add(new JsTypeVariableMirror(typeVariable, this)); |
| 1421 } | 1438 } |
| 1422 return _cachedTypeVariables = new UnmodifiableListView(result); | 1439 return _cachedTypeVariables = new UnmodifiableListView(result); |
| 1423 } | 1440 } |
| 1424 | 1441 |
| 1425 List<TypeMirror> get typeArguments => new List(); | 1442 List<TypeMirror> get typeArguments => new List(); |
| 1426 } | 1443 } |
| 1427 | 1444 |
| 1428 class JsVariableMirror extends JsDeclarationMirror implements VariableMirror { | 1445 class JsVariableMirror extends JsDeclarationMirror implements VariableMirror { |
| 1429 static final int REFLECTION_MARKER = 45; | 1446 static final int REFLECTION_MARKER = 45; |
| (...skipping 222 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1652 } | 1669 } |
| 1653 | 1670 |
| 1654 bool canInvokeReflectively() { | 1671 bool canInvokeReflectively() { |
| 1655 return hasReflectableProperty(_jsFunction); | 1672 return hasReflectableProperty(_jsFunction); |
| 1656 } | 1673 } |
| 1657 | 1674 |
| 1658 DeclarationMirror get owner => _owner; | 1675 DeclarationMirror get owner => _owner; |
| 1659 | 1676 |
| 1660 TypeMirror get returnType { | 1677 TypeMirror get returnType { |
| 1661 metadata; // Compute _returnType as a side-effect of extracting metadata. | 1678 metadata; // Compute _returnType as a side-effect of extracting metadata. |
| 1662 return computeTypeMirror(owner, _returnType); | 1679 return typeMirrorFromRuntimeTypeRepresentation(owner, _returnType); |
| 1663 } | 1680 } |
| 1664 | 1681 |
| 1665 List<InstanceMirror> get metadata { | 1682 List<InstanceMirror> get metadata { |
| 1666 if (_metadata == null) { | 1683 if (_metadata == null) { |
| 1667 var raw = extractMetadata(_jsFunction); | 1684 var raw = extractMetadata(_jsFunction); |
| 1668 var formals = new List(_parameterCount); | 1685 var formals = new List(_parameterCount); |
| 1669 if (!raw.isEmpty) { | 1686 if (!raw.isEmpty) { |
| 1670 _returnType = raw[0]; | 1687 _returnType = raw[0]; |
| 1671 int parameterLength = 1 + _parameterCount * 2; | 1688 int parameterLength = 1 + _parameterCount * 2; |
| 1672 int formalsCount = 0; | 1689 int formalsCount = 0; |
| (...skipping 78 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1751 final DeclarationMirror owner; | 1768 final DeclarationMirror owner; |
| 1752 // A JS object representing the type. | 1769 // A JS object representing the type. |
| 1753 final _type; | 1770 final _type; |
| 1754 | 1771 |
| 1755 JsParameterMirror(String unmangledName, this.owner, this._type) | 1772 JsParameterMirror(String unmangledName, this.owner, this._type) |
| 1756 : super(s(unmangledName)); | 1773 : super(s(unmangledName)); |
| 1757 | 1774 |
| 1758 String get _prettyName => 'ParameterMirror'; | 1775 String get _prettyName => 'ParameterMirror'; |
| 1759 | 1776 |
| 1760 TypeMirror get type { | 1777 TypeMirror get type { |
| 1761 return computeTypeMirror(owner, _type); | 1778 return typeMirrorFromRuntimeTypeRepresentation(owner, _type); |
| 1762 } | 1779 } |
| 1763 | 1780 |
| 1764 // Only true for static fields, never for a parameter. | 1781 // Only true for static fields, never for a parameter. |
| 1765 bool get isStatic => false; | 1782 bool get isStatic => false; |
| 1766 | 1783 |
| 1767 // TODO(ahe): Implement this. | 1784 // TODO(ahe): Implement this. |
| 1768 bool get isFinal => false; | 1785 bool get isFinal => false; |
| 1769 | 1786 |
| 1770 // TODO(ahe): Implement this. | 1787 // TODO(ahe): Implement this. |
| 1771 bool get isOptional => false; | 1788 bool get isOptional => false; |
| (...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1812 bool get _isVoid => JS('bool', '!!#.void', _typeData); | 1829 bool get _isVoid => JS('bool', '!!#.void', _typeData); |
| 1813 | 1830 |
| 1814 bool get _hasArguments => JS('bool', '"args" in #', _typeData); | 1831 bool get _hasArguments => JS('bool', '"args" in #', _typeData); |
| 1815 List get _arguments => JS('JSExtendableArray', '#.args', _typeData); | 1832 List get _arguments => JS('JSExtendableArray', '#.args', _typeData); |
| 1816 | 1833 |
| 1817 bool get _hasOptionalArguments => JS('bool', '"opt" in #', _typeData); | 1834 bool get _hasOptionalArguments => JS('bool', '"opt" in #', _typeData); |
| 1818 List get _optionalArguments => JS('JSExtendableArray', '#.opt', _typeData); | 1835 List get _optionalArguments => JS('JSExtendableArray', '#.opt', _typeData); |
| 1819 | 1836 |
| 1820 bool get _hasNamedArguments => JS('bool', '"named" in #', _typeData); | 1837 bool get _hasNamedArguments => JS('bool', '"named" in #', _typeData); |
| 1821 get _namedArguments => JS('=Object', '#.named', _typeData); | 1838 get _namedArguments => JS('=Object', '#.named', _typeData); |
| 1839 bool get isOriginalDeclaration => true; | |
| 1822 | 1840 |
| 1823 TypeMirror get returnType { | 1841 TypeMirror get returnType { |
| 1824 if (_cachedReturnType != null) return _cachedReturnType; | 1842 if (_cachedReturnType != null) return _cachedReturnType; |
| 1825 if (_isVoid) return _cachedReturnType = JsMirrorSystem._voidType; | 1843 if (_isVoid) return _cachedReturnType = JsMirrorSystem._voidType; |
| 1826 if (!_hasReturnType) return _cachedReturnType = JsMirrorSystem._dynamicType; | 1844 if (!_hasReturnType) return _cachedReturnType = JsMirrorSystem._dynamicType; |
| 1827 return _cachedReturnType = | 1845 return _cachedReturnType = |
| 1828 typeMirrorFromRuntimeTypeRepresentation(_returnType); | 1846 typeMirrorFromRuntimeTypeRepresentation(this, _returnType); |
| 1829 } | 1847 } |
| 1830 | 1848 |
| 1831 List<ParameterMirror> get parameters { | 1849 List<ParameterMirror> get parameters { |
| 1832 if (_cachedParameters != null) return _cachedParameters; | 1850 if (_cachedParameters != null) return _cachedParameters; |
| 1833 List result = []; | 1851 List result = []; |
| 1834 int parameterCount = 0; | 1852 int parameterCount = 0; |
| 1835 if (_hasArguments) { | 1853 if (_hasArguments) { |
| 1836 for (var type in _arguments) { | 1854 for (var type in _arguments) { |
| 1837 result.add( | 1855 result.add( |
| 1838 new JsParameterMirror('argument${parameterCount++}', this, type)); | 1856 new JsParameterMirror('argument${parameterCount++}', this, type)); |
| (...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1891 s += 'void'; | 1909 s += 'void'; |
| 1892 } else if (_hasReturnType) { | 1910 } else if (_hasReturnType) { |
| 1893 s += runtimeTypeToString(_returnType); | 1911 s += runtimeTypeToString(_returnType); |
| 1894 } else { | 1912 } else { |
| 1895 s += 'dynamic'; | 1913 s += 'dynamic'; |
| 1896 } | 1914 } |
| 1897 return _cachedToString = "$s'"; | 1915 return _cachedToString = "$s'"; |
| 1898 } | 1916 } |
| 1899 } | 1917 } |
| 1900 | 1918 |
| 1901 TypeMirror typeMirrorFromRuntimeTypeRepresentation(type) { | 1919 int findTypeVariableIndex(List<TypeVariableMirror> typeVariables, String name) { |
| 1902 if (type == null) return JsMirrorSystem._dynamicType; | 1920 for (int i = 0; i < typeVariables.length; i++) { |
| 1903 String representation = runtimeTypeToString(type); | 1921 if (typeVariables[i].simpleName == s(name)) { |
| 1904 if (representation == null) return reflectClass(Function); | 1922 return i; |
| 1905 return reflectType(createRuntimeType(representation)); | 1923 } |
| 1924 } | |
| 1925 throw new ArgumentError('Type variable not present in list.'); | |
| 1906 } | 1926 } |
| 1907 | 1927 |
| 1908 TypeMirror computeTypeMirror(DeclarationMirror owner, var type) { | 1928 getMetadata(int index) => JS('', 'init.metadata[#]', index); |
| 1909 if (type is! int) { | 1929 |
| 1910 return typeMirrorFromRuntimeTypeRepresentation(type); | 1930 TypeMirror typeMirrorFromRuntimeTypeRepresentation( |
| 1911 } | 1931 DeclarationMirror owner, |
| 1912 | 1932 var /*int|List|JsFunction*/ type) { |
| 1913 ClassMirror ownerClass; | 1933 ClassMirror ownerClass; |
| 1914 DeclarationMirror context = owner; | 1934 DeclarationMirror context = owner; |
| 1915 while(context != null) { | 1935 while(context != null) { |
| 1916 if (context is ClassMirror) { | 1936 if (context is ClassMirror) { |
| 1917 ownerClass = context; | 1937 ownerClass = context; |
| 1918 break; | 1938 break; |
| 1919 } | 1939 } |
| 1920 context = context.owner; | 1940 context = context.owner; |
| 1921 } | 1941 } |
| 1922 | 1942 assert(ownerClass != null); |
| 1923 TypeVariable typeVariable = JS('', 'init.metadata[#]', type); | 1943 |
| 1924 Symbol name = new Symbol(typeVariable.name); | 1944 if (type == null){ |
| 1925 List<TypeVariableMirror> typeVariables = ownerClass.typeVariables; | 1945 return JsMirrorSystem._dynamicType; |
| 1926 for (int i = 0; i < typeVariables.length; i++) { | 1946 } else if (ownerClass.isOriginalDeclaration) { |
| 1927 if (typeVariables[i].simpleName == name) { | 1947 if (type is int) { |
| 1928 if (ownerClass.isOriginalDeclaration) { | 1948 // [type] represents a type variable so in the context of an original |
| 1929 return typeVariables[i]; | 1949 // declaration the corresponding type variable should be returned. |
| 1930 } else { | 1950 TypeVariable typeVariable = getMetadata(type); |
| 1931 return ownerClass.typeArguments[i]; | 1951 List<TypeVariableMirror> typeVariables = ownerClass.typeVariables; |
| 1952 int variableIndex = findTypeVariableIndex(typeVariables, typeVariable.name ); | |
|
Johnni Winther
2013/10/30 11:53:43
Long line.
zarah
2013/10/30 15:01:36
Done.
| |
| 1953 return typeVariables[variableIndex]; | |
| 1954 } else { | |
| 1955 // Nested type variables will be retrieved lazily (the integer | |
| 1956 // representation is kept in the string) so they are not processd here. | |
| 1957 String representation = runtimeTypeToString(type); | |
| 1958 if (representation != null) { | |
| 1959 return reflectType(createRuntimeType(representation)); | |
| 1932 } | 1960 } |
| 1933 } | 1961 } |
| 1962 } else { | |
| 1963 String substituteTypeVariable(int index) { | |
| 1964 TypeVariable typeVariable = getMetadata(index); | |
| 1965 int variableIndex = | |
| 1966 findTypeVariableIndex(ownerClass.typeVariables, typeVariable.name); | |
| 1967 return n(ownerClass.typeArguments[variableIndex].simpleName); | |
| 1968 } | |
| 1969 | |
| 1970 String representation = | |
| 1971 runtimeTypeToString(type, onTypeVariable: substituteTypeVariable); | |
| 1972 if (representation != null) { | |
| 1973 return reflectType(createRuntimeType(representation)); | |
| 1974 } | |
| 1934 } | 1975 } |
| 1976 return reflectClass(Function); | |
| 1935 } | 1977 } |
| 1936 | 1978 |
| 1937 Symbol computeQualifiedName(DeclarationMirror owner, Symbol simpleName) { | 1979 Symbol computeQualifiedName(DeclarationMirror owner, Symbol simpleName) { |
| 1938 if (owner == null) return simpleName; | 1980 if (owner == null) return simpleName; |
| 1939 String ownerName = n(owner.qualifiedName); | 1981 String ownerName = n(owner.qualifiedName); |
| 1940 return s('$ownerName.${n(simpleName)}'); | 1982 return s('$ownerName.${n(simpleName)}'); |
| 1941 } | 1983 } |
| 1942 | 1984 |
| 1943 List extractMetadata(victim) { | 1985 List extractMetadata(victim) { |
| 1944 preserveMetadata(); | 1986 preserveMetadata(); |
| 1945 var metadataFunction = JS('', '#["@"]', victim); | 1987 var metadataFunction = JS('', '#["@"]', victim); |
| 1946 if (metadataFunction != null) return JS('', '#()', metadataFunction); | 1988 if (metadataFunction != null) return JS('', '#()', metadataFunction); |
| 1947 if (JS('String', 'typeof #', victim) != 'function') return const []; | 1989 if (JS('String', 'typeof #', victim) != 'function') return const []; |
| 1948 String source = JS('String', 'Function.prototype.toString.call(#)', victim); | 1990 String source = JS('String', 'Function.prototype.toString.call(#)', victim); |
| 1949 int index = source.lastIndexOf(new RegExp('"[0-9,]*";?[ \n\r]*}')); | 1991 int index = source.lastIndexOf(new RegExp('"[0-9,]*";?[ \n\r]*}')); |
| 1950 if (index == -1) return const []; | 1992 if (index == -1) return const []; |
| 1951 index++; | 1993 index++; |
| 1952 int endQuote = source.indexOf('"', index); | 1994 int endQuote = source.indexOf('"', index); |
| 1953 return source.substring(index, endQuote).split(',').map(int.parse).map( | 1995 return source.substring(index, endQuote).split(',').map(int.parse).map( |
| 1954 (int i) => JS('', 'init.metadata[#]', i)).toList(); | 1996 (int i) => getMetadata(i)).toList(); |
| 1955 } | 1997 } |
| 1956 | 1998 |
| 1957 List<JsVariableMirror> parseCompactFieldSpecification( | 1999 List<JsVariableMirror> parseCompactFieldSpecification( |
| 1958 JsDeclarationMirror owner, | 2000 JsDeclarationMirror owner, |
| 1959 fieldSpecification, | 2001 fieldSpecification, |
| 1960 bool isStatic, | 2002 bool isStatic, |
| 1961 List<Mirror> result) { | 2003 List<Mirror> result) { |
| 1962 List fieldsMetadata = null; | 2004 List fieldsMetadata = null; |
| 1963 List<String> fieldNames; | 2005 List<String> fieldNames; |
| 1964 if (fieldSpecification is List) { | 2006 if (fieldSpecification is List) { |
| (...skipping 101 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 2066 | 2108 |
| 2067 // TODO(ahe): Remove this class and call noSuchMethod instead. | 2109 // TODO(ahe): Remove this class and call noSuchMethod instead. |
| 2068 class UnimplementedNoSuchMethodError extends Error | 2110 class UnimplementedNoSuchMethodError extends Error |
| 2069 implements NoSuchMethodError { | 2111 implements NoSuchMethodError { |
| 2070 final String _message; | 2112 final String _message; |
| 2071 | 2113 |
| 2072 UnimplementedNoSuchMethodError(this._message); | 2114 UnimplementedNoSuchMethodError(this._message); |
| 2073 | 2115 |
| 2074 String toString() => "Unsupported operation: $_message"; | 2116 String toString() => "Unsupported operation: $_message"; |
| 2075 } | 2117 } |
| OLD | NEW |