Skip to content

Commit 0df3463

Browse files
committed
Compile asynchronous code to synchronous (#194)
See #9
1 parent 74400dc commit 0df3463

File tree

6 files changed

+291
-32
lines changed

6 files changed

+291
-32
lines changed

lib/src/environment.dart

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,11 @@
22
// MIT-style license that can be found in the LICENSE file or at
33
// https://opensource.org/licenses/MIT.
44

5+
// DO NOT EDIT. This file was generated from async_environment.dart.
6+
// See tool/synchronize.dart for details.
7+
//
8+
// Checksum: 97410abbd78c3bbc9899f3ac460cc0736218bfe3
9+
510
import 'ast/sass.dart';
611
import 'callable.dart';
712
import 'functions.dart';

lib/src/visitor/evaluate.dart

Lines changed: 38 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,11 @@
22
// MIT-style license that can be found in the LICENSE file or at
33
// https://opensource.org/licenses/MIT.
44

5+
// DO NOT EDIT. This file was generated from async_evaluate.dart.
6+
// See tool/synchronize.dart for details.
7+
//
8+
// Checksum: ef8fa3966d7580d8511d8d8430a8f65cd9cb9018
9+
510
import 'dart:math' as math;
611

712
import 'package:charcode/charcode.dart';
@@ -13,9 +18,9 @@ import 'package:tuple/tuple.dart';
1318
import '../ast/css.dart';
1419
import '../ast/sass.dart';
1520
import '../ast/selector.dart';
21+
import '../environment.dart';
1622
import '../callable.dart';
1723
import '../color_names.dart';
18-
import '../environment.dart';
1924
import '../exception.dart';
2025
import '../extend/extender.dart';
2126
import '../importer.dart';
@@ -29,7 +34,7 @@ import 'interface/statement.dart';
2934
import 'interface/expression.dart';
3035

3136
/// A function that takes a callback with no arguments.
32-
typedef _ScopeCallback(callback());
37+
typedef void _ScopeCallback(void callback());
3338

3439
/// The URL used in stack traces when no source URL is available.
3540
final _noSourceUrl = Uri.parse("-");
@@ -301,12 +306,12 @@ class _EvaluateVisitor
301306
}
302307

303308
Value visitAtRootRule(AtRootRule node) {
304-
var query = node.query == null
305-
? AtRootQuery.defaultQuery
306-
: _adjustParseError(
307-
node.query.span,
308-
() => new AtRootQuery.parse(
309-
_performInterpolation(node.query, warnForColor: true)));
309+
var query = AtRootQuery.defaultQuery;
310+
if (node.query != null) {
311+
var resolved = _performInterpolation(node.query, warnForColor: true);
312+
query = _adjustParseError(
313+
node.query.span, () => new AtRootQuery.parse(resolved));
314+
}
310315

311316
var parent = _parent;
312317
var included = <CssParentNode>[];
@@ -384,7 +389,7 @@ class _EvaluateVisitor
384389
/// [_parent] to [newParent].
385390
_ScopeCallback _scopeForAtRoot(CssParentNode newParent, AtRootQuery query,
386391
List<CssParentNode> included) {
387-
var scope = (callback()) {
392+
var scope = (void callback()) {
388393
// We can't use [_withParent] here because it'll add the node to the tree
389394
// in the wrong place.
390395
var oldParent = _parent;
@@ -623,11 +628,13 @@ class _EvaluateVisitor
623628
}
624629

625630
Value visitIfRule(IfRule node) {
626-
var clause = node.clauses
627-
.firstWhere((pair) => pair.item1.accept(this).isTruthy,
628-
orElse: () => null)
629-
?.item2 ??
630-
node.lastClause;
631+
var clause = node.lastClause;
632+
for (var pair in node.clauses) {
633+
if (pair.item1.accept(this).isTruthy) {
634+
clause = pair.item2;
635+
break;
636+
}
637+
}
631638
if (clause == null) return null;
632639

633640
return _environment.scope(
@@ -802,18 +809,16 @@ class _EvaluateVisitor
802809
throw _exception("Mixin doesn't accept a content block.", node.span);
803810
}
804811

805-
Value callback() {
806-
_environment.asMixin(() {
807-
for (var statement in mixin.declaration.children) {
808-
statement.accept(this);
809-
}
810-
});
811-
return null;
812-
}
813-
814812
var environment = node.children == null ? null : _environment.closure();
815813
_runUserDefinedCallable(node.arguments, mixin, node.span, () {
816-
_environment.withContent(node.children, environment, callback);
814+
_environment.withContent(node.children, environment, () {
815+
_environment.asMixin(() {
816+
for (var statement in mixin.declaration.children) {
817+
statement.accept(this);
818+
}
819+
});
820+
return null;
821+
});
817822
});
818823

819824
return null;
@@ -876,11 +881,13 @@ class _EvaluateVisitor
876881

877882
/// Evaluates [interpolation] and parses the result as a list of media
878883
/// queries.
879-
List<CssMediaQuery> _visitMediaQueries(Interpolation interpolation) =>
880-
_adjustParseError(
881-
interpolation.span,
882-
() => CssMediaQuery.parseList(
883-
_performInterpolation(interpolation, warnForColor: true)));
884+
List<CssMediaQuery> _visitMediaQueries(Interpolation interpolation) {
885+
var resolved = _performInterpolation(interpolation, warnForColor: true);
886+
887+
// TODO(nweiz): Remove this type argument when sdk#31398 is fixed.
888+
return _adjustParseError<List<CssMediaQuery>>(
889+
interpolation.span, () => CssMediaQuery.parseList(resolved));
890+
}
884891

885892
/// Returns a list of queries that selects for platforms that match both
886893
/// [queries1] and [queries2].
@@ -1176,7 +1183,7 @@ class _EvaluateVisitor
11761183
SassColor visitColorExpression(ColorExpression node) => node.value;
11771184

11781185
SassList visitListExpression(ListExpression node) => new SassList(
1179-
node.contents.map((expression) => expression.accept(this)),
1186+
node.contents.map((Expression expression) => expression.accept(this)),
11801187
node.separator,
11811188
brackets: node.hasBrackets);
11821189

@@ -1375,7 +1382,7 @@ class _EvaluateVisitor
13751382
Tuple3<List<Value>, Map<String, Value>, ListSeparator> _evaluateArguments(
13761383
ArgumentInvocation arguments, FileSpan span) {
13771384
var positional = arguments.positional
1378-
.map((expression) => expression.accept(this))
1385+
.map((Expression expression) => expression.accept(this))
13791386
.toList();
13801387
var named = normalizedMapMap<String, Expression, Value>(arguments.named,
13811388
value: (_, expression) => expression.accept(this));

pubspec.yaml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,8 @@ dependencies:
2525

2626
dev_dependencies:
2727
archive: "^1.0.0"
28+
analyzer: "^0.30.0"
29+
crypto: ">=0.9.2 <3.0.0"
2830
dart_style: "^1.0.0"
2931
grinder: "^0.8.0"
3032
http: "^0.11.0"

test/synchronize_test.dart

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
// Copyright 2017 Google Inc. Use of this source code is governed by an
2+
// MIT-style license that can be found in the LICENSE file or at
3+
// https://opensource.org/licenses/MIT.
4+
5+
import 'dart:convert';
6+
import 'dart:io';
7+
8+
import 'package:crypto/crypto.dart';
9+
import 'package:test/test.dart';
10+
11+
void main() {
12+
test("synchronized files are up-to-date", () {
13+
({
14+
'lib/src/visitor/async_evaluate.dart': 'lib/src/visitor/evaluate.dart',
15+
'lib/src/async_environment.dart': 'lib/src/environment.dart'
16+
}).forEach((sourcePath, targetPath) {
17+
var source = new File(sourcePath).readAsStringSync();
18+
var target = new File(targetPath).readAsStringSync();
19+
20+
var hash = sha1.convert(UTF8.encode(source));
21+
if (!target.contains("Checksum: $hash")) {
22+
fail("$targetPath is out-of-date.\n"
23+
"Run pub run grinder to update it.");
24+
}
25+
});
26+
});
27+
}

tool/grind.dart

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,10 @@ import 'package:yaml/yaml.dart';
1717

1818
import 'package:sass/src/util/path.dart';
1919

20+
import 'synchronize.dart';
21+
22+
export 'synchronize.dart';
23+
2024
/// The version of Dart Sass.
2125
final String _version =
2226
loadYaml(new File('pubspec.yaml').readAsStringSync())['version'] as String;
@@ -33,7 +37,13 @@ final _sdkDir = p.dirname(p.dirname(Platform.resolvedExecutable));
3337

3438
main(List<String> args) => grind(args);
3539

36-
@DefaultTask('Run the Dart formatter.')
40+
@DefaultTask('Compile async code and reformat.')
41+
all() {
42+
format();
43+
synchronize();
44+
}
45+
46+
@Task('Run the Dart formatter.')
3747
format() {
3848
Pub.run('dart_style',
3949
script: 'format',

0 commit comments

Comments
 (0)