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.entry_point_transformer; | 5 library js.transformer.entry_point_transformer; |
6 | 6 |
7 import 'dart:async'; | 7 import 'dart:async'; |
8 | 8 |
9 import 'package:barback/barback.dart' show Asset, AssetId, Transform, | 9 import 'package:barback/barback.dart' show Asset, AssetId, Transform, |
10 Transformer, AssetNotFoundException; | 10 Transformer, AssetNotFoundException; |
11 import 'package:code_transformers/resolver.dart' show Resolver, | 11 import 'package:code_transformers/resolver.dart' show Resolver, |
12 ResolverTransformer, Resolvers, isPossibleDartEntryId; | 12 ResolverTransformer, Resolvers, isPossibleDartEntryId; |
13 import 'package:logging/logging.dart' show Logger; | 13 import 'package:logging/logging.dart' show Logger; |
14 import 'package:path/path.dart' as path; | |
15 | 14 |
16 import 'utils.dart'; | 15 import 'utils.dart'; |
17 | 16 |
18 final _logger = new Logger('js.transformer.interface_transformer'); | 17 final _logger = new Logger('js.transformer.interface_transformer'); |
19 | 18 |
20 class EntryPointTransformer extends Transformer with ResolverTransformer { | 19 class EntryPointTransformer extends Transformer with ResolverTransformer { |
21 @override | 20 @override |
22 final Resolvers resolvers; | 21 final Resolvers resolvers; |
23 | 22 |
24 EntryPointTransformer(this.resolvers); | 23 EntryPointTransformer(this.resolvers); |
(...skipping 14 matching lines...) Expand all Loading... |
39 } | 38 } |
40 | 39 |
41 var transaction = resolver.createTextEditTransaction(library); | 40 var transaction = resolver.createTextEditTransaction(library); |
42 | 41 |
43 var initializerFutures = resolver.libraries | 42 var initializerFutures = resolver.libraries |
44 .where((lib) => | 43 .where((lib) => |
45 lib != jsLibrary && lib.visibleLibraries.contains(jsLibrary)) | 44 lib != jsLibrary && lib.visibleLibraries.contains(jsLibrary)) |
46 .map((lib) { | 45 .map((lib) { |
47 // look for initializer library | 46 // look for initializer library |
48 var libAssetId = resolver.getSourceAssetId(lib); | 47 var libAssetId = resolver.getSourceAssetId(lib); |
49 var initializerAssetId = libAssetId.addExtension(INITIALIZER_SUFFIX); | 48 var dartInitializerAssetId = |
50 return transform | 49 libAssetId.addExtension(DART_INITIALIZER_SUFFIX); |
51 .getInput(initializerAssetId) | 50 var jsInitializerAssetId = |
52 .catchError((e) => null, | 51 libAssetId.addExtension(JS_INITIALIZER_SUFFIX); |
53 test: (e) => e is AssetNotFoundException); | 52 return [ |
| 53 transform |
| 54 .getInput(dartInitializerAssetId) |
| 55 .catchError((e) => null, |
| 56 test: (e) => e is AssetNotFoundException), |
| 57 transform |
| 58 .getInput(jsInitializerAssetId) |
| 59 .catchError((e) => null, |
| 60 test: (e) => e is AssetNotFoundException), |
| 61 ]; |
| 62 }); |
| 63 |
| 64 var dartInitializerFutures = initializerFutures.map((l) => l[0]); |
| 65 var jsInitializerFutures = initializerFutures.map((l) => l[1]); |
| 66 |
| 67 var dartImports = new StringBuffer('\n'); |
| 68 var dartInitializerCalls = new StringBuffer(); |
| 69 |
| 70 var dartFuture = Future.wait(dartInitializerFutures) |
| 71 .then((initializerAssets) { |
| 72 for (Asset asset in initializerAssets.where((a) => a != null)) { |
| 73 var id = asset.id; |
| 74 var importUri = getImportUri(id, input.id); |
| 75 if (importUri == null) continue; |
| 76 var prefix = assetIdToPrefix(id); |
| 77 dartImports.writeln("import '$importUri' as $prefix;"); |
| 78 dartInitializerCalls |
| 79 .writeln(" $prefix.initializeJavaScriptLibrary();"); |
| 80 } |
54 }) | 81 }) |
55 .where((f) => f != null); | 82 .then((_) { |
56 return Future.wait(initializerFutures).then((initializerAssets) { | 83 var initMethod = 'initializeJavaScript() {\n$dartInitializerCalls}\n'; |
57 var imports = new StringBuffer('\n'); | 84 var insertImportOffset = getInsertImportOffset(library); |
58 var calls = new StringBuffer(); | 85 var initMethodOffset = library.source.contents.data.length; |
59 for (Asset asset in initializerAssets.where((a) => a != null)) { | 86 transaction.edit(insertImportOffset, insertImportOffset, |
60 var id = asset.id; | 87 '$dartImports'); |
61 var importUri = getImportUri(id, input.id); | 88 transaction.edit(initMethodOffset, initMethodOffset, initMethod); |
62 if (importUri == null) continue; | 89 var printer = transaction.commit(); |
63 var prefix = assetIdToPrefix(id); | 90 printer.build(input.id.path); |
64 imports.writeln("import '$importUri' as $prefix;"); | 91 transform.addOutput(new Asset.fromString(input.id, printer.text)); |
65 calls.writeln(" $prefix.initializeJavaScriptLibrary();"); | 92 }); |
66 } | |
67 | 93 |
68 var initMethod = 'initializeJavaScript() {\n$calls}\n'; | 94 var jsInitializerScript = new StringBuffer(''' |
69 var insertImportOffset = getInsertImportOffset(library); | 95 |
70 var initMethodOffset = library.source.contents.data.length; | 96 window.dart = window.dart || {}; |
71 transaction.edit(insertImportOffset, insertImportOffset, '$imports'); | 97 |
72 transaction.edit(initMethodOffset, initMethodOffset, initMethod); | 98 window.dart.Object = function DartObject() { |
73 var printer = transaction.commit(); | 99 throw "not allowed"; |
74 printer.build(input.id.path); | 100 }; |
75 transform.addOutput(new Asset.fromString(input.id, printer.text)); | 101 |
76 }); | 102 window.dart.Object._wrapDartObject = function(dartObject) { |
| 103 var o = Object.create(window.dart.Object.prototype); |
| 104 o.__dart_object__ = dartObject; |
| 105 return o; |
| 106 }; |
| 107 |
| 108 '''); |
| 109 |
| 110 var jsFuture = |
| 111 Future.wait(jsInitializerFutures) |
| 112 .then((assets) => Future.wait(assets |
| 113 .where((a) => a != null) |
| 114 .map((Asset a) => a.readAsString()))) |
| 115 .then((initializerSources) { |
| 116 for (String source in initializerSources) { |
| 117 jsInitializerScript.writeln(source); |
| 118 } |
| 119 }).then((_) { |
| 120 var jsInitializerId = input.id.addExtension('_initialize.js'); |
| 121 var asset = new Asset.fromString(jsInitializerId, |
| 122 jsInitializerScript.toString()); |
| 123 transform.addOutput(asset); |
| 124 }); |
| 125 return Future.wait([dartFuture, jsFuture]); |
77 } | 126 } |
78 } | 127 } |
79 | |
80 final illegalIdRegex = new RegExp(r'[^a-zA-Z0-9_]'); | |
81 | |
82 String assetIdToPrefix(AssetId id) => | |
83 '_js__${id.package}__${id.path.replaceAll(illegalIdRegex, '_')}'; | |
84 | |
85 // TODO(justinfagnani): put this in code_transformers ? | |
86 String getImportUri(AssetId importId, AssetId from) { | |
87 if (importId.path.startsWith('lib/')) { | |
88 // we support package imports | |
89 return "package:${importId.package}/${importId.path.substring(4)}"; | |
90 } else if (importId.package == from.package) { | |
91 // we can support relative imports | |
92 return path.relative(importId.path, from: path.dirname(from.path)); | |
93 } | |
94 // cannot import | |
95 return null; | |
96 } | |
OLD | NEW |