Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merge master into feature.use #690

Merged
merged 10 commits into from
May 22, 2019
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,12 @@

* Improve performance for stand-alone packages on Linux and Mac OS.

### JavaScript API

* Pass imports to custom importers before resolving them using `includePaths` or
the `SASS_PATH` environment variable. This matches Node Sass's behavior, so
it's considered a bug fix.

## 1.20.1

* No user-visible changes.
Expand Down
2 changes: 1 addition & 1 deletion CONTRIBUTING.md
Original file line number Diff line number Diff line change
Expand Up @@ -191,7 +191,7 @@ ways they can't share code.

To avoid colossal amounts of duplicated code, we have a few files that are
written in an asynchronous style originally and then compiled to their
synchronous equivalents using `tool/synchronize.dart`. In particular:
synchronous equivalents using `pub run grinder synchronize`. In particular:

* `lib/src/visitor/async_evaluate.dart` is compiled to
`lib/src/visitor/evaluate.dart`.
Expand Down
23 changes: 13 additions & 10 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -144,16 +144,19 @@ That's it!

## JavaScript API

When installed via npm, Dart Sass supports a JavaScript API that aims to be
compatible with [Node Sass](https://github.com/sass/node-sass#usage). Full
compatibility is a work in progress, but Dart Sass currently supports the
`render()` and `renderSync()` functions. Note however that by default,
**`renderSync()` is more than twice as fast as `render()`**, due to the overhead
of asynchronous callbacks.

To avoid this performance hit, `render()` can use the [`fibers`][fibers] package
to call asynchronous importers from the synchronous code path. To enable this,
pass the `Fiber` class to the `fiber` option:
When installed via npm, Dart Sass supports a JavaScript API that's fully
compatible with [Node Sass][] (with a few exceptions listed below), with support
for both the `render()` and `renderSync()` functions. See [the Sass
website][js api] for full API documentation!

[Node Sass]: https://github.com/sass/node-sass
[js api]: https://sass-lang.com/documentation/js-api

Note however that by default, **`renderSync()` is more than twice as fast as
`render()`** due to the overhead of asynchronous callbacks. To avoid this
performance hit, `render()` can use the [`fibers`][fibers] package to call
asynchronous importers from the synchronous code path. To enable this, pass the
`Fiber` class to the `fiber` option:

[fibers]: https://www.npmjs.com/package/fibers

Expand Down
10 changes: 5 additions & 5 deletions lib/src/ast/css/media_query.dart
Original file line number Diff line number Diff line change
Expand Up @@ -54,8 +54,8 @@ class CssMediaQuery {
var theirType = other.type?.toLowerCase();

if (ourType == null && theirType == null) {
return MediaQuerySuccessfulMergeResult._(CssMediaQuery.condition(
this.features.toList()..addAll(other.features)));
return MediaQuerySuccessfulMergeResult._(
CssMediaQuery.condition([...this.features, ...other.features]));
}

String modifier;
Expand Down Expand Up @@ -120,17 +120,17 @@ class CssMediaQuery {
// Omit the type if either input query did, since that indicates that they
// aren't targeting a browser that requires "all and".
type = (other.matchesAllTypes && ourType == null) ? null : theirType;
features = this.features.toList()..addAll(other.features);
features = [...this.features, ...other.features];
} else if (other.matchesAllTypes) {
modifier = ourModifier;
type = ourType;
features = this.features.toList()..addAll(other.features);
features = [...this.features, ...other.features];
} else if (ourType != theirType) {
return MediaQueryMergeResult.empty;
} else {
modifier = ourModifier ?? theirModifier;
type = ourType;
features = this.features.toList()..addAll(other.features);
features = [...this.features, ...other.features];
}

return MediaQuerySuccessfulMergeResult._(CssMediaQuery(
Expand Down
9 changes: 4 additions & 5 deletions lib/src/ast/sass/argument_declaration.dart
Original file line number Diff line number Diff line change
Expand Up @@ -100,9 +100,8 @@ class ArgumentDeclaration implements SassNode {
return true;
}

String toString() {
var components = List.of(arguments.map((arg) => arg.toString()));
if (restArgument != null) components.add('$restArgument...');
return components.join(', ');
}
String toString() => [
for (var arg in arguments) arg.toString(),
if (restArgument != null) '$restArgument...'
].join(', ');
}
10 changes: 6 additions & 4 deletions lib/src/ast/sass/argument_invocation.dart
Original file line number Diff line number Diff line change
Expand Up @@ -42,10 +42,12 @@ class ArgumentInvocation implements SassNode {
keywordRest = null;

String toString() {
var components = List<Object>.from(positional)
..addAll(named.keys.map((name) => "$name: ${named[name]}"));
if (rest != null) components.add("$rest...");
if (keywordRest != null) components.add("$keywordRest...");
var components = [
...positional,
for (var name in named.keys) "$name: ${named[name]}",
if (rest != null) "$rest...",
if (keywordRest != null) "$keywordRest..."
];
return "(${components.join(', ')})";
}
}
21 changes: 10 additions & 11 deletions lib/src/ast/selector/list.dart
Original file line number Diff line number Diff line change
Expand Up @@ -103,7 +103,7 @@ class SelectorList extends Selector {
if (!_complexContainsParentSelector(complex)) {
if (!implicitParent) return [complex];
return parent.components.map((parentComplex) => ComplexSelector(
parentComplex.components.toList()..addAll(complex.components),
[...parentComplex.components, ...complex.components],
lineBreak: complex.lineBreak || parentComplex.lineBreak));
}

Expand All @@ -127,8 +127,7 @@ class SelectorList extends Selector {
for (var newComplex in previousComplexes) {
var lineBreak = previousLineBreaks[i++];
for (var resolvedComplex in resolved) {
newComplexes
.add(newComplex.toList()..addAll(resolvedComplex.components));
newComplexes.add([...newComplex, ...resolvedComplex.components]);
lineBreaks.add(lineBreak || resolvedComplex.lineBreak);
}
}
Expand Down Expand Up @@ -204,18 +203,18 @@ class SelectorList extends Selector {
var last = lastComponent as CompoundSelector;
var suffix = (compound.components.first as ParentSelector).suffix;
if (suffix != null) {
last = CompoundSelector(
last.components.take(last.components.length - 1).toList()
..add(last.components.last.addSuffix(suffix))
..addAll(resolvedMembers.skip(1)));
last = CompoundSelector([
...last.components.take(last.components.length - 1),
last.components.last.addSuffix(suffix),
...resolvedMembers.skip(1)
]);
} else {
last = CompoundSelector(
last.components.toList()..addAll(resolvedMembers.skip(1)));
last =
CompoundSelector([...last.components, ...resolvedMembers.skip(1)]);
}

return ComplexSelector(
complex.components.take(complex.components.length - 1).toList()
..add(last),
[...complex.components.take(complex.components.length - 1), last],
lineBreak: complex.lineBreak);
});
}
Expand Down
4 changes: 2 additions & 2 deletions lib/src/ast/selector/type.dart
Original file line number Diff line number Diff line change
Expand Up @@ -25,9 +25,9 @@ class TypeSelector extends SimpleSelector {
if (compound.first is UniversalSelector || compound.first is TypeSelector) {
var unified = unifyUniversalAndElement(this, compound.first);
if (unified == null) return null;
return [unified]..addAll(compound.skip(1));
return [unified, ...compound.skip(1)];
} else {
return <SimpleSelector>[this]..addAll(compound);
return [this, ...compound];
}
}

Expand Down
6 changes: 2 additions & 4 deletions lib/src/ast/selector/universal.dart
Original file line number Diff line number Diff line change
Expand Up @@ -27,12 +27,10 @@ class UniversalSelector extends SimpleSelector {
if (compound.first is UniversalSelector || compound.first is TypeSelector) {
var unified = unifyUniversalAndElement(this, compound.first);
if (unified == null) return null;
return [unified]..addAll(compound.skip(1));
return [unified, ...compound.skip(1)];
}

if (namespace != null && namespace != "*") {
return <SimpleSelector>[this]..addAll(compound);
}
if (namespace != null && namespace != "*") return [this, ...compound];
if (compound.isNotEmpty) return compound;
return [this];
}
Expand Down
26 changes: 9 additions & 17 deletions lib/src/async_import_cache.dart
Original file line number Diff line number Diff line change
Expand Up @@ -77,24 +77,16 @@ class AsyncImportCache {
/// options into a single list of importers.
static List<AsyncImporter> _toImporters(Iterable<AsyncImporter> importers,
Iterable<String> loadPaths, SyncPackageResolver packageResolver) {
var list = importers?.toList() ?? [];

if (loadPaths != null) {
list.addAll(loadPaths.map((path) => FilesystemImporter(path)));
}

var sassPath = getEnvironmentVariable('SASS_PATH');
if (sassPath != null) {
list.addAll(sassPath
.split(isWindows ? ';' : ':')
.map((path) => FilesystemImporter(path)));
}

if (packageResolver != null) {
list.add(PackageImporter(packageResolver));
}

return list;
return [
...?importers,
if (loadPaths != null)
for (var path in loadPaths) FilesystemImporter(path),
if (sassPath != null)
for (var path in sassPath.split(isWindows ? ';' : ':'))
FilesystemImporter(path),
if (packageResolver != null) PackageImporter(packageResolver)
];
}

/// Creates a cache that contains no importers.
Expand Down
2 changes: 1 addition & 1 deletion lib/src/callable/async_built_in.dart
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ import '../value.dart';
import 'async.dart';

/// An [AsyncBuiltInCallable]'s callback.
typedef FutureOr<Value> _Callback(List<Value> arguments);
typedef _Callback = FutureOr<Value> Function(List<Value> arguments);

/// A callable defined in Dart code.
///
Expand Down
2 changes: 1 addition & 1 deletion lib/src/callable/built_in.dart
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ import '../callable.dart';
import '../value.dart';
import 'async_built_in.dart';

typedef Value _Callback(List<Value> arguments);
typedef _Callback = Value Function(List<Value> arguments);

/// A callable defined in Dart code.
///
Expand Down
2 changes: 1 addition & 1 deletion lib/src/compile.dart
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
// https://opensource.org/licenses/MIT.

// DO NOT EDIT. This file was generated from async_compile.dart.
// See tool/synchronize.dart for details.
// See tool/grind/synchronize.dart for details.
//
// Checksum: ea78ec4431055c1d222e52f4ea54a9659c4df11f
//
Expand Down
2 changes: 1 addition & 1 deletion lib/src/environment.dart
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
// https://opensource.org/licenses/MIT.

// DO NOT EDIT. This file was generated from async_environment.dart.
// See tool/synchronize.dart for details.
// See tool/grind/synchronize.dart for details.
//
// Checksum: a7e4f09ccb8a4997500abfe34e712b9c2ad212c6
//
Expand Down
23 changes: 12 additions & 11 deletions lib/src/executable/options.dart
Original file line number Diff line number Diff line change
Expand Up @@ -371,18 +371,19 @@ class ExecutableOptions {
/// Returns the sub-map of [sourcesToDestinations] for the given [source] and
/// [destination] directories.
Map<String, String> _listSourceDirectory(String source, String destination) {
var map = <String, String>{};
for (var path in listDir(source, recursive: true)) {
var basename = p.basename(path);
if (basename.startsWith("_")) continue;

var extension = p.extension(path);
if (extension != ".scss" && extension != ".sass") continue;
return {
for (var path in listDir(source, recursive: true))
if (_isEntrypoint(path))
path: p.join(destination,
p.setExtension(p.relative(path, from: source), '.css'))
};
}

map[path] = p.join(
destination, p.setExtension(p.relative(path, from: source), '.css'));
}
return map;
/// Returns whether [path] is a Sass entrypoint (that is, not a partial).
bool _isEntrypoint(String path) {
if (p.basename(path).startsWith("_")) return false;
var extension = p.extension(path);
return extension == ".scss" || extension == ".sass";
}

/// Whether to emit a source map file.
Expand Down
9 changes: 5 additions & 4 deletions lib/src/executable/watch.dart
Original file line number Diff line number Diff line change
Expand Up @@ -20,10 +20,11 @@ import 'options.dart';

/// Watches all the files in [graph] for changes and updates them as necessary.
Future watch(ExecutableOptions options, StylesheetGraph graph) async {
var directoriesToWatch = <String>[]
..addAll(options.sourceDirectoriesToDestinations.keys)
..addAll(options.sourcesToDestinations.keys.map(p.dirname))
..addAll(options.loadPaths);
var directoriesToWatch = [
...options.sourceDirectoriesToDestinations.keys,
...options.sourcesToDestinations.keys.map(p.dirname),
...options.loadPaths
];

var dirWatcher = MultiDirWatcher(poll: options.poll);
await Future.wait(directoriesToWatch.map((dir) {
Expand Down
12 changes: 4 additions & 8 deletions lib/src/extend/extender.dart
Original file line number Diff line number Diff line change
Expand Up @@ -96,11 +96,10 @@ class Extender {
throw SassScriptException("Can't extend complex selector $complex.");
}

var extensions = <SimpleSelector, Map<ComplexSelector, Extension>>{};
var compound = complex.components.first as CompoundSelector;
for (var simple in compound.components) {
extensions[simple] = extenders;
}
var extensions = {
for (var simple in compound.components) simple: extenders
};

var extender = Extender._mode(mode);
if (!selector.isInvisible) {
Expand Down Expand Up @@ -702,10 +701,7 @@ class Extender {
targetsUsed?.add(simple);
if (_mode == ExtendMode.replace) return extenders.values.toList();

var extenderList = List<Extension>(extenders.length + 1);
extenderList[0] = _extensionForSimple(simple);
extenderList.setRange(1, extenderList.length, extenders.values);
return extenderList;
return [_extensionForSimple(simple), ...extenders.values];
}

if (simple is PseudoSelector && simple.selector != null) {
Expand Down
Loading