@@ -17,6 +17,7 @@ import 'package:angular2/src/transform/common/logging.dart';
1717import 'package:angular2/src/transform/common/names.dart' ;
1818import 'package:angular2/src/transform/common/parser.dart' ;
1919import 'package:barback/barback.dart' ;
20+ import 'package:code_transformers/assets.dart' ;
2021
2122import 'recording_reflection_capabilities.dart' ;
2223
@@ -28,11 +29,12 @@ import 'recording_reflection_capabilities.dart';
2829Future <String > processTemplates (AssetReader reader, AssetId entryPoint) async {
2930 var parser = new Parser (reader);
3031 NgDeps ngDeps = await parser.parse (entryPoint);
32+ var extractor = new _TemplateExtractor (reader, entryPoint);
3133
3234 var registrations = new StringBuffer ();
33- ngDeps.registeredTypes. forEach ((rType ) {
34- _processRegisteredType (reader, rType). forEach (( String templateText) {
35- var values = _processTemplate (templateText);
35+ for ( var rType in ngDeps.registeredTypes) {
36+ ( await extractor. extractTemplates (rType))
37+ . forEach (( RecordingReflectionCapabilities values) {
3638 var calls = _generateGetters ('${rType .typeName }' , values.getterNames);
3739 if (calls.isNotEmpty) {
3840 registrations.write ('..${REGISTER_GETTERS_METHOD_NAME }'
@@ -49,7 +51,7 @@ Future<String> processTemplates(AssetReader reader, AssetId entryPoint) async {
4951 '({${calls .join (', ' )}})' );
5052 }
5153 });
52- });
54+ }
5355
5456 var code = ngDeps.code;
5557 if (registrations.length == 0 ) return code;
@@ -60,82 +62,123 @@ Future<String> processTemplates(AssetReader reader, AssetId entryPoint) async {
6062}
6163
6264Iterable <String > _generateGetters (String typeName, List <String > getterNames) {
63- return getterNames. map ((prop) {
64- // TODO(kegluneq): Include `typeName` where possible.
65- return '''' $prop ': (o) => o.$prop ''' ;
66- } );
65+ // TODO(kegluneq): Include `typeName` where possible.
66+ return getterNames. map ((prop) => '''
67+ ' $prop ': (o) => o.$prop
68+ ''' );
6769}
6870
6971Iterable <String > _generateSetters (String typeName, List <String > setterName) {
70- return setterName.map ((prop) {
71- return '''' $prop ': (o, v) => o.$prop = v''' ;
72- } );
72+ return setterName.map ((prop) => '''
73+ ' $prop ': (o, v) => o.$prop = v
74+ ''' );
7375}
7476
7577Iterable <String > _generateMethods (String typeName, List <String > methodNames) {
76- return methodNames.map ((methodName) {
77- return ''''$methodName ': (o, List args) =>
78- Function.apply(o.$methodName , args)''' ;
79- });
78+ return methodNames.map ((methodName) => '''
79+ '$methodName ': (o, List args) => Function.apply(o.$methodName , args)
80+ ''' );
8081}
8182
82- RecordingReflectionCapabilities _processTemplate (String templateCode) {
83- var recordingCapabilities = new RecordingReflectionCapabilities ();
84- var savedReflectionCapabilities = reflector.reflectionCapabilities;
85- reflector.reflectionCapabilities = recordingCapabilities;
83+ /// Extracts `inline` and `url` values from `Template` annotations, reads
84+ /// template code if necessary, and determines what values will be
85+ /// reflectively accessed from that template.
86+ class _TemplateExtractor {
87+ final AssetReader _reader;
88+ final AssetId _entryPoint;
89+ final CompilePipeline _pipeline;
90+ final _TemplateExtractVisitor _visitor = new _TemplateExtractVisitor ();
91+
92+ _TemplateExtractor (this ._reader, this ._entryPoint)
93+ : _pipeline = new CompilePipeline (_createCompileSteps ());
94+
95+ static List <CompileStep > _createCompileSteps () {
96+ var parser = new ng.Parser (new ng.Lexer ());
97+ // TODO(kegluneq): Add other compile steps from default_steps.dart.
98+ return [
99+ new ViewSplitter (parser),
100+ new PropertyBindingParser (parser),
101+ new TextInterpolationParser (parser)
102+ ];
103+ }
86104
87- var compilePipeline = new CompilePipeline ( _createCompileSteps ());
88- var template = DOM . createTemplate (templateCode);
89- // TODO(kegluneq): Need to parse this from a file when not inline.
90- compilePipeline. process (template, templateCode);
105+ Future < List < RecordingReflectionCapabilities >> extractTemplates (
106+ RegisteredType t) async {
107+ return ( await _processRegisteredType (t)). map (_processTemplate). toList ();
108+ }
91109
92- reflector.reflectionCapabilities = savedReflectionCapabilities;
93- return recordingCapabilities;
94- }
110+ RecordingReflectionCapabilities _processTemplate (String templateCode) {
111+ var recordingCapabilities = new RecordingReflectionCapabilities ();
112+ var savedReflectionCapabilities = reflector.reflectionCapabilities;
113+ reflector.reflectionCapabilities = recordingCapabilities;
95114
96- List <CompileStep > _createCompileSteps () {
97- var parser = new ng.Parser (new ng.Lexer ());
98- // TODO(kegluneq): Add other compile steps from default_steps.dart.
99- return [
100- new ViewSplitter (parser),
101- new PropertyBindingParser (parser),
102- new TextInterpolationParser (parser)
103- ];
104- }
115+ _pipeline.process (DOM .createTemplate (templateCode), templateCode);
116+
117+ reflector.reflectionCapabilities = savedReflectionCapabilities;
118+ return recordingCapabilities;
119+ }
120+
121+ Future <List <String >> _processRegisteredType (RegisteredType t) async {
122+ _visitor.reset ();
123+ t.annotations.accept (_visitor);
124+ var toReturn = _visitor.inlineValues;
125+ for (var url in _visitor.urlValues) {
126+ var templateText = await _readUrlTemplate (url);
127+ if (templateText != null ) {
128+ toReturn.add (templateText);
129+ }
130+ }
131+ return toReturn;
132+ }
105133
106- List <String > _processRegisteredType (AssetReader reader, RegisteredType t) {
107- var visitor = new _TemplateExtractVisitor (reader);
108- t.annotations.accept (visitor);
109- return visitor.templateText;
134+ // TODO(kegluneq): Rewrite these to `inline` where possible.
135+ // See [https://github.com/angular/angular/issues/1035].
136+ Future <String > _readUrlTemplate (String url) async {
137+ var assetId = uriToAssetId (_entryPoint, url, logger, null );
138+ var templateExists = await _reader.hasInput (assetId);
139+ if (! templateExists) {
140+ logger.error ('Could not read template at uri $url from $_entryPoint ' );
141+ return null ;
142+ }
143+ return await _reader.readAsString (assetId);
144+ }
110145}
111146
112147/// Visitor responsible for processing the `annotations` property of a
113148/// [RegisterType] object and pulling out template text.
114149class _TemplateExtractVisitor extends Object with RecursiveAstVisitor <Object > {
115- final List <String > templateText = [];
116- final AssetReader _reader ;
150+ final List <String > inlineValues = [];
151+ final List < String > urlValues = [] ;
117152
118- _TemplateExtractVisitor (this ._reader);
153+ void reset () {
154+ inlineValues.clear ();
155+ urlValues.clear ();
156+ }
119157
120158 @override
121159 Object visitNamedExpression (NamedExpression node) {
122160 // TODO(kegluneq): Remove this limitation.
123- if (node.name is Label && node.name.label is SimpleIdentifier ) {
124- var keyString = '${node .name .label }' ;
125- if (keyString == 'inline' ) {
126- if (node.expression is SimpleStringLiteral ) {
127- templateText.add (stringLiteralToString (node.expression));
128- } else {
129- logger.error (
130- 'Angular 2 currently only supports string literals in directives' ,
131- ' Source: ${node }' );
132- }
133- }
134- } else {
161+ if (node.name is ! Label || node.name.label is ! SimpleIdentifier ) {
135162 logger.error (
136163 'Angular 2 currently only supports simple identifiers in directives' ,
137164 ' Source: ${node }' );
165+ return null ;
166+ }
167+ var keyString = '${node .name .label }' ;
168+ if (keyString == 'inline' || keyString == 'url' ) {
169+ if (node.expression is ! SimpleStringLiteral ) {
170+ logger.error (
171+ 'Angular 2 currently only supports string literals in directives' ,
172+ ' Source: ${node }' );
173+ return null ;
174+ }
175+ var valueString = stringLiteralToString (node.expression);
176+ if (keyString == 'url' ) {
177+ urlValues.add (valueString);
178+ } else {
179+ inlineValues.add (valueString);
180+ }
138181 }
139- return super . visitNamedExpression (node) ;
182+ return null ;
140183 }
141184}
0 commit comments