OLD | NEW |
---|---|
1 // Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file | 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 | 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:async'; | 7 import 'dart:async'; |
8 import 'dart:mirrors'; | 8 import 'dart:mirrors'; |
9 | 9 |
10 import 'dart:_foreign_helper' show JS, JS_CURRENT_ISOLATE; | 10 import 'dart:_foreign_helper' show JS, JS_CURRENT_ISOLATE; |
11 import 'dart:_collection-dev' as _symbol_dev; | 11 import 'dart:_collection-dev' as _symbol_dev; |
12 import 'dart:_js_helper' show | 12 import 'dart:_js_helper' show |
13 BoundClosure, | 13 BoundClosure, |
14 Closure, | 14 Closure, |
15 JSInvocationMirror, | 15 JSInvocationMirror, |
16 Null, | 16 Null, |
17 Primitives, | 17 Primitives, |
18 RuntimeError, | 18 RuntimeError, |
19 createInvocationMirror; | 19 createInvocationMirror; |
20 import 'dart:_interceptors' show Interceptor; | 20 import 'dart:_interceptors' show Interceptor; |
21 | 21 |
22 String getName(Symbol symbol) => n(symbol); | 22 /// No-op method that is called to inform the compiler that |
23 /// tree-shaking needs to be disabled. | |
24 disableTreeShaking() => preserveNames(); | |
25 | |
26 /// No-op method that is called to infrom the compiler that unmangled | |
ngeoffray
2013/06/12 19:38:42
infrom -> inform
ahe
2013/06/14 12:00:22
Done.
| |
27 /// named must be preserved. | |
28 preserveNames() {} | |
29 | |
30 String getName(Symbol symbol) { | |
31 preserveNames(); | |
32 return n(symbol); | |
33 } | |
23 | 34 |
24 final Map<String, String> mangledNames = JsMirrorSystem.computeMangledNames(); | 35 final Map<String, String> mangledNames = JsMirrorSystem.computeMangledNames(); |
25 | 36 |
26 final Map<String, String> reflectiveNames = | 37 final Map<String, String> reflectiveNames = |
27 JsMirrorSystem.computeReflectiveNames(); | 38 JsMirrorSystem.computeReflectiveNames(); |
28 | 39 |
29 class JsMirrorSystem implements MirrorSystem { | 40 class JsMirrorSystem implements MirrorSystem { |
30 TypeMirror get dynamicType => _dynamicType; | 41 TypeMirror get dynamicType => _dynamicType; |
31 TypeMirror get voidType => _voidType; | 42 TypeMirror get voidType => _voidType; |
32 | 43 |
33 final static TypeMirror _dynamicType = | 44 final static TypeMirror _dynamicType = |
34 new JsTypeMirror(const Symbol('dynamic')); | 45 new JsTypeMirror(const Symbol('dynamic')); |
35 final static TypeMirror _voidType = new JsTypeMirror(const Symbol('void')); | 46 final static TypeMirror _voidType = new JsTypeMirror(const Symbol('void')); |
36 | 47 |
37 static final Map<String, List<LibraryMirror>> librariesByName = | 48 static final Map<String, List<LibraryMirror>> librariesByName = |
38 computeLibrariesByName(); | 49 computeLibrariesByName(); |
39 | 50 |
40 Iterable<LibraryMirror> findLibrary(Symbol libraryName) { | 51 Iterable<LibraryMirror> findLibrary(Symbol libraryName) { |
41 return new List<LibraryMirror>.from(librariesByName[n(libraryName)]); | 52 return new List<LibraryMirror>.from(librariesByName[n(libraryName)]); |
42 } | 53 } |
43 | 54 |
44 static Map<String, List<LibraryMirror>> computeLibrariesByName() { | 55 static Map<String, List<LibraryMirror>> computeLibrariesByName() { |
56 disableTreeShaking(); | |
45 var result = new Map<String, List<LibraryMirror>>(); | 57 var result = new Map<String, List<LibraryMirror>>(); |
46 var jsLibraries = JS('=List|Null', 'init.libraries'); | 58 var jsLibraries = JS('=List|Null', 'init.libraries'); |
47 if (jsLibraries == null) return result; | 59 if (jsLibraries == null) return result; |
48 for (List data in jsLibraries) { | 60 for (List data in jsLibraries) { |
49 String name = data[0]; | 61 String name = data[0]; |
50 Uri uri = Uri.parse(data[1]); | 62 Uri uri = Uri.parse(data[1]); |
51 List<String> classes = data[2]; | 63 List<String> classes = data[2]; |
52 List<String> functions = data[3]; | 64 List<String> functions = data[3]; |
53 var metadataFunction = data[4]; | 65 var metadataFunction = data[4]; |
54 List metadata = (metadataFunction == null) | 66 List metadata = (metadataFunction == null) |
55 ? null : JS('List', '#()', metadataFunction); | 67 ? null : JS('List', '#()', metadataFunction); |
56 var libraries = result.putIfAbsent(name, () => <LibraryMirror>[]); | 68 var libraries = result.putIfAbsent(name, () => <LibraryMirror>[]); |
57 libraries.add( | 69 libraries.add( |
58 new JsLibraryMirror(s(name), uri, classes, functions, metadata)); | 70 new JsLibraryMirror(s(name), uri, classes, functions, metadata)); |
59 } | 71 } |
60 return result; | 72 return result; |
61 } | 73 } |
62 | 74 |
63 static Map<String, String> computeMangledNames() { | 75 static Map<String, String> computeMangledNames() { |
76 disableTreeShaking(); | |
64 var mangledNames = JS('', 'init.mangledNames'); | 77 var mangledNames = JS('', 'init.mangledNames'); |
65 var keys = extractKeys(mangledNames); | 78 var keys = extractKeys(mangledNames); |
66 var result = <String, String>{}; | 79 var result = <String, String>{}; |
67 for (String key in keys) { | 80 for (String key in keys) { |
68 result[key] = JS('String', '#[#]', mangledNames, key); | 81 result[key] = JS('String', '#[#]', mangledNames, key); |
69 } | 82 } |
70 return result; | 83 return result; |
71 } | 84 } |
72 | 85 |
73 static Map<String, String> computeReflectiveNames() { | 86 static Map<String, String> computeReflectiveNames() { |
87 disableTreeShaking(); | |
74 var result = <String, String>{}; | 88 var result = <String, String>{}; |
75 mangledNames.forEach((String mangledName, String reflectiveName) { | 89 mangledNames.forEach((String mangledName, String reflectiveName) { |
76 result[reflectiveName] = mangledName; | 90 result[reflectiveName] = mangledName; |
77 }); | 91 }); |
78 return result; | 92 return result; |
79 } | 93 } |
80 } | 94 } |
81 | 95 |
82 class JsTypeMirror implements TypeMirror { | 96 class JsTypeMirror implements TypeMirror { |
83 final Symbol simpleName; | 97 final Symbol simpleName; |
(...skipping 109 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
193 } | 207 } |
194 } | 208 } |
195 | 209 |
196 final Expando<ClassMirror> classMirrors = new Expando<ClassMirror>(); | 210 final Expando<ClassMirror> classMirrors = new Expando<ClassMirror>(); |
197 | 211 |
198 ClassMirror reflectType(Type key) { | 212 ClassMirror reflectType(Type key) { |
199 return reflectClassByName(s('$key'.split('<')[0])); | 213 return reflectClassByName(s('$key'.split('<')[0])); |
200 } | 214 } |
201 | 215 |
202 ClassMirror reflectClassByName(Symbol symbol) { | 216 ClassMirror reflectClassByName(Symbol symbol) { |
217 disableTreeShaking(); | |
203 String className = n(symbol); | 218 String className = n(symbol); |
204 var constructor = Primitives.getConstructor(className); | 219 var constructor = Primitives.getConstructor(className); |
205 if (constructor == null) { | 220 if (constructor == null) { |
206 // Probably an intercepted class. | 221 // Probably an intercepted class. |
207 // TODO(ahe): How to handle intercepted classes? | 222 // TODO(ahe): How to handle intercepted classes? |
208 throw new UnsupportedError('Cannot find class for: $className'); | 223 throw new UnsupportedError('Cannot find class for: $className'); |
209 } | 224 } |
210 var descriptor = JS('', '#["@"]', constructor); | 225 var descriptor = JS('', '#["@"]', constructor); |
211 var fields; | 226 var fields; |
212 var fieldsMetadata; | 227 var fieldsMetadata; |
(...skipping 353 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
566 if (code >= 123 && code <= 126) return code - 117; | 581 if (code >= 123 && code <= 126) return code - 117; |
567 if (code >= 37 && code <= 43) return code - 27; | 582 if (code >= 37 && code <= 43) return code - 27; |
568 return 0; | 583 return 0; |
569 } | 584 } |
570 } | 585 } |
571 | 586 |
572 class JsClosureMirror extends JsInstanceMirror implements ClosureMirror { | 587 class JsClosureMirror extends JsInstanceMirror implements ClosureMirror { |
573 JsClosureMirror(reflectee) : super(reflectee); | 588 JsClosureMirror(reflectee) : super(reflectee); |
574 | 589 |
575 MethodMirror get function { | 590 MethodMirror get function { |
591 disableTreeShaking(); | |
576 // TODO(ahe): What about optional parameters (named or not). | 592 // TODO(ahe): What about optional parameters (named or not). |
577 var extractCallName = JS('', r''' | 593 var extractCallName = JS('', r''' |
578 function(reflectee) { | 594 function(reflectee) { |
579 for (var property in reflectee) { | 595 for (var property in reflectee) { |
580 if ("call$" == property.substring(0, 5)) return property; | 596 if ("call$" == property.substring(0, 5)) return property; |
581 } | 597 } |
582 return null; | 598 return null; |
583 } | 599 } |
584 '''); | 600 '''); |
585 String callName = JS('String|Null', '#(#)', extractCallName, reflectee); | 601 String callName = JS('String|Null', '#(#)', extractCallName, reflectee); |
(...skipping 113 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
699 List extractKeys(victim) { | 715 List extractKeys(victim) { |
700 return JS('List', ''' | 716 return JS('List', ''' |
701 (function(victim, hasOwnProperty) { | 717 (function(victim, hasOwnProperty) { |
702 var result = []; | 718 var result = []; |
703 for (var key in victim) { | 719 for (var key in victim) { |
704 if (hasOwnProperty.call(victim, key)) result.push(key); | 720 if (hasOwnProperty.call(victim, key)) result.push(key); |
705 } | 721 } |
706 return result; | 722 return result; |
707 })(#, Object.prototype.hasOwnProperty)''', victim); | 723 })(#, Object.prototype.hasOwnProperty)''', victim); |
708 } | 724 } |
OLD | NEW |