| Index: dart/sdk/lib/_internal/lib/js_mirrors.dart
|
| diff --git a/dart/sdk/lib/_internal/lib/js_mirrors.dart b/dart/sdk/lib/_internal/lib/js_mirrors.dart
|
| index d904246e83bd5d07c6b33bbd59621603d25480eb..5598048440d5ef2fc04c5bf8c068b38ae8b37816 100644
|
| --- a/dart/sdk/lib/_internal/lib/js_mirrors.dart
|
| +++ b/dart/sdk/lib/_internal/lib/js_mirrors.dart
|
| @@ -16,7 +16,9 @@ import 'dart:_js_helper' show
|
| Null,
|
| Primitives,
|
| RuntimeError,
|
| - createUnmangledInvocationMirror;
|
| + createRuntimeType,
|
| + createUnmangledInvocationMirror,
|
| + runtimeTypeToString;
|
| import 'dart:_interceptors' show Interceptor, JSExtendableArray;
|
| import 'dart:_js_names';
|
|
|
| @@ -93,6 +95,8 @@ abstract class JsDeclarationMirror extends JsMirror
|
|
|
| const JsDeclarationMirror(this.simpleName);
|
|
|
| + Symbol get qualifiedName => computeQualifiedName(owner, simpleName);
|
| +
|
| bool get isPrivate => n(simpleName).startsWith('_');
|
|
|
| bool get isTopLevel => owner != null && owner is LibraryMirror;
|
| @@ -105,6 +109,11 @@ class JsTypeMirror extends JsDeclarationMirror implements TypeMirror {
|
| : super(simpleName);
|
|
|
| String get _prettyName => 'TypeMirror';
|
| +
|
| + DeclarationMirror get owner => null;
|
| +
|
| + // TODO(ahe): Doesn't match the specification, see http://dartbug.com/11569.
|
| + bool get isTopLevel => true;
|
| }
|
|
|
| class JsLibraryMirror extends JsDeclarationMirror with JsObjectMirror
|
| @@ -152,26 +161,20 @@ class JsLibraryMirror extends JsDeclarationMirror with JsObjectMirror
|
| var result = new List<JsMethodMirror>(_functions.length);
|
| for (int i = 0; i < _functions.length; i++) {
|
| String name = _functions[i];
|
| + // TODO(ahe): Create accessor for accessing $. It is also
|
| + // used in js_helper.
|
| + var jsFunction = JS('', '#[#]', JS_CURRENT_ISOLATE(), name);
|
| String unmangledName = mangledGlobalNames[name];
|
| if (unmangledName == null) unmangledName = name;
|
| - int parameterCount = null; // TODO(ahe): Compute this.
|
| - bool isSetter = false; // TODO(ahe): Compute this.
|
| - bool isGetter = false; // TODO(ahe): Compute this.
|
| bool isConstructor = unmangledName.startsWith('new ');
|
| - bool isStatic = true && !isConstructor; // Top-level functions are
|
| - // static, but constructors are
|
| - // not.
|
| + bool isStatic = !isConstructor; // Top-level functions are static, but
|
| + // constructors are not.
|
| if (isConstructor) {
|
| unmangledName = unmangledName.substring(4).replaceAll(r'$', '.');
|
| }
|
| - unmangledName = unmangledName.split(':')[0];
|
| - Symbol symbol = s(unmangledName);
|
| JsMethodMirror mirror =
|
| - // TODO(ahe): Create accessor for accessing $. It is also
|
| - // used in js_helper.
|
| - new JsMethodMirror(
|
| - symbol, JS('', '#[#]', JS_CURRENT_ISOLATE(), name),
|
| - parameterCount, isGetter, isSetter, isStatic, isConstructor);
|
| + new JsMethodMirror.fromUnmangledName(
|
| + unmangledName, jsFunction, isStatic, isConstructor);
|
| result[i] = mirror;
|
| mirror._owner = this;
|
| }
|
| @@ -387,8 +390,6 @@ class JsClassMirror extends JsTypeMirror with JsObjectMirror
|
|
|
| String get _prettyName => 'ClassMirror';
|
|
|
| - Symbol get qualifiedName => computeQualifiedName(owner, simpleName);
|
| -
|
| get _jsConstructor {
|
| if (_jsConstructorOrInterceptor is Interceptor) {
|
| return JS('', '#.constructor', _jsConstructorOrInterceptor);
|
| @@ -400,8 +401,7 @@ class JsClassMirror extends JsTypeMirror with JsObjectMirror
|
| Map<Symbol, MethodMirror> get constructors {
|
| Map<Symbol, MethodMirror> result = new Map<Symbol, MethodMirror>();
|
| JsLibraryMirror library = owner;
|
| - String unmangledName = mangledGlobalNames[n(simpleName)];
|
| - if (unmangledName == null) unmangledName = n(simpleName);
|
| + String unmangledName = n(simpleName);
|
| for (JsMethodMirror mirror in library._functionMirrors) {
|
| Symbol name = mirror.simpleName;
|
| if (mirror.isConstructor
|
| @@ -428,7 +428,9 @@ class JsClassMirror extends JsTypeMirror with JsObjectMirror
|
| // reflection with metadata.
|
| if (simpleName == null) continue;
|
| var function = JS('', '#[#]', prototype, key);
|
| - var mirror = new JsMethodMirror.fromUnmangledName(simpleName, function);
|
| + var mirror =
|
| + new JsMethodMirror.fromUnmangledName(
|
| + simpleName, function, false, false);
|
| result.add(mirror);
|
| mirror._owner = this;
|
| }
|
| @@ -636,8 +638,6 @@ class JsVariableMirror extends JsDeclarationMirror implements VariableMirror {
|
|
|
| DeclarationMirror get owner => _owner;
|
|
|
| - Symbol get qualifiedName => computeQualifiedName(owner, simpleName);
|
| -
|
| List<InstanceMirror> get metadata {
|
| preserveMetadata();
|
| if (_metadata == null) {
|
| @@ -714,6 +714,8 @@ class JsMethodMirror extends JsDeclarationMirror implements MethodMirror {
|
| final bool isConstructor;
|
| DeclarationMirror _owner;
|
| List _metadata;
|
| + var _returnType;
|
| + var _parameters;
|
|
|
| JsMethodMirror(Symbol simpleName,
|
| this._jsFunction,
|
| @@ -724,7 +726,10 @@ class JsMethodMirror extends JsDeclarationMirror implements MethodMirror {
|
| this.isConstructor)
|
| : super(simpleName);
|
|
|
| - factory JsMethodMirror.fromUnmangledName(String name, jsFunction) {
|
| + factory JsMethodMirror.fromUnmangledName(String name,
|
| + jsFunction,
|
| + bool isStatic,
|
| + bool isConstructor) {
|
| List<String> info = name.split(':');
|
| name = info[0];
|
| bool isSetter = name.endsWith('=');
|
| @@ -744,31 +749,79 @@ class JsMethodMirror extends JsDeclarationMirror implements MethodMirror {
|
| }
|
| return new JsMethodMirror(
|
| s(name), jsFunction, requiredParameterCount + optionalParameterCount,
|
| - isGetter, isSetter, false, false);
|
| + isGetter, isSetter, isStatic, isConstructor);
|
| }
|
|
|
| String get _prettyName => 'MethodMirror';
|
|
|
| List<ParameterMirror> get parameters {
|
| - // TODO(ahe): Fill the list with parameter mirrors.
|
| - return new List<ParameterMirror>(_parameterCount);
|
| + metadata; // Compute _parameters as a side-effect of extracting metadata.
|
| + return new List<ParameterMirror>.from(_parameters);
|
| }
|
|
|
| DeclarationMirror get owner => _owner;
|
|
|
| - Symbol get qualifiedName => computeQualifiedName(owner, simpleName);
|
| -
|
| - // TODO(ahe): Improve this information and test it.
|
| - TypeMirror get returnType => JsMirrorSystem._dynamicType;
|
| + TypeMirror get returnType {
|
| + metadata; // Compute _returnType as a side-effect of extracting metadata.
|
| + return typeMirrorFromRuntimeTypeRepresentation(_returnType);
|
| + }
|
|
|
| List<InstanceMirror> get metadata {
|
| if (_metadata == null) {
|
| - _metadata = extractMetadata(_jsFunction);
|
| + var raw = extractMetadata(_jsFunction);
|
| + _returnType = raw[0];
|
| + int parameterLength = 1 + _parameterCount * 2;
|
| + var formals = new List<ParameterMirror>(_parameterCount);
|
| + int formalsCount = 0;
|
| + for (int i = 1; i < parameterLength; i += 2) {
|
| + var name = raw[i];
|
| + var type = raw[i + 1];
|
| + formals[formalsCount++] = new JsParameterMirror(name, this, type);
|
| + }
|
| + _parameters = formals;
|
| + _metadata = raw.sublist(parameterLength);
|
| }
|
| return _metadata.map(reflect).toList();
|
| }
|
| }
|
|
|
| +class JsParameterMirror extends JsDeclarationMirror implements ParameterMirror {
|
| + final JsMethodMirror owner;
|
| + // A JS object representing the type.
|
| + final _type;
|
| +
|
| + JsParameterMirror(String unmangledName, this.owner, this._type)
|
| + : super(s(unmangledName));
|
| +
|
| + String get _prettyName => 'ParameterMirror';
|
| +
|
| + TypeMirror get type => typeMirrorFromRuntimeTypeRepresentation(_type);
|
| +
|
| + bool get isStatic => owner.isStatic;
|
| +
|
| + // TODO(ahe): Implement this.
|
| + bool get isFinal => false;
|
| +
|
| + // TODO(ahe): Implement this.
|
| + bool get isOptional => false;
|
| +
|
| + // TODO(ahe): Implement this.
|
| + bool get isNamed => false;
|
| +
|
| + // TODO(ahe): Implement this.
|
| + bool get hasDefaultValue => false;
|
| +
|
| + // TODO(ahe): Implement this.
|
| + get defaultValue => null;
|
| +}
|
| +
|
| +TypeMirror typeMirrorFromRuntimeTypeRepresentation(type) {
|
| + if (type == null) return JsMirrorSystem._dynamicType;
|
| + String representation = runtimeTypeToString(type);
|
| + if (representation == null) return reflectClass(Function);
|
| + return reflectClass(createRuntimeType(representation));
|
| +}
|
| +
|
| Symbol computeQualifiedName(DeclarationMirror owner, Symbol simpleName) {
|
| if (owner == null) return simpleName;
|
| String ownerName = n(owner.qualifiedName);
|
| @@ -779,6 +832,12 @@ Symbol computeQualifiedName(DeclarationMirror owner, Symbol simpleName) {
|
| List extractMetadata(victim) {
|
| preserveMetadata();
|
| var metadataFunction = JS('', '#["@"]', victim);
|
| - return (metadataFunction == null)
|
| - ? const [] : JS('', '#()', metadataFunction);
|
| + if (metadataFunction != null) return JS('', '#()', metadataFunction);
|
| + String source = JS('String', 'Function.prototype.toString.call(#)', victim);
|
| + int index = source.lastIndexOf(new RegExp('"[0-9,]*";?[ \n\r]*}'));
|
| + if (index == -1) return const [];
|
| + index++;
|
| + int endQuote = source.indexOf('"', index);
|
| + return source.substring(index, endQuote).split(',').map(int.parse).map(
|
| + (int i) => JS('', 'init.metadata[#]', i)).toList();
|
| }
|
|
|