| OLD | NEW |
| 1 // Copyright (c) 2014, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2014, 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 js.transformer.js_proxy_generator; | 5 library js.transformer.js_proxy_generator; |
| 6 | 6 |
| 7 import 'package:analyzer/analyzer.dart'; | 7 import 'package:analyzer/analyzer.dart'; |
| 8 import 'package:analyzer/src/generated/element.dart'; | 8 import 'package:analyzer/src/generated/element.dart'; |
| 9 import 'package:analyzer/src/generated/resolver.dart'; | 9 import 'package:analyzer/src/generated/resolver.dart'; |
| 10 import 'package:barback/barback.dart'; | 10 import 'package:barback/barback.dart'; |
| 11 import 'package:js/src/metadata.dart'; | 11 import 'package:js/src/metadata.dart'; |
| 12 import 'package:js/src/transformer/utils.dart'; | 12 import 'package:js/src/transformer/utils.dart'; |
| 13 import 'package:logging/logging.dart'; | 13 import 'package:logging/logging.dart'; |
| 14 import 'package:quiver/iterables.dart' show max, concat; | 14 import 'package:quiver/iterables.dart' show max, concat; |
| 15 import 'package:source_maps/refactor.dart'; | 15 import 'package:source_maps/refactor.dart'; |
| 16 | 16 |
| 17 final _logger = new Logger('js.transformer.js_proxy_generator'); | 17 final _logger = new Logger('js.transformer.js_proxy_generator'); |
| 18 | 18 |
| 19 const JS_PREFIX = '__package_js_impl__'; | 19 const JS_PREFIX = '__package_js_impl__'; |
| 20 | 20 |
| 21 class JsProxyGenerator { | 21 class JsProxyGenerator { |
| 22 final AssetId inputId; | 22 final AssetId inputId; |
| 23 final ClassElement jsInterfaceClass; | 23 final ClassElement jsInterfaceClass; |
| 24 final ClassElement jsProxyClass; | 24 final ClassElement jsProxyClass; |
| 25 final ClassElement exportClass; | 25 final ClassElement exportClass; |
| 26 final ClassElement noExportClass; | 26 final ClassElement noExportClass; |
| 27 final ClassElement jsifyClass; |
| 27 | 28 |
| 28 final LibraryElement library; | 29 final LibraryElement library; |
| 29 final LibraryElement jsLibrary; | 30 final LibraryElement jsLibrary; |
| 30 final TextEditTransaction transaction; | 31 final TextEditTransaction transaction; |
| 31 | 32 |
| 32 /// The list of classes to generate proxy implementations for | 33 /// The list of classes to generate proxy implementations for |
| 33 final Iterable<ClassElement> jsProxies; | 34 final Iterable<ClassElement> jsProxies; |
| 34 final InheritanceManager inheritanceManager; | 35 final InheritanceManager inheritanceManager; |
| 35 | 36 |
| 36 var generatedMembers = new Set<Element>(); | 37 var generatedMembers = new Set<Element>(); |
| 37 | 38 |
| 38 JsProxyGenerator( | 39 JsProxyGenerator( |
| 39 this.inputId, | 40 this.inputId, |
| 40 this.jsProxies, | 41 this.jsProxies, |
| 41 LibraryElement library, | 42 LibraryElement library, |
| 42 LibraryElement jsLibrary, | 43 LibraryElement jsLibrary, |
| 43 LibraryElement jsMetadataLibrary, | 44 LibraryElement jsMetadataLibrary, |
| 44 this.transaction) | 45 this.transaction) |
| 45 : library = library, | 46 : library = library, |
| 46 jsLibrary = jsLibrary, | 47 jsLibrary = jsLibrary, |
| 47 jsInterfaceClass = getImplLib(jsLibrary).getType('JsInterface'), | 48 jsInterfaceClass = getImplLib(jsLibrary).getType('JsInterface'), |
| 48 jsProxyClass = jsMetadataLibrary.getType('JsProxy'), | 49 jsProxyClass = jsMetadataLibrary.getType('JsProxy'), |
| 49 exportClass = jsMetadataLibrary.getType('Export'), | 50 exportClass = jsMetadataLibrary.getType('Export'), |
| 50 noExportClass = jsMetadataLibrary.getType('NoExport'), | 51 noExportClass = jsMetadataLibrary.getType('NoExport'), |
| 52 jsifyClass = jsMetadataLibrary.getType('Jsify'), |
| 51 inheritanceManager = new InheritanceManager(library) { | 53 inheritanceManager = new InheritanceManager(library) { |
| 52 assert(jsLibrary != null); | 54 assert(jsLibrary != null); |
| 53 assert(library != null); | 55 assert(library != null); |
| 54 assert(jsInterfaceClass != null); | 56 assert(jsInterfaceClass != null); |
| 55 assert(jsProxyClass != null); | 57 assert(jsProxyClass != null); |
| 56 assert(exportClass != null); | 58 assert(exportClass != null); |
| 57 assert(noExportClass != null); | 59 assert(noExportClass != null); |
| 58 } | 60 } |
| 59 | 61 |
| 60 /** | 62 /** |
| (...skipping 125 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 186 } | 188 } |
| 187 } | 189 } |
| 188 | 190 |
| 189 } | 191 } |
| 190 | 192 |
| 191 void _generateMethod(MethodElement a) { | 193 void _generateMethod(MethodElement a) { |
| 192 var name = a.displayName; | 194 var name = a.displayName; |
| 193 if (!a.isStatic) { | 195 if (!a.isStatic) { |
| 194 var returnType = a.returnType; | 196 var returnType = a.returnType; |
| 195 | 197 |
| 196 var jsParameterList = new StringBuffer(); | 198 var jsArgs = new List(a.parameters.length); |
| 197 | 199 |
| 198 var parameterList = a.parameters | 200 for (int i = 0; i < a.parameters.length; i++) { |
| 199 .map((p) => '$JS_PREFIX.toJs(${p.name})') | 201 var param = a.parameters[i]; |
| 200 .join(', '); | 202 var hasJsify = hasAnnotation(param, jsifyClass); |
| 203 if (hasJsify) { |
| 204 jsArgs[i] = '$JS_PREFIX.jsify(${param.name})'; |
| 205 } else { |
| 206 jsArgs[i] = '$JS_PREFIX.toJs(${param.name})'; |
| 207 } |
| 208 } |
| 209 |
| 210 var parameterList = jsArgs.join(', '); |
| 201 | 211 |
| 202 MethodDeclaration m = a.node; | 212 MethodDeclaration m = a.node; |
| 203 var offset = m.body.offset; | 213 var offset = m.body.offset; |
| 204 var end = m.body.end; | 214 var end = m.body.end; |
| 205 if (a.returnType.name == 'void') { | 215 if (a.returnType.name == 'void') { |
| 206 transaction.edit(offset, end, " { $JS_PREFIX.toDart(" | 216 transaction.edit(offset, end, " { $JS_PREFIX.toDart(" |
| 207 "$JS_PREFIX.toJs(this).callMethod('$name', [$parameterList])); }"); | 217 "$JS_PREFIX.toJs(this).callMethod('$name', [$parameterList])); }"); |
| 208 } else { | 218 } else { |
| 209 transaction.edit(offset, end, " => $JS_PREFIX.toDart(" | 219 transaction.edit(offset, end, " => $JS_PREFIX.toDart(" |
| 210 "$JS_PREFIX.toJs(this).callMethod('$name', [$parameterList]))" | 220 "$JS_PREFIX.toJs(this).callMethod('$name', [$parameterList]), " |
| 211 " as ${a.returnType};"); | 221 "#${returnType.name}) as ${a.returnType};"); |
| 212 } | 222 } |
| 213 } | 223 } |
| 214 } | 224 } |
| 215 | 225 |
| 216 void _generateSetter(PropertyAccessorElement a) { | 226 void _generateSetter(PropertyAccessorElement a) { |
| 217 var name = a.displayName; | 227 var name = a.displayName; |
| 218 var parameter = a.parameters.single; | 228 var parameter = a.parameters.single; |
| 219 var type = parameter.type; | 229 var type = parameter.type; |
| 220 if (type == null) { | 230 if (type == null) { |
| 221 _logger.severe("abstract JsInterface setters must have type annotations"); | 231 _logger.severe("abstract JsInterface setters must have type annotations"); |
| (...skipping 28 matching lines...) Expand all Loading... |
| 250 ConstructorElement _checkCreatedConstructor(ClassElement interface) => | 260 ConstructorElement _checkCreatedConstructor(ClassElement interface) => |
| 251 interface.constructors.firstWhere( | 261 interface.constructors.firstWhere( |
| 252 (c) => c.name == 'created' && !c.isFactory, | 262 (c) => c.name == 'created' && !c.isFactory, |
| 253 orElse: () { | 263 orElse: () { |
| 254 _logger.severe("JsInterface subclasses must have a" | 264 _logger.severe("JsInterface subclasses must have a" |
| 255 "generative constructor named 'created'"); | 265 "generative constructor named 'created'"); |
| 256 return null; | 266 return null; |
| 257 }); | 267 }); |
| 258 | 268 |
| 259 } | 269 } |
| OLD | NEW |