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