| 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 part of dart2js.js_emitter; | 5 part of dart2js.js_emitter; |
| 6 | 6 |
| 7 class NativeEmitter { | 7 class NativeEmitter { |
| 8 | 8 |
| 9 final Map<Element, ClassBuilder> cachedBuilders; | 9 final Map<Element, ClassBuilder> cachedBuilders; |
| 10 | 10 |
| (...skipping 366 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 377 // used. We should also use an interceptor if the check can't be satisfied | 377 // used. We should also use an interceptor if the check can't be satisfied |
| 378 // by a native class in case we get a native instance that tries to spoof | 378 // by a native class in case we get a native instance that tries to spoof |
| 379 // the type info. i.e the criteria for whether or not to use an interceptor | 379 // the type info. i.e the criteria for whether or not to use an interceptor |
| 380 // is whether the receiver can be native, not the type of the test. | 380 // is whether the receiver can be native, not the type of the test. |
| 381 if (element == null || !element.isClass) return false; | 381 if (element == null || !element.isClass) return false; |
| 382 ClassElement cls = element; | 382 ClassElement cls = element; |
| 383 if (Elements.isNativeOrExtendsNative(cls)) return true; | 383 if (Elements.isNativeOrExtendsNative(cls)) return true; |
| 384 return isSupertypeOfNativeClass(element); | 384 return isSupertypeOfNativeClass(element); |
| 385 } | 385 } |
| 386 | 386 |
| 387 void assembleCode(CodeOutput targetOutput) { | |
| 388 List<jsAst.Property> objectProperties = <jsAst.Property>[]; | |
| 389 | |
| 390 jsAst.Property addProperty(String name, jsAst.Expression value) { | |
| 391 jsAst.Property prop = new jsAst.Property(js.string(name), value); | |
| 392 objectProperties.add(prop); | |
| 393 return prop; | |
| 394 } | |
| 395 | |
| 396 if (hasNativeClasses) { | |
| 397 // If the native emitter has been asked to take care of the | |
| 398 // noSuchMethod handlers, we do that now. | |
| 399 if (handleNoSuchMethod) { | |
| 400 emitterTask.oldEmitter.nsmEmitter.emitNoSuchMethodHandlers(addProperty); | |
| 401 } | |
| 402 } | |
| 403 | |
| 404 // If we have any properties to add to Object.prototype, we run | |
| 405 // through them and add them using defineProperty. | |
| 406 if (!objectProperties.isEmpty) { | |
| 407 jsAst.Expression init = js(r''' | |
| 408 (function(table) { | |
| 409 for(var key in table) | |
| 410 #(Object.prototype, key, table[key]); | |
| 411 })(#)''', | |
| 412 [ defPropFunction, | |
| 413 new jsAst.ObjectInitializer(objectProperties)]); | |
| 414 | |
| 415 if (emitterTask.compiler.enableMinification) { | |
| 416 targetOutput.add(';'); | |
| 417 } | |
| 418 targetOutput.addBuffer(jsAst.prettyPrint( | |
| 419 new jsAst.ExpressionStatement(init), compiler)); | |
| 420 targetOutput.add('\n'); | |
| 421 } | |
| 422 | |
| 423 targetOutput.add('\n'); | |
| 424 } | |
| 425 | |
| 426 /// Returns a JavaScript template that fills the embedded globals referenced | 387 /// Returns a JavaScript template that fills the embedded globals referenced |
| 427 /// by [interceptorsByTagAccess] and [leafTagsAccess]. | 388 /// by [interceptorsByTagAccess] and [leafTagsAccess]. |
| 428 /// | 389 /// |
| 429 /// This code must be invoked for every class that has a native info before | 390 /// This code must be invoked for every class that has a native info before |
| 430 /// the program starts. | 391 /// the program starts. |
| 431 /// | 392 /// |
| 432 /// The [infoAccess] parameter must evaluate to an expression that contains | 393 /// The [infoAccess] parameter must evaluate to an expression that contains |
| 433 /// the info (as a JavaScript string). | 394 /// the info (as a JavaScript string). |
| 434 /// | 395 /// |
| 435 /// The [constructorAccess] parameter must evaluate to an expression that | 396 /// The [constructorAccess] parameter must evaluate to an expression that |
| (...skipping 72 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 508 } | 469 } |
| 509 ''', {'info': infoAccess, | 470 ''', {'info': infoAccess, |
| 510 'constructor': constructorAccess, | 471 'constructor': constructorAccess, |
| 511 'subclassRead': subclassRead, | 472 'subclassRead': subclassRead, |
| 512 'interceptorsByTagAccess': interceptorsByTagAccess, | 473 'interceptorsByTagAccess': interceptorsByTagAccess, |
| 513 'leafTagsAccess': leafTagsAccess, | 474 'leafTagsAccess': leafTagsAccess, |
| 514 'nativeSuperclassTagName': embeddedNames.NATIVE_SUPERCLASS_TAG_NAME, | 475 'nativeSuperclassTagName': embeddedNames.NATIVE_SUPERCLASS_TAG_NAME, |
| 515 'allowNativesSubclassing': true}); | 476 'allowNativesSubclassing': true}); |
| 516 } | 477 } |
| 517 } | 478 } |
| OLD | NEW |