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

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

Issue 27903006: Improves how to initialize polymer apps and fixes polymer build and linter to (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 203 matching lines...) Expand 10 before | Expand all | Expand 10 after
214 214
215 _ElementSummary(this.tagName, this.extendsTag, this.span); 215 _ElementSummary(this.tagName, this.extendsTag, this.span);
216 216
217 String toString() => "($tagName <: $extendsTag)"; 217 String toString() => "($tagName <: $extendsTag)";
218 } 218 }
219 219
220 class _LinterVisitor extends TreeVisitor { 220 class _LinterVisitor extends TreeVisitor {
221 TransformLogger _logger; 221 TransformLogger _logger;
222 bool _inPolymerElement = false; 222 bool _inPolymerElement = false;
223 bool _dartJSSeen = false; 223 bool _dartJSSeen = false;
224 bool _initSeen = false; 224 bool _dartTagSeen = false;
225 bool _isEntrypoint; 225 bool _isEntrypoint;
226 Map<String, _ElementSummary> _elements; 226 Map<String, _ElementSummary> _elements;
227 227
228 _LinterVisitor(this._logger, this._elements, this._isEntrypoint) { 228 _LinterVisitor(this._logger, this._elements, this._isEntrypoint) {
229 // 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
230 // element it extends from. 230 // element it extends from.
231 for (var tag in _elements.values) { 231 for (var tag in _elements.values) {
232 var extendsTag = tag.extendsTag; 232 var extendsTag = tag.extendsTag;
233 if (extendsTag == null) continue; 233 if (extendsTag == null) continue;
234 tag.extendsType = _elements[extendsTag]; 234 tag.extendsType = _elements[extendsTag];
235 } 235 }
236 } 236 }
237 237
238 void visitElement(Element node) { 238 void visitElement(Element node) {
239 switch (node.tagName) { 239 switch (node.tagName) {
240 case 'link': _validateLinkElement(node); break; 240 case 'link': _validateLinkElement(node); break;
241 case 'element': _validateElementElement(node); break; 241 case 'element': _validateElementElement(node); break;
242 case 'polymer-element': _validatePolymerElement(node); break; 242 case 'polymer-element': _validatePolymerElement(node); break;
243 case 'script': _validateScriptElement(node); break; 243 case 'script': _validateScriptElement(node); break;
244 default: 244 default:
245 _validateNormalElement(node); 245 _validateNormalElement(node);
246 super.visitElement(node); 246 super.visitElement(node);
247 break; 247 break;
248 } 248 }
249 } 249 }
250 250
251 void run(Document doc) { 251 void run(Document doc) {
252 visit(doc); 252 visit(doc);
253 253
254 if (_isEntrypoint && !_initSeen) { 254 if (_isEntrypoint && !_dartTagSeen) {
255 _logger.error(USE_INIT_DART, span: doc.body.sourceSpan); 255 _logger.error(USE_INIT_DART, span: doc.body.sourceSpan);
256 } 256 }
257 257
258 if (_isEntrypoint && !_dartJSSeen) { 258 if (_isEntrypoint && !_dartJSSeen) {
259 // TODO(sigmund): remove this when webkitStartDart is gone. 259 // TODO(sigmund): remove this when webkitStartDart is gone.
260 _logger.error(USE_DART_JS, span: doc.body.sourceSpan); 260 _logger.error(USE_DART_JS, span: doc.body.sourceSpan);
261 } 261 }
262 } 262 }
263 263
264 /** Produce warnings for invalid link-rel tags. */ 264 /** Produce warnings for invalid link-rel tags. */
265 void _validateLinkElement(Element node) { 265 void _validateLinkElement(Element node) {
266 var rel = node.attributes['rel']; 266 var rel = node.attributes['rel'];
267 if (rel != 'import' && rel != 'stylesheet') return; 267 if (rel != 'import' && rel != 'stylesheet') return;
268 268
269 if (rel == 'import' && _initSeen) { 269 if (rel == 'import' && _dartTagSeen) {
270 _logger.warning( 270 _logger.warning(
271 "Move HTML imports above the 'polymer/init.dart' script tag", 271 "Move HTML imports above your Dart script tag.",
272 span: node.sourceSpan); 272 span: node.sourceSpan);
273 } 273 }
274 274
275 var href = node.attributes['href']; 275 var href = node.attributes['href'];
276 if (href != null && href != '') return; 276 if (href != null && href != '') return;
277 277
278 // TODO(sigmund): warn also if href can't be resolved. 278 // TODO(sigmund): warn also if href can't be resolved.
279 _logger.warning('link rel="$rel" missing href.', span: node.sourceSpan); 279 _logger.warning('link rel="$rel" missing href.', span: node.sourceSpan);
280 } 280 }
281 281
(...skipping 58 matching lines...) Expand 10 before | Expand all | Expand 10 after
340 * error, we warn about it when src file ends in .dart, but the type is 340 * error, we warn about it when src file ends in .dart, but the type is
341 * incorrect, or when users write code in an inline script tag of a custom 341 * incorrect, or when users write code in an inline script tag of a custom
342 * element. 342 * element.
343 * 343 *
344 * The hope is that these cases shouldn't break existing valid code, but that 344 * The hope is that these cases shouldn't break existing valid code, but that
345 * they'll help Polymer authors avoid having their Dart code accidentally 345 * they'll help Polymer authors avoid having their Dart code accidentally
346 * interpreted as JavaScript by the browser. 346 * interpreted as JavaScript by the browser.
347 */ 347 */
348 void _validateScriptElement(Element node) { 348 void _validateScriptElement(Element node) {
349 var scriptType = node.attributes['type']; 349 var scriptType = node.attributes['type'];
350 var isDart = scriptType == 'application/dart';
350 var src = node.attributes['src']; 351 var src = node.attributes['src'];
351 352
352 if (scriptType == null) { 353 if (scriptType == null) {
353 if (src == null && _inPolymerElement) { 354 if (src == null && _inPolymerElement) {
354 // TODO(sigmund): revisit this check once we start interop with polymer 355 // TODO(sigmund): revisit this check once we start interop with polymer
355 // elements written in JS. Maybe we need to inspect the contents of the 356 // elements written in JS. Maybe we need to inspect the contents of the
356 // script to find whether there is an import or something that indicates 357 // script to find whether there is an import or something that indicates
357 // that the code is indeed using Dart. 358 // that the code is indeed using Dart.
358 _logger.warning('script tag in polymer element with no type will ' 359 _logger.warning('script tag in polymer element with no type will '
359 'be treated as JavaScript. Did you forget type="application/dart"?', 360 'be treated as JavaScript. Did you forget type="application/dart"?',
360 span: node.sourceSpan); 361 span: node.sourceSpan);
361 } 362 }
362 if (src != null && src.endsWith('.dart')) { 363 } else if (isDart) {
363 _logger.warning('script tag with .dart source file but no type will ' 364 if (_dartTagSeen) {
364 'be treated as JavaScript. Did you forget type="application/dart"?', 365 _logger.warning('Only one "application/dart" script tag per document '
365 span: node.sourceSpan); 366 'is allowed.', span: node.sourceSpan);
366 } 367 }
368 _dartTagSeen = true;
367 } 369 }
368 370
369 if (src == null) return; 371 if (src == null) return;
370 372
371 if (src == 'packages/polymer/boot.js') { 373 if (src == 'packages/polymer/boot.js') {
372 _logger.warning(BOOT_JS_DEPRECATED, span: node.sourceSpan); 374 _logger.warning(BOOT_JS_DEPRECATED, span: node.sourceSpan);
373 return; 375 return;
374 } 376 }
375 if (src == 'packages/browser/dart.js' || 377 if (src == 'packages/browser/dart.js' ||
376 src == 'packages/unittest/test_controller.js') { 378 src == 'packages/unittest/test_controller.js') {
377 _dartJSSeen = true; 379 _dartJSSeen = true;
378 return; 380 return;
379 } 381 }
380 382
381 if (src == 'packages/polymer/init.dart') { 383 if (src.endsWith('.dart') && !isDart) {
382 _initSeen = true; 384 _logger.warning('Wrong script type, expected type="application/dart".',
383 if (scriptType != 'application/dart') { 385 span: node.sourceSpan);
384 _logger.warning('wrong script type, expected type="application/dart".',
385 span: node.sourceSpan);
386 }
387 return; 386 return;
388 } 387 }
389 388
390 if (scriptType != 'application/dart') return; 389 if (!src.endsWith('.dart') && isDart) {
391
392 if (!src.endsWith('.dart')) {
393 _logger.warning('"application/dart" scripts should ' 390 _logger.warning('"application/dart" scripts should '
394 'use the .dart file extension.', 391 'use the .dart file extension.',
395 span: node.sourceSpan); 392 span: node.sourceSpan);
393 return;
396 } 394 }
397 395
398 if (node.innerHtml.trim() != '') { 396 if (node.innerHtml.trim() != '') {
399 _logger.warning('script tag has "src" attribute and also has script ' 397 _logger.warning('script tag has "src" attribute and also has script '
400 'text.', span: node.sourceSpan); 398 'text.', span: node.sourceSpan);
401 } 399 }
402 } 400 }
403 401
404 /** 402 /**
405 * Produces warnings for misuses of on-foo event handlers, and for instanting 403 * Produces warnings for misuses of on-foo event handlers, and for instanting
(...skipping 131 matching lines...) Expand 10 before | Expand all | Expand 10 after
537 bool _isCustomTag(String name) { 535 bool _isCustomTag(String name) {
538 if (name == null || !name.contains('-')) return false; 536 if (name == null || !name.contains('-')) return false;
539 return !_invalidTagNames.containsKey(name); 537 return !_invalidTagNames.containsKey(name);
540 } 538 }
541 539
542 const String _RED_COLOR = '\u001b[31m'; 540 const String _RED_COLOR = '\u001b[31m';
543 const String _MAGENTA_COLOR = '\u001b[35m'; 541 const String _MAGENTA_COLOR = '\u001b[35m';
544 const String _NO_COLOR = '\u001b[0m'; 542 const String _NO_COLOR = '\u001b[0m';
545 543
546 const String USE_INIT_DART = 544 const String USE_INIT_DART =
547 'To run a polymer applications, make sure to include ' 545 'To run a polymer applications, you need to call "initPolymer". You can '
546 'either include a generic script tag that does this for you:'
548 '\'<script type="application/dart" src="packages/polymer/init.dart">' 547 '\'<script type="application/dart" src="packages/polymer/init.dart">'
549 '</script>\' in your page, after all HTML imports.'; 548 '</script>\' or add your own script tag and call that function. '
549 'Make sure the script tag is placed after all HTML imports.';
550 550
551 const String USE_DART_JS = 551 const String USE_DART_JS =
552 'To run a polymer applications in Dartium, make sure to include' 552 'To run a polymer applications in Dartium, make sure to include'
553 '\'<script src="packages/browser/dart.js"></script>\' in your page'; 553 '\'<script src="packages/browser/dart.js"></script>\' in your page';
554 554
555 const String BOOT_JS_DEPRECATED = 555 const String BOOT_JS_DEPRECATED =
556 '"boot.js" is now deprecated. Instead, you can initialize your polymer ' 556 '"boot.js" is now deprecated. Instead, you can initialize your polymer '
557 'application by calling "initPolymer()" in your main. If you don\'t have a ' 557 'application by calling "initPolymer()" in your main. If you don\'t have a '
558 'main, then you can include our generic main by adding the following ' 558 'main, then you can include our generic main by adding the following '
559 'script tag to your page: \'<script type="application/dart" ' 559 'script tag to your page: \'<script type="application/dart" '
560 'src="packages/polymer/init.dart"> </script>\'. Additionally you need to ' 560 'src="packages/polymer/init.dart"> </script>\'. Additionally you need to '
561 'include: \'<script src="packages/browser/dart.js"></script>\' in the page ' 561 'include: \'<script src="packages/browser/dart.js"></script>\' in the page '
562 'too. Make sure these script tags come after all HTML imports.'; 562 'too. Make sure these script tags come after all HTML imports.';
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698