OLD | NEW |
1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2012, 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 _interceptors; | 5 library _interceptors; |
6 | 6 |
7 import 'dart:collection'; | 7 import 'dart:collection'; |
8 import 'dart:_collection-dev' hide Symbol; | 8 import 'dart:_collection-dev' hide Symbol; |
9 import "dart:_collection-dev" as _symbol_dev show Symbol; | 9 import "dart:_collection-dev" as _symbol_dev show Symbol; |
10 import 'dart:_js_helper' show allMatchesInStringUnchecked, | 10 import 'dart:_js_helper' show allMatchesInStringUnchecked, |
(...skipping 133 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
144 | 144 |
145 /** | 145 /** |
146 * If [JSInvocationMirror._invokeOn] is being used, this variable | 146 * If [JSInvocationMirror._invokeOn] is being used, this variable |
147 * contains a JavaScript array with the names of methods that are | 147 * contains a JavaScript array with the names of methods that are |
148 * intercepted. | 148 * intercepted. |
149 */ | 149 */ |
150 var interceptedNames; | 150 var interceptedNames; |
151 | 151 |
152 | 152 |
153 /** | 153 /** |
154 * Data structure used to map a [Type] to the [Interceptor] for that type. It | 154 * Data structure used to map a [Type] to the [Interceptor] and constructors for |
155 * is JavaScript array of 2N entries of adjacent slots containing a [Type] | 155 * that type. It is JavaScript array of 3N entries of adjacent slots containing |
156 * followed by an [Interceptor] class for the type. | 156 * a [Type], followed by an [Interceptor] class for the type, followed by a |
| 157 * JavaScript object map for the constructors. |
157 * | 158 * |
158 * The value of this variable is set by the compiler and contains only types | 159 * The value of this variable is set by the compiler and contains only types |
159 * that are user extensions of native classes where the type occurs as a | 160 * that are user extensions of native classes where the type occurs as a |
160 * constant in the program. | 161 * constant in the program. |
161 */ | 162 */ |
162 // TODO(sra): Mark this as initialized to a constant with unknown value. | 163 // TODO(sra): Mark this as initialized to a constant with unknown value. |
163 var mapTypeToInterceptor; | 164 var mapTypeToInterceptor; |
164 | 165 |
165 findInterceptorConstructorForType(Type type) { | 166 int findIndexForWebComponentType(Type type) { |
166 JS_EFFECT((_){ mapTypeToInterceptor = _; }); | 167 JS_EFFECT((_){ mapTypeToInterceptor = _; }); |
167 if (mapTypeToInterceptor == null) return null; | 168 if (mapTypeToInterceptor == null) return null; |
168 List map = JS('JSFixedArray', '#', mapTypeToInterceptor); | 169 List map = JS('JSFixedArray', '#', mapTypeToInterceptor); |
169 for (int i = 0; i + 1 < map.length; i += 2) { | 170 for (int i = 0; i + 1 < map.length; i += 3) { |
170 if (type == map[i]) { | 171 if (type == map[i]) { |
171 return map[i + 1]; | 172 return i; |
172 } | 173 } |
173 } | 174 } |
174 return null; | 175 return null; |
175 } | 176 } |
176 | 177 |
| 178 findInterceptorConstructorForType(Type type) { |
| 179 var index = findIndexForWebComponentType(type); |
| 180 if (index == null) return null; |
| 181 List map = JS('JSFixedArray', '#', mapTypeToInterceptor); |
| 182 return mapTypeToInterceptor[index + 1]; |
| 183 } |
| 184 |
| 185 /** |
| 186 * Returns a JavaScript function that runs the constructor on its argument, or |
| 187 * `null` if there is no such constructor. |
| 188 * |
| 189 * The returned function takes one argument, the web component object. |
| 190 */ |
| 191 findConstructorForWebComponentType(Type type, String name) { |
| 192 var index = findIndexForWebComponentType(type); |
| 193 if (index == null) return null; |
| 194 List map = JS('JSFixedArray', '#', mapTypeToInterceptor); |
| 195 var constructorMap = mapTypeToInterceptor[index + 2]; |
| 196 var constructorFn = JS('', '#[#]', constructorMap, name); |
| 197 return constructorFn; |
| 198 } |
| 199 |
177 findInterceptorForType(Type type) { | 200 findInterceptorForType(Type type) { |
178 var constructor = findInterceptorConstructorForType(type); | 201 var constructor = findInterceptorConstructorForType(type); |
179 if (constructor == null) return null; | 202 if (constructor == null) return null; |
180 return JS('', '#.prototype', constructor); | 203 return JS('', '#.prototype', constructor); |
181 } | 204 } |
182 | 205 |
183 /** | 206 /** |
184 * The base interceptor class. | 207 * The base interceptor class. |
185 * | 208 * |
186 * The code `r.foo(a)` is compiled to `getInterceptor(r).foo$1(r, a)`. The | 209 * The code `r.foo(a)` is compiled to `getInterceptor(r).foo$1(r, a)`. The |
(...skipping 149 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
336 } | 359 } |
337 | 360 |
338 | 361 |
339 /** | 362 /** |
340 * Interceptor for unclassified JavaScript objects, typically objects with a | 363 * Interceptor for unclassified JavaScript objects, typically objects with a |
341 * non-trivial prototype chain. | 364 * non-trivial prototype chain. |
342 */ | 365 */ |
343 class UnknownJavaScriptObject extends JavaScriptObject { | 366 class UnknownJavaScriptObject extends JavaScriptObject { |
344 const UnknownJavaScriptObject(); | 367 const UnknownJavaScriptObject(); |
345 } | 368 } |
OLD | NEW |