| OLD | NEW |
| (Empty) |
| 1 // Copyright (c) 2015, the Dart project authors. Please see the AUTHORS file | |
| 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. | |
| 4 library initialize.plugin_transformer; | |
| 5 | |
| 6 import 'dart:async'; | |
| 7 import 'package:analyzer/analyzer.dart'; | |
| 8 import 'package:barback/barback.dart'; | |
| 9 import 'package:source_maps/refactor.dart'; | |
| 10 import 'package:source_span/source_span.dart'; | |
| 11 | |
| 12 /// Abstract transformer which will call [initEntry] for every [InitEntry] | |
| 13 /// expression found in the bootstrap file. This is used to centralize logic | |
| 14 /// for initializers which want to do something special at transform time. | |
| 15 abstract class InitializePluginTransformer extends AggregateTransformer { | |
| 16 // Path to the bootstrap file created by the initialize transformer. | |
| 17 final String _bootstrapFile; | |
| 18 | |
| 19 // All the extra assets that were found, if child classes override | |
| 20 // classifyPrimary this lets them get at the other assets easily. | |
| 21 final allAssets = <Asset>[]; | |
| 22 | |
| 23 TransformLogger _logger; | |
| 24 | |
| 25 InitializePluginTransformer(this._bootstrapFile); | |
| 26 | |
| 27 classifyPrimary(AssetId id) => | |
| 28 _bootstrapFile == id.path ? _bootstrapFile : null; | |
| 29 | |
| 30 Future apply(AggregateTransform transform) { | |
| 31 _logger = transform.logger; | |
| 32 var done = new Completer(); | |
| 33 var listener = transform.primaryInputs.listen((Asset asset) { | |
| 34 allAssets.add(asset); | |
| 35 var id = asset.id; | |
| 36 if (id.path != _bootstrapFile) return; | |
| 37 // Calls initEntry for each InitEntry expression. | |
| 38 asset.readAsString().then((dartCode) { | |
| 39 var url = id.path.startsWith('lib/') | |
| 40 ? 'package:${id.package}/${id.path.substring(4)}' | |
| 41 : id.path; | |
| 42 var source = new SourceFile(dartCode, url: url); | |
| 43 var transaction = new TextEditTransaction(dartCode, source); | |
| 44 (parseCompilationUnit(dartCode, | |
| 45 suppressErrors: true) as dynamic).declarations.firstWhere( | |
| 46 (d) => d.name.toString() == | |
| 47 'main').functionExpression.body.block.statements.firstWhere( | |
| 48 (statement) { | |
| 49 return statement.expression.target.toString() == 'initializers' && | |
| 50 statement.expression.methodName.toString() == 'addAll'; | |
| 51 }).expression.argumentList.arguments[0].elements | |
| 52 .where((arg) => arg is InstanceCreationExpression) | |
| 53 .forEach((e) => initEntry(e, transaction)); | |
| 54 | |
| 55 // Apply any transformations. | |
| 56 if (!transaction.hasEdits) { | |
| 57 transform.addOutput(asset); | |
| 58 } else { | |
| 59 var printer = transaction.commit(); | |
| 60 printer.build(url); | |
| 61 transform.addOutput(new Asset.fromString(id, printer.text)); | |
| 62 } | |
| 63 done.complete(); | |
| 64 }); | |
| 65 }); | |
| 66 | |
| 67 // Make sure all the assets are read before returning. | |
| 68 return Future.wait([listener.asFuture(), done.future]); | |
| 69 } | |
| 70 | |
| 71 /// Gets called once for each generated [InitEntry] expression in the | |
| 72 /// bootstrap file. A [TextEditTransaction] is supplied so that the user can | |
| 73 /// modify the expression however they see fit. | |
| 74 void initEntry( | |
| 75 InstanceCreationExpression expression, TextEditTransaction transaction); | |
| 76 | |
| 77 /// Convenience method to delete an Initializer expression completely. | |
| 78 void removeInitializer( | |
| 79 InstanceCreationExpression expression, TextEditTransaction transaction) { | |
| 80 // Delete the entire line. | |
| 81 var line = transaction.file.getLine(expression.offset); | |
| 82 transaction.edit(transaction.file.getOffset(line), | |
| 83 transaction.file.getOffset(line + 1), ''); | |
| 84 } | |
| 85 } | |
| OLD | NEW |