| Index: sdk/lib/_internal/compiler/implementation/mirrors/dart2js_type_mirrors.dart
|
| diff --git a/sdk/lib/_internal/compiler/implementation/mirrors/dart2js_type_mirrors.dart b/sdk/lib/_internal/compiler/implementation/mirrors/dart2js_type_mirrors.dart
|
| new file mode 100644
|
| index 0000000000000000000000000000000000000000..8a5a41e33ceb4d163611228ce46590b3b8069f09
|
| --- /dev/null
|
| +++ b/sdk/lib/_internal/compiler/implementation/mirrors/dart2js_type_mirrors.dart
|
| @@ -0,0 +1,458 @@
|
| +// 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.
|
| +
|
| +part of dart2js.mirrors;
|
| +
|
| +//------------------------------------------------------------------------------
|
| +// Types
|
| +//------------------------------------------------------------------------------
|
| +
|
| +abstract class ClassMirrorMixin implements ClassSourceMirror {
|
| + bool get hasReflectedType => false;
|
| + Type get reflectedType {
|
| + throw new UnsupportedError("ClassMirror.reflectedType is not supported.");
|
| + }
|
| + InstanceMirror newInstance(Symbol constructorName,
|
| + List positionalArguments,
|
| + [Map<Symbol, dynamic> namedArguments]) {
|
| + throw new UnsupportedError("ClassMirror.newInstance is not supported.");
|
| + }
|
| +}
|
| +
|
| +abstract class Dart2JsTypeMirror
|
| + extends Dart2JsElementMirror
|
| + implements TypeSourceMirror {
|
| + final DartType _type;
|
| +
|
| + Dart2JsTypeMirror(Dart2JsMirrorSystem system, DartType type)
|
| + : super(system, type.element),
|
| + this._type = type;
|
| +
|
| + String get _simpleNameString => _type.name;
|
| +
|
| + Dart2JsDeclarationMirror get owner => library;
|
| +
|
| + Dart2JsLibraryMirror get library {
|
| + return mirrorSystem._getLibrary(_type.element.getLibrary());
|
| + }
|
| +
|
| + bool get isOriginalDeclaration => true;
|
| +
|
| + TypeMirror get originalDeclaration => this;
|
| +
|
| + List<TypeMirror> get typeArguments => const <TypeMirror>[];
|
| +
|
| + List<TypeVariableMirror> get typeVariables => const <TypeVariableMirror>[];
|
| +
|
| + TypeMirror createInstantiation(List<TypeMirror> typeArguments) {
|
| + if (typeArguments.isEmpty) return this;
|
| + throw new ArgumentError('Cannot create generic instantiation of $_type.');
|
| + }
|
| +
|
| + bool get isVoid => false;
|
| +
|
| + bool get isDynamic => false;
|
| +
|
| + String toString() => _type.toString();
|
| +}
|
| +
|
| +abstract class DeclarationMixin implements TypeMirror {
|
| +
|
| + bool get isOriginalDeclaration => true;
|
| +
|
| + TypeMirror get originalDeclaration => this;
|
| +
|
| + List<TypeMirror> get typeArguments => const <TypeMirror>[];
|
| +}
|
| +
|
| +abstract class Dart2JsGenericTypeMirror extends Dart2JsTypeMirror {
|
| + List<TypeMirror> _typeArguments;
|
| + List<TypeVariableMirror> _typeVariables;
|
| +
|
| + Dart2JsGenericTypeMirror(Dart2JsMirrorSystem system, GenericType type)
|
| + : super(system, type);
|
| +
|
| + TypeDeclarationElement get _element => super._element;
|
| +
|
| + GenericType get _type => super._type;
|
| +
|
| + bool get isOriginalDeclaration => false;
|
| +
|
| + TypeMirror get originalDeclaration =>
|
| + mirrorSystem._getTypeDeclarationMirror(_element);
|
| +
|
| + List<TypeMirror> get typeArguments {
|
| + if (_typeArguments == null) {
|
| + _typeArguments = <TypeMirror>[];
|
| + if (!_type.isRaw) {
|
| + Link<DartType> type = _type.typeArguments;
|
| + while (type != null && type.head != null) {
|
| + _typeArguments.add(_getTypeMirror(type.head));
|
| + type = type.tail;
|
| + }
|
| + }
|
| + }
|
| + return _typeArguments;
|
| + }
|
| +
|
| + List<TypeVariableMirror> get typeVariables {
|
| + if (_typeVariables == null) {
|
| + _typeVariables = <TypeVariableMirror>[];
|
| + for (TypeVariableType typeVariable in _element.typeVariables) {
|
| + _typeVariables.add(
|
| + new Dart2JsTypeVariableMirror(mirrorSystem, typeVariable));
|
| + }
|
| + }
|
| + return _typeVariables;
|
| + }
|
| +
|
| + Iterable<Dart2JsMemberMirror> _getDeclarationMirrors(Element element) {
|
| + if (element.isTypeVariable()) {
|
| + assert(invariant(_element, _element == element.enclosingElement,
|
| + message: 'Foreigned type variable element $element.'));
|
| + for (Dart2JsTypeVariableMirror mirror in typeVariables) {
|
| + if (mirror._element == element) return [mirror];
|
| + }
|
| + }
|
| + return super._getDeclarationMirrors(element);
|
| + }
|
| +
|
| + TypeMirror _getTypeMirror(DartType type, [FunctionSignature signature]) {
|
| + return super._getTypeMirror(
|
| + type.subst(_type.typeArguments, _type.element.typeVariables),
|
| + signature);
|
| + }
|
| +
|
| + TypeSourceMirror createInstantiation(
|
| + List<TypeSourceMirror> newTypeArguments) {
|
| + if (newTypeArguments.isEmpty) return owner._getTypeMirror(_type.asRaw());
|
| + if (newTypeArguments.length != typeVariables.length) {
|
| + throw new ArgumentError('Cannot create generic instantiation of $_type '
|
| + 'with ${newTypeArguments.length} arguments, '
|
| + 'expect ${typeVariables.length} arguments.');
|
| + }
|
| + LinkBuilder<DartType> builder = new LinkBuilder<DartType>();
|
| + for (TypeSourceMirror newTypeArgument in newTypeArguments) {
|
| + if (newTypeArgument.isVoid) {
|
| + throw new ArgumentError('Cannot use void as type argument.');
|
| + }
|
| + if (newTypeArgument is Dart2JsTypeMirror) {
|
| + builder.addLast(newTypeArgument._type);
|
| + } else {
|
| + throw new UnsupportedError(
|
| + 'Cannot create instantiation using a type '
|
| + 'mirror from a different mirrorSystem implementation.');
|
| + }
|
| + }
|
| + return owner._getTypeMirror(_type.createInstantiation(builder.toLink()));
|
| + }
|
| +}
|
| +
|
| +class Dart2JsInterfaceTypeMirror
|
| + extends Dart2JsGenericTypeMirror
|
| + with ObjectMirrorMixin, InstanceMirrorMixin, ClassMirrorMixin,
|
| + ContainerMixin
|
| + implements ClassMirror {
|
| + Dart2JsInterfaceTypeMirror(Dart2JsMirrorSystem system,
|
| + InterfaceType interfaceType)
|
| + : super(system, interfaceType);
|
| +
|
| + ClassElement get _element => super._element;
|
| +
|
| + InterfaceType get _type => super._type;
|
| +
|
| + bool get isNameSynthetic {
|
| + if (_element.isMixinApplication) {
|
| + MixinApplicationElement mixinApplication = _element;
|
| + return mixinApplication.isUnnamedMixinApplication;
|
| + }
|
| + return false;
|
| + }
|
| +
|
| + void _forEachElement(f(Element element)) {
|
| + _element.forEachMember((_, element) => f(element));
|
| + }
|
| +
|
| + ClassMirror get superclass {
|
| + if (_element.supertype != null) {
|
| + return _getTypeMirror(_element.supertype);
|
| + }
|
| + return null;
|
| + }
|
| +
|
| + ClassMirror get mixin {
|
| + if (_element.isMixinApplication) {
|
| + MixinApplicationElement mixinApplication = _element;
|
| + return _getTypeMirror(mixinApplication.mixinType);
|
| + }
|
| + return this;
|
| + }
|
| +
|
| + List<ClassMirror> get superinterfaces {
|
| + var list = <ClassMirror>[];
|
| + Link<DartType> link = _element.interfaces;
|
| + while (!link.isEmpty) {
|
| + var type = _getTypeMirror(link.head);
|
| + list.add(type);
|
| + link = link.tail;
|
| + }
|
| + return list;
|
| + }
|
| +
|
| + Map<Symbol, MethodMirror> get instanceMembers => null;
|
| + Map<Symbol, MethodMirror> get staticMembers => null;
|
| +
|
| + bool get isAbstract => _element.modifiers.isAbstract();
|
| +
|
| + bool operator ==(other) {
|
| + if (identical(this, other)) {
|
| + return true;
|
| + }
|
| + if (other is! ClassMirror) {
|
| + return false;
|
| + }
|
| + return _type == other._type;
|
| + }
|
| +
|
| + String toString() => 'Mirror on interface type $_type';
|
| +}
|
| +
|
| +class Dart2JsClassDeclarationMirror
|
| + extends Dart2JsInterfaceTypeMirror
|
| + with DeclarationMixin {
|
| +
|
| + Dart2JsClassDeclarationMirror(Dart2JsMirrorSystem system,
|
| + InterfaceType type)
|
| + : super(system, type);
|
| +
|
| + String toString() => 'Mirror on class ${_type.name}';
|
| +}
|
| +
|
| +class Dart2JsTypedefMirror
|
| + extends Dart2JsGenericTypeMirror
|
| + implements TypedefMirror {
|
| + final Dart2JsLibraryMirror _library;
|
| + List<TypeVariableMirror> _typeVariables;
|
| + var _definition;
|
| +
|
| + Dart2JsTypedefMirror(Dart2JsMirrorSystem system, TypedefType _typedef)
|
| + : this._library = system._getLibrary(_typedef.element.getLibrary()),
|
| + super(system, _typedef);
|
| +
|
| + Dart2JsTypedefMirror.fromLibrary(Dart2JsLibraryMirror library,
|
| + TypedefType _typedef)
|
| + : this._library = library,
|
| + super(library.mirrorSystem, _typedef);
|
| +
|
| + TypedefType get _typedef => _type;
|
| +
|
| + LibraryMirror get library => _library;
|
| +
|
| + bool get isTypedef => true;
|
| +
|
| + FunctionTypeMirror get referent {
|
| + if (_definition == null) {
|
| + _definition = _getTypeMirror(
|
| + _typedef.element.alias,
|
| + _typedef.element.functionSignature);
|
| + }
|
| + return _definition;
|
| + }
|
| +
|
| + bool get isClass => false;
|
| +
|
| + bool get isAbstract => false;
|
| +
|
| + String toString() => 'Mirror on typedef $_type';
|
| +}
|
| +
|
| +class Dart2JsTypedefDeclarationMirror
|
| + extends Dart2JsTypedefMirror
|
| + with DeclarationMixin {
|
| + Dart2JsTypedefDeclarationMirror(Dart2JsMirrorSystem system,
|
| + TypedefType type)
|
| + : super(system, type);
|
| +
|
| + String toString() => 'Mirror on typedef ${_type.name}';
|
| +}
|
| +
|
| +class Dart2JsTypeVariableMirror extends Dart2JsTypeMirror
|
| + implements TypeVariableMirror {
|
| + Dart2JsDeclarationMirror _owner;
|
| +
|
| + Dart2JsTypeVariableMirror(Dart2JsMirrorSystem system,
|
| + TypeVariableType typeVariableType)
|
| + : super(system, typeVariableType);
|
| +
|
| + TypeVariableType get _type => super._type;
|
| +
|
| + Dart2JsDeclarationMirror get owner {
|
| + if (_owner == null) {
|
| + _owner = mirrorSystem._getTypeDeclarationMirror(
|
| + _type.element.enclosingElement);
|
| + }
|
| + return _owner;
|
| + }
|
| +
|
| + TypeMirror get upperBound => owner._getTypeMirror(_type.element.bound);
|
| +
|
| + bool operator ==(var other) {
|
| + if (identical(this, other)) {
|
| + return true;
|
| + }
|
| + if (other is! TypeVariableMirror) {
|
| + return false;
|
| + }
|
| + if (owner != other.owner) {
|
| + return false;
|
| + }
|
| + return qualifiedName == other.qualifiedName;
|
| + }
|
| +
|
| + String toString() => 'Mirror on type variable $_type';
|
| +}
|
| +
|
| +class Dart2JsFunctionTypeMirror extends Dart2JsTypeMirror
|
| + with ObjectMirrorMixin, InstanceMirrorMixin,
|
| + ClassMirrorMixin, DeclarationMixin
|
| + implements FunctionTypeMirror {
|
| + final FunctionSignature _functionSignature;
|
| + List<ParameterMirror> _parameters;
|
| +
|
| + Dart2JsFunctionTypeMirror(Dart2JsMirrorSystem system,
|
| + FunctionType functionType, this._functionSignature)
|
| + : super(system, functionType) {
|
| + assert (_functionSignature != null);
|
| + }
|
| +
|
| + FunctionType get _type => super._type;
|
| +
|
| + // TODO(johnniwinther): Is this the qualified name of a function type?
|
| + Symbol get qualifiedName => originalDeclaration.qualifiedName;
|
| +
|
| + // TODO(johnniwinther): Substitute type arguments for type variables.
|
| + Map<Symbol, DeclarationMirror> get declarations {
|
| + var method = callMethod;
|
| + if (method != null) {
|
| + var map = new Map<Symbol, DeclarationMirror>.from(
|
| + originalDeclaration.declarations);
|
| + var name = method.qualifiedName;
|
| + assert(!map.containsKey(name));
|
| + map[name] = method;
|
| + return new ImmutableMapWrapper<Symbol, DeclarationMirror>(map);
|
| + }
|
| + return originalDeclaration.declarations;
|
| + }
|
| +
|
| + bool get isFunction => true;
|
| +
|
| + MethodMirror get callMethod => _convertElementMethodToMethodMirror(
|
| + mirrorSystem._getLibrary(_type.element.getLibrary()),
|
| + _type.element);
|
| +
|
| + ClassMirror get originalDeclaration =>
|
| + mirrorSystem._getTypeDeclarationMirror(
|
| + mirrorSystem.compiler.functionClass);
|
| +
|
| + // TODO(johnniwinther): Substitute type arguments for type variables.
|
| + ClassMirror get superclass => originalDeclaration.superclass;
|
| +
|
| + // TODO(johnniwinther): Substitute type arguments for type variables.
|
| + List<ClassMirror> get superinterfaces => originalDeclaration.superinterfaces;
|
| +
|
| + Map<Symbol, MethodMirror> get instanceMembers => null;
|
| + Map<Symbol, MethodMirror> get staticMembers => null;
|
| +
|
| + ClassMirror get mixin => this;
|
| +
|
| + bool get isPrivate => false;
|
| +
|
| + bool get isAbstract => false;
|
| +
|
| + List<TypeVariableMirror> get typeVariables =>
|
| + originalDeclaration.typeVariables;
|
| +
|
| + TypeMirror get returnType => owner._getTypeMirror(_type.returnType);
|
| +
|
| + List<ParameterMirror> get parameters {
|
| + if (_parameters == null) {
|
| + _parameters = _parametersFromFunctionSignature(owner,
|
| + _functionSignature);
|
| + }
|
| + return _parameters;
|
| + }
|
| +
|
| + String toString() => 'Mirror on function type $_type';
|
| +}
|
| +
|
| +class Dart2JsVoidMirror extends Dart2JsTypeMirror {
|
| +
|
| + Dart2JsVoidMirror(Dart2JsMirrorSystem system, VoidType voidType)
|
| + : super(system, voidType);
|
| +
|
| + VoidType get _voidType => _type;
|
| +
|
| + Symbol get qualifiedName => simpleName;
|
| +
|
| + /**
|
| + * The void type has no location.
|
| + */
|
| + SourceLocation get location => null;
|
| +
|
| + /**
|
| + * The void type has no library.
|
| + */
|
| + LibraryMirror get library => null;
|
| +
|
| + bool get isVoid => true;
|
| +
|
| + bool operator ==(other) {
|
| + if (identical(this, other)) {
|
| + return true;
|
| + }
|
| + if (other is! TypeMirror) {
|
| + return false;
|
| + }
|
| + return other.isVoid;
|
| + }
|
| +
|
| + int get hashCode => 13 * _element.hashCode;
|
| +
|
| + String toString() => 'Mirror on void';
|
| +}
|
| +
|
| +class Dart2JsDynamicMirror extends Dart2JsTypeMirror {
|
| + Dart2JsDynamicMirror(Dart2JsMirrorSystem system, InterfaceType voidType)
|
| + : super(system, voidType);
|
| +
|
| + InterfaceType get _dynamicType => _type;
|
| +
|
| + Symbol get qualifiedName => simpleName;
|
| +
|
| + /**
|
| + * The dynamic type has no location.
|
| + */
|
| + SourceLocation get location => null;
|
| +
|
| + /**
|
| + * The dynamic type has no library.
|
| + */
|
| + LibraryMirror get library => null;
|
| +
|
| + bool get isDynamic => true;
|
| +
|
| + bool operator ==(other) {
|
| + if (identical(this, other)) {
|
| + return true;
|
| + }
|
| + if (other is! TypeMirror) {
|
| + return false;
|
| + }
|
| + return other.isDynamic;
|
| + }
|
| +
|
| + int get hashCode => 13 * _element.hashCode;
|
| +
|
| + String toString() => 'Mirror on dynamic';
|
| +}
|
|
|