| 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 |