Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(431)

Side by Side Diff: third_party/pkg/angular/lib/tools/transformer/referenced_uris.dart

Issue 257423008: Update all Angular libs (run update_all.sh). (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Created 6 years, 8 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
(Empty)
1 library angular.tools.transformers.referenced_uris;
2
3 import 'dart:async';
4
5 import 'package:analyzer/src/generated/ast.dart';
6 import 'package:analyzer/src/generated/element.dart';
7 import 'package:angular/tools/transformer/options.dart';
8 import 'package:barback/barback.dart';
9 import 'package:code_transformers/resolver.dart';
10 import 'package:path/path.dart' as path;
11
12 /// Gathers the contents of all URIs which are referenced by the contents of
13 /// the application.
14 /// Returns a map from URI to contents.
15 Future<Map<String, String>> gatherReferencedUris(Transform transform,
16 Resolver resolver, TransformOptions options,
17 {bool skipNonCached: false, bool templatesOnly: false}) {
18 return new _Processor(transform, resolver, options, skipNonCached,
19 templatesOnly).process();
20 }
21
22 class _Processor {
23 final Transform transform;
24 final Resolver resolver;
25 final TransformOptions options;
26 final Map<RegExp, String> templateUriRewrites = <RegExp, String>{};
27 final bool skipNonCached;
28 final bool templatesOnly;
29
30 ConstructorElement cacheAnnotation;
31 ConstructorElement componentAnnotation;
32
33 static const String cacheAnnotationName =
34 'angular.template_cache_annotation.NgTemplateCache';
35 static const String componentAnnotationName = 'angular.core.annotation_src.Com ponent';
36
37 _Processor(this.transform, this.resolver, this.options, this.skipNonCached,
38 this.templatesOnly) {
39 for (var key in options.templateUriRewrites.keys) {
40 templateUriRewrites[new RegExp(key)] = options.templateUriRewrites[key];
41 }
42 }
43
44 /// Gathers the contents of all URIs which are to be cached.
45 /// Returns a map from URI to contents.
46 Future<Map<String, String>> process() {
47 var cacheAnnotationType = resolver.getType(cacheAnnotationName);
48 if (cacheAnnotationType != null &&
49 cacheAnnotationType.unnamedConstructor != null) {
50 cacheAnnotation = cacheAnnotationType.unnamedConstructor;
51 }
52
53 var componentAnnotationType = resolver.getType(componentAnnotationName);
54 if (componentAnnotationType != null &&
55 componentAnnotationType.unnamedConstructor != null) {
56 componentAnnotation = componentAnnotationType.unnamedConstructor;
57 } else {
58 logger.warning('Unable to resolve $componentAnnotationName.');
59 }
60
61 var annotations = resolver.libraries
62 .expand((lib) => lib.units)
63 .expand((unit) => unit.types)
64 .where((type) => type.node != null)
65 .expand(_AnnotatedElement.fromElement)
66 .where((e) =>
67 (e.annotation.element == cacheAnnotation ||
68 e.annotation.element == componentAnnotation))
69 .toList();
70
71 var uriToEntry = <String, _CacheEntry>{};
72 annotations.where((anno) => anno.annotation.element == componentAnnotation)
73 .expand(processComponentAnnotation)
74 .forEach((entry) {
75 uriToEntry[entry.uri] = entry;
76 });
77 if (!templatesOnly) {
78 annotations.where((anno) => anno.annotation.element == cacheAnnotation)
79 .expand(processCacheAnnotation)
80 .forEach((entry) {
81 uriToEntry[entry.uri] = entry;
82 });
83 }
84
85 var futures = uriToEntry.values.map(cacheEntry);
86
87 return Future.wait(futures).then((_) {
88 var uriToContents = <String, String>{};
89 for (var entry in uriToEntry.values) {
90 if (entry.contents == null) continue;
91
92 uriToContents[entry.uri] = entry.contents;
93 }
94 return uriToContents;
95 });
96 }
97
98 /// Extracts the cacheable URIs from the Component annotation.
99 List<_CacheEntry> processComponentAnnotation(_AnnotatedElement annotation) {
100 var entries = <_CacheEntry>[];
101 if (skipNonCached && isCachingSuppressed(annotation.element)) {
102 return entries;
103 }
104 for (var arg in annotation.annotation.arguments.arguments) {
105 if (arg is NamedExpression) {
106 var paramName = arg.name.label.name;
107 if (paramName == 'templateUrl') {
108 var entry = extractString('templateUrl', arg.expression,
109 annotation.element);
110 if (entry != null) {
111 entries.add(entry);
112 }
113 } else if (paramName == 'cssUrl' && !templatesOnly) {
114 entries.addAll(extractListOrString(paramName, arg.expression,
115 annotation.element));
116 }
117 }
118 }
119
120 return entries;
121 }
122
123 bool isCachingSuppressed(Element e) {
124 if (cacheAnnotation == null) return false;
125 AnnotatedNode node = e.node;
126 for (var annotation in node.metadata) {
127 if (annotation.element == cacheAnnotation) {
128 for (var arg in annotation.arguments.arguments) {
129 if (arg is NamedExpression && arg.name.label.name == 'cache') {
130 var value = arg.expression;
131 if (value is! BooleanLiteral) {
132 warn('Expected boolean literal for NgTemplateCache.cache', e);
133 return false;
134 }
135 return !value.value;
136 }
137 }
138 }
139 }
140 return false;
141 }
142
143 List<_CacheEntry> processCacheAnnotation(_AnnotatedElement annotation) {
144 var entries = <_CacheEntry>[];
145 for (var arg in annotation.annotation.arguments.arguments) {
146 if (arg is NamedExpression) {
147 var paramName = arg.name.label.name;
148 if (paramName == 'preCacheUrls') {
149 entries.addAll(extractListOrString(paramName, arg.expression,
150 annotation.element));
151 }
152 }
153 }
154 return entries;
155 }
156
157 List<_CacheEntry> extractListOrString(String paramName,
158 Expression expression, Element element) {
159 var entries = [];
160 if (expression is StringLiteral) {
161 var entry = uriToEntry(expression.stringValue, element);
162 if (entry != null) {
163 entries.add(entry);
164 }
165 } else if (expression is ListLiteral) {
166 for (var value in expression.elements) {
167 if (value is! StringLiteral) {
168 warn('Expected a string literal in $paramName', element);
169 continue;
170 }
171 var entry = uriToEntry(value.stringValue, element);
172 if (entry != null) {
173 entries.add(entry);
174 }
175 }
176 } else {
177 warn('$paramName must be a string or list literal.', element);
178 }
179 return entries;
180 }
181
182 _CacheEntry extractString(String paramName, Expression expression,
183 Element element) {
184 if (expression is StringLiteral) {
185 return uriToEntry(expression.stringValue, element);
186 }
187 warn('$paramName must be a string literal.', element);
188 return null;
189 }
190
191 Future<_CacheEntry> cacheEntry(_CacheEntry entry) {
192 return transform.readInputAsString(entry.assetId).then((contents) {
193 entry.contents = contents;
194 return entry;
195 }, onError: (e) {
196 warn('Unable to find ${entry.uri} at ${entry.assetId}', entry.element);
197 });
198 }
199
200 _CacheEntry uriToEntry(String uri, Element reference) {
201 uri = rewriteUri(uri);
202 if (Uri.parse(uri).scheme != '') {
203 warn('Cannot cache non-local URIs. $uri', reference);
204 return null;
205 }
206 if (path.url.isAbsolute(uri)) {
207 var parts = path.posix.split(uri);
208 if (parts[1] == 'packages') {
209 var pkgPath = path.url.join('lib', path.url.joinAll(parts.skip(3)));
210 return new _CacheEntry(uri, reference, new AssetId(parts[2], pkgPath));
211 }
212 warn('Cannot cache non-package absolute URIs. $uri', reference);
213 return null;
214 }
215 var assetId = new AssetId(transform.primaryInput.id.package, uri);
216 return new _CacheEntry(uri, reference, assetId);
217 }
218
219 String rewriteUri(String uri) {
220 templateUriRewrites.forEach((regexp, replacement) {
221 uri = uri.replaceFirst(regexp, replacement);
222 });
223 // Normalize packages/ uri's to be /packages/
224 if (uri.startsWith('packages/')) {
225 uri = '/' + uri;
226 }
227 return uri;
228 }
229
230 void warn(String msg, Element element) {
231 logger.warning(msg, asset: resolver.getSourceAssetId(element),
232 span: resolver.getSourceSpan(element));
233 }
234
235 TransformLogger get logger => transform.logger;
236 }
237
238 /// Wrapper for data related to a single cache entry.
239 class _CacheEntry {
240 final String uri;
241 final Element element;
242 final AssetId assetId;
243 String contents;
244
245 _CacheEntry(this.uri, this.element, this.assetId);
246 }
247
248 /// Wrapper for annotation AST nodes to track the element they were declared on.
249 class _AnnotatedElement {
250 /// The annotation node.
251 final Annotation annotation;
252 /// The element which the annotation was declared on.
253 final Element element;
254
255 _AnnotatedElement(this.annotation, this.element);
256
257 static Iterable<_AnnotatedElement> fromElement(Element element) {
258 AnnotatedNode node = element.node;
259 return node.metadata.map(
260 (annotation) => new _AnnotatedElement(annotation, element));
261 }
262 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698