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

Side by Side Diff: pkg/polymer/lib/src/analyzer.dart

Issue 23658002: Remove processing of dart code, summary.dart, simplified info.dart (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Created 7 years, 3 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
« no previous file with comments | « pkg/polymer/lib/dwc.dart ('k') | pkg/polymer/lib/src/compiler.dart » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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 * Part of the template compilation that concerns with extracting information 6 * Part of the template compilation that concerns with extracting information
7 * from the HTML parse tree. 7 * from the HTML parse tree.
8 */ 8 */
9 library analyzer; 9 library analyzer;
10 10
11 import 'package:html5lib/dom.dart'; 11 import 'package:html5lib/dom.dart';
12 import 'package:html5lib/dom_parsing.dart'; 12 import 'package:html5lib/dom_parsing.dart';
13 import 'package:source_maps/span.dart' hide SourceFile;
14 13
15 import 'custom_tag_name.dart'; 14 import 'custom_tag_name.dart';
16 import 'dart_parser.dart' show parseDartCode;
17 import 'files.dart'; 15 import 'files.dart';
18 import 'info.dart'; 16 import 'info.dart';
19 import 'messages.dart'; 17 import 'messages.dart';
20 import 'summary.dart';
21 18
22 /** 19 /**
23 * Finds custom elements in this file and the list of referenced files with 20 * Finds custom elements in this file and the list of referenced files with
24 * component declarations. This is the first pass of analysis on a file. 21 * component declarations. This is the first pass of analysis on a file.
25 * 22 *
26 * Adds emitted error/warning messages to [messages], if [messages] is 23 * Adds emitted error/warning messages to [messages], if [messages] is
27 * supplied. 24 * supplied.
28 */ 25 */
29 FileInfo analyzeDefinitions(GlobalInfo global, UrlInfo inputUrl, 26 FileInfo analyzeDefinitions(GlobalInfo global, UrlInfo inputUrl,
30 Document document, String packageRoot, 27 Document document, String packageRoot, Messages messages) {
31 Messages messages, {bool isEntryPoint: false}) { 28 var result = new FileInfo(inputUrl);
32 var result = new FileInfo(inputUrl, isEntryPoint);
33 var loader = new _ElementLoader(global, result, packageRoot, messages); 29 var loader = new _ElementLoader(global, result, packageRoot, messages);
34 loader.visit(document); 30 loader.visit(document);
35 return result; 31 return result;
36 } 32 }
37 33
38 /** 34 /**
39 * Extract relevant information from all files found from the root document. 35 * Extract relevant information from all files found from the root document.
40 * 36 *
41 * Adds emitted error/warning messages to [messages], if [messages] is 37 * Adds emitted error/warning messages to [messages], if [messages] is
42 * supplied. 38 * supplied.
(...skipping 89 matching lines...) Expand 10 before | Expand all | Expand 10 after
132 node.sourceSpan); 128 node.sourceSpan);
133 } 129 }
134 _keepIndentationSpaces = value != 'remove'; 130 _keepIndentationSpaces = value != 'remove';
135 } 131 }
136 132
137 // Invoke super to visit children. 133 // Invoke super to visit children.
138 super.visitElement(node); 134 super.visitElement(node);
139 135
140 _keepIndentationSpaces = keepSpaces; 136 _keepIndentationSpaces = keepSpaces;
141 _currentInfo = lastInfo; 137 _currentInfo = lastInfo;
142
143 if (node.tagName == 'body' || node.parent == null) {
144 _fileInfo.body = node;
145 }
146 } 138 }
147 139
148 void _analyzeComponent(ComponentInfo component) { 140 void _analyzeComponent(ComponentInfo component) {
149 var baseTag = component.extendsTag; 141 var baseTag = component.extendsTag;
150 component.extendsComponent = baseTag == null ? null 142 component.extendsComponent = baseTag == null ? null
151 : _fileInfo.components[baseTag]; 143 : _fileInfo.components[baseTag];
152 if (component.extendsComponent == null && isCustomTag(baseTag)) { 144 if (component.extendsComponent == null && isCustomTag(baseTag)) {
153 _messages.warning( 145 _messages.warning(
154 'custom element with tag name ${component.extendsTag} not found.', 146 'custom element with tag name ${component.extendsTag} not found.',
155 component.element.sourceSpan); 147 component.element.sourceSpan);
156 } 148 }
157
158 // Now that the component's code has been loaded, we can validate that the
159 // class exists.
160 component.findClassDeclaration(_messages);
161 } 149 }
162 150
163 void _bindCustomElement(Element node) { 151 void _bindCustomElement(Element node) {
164 // <fancy-button> 152 // <fancy-button>
165 var component = _fileInfo.components[node.tagName]; 153 var component = _fileInfo.components[node.tagName];
166 if (component == null) { 154 if (component == null) {
167 // TODO(jmesserly): warn for unknown element tags? 155 // TODO(jmesserly): warn for unknown element tags?
168 156
169 // <button is="fancy-button"> 157 // <button is="fancy-button">
170 var componentName = node.attributes['is']; 158 var componentName = node.attributes['is'];
171 if (componentName != null) { 159 if (componentName != null) {
172 component = _fileInfo.components[componentName]; 160 component = _fileInfo.components[componentName];
173 } else if (isCustomTag(node.tagName)) { 161 } else if (isCustomTag(node.tagName)) {
174 componentName = node.tagName; 162 componentName = node.tagName;
175 } 163 }
176 if (component == null && componentName != null && 164 if (component == null && componentName != null &&
177 componentName != 'polymer-element') { 165 componentName != 'polymer-element') {
178 _messages.warning( 166 _messages.warning(
179 'custom element with tag name $componentName not found.', 167 'custom element with tag name $componentName not found.',
180 node.sourceSpan); 168 node.sourceSpan);
181 } 169 }
182 } 170 }
183 171
184 if (component != null) { 172 if (component != null) {
185 if (!component.hasConflict) {
186 _currentInfo.usedComponents[component] = true;
187 }
188
189 var baseTag = component.baseExtendsTag; 173 var baseTag = component.baseExtendsTag;
190 var nodeTag = node.tagName; 174 var nodeTag = node.tagName;
191 var hasIsAttribute = node.attributes.containsKey('is'); 175 var hasIsAttribute = node.attributes.containsKey('is');
192 176
193 if (baseTag != null && !hasIsAttribute) { 177 if (baseTag != null && !hasIsAttribute) {
194 _messages.warning( 178 _messages.warning(
195 'custom element "${component.tagName}" extends from "$baseTag", but' 179 'custom element "${component.tagName}" extends from "$baseTag", but'
196 ' this tag will not include the default properties of "$baseTag". ' 180 ' this tag will not include the default properties of "$baseTag". '
197 'To fix this, either write this tag as <$baseTag ' 181 'To fix this, either write this tag as <$baseTag '
198 'is="${component.tagName}"> or remove the "extends" attribute from ' 182 'is="${component.tagName}"> or remove the "extends" attribute from '
(...skipping 65 matching lines...) Expand 10 before | Expand all | Expand 10 after
264 248
265 /** 249 /**
266 * Normalizes references in [info]. On the [analyzeDefinitions] phase, the 250 * Normalizes references in [info]. On the [analyzeDefinitions] phase, the
267 * analyzer extracted names of files and components. Here we link those names 251 * analyzer extracted names of files and components. Here we link those names
268 * to actual info classes. In particular: 252 * to actual info classes. In particular:
269 * * we initialize the [FileInfo.components] map in [info] by importing all 253 * * we initialize the [FileInfo.components] map in [info] by importing all
270 * [declaredComponents], 254 * [declaredComponents],
271 * * we scan all [info.componentLinks] and import their 255 * * we scan all [info.componentLinks] and import their
272 * [info.declaredComponents], using [files] to map the href to the file 256 * [info.declaredComponents], using [files] to map the href to the file
273 * info. Names in [info] will shadow names from imported files. 257 * info. Names in [info] will shadow names from imported files.
274 * * we fill [LibraryInfo.externalCode] on each component declared in
275 * [info].
276 */ 258 */
277 void _normalize(FileInfo info, Map<String, FileInfo> files) { 259 void _normalize(FileInfo info, Map<String, FileInfo> files) {
278 _attachExtenalScript(info, files);
279
280 for (var component in info.declaredComponents) { 260 for (var component in info.declaredComponents) {
281 _addComponent(info, component); 261 _addComponent(info, component);
282 _attachExtenalScript(component, files);
283 } 262 }
284 263
285 for (var link in info.componentLinks) { 264 for (var link in info.componentLinks) {
286 var file = files[link.resolvedPath]; 265 var file = files[link.resolvedPath];
287 // We already issued an error for missing files. 266 // We already issued an error for missing files.
288 if (file == null) continue; 267 if (file == null) continue;
289 file.declaredComponents.forEach((c) => _addComponent(info, c)); 268 file.declaredComponents.forEach((c) => _addComponent(info, c));
290 } 269 }
291 } 270 }
292 271
293 /**
294 * Stores a direct reference in [info] to a dart source file that was loaded
295 * in a script tag with the 'src' attribute.
296 */
297 void _attachExtenalScript(LibraryInfo info, Map<String, FileInfo> files) {
298 var externalFile = info.externalFile;
299 if (externalFile != null) {
300 info.externalCode = files[externalFile.resolvedPath];
301 if (info.externalCode != null) info.externalCode.htmlFile = info;
302 }
303 }
304
305 /** Adds a component's tag name to the names in scope for [fileInfo]. */ 272 /** Adds a component's tag name to the names in scope for [fileInfo]. */
306 void _addComponent(FileInfo fileInfo, ComponentSummary component) { 273 void _addComponent(FileInfo fileInfo, ComponentInfo component) {
307 var existing = fileInfo.components[component.tagName]; 274 var existing = fileInfo.components[component.tagName];
308 if (existing != null) { 275 if (existing != null) {
309 if (existing == component) { 276 if (existing == component) {
310 // This is the same exact component as the existing one. 277 // This is the same exact component as the existing one.
311 return; 278 return;
312 } 279 }
313 280
314 if (existing is ComponentInfo && component is! ComponentInfo) { 281 if (existing is ComponentInfo && component is! ComponentInfo) {
315 // Components declared in [fileInfo] shadow component names declared in 282 // Components declared in [fileInfo] shadow component names declared in
316 // imported files. 283 // imported files.
(...skipping 115 matching lines...) Expand 10 before | Expand all | Expand 10 after
432 var tagName = node.attributes['name']; 399 var tagName = node.attributes['name'];
433 var extendsTag = node.attributes['extends']; 400 var extendsTag = node.attributes['extends'];
434 401
435 if (tagName == null) { 402 if (tagName == null) {
436 _messages.error('Missing tag name of the component. Please include an ' 403 _messages.error('Missing tag name of the component. Please include an '
437 'attribute like \'name="your-tag-name"\'.', 404 'attribute like \'name="your-tag-name"\'.',
438 node.sourceSpan); 405 node.sourceSpan);
439 return; 406 return;
440 } 407 }
441 408
442 var component = new ComponentInfo(node, _fileInfo, tagName, extendsTag); 409 var component = new ComponentInfo(node, tagName, extendsTag);
443 _fileInfo.declaredComponents.add(component); 410 _fileInfo.declaredComponents.add(component);
444 _addComponent(component); 411 _addComponent(component);
445 412
446 var lastInfo = _currentInfo; 413 var lastInfo = _currentInfo;
447 _currentInfo = component; 414 _currentInfo = component;
448 super.visitElement(node); 415 super.visitElement(node);
449 _currentInfo = lastInfo; 416 _currentInfo = lastInfo;
450 } 417 }
451 418
452 /** Adds a component's tag name to the global list. */ 419 /** Adds a component's tag name to the global list. */
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after
489 node.sourceSpan); 456 node.sourceSpan);
490 } 457 }
491 if (src != null && src.endsWith('.dart')) { 458 if (src != null && src.endsWith('.dart')) {
492 _messages.warning('script tag with .dart source file but no type will ' 459 _messages.warning('script tag with .dart source file but no type will '
493 'be treated as JavaScript. Did you forget type="application/dart"?', 460 'be treated as JavaScript. Did you forget type="application/dart"?',
494 node.sourceSpan); 461 node.sourceSpan);
495 } 462 }
496 return; 463 return;
497 } 464 }
498 465
499 if (scriptType != 'application/dart') { 466 if (scriptType != 'application/dart') return;
500 if (_currentInfo is ComponentInfo) {
501 // TODO(jmesserly): this warning should not be here, but our compiler
502 // does the wrong thing and it could cause surprising behavior, so let
503 // the user know! See issue #340 for more info.
504 // What we should be doing: leave JS component untouched by compiler.
505 _messages.warning('our custom element implementation does not support '
506 'JavaScript components yet. If this is affecting you please let us '
507 'know at https://github.com/dart-lang/web-ui/issues/340.',
508 node.sourceSpan);
509 }
510
511 return;
512 }
513 467
514 if (src != null) { 468 if (src != null) {
515 if (!src.endsWith('.dart')) { 469 if (!src.endsWith('.dart')) {
516 _messages.warning('"application/dart" scripts should ' 470 _messages.warning('"application/dart" scripts should '
517 'use the .dart file extension.', 471 'use the .dart file extension.',
518 node.sourceSpan); 472 node.sourceSpan);
519 } 473 }
520 474
521 if (node.innerHtml.trim() != '') { 475 if (node.innerHtml.trim() != '') {
522 _messages.error('script tag has "src" attribute and also has script ' 476 _messages.error('script tag has "src" attribute and also has script '
523 'text.', node.sourceSpan); 477 'text.', node.sourceSpan);
524 } 478 }
525
526 if (_currentInfo.codeAttached) {
527 _tooManyScriptsError(node);
528 } else {
529 _currentInfo.externalFile = UrlInfo.resolve(src, _fileInfo.inputUrl,
530 node.sourceSpan, _packageRoot, _messages);
531 }
532 return;
533 }
534
535 if (node.nodes.length == 0) return;
536
537 // I don't think the html5 parser will emit a tree with more than
538 // one child of <script>
539 assert(node.nodes.length == 1);
540 Text text = node.nodes[0];
541
542 if (_currentInfo.codeAttached) {
543 _tooManyScriptsError(node);
544 } else if (_currentInfo == _fileInfo && !_fileInfo.isEntryPoint) {
545 _messages.warning('top-level dart code is ignored on '
546 ' HTML pages that define components, but are not the entry HTML '
547 'file.', node.sourceSpan);
548 } else {
549 _currentInfo.inlinedCode = parseDartCode(
550 _currentInfo.dartCodeUrl.resolvedPath, text.value,
551 text.sourceSpan.start);
552 if (_currentInfo.userCode.partOf != null) {
553 _messages.error('expected a library, not a part.',
554 node.sourceSpan);
555 }
556 } 479 }
557 } 480 }
558
559 void _tooManyScriptsError(Node node) {
560 var location = _currentInfo is ComponentInfo ?
561 'a custom element declaration' : 'the top-level HTML page';
562
563 _messages.error('there should be only one dart script tag in $location.',
564 node.sourceSpan);
565 }
566 } 481 }
OLDNEW
« no previous file with comments | « pkg/polymer/lib/dwc.dart ('k') | pkg/polymer/lib/src/compiler.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698