| OLD | NEW |
| (Empty) |
| 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 | |
| 3 // BSD-style license that can be found in the LICENSE file. | |
| 4 | |
| 5 /** | |
| 6 * Datatypes holding information extracted by the analyzer and used by later | |
| 7 * phases of the compiler. | |
| 8 */ | |
| 9 library polymer.src.info; | |
| 10 | |
| 11 import 'dart:collection' show SplayTreeMap, LinkedHashMap; | |
| 12 | |
| 13 import 'package:csslib/visitor.dart'; | |
| 14 import 'package:html5lib/dom.dart'; | |
| 15 import 'package:source_maps/span.dart' show Span; | |
| 16 | |
| 17 import 'messages.dart'; | |
| 18 import 'utils.dart'; | |
| 19 | |
| 20 /** | |
| 21 * Information that is global. Roughly corresponds to `window` and `document`. | |
| 22 */ | |
| 23 class GlobalInfo { | |
| 24 /** | |
| 25 * Pseudo-element names exposed in a component via a pseudo attribute. | |
| 26 * The name is only available from CSS (not Dart code) so they're mangled. | |
| 27 * The same pseudo-element in different components maps to the same | |
| 28 * mangled name (as the pseudo-element is scoped inside of the component). | |
| 29 */ | |
| 30 final Map<String, String> pseudoElements = <String, String>{}; | |
| 31 | |
| 32 /** All components declared in the application. */ | |
| 33 final Map<String, ComponentInfo> components = new SplayTreeMap(); | |
| 34 } | |
| 35 | |
| 36 /** | |
| 37 * Information for any library-like input. We consider each HTML file a library, | |
| 38 * and each component declaration a library as well. Hence we use this as a base | |
| 39 * class for both [FileInfo] and [ComponentInfo]. Both HTML files and components | |
| 40 * can have .dart code provided by the user for top-level user scripts and | |
| 41 * component-level behavior code. This code can either be inlined in the HTML | |
| 42 * file or included in a script tag with the "src" attribute. | |
| 43 */ | |
| 44 abstract class LibraryInfo { | |
| 45 /** Parsed cssSource. */ | |
| 46 List<StyleSheet> styleSheets = []; | |
| 47 } | |
| 48 | |
| 49 /** Information extracted at the file-level. */ | |
| 50 class FileInfo extends LibraryInfo { | |
| 51 /** Relative path to this file from the compiler's base directory. */ | |
| 52 final UrlInfo inputUrl; | |
| 53 | |
| 54 /** | |
| 55 * All custom element definitions in this file. This may contain duplicates. | |
| 56 * Normally you should use [components] for lookup. | |
| 57 */ | |
| 58 final List<ComponentInfo> declaredComponents = new List<ComponentInfo>(); | |
| 59 | |
| 60 /** | |
| 61 * All custom element definitions defined in this file or imported via | |
| 62 *`<link rel='components'>` tag. Maps from the tag name to the component | |
| 63 * information. This map is sorted by the tag name. | |
| 64 */ | |
| 65 final Map<String, ComponentInfo> components = | |
| 66 new SplayTreeMap<String, ComponentInfo>(); | |
| 67 | |
| 68 /** Files imported with `<link rel="import">` */ | |
| 69 final List<UrlInfo> componentLinks = <UrlInfo>[]; | |
| 70 | |
| 71 /** Files imported with `<link rel="stylesheet">` */ | |
| 72 final List<UrlInfo> styleSheetHrefs = <UrlInfo>[]; | |
| 73 | |
| 74 FileInfo(this.inputUrl); | |
| 75 } | |
| 76 | |
| 77 | |
| 78 /** Information about a web component definition declared locally. */ | |
| 79 class ComponentInfo extends LibraryInfo { | |
| 80 | |
| 81 /** The component tag name, defined with the `name` attribute on `element`. */ | |
| 82 final String tagName; | |
| 83 | |
| 84 /** | |
| 85 * The tag name that this component extends, defined with the `extends` | |
| 86 * attribute on `element`. | |
| 87 */ | |
| 88 final String extendsTag; | |
| 89 | |
| 90 /** | |
| 91 * The component info associated with the [extendsTag] name, if any. | |
| 92 * This will be `null` if the component extends a built-in HTML tag, or | |
| 93 * if the analyzer has not run yet. | |
| 94 */ | |
| 95 ComponentInfo extendsComponent; | |
| 96 | |
| 97 /** The declaring `<element>` tag. */ | |
| 98 final Node element; | |
| 99 | |
| 100 /** | |
| 101 * True if [tagName] was defined by more than one component. If this happened | |
| 102 * we will skip over the component. | |
| 103 */ | |
| 104 bool hasConflict = false; | |
| 105 | |
| 106 ComponentInfo(this.element, this.tagName, this.extendsTag); | |
| 107 | |
| 108 /** | |
| 109 * Gets the HTML tag extended by the base of the component hierarchy. | |
| 110 * Equivalent to [extendsTag] if this inherits directly from an HTML element, | |
| 111 * in other words, if [extendsComponent] is null. | |
| 112 */ | |
| 113 String get baseExtendsTag => | |
| 114 extendsComponent == null ? extendsTag : extendsComponent.baseExtendsTag; | |
| 115 | |
| 116 Span get sourceSpan => element.sourceSpan; | |
| 117 | |
| 118 /** Is apply-author-styles enabled. */ | |
| 119 bool get hasAuthorStyles => | |
| 120 element.attributes.containsKey('apply-author-styles'); | |
| 121 | |
| 122 String toString() => '#<ComponentInfo $tagName>'; | |
| 123 } | |
| 124 | |
| 125 | |
| 126 /** | |
| 127 * Information extracted about a URL that refers to another file. This is | |
| 128 * mainly introduced to be able to trace back where URLs come from when | |
| 129 * reporting errors. | |
| 130 */ | |
| 131 class UrlInfo { | |
| 132 /** Original url. */ | |
| 133 final String url; | |
| 134 | |
| 135 /** Path that the URL points to. */ | |
| 136 final String resolvedPath; | |
| 137 | |
| 138 /** Original source location where the URL was extracted from. */ | |
| 139 final Span sourceSpan; | |
| 140 | |
| 141 UrlInfo(this.url, this.resolvedPath, this.sourceSpan); | |
| 142 | |
| 143 /** | |
| 144 * Resolve a path from an [url] found in a file located at [inputUrl]. | |
| 145 * Returns null for absolute [url]. Unless [ignoreAbsolute] is true, reports | |
| 146 * an error message if the url is an absolute url. | |
| 147 */ | |
| 148 static UrlInfo resolve(String url, UrlInfo inputUrl, Span span, | |
| 149 String packageRoot, Messages messages, {bool ignoreAbsolute: false}) { | |
| 150 | |
| 151 var uri = Uri.parse(url); | |
| 152 if (uri.host != '' || (uri.scheme != '' && uri.scheme != 'package')) { | |
| 153 if (!ignoreAbsolute) { | |
| 154 messages.error('absolute paths not allowed here: "$url"', span); | |
| 155 } | |
| 156 return null; | |
| 157 } | |
| 158 | |
| 159 var target; | |
| 160 if (url.startsWith('package:')) { | |
| 161 target = path.join(packageRoot, url.substring(8)); | |
| 162 } else if (path.isAbsolute(url)) { | |
| 163 if (!ignoreAbsolute) { | |
| 164 messages.error('absolute paths not allowed here: "$url"', span); | |
| 165 } | |
| 166 return null; | |
| 167 } else { | |
| 168 target = path.join(path.dirname(inputUrl.resolvedPath), url); | |
| 169 url = pathToUrl(path.normalize(path.join( | |
| 170 path.dirname(inputUrl.url), url))); | |
| 171 } | |
| 172 target = path.normalize(target); | |
| 173 | |
| 174 return new UrlInfo(url, target, span); | |
| 175 } | |
| 176 | |
| 177 bool operator ==(UrlInfo other) => | |
| 178 url == other.url && resolvedPath == other.resolvedPath; | |
| 179 | |
| 180 int get hashCode => resolvedPath.hashCode; | |
| 181 | |
| 182 String toString() => "#<UrlInfo url: $url, resolvedPath: $resolvedPath>"; | |
| 183 } | |
| OLD | NEW |