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

Unified Diff: pkg/checked_mirrors/lib/checked_mirrors.dart

Issue 111643015: Preliminary checked mirrors (not ready for review yet) (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Created 7 years 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 | « pkg/checked_mirrors/example/target.dart ('k') | pkg/checked_mirrors/lib/control.dart » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: pkg/checked_mirrors/lib/checked_mirrors.dart
diff --git a/pkg/checked_mirrors/lib/checked_mirrors.dart b/pkg/checked_mirrors/lib/checked_mirrors.dart
new file mode 100644
index 0000000000000000000000000000000000000000..91ccc30d7e7ce14363810b8ad7742344882116b9
--- /dev/null
+++ b/pkg/checked_mirrors/lib/checked_mirrors.dart
@@ -0,0 +1,443 @@
+// Copyright (c) 2013, 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.
+
+/// An implementation of dart:mirrors that checks if everything accessed through
+/// reflection has been declared via the @MirrorUsed API.
+///
+/// Usage:
+///
+/// * Import `package:checked_mirrors/checked_mirrors.dart` instead of
+/// `dart:mirrors`.
+///
+/// * Move the @[MirrorsUsed] annotations to a top-level const symbol named
+/// `checked_mirrors_workaround_for_10360`. This step is needed temporarily
+/// until issue [10360](http://dartbug.com/10360) is fixed.
+///
+/// * Add a transformer section to your pubspec to include a phase that will
+/// remove the checks from this library when you deploy your application:
+///
+/// transformers:
+/// - checked_mirrors
+
+library checked_mirrors;
+
+// Except for top-level APIs, expose everything else.
+export "dart:mirrors" hide currentMirrorSystem, reflect, reflectClass,
+ reflectType, MirrorSystem;
+
+import 'dart:async';
+import "dart:collection" show ListMixin;
+import 'dart:isolate';
+import "dart:mirrors" as mirrors;
+import "dart:mirrors" hide currentMirrorSystem, reflect, reflectClass,
+ reflectType, MirrorSystem;
+
+import 'src/checker.dart';
+
+/// An expando to store existing wrappers, since some APIs are expected to
+/// return the same instance (at least according to the mirror tests).
+Expando _wrappers = new Expando();
+
+/// Returns a wrapper for [original], an object from the base mirror system. We
+/// internally try to store the wrapper in an expando to ensure we use the same
+/// wrapper whenever it's possible.
+_wrap(original) {
+ if (original == null) return null;
+ var value = _wrappers[original];
+ if (value != null) return value;
+ value = _createWrapper(original);
+ _wrappers[original] = value;
+ return value;
+}
+
+/// Creates a wrapper for [original] assuming one doesn't exist already. The
+/// wrapper will be a corresponding object in this library, for instance
+/// _ClosureMirror for ClosureMirror. This function also wraps maps and lists
+/// whose values are mirror system objects.
+_createWrapper(original) {
+ // Note: the order below is important to guarnatee we create the most precise
+ // wrapper for a given type (e.g. FunctionTypeMirror is a ClassMirror too).
+
+ if (original is Map) return new _MapWrapper(original);
+ if (original is List) return new _ListWrapper(original);
+ if (original is FunctionTypeMirror) return new _FunctionTypeMirror(original);
+ if (original is ClassMirror) return new _ClassMirror(original);
+
+ if (original is ClosureMirror) return new _ClosureMirror(original);
+ if (original is InstanceMirror) return new _InstanceMirror(original);
+ if (original is LibraryMirror) return new _LibraryMirror(original);
+ if (original is ObjectMirror) return new _ObjectMirror(original);
+
+ if (original is ParameterMirror) return new _ParameterMirror(original);
+ if (original is VariableMirror) return new _VariableMirror(original);
+
+ if (original is TypeVariableMirror) return new _TypeVariableMirror(original);
+ if (original is IsolateMirror) return new _IsolateMirror(original);
+ if (original is MethodMirror) return new _MethodMirror(original);
+ if (original is mirrors.MirrorSystem) return new MirrorSystem(original);
+ if (original is TypedefMirror) return new _TypedefMirror(original);
+
+ if (original is TypeMirror) return new _TypeMirror(original);
+ if (original is DeclarationMirror) return new _DeclarationMirror(original);
+ throw "Unknown mirror type: ${original.runtimeType}";
+}
+
+MirrorSystem _current = _wrap(mirrors.currentMirrorSystem());
+MirrorSystem currentMirrorSystem() => _current;
+InstanceMirror reflect(Object reflectee) => _wrap(mirrors.reflect(reflectee));
+ClassMirror reflectClass(Type key) => _wrap(mirrors.reflectClass(key));
+TypeMirror reflectType(Type key) => _wrap(mirrors.reflectType(key));
+
+class _Mirror {
+ dynamic _original;
+ _Mirror(this._original);
+
+ toString() => _original.toString();
+}
+
+// We use the original name for this class because it exposes static methods
+// that could be used externally.
+// TODO(sigmund): technically the top-level symbols exposed here could be used
+// too, like #LibraryMirror. Maybe we need to override the names of all these
+// symbols?
+class MirrorSystem extends _Mirror with mirrors.MirrorSystem {
+ MirrorSystem(original) : super(original);
+
+ Map<Uri, LibraryMirror> get libraries => _wrap(_original.libraries);
+
+ IsolateMirror get isolate => _wrap(_original.isolate);
+
+ TypeMirror get dynamicType => _wrap(_original.dynamicType);
+
+ TypeMirror get voidType => _wrap(_original.voidType);
+
+ static String getName(Symbol symbol) {
+ checker.useSymbol(symbol);
+ return mirrors.MirrorSystem.getName(symbol);
+ }
+
+ static Symbol getSymbol(String name, [LibraryMirror library]) {
+ if (library == null) {
+ var symbol = mirrors.MirrorSystem.getSymbol(name);
+ checker.useSymbol(symbol);
+ return symbol;
+ }
+ if (library is! _LibraryMirror) {
+ throw new ArgumentError("$library is not a LibraryMirror");
+ }
+ _LibraryMirror lib = library; // type-check
+ var symbol = mirrors.MirrorSystem.getSymbol(name, lib._original);
+ checker.useSymbol(symbol);
+ return symbol;
+ }
+}
+
+class _IsolateMirror extends _Mirror implements mirrors.IsolateMirror {
+ _IsolateMirror(original) : super(original);
+
+ String get debugName => _original.debugName;
+ bool get isCurrent => _original.isCurrent;
+ LibraryMirror get rootLibrary => _wrap(_original.rootLibrary);
+ bool operator == (other) {
+ if (other == null || other is! _IsolateMirror) return false;
+ return _original == other._original;
+ }
+ int get hashCode => _original.hashCode;
+}
+
+abstract class _DeclarationMirrorMixin implements mirrors.DeclarationMirror {
+ get _original;
+ Symbol get simpleName => _original.simpleName;
+ Symbol get qualifiedName => _original.qualifiedName;
+ DeclarationMirror get owner => _wrap(_original.owner);
+ bool get isPrivate => _original.isPrivate;
+ bool get isTopLevel => _original.isTopLevel;
+ SourceLocation get location => _original.location;
+ List<InstanceMirror> get metadata => _wrap(_original.metadata);
+}
+
+class _DeclarationMirror extends _Mirror with _DeclarationMirrorMixin
+ implements mirrors.DeclarationMirror {
+ _DeclarationMirror(original) : super(original);
+ get _original => super._original; // to get rid of static warnings
+
+}
+
+abstract class _ObjectMirrorMixin implements mirrors.ObjectMirror {
+ get _original;
+
+ InstanceMirror invoke(Symbol memberName,
+ List positionalArguments,
+ [Map<Symbol,dynamic> namedArguments]) =>
+ _wrap(_original.invoke(memberName, positionalArguments, namedArguments));
+
+ InstanceMirror getField(Symbol fieldName) {
+ checker.access(_original, fieldName);
+ return _wrap(_original.getField(fieldName));
+ }
+
+ InstanceMirror setField(Symbol fieldName, Object value) {
+ checker.access(_original, fieldName);
+ return _wrap(_original.setField(fieldName, value));
+ }
+}
+
+class _ObjectMirror extends _Mirror with _ObjectMirrorMixin
+ implements mirrors.ObjectMirror {
+ _ObjectMirror(original) : super(original);
+ get _original => super._original; // to get rid of static warnings
+}
+
+class _InstanceMirror extends _ObjectMirror implements mirrors.InstanceMirror {
+ _InstanceMirror(original) : super(original);
+
+ ClassMirror get type => _wrap(_original.type);
+ bool get hasReflectee => _original.hasReflectee;
+ get reflectee => _original.reflectee;
+ bool operator == (other) {
+ if (other == null || other is! _InstanceMirror) return false;
+ return _original == other._original;
+ }
+ int get hashCode => _original.hashCode;
+
+ delegate(Invocation invocation) => _original.delegate(invocation);
+ Function operator [](Symbol name) {
+ print('warning: this cannot be debugged: InstanceMirror.operator[]');
+ // TODO(sigmund): we'd like to wrap the result inside the function, but we
+ // don't have a way to dynamically take arguments.
+ return _original[name];
+ }
+}
+
+class _ClosureMirror extends _InstanceMirror implements mirrors.ClosureMirror {
+ _ClosureMirror(original) : super(original);
+
+ MethodMirror get function => _wrap(_original.function);
+ InstanceMirror apply(List positionalArguments,
+ [Map<Symbol, dynamic> namedArguments]) =>
+ _wrap(_original.apply(positionalArguments, namedArguments));
+ InstanceMirror findInContext(Symbol name, {ifAbsent: null}) =>
+ _wrap(_original.findInContext(name, ifAbsent: ifAbsent));
+}
+
+class _LibraryMirror extends _DeclarationMirror with _ObjectMirrorMixin
+ implements mirrors.LibraryMirror {
+ _LibraryMirror(original) : super(original);
+ get _original => super._original; // to get rid of static warnings
+
+ Uri get uri => _original.uri;
+ Map<Symbol, DeclarationMirror> get declarations =>
+ _wrap(_original.declarations);
+
+ Map<Symbol, MethodMirror> get topLevelMembers =>
+ _wrap(_original.topLevelMembers);
+
+ bool operator == (other) {
+ if (other == null || other is! _LibraryMirror) return false;
+ return _original == other._original;
+ }
+ int get hashCode => _original.hashCode;
+
+ Function operator [](Symbol name) {
+ print('warning: this cannot be debugged: LibraryMirror.operator[]');
+ // TODO(sigmund): we'd like to wrap the result inside the function, but we
+ // don't have a way to dynamically take arguments.
+ return _original[name];
+ }
+}
+
+class _TypeMirror extends _DeclarationMirror implements mirrors.TypeMirror {
+ _TypeMirror(original) : super(original);
+
+ List<TypeVariableMirror> get typeVariables =>
+ _wrap(_original.typeVariables);
+ List<TypeMirror> get typeArguments =>
+ _wrap(_original.typeArguments);
+ bool get isOriginalDeclaration => _original.isOriginalDeclaration;
+ TypeMirror get originalDeclaration =>
+ _wrap(_original.originalDeclaration);
+
+ bool operator == (other) {
+ if (other == null || other is! _TypeMirror) return false;
+ return _original == other._original;
+ }
+ int get hashCode => _original.hashCode;
+}
+
+class _ClassMirror extends _TypeMirror with _ObjectMirrorMixin
+ implements ClassMirror {
+ _ClassMirror(original) : super(original);
+
+ bool get hasReflectedType => _original.hasReflectedType;
+ Type get reflectedType => _original.reflectedType;
+ ClassMirror get superclass => _wrap(_original.superclass);
+ List<ClassMirror> get superinterfaces =>
+ _wrap(_original.superinterfaces);
+
+ Map<Symbol, DeclarationMirror> get declarations =>
+ _wrap(_original.declarations);
+ Map<Symbol, MethodMirror> get instanceMembers =>
+ _wrap(_original.instanceMembers);
+ Map<Symbol, MethodMirror> get staticMembers =>
+ _wrap(_original.staticMembers);
+ ClassMirror get mixin => _wrap(_original.mixin);
+ InstanceMirror newInstance(Symbol constructorName,
+ List positionalArguments,
+ [Map<Symbol,dynamic> namedArguments]) =>
+ _wrap(_original.newInstance(constructorName,
+ positionalArguments, namedArguments));
+
+ bool operator == (other) {
+ if (other == null || other is! _ClassMirror) return false;
+ return _original == other._original;
+ }
+ int get hashCode => _original.hashCode;
+
+ Function operator [](Symbol name) {
+ print('warning: this cannot be debugged: ClassMirror.operator[]');
+ // TODO(sigmund): we'd like to wrap the result inside the function, but we
+ // don't have a way to dynamically take arguments.
+ return _original[name];
+ }
+}
+
+class _FunctionTypeMirror extends _ClassMirror implements FunctionTypeMirror {
+ _FunctionTypeMirror(original) : super(original);
+ get _original => super._original; // to get rid of static warnings
+
+ TypeMirror get returnType => _wrap(_original.returnType);
+ List<ParameterMirror> get parameters =>
+ _wrap(_original.parameters);
+ MethodMirror get callMethod => _wrap(_original.callMethod);
+}
+
+class _TypeVariableMirror extends _TypeMirror implements TypeVariableMirror {
+ _TypeVariableMirror(original) : super(original);
+
+ TypeMirror get upperBound => _wrap(_original.upperBound);
+ bool get isStatic => _original.isStatic;
+ bool operator == (other) {
+ if (other == null || other is! _TypeVariableMirror) return false;
+ return _original == other._original;
+ }
+ int get hashCode => _original.hashCode;
+}
+
+class _TypedefMirror extends _TypeMirror implements TypedefMirror {
+ _TypedefMirror(original) : super(original);
+
+ FunctionTypeMirror get referent => _wrap(_original.referent);
+}
+
+class _MethodMirror extends _DeclarationMirror implements MethodMirror {
+ _MethodMirror(original) : super(original);
+
+ TypeMirror get returnType => _wrap(_original.returnType);
+ String get source => _original.source;
+ List<ParameterMirror> get parameters =>
+ _wrap(_original.parameters);
+ bool get isStatic => _original.isStatic;
+ bool get isAbstract => _original.isAbstract;
+ bool get isSynthetic => _original.isSynthetic;
+ bool get isRegularMethod => _original.isRegularMethod;
+ bool get isOperator => _original.isOperator;
+ bool get isGetter => _original.isGetter;
+ bool get isSetter => _original.isSetter;
+ bool get isConstructor => _original.isConstructor;
+ Symbol get constructorName => _original.constructorName;
+ bool get isConstConstructor => _original.isConstConstructor;
+ bool get isGenerativeConstructor => _original.isGenerativeConstructor;
+ bool get isRedirectingConstructor => _original.isRedirectingConstructor;
+ bool get isFactoryConstructor => _original.isFactoryConstructor;
+ bool operator == (other) {
+ if (other == null || other is! _MethodMirror) return false;
+ return _original == other._original;
+ }
+ int get hashCode => _original.hashCode;
+}
+
+class _VariableMirror extends _DeclarationMirror implements VariableMirror {
+ _VariableMirror(original) : super(original);
+ TypeMirror get type => _wrap(_original.type);
+ bool get isStatic => _original.isStatic;
+ bool get isFinal => _original.isFinal;
+ bool get isConst => _original.isConst;
+ bool operator == (other) {
+ if (other == null || other is! _VariableMirror) return false;
+ return _original == other._original;
+ }
+ int get hashCode => _original.hashCode;
+}
+
+class _ParameterMirror extends _VariableMirror implements ParameterMirror {
+ _ParameterMirror(original) : super(original);
+ TypeMirror get type => _wrap(_original.type);
+ bool get isOptional => _original.isOptional;
+ bool get isNamed => _original.isNamed;
+ bool get hasDefaultValue => _original.hasDefaultValue;
+ InstanceMirror get defaultValue => _original.defaultValue;
+}
+
+/// Wraps a map that contains mirror values
+class _MapWrapper<K, V extends _Mirror> implements Map<K, V> {
+ Map<K, V> _original;
+ _MapWrapper(Map<K, V> original) : _original = original;
+
+ V operator [](Object key) => _wrap(_original[key]);
+
+ void operator []=(K key, V value) {
+ _original[key] = value._original;
+ }
+
+ void addAll(Map<K, V> other) {
+ other.forEach((key, value) { _original[key] = value; });
+ }
+
+ bool containsValue(Object value) =>
+ _original.containsValue(value != null && (value as dynamic)._original);
+
+ V putIfAbsent(K key, V ifAbsent()) =>
+ _original.putIfAbsent(key, () => ifAbsent()._original);
+
+ // Every other method is just delegated to the original
+
+ Iterable<V> get values => _original.values.map(_wrap);
+
+ void clear() => _original.clear();
+
+ bool containsKey(Object key) => _original.containsKey(key);
+
+ void forEach(void f(K key, V value)) {
+ _original.forEach(f);
+ }
+
+ bool get isEmpty => _original.isEmpty;
+
+ bool get isNotEmpty => _original.isNotEmpty;
+
+ Iterable<K> get keys => _original.keys;
+
+ int get length => _original.length;
+
+ V remove(Object key) => _original.remove(key);
+}
+
+/// Wraps a list of mirror values
+class _ListWrapper<E extends _Mirror> extends Object with ListMixin<E> {
+ List _original;
+
+ _ListWrapper(this._original);
+
+ E operator [](int index) => _wrap(_original[index]);
+
+ void operator []=(int index, E value) {
+ _original[index] = value._original;
+ }
+
+ int get length => _original.length;
+
+ void set length(int newLength) {
+ _original.length = newLength;
+ }
+}
« no previous file with comments | « pkg/checked_mirrors/example/target.dart ('k') | pkg/checked_mirrors/lib/control.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698