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

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

Issue 19391004: Implement reflective access to static methods. (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge
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
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:mirrors'; 8 import 'dart:mirrors';
9 9
10 import 'dart:_foreign_helper' show JS, JS_CURRENT_ISOLATE; 10 import 'dart:_foreign_helper' show JS, JS_CURRENT_ISOLATE;
(...skipping 289 matching lines...) Expand 10 before | Expand all | Expand 10 after
300 } 300 }
301 if (fields is! String) { 301 if (fields is! String) {
302 // TODO(ahe): This is CSP mode. Find a way to determine the 302 // TODO(ahe): This is CSP mode. Find a way to determine the
303 // fields of this class. 303 // fields of this class.
304 fields = ''; 304 fields = '';
305 } 305 }
306 } 306 }
307 var mirror = classMirrors[constructorOrInterceptor]; 307 var mirror = classMirrors[constructorOrInterceptor];
308 if (mirror == null) { 308 if (mirror == null) {
309 mirror = new JsClassMirror( 309 mirror = new JsClassMirror(
310 symbol, constructorOrInterceptor, fields, fieldsMetadata); 310 symbol, mangledName, constructorOrInterceptor, fields, fieldsMetadata);
311 classMirrors[constructorOrInterceptor] = mirror; 311 classMirrors[constructorOrInterceptor] = mirror;
312 } 312 }
313 return mirror; 313 return mirror;
314 } 314 }
315 315
316 abstract class JsObjectMirror implements ObjectMirror { 316 abstract class JsObjectMirror implements ObjectMirror {
317 Future<InstanceMirror> setFieldAsync(Symbol fieldName, Object value) { 317 Future<InstanceMirror> setFieldAsync(Symbol fieldName, Object value) {
318 return new Future<InstanceMirror>(() => this.setField(fieldName, value)); 318 return new Future<InstanceMirror>(() => this.setField(fieldName, value));
319 } 319 }
320 320
(...skipping 74 matching lines...) Expand 10 before | Expand all | Expand 10 after
395 } 395 }
396 396
397 String toString() => 'InstanceMirror on ${Error.safeToString(reflectee)}'; 397 String toString() => 'InstanceMirror on ${Error.safeToString(reflectee)}';
398 398
399 // TODO(ahe): Remove this method from the API. 399 // TODO(ahe): Remove this method from the API.
400 MirrorSystem get mirrors => currentJsMirrorSystem; 400 MirrorSystem get mirrors => currentJsMirrorSystem;
401 } 401 }
402 402
403 class JsClassMirror extends JsTypeMirror with JsObjectMirror 403 class JsClassMirror extends JsTypeMirror with JsObjectMirror
404 implements ClassMirror { 404 implements ClassMirror {
405 final String _mangledName;
405 final _jsConstructorOrInterceptor; 406 final _jsConstructorOrInterceptor;
406 final String _fields; 407 final String _fields;
407 final List _fieldsMetadata; 408 final List _fieldsMetadata;
408 List _metadata; 409 List _metadata;
409 JsClassMirror _superclass; 410 JsClassMirror _superclass;
410 List<JsMethodMirror> _cachedMethods; 411 List<JsMethodMirror> _cachedMethods;
411 412
412 // Set as side-effect of accessing JsLibraryMirror.classes. 413 // Set as side-effect of accessing JsLibraryMirror.classes.
413 JsLibraryMirror _owner; 414 JsLibraryMirror _owner;
414 415
415 JsClassMirror(Symbol simpleName, 416 JsClassMirror(Symbol simpleName,
417 this._mangledName,
416 this._jsConstructorOrInterceptor, 418 this._jsConstructorOrInterceptor,
417 this._fields, 419 this._fields,
418 this._fieldsMetadata) 420 this._fieldsMetadata)
419 : super(simpleName); 421 : super(simpleName);
420 422
421 String get _prettyName => 'ClassMirror'; 423 String get _prettyName => 'ClassMirror';
422 424
423 get _jsConstructor { 425 get _jsConstructor {
424 if (_jsConstructorOrInterceptor is Interceptor) { 426 if (_jsConstructorOrInterceptor is Interceptor) {
425 return JS('', '#.constructor', _jsConstructorOrInterceptor); 427 return JS('', '#.constructor', _jsConstructorOrInterceptor);
426 } else { 428 } else {
427 return _jsConstructorOrInterceptor; 429 return _jsConstructorOrInterceptor;
428 } 430 }
429 } 431 }
430 432
431 Map<Symbol, MethodMirror> get constructors { 433 Map<Symbol, MethodMirror> get constructors {
432 Map<Symbol, MethodMirror> result = new Map<Symbol, MethodMirror>(); 434 var result = new Map<Symbol, MethodMirror>();
433 JsLibraryMirror library = owner; 435 for (JsMethodMirror method in _methods) {
434 String unmangledName = n(simpleName); 436 if (method.isConstructor) {
435 for (JsMethodMirror mirror in library._functionMirrors) { 437 result[method.simpleName] = method;
436 Symbol name = mirror.simpleName;
437 if (mirror.isConstructor
438 && (name == simpleName || n(name).startsWith('$unmangledName.'))) {
439 result[name] = mirror;
440 mirror._owner = this;
441 } 438 }
442 } 439 }
443 return result; 440 return result;
444 } 441 }
445 442
446 List<JsMethodMirror> get _methods { 443 List<JsMethodMirror> get _methods {
447 if (_cachedMethods != null) return _cachedMethods; 444 if (_cachedMethods != null) return _cachedMethods;
448 var prototype = JS('', '#.prototype', _jsConstructor); 445 var prototype = JS('', '#.prototype', _jsConstructor);
449 List<String> keys = extractKeys(prototype); 446 List<String> keys = extractKeys(prototype);
450 var result = <JsMethodMirror>[]; 447 var result = <JsMethodMirror>[];
451 for (String key in keys) { 448 for (String key in keys) {
452 if (key == '') continue; 449 if (key == '') continue;
453 String simpleName = mangledNames[key]; 450 String simpleName = mangledNames[key];
454 // [simpleName] can be null if [key] represents an implementation 451 // [simpleName] can be null if [key] represents an implementation
455 // detail, for example, a bailout method, or runtime type support. 452 // detail, for example, a bailout method, or runtime type support.
456 // It might also be null if the user has limited what is reified for 453 // It might also be null if the user has limited what is reified for
457 // reflection with metadata. 454 // reflection with metadata.
458 if (simpleName == null) continue; 455 if (simpleName == null) continue;
459 var function = JS('', '#[#]', prototype, key); 456 var function = JS('', '#[#]', prototype, key);
460 var mirror = 457 var mirror =
461 new JsMethodMirror.fromUnmangledName( 458 new JsMethodMirror.fromUnmangledName(
462 simpleName, function, false, false); 459 simpleName, function, false, false);
463 result.add(mirror); 460 result.add(mirror);
464 mirror._owner = this; 461 mirror._owner = this;
465 } 462 }
463
464 keys = extractKeys(JS('', 'init.statics[#]', _mangledName));
465 int length = keys.length;
466 for (int i = 0; i < length; i++) {
467 String mangledName = keys[i];
468 String unmangledName = mangledName;
469 // TODO(ahe): Create accessor for accessing $. It is also
470 // used in js_helper.
471 var jsFunction = JS('', '#[#]', JS_CURRENT_ISOLATE(), mangledName);
472
473 bool isConstructor = false;
474 if (i + 1 < length) {
475 String reflectionName = keys[i + 1];
476 if (reflectionName.startsWith('+')) {
477 i++;
478 reflectionName = reflectionName.substring(1);
479 isConstructor = reflectionName.startsWith('new ');
480 if (isConstructor) {
481 reflectionName = reflectionName.substring(4).replaceAll(r'$', '.');
482 }
483 }
484 unmangledName = reflectionName;
485 }
486 bool isStatic = !isConstructor; // Constructors are not static.
487 JsMethodMirror mirror =
488 new JsMethodMirror.fromUnmangledName(
489 unmangledName, jsFunction, isStatic, isConstructor);
490 result.add(mirror);
491 mirror._owner = this;
492 }
493
466 return _cachedMethods = result; 494 return _cachedMethods = result;
467 } 495 }
468 496
469 Map<Symbol, MethodMirror> get methods { 497 Map<Symbol, MethodMirror> get methods {
470 var result = new Map<Symbol, MethodMirror>(); 498 var result = new Map<Symbol, MethodMirror>();
471 for (JsMethodMirror method in _methods) { 499 for (JsMethodMirror method in _methods) {
472 if (!method.isGetter && !method.isSetter) { 500 if (!method.isConstructor && !method.isGetter && !method.isSetter) {
473 result[method.simpleName] = method; 501 result[method.simpleName] = method;
474 } 502 }
475 } 503 }
476 return result; 504 return result;
477 } 505 }
478 506
479 Map<Symbol, MethodMirror> get getters { 507 Map<Symbol, MethodMirror> get getters {
480 // TODO(ahe): This is a hack to remove getters corresponding to a field. 508 // TODO(ahe): This is a hack to remove getters corresponding to a field.
481 var fields = variables; 509 var fields = variables;
482 510
(...skipping 447 matching lines...) Expand 10 before | Expand all | Expand 10 after
930 var metadataFunction = JS('', '#["@"]', victim); 958 var metadataFunction = JS('', '#["@"]', victim);
931 if (metadataFunction != null) return JS('', '#()', metadataFunction); 959 if (metadataFunction != null) return JS('', '#()', metadataFunction);
932 String source = JS('String', 'Function.prototype.toString.call(#)', victim); 960 String source = JS('String', 'Function.prototype.toString.call(#)', victim);
933 int index = source.lastIndexOf(new RegExp('"[0-9,]*";?[ \n\r]*}')); 961 int index = source.lastIndexOf(new RegExp('"[0-9,]*";?[ \n\r]*}'));
934 if (index == -1) return const []; 962 if (index == -1) return const [];
935 index++; 963 index++;
936 int endQuote = source.indexOf('"', index); 964 int endQuote = source.indexOf('"', index);
937 return source.substring(index, endQuote).split(',').map(int.parse).map( 965 return source.substring(index, endQuote).split(',').map(int.parse).map(
938 (int i) => JS('', 'init.metadata[#]', i)).toList(); 966 (int i) => JS('', 'init.metadata[#]', i)).toList();
939 } 967 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698