| Index: pkg/polymer/lib/src/paths.dart
|
| diff --git a/pkg/polymer/lib/src/paths.dart b/pkg/polymer/lib/src/paths.dart
|
| new file mode 100644
|
| index 0000000000000000000000000000000000000000..34037d95fd4d818e806a40b18d7bccb9fbfd62af
|
| --- /dev/null
|
| +++ b/pkg/polymer/lib/src/paths.dart
|
| @@ -0,0 +1,170 @@
|
| +// Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file
|
| +// for details. All rights reserved. Use of this source code is governed by a
|
| +// BSD-style license that can be found in the LICENSE file.
|
| +
|
| +/**
|
| + * Holds path information that is used by the WebUI compiler to find files,
|
| + * compute their output location and relative paths between them.
|
| + */
|
| +library polymer.src.paths;
|
| +
|
| +import 'info.dart' show UrlInfo;
|
| +import 'messages.dart';
|
| +import 'summary.dart';
|
| +import 'utils.dart' show path, pathToUrl;
|
| +
|
| +/**
|
| + * Stores information about paths and computes mappings between input and output
|
| + * path locations.
|
| + */
|
| +class PathMapper {
|
| + /**
|
| + * Common prefix to all input paths that are read from the file system. The
|
| + * output generated by the compiler will reflect the directory structure
|
| + * starting from [_baseDir]. For instance, if [_baseDir] is `a/b/c` and
|
| + * [_outputDir] is `g/h/`, then the corresponding output file for
|
| + * `a/b/c/e/f.html` will be under `g/h/e/f.html.dart`.
|
| + */
|
| + final String _baseDir;
|
| +
|
| + /** Base path where all output is generated. */
|
| + final String _outputDir;
|
| +
|
| + /** The package root directory. */
|
| + final String packageRoot;
|
| +
|
| + /** Whether to add prefixes and to output file names. */
|
| + final bool _mangleFilenames;
|
| +
|
| + final bool _rewriteUrls;
|
| +
|
| + bool get _rewritePackageImports => _rewriteUrls || !_mangleFilenames;
|
| +
|
| + /** Default prefix added to all filenames. */
|
| + static const String _DEFAULT_PREFIX = '_';
|
| +
|
| + PathMapper(String baseDir, String outputDir, this.packageRoot,
|
| + bool forceMangle, this._rewriteUrls)
|
| + : _baseDir = baseDir,
|
| + _outputDir = outputDir,
|
| + _mangleFilenames = forceMangle || (baseDir == outputDir);
|
| +
|
| + /** Add a prefix and [suffix] if [_mangleFilenames] is true */
|
| + String mangle(String name, String suffix, [bool forceSuffix = false]) =>
|
| + _mangleFilenames ? "$_DEFAULT_PREFIX$name$suffix"
|
| + : (forceSuffix ? "$name$suffix" : name);
|
| +
|
| + /**
|
| + * Checks that `input.resolvedPath` is a valid input path. It must be in
|
| + * [_baseDir] and must not be in the [_outputDir]. If not, an error message
|
| + * is added to [messages].
|
| + */
|
| + bool checkInputPath(UrlInfo input, Messages messages) {
|
| + if (_mangleFilenames) return true;
|
| + var canonicalized = path.normalize(input.resolvedPath);
|
| + var parentDir = '..${path.separator}';
|
| + if (!path.relative(canonicalized, from: _outputDir).startsWith(parentDir)) {
|
| + messages.error(
|
| + 'The file ${input.resolvedPath} cannot be processed. '
|
| + 'Files cannot be under the output folder (${_outputDir}).',
|
| + input.sourceSpan);
|
| + return false;
|
| + }
|
| + if (path.relative(canonicalized, from: _baseDir).startsWith(parentDir)) {
|
| + messages.error(
|
| + 'The file ${input.resolvedPath} cannot be processed. '
|
| + 'All processed files must be under the base folder (${_baseDir}), you'
|
| + ' can specify the base folder using the --basedir flag.',
|
| + input.sourceSpan);
|
| + return false;
|
| + }
|
| + return true;
|
| + }
|
| +
|
| + /**
|
| + * The path to the output file corresponding to [input], by adding
|
| + * [_DEFAULT_PREFIX] and a [suffix] to its file name.
|
| + */
|
| + String outputPath(String input, String suffix, [bool forceSuffix = false]) =>
|
| + path.join(outputDirPath(input),
|
| + mangle(path.basename(input), suffix, forceSuffix));
|
| +
|
| + /** The path to the output file corresponding to [info]. */
|
| + String outputLibraryPath(LibrarySummary lib) =>
|
| + path.join(outputDirPath(lib.dartCodeUrl.resolvedPath),
|
| + lib.outputFilename);
|
| +
|
| + /** The corresponding output directory for [input]'s directory. */
|
| + String outputDirPath(String input) {
|
| + return _rewritePackages(path.normalize(
|
| + path.join(_outputDir, path.relative(
|
| + path.dirname(input), from: _baseDir))));
|
| + }
|
| +
|
| + /**
|
| + * We deal with `packages/` directories in a very special way. We assume it
|
| + * points to resources loaded from other pub packages. If an output directory
|
| + * is specified, the compiler will create a packages symlink so that
|
| + * `package:` imports work.
|
| + *
|
| + * To make it possible to share components through pub, we allow using tags of
|
| + * the form `<link rel="import" href="packages/...">`, so that you can
|
| + * refer to components within the packages symlink. Regardless of whether an
|
| + * --out option was given to the compiler, we don't want to generate files
|
| + * inside `packages/` for those components. Instead we will generate such
|
| + * code in a special directory called `_from_packages/`.
|
| + */
|
| + String _rewritePackages(String outputPath) {
|
| + // TODO(jmesserly): this should match against packageRoot instead.
|
| + if (!outputPath.contains('packages')) return outputPath;
|
| + if (!_rewritePackageImports) return outputPath;
|
| + var segments = path.split(outputPath);
|
| + return path.joinAll(
|
| + segments.map((s) => s == 'packages' ? '_from_packages' : s));
|
| + }
|
| +
|
| + /**
|
| + * Returns a url to import/export the output library represented by [target]
|
| + * from the output library of [src]. In other words, a url to import or export
|
| + * `target.outputFilename` from `src.outputFilename`.
|
| + */
|
| + String importUrlFor(LibrarySummary src, LibrarySummary target) {
|
| + if (!_rewritePackageImports &&
|
| + target.dartCodeUrl.url.startsWith('package:')) {
|
| + return pathToUrl(path.join(path.dirname(target.dartCodeUrl.url),
|
| + target.outputFilename));
|
| + }
|
| + var srcDir = path.dirname(src.dartCodeUrl.resolvedPath);
|
| + var relDir = path.relative(
|
| + path.dirname(target.dartCodeUrl.resolvedPath), from: srcDir);
|
| + return pathToUrl(_rewritePackages(path.normalize(
|
| + path.join(relDir, target.outputFilename))));
|
| + }
|
| +
|
| + /**
|
| + * Transforms a [target] url seen in [src] (e.g. a Dart import, a .css href in
|
| + * an HTML file, etc) into a corresponding url from the output file associated
|
| + * with [src]. This will keep 'package:', 'dart:', path-absolute, and absolute
|
| + * urls intact, but it will fix relative paths to walk from the output
|
| + * directory back to the input directory. An exception will be thrown if
|
| + * [target] is not under [_baseDir].
|
| + */
|
| + String transformUrl(String src, String target) {
|
| + var uri = Uri.parse(target);
|
| + if (uri.isAbsolute) return target;
|
| + if (!uri.scheme.isEmpty) return target;
|
| + if (!uri.host.isEmpty) return target;
|
| + if (uri.path.isEmpty) return target; // Implies standalone ? or # in URI.
|
| + if (path.isAbsolute(target)) return target;
|
| +
|
| + return pathToUrl(path.normalize(path.relative(
|
| + path.join(path.dirname(src), target), from: outputDirPath(src))));
|
| + }
|
| +}
|
| +
|
| +/**
|
| + * Returns a "mangled" name, with a prefix and [suffix] depending on the
|
| + * compiler's settings. [forceSuffix] causes [suffix] to be appended even if
|
| + * the compiler is not mangling names.
|
| + */
|
| +typedef String NameMangler(String name, String suffix, [bool forceSuffix]);
|
|
|