| OLD | NEW |
| 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 /// Common methods used by transfomers. | 5 /// Common methods used by transfomers. |
| 6 library polymer.src.build.common; | 6 library polymer.src.build.common; |
| 7 | 7 |
| 8 import 'dart:async'; | 8 import 'dart:async'; |
| 9 import 'dart:math' show min, max; | 9 import 'dart:math' show min, max; |
| 10 | 10 |
| (...skipping 118 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 129 var primaryId = transform.primaryInput.id; | 129 var primaryId = transform.primaryInput.id; |
| 130 bool samePackage = id.package == primaryId.package; | 130 bool samePackage = id.package == primaryId.package; |
| 131 return samePackage ? id.path | 131 return samePackage ? id.path |
| 132 : assetUrlFor(id, primaryId, transform.logger, allowAssetUrl: true); | 132 : assetUrlFor(id, primaryId, transform.logger, allowAssetUrl: true); |
| 133 } | 133 } |
| 134 | 134 |
| 135 /// Transformer phases which should be applied to the Polymer package. | 135 /// Transformer phases which should be applied to the Polymer package. |
| 136 List<List<Transformer>> get phasesForPolymer => | 136 List<List<Transformer>> get phasesForPolymer => |
| 137 [[new ObservableTransformer(['lib/src/instance.dart'])]]; | 137 [[new ObservableTransformer(['lib/src/instance.dart'])]]; |
| 138 | 138 |
| 139 /// Create an [AssetId] for a [url] seen in the [source] asset. By default this | |
| 140 /// is used to resolve relative urls that occur in HTML assets, including | |
| 141 /// cross-package urls of the form "packages/foo/bar.html". Dart "package:" | |
| 142 /// urls are not resolved unless [source] is Dart file (has a .dart extension). | |
| 143 // TODO(sigmund): delete once this is part of barback (dartbug.com/12610) | |
| 144 AssetId resolve(AssetId source, String url, TransformLogger logger, Span span, | |
| 145 {bool allowAbsolute: false}) { | |
| 146 if (url == null || url == '') return null; | |
| 147 var uri = Uri.parse(url); | |
| 148 var urlBuilder = path.url; | |
| 149 if (uri.host != '' || uri.scheme != '' || urlBuilder.isAbsolute(url)) { | |
| 150 if (source.extension == '.dart' && uri.scheme == 'package') { | |
| 151 var index = uri.path.indexOf('/'); | |
| 152 if (index != -1) { | |
| 153 return new AssetId(uri.path.substring(0, index), | |
| 154 'lib${uri.path.substring(index)}'); | |
| 155 } | |
| 156 } | |
| 157 | |
| 158 if (!allowAbsolute) { | |
| 159 logger.error('absolute paths not allowed: "$url"', span: span); | |
| 160 } | |
| 161 return null; | |
| 162 } | |
| 163 | |
| 164 var targetPath = urlBuilder.normalize( | |
| 165 urlBuilder.join(urlBuilder.dirname(source.path), url)); | |
| 166 var segments = urlBuilder.split(targetPath); | |
| 167 var sourceSegments = urlBuilder.split(source.path); | |
| 168 assert (sourceSegments.length > 0); | |
| 169 var topFolder = sourceSegments[0]; | |
| 170 var entryFolder = topFolder != 'lib' && topFolder != 'asset'; | |
| 171 | |
| 172 // Find the first 'packages/' or 'assets/' segment: | |
| 173 var packagesIndex = segments.indexOf('packages'); | |
| 174 var assetsIndex = segments.indexOf('assets'); | |
| 175 var index = (packagesIndex >= 0 && assetsIndex >= 0) | |
| 176 ? min(packagesIndex, assetsIndex) | |
| 177 : max(packagesIndex, assetsIndex); | |
| 178 if (index > -1) { | |
| 179 if (entryFolder) { | |
| 180 // URLs of the form "packages/foo/bar" seen under entry folders (like | |
| 181 // web/, test/, example/, etc) are resolved as an asset in another | |
| 182 // package. 'packages' can be used anywhere, there is no need to walk up | |
| 183 // where the entrypoint file was. | |
| 184 return _extractOtherPackageId(index, segments, logger, span); | |
| 185 } else if (index == 1 && segments[0] == '..') { | |
| 186 // Relative URLs of the form "../../packages/foo/bar" in an asset under | |
| 187 // lib/ or asset/ are also resolved as an asset in another package, but we | |
| 188 // check that the relative path goes all the way out where the packages | |
| 189 // folder lives (otherwise the app would not work in Dartium). Since | |
| 190 // [targetPath] has been normalized, "packages" or "assets" should be at | |
| 191 // index 1. | |
| 192 return _extractOtherPackageId(1, segments, logger, span); | |
| 193 } else { | |
| 194 var prefix = segments[index]; | |
| 195 var fixedSegments = []; | |
| 196 fixedSegments.addAll(sourceSegments.map((_) => '..')); | |
| 197 fixedSegments.addAll(segments.sublist(index)); | |
| 198 var fixedUrl = urlBuilder.joinAll(fixedSegments); | |
| 199 logger.error('Invalid url to reach to another package: $url. Path ' | |
| 200 'reaching to other packages must first reach up all the ' | |
| 201 'way to the $prefix folder. For example, try changing the url above ' | |
| 202 'to: $fixedUrl', span: span); | |
| 203 return null; | |
| 204 } | |
| 205 } | |
| 206 | |
| 207 // Otherwise, resolve as a path in the same package. | |
| 208 return new AssetId(source.package, targetPath); | |
| 209 } | |
| 210 | |
| 211 AssetId _extractOtherPackageId(int index, List segments, | |
| 212 TransformLogger logger, Span span) { | |
| 213 if (index >= segments.length) return null; | |
| 214 var prefix = segments[index]; | |
| 215 if (prefix != 'packages' && prefix != 'assets') return null; | |
| 216 var folder = prefix == 'packages' ? 'lib' : 'asset'; | |
| 217 if (segments.length < index + 3) { | |
| 218 logger.error("incomplete $prefix/ path. It should have at least 3 " | |
| 219 "segments $prefix/name/path-from-name's-$folder-dir", span: span); | |
| 220 return null; | |
| 221 } | |
| 222 return new AssetId(segments[index + 1], | |
| 223 path.url.join(folder, path.url.joinAll(segments.sublist(index + 2)))); | |
| 224 } | |
| 225 | |
| 226 /// Generate the import url for a file described by [id], referenced by a file | 139 /// Generate the import url for a file described by [id], referenced by a file |
| 227 /// with [sourceId]. | 140 /// with [sourceId]. |
| 228 // TODO(sigmund): this should also be in barback (dartbug.com/12610) | 141 // TODO(sigmund): this should also be in barback (dartbug.com/12610) |
| 229 String assetUrlFor(AssetId id, AssetId sourceId, TransformLogger logger, | 142 String assetUrlFor(AssetId id, AssetId sourceId, TransformLogger logger, |
| 230 {bool allowAssetUrl: false}) { | 143 {bool allowAssetUrl: false}) { |
| 231 // use package: and asset: urls if possible | 144 // use package: and asset: urls if possible |
| 232 if (id.path.startsWith('lib/')) { | 145 if (id.path.startsWith('lib/')) { |
| 233 return 'package:${id.package}/${id.path.substring(4)}'; | 146 return 'package:${id.package}/${id.path.substring(4)}'; |
| 234 } | 147 } |
| 235 | 148 |
| (...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 268 var scanner = new Scanner(null, reader, errorListener); | 181 var scanner = new Scanner(null, reader, errorListener); |
| 269 var token = scanner.tokenize(); | 182 var token = scanner.tokenize(); |
| 270 var parser = new Parser(null, errorListener); | 183 var parser = new Parser(null, errorListener); |
| 271 return parser.parseCompilationUnit(token); | 184 return parser.parseCompilationUnit(token); |
| 272 } | 185 } |
| 273 | 186 |
| 274 class _ErrorCollector extends AnalysisErrorListener { | 187 class _ErrorCollector extends AnalysisErrorListener { |
| 275 final errors = <AnalysisError>[]; | 188 final errors = <AnalysisError>[]; |
| 276 onError(error) => errors.add(error); | 189 onError(error) => errors.add(error); |
| 277 } | 190 } |
| OLD | NEW |