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

Side by Side Diff: pkg/polymer/lib/src/build/linter.dart

Issue 27518006: Practically remove boot.js, adds the initialization from the Dart side of (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Created 7 years, 2 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
1 // Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file 1 // Copyright (c) 2013, 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 /** 5 /**
6 * Logic to validate that developers are correctly using Polymer constructs. 6 * Logic to validate that developers are correctly using Polymer constructs.
7 * This is mainly used to produce warnings for feedback in the editor. 7 * This is mainly used to produce warnings for feedback in the editor.
8 */ 8 */
9 library polymer.src.build.linter; 9 library polymer.src.build.linter;
10 10
(...skipping 29 matching lines...) Expand all
40 40
41 Future apply(Transform transform) { 41 Future apply(Transform transform) {
42 var wrapper = new _LoggerInterceptor(transform, _formatter); 42 var wrapper = new _LoggerInterceptor(transform, _formatter);
43 var seen = new Set<AssetId>(); 43 var seen = new Set<AssetId>();
44 var primary = transform.primaryInput; 44 var primary = transform.primaryInput;
45 var id = primary.id; 45 var id = primary.id;
46 wrapper.addOutput(primary); // this phase is analysis only 46 wrapper.addOutput(primary); // this phase is analysis only
47 seen.add(id); 47 seen.add(id);
48 return readPrimaryAsHtml(wrapper).then((document) { 48 return readPrimaryAsHtml(wrapper).then((document) {
49 return _collectElements(document, id, wrapper, seen).then((elements) { 49 return _collectElements(document, id, wrapper, seen).then((elements) {
50 new _LinterVisitor(wrapper, elements).visit(document); 50 bool isEntrypoint = options.isHtmlEntryPoint(id);
51 new _LinterVisitor(wrapper, elements, isEntrypoint).run(document);
51 var messagesId = id.addExtension('.messages'); 52 var messagesId = id.addExtension('.messages');
52 wrapper.addOutput(new Asset.fromString(messagesId, 53 wrapper.addOutput(new Asset.fromString(messagesId,
53 wrapper._messages.join('\n'))); 54 wrapper._messages.join('\n')));
54 }); 55 });
55 }); 56 });
56 } 57 }
57 58
58 /** 59 /**
59 * Collect into [elements] any data about each polymer-element defined in 60 * Collect into [elements] any data about each polymer-element defined in
60 * [document] or any of it's imports, unless they have already been [seen]. 61 * [document] or any of it's imports, unless they have already been [seen].
(...skipping 22 matching lines...) Expand all
83 84
84 Future<List<AssetId>> _getImportedIds( 85 Future<List<AssetId>> _getImportedIds(
85 Document document, AssetId sourceId, Tranform transform) { 86 Document document, AssetId sourceId, Tranform transform) {
86 var importIds = []; 87 var importIds = [];
87 var logger = transform.logger; 88 var logger = transform.logger;
88 for (var tag in document.queryAll('link')) { 89 for (var tag in document.queryAll('link')) {
89 if (tag.attributes['rel'] != 'import') continue; 90 if (tag.attributes['rel'] != 'import') continue;
90 var href = tag.attributes['href']; 91 var href = tag.attributes['href'];
91 var span = tag.sourceSpan; 92 var span = tag.sourceSpan;
92 var id = resolve(sourceId, href, logger, span); 93 var id = resolve(sourceId, href, logger, span);
93 if (id == null) continue; 94 if (id == null ||
95 (id.package == 'polymer' && id.path == 'lib/init.html')) continue;
94 importIds.add(assetExists(id, transform).then((exists) { 96 importIds.add(assetExists(id, transform).then((exists) {
95 if (exists) return id; 97 if (exists) return id;
96 if (sourceId == transform.primaryInput.id) { 98 if (sourceId == transform.primaryInput.id) {
97 logger.error('couldn\'t find imported asset "${id.path}" in package ' 99 logger.error('couldn\'t find imported asset "${id.path}" in package '
98 '"${id.package}".', span: span); 100 '"${id.package}".', span: span);
99 } 101 }
100 })); 102 }));
101 } 103 }
102 return Future.wait(importIds); 104 return Future.wait(importIds);
103 } 105 }
(...skipping 107 matching lines...) Expand 10 before | Expand all | Expand 10 after
211 ? extendsTag : extendsType.baseExtendsTag; 213 ? extendsTag : extendsType.baseExtendsTag;
212 214
213 _ElementSummary(this.tagName, this.extendsTag, this.span); 215 _ElementSummary(this.tagName, this.extendsTag, this.span);
214 216
215 String toString() => "($tagName <: $extendsTag)"; 217 String toString() => "($tagName <: $extendsTag)";
216 } 218 }
217 219
218 class _LinterVisitor extends TreeVisitor { 220 class _LinterVisitor extends TreeVisitor {
219 TransformLogger _logger; 221 TransformLogger _logger;
220 bool _inPolymerElement = false; 222 bool _inPolymerElement = false;
223 bool _dartJSSeen = false;
224 bool _initSeen = false;
225 bool _isEntrypoint;
221 Map<String, _ElementSummary> _elements; 226 Map<String, _ElementSummary> _elements;
222 227
223 _LinterVisitor(this._logger, this._elements) { 228 _LinterVisitor(this._logger, this._elements, this._isEntrypoint) {
224 // We normalize the map, so each element has a direct reference to any 229 // We normalize the map, so each element has a direct reference to any
225 // element it extends from. 230 // element it extends from.
226 for (var tag in _elements.values) { 231 for (var tag in _elements.values) {
227 var extendsTag = tag.extendsTag; 232 var extendsTag = tag.extendsTag;
228 if (extendsTag == null) continue; 233 if (extendsTag == null) continue;
229 tag.extendsType = _elements[extendsTag]; 234 tag.extendsType = _elements[extendsTag];
230 } 235 }
231 } 236 }
232 237
233 void visitElement(Element node) { 238 void visitElement(Element node) {
234 switch (node.tagName) { 239 switch (node.tagName) {
235 case 'link': _validateLinkElement(node); break; 240 case 'link': _validateLinkElement(node); break;
236 case 'element': _validateElementElement(node); break; 241 case 'element': _validateElementElement(node); break;
237 case 'polymer-element': _validatePolymerElement(node); break; 242 case 'polymer-element': _validatePolymerElement(node); break;
238 case 'script': _validateScriptElement(node); break; 243 case 'script': _validateScriptElement(node); break;
239 default: 244 default:
240 _validateNormalElement(node); 245 _validateNormalElement(node);
241 super.visitElement(node); 246 super.visitElement(node);
242 break; 247 break;
243 } 248 }
244 } 249 }
245 250
251 void run(Document doc) {
252 visit(doc);
253
254 if (_isEntrypoint && !_initSeen) {
255 _logger.error(USE_INIT_DART, span: doc.body.sourceSpan);
256 }
257
258 if (_isEntrypoint && !_dartJSSeen) {
259 // TODO(sigmund): remove this when webkitStartDart is gone.
260 _logger.error(USE_DART_JS, span: doc.body.sourceSpan);
261 }
262 }
263
246 /** Produce warnings for invalid link-rel tags. */ 264 /** Produce warnings for invalid link-rel tags. */
247 void _validateLinkElement(Element node) { 265 void _validateLinkElement(Element node) {
248 var rel = node.attributes['rel']; 266 var rel = node.attributes['rel'];
249 if (rel != 'import' && rel != 'stylesheet') return; 267 if (rel != 'import' && rel != 'stylesheet') return;
250 268
269 if (rel == 'import' && _initSeen) {
270 _logger.warning(
271 "Move HTML imports above the 'polymer/init.dart' script tag",
272 span: node.sourceSpan);
273 }
274
251 var href = node.attributes['href']; 275 var href = node.attributes['href'];
252 if (href != null && href != '') return; 276 if (href != null && href != '') return;
253 277
254 // TODO(sigmund): warn also if href can't be resolved. 278 // TODO(sigmund): warn also if href can't be resolved.
255 _logger.warning('link rel="$rel" missing href.', span: node.sourceSpan); 279 _logger.warning('link rel="$rel" missing href.', span: node.sourceSpan);
256 } 280 }
257 281
258 /** Produce warnings if using `<element>` instead of `<polymer-element>`. */ 282 /** Produce warnings if using `<element>` instead of `<polymer-element>`. */
259 void _validateElementElement(Element node) { 283 void _validateElementElement(Element node) {
260 _logger.warning('<element> elements are not supported, use' 284 _logger.warning('<element> elements are not supported, use'
(...skipping 72 matching lines...) Expand 10 before | Expand all | Expand 10 after
333 // that the code is indeed using Dart. 357 // that the code is indeed using Dart.
334 _logger.warning('script tag in polymer element with no type will ' 358 _logger.warning('script tag in polymer element with no type will '
335 'be treated as JavaScript. Did you forget type="application/dart"?', 359 'be treated as JavaScript. Did you forget type="application/dart"?',
336 span: node.sourceSpan); 360 span: node.sourceSpan);
337 } 361 }
338 if (src != null && src.endsWith('.dart')) { 362 if (src != null && src.endsWith('.dart')) {
339 _logger.warning('script tag with .dart source file but no type will ' 363 _logger.warning('script tag with .dart source file but no type will '
340 'be treated as JavaScript. Did you forget type="application/dart"?', 364 'be treated as JavaScript. Did you forget type="application/dart"?',
341 span: node.sourceSpan); 365 span: node.sourceSpan);
342 } 366 }
367 }
368
369 if (src == null) return;
370
371 if (src == 'packages/polymer/boot.js') {
372 _logger.warning(BOOT_JS_DEPRECATED, span: node.sourceSpan);
373 return;
374 }
375 if (src == 'packages/browser/dart.js' ||
376 src == 'packages/unittest/test_controller.js') {
377 _dartJSSeen = true;
378 return;
379 }
380
381 if (src == 'packages/polymer/init.dart') {
382 _initSeen = true;
383 if (scriptType == null) {
384 _logger.warning('script tag missing type="application/dart".',
Jennifer Messerly 2013/10/17 02:04:35 not a big deal either way, but these 2 messages co
Siggi Cherem (dart-lang) 2013/10/17 02:37:40 Done.
385 span: node.sourceSpan);
386 } else if (scriptType != 'application/dart') {
387 _logger.warning('wrong script type, expected type="application/dart".',
388 span: node.sourceSpan);
389 }
343 return; 390 return;
344 } 391 }
345 392
346 if (scriptType != 'application/dart') return; 393 if (scriptType != 'application/dart') return;
347 394
348 if (src != null) { 395 if (!src.endsWith('.dart')) {
349 if (!src.endsWith('.dart')) { 396 _logger.warning('"application/dart" scripts should '
350 _logger.warning('"application/dart" scripts should ' 397 'use the .dart file extension.',
351 'use the .dart file extension.', 398 span: node.sourceSpan);
352 span: node.sourceSpan); 399 }
353 }
354 400
355 if (node.innerHtml.trim() != '') { 401 if (node.innerHtml.trim() != '') {
356 _logger.warning('script tag has "src" attribute and also has script ' 402 _logger.warning('script tag has "src" attribute and also has script '
357 'text.', span: node.sourceSpan); 403 'text.', span: node.sourceSpan);
358 }
359 } 404 }
360 } 405 }
361 406
362 /** 407 /**
363 * Produces warnings for misuses of on-foo event handlers, and for instanting 408 * Produces warnings for misuses of on-foo event handlers, and for instanting
364 * custom tags incorrectly. 409 * custom tags incorrectly.
365 */ 410 */
366 void _validateNormalElement(Element node) { 411 void _validateNormalElement(Element node) {
367 // Event handlers only allowed inside polymer-elements 412 // Event handlers only allowed inside polymer-elements
368 node.attributes.forEach((name, value) { 413 node.attributes.forEach((name, value) {
(...skipping 121 matching lines...) Expand 10 before | Expand all | Expand 10 after
490 535
491 /** 536 /**
492 * Returns true if this is a valid custom element name. See: 537 * Returns true if this is a valid custom element name. See:
493 * <https://dvcs.w3.org/hg/webcomponents/raw-file/tip/spec/custom/index.html#dfn -custom-element-name> 538 * <https://dvcs.w3.org/hg/webcomponents/raw-file/tip/spec/custom/index.html#dfn -custom-element-name>
494 */ 539 */
495 bool _isCustomTag(String name) { 540 bool _isCustomTag(String name) {
496 if (name == null || !name.contains('-')) return false; 541 if (name == null || !name.contains('-')) return false;
497 return !_invalidTagNames.containsKey(name); 542 return !_invalidTagNames.containsKey(name);
498 } 543 }
499 544
500 final String _RED_COLOR = '\u001b[31m'; 545 const String _RED_COLOR = '\u001b[31m';
501 final String _MAGENTA_COLOR = '\u001b[35m'; 546 const String _MAGENTA_COLOR = '\u001b[35m';
502 final String _NO_COLOR = '\u001b[0m'; 547 const String _NO_COLOR = '\u001b[0m';
548
549 const String USE_INIT_DART =
550 'To run a polymer applications, make sure to include '
551 '\'<script type="application/dart" src="packages/polymer/init.dart">'
552 '</script>\' in your page, after all HTML imports.';
553
554 const String USE_DART_JS =
555 'To run a polymer applications in Dartium, make sure to include'
556 '\'<script src="packages/browser/dart.js"></script>\' in your page';
557
558 const String BOOT_JS_DEPRECATED =
559 '"boot.js" is now deprecated. Instead, you can initialize your polymer '
560 'application by calling "initPolymer()" in your main. If you don\'t have a '
561 'main, then you can include our generic main by adding the following '
562 'script tag to your page: \'<script type="application/dart" '
563 'src="packages/polymer/init.dart"> </script>\'. Additionally you need to '
564 'include: \'<script src="packages/browser/dart.js"></script>\' in the page '
565 'too. Make sure these script tags come after all HTML imports.';
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698