| 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 js_backend; | 5 part of js_backend; |
| 6 | 6 |
| 7 /** | 7 /** |
| 8 * A function element that represents a closure call. The signature is copied | 8 * A function element that represents a closure call. The signature is copied |
| 9 * from the given element. | 9 * from the given element. |
| 10 */ | 10 */ |
| (...skipping 213 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 224 | 224 |
| 225 // return field; | 225 // return field; |
| 226 js.return_('field') | 226 js.return_('field') |
| 227 ]); | 227 ]); |
| 228 | 228 |
| 229 return new jsAst.FunctionDeclaration( | 229 return new jsAst.FunctionDeclaration( |
| 230 new jsAst.VariableDeclaration('generateAccessor'), | 230 new jsAst.VariableDeclaration('generateAccessor'), |
| 231 fun); | 231 fun); |
| 232 } | 232 } |
| 233 | 233 |
| 234 jsAst.Fun get defineClassFunction { | 234 List get defineClassFunction { |
| 235 // First the class name, then the field names in an array and the members | 235 // First the class name, then the field names in an array and the members |
| 236 // (inside an Object literal). | 236 // (inside an Object literal). |
| 237 // The caller can also pass in the constructor as a function if needed. | 237 // The caller can also pass in the constructor as a function if needed. |
| 238 // | 238 // |
| 239 // Example: | 239 // Example: |
| 240 // defineClass("A", ["x", "y"], { | 240 // defineClass("A", ["x", "y"], { |
| 241 // foo$1: function(y) { | 241 // foo$1: function(y) { |
| 242 // print(this.x + y); | 242 // print(this.x + y); |
| 243 // }, | 243 // }, |
| 244 // bar$2: function(t, v) { | 244 // bar$2: function(t, v) { |
| 245 // this.x = t - v; | 245 // this.x = t - v; |
| 246 // }, | 246 // }, |
| 247 // }); | 247 // }); |
| 248 | 248 |
| 249 // function(cls, fields, prototype) { | 249 // function(cls, fields, prototype) { |
| 250 return js.fun(['cls', 'fields', 'prototype'], [ | 250 var defineClass = js.fun(['cls', 'fields', 'prototype'], [ |
| 251 js['var constructor'], | 251 js['var constructor'], |
| 252 | 252 |
| 253 // if (typeof fields == "function") { | 253 // if (typeof fields == "function") { |
| 254 js.if_(js['typeof fields == "function"'], [ | 254 js.if_(js['typeof fields == "function"'], [ |
| 255 js['constructor = fields'] | 255 js['constructor = fields'] |
| 256 ], /* else */ [ | 256 ], /* else */ [ |
| 257 js['var str = "function " + cls + "("'], | 257 js['var str = "function " + cls + "("'], |
| 258 js['var body = ""'], | 258 js['var body = ""'], |
| 259 | 259 |
| 260 // for (var i = 0; i < fields.length; i++) { | 260 // for (var i = 0; i < fields.length; i++) { |
| (...skipping 11 matching lines...) Expand all Loading... |
| 272 | 272 |
| 273 js['constructor = (new Function(str))()'] | 273 js['constructor = (new Function(str))()'] |
| 274 ]), | 274 ]), |
| 275 | 275 |
| 276 js['constructor.prototype = prototype'], | 276 js['constructor.prototype = prototype'], |
| 277 js['constructor.builtin\$cls = cls'], | 277 js['constructor.builtin\$cls = cls'], |
| 278 | 278 |
| 279 // return constructor; | 279 // return constructor; |
| 280 js.return_('constructor') | 280 js.return_('constructor') |
| 281 ]); | 281 ]); |
| 282 // Declare a function called "generateAccessor". This is used in |
| 283 // defineClassFunction (it's a local declaration in init()). |
| 284 return [ |
| 285 generateAccessorFunction, |
| 286 js['$generateAccessorHolder = generateAccessor'], |
| 287 new jsAst.FunctionDeclaration( |
| 288 new jsAst.VariableDeclaration('defineClass'), defineClass) ]; |
| 282 } | 289 } |
| 283 | 290 |
| 284 /** Needs defineClass to be defined. */ | 291 /** Needs defineClass to be defined. */ |
| 285 List buildProtoSupportCheck() { | 292 List buildProtoSupportCheck() { |
| 286 // On Firefox and Webkit browsers we can manipulate the __proto__ | 293 // On Firefox and Webkit browsers we can manipulate the __proto__ |
| 287 // directly. Opera claims to have __proto__ support, but it is buggy. | 294 // directly. Opera claims to have __proto__ support, but it is buggy. |
| 288 // So we have to do more checks. | 295 // So we have to do more checks. |
| 289 // Opera bug was filed as DSK-370158, and fixed as CORE-47615 | 296 // Opera bug was filed as DSK-370158, and fixed as CORE-47615 |
| 290 // (http://my.opera.com/desktopteam/blog/2012/07/20/more-12-01-fixes). | 297 // (http://my.opera.com/desktopteam/blog/2012/07/20/more-12-01-fixes). |
| 291 // If the browser does not support __proto__ we need to instantiate an | 298 // If the browser does not support __proto__ we need to instantiate an |
| (...skipping 270 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 562 | 569 |
| 563 ], finallyPart: [ | 570 ], finallyPart: [ |
| 564 js['$isolate[getterName] = getter'] | 571 js['$isolate[getterName] = getter'] |
| 565 ]) | 572 ]) |
| 566 ])) | 573 ])) |
| 567 ]; | 574 ]; |
| 568 } | 575 } |
| 569 | 576 |
| 570 List buildDefineClassAndFinishClassFunctionsIfNecessary() { | 577 List buildDefineClassAndFinishClassFunctionsIfNecessary() { |
| 571 if (!needsDefineClass) return []; | 578 if (!needsDefineClass) return []; |
| 572 return [ | 579 return defineClassFunction |
| 573 // Declare a function called "generateAccessor". This is used in | |
| 574 // defineClassFunction (it's a local declaration in init()). | |
| 575 generateAccessorFunction, | |
| 576 | |
| 577 js['$generateAccessorHolder = generateAccessor'], | |
| 578 | |
| 579 // function defineClass ... | |
| 580 new jsAst.FunctionDeclaration( | |
| 581 new jsAst.VariableDeclaration('defineClass'), defineClassFunction) | |
| 582 ] | |
| 583 ..addAll(buildProtoSupportCheck()) | 580 ..addAll(buildProtoSupportCheck()) |
| 584 ..addAll([ | 581 ..addAll([ |
| 585 js[finishClassesName].assign(finishClassesFunction) | 582 js[finishClassesName].assign(finishClassesFunction) |
| 586 ]); | 583 ]); |
| 587 } | 584 } |
| 588 | 585 |
| 589 List buildLazyInitializerFunctionIfNecessary() { | 586 List buildLazyInitializerFunctionIfNecessary() { |
| 590 if (!needsLazyInitializer) return []; | 587 if (!needsLazyInitializer) return []; |
| 591 | 588 |
| 592 // $lazyInitializerName = $lazyInitializerFunction | 589 // $lazyInitializerName = $lazyInitializerFunction |
| (...skipping 603 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1196 /* Do nothing. */ | 1193 /* Do nothing. */ |
| 1197 } | 1194 } |
| 1198 | 1195 |
| 1199 void emitSuper(String superName, ClassBuilder builder) { | 1196 void emitSuper(String superName, ClassBuilder builder) { |
| 1200 /* Do nothing. */ | 1197 /* Do nothing. */ |
| 1201 } | 1198 } |
| 1202 | 1199 |
| 1203 void emitClassFields(ClassElement classElement, | 1200 void emitClassFields(ClassElement classElement, |
| 1204 ClassBuilder builder, | 1201 ClassBuilder builder, |
| 1205 { String superClass: "", | 1202 { String superClass: "", |
| 1206 bool classIsNative: false}) { | 1203 bool classIsNative: false }) { |
| 1207 bool isFirstField = true; | 1204 bool isFirstField = true; |
| 1208 StringBuffer buffer = new StringBuffer(); | 1205 StringBuffer buffer = new StringBuffer(); |
| 1209 if (!classIsNative) { | 1206 if (!classIsNative) { |
| 1210 buffer.write('$superClass;'); | 1207 buffer.write('$superClass;'); |
| 1211 } | 1208 } |
| 1212 visitClassFields(classElement, (Element member, | 1209 visitClassFields(classElement, (Element member, |
| 1213 String name, | 1210 String name, |
| 1214 String accessorName, | 1211 String accessorName, |
| 1215 bool needsGetter, | 1212 bool needsGetter, |
| 1216 bool needsSetter, | 1213 bool needsSetter, |
| (...skipping 1474 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2691 """; | 2688 """; |
| 2692 const String HOOKS_API_USAGE = """ | 2689 const String HOOKS_API_USAGE = """ |
| 2693 // The code supports the following hooks: | 2690 // The code supports the following hooks: |
| 2694 // dartPrint(message) - if this function is defined it is called | 2691 // dartPrint(message) - if this function is defined it is called |
| 2695 // instead of the Dart [print] method. | 2692 // instead of the Dart [print] method. |
| 2696 // dartMainRunner(main) - if this function is defined, the Dart [main] | 2693 // dartMainRunner(main) - if this function is defined, the Dart [main] |
| 2697 // method will not be invoked directly. | 2694 // method will not be invoked directly. |
| 2698 // Instead, a closure that will invoke [main] is | 2695 // Instead, a closure that will invoke [main] is |
| 2699 // passed to [dartMainRunner]. | 2696 // passed to [dartMainRunner]. |
| 2700 """; | 2697 """; |
| OLD | NEW |