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

Unified Diff: packages/smoke/lib/mirrors.dart

Issue 2989763002: Update charted to 0.4.8 and roll (Closed)
Patch Set: Removed Cutch from list of reviewers Created 3 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 side-by-side diff with in-line comments
Download patch
« no previous file with comments | « packages/smoke/lib/codegen/recorder.dart ('k') | packages/smoke/lib/smoke.dart » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: packages/smoke/lib/mirrors.dart
diff --git a/packages/smoke/lib/mirrors.dart b/packages/smoke/lib/mirrors.dart
deleted file mode 100644
index ef018aa818b4362eb54c8b6e84baf4f710807dfc..0000000000000000000000000000000000000000
--- a/packages/smoke/lib/mirrors.dart
+++ /dev/null
@@ -1,324 +0,0 @@
-// Copyright (c) 2014, the Dart project authors. Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-/// Implementation of the smoke services using mirrors.
-library smoke.mirrors;
-
-import 'dart:mirrors';
-import 'package:smoke/smoke.dart';
-import 'package:logging/logging.dart';
-import 'src/common.dart';
-
-/// Set up the smoke package to use a mirror-based implementation. To tune what
-/// is preserved by `dart:mirrors`, use a @MirrorsUsed annotation and include
-/// 'smoke.mirrors' in your override arguments.
-useMirrors() {
- configure(new ReflectiveObjectAccessorService(),
- new ReflectiveTypeInspectorService(),
- new ReflectiveSymbolConverterService());
-}
-
-var _logger = new Logger('smoke.mirrors');
-
-/// Implements [ObjectAccessorService] using mirrors.
-class ReflectiveObjectAccessorService implements ObjectAccessorService {
- read(Object object, Symbol name) => reflect(object).getField(name).reflectee;
-
- void write(Object object, Symbol name, value) {
- reflect(object).setField(name, value);
- }
-
- invoke(receiver, Symbol methodName, List args,
- {Map namedArgs, bool adjust: false}) {
- var receiverMirror;
- var method;
- if (receiver is Type && methodName != #toString) {
- receiverMirror = reflectType(receiver);
- method = receiverMirror.declarations[methodName];
- } else {
- receiverMirror = reflect(receiver);
- method = _findMethod(receiverMirror.type, methodName);
- }
- if (method != null && adjust) {
- var required = 0;
- var optional = 0;
- for (var p in method.parameters) {
- if (p.isOptional) {
- if (!p.isNamed) optional++;
- } else {
- required++;
- }
- }
- args = adjustList(args, required, required + optional);
- }
- return receiverMirror.invoke(methodName, args, namedArgs).reflectee;
- }
-}
-
-/// Implements [TypeInspectorService] using mirrors.
-class ReflectiveTypeInspectorService implements TypeInspectorService {
- bool isSubclassOf(Type type, Type supertype) {
- if (type == supertype || supertype == Object) return true;
- // TODO(sigmund): change to mirror.isSubclassOf when it gets implemented in
- // dart2js. (dartbug.com/12439)
- var mirror = reflectClass(type);
- var top = reflectClass(supertype);
- while (mirror != _objectType) {
- mirror = _safeSuperclass(mirror);
- if (mirror == top) return true;
- }
- return false;
- }
-
- bool hasGetter(Type type, Symbol name) {
- var mirror = reflectType(type);
- if (mirror is! ClassMirror) return false;
- while (mirror != _objectType) {
- final members = mirror.declarations;
- if (members.containsKey(name)) return true;
- mirror = _safeSuperclass(mirror);
- }
- return false;
- }
-
- bool hasSetter(Type type, Symbol name) {
- var mirror = reflectType(type);
- if (mirror is! ClassMirror) return false;
- var setterName = _setterName(name);
- while (mirror != _objectType) {
- final members = mirror.declarations;
- var declaration = members[name];
- if (declaration is VariableMirror && !declaration.isFinal) return true;
- if (members.containsKey(setterName)) return true;
- mirror = _safeSuperclass(mirror);
- }
- return false;
- }
-
- bool hasInstanceMethod(Type type, Symbol name) {
- var mirror = reflectType(type);
- if (mirror is! ClassMirror) return false;
- while (mirror != _objectType) {
- final m = mirror.declarations[name];
- if (m is MethodMirror && m.isRegularMethod && !m.isStatic) return true;
- mirror = _safeSuperclass(mirror);
- }
- return false;
- }
-
- bool hasStaticMethod(Type type, Symbol name) {
- var mirror = reflectType(type);
- if (mirror is! ClassMirror) return false;
- final m = mirror.declarations[name];
- return m is MethodMirror && m.isRegularMethod && m.isStatic;
- }
-
- Declaration getDeclaration(Type type, Symbol name) {
- var mirror = reflectType(type);
- if (mirror is! ClassMirror) return null;
-
- var declaration;
- while (mirror != _objectType) {
- final members = mirror.declarations;
- if (members.containsKey(name)) {
- declaration = members[name];
- break;
- }
- mirror = _safeSuperclass(mirror);
- }
- if (declaration == null) {
- _logger.severe("declaration doesn't exists ($type.$name).");
- return null;
- }
- return new _MirrorDeclaration(mirror, declaration);
- }
-
- List<Declaration> query(Type type, QueryOptions options) {
- var mirror = reflectType(type);
- if (mirror is! ClassMirror) return null;
- return _query(mirror, options);
- }
-
- List<Declaration> _query(ClassMirror cls, QueryOptions options) {
- final visitParent = options.includeInherited && cls.superclass != null &&
- // TODO(sigmund): use _toType(cls.superclass) != options.includeUpTo
- // when dartbug.com/16925 gets fixed (_toType fails in dart2js if
- // applied to classes with type-arguments).
- cls.superclass != reflectClass(options.includeUpTo);
- var result = visitParent ? _query(cls.superclass, options) : [];
- for (var member in cls.declarations.values) {
- if (member is! VariableMirror && member is! MethodMirror) continue;
- if (member.isStatic || member.isPrivate) continue;
- var name = member.simpleName;
- if (member is VariableMirror) {
- if (!options.includeFields) continue;
- if (options.excludeFinal && member.isFinal) continue;
- }
-
- // TODO(sigmund): what if we have a setter but no getter?
- if (member is MethodMirror && member.isSetter) continue;
- if (member is MethodMirror && member.isConstructor) continue;
-
- if (member is MethodMirror && member.isGetter) {
- if (!options.includeProperties) continue;
- if (options.excludeFinal && !_hasSetter(cls, member)) continue;
- }
-
- if (member is MethodMirror && member.isRegularMethod) {
- if (!options.includeMethods) continue;
- }
-
- if (options.matches != null && !options.matches(name)) continue;
-
- var annotations = member.metadata.map((m) => m.reflectee).toList();
- if (options.withAnnotations != null &&
- !matchesAnnotation(annotations, options.withAnnotations)) {
- continue;
- }
-
- var declaration = new _MirrorDeclaration(cls, member);
-
- if (options.excludeOverriden) {
- result.retainWhere((value) => declaration.name != value.name);
- }
-
- // TODO(sigmund): should we cache parts of this declaration so we don't
- // compute them twice? For example, this chould be `new Declaration(name,
- // type, ...)` and we could reuse what we computed above to implement the
- // query filtering. Note, when I tried to eagerly compute everything, I
- // run into trouble with type (`type = _toType(member.type)`), dart2js
- // failed when the underlying types had type-arguments (see
- // dartbug.com/16925).
- result.add(declaration);
- }
-
- return result;
- }
-}
-
-/// Implements [SymbolConverterService] using mirrors.
-class ReflectiveSymbolConverterService implements SymbolConverterService {
- String symbolToName(Symbol symbol) => MirrorSystem.getName(symbol);
- Symbol nameToSymbol(String name) => new Symbol(name);
-}
-
-// TODO(jmesserly): workaround for:
-// https://code.google.com/p/dart/issues/detail?id=10029
-Symbol _setterName(Symbol getter) =>
- new Symbol('${MirrorSystem.getName(getter)}=');
-
-ClassMirror _safeSuperclass(ClassMirror type) {
- try {
- var t = type.superclass;
- // TODO(sigmund): workaround for darbug.com/17779.
- // Interceptor is leaked by dart2js. It has the same methods as Object
- // (including noSuchMethod), and our code above assumes that it doesn't
- // exist. Most queries exclude Object, so they should exclude Interceptor
- // too. We don't check for t.simpleName == #Interceptor because depending on
- // dart2js optimizations it may be #Interceptor or #num/Interceptor.
- // Checking for a private library seems to reliably filter this out.
- if (t != null && t.owner != null && t.owner.isPrivate) {
- t = _objectType;
- }
- return t;
- } on UnsupportedError catch (_) {
- // Note: dart2js throws UnsupportedError when the type is not reflectable.
- return _objectType;
- }
-}
-
-MethodMirror _findMethod(ClassMirror type, Symbol name) {
- do {
- var member = type.declarations[name];
- if (member is MethodMirror) return member;
- type = type.superclass;
- } while (type != null);
- return null;
-}
-
-// When recursively looking for symbols up the type-hierarchy it's generally a
-// good idea to stop at Object, since we know it doesn't have what we want.
-// TODO(jmesserly): This is also a workaround for what appears to be a V8
-// bug introduced between Chrome 31 and 32. After 32
-// JsClassMirror.declarations on Object calls
-// JsClassMirror.typeVariables, which tries to get the _jsConstructor's
-// .prototype["<>"]. This ends up getting the "" property instead, maybe
-// because "<>" doesn't exist, and gets ";" which then blows up because
-// the code later on expects a List of ints.
-final _objectType = reflectClass(Object);
-
-bool _hasSetter(ClassMirror cls, MethodMirror getter) {
- var mirror = cls.declarations[_setterName(getter.simpleName)];
- return mirror is MethodMirror && mirror.isSetter;
-}
-
-Type _toType(TypeMirror t) {
- // TODO(sigmund): this line can go away after dartbug.com/16962
- if (t == _objectType) return Object;
- if (t is ClassMirror) return t.reflectedType;
- if (t == null || t.qualifiedName != #dynamic) {
- _logger.warning('unknown type ($t).');
- }
- return dynamic;
-}
-
-class _MirrorDeclaration implements Declaration {
- final ClassMirror _cls;
- final _original;
-
- _MirrorDeclaration(this._cls, DeclarationMirror this._original);
-
- Symbol get name => _original.simpleName;
-
- DeclarationKind get kind => isField ? FIELD : isProperty ? PROPERTY : METHOD;
-
- bool get isField => _original is VariableMirror;
-
- bool get isProperty =>
- _original is MethodMirror && !_original.isRegularMethod;
-
- bool get isMethod => !isField && !isProperty;
-
- /// If this is a property, whether it's read only (final fields or properties
- /// with no setter).
- bool get isFinal => (_original is VariableMirror && _original.isFinal) ||
- (_original is MethodMirror &&
- _original.isGetter &&
- !_hasSetter(_cls, _original));
-
- /// If this is a property, it's declared type (including dynamic if it's not
- /// declared). For methods, the returned type.
- Type get type {
- if (_original is MethodMirror && _original.isRegularMethod) {
- return Function;
- }
- var typeMirror =
- _original is VariableMirror ? _original.type : _original.returnType;
- return _toType(typeMirror);
- }
-
- /// Whether this symbol is static.
- bool get isStatic => _original.isStatic;
-
- /// List of annotations in this declaration.
- List get annotations => _original.metadata.map((a) => a.reflectee).toList();
-
- int get hashCode => name.hashCode;
- operator ==(other) => other is Declaration &&
- name == other.name &&
- kind == other.kind &&
- isFinal == other.isFinal &&
- type == other.type &&
- isStatic == other.isStatic &&
- compareLists(annotations, other.annotations);
- String toString() => (new StringBuffer()
- ..write('(mirror-based-declaration ')
- ..write(name)
- ..write(
- isField ? ' (field) ' : (isProperty ? ' (property) ' : ' (method) '))
- ..write(isFinal ? 'final ' : '')
- ..write(isStatic ? 'static ' : '')
- ..write(annotations)
- ..write(')')).toString();
-}
« no previous file with comments | « packages/smoke/lib/codegen/recorder.dart ('k') | packages/smoke/lib/smoke.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698