OLD | NEW |
(Empty) | |
| 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 |
| 3 // BSD-style license that can be found in the LICENSE file. |
| 4 |
| 5 part of dart2js.mirrors; |
| 6 |
| 7 //------------------------------------------------------------------------------ |
| 8 // Types |
| 9 //------------------------------------------------------------------------------ |
| 10 |
| 11 abstract class ClassMirrorMixin implements ClassSourceMirror { |
| 12 bool get hasReflectedType => false; |
| 13 Type get reflectedType { |
| 14 throw new UnsupportedError("ClassMirror.reflectedType is not supported."); |
| 15 } |
| 16 InstanceMirror newInstance(Symbol constructorName, |
| 17 List positionalArguments, |
| 18 [Map<Symbol, dynamic> namedArguments]) { |
| 19 throw new UnsupportedError("ClassMirror.newInstance is not supported."); |
| 20 } |
| 21 } |
| 22 |
| 23 abstract class Dart2JsTypeMirror |
| 24 extends Dart2JsElementMirror |
| 25 implements TypeSourceMirror { |
| 26 final DartType _type; |
| 27 |
| 28 Dart2JsTypeMirror(Dart2JsMirrorSystem system, DartType type) |
| 29 : super(system, type.element), |
| 30 this._type = type; |
| 31 |
| 32 String get _simpleNameString => _type.name; |
| 33 |
| 34 Dart2JsDeclarationMirror get owner => library; |
| 35 |
| 36 Dart2JsLibraryMirror get library { |
| 37 return mirrorSystem._getLibrary(_type.element.getLibrary()); |
| 38 } |
| 39 |
| 40 bool get isOriginalDeclaration => true; |
| 41 |
| 42 TypeMirror get originalDeclaration => this; |
| 43 |
| 44 List<TypeMirror> get typeArguments => const <TypeMirror>[]; |
| 45 |
| 46 List<TypeVariableMirror> get typeVariables => const <TypeVariableMirror>[]; |
| 47 |
| 48 TypeMirror createInstantiation(List<TypeMirror> typeArguments) { |
| 49 if (typeArguments.isEmpty) return this; |
| 50 throw new ArgumentError('Cannot create generic instantiation of $_type.'); |
| 51 } |
| 52 |
| 53 bool get isVoid => false; |
| 54 |
| 55 bool get isDynamic => false; |
| 56 |
| 57 String toString() => _type.toString(); |
| 58 } |
| 59 |
| 60 abstract class DeclarationMixin implements TypeMirror { |
| 61 |
| 62 bool get isOriginalDeclaration => true; |
| 63 |
| 64 TypeMirror get originalDeclaration => this; |
| 65 |
| 66 List<TypeMirror> get typeArguments => const <TypeMirror>[]; |
| 67 } |
| 68 |
| 69 abstract class Dart2JsGenericTypeMirror extends Dart2JsTypeMirror { |
| 70 List<TypeMirror> _typeArguments; |
| 71 List<TypeVariableMirror> _typeVariables; |
| 72 |
| 73 Dart2JsGenericTypeMirror(Dart2JsMirrorSystem system, GenericType type) |
| 74 : super(system, type); |
| 75 |
| 76 TypeDeclarationElement get _element => super._element; |
| 77 |
| 78 GenericType get _type => super._type; |
| 79 |
| 80 bool get isOriginalDeclaration => false; |
| 81 |
| 82 TypeMirror get originalDeclaration => |
| 83 mirrorSystem._getTypeDeclarationMirror(_element); |
| 84 |
| 85 List<TypeMirror> get typeArguments { |
| 86 if (_typeArguments == null) { |
| 87 _typeArguments = <TypeMirror>[]; |
| 88 if (!_type.isRaw) { |
| 89 Link<DartType> type = _type.typeArguments; |
| 90 while (type != null && type.head != null) { |
| 91 _typeArguments.add(_getTypeMirror(type.head)); |
| 92 type = type.tail; |
| 93 } |
| 94 } |
| 95 } |
| 96 return _typeArguments; |
| 97 } |
| 98 |
| 99 List<TypeVariableMirror> get typeVariables { |
| 100 if (_typeVariables == null) { |
| 101 _typeVariables = <TypeVariableMirror>[]; |
| 102 for (TypeVariableType typeVariable in _element.typeVariables) { |
| 103 _typeVariables.add( |
| 104 new Dart2JsTypeVariableMirror(mirrorSystem, typeVariable)); |
| 105 } |
| 106 } |
| 107 return _typeVariables; |
| 108 } |
| 109 |
| 110 Iterable<Dart2JsMemberMirror> _getDeclarationMirrors(Element element) { |
| 111 if (element.isTypeVariable()) { |
| 112 assert(invariant(_element, _element == element.enclosingElement, |
| 113 message: 'Foreigned type variable element $element.')); |
| 114 for (Dart2JsTypeVariableMirror mirror in typeVariables) { |
| 115 if (mirror._element == element) return [mirror]; |
| 116 } |
| 117 } |
| 118 return super._getDeclarationMirrors(element); |
| 119 } |
| 120 |
| 121 TypeMirror _getTypeMirror(DartType type, [FunctionSignature signature]) { |
| 122 return super._getTypeMirror( |
| 123 type.subst(_type.typeArguments, _type.element.typeVariables), |
| 124 signature); |
| 125 } |
| 126 |
| 127 TypeSourceMirror createInstantiation( |
| 128 List<TypeSourceMirror> newTypeArguments) { |
| 129 if (newTypeArguments.isEmpty) return owner._getTypeMirror(_type.asRaw()); |
| 130 if (newTypeArguments.length != typeVariables.length) { |
| 131 throw new ArgumentError('Cannot create generic instantiation of $_type ' |
| 132 'with ${newTypeArguments.length} arguments, ' |
| 133 'expect ${typeVariables.length} arguments.'); |
| 134 } |
| 135 LinkBuilder<DartType> builder = new LinkBuilder<DartType>(); |
| 136 for (TypeSourceMirror newTypeArgument in newTypeArguments) { |
| 137 if (newTypeArgument.isVoid) { |
| 138 throw new ArgumentError('Cannot use void as type argument.'); |
| 139 } |
| 140 if (newTypeArgument is Dart2JsTypeMirror) { |
| 141 builder.addLast(newTypeArgument._type); |
| 142 } else { |
| 143 throw new UnsupportedError( |
| 144 'Cannot create instantiation using a type ' |
| 145 'mirror from a different mirrorSystem implementation.'); |
| 146 } |
| 147 } |
| 148 return owner._getTypeMirror(_type.createInstantiation(builder.toLink())); |
| 149 } |
| 150 } |
| 151 |
| 152 class Dart2JsInterfaceTypeMirror |
| 153 extends Dart2JsGenericTypeMirror |
| 154 with ObjectMirrorMixin, InstanceMirrorMixin, ClassMirrorMixin, |
| 155 ContainerMixin |
| 156 implements ClassMirror { |
| 157 Dart2JsInterfaceTypeMirror(Dart2JsMirrorSystem system, |
| 158 InterfaceType interfaceType) |
| 159 : super(system, interfaceType); |
| 160 |
| 161 ClassElement get _element => super._element; |
| 162 |
| 163 InterfaceType get _type => super._type; |
| 164 |
| 165 bool get isNameSynthetic { |
| 166 if (_element.isMixinApplication) { |
| 167 MixinApplicationElement mixinApplication = _element; |
| 168 return mixinApplication.isUnnamedMixinApplication; |
| 169 } |
| 170 return false; |
| 171 } |
| 172 |
| 173 void _forEachElement(f(Element element)) { |
| 174 _element.forEachMember((_, element) => f(element)); |
| 175 } |
| 176 |
| 177 ClassMirror get superclass { |
| 178 if (_element.supertype != null) { |
| 179 return _getTypeMirror(_element.supertype); |
| 180 } |
| 181 return null; |
| 182 } |
| 183 |
| 184 ClassMirror get mixin { |
| 185 if (_element.isMixinApplication) { |
| 186 MixinApplicationElement mixinApplication = _element; |
| 187 return _getTypeMirror(mixinApplication.mixinType); |
| 188 } |
| 189 return this; |
| 190 } |
| 191 |
| 192 List<ClassMirror> get superinterfaces { |
| 193 var list = <ClassMirror>[]; |
| 194 Link<DartType> link = _element.interfaces; |
| 195 while (!link.isEmpty) { |
| 196 var type = _getTypeMirror(link.head); |
| 197 list.add(type); |
| 198 link = link.tail; |
| 199 } |
| 200 return list; |
| 201 } |
| 202 |
| 203 Map<Symbol, MethodMirror> get instanceMembers => null; |
| 204 Map<Symbol, MethodMirror> get staticMembers => null; |
| 205 |
| 206 bool get isAbstract => _element.modifiers.isAbstract(); |
| 207 |
| 208 bool operator ==(other) { |
| 209 if (identical(this, other)) { |
| 210 return true; |
| 211 } |
| 212 if (other is! ClassMirror) { |
| 213 return false; |
| 214 } |
| 215 return _type == other._type; |
| 216 } |
| 217 |
| 218 String toString() => 'Mirror on interface type $_type'; |
| 219 } |
| 220 |
| 221 class Dart2JsClassDeclarationMirror |
| 222 extends Dart2JsInterfaceTypeMirror |
| 223 with DeclarationMixin { |
| 224 |
| 225 Dart2JsClassDeclarationMirror(Dart2JsMirrorSystem system, |
| 226 InterfaceType type) |
| 227 : super(system, type); |
| 228 |
| 229 String toString() => 'Mirror on class ${_type.name}'; |
| 230 } |
| 231 |
| 232 class Dart2JsTypedefMirror |
| 233 extends Dart2JsGenericTypeMirror |
| 234 implements TypedefMirror { |
| 235 final Dart2JsLibraryMirror _library; |
| 236 List<TypeVariableMirror> _typeVariables; |
| 237 var _definition; |
| 238 |
| 239 Dart2JsTypedefMirror(Dart2JsMirrorSystem system, TypedefType _typedef) |
| 240 : this._library = system._getLibrary(_typedef.element.getLibrary()), |
| 241 super(system, _typedef); |
| 242 |
| 243 Dart2JsTypedefMirror.fromLibrary(Dart2JsLibraryMirror library, |
| 244 TypedefType _typedef) |
| 245 : this._library = library, |
| 246 super(library.mirrorSystem, _typedef); |
| 247 |
| 248 TypedefType get _typedef => _type; |
| 249 |
| 250 LibraryMirror get library => _library; |
| 251 |
| 252 bool get isTypedef => true; |
| 253 |
| 254 FunctionTypeMirror get referent { |
| 255 if (_definition == null) { |
| 256 _definition = _getTypeMirror( |
| 257 _typedef.element.alias, |
| 258 _typedef.element.functionSignature); |
| 259 } |
| 260 return _definition; |
| 261 } |
| 262 |
| 263 bool get isClass => false; |
| 264 |
| 265 bool get isAbstract => false; |
| 266 |
| 267 String toString() => 'Mirror on typedef $_type'; |
| 268 } |
| 269 |
| 270 class Dart2JsTypedefDeclarationMirror |
| 271 extends Dart2JsTypedefMirror |
| 272 with DeclarationMixin { |
| 273 Dart2JsTypedefDeclarationMirror(Dart2JsMirrorSystem system, |
| 274 TypedefType type) |
| 275 : super(system, type); |
| 276 |
| 277 String toString() => 'Mirror on typedef ${_type.name}'; |
| 278 } |
| 279 |
| 280 class Dart2JsTypeVariableMirror extends Dart2JsTypeMirror |
| 281 implements TypeVariableMirror { |
| 282 Dart2JsDeclarationMirror _owner; |
| 283 |
| 284 Dart2JsTypeVariableMirror(Dart2JsMirrorSystem system, |
| 285 TypeVariableType typeVariableType) |
| 286 : super(system, typeVariableType); |
| 287 |
| 288 TypeVariableType get _type => super._type; |
| 289 |
| 290 Dart2JsDeclarationMirror get owner { |
| 291 if (_owner == null) { |
| 292 _owner = mirrorSystem._getTypeDeclarationMirror( |
| 293 _type.element.enclosingElement); |
| 294 } |
| 295 return _owner; |
| 296 } |
| 297 |
| 298 TypeMirror get upperBound => owner._getTypeMirror(_type.element.bound); |
| 299 |
| 300 bool operator ==(var other) { |
| 301 if (identical(this, other)) { |
| 302 return true; |
| 303 } |
| 304 if (other is! TypeVariableMirror) { |
| 305 return false; |
| 306 } |
| 307 if (owner != other.owner) { |
| 308 return false; |
| 309 } |
| 310 return qualifiedName == other.qualifiedName; |
| 311 } |
| 312 |
| 313 String toString() => 'Mirror on type variable $_type'; |
| 314 } |
| 315 |
| 316 class Dart2JsFunctionTypeMirror extends Dart2JsTypeMirror |
| 317 with ObjectMirrorMixin, InstanceMirrorMixin, |
| 318 ClassMirrorMixin, DeclarationMixin |
| 319 implements FunctionTypeMirror { |
| 320 final FunctionSignature _functionSignature; |
| 321 List<ParameterMirror> _parameters; |
| 322 |
| 323 Dart2JsFunctionTypeMirror(Dart2JsMirrorSystem system, |
| 324 FunctionType functionType, this._functionSignature) |
| 325 : super(system, functionType) { |
| 326 assert (_functionSignature != null); |
| 327 } |
| 328 |
| 329 FunctionType get _type => super._type; |
| 330 |
| 331 // TODO(johnniwinther): Is this the qualified name of a function type? |
| 332 Symbol get qualifiedName => originalDeclaration.qualifiedName; |
| 333 |
| 334 // TODO(johnniwinther): Substitute type arguments for type variables. |
| 335 Map<Symbol, DeclarationMirror> get declarations { |
| 336 var method = callMethod; |
| 337 if (method != null) { |
| 338 var map = new Map<Symbol, DeclarationMirror>.from( |
| 339 originalDeclaration.declarations); |
| 340 var name = method.qualifiedName; |
| 341 assert(!map.containsKey(name)); |
| 342 map[name] = method; |
| 343 return new ImmutableMapWrapper<Symbol, DeclarationMirror>(map); |
| 344 } |
| 345 return originalDeclaration.declarations; |
| 346 } |
| 347 |
| 348 bool get isFunction => true; |
| 349 |
| 350 MethodMirror get callMethod => _convertElementMethodToMethodMirror( |
| 351 mirrorSystem._getLibrary(_type.element.getLibrary()), |
| 352 _type.element); |
| 353 |
| 354 ClassMirror get originalDeclaration => |
| 355 mirrorSystem._getTypeDeclarationMirror( |
| 356 mirrorSystem.compiler.functionClass); |
| 357 |
| 358 // TODO(johnniwinther): Substitute type arguments for type variables. |
| 359 ClassMirror get superclass => originalDeclaration.superclass; |
| 360 |
| 361 // TODO(johnniwinther): Substitute type arguments for type variables. |
| 362 List<ClassMirror> get superinterfaces => originalDeclaration.superinterfaces; |
| 363 |
| 364 Map<Symbol, MethodMirror> get instanceMembers => null; |
| 365 Map<Symbol, MethodMirror> get staticMembers => null; |
| 366 |
| 367 ClassMirror get mixin => this; |
| 368 |
| 369 bool get isPrivate => false; |
| 370 |
| 371 bool get isAbstract => false; |
| 372 |
| 373 List<TypeVariableMirror> get typeVariables => |
| 374 originalDeclaration.typeVariables; |
| 375 |
| 376 TypeMirror get returnType => owner._getTypeMirror(_type.returnType); |
| 377 |
| 378 List<ParameterMirror> get parameters { |
| 379 if (_parameters == null) { |
| 380 _parameters = _parametersFromFunctionSignature(owner, |
| 381 _functionSignature); |
| 382 } |
| 383 return _parameters; |
| 384 } |
| 385 |
| 386 String toString() => 'Mirror on function type $_type'; |
| 387 } |
| 388 |
| 389 class Dart2JsVoidMirror extends Dart2JsTypeMirror { |
| 390 |
| 391 Dart2JsVoidMirror(Dart2JsMirrorSystem system, VoidType voidType) |
| 392 : super(system, voidType); |
| 393 |
| 394 VoidType get _voidType => _type; |
| 395 |
| 396 Symbol get qualifiedName => simpleName; |
| 397 |
| 398 /** |
| 399 * The void type has no location. |
| 400 */ |
| 401 SourceLocation get location => null; |
| 402 |
| 403 /** |
| 404 * The void type has no library. |
| 405 */ |
| 406 LibraryMirror get library => null; |
| 407 |
| 408 bool get isVoid => true; |
| 409 |
| 410 bool operator ==(other) { |
| 411 if (identical(this, other)) { |
| 412 return true; |
| 413 } |
| 414 if (other is! TypeMirror) { |
| 415 return false; |
| 416 } |
| 417 return other.isVoid; |
| 418 } |
| 419 |
| 420 int get hashCode => 13 * _element.hashCode; |
| 421 |
| 422 String toString() => 'Mirror on void'; |
| 423 } |
| 424 |
| 425 class Dart2JsDynamicMirror extends Dart2JsTypeMirror { |
| 426 Dart2JsDynamicMirror(Dart2JsMirrorSystem system, InterfaceType voidType) |
| 427 : super(system, voidType); |
| 428 |
| 429 InterfaceType get _dynamicType => _type; |
| 430 |
| 431 Symbol get qualifiedName => simpleName; |
| 432 |
| 433 /** |
| 434 * The dynamic type has no location. |
| 435 */ |
| 436 SourceLocation get location => null; |
| 437 |
| 438 /** |
| 439 * The dynamic type has no library. |
| 440 */ |
| 441 LibraryMirror get library => null; |
| 442 |
| 443 bool get isDynamic => true; |
| 444 |
| 445 bool operator ==(other) { |
| 446 if (identical(this, other)) { |
| 447 return true; |
| 448 } |
| 449 if (other is! TypeMirror) { |
| 450 return false; |
| 451 } |
| 452 return other.isDynamic; |
| 453 } |
| 454 |
| 455 int get hashCode => 13 * _element.hashCode; |
| 456 |
| 457 String toString() => 'Mirror on dynamic'; |
| 458 } |
OLD | NEW |