11library angular2.src.transform.inliner_for_test.transformer;
22
33import 'dart:async' ;
4+ import 'dart:convert' show LineSplitter;
45
56import 'package:analyzer/analyzer.dart' ;
67import 'package:analyzer/src/generated/ast.dart' ;
@@ -49,6 +50,7 @@ class InlinerForTest extends Transformer {
4950}
5051
5152/// Reads the code at `assetId` , inlining values where possible.
53+ ///
5254/// Returns the code at `assetId` with the following modifications:
5355/// - `part` Directives are inlined
5456/// - `templateUrl` values are inlined as `template` values.
@@ -73,6 +75,10 @@ Future<String> inline(AssetReader reader, AssetId assetId,
7375final _urlResolver = const TransformerUrlResolver ();
7476
7577class _ViewPropInliner extends RecursiveAstVisitor <Object > {
78+ /// The prefixes given to inlined names.
79+ static const _inlinedTemplateBase = '_template' ;
80+ static const _inlinedStyleBase = '_style' ;
81+
7682 final AssetId _assetId;
7783
7884 /// The code we are operating on.
@@ -84,6 +90,9 @@ class _ViewPropInliner extends RecursiveAstVisitor<Object> {
8490 final XHR _xhr;
8591 final AnnotationMatcher _annotationMatcher;
8692
93+ /// Variable name, string to be inlined pairs.
94+ final _inlinedValues = < _InlinedValue > [];
95+
8796 /// The final index of the last substring we wrote.
8897 int _lastIndex = 0 ;
8998
@@ -105,6 +114,7 @@ class _ViewPropInliner extends RecursiveAstVisitor<Object> {
105114 final retVal = super .visitCompilationUnit (node);
106115 if (modifiedSource) {
107116 _writer.print (_code.substring (_lastIndex));
117+ _inlinedValues.forEach ((v) => _writer.asyncPrint (v.asyncToString ()));
108118 }
109119 return retVal;
110120 }
@@ -142,6 +152,18 @@ class _ViewPropInliner extends RecursiveAstVisitor<Object> {
142152 return super .visitNamedExpression (node);
143153 }
144154
155+ /// Counts the newline characters in the code represented by `node` .
156+ int _countNewlines (AstNode node) {
157+ if (node.offset == null ||
158+ node.offset < 0 ||
159+ node.end == null ||
160+ node.end < 0 ) {
161+ return 0 ;
162+ }
163+ return LineSplitter .split (_code.substring (node.offset, node.end)).length -
164+ 1 ;
165+ }
166+
145167 void _populateStyleUrls (NamedExpression node) {
146168 var urls = naiveEval (node.expression);
147169 if (urls is ! List ) {
@@ -154,14 +176,16 @@ class _ViewPropInliner extends RecursiveAstVisitor<Object> {
154176 _writer.print ('styles: const [' );
155177 for (var url in urls) {
156178 if (url is String ) {
157- _writer.print ("r'''" );
158- _writer.asyncPrint (_readOrEmptyString (url));
159- _writer.print ("''', " );
179+ final inlinedVal = _addInlineValue (url, varBase: _inlinedStyleBase);
180+ _writer.print ('${inlinedVal .name },' );
160181 } else {
161182 zone.log.warning ('style url is not a String (${url })' );
162183 }
163184 }
164- _writer.println (']' );
185+ _writer.print (']' );
186+ for (var i = 0 , n = _countNewlines (node); i < n; ++ i) {
187+ _writer.println ('' );
188+ }
165189 }
166190
167191 void _populateTemplateUrl (NamedExpression node) {
@@ -172,9 +196,11 @@ class _ViewPropInliner extends RecursiveAstVisitor<Object> {
172196 }
173197 _writer.print (_code.substring (_lastIndex, node.offset));
174198 _lastIndex = node.end;
175- _writer.print ("template: r'''" );
176- _writer.asyncPrint (_readOrEmptyString (url));
177- _writer.println ("'''" );
199+ final inlinedVal = _addInlineValue (url, varBase: _inlinedTemplateBase);
200+ _writer.print ('template: ${inlinedVal .name }' );
201+ for (var i = 0 , n = _countNewlines (node); i < n; ++ i) {
202+ _writer.println ('' );
203+ }
178204 }
179205
180206 /// Attempts to read the content from [url] . If [url] is relative, uses
@@ -187,4 +213,28 @@ class _ViewPropInliner extends RecursiveAstVisitor<Object> {
187213 return '' ;
188214 });
189215 }
216+
217+ /// Adds a url to be inlined and requests its content.
218+ ///
219+ /// `varBase` is the base of the variable name the inlined value will be
220+ /// assigned to.
221+ /// Returns the created [_InlinedValue] object.
222+ _InlinedValue _addInlineValue (String url, {String varBase}) {
223+ final val = new _InlinedValue (
224+ '${varBase }${_inlinedValues .length }' , _readOrEmptyString (url));
225+ _inlinedValues.add (val);
226+ return val;
227+ }
228+ }
229+
230+ class _InlinedValue {
231+ final String name;
232+ final Future <String > futureValue;
233+
234+ _InlinedValue (this .name, this .futureValue);
235+
236+ /// Returns a const declaration of the inlined value.
237+ Future <String > asyncToString () async {
238+ return "const $name = r'''${await futureValue }''';" ;
239+ }
190240}
0 commit comments