 Chromium Code Reviews
 Chromium Code Reviews Issue 2623053004:
  Fix noSuchMethod handling of methods that are also extension methods. Fix noSuchMethod handling of …  (Closed)
    
  
    Issue 2623053004:
  Fix noSuchMethod handling of methods that are also extension methods. Fix noSuchMethod handling of …  (Closed) 
  | OLD | NEW | 
|---|---|
| 1 // Copyright (c) 2015, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2015, the Dart project authors. Please see the AUTHORS file | 
| 2 // for details. All rights reserved. Use of this source code is governed by a | 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. | 3 // BSD-style license that can be found in the LICENSE file. | 
| 4 | 4 | 
| 5 library dart._js_mirrors; | 5 library dart._js_mirrors; | 
| 6 | 6 | 
| 7 import 'dart:mirrors'; | 7 import 'dart:mirrors'; | 
| 8 import 'dart:_foreign_helper' show JS; | 8 import 'dart:_foreign_helper' show JS; | 
| 9 import 'dart:_internal' as _internal; | 9 import 'dart:_internal' as _internal; | 
| 10 | 10 | 
| (...skipping 13 matching lines...) Expand all Loading... | |
| 24 // reflectee may be a primitive - i.e., we can't just add an expando. | 24 // reflectee may be a primitive - i.e., we can't just add an expando. | 
| 25 if (reflectee is Function) { | 25 if (reflectee is Function) { | 
| 26 return new JsClosureMirror._(reflectee); | 26 return new JsClosureMirror._(reflectee); | 
| 27 } else { | 27 } else { | 
| 28 return new JsInstanceMirror._(reflectee); | 28 return new JsInstanceMirror._(reflectee); | 
| 29 } | 29 } | 
| 30 } | 30 } | 
| 31 | 31 | 
| 32 TypeMirror reflectType(Type key) { | 32 TypeMirror reflectType(Type key) { | 
| 33 var unwrapped = _unwrap(key); | 33 var unwrapped = _unwrap(key); | 
| 34 var property = JS('', 'Object.getOwnPropertyDescriptor(#, #)', unwrapped, _typ eMirror); | 34 var property = | 
| 35 JS('', 'Object.getOwnPropertyDescriptor(#, #)', unwrapped, _typeMirror); | |
| 35 if (property != null) { | 36 if (property != null) { | 
| 36 return JS('', '#.value', property); | 37 return JS('', '#.value', property); | 
| 37 } | 38 } | 
| 38 // TODO(vsm): Might not be a class. | 39 // TODO(vsm): Might not be a class. | 
| 39 var mirror = new JsClassMirror._(key); | 40 var mirror = new JsClassMirror._(key); | 
| 40 JS('', '#[#] = #', unwrapped, _typeMirror, mirror); | 41 JS('', '#[#] = #', unwrapped, _typeMirror, mirror); | 
| 41 return mirror; | 42 return mirror; | 
| 42 } | 43 } | 
| 43 | 44 | 
| 44 final dynamic _dart = JS('', 'dart'); | 45 final dynamic _dart = JS('', 'dart'); | 
| (...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 78 typedef T _Lazy<T>(); | 79 typedef T _Lazy<T>(); | 
| 79 | 80 | 
| 80 dynamic _getESSymbol(Symbol symbol) => | 81 dynamic _getESSymbol(Symbol symbol) => | 
| 81 _internal.Symbol.getNativeSymbol(symbol as _internal.Symbol); | 82 _internal.Symbol.getNativeSymbol(symbol as _internal.Symbol); | 
| 82 | 83 | 
| 83 dynamic _getMember(Symbol symbol) { | 84 dynamic _getMember(Symbol symbol) { | 
| 84 var privateSymbol = _getESSymbol(symbol); | 85 var privateSymbol = _getESSymbol(symbol); | 
| 85 if (privateSymbol != null) { | 86 if (privateSymbol != null) { | 
| 86 return privateSymbol; | 87 return privateSymbol; | 
| 87 } | 88 } | 
| 88 return getName(symbol); | 89 var name = getName(symbol); | 
| 
Jacob
2017/01/21 01:11:30
only relevant change in this file. Rest is just th
 | |
| 90 // TODO(jacobr): this code is duplicated in code_generator.dart | |
| 91 switch (name) { | |
| 92 case '[]': | |
| 93 name = '_get'; | |
| 94 break; | |
| 95 case '[]=': | |
| 96 name = '_set'; | |
| 97 break; | |
| 98 case 'unary-': | |
| 99 name = '_negate'; | |
| 100 break; | |
| 101 case 'constructor': | |
| 102 case 'prototype': | |
| 103 name = '_$name'; | |
| 104 break; | |
| 105 } | |
| 106 return name; | |
| 89 } | 107 } | 
| 90 | 108 | 
| 91 String _getNameForESSymbol(member) { | 109 String _getNameForESSymbol(member) { | 
| 92 // Convert private JS symbol "Symbol(_foo)" to string "_foo". | 110 // Convert private JS symbol "Symbol(_foo)" to string "_foo". | 
| 93 assert(JS('bool', 'typeof # == "symbol"', member)); | 111 assert(JS('bool', 'typeof # == "symbol"', member)); | 
| 94 var str = member.toString(); | 112 var str = member.toString(); | 
| 95 assert(str.startsWith('Symbol(') && str.endsWith(')')); | 113 assert(str.startsWith('Symbol(') && str.endsWith(')')); | 
| 96 return str.substring(7, str.length - 1); | 114 return str.substring(7, str.length - 1); | 
| 97 } | 115 } | 
| 98 | 116 | 
| (...skipping 78 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 177 return _toDartMap(sig); | 195 return _toDartMap(sig); | 
| 178 } | 196 } | 
| 179 | 197 | 
| 180 // TODO(vsm): These methods need to validate whether we really have a | 198 // TODO(vsm): These methods need to validate whether we really have a | 
| 181 // WrappedType or a raw type that should be wrapped (as opposed to a | 199 // WrappedType or a raw type that should be wrapped (as opposed to a | 
| 182 // function). | 200 // function). | 
| 183 dynamic _unwrap(obj) => JS('', '#.unwrapType(#)', _dart, obj); | 201 dynamic _unwrap(obj) => JS('', '#.unwrapType(#)', _dart, obj); | 
| 184 | 202 | 
| 185 dynamic _wrap(obj) => JS('', '#.wrapType(#)', _dart, obj); | 203 dynamic _wrap(obj) => JS('', '#.wrapType(#)', _dart, obj); | 
| 186 | 204 | 
| 187 dynamic _runtimeType(obj) => | 205 dynamic _runtimeType(obj) => _wrap(JS('', '#.getReifiedType(#)', _dart, obj)); | 
| 188 _wrap(JS('', '#.getReifiedType(#)', _dart, obj)); | |
| 189 | 206 | 
| 190 _unimplemented(Type t, Invocation i) { | 207 _unimplemented(Type t, Invocation i) { | 
| 191 throw new UnimplementedError('$t.${getName(i.memberName)} unimplemented'); | 208 throw new UnimplementedError('$t.${getName(i.memberName)} unimplemented'); | 
| 192 } | 209 } | 
| 193 | 210 | 
| 194 dynamic _toJsMap(Map<Symbol, dynamic> map) { | 211 dynamic _toJsMap(Map<Symbol, dynamic> map) { | 
| 195 var obj = JS('', '{}'); | 212 var obj = JS('', '{}'); | 
| 196 map.forEach((Symbol key, value) { | 213 map.forEach((Symbol key, value) { | 
| 197 JS('', '#[#] = #', obj, getName(key), value); | 214 JS('', '#[#] = #', obj, getName(key), value); | 
| 198 }); | 215 }); | 
| 199 return obj; | 216 return obj; | 
| 200 } | 217 } | 
| 201 | 218 | 
| 202 class JsMirror implements Mirror { | 219 class JsMirror implements Mirror { | 
| 203 noSuchMethod(Invocation i) { | 220 noSuchMethod(Invocation i) { | 
| 204 _unimplemented(this.runtimeType, i); | 221 _unimplemented(this.runtimeType, i); | 
| 205 } | 222 } | 
| 206 } | 223 } | 
| 207 | 224 | 
| 208 class JsCombinatorMirror extends JsMirror implements CombinatorMirror { | 225 class JsCombinatorMirror extends JsMirror implements CombinatorMirror {} | 
| 209 } | |
| 210 | 226 | 
| 211 class JsDeclarationMirror extends JsMirror implements DeclarationMirror { | 227 class JsDeclarationMirror extends JsMirror implements DeclarationMirror {} | 
| 212 } | |
| 213 | 228 | 
| 214 class JsIsolateMirror extends JsMirror implements IsolateMirror { | 229 class JsIsolateMirror extends JsMirror implements IsolateMirror {} | 
| 215 } | |
| 216 | 230 | 
| 217 class JsLibraryDependencyMirror extends JsMirror implements LibraryDependencyMir ror { | 231 class JsLibraryDependencyMirror extends JsMirror | 
| 218 } | 232 implements LibraryDependencyMirror {} | 
| 219 | 233 | 
| 220 class JsObjectMirror extends JsMirror implements ObjectMirror { | 234 class JsObjectMirror extends JsMirror implements ObjectMirror {} | 
| 221 } | |
| 222 | 235 | 
| 223 class JsInstanceMirror extends JsObjectMirror implements InstanceMirror { | 236 class JsInstanceMirror extends JsObjectMirror implements InstanceMirror { | 
| 224 | |
| 225 // Reflected object | 237 // Reflected object | 
| 226 final reflectee; | 238 final reflectee; | 
| 227 bool get hasReflectee => true; | 239 bool get hasReflectee => true; | 
| 228 | 240 | 
| 229 ClassMirror get type { | 241 ClassMirror get type { | 
| 230 // The spec guarantees that `null` is the singleton instance of the `Null` | 242 // The spec guarantees that `null` is the singleton instance of the `Null` | 
| 231 // class. | 243 // class. | 
| 232 if (reflectee == null) return reflectClass(Null); | 244 if (reflectee == null) return reflectClass(Null); | 
| 233 return reflectType(_runtimeType(reflectee)); | 245 return reflectType(_runtimeType(reflectee)); | 
| 234 } | 246 } | 
| 235 | 247 | 
| 236 JsInstanceMirror._(this.reflectee); | 248 JsInstanceMirror._(this.reflectee); | 
| 237 | 249 | 
| 238 bool operator==(Object other) { | 250 bool operator ==(Object other) { | 
| 239 return (other is JsInstanceMirror) && identical(reflectee, other.reflectee); | 251 return (other is JsInstanceMirror) && identical(reflectee, other.reflectee); | 
| 240 } | 252 } | 
| 241 | 253 | 
| 242 int get hashCode { | 254 int get hashCode { | 
| 243 // Avoid hash collisions with the reflectee. This constant is in Smi range | 255 // Avoid hash collisions with the reflectee. This constant is in Smi range | 
| 244 // and happens to be the inner padding from RFC 2104. | 256 // and happens to be the inner padding from RFC 2104. | 
| 245 return identityHashCode(reflectee) ^ 0x36363636; | 257 return identityHashCode(reflectee) ^ 0x36363636; | 
| 246 } | 258 } | 
| 247 | 259 | 
| 248 // Returns a String for public members or an ES6 symbol for private members. | 260 // Returns a String for public members or an ES6 symbol for private members. | 
| 249 _getAccessor(dynamic reflectee, Symbol symbol, [List<dynamic> args, | 261 _getAccessor(dynamic reflectee, Symbol symbol, | 
| 250 Map<Symbol, dynamic> namedArgs]) { | 262 [List<dynamic> args, Map<Symbol, dynamic> namedArgs]) { | 
| 251 return _getMember(symbol); | 263 return _getMember(symbol); | 
| 252 } | 264 } | 
| 253 | 265 | 
| 254 InstanceMirror getField(Symbol symbol) { | 266 InstanceMirror getField(Symbol symbol) { | 
| 255 var name = _getAccessor(reflectee, symbol); | 267 var name = _getAccessor(reflectee, symbol); | 
| 256 var field = _dload(reflectee, name); | 268 var field = _dload(reflectee, name); | 
| 257 return reflect(field); | 269 return reflect(field); | 
| 258 } | 270 } | 
| 259 | 271 | 
| 260 InstanceMirror setField(Symbol symbol, Object value) { | 272 InstanceMirror setField(Symbol symbol, Object value) { | 
| (...skipping 12 matching lines...) Expand all Loading... | |
| 273 var result = _dsend(reflectee, name, args); | 285 var result = _dsend(reflectee, name, args); | 
| 274 return reflect(result); | 286 return reflect(result); | 
| 275 } | 287 } | 
| 276 | 288 | 
| 277 String toString() => "InstanceMirror on '$reflectee'"; | 289 String toString() => "InstanceMirror on '$reflectee'"; | 
| 278 } | 290 } | 
| 279 | 291 | 
| 280 class JsClosureMirror extends JsInstanceMirror implements ClosureMirror { | 292 class JsClosureMirror extends JsInstanceMirror implements ClosureMirror { | 
| 281 JsClosureMirror._(reflectee) : super._(reflectee); | 293 JsClosureMirror._(reflectee) : super._(reflectee); | 
| 282 | 294 | 
| 283 InstanceMirror apply(List<dynamic> args, | 295 InstanceMirror apply(List<dynamic> args, [Map<Symbol, dynamic> namedArgs]) { | 
| 284 [Map<Symbol, dynamic> namedArgs]) { | |
| 285 if (namedArgs != null) { | 296 if (namedArgs != null) { | 
| 286 args = new List.from(args); | 297 args = new List.from(args); | 
| 287 args.add(_toJsMap(namedArgs)); | 298 args.add(_toJsMap(namedArgs)); | 
| 288 } | 299 } | 
| 289 var result = _dcall(reflectee, args); | 300 var result = _dcall(reflectee, args); | 
| 290 return reflect(result); | 301 return reflect(result); | 
| 291 } | 302 } | 
| 292 } | 303 } | 
| 293 | 304 | 
| 294 class JsClassMirror extends JsMirror implements ClassMirror { | 305 class JsClassMirror extends JsMirror implements ClassMirror { | 
| 295 final Type _cls; | 306 final Type _cls; | 
| 296 final Symbol simpleName; | 307 final Symbol simpleName; | 
| 297 // Generic class factory | 308 // Generic class factory | 
| 298 final dynamic _raw; | 309 final dynamic _raw; | 
| 299 | 310 | 
| 300 // TODO(vsm): Do this properly | 311 // TODO(vsm): Do this properly | 
| 301 ClassMirror _mixin = null; | 312 ClassMirror _mixin = null; | 
| 302 List<TypeMirror> _typeArguments; | 313 List<TypeMirror> _typeArguments; | 
| 303 | 314 | 
| 304 List<InstanceMirror> _metadata; | 315 List<InstanceMirror> _metadata; | 
| 305 Map<Symbol, DeclarationMirror> _declarations; | 316 Map<Symbol, DeclarationMirror> _declarations; | 
| 306 | 317 | 
| 307 List<InstanceMirror> get metadata { | 318 List<InstanceMirror> get metadata { | 
| 308 if (_metadata == null) { | 319 if (_metadata == null) { | 
| 309 // Load metadata. | 320 // Load metadata. | 
| 310 var unwrapped = _unwrap(_cls); | 321 var unwrapped = _unwrap(_cls); | 
| 311 // Only get metadata directly embedded on this class, not its | 322 // Only get metadata directly embedded on this class, not its | 
| 312 // superclasses. | 323 // superclasses. | 
| 313 var fn = JS('Function', | 324 var fn = JS( | 
| 314 'Object.hasOwnProperty.call(#, dart.metadata) ? #[dart.metadata] : null' , | 325 'Function', | 
| 315 unwrapped, unwrapped); | 326 'Object.hasOwnProperty.call(#, dart.metadata) ? #[dart.metadata] : nul l', | 
| 327 unwrapped, | |
| 328 unwrapped); | |
| 316 _metadata = (fn == null) | 329 _metadata = (fn == null) | 
| 317 ? const <InstanceMirror>[] | 330 ? const <InstanceMirror>[] | 
| 318 : new List<InstanceMirror>.unmodifiable( | 331 : new List<InstanceMirror>.unmodifiable(fn().map((i) => reflect(i))); | 
| 319 fn().map((i) => reflect(i))); | |
| 320 } | 332 } | 
| 321 return _metadata; | 333 return _metadata; | 
| 322 } | 334 } | 
| 323 | 335 | 
| 324 Map<Symbol, DeclarationMirror> get declarations { | 336 Map<Symbol, DeclarationMirror> get declarations { | 
| 325 if (_declarations == null) { | 337 if (_declarations == null) { | 
| 326 // Load declarations. | 338 // Load declarations. | 
| 327 // TODO(vsm): This is only populating the default constructor right now. | 339 // TODO(vsm): This is only populating the default constructor right now. | 
| 328 _declarations = new Map<Symbol, DeclarationMirror>(); | 340 _declarations = new Map<Symbol, DeclarationMirror>(); | 
| 329 var unwrapped = _unwrap(_cls); | 341 var unwrapped = _unwrap(_cls); | 
| 330 var constructors = _getConstructors(unwrapped); | 342 var constructors = _getConstructors(unwrapped); | 
| 331 constructors.forEach((symbol, ft) { | 343 constructors.forEach((symbol, ft) { | 
| 332 var name = getName(symbol); | 344 var name = getName(symbol); | 
| 333 _declarations[symbol] = new JsMethodMirror._constructor(this, symbol, ft ); | 345 _declarations[symbol] = | 
| 346 new JsMethodMirror._constructor(this, symbol, ft); | |
| 334 }); | 347 }); | 
| 335 if (constructors.isEmpty) { | 348 if (constructors.isEmpty) { | 
| 336 // Add a default | 349 // Add a default | 
| 337 var name = 'new'; | 350 var name = 'new'; | 
| 338 var ft = _defaultConstructorType(_unwrap(_cls)); | 351 var ft = _defaultConstructorType(_unwrap(_cls)); | 
| 339 var symbol = new Symbol(name); | 352 var symbol = new Symbol(name); | 
| 340 _declarations[symbol] = new JsMethodMirror._constructor(this, symbol, ft ); | 353 _declarations[symbol] = | 
| 354 new JsMethodMirror._constructor(this, symbol, ft); | |
| 341 } | 355 } | 
| 342 var fields = _getFields(unwrapped); | 356 var fields = _getFields(unwrapped); | 
| 343 fields.forEach((symbol, t) { | 357 fields.forEach((symbol, t) { | 
| 344 var metadata = []; | 358 var metadata = []; | 
| 345 if (t is List) { | 359 if (t is List) { | 
| 346 metadata = t.skip(1).toList(); | 360 metadata = t.skip(1).toList(); | 
| 347 t = t[0]; | 361 t = t[0]; | 
| 348 } | 362 } | 
| 349 _declarations[symbol] = new JsVariableMirror._(symbol, _wrap(t), metadat a); | 363 _declarations[symbol] = | 
| 364 new JsVariableMirror._(symbol, _wrap(t), metadata); | |
| 350 }); | 365 }); | 
| 351 var methods = _getMethods(unwrapped); | 366 var methods = _getMethods(unwrapped); | 
| 352 methods.forEach((symbol, ft) { | 367 methods.forEach((symbol, ft) { | 
| 353 var name = getName(symbol); | 368 var name = getName(symbol); | 
| 354 _declarations[symbol] = new JsMethodMirror._instanceMethod(this, symbol, ft); | 369 _declarations[symbol] = | 
| 370 new JsMethodMirror._instanceMethod(this, symbol, ft); | |
| 355 }); | 371 }); | 
| 356 var getters = _getGetters(unwrapped); | 372 var getters = _getGetters(unwrapped); | 
| 357 getters.forEach((symbol, ft) { | 373 getters.forEach((symbol, ft) { | 
| 358 var name = getName(symbol); | 374 var name = getName(symbol); | 
| 359 _declarations[symbol] = new JsMethodMirror._instanceMethod(this, symbol, ft); | 375 _declarations[symbol] = | 
| 376 new JsMethodMirror._instanceMethod(this, symbol, ft); | |
| 360 }); | 377 }); | 
| 361 var setters = _getSetters(unwrapped); | 378 var setters = _getSetters(unwrapped); | 
| 362 setters.forEach((symbol, ft) { | 379 setters.forEach((symbol, ft) { | 
| 363 var name = getName(symbol) + '='; | 380 var name = getName(symbol) + '='; | 
| 364 // Create a separate symbol for the setter. | 381 // Create a separate symbol for the setter. | 
| 365 symbol = new _internal.Symbol.es6(name, _getESSymbol(symbol)); | 382 symbol = new _internal.Symbol.es6(name, _getESSymbol(symbol)); | 
| 366 _declarations[symbol] = new JsMethodMirror._instanceMethod(this, symbol, ft); | 383 _declarations[symbol] = | 
| 384 new JsMethodMirror._instanceMethod(this, symbol, ft); | |
| 367 }); | 385 }); | 
| 368 var staticFields = _getStaticFields(unwrapped); | 386 var staticFields = _getStaticFields(unwrapped); | 
| 369 staticFields.forEach((symbol, t) { | 387 staticFields.forEach((symbol, t) { | 
| 370 var name = getName(symbol); | 388 var name = getName(symbol); | 
| 371 var metadata = []; | 389 var metadata = []; | 
| 372 if (t is List) { | 390 if (t is List) { | 
| 373 metadata = t.skip(1).toList(); | 391 metadata = t.skip(1).toList(); | 
| 374 t = t[0]; | 392 t = t[0]; | 
| 375 } | 393 } | 
| 376 _declarations[symbol] = new JsVariableMirror._(symbol, _wrap(t), metadat a); | 394 _declarations[symbol] = | 
| 395 new JsVariableMirror._(symbol, _wrap(t), metadata); | |
| 377 }); | 396 }); | 
| 378 var statics = _getStatics(unwrapped); | 397 var statics = _getStatics(unwrapped); | 
| 379 statics.forEach((symbol, ft) { | 398 statics.forEach((symbol, ft) { | 
| 380 var name = getName(symbol); | 399 var name = getName(symbol); | 
| 381 _declarations[symbol] = new JsMethodMirror._staticMethod(this, symbol, f t); | 400 _declarations[symbol] = | 
| 401 new JsMethodMirror._staticMethod(this, symbol, ft); | |
| 382 }); | 402 }); | 
| 383 var staticGetters = _getStaticGetters(unwrapped); | 403 var staticGetters = _getStaticGetters(unwrapped); | 
| 384 staticGetters.forEach((symbol, ft) { | 404 staticGetters.forEach((symbol, ft) { | 
| 385 var name = getName(symbol); | 405 var name = getName(symbol); | 
| 386 _declarations[symbol] = new JsMethodMirror._staticMethod(this, symbol, f t); | 406 _declarations[symbol] = | 
| 407 new JsMethodMirror._staticMethod(this, symbol, ft); | |
| 387 }); | 408 }); | 
| 388 var staticSetters = _getStaticSetters(unwrapped); | 409 var staticSetters = _getStaticSetters(unwrapped); | 
| 389 staticSetters.forEach((symbol, ft) { | 410 staticSetters.forEach((symbol, ft) { | 
| 390 var name = getName(symbol); | 411 var name = getName(symbol); | 
| 391 _declarations[symbol] = new JsMethodMirror._staticMethod(this, symbol, f t); | 412 _declarations[symbol] = | 
| 413 new JsMethodMirror._staticMethod(this, symbol, ft); | |
| 392 }); | 414 }); | 
| 393 _declarations = new Map<Symbol, DeclarationMirror>.unmodifiable(_declarati ons); | 415 _declarations = | 
| 416 new Map<Symbol, DeclarationMirror>.unmodifiable(_declarations); | |
| 394 } | 417 } | 
| 395 return _declarations; | 418 return _declarations; | 
| 396 } | 419 } | 
| 397 | 420 | 
| 398 JsClassMirror._(Type cls) | 421 JsClassMirror._(Type cls) | 
| 399 : _cls = cls, | 422 : _cls = cls, | 
| 400 _raw = _getGenericClass(_unwrap(cls)), | 423 _raw = _getGenericClass(_unwrap(cls)), | 
| 401 simpleName = new Symbol(JS('String', '#.name', _unwrap(cls))) { | 424 simpleName = new Symbol(JS('String', '#.name', _unwrap(cls))) { | 
| 402 var typeArgs = _getGenericArgs(_unwrap(cls)); | 425 var typeArgs = _getGenericArgs(_unwrap(cls)); | 
| 403 if (typeArgs == null) { | 426 if (typeArgs == null) { | 
| 404 _typeArguments = const[]; | 427 _typeArguments = const []; | 
| 405 } else { | 428 } else { | 
| 406 _typeArguments = new List.unmodifiable(typeArgs.map((t) => reflectType(_wr ap(t)))); | 429 _typeArguments = | 
| 430 new List.unmodifiable(typeArgs.map((t) => reflectType(_wrap(t)))); | |
| 407 } | 431 } | 
| 408 } | 432 } | 
| 409 | 433 | 
| 410 InstanceMirror newInstance(Symbol constructorName, List args, | 434 InstanceMirror newInstance(Symbol constructorName, List args, | 
| 411 [Map<Symbol, dynamic> namedArgs]) { | 435 [Map<Symbol, dynamic> namedArgs]) { | 
| 412 // TODO(vsm): Support factory constructors and named arguments. | 436 // TODO(vsm): Support factory constructors and named arguments. | 
| 413 var name = getName(constructorName); | 437 var name = getName(constructorName); | 
| 414 assert(namedArgs == null || namedArgs.isEmpty); | 438 assert(namedArgs == null || namedArgs.isEmpty); | 
| 415 var instance = (name == 'new' || name == '') | 439 var instance = (name == 'new' || name == '') | 
| 416 ? JS('', 'new #(...#)', _unwrap(_cls), args) | 440 ? JS('', 'new #(...#)', _unwrap(_cls), args) | 
| 417 : JS('', 'new (#.#)(...#)', _unwrap(_cls), name, args); | 441 : JS('', 'new (#.#)(...#)', _unwrap(_cls), name, args); | 
| 418 return reflect(instance); | 442 return reflect(instance); | 
| 419 } | 443 } | 
| 420 | 444 | 
| 421 // TODO(vsm): Need to check for NSM, types on accessors below. Unlike the | 445 // TODO(vsm): Need to check for NSM, types on accessors below. Unlike the | 
| 422 // InstanceMirror case, there is no dynamic helper to delegate to - we never | 446 // InstanceMirror case, there is no dynamic helper to delegate to - we never | 
| 423 // need a dload, etc. on a static. | 447 // need a dload, etc. on a static. | 
| 424 | 448 | 
| 425 InstanceMirror getField(Symbol symbol) { | 449 InstanceMirror getField(Symbol symbol) { | 
| 426 var name = getName(symbol); | 450 var name = getName(symbol); | 
| 427 return reflect(JS('', '#[#]', _unwrap(_cls), name)); | 451 return reflect(JS('', '#[#]', _unwrap(_cls), name)); | 
| (...skipping 10 matching lines...) Expand all Loading... | |
| 438 var name = getName(symbol); | 462 var name = getName(symbol); | 
| 439 if (namedArgs != null) { | 463 if (namedArgs != null) { | 
| 440 args = new List.from(args); | 464 args = new List.from(args); | 
| 441 args.add(_toJsMap(namedArgs)); | 465 args.add(_toJsMap(namedArgs)); | 
| 442 } | 466 } | 
| 443 var result = JS('', '#.#(...#)', _unwrap(_cls), name, args); | 467 var result = JS('', '#.#(...#)', _unwrap(_cls), name, args); | 
| 444 return reflect(result); | 468 return reflect(result); | 
| 445 } | 469 } | 
| 446 | 470 | 
| 447 List<ClassMirror> get superinterfaces { | 471 List<ClassMirror> get superinterfaces { | 
| 448 _Lazy<List<Type>> interfaceThunk = JS('', '#[dart.implements]', _unwrap(_cls )); | 472 _Lazy<List<Type>> interfaceThunk = | 
| 473 JS('', '#[dart.implements]', _unwrap(_cls)); | |
| 449 if (interfaceThunk == null) { | 474 if (interfaceThunk == null) { | 
| 450 return []; | 475 return []; | 
| 451 } else { | 476 } else { | 
| 452 List<Type> interfaces = interfaceThunk(); | 477 List<Type> interfaces = interfaceThunk(); | 
| 453 return interfaces.map((t) => reflectType(t)).toList(); | 478 return interfaces.map((t) => reflectType(t)).toList(); | 
| 454 } | 479 } | 
| 455 } | 480 } | 
| 456 | 481 | 
| 457 bool get hasReflectedType => true; | 482 bool get hasReflectedType => true; | 
| 458 Type get reflectedType { return _cls; } | 483 Type get reflectedType { | 
| 484 return _cls; | |
| 485 } | |
| 459 | 486 | 
| 460 bool get isOriginalDeclaration => _raw == null; | 487 bool get isOriginalDeclaration => _raw == null; | 
| 461 | 488 | 
| 462 List<TypeMirror> get typeArguments => _typeArguments; | 489 List<TypeMirror> get typeArguments => _typeArguments; | 
| 463 | 490 | 
| 464 TypeMirror get originalDeclaration { | 491 TypeMirror get originalDeclaration { | 
| 465 // TODO(vsm): Handle generic case. How should we represent an original | 492 // TODO(vsm): Handle generic case. How should we represent an original | 
| 466 // declaration for a generic class? | 493 // declaration for a generic class? | 
| 467 if (_raw == null) { | 494 if (_raw == null) { | 
| 468 return this; | 495 return this; | 
| 469 } | 496 } | 
| 470 throw new UnimplementedError("ClassMirror.originalDeclaration unimplemented" ); | 497 throw new UnimplementedError( | 
| 498 "ClassMirror.originalDeclaration unimplemented"); | |
| 471 } | 499 } | 
| 472 | 500 | 
| 473 ClassMirror get superclass { | 501 ClassMirror get superclass { | 
| 474 if (_cls == Object) { | 502 if (_cls == Object) { | 
| 475 return null; | 503 return null; | 
| 476 } else { | 504 } else { | 
| 477 return reflectType(_wrap(JS('Type', '#.__proto__', _unwrap(_cls)))); | 505 return reflectType(_wrap(JS('Type', '#.__proto__', _unwrap(_cls)))); | 
| 478 } | 506 } | 
| 479 } | 507 } | 
| 480 | 508 | 
| 481 ClassMirror get mixin { | 509 ClassMirror get mixin { | 
| 482 if (_mixin != null) { | 510 if (_mixin != null) { | 
| 483 return _mixin; | 511 return _mixin; | 
| 484 } | 512 } | 
| 485 var mixins = _getMixins(_unwrap(_cls)); | 513 var mixins = _getMixins(_unwrap(_cls)); | 
| 486 if (mixins == null || mixins.isEmpty) { | 514 if (mixins == null || mixins.isEmpty) { | 
| 487 // If there is no mixin, return this mirror per API. | 515 // If there is no mixin, return this mirror per API. | 
| 488 _mixin = this; | 516 _mixin = this; | 
| 489 return _mixin; | 517 return _mixin; | 
| 490 } | 518 } | 
| 491 if (mixins.length > 1) { | 519 if (mixins.length > 1) { | 
| 492 throw new UnsupportedError("ClassMirror.mixin not yet supported for " | 520 throw new UnsupportedError("ClassMirror.mixin not yet supported for " | 
| 493 "classes ($_cls) with multiple mixins"); | 521 "classes ($_cls) with multiple mixins"); | 
| 494 } | 522 } | 
| 495 _mixin = reflectType(_wrap(mixins[0])); | 523 _mixin = reflectType(_wrap(mixins[0])); | 
| 496 return _mixin; | 524 return _mixin; | 
| 497 } | 525 } | 
| 498 | 526 | 
| 499 String toString() => "ClassMirror on '$_cls'"; | 527 String toString() => "ClassMirror on '$_cls'"; | 
| 500 } | 528 } | 
| 501 | 529 | 
| 502 class JsVariableMirror extends JsMirror implements VariableMirror { | 530 class JsVariableMirror extends JsMirror implements VariableMirror { | 
| 503 final Symbol _symbol; | 531 final Symbol _symbol; | 
| (...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 539 | 567 | 
| 540 // TODO(vsm): Fix this | 568 // TODO(vsm): Fix this | 
| 541 final bool isFinal = false; | 569 final bool isFinal = false; | 
| 542 bool get isSetter => _name.endsWith('='); | 570 bool get isSetter => _name.endsWith('='); | 
| 543 bool get isPrivate => _name.startsWith('_'); | 571 bool get isPrivate => _name.startsWith('_'); | 
| 544 | 572 | 
| 545 // TODO(vsm): Refactor this out. | 573 // TODO(vsm): Refactor this out. | 
| 546 Symbol get simpleName => _symbol; | 574 Symbol get simpleName => _symbol; | 
| 547 | 575 | 
| 548 JsMethodMirror._constructor(JsClassMirror cls, Symbol symbol, ftype) | 576 JsMethodMirror._constructor(JsClassMirror cls, Symbol symbol, ftype) | 
| 549 : _symbol = symbol, _name = getName(symbol), isConstructor = true, isStatic = false { | 577 : _symbol = symbol, | 
| 550 _createParameterMirrorList(ftype); | 578 _name = getName(symbol), | 
| 579 isConstructor = true, | |
| 580 isStatic = false { | |
| 581 _createParameterMirrorList(ftype); | |
| 551 } | 582 } | 
| 552 | 583 | 
| 553 JsMethodMirror._instanceMethod(JsClassMirror cls, Symbol symbol, ftype) | 584 JsMethodMirror._instanceMethod(JsClassMirror cls, Symbol symbol, ftype) | 
| 554 : _symbol = symbol, _name = getName(symbol), isConstructor = false, isStatic = false { | 585 : _symbol = symbol, | 
| 555 _createParameterMirrorList(ftype); | 586 _name = getName(symbol), | 
| 587 isConstructor = false, | |
| 588 isStatic = false { | |
| 589 _createParameterMirrorList(ftype); | |
| 556 } | 590 } | 
| 557 | 591 | 
| 558 JsMethodMirror._staticMethod(JsClassMirror cls, Symbol symbol, ftype) | 592 JsMethodMirror._staticMethod(JsClassMirror cls, Symbol symbol, ftype) | 
| 559 : _symbol = symbol, _name = getName(symbol), isConstructor = false, isStatic = true { | 593 : _symbol = symbol, | 
| 560 _createParameterMirrorList(ftype); | 594 _name = getName(symbol), | 
| 595 isConstructor = false, | |
| 596 isStatic = true { | |
| 597 _createParameterMirrorList(ftype); | |
| 561 } | 598 } | 
| 562 | 599 | 
| 563 // TODO(vsm): Support named constructors. | 600 // TODO(vsm): Support named constructors. | 
| 564 Symbol get constructorName => isConstructor ? _symbol : null; | 601 Symbol get constructorName => isConstructor ? _symbol : null; | 
| 565 List<ParameterMirror> get parameters => _params; | 602 List<ParameterMirror> get parameters => _params; | 
| 566 List<InstanceMirror> get metadata => _metadata; | 603 List<InstanceMirror> get metadata => _metadata; | 
| 567 | 604 | 
| 568 void _createParameterMirrorList(ftype) { | 605 void _createParameterMirrorList(ftype) { | 
| 569 if (ftype == null) { | 606 if (ftype == null) { | 
| 570 // TODO(vsm): No explicit constructor. Verify this. | 607 // TODO(vsm): No explicit constructor. Verify this. | 
| (...skipping 22 matching lines...) Expand all Loading... | |
| 593 | 630 | 
| 594 // TODO(vsm): Add named args. | 631 // TODO(vsm): Add named args. | 
| 595 List args = ftype.args; | 632 List args = ftype.args; | 
| 596 List opts = ftype.optionals; | 633 List opts = ftype.optionals; | 
| 597 var params = new List<ParameterMirror>(args.length + opts.length); | 634 var params = new List<ParameterMirror>(args.length + opts.length); | 
| 598 | 635 | 
| 599 for (var i = 0; i < args.length; ++i) { | 636 for (var i = 0; i < args.length; ++i) { | 
| 600 var type = args[i]; | 637 var type = args[i]; | 
| 601 var metadata = ftype.metadata[i]; | 638 var metadata = ftype.metadata[i]; | 
| 602 // TODO(vsm): Recover the param name. | 639 // TODO(vsm): Recover the param name. | 
| 603 var param = new JsParameterMirror._(new Symbol(''), _wrap(type), metadata) ; | 640 var param = | 
| 641 new JsParameterMirror._(new Symbol(''), _wrap(type), metadata); | |
| 604 params[i] = param; | 642 params[i] = param; | 
| 605 } | 643 } | 
| 606 | 644 | 
| 607 for (var i = 0; i < opts.length; ++i) { | 645 for (var i = 0; i < opts.length; ++i) { | 
| 608 var type = opts[i]; | 646 var type = opts[i]; | 
| 609 var metadata = ftype.metadata[args.length + i]; | 647 var metadata = ftype.metadata[args.length + i]; | 
| 610 // TODO(vsm): Recover the param name. | 648 // TODO(vsm): Recover the param name. | 
| 611 var param = new JsParameterMirror._(new Symbol(''), _wrap(type), metadata) ; | 649 var param = | 
| 650 new JsParameterMirror._(new Symbol(''), _wrap(type), metadata); | |
| 612 params[i + args.length] = param; | 651 params[i + args.length] = param; | 
| 613 } | 652 } | 
| 614 | 653 | 
| 615 _params = new List.unmodifiable(params); | 654 _params = new List.unmodifiable(params); | 
| 616 } | 655 } | 
| 617 | 656 | 
| 618 String toString() => "MethodMirror on '$_name'"; | 657 String toString() => "MethodMirror on '$_name'"; | 
| 619 } | 658 } | 
| OLD | NEW |