Skip to content

Commit

Permalink
Fix broken tests
Browse files Browse the repository at this point in the history
  • Loading branch information
Awjin authored and nex3 committed Apr 14, 2021
1 parent e0129ce commit aae8e6a
Show file tree
Hide file tree
Showing 28 changed files with 169 additions and 104 deletions.
2 changes: 1 addition & 1 deletion bin/sass.dart
Expand Up @@ -121,7 +121,7 @@ Future<void> main(List<String> args) async {

/// Loads and returns the current version of Sass.
Future<String> _loadVersion() async {
if (bool.hasEnvironment('version')) {
if (const bool.hasEnvironment('version')) {
var version = const String.fromEnvironment('version');
if (const bool.fromEnvironment('node')) {
version += " compiled with dart2js "
Expand Down
2 changes: 1 addition & 1 deletion lib/src/ast/css/modifiable/declaration.dart
Expand Up @@ -25,7 +25,7 @@ class ModifiableCssDeclaration extends ModifiableCssNode
ModifiableCssDeclaration(this.name, this.value, this.span,
{required bool parsedAsCustomProperty, FileSpan? valueSpanForMap})
: parsedAsCustomProperty = parsedAsCustomProperty,
valueSpanForMap = valueSpanForMap ?? span {
valueSpanForMap = valueSpanForMap ?? value.span {
if (parsedAsCustomProperty) {
if (!isCustomProperty) {
throw ArgumentError(
Expand Down
2 changes: 1 addition & 1 deletion lib/src/ast/selector/list.dart
Expand Up @@ -150,7 +150,7 @@ class SelectorList extends Selector {
component is CompoundSelector &&
component.components.any((simple) {
if (simple is ParentSelector) return true;
if (simple is! PseudoSelector) return true;
if (simple is! PseudoSelector) return false;
var selector = simple.selector;
return selector != null && selector._containsParentSelector;
}));
Expand Down
7 changes: 7 additions & 0 deletions lib/src/configuration.dart
Expand Up @@ -68,6 +68,13 @@ class Configuration {
/// Returns a copy of [this] with the given [values] map.
Configuration _withValues(Map<String, ConfiguredValue> values) =>
Configuration.implicit(values);

String toString() =>
"(" +
values.entries
.map((entry) => "\$${entry.key}: ${entry.value}")
.join(", ") +
")";
}

/// A [Configuratoin] that was created with an explicit `with` clause of a
Expand Down
5 changes: 3 additions & 2 deletions lib/src/exception.dart
Expand Up @@ -23,8 +23,9 @@ class SassException extends SourceSpanException {
SassException(String message, FileSpan span) : super(message, span);

String toString({Object? color}) {
var buffer = StringBuffer("Error: $message");
span.highlight(color: color).andThen(buffer.write);
var buffer = StringBuffer()
..writeln("Error: $message")
..write(span.highlight(color: color));

for (var frame in trace.toString().split("\n")) {
if (frame.isEmpty) continue;
Expand Down
4 changes: 2 additions & 2 deletions lib/src/executable/options.dart
Expand Up @@ -150,7 +150,7 @@ class ExecutableOptions {
///
/// This may be `null`, indicating that this should be determined by each
/// stylesheet's extension.
bool get indented => _ifParsed('indented') as bool;
bool? get indented => _ifParsed('indented') as bool?;

/// Whether to use ANSI terminal colors.
bool get color => _options.wasParsed('color')
Expand Down Expand Up @@ -357,7 +357,7 @@ class ExecutableOptions {
// A colon 2 characters after the separator may also be a Windows
// drive letter.
if (nextColon == i + 2 && _isWindowsPath(argument, i + 1)) {
nextColon = argument.indexOf(':', nextColon);
nextColon = argument.indexOf(':', nextColon + 1);
}
if (nextColon != -1) _fail('"$argument" may only contain one ":".');

Expand Down
8 changes: 7 additions & 1 deletion lib/src/io/node.dart
Expand Up @@ -190,7 +190,13 @@ T _systemErrorToFileSystemException<T>(T callback()) {

final stderr = Stderr(process.stderr);

bool get hasTerminal => process.stdout.isTTY;
/// We can't use [process.stdout.isTTY] from `node_interop` because of
/// pulyaevskiy/node-interop#93: it declares `isTTY` as always non-nullably
/// available, but in practice it's undefined if stdout isn't a TTY.
@JS('process.stdout.isTTY')
external bool? get isTTY;

bool get hasTerminal => isTTY == true;

bool get isWindows => process.platform == 'win32';

Expand Down
7 changes: 4 additions & 3 deletions lib/src/node.dart
Expand Up @@ -235,7 +235,7 @@ List<AsyncCallable> _parseFunctions(RenderOptions options, DateTime start,
} else {
result.add(AsyncBuiltInCallable.parsed(tuple.item1, tuple.item2,
(arguments) async {
var completer = Completer<Object>();
var completer = Completer<Object?>();
var jsArguments = [
...arguments.map(wrapValue),
allowInterop(([Object? result]) => completer.complete(result))
Expand All @@ -261,8 +261,9 @@ NodeImporter _parseImporter(RenderOptions options, DateTime start) {
importers = [options.importer as JSFunction];
}

late RenderContext context;
if (importers.isNotEmpty) context = _contextWithOptions(options, start);
var context = importers.isNotEmpty
? _contextWithOptions(options, start)
: const Object();

var fiber = options.fiber;
if (fiber != null) {
Expand Down
4 changes: 2 additions & 2 deletions lib/src/node/function.dart
Expand Up @@ -10,7 +10,7 @@ class JSFunction implements Function {

// Note that this just invokes the function with the given arguments, rather
// than calling `Function.prototype.call()`. See sdk#31271.
external Object call([Object? arg1, Object? arg2, Object? arg3]);
external Object? call([Object? arg1, Object? arg2, Object? arg3]);

external Object apply(Object thisArg, [List<Object>? args]);
external Object? apply(Object thisArg, [List<Object>? args]);
}
5 changes: 3 additions & 2 deletions lib/src/node/value/color.dart
Expand Up @@ -22,7 +22,7 @@ Object newNodeSassColor(SassColor value) =>

/// The JS constructor for the `sass.types.Color` class.
final Function colorConstructor = createClass('SassColor',
(_NodeSassColor thisArg, num redOrArgb,
(_NodeSassColor thisArg, num? redOrArgb,
[num? green, num? blue, num? alpha, SassColor? dartValue]) {
if (dartValue != null) {
thisArg.dartValue = dartValue;
Expand All @@ -43,7 +43,8 @@ final Function colorConstructor = createClass('SassColor',
green = (argb >> 8) % 0x100;
blue = argb % 0x100;
} else {
red = redOrArgb;
// Either [dartValue] or [redOrArgb] must be passed.
red = redOrArgb!;
}

thisArg.dartValue = SassColor.rgb(
Expand Down
5 changes: 3 additions & 2 deletions lib/src/node/value/list.dart
Expand Up @@ -22,10 +22,11 @@ Object newNodeSassList(SassList value) =>

/// The JS constructor for the `sass.types.List` class.
final Function listConstructor = createClass('SassList',
(_NodeSassList thisArg, int length,
(_NodeSassList thisArg, int? length,
[bool? commaSeparator, SassList? dartValue]) {
thisArg.dartValue = dartValue ??
SassList(Iterable.generate(length, (_) => sassNull),
// Either [dartValue] or [length] must be passed.
SassList(Iterable.generate(length!, (_) => sassNull),
(commaSeparator ?? true) ? ListSeparator.comma : ListSeparator.space);
}, {
'getValue': (_NodeSassList thisArg, int index) =>
Expand Down
6 changes: 4 additions & 2 deletions lib/src/node/value/map.dart
Expand Up @@ -22,9 +22,11 @@ Object newNodeSassMap(SassMap value) =>

/// The JS constructor for the `sass.types.Map` class.
final Function mapConstructor = createClass('SassMap',
(_NodeSassMap thisArg, int length, [SassMap? dartValue]) {
(_NodeSassMap thisArg, int? length, [SassMap? dartValue]) {
thisArg.dartValue = dartValue ??
SassMap(Map.fromIterables(Iterable.generate(length, (i) => SassNumber(i)),
SassMap(Map.fromIterables(
// Either [dartValue] or [length] must be passed.
Iterable.generate(length!, (i) => SassNumber(i)),
Iterable.generate(length, (_) => sassNull)));
}, {
'getKey': (_NodeSassMap thisArg, int index) =>
Expand Down
5 changes: 3 additions & 2 deletions lib/src/node/value/number.dart
Expand Up @@ -21,9 +21,10 @@ Object newNodeSassNumber(SassNumber value) =>

/// The JS constructor for the `sass.types.Number` class.
final Function numberConstructor = createClass('SassNumber',
(_NodeSassNumber thisArg, num value,
(_NodeSassNumber thisArg, num? value,
[String? unit, SassNumber? dartValue]) {
thisArg.dartValue = dartValue ?? _parseNumber(value, unit);
// Either [dartValue] or [value] must be passed.
thisArg.dartValue = dartValue ?? _parseNumber(value!, unit);
}, {
'getValue': (_NodeSassNumber thisArg) => thisArg.dartValue.value,
'setValue': (_NodeSassNumber thisArg, num value) {
Expand Down
5 changes: 3 additions & 2 deletions lib/src/node/value/string.dart
Expand Up @@ -21,8 +21,9 @@ Object newNodeSassString(SassString value) =>

/// The JS constructor for the `sass.types.String` class.
final Function stringConstructor = createClass('SassString',
(_NodeSassString thisArg, String value, [SassString? dartValue]) {
thisArg.dartValue = dartValue ?? SassString(value, quotes: false);
(_NodeSassString thisArg, String? value, [SassString? dartValue]) {
// Either [dartValue] or [value] must be passed.
thisArg.dartValue = dartValue ?? SassString(value!, quotes: false);
}, {
'getValue': (_NodeSassString thisArg) => thisArg.dartValue.text,
'setValue': (_NodeSassString thisArg, String value) {
Expand Down
5 changes: 3 additions & 2 deletions lib/src/parse/stylesheet.dart
Expand Up @@ -95,7 +95,7 @@ abstract class StylesheetParser extends Parser {
return null;
}

_statement(root: true);
return _statement(root: true);
});
scanner.expectDone();

Expand Down Expand Up @@ -2055,7 +2055,8 @@ relase. For details, see http://bit.ly/moz-document.
var singleExpression = singleExpression_;
if (singleExpression != null) commaExpressions.add(singleExpression);
return ListExpression(commaExpressions, ListSeparator.comma,
brackets: bracketList, span: scanner.spanFrom(beforeBracket!));
brackets: bracketList,
span: scanner.spanFrom(beforeBracket ?? start));
} else if (bracketList && spaceExpressions != null) {
resolveOperations();
return ListExpression(
Expand Down
12 changes: 2 additions & 10 deletions lib/src/value/number.dart
Expand Up @@ -533,11 +533,7 @@ abstract class SassNumber extends Value implements ext.SassNumber {
if (factor == null) return false;
value /= factor;
return true;
},
orElse: () {
newNumerators.add(numerator);
return null;
} as String Function()?);
}, orElse: () => newNumerators.add(numerator));
}

var mutableDenominatorUnits = denominatorUnits.toList();
Expand All @@ -547,11 +543,7 @@ abstract class SassNumber extends Value implements ext.SassNumber {
if (factor == null) return false;
value /= factor;
return true;
},
orElse: () {
newNumerators.add(numerator);
return null;
} as String Function()?);
}, orElse: () => newNumerators.add(numerator));
}

return SassNumber.withUnits(value,
Expand Down
66 changes: 45 additions & 21 deletions lib/src/visitor/async_evaluate.dart
Expand Up @@ -164,7 +164,10 @@ class _EvaluateVisitor
List<CssMediaQuery>? _mediaQueries;

/// The current parent node in the output CSS tree.
late ModifiableCssParentNode _parent;
ModifiableCssParentNode get _parent => _assertInModule(__parent, "__parent");
set _parent(ModifiableCssParentNode value) => __parent = value;

ModifiableCssParentNode? __parent;

/// The name of the current declaration parent.
String? _declarationName;
Expand Down Expand Up @@ -242,14 +245,20 @@ class _EvaluateVisitor
AsyncImporter? _importer;

/// The stylesheet that's currently being evaluated.
late Stylesheet _stylesheet;
Stylesheet get _stylesheet => _assertInModule(__stylesheet, "_stylesheet");
set _stylesheet(Stylesheet value) => __stylesheet = value;
Stylesheet? __stylesheet;

/// The root stylesheet node.
late ModifiableCssStylesheet _root;
ModifiableCssStylesheet get _root => _assertInModule(__root, "_root");
set _root(ModifiableCssStylesheet value) => __root = value;
ModifiableCssStylesheet? __root;

/// The first index in [_root.children] after the initial block of CSS
/// imports.
late int _endOfImports;
int get _endOfImports => _assertInModule(__endOfImports, "_endOfImports");
set _endOfImports(int value) => __endOfImports = value;
int? __endOfImports;

/// Plain-CSS imports that didn't appear in the initial block of CSS imports.
///
Expand All @@ -258,11 +267,14 @@ class _EvaluateVisitor
///
/// This is `null` unless there are any out-of-order imports in the current
/// stylesheet.
late List<ModifiableCssImport>? _outOfOrderImports;
List<ModifiableCssImport>? _outOfOrderImports;

/// The extension store that tracks extensions and style rules for the current
/// module.
late ExtensionStore _extensionStore;
ExtensionStore get _extensionStore =>
_assertInModule(__extensionStore, "_extensionStore");
set _extensionStore(ExtensionStore value) => __extensionStore = value;
ExtensionStore? __extensionStore;

/// The configuration for the current module.
///
Expand Down Expand Up @@ -513,20 +525,31 @@ class _EvaluateVisitor
callback);
}

/// Asserts that [value] is not `null` and returns it.
///
/// This is used for fields that are set whenever the evaluator is evaluating
/// a module, which is to say essentially all the time (unless running via
/// [runExpression] or [runStatement]).
T _assertInModule<T>(T? value, String name) {
if (value != null) return value;
throw StateError("Can't access $name outside of a module.");
}

/// Runs [callback] with [importer] as [_importer] and a fake [_stylesheet]
/// with [nodeWithSpan]'s source span.
Future<T> _withFakeStylesheet<T>(AsyncImporter? importer,
AstNode nodeWithSpan, FutureOr<T> callback()) async {
var oldImporter = _importer;
_importer = importer;
var oldStylesheet = _stylesheet;

assert(__stylesheet == null);
_stylesheet = Stylesheet(const [], nodeWithSpan.span);

try {
return await callback();
} finally {
_importer = oldImporter;
_stylesheet = oldStylesheet;
__stylesheet = null;
}
}

Expand Down Expand Up @@ -659,12 +682,12 @@ class _EvaluateVisitor
var extensionStore = ExtensionStore();
await _withEnvironment(environment, () async {
var oldImporter = _importer;
var oldStylesheet = _stylesheet;
var oldRoot = _root;
var oldParent = _parent;
var oldEndOfImports = _endOfImports;
var oldStylesheet = __stylesheet;
var oldRoot = __root;
var oldParent = __parent;
var oldEndOfImports = __endOfImports;
var oldOutOfOrderImports = _outOfOrderImports;
var oldExtensionStore = _extensionStore;
var oldExtensionStore = __extensionStore;
var oldStyleRule = _styleRule;
var oldMediaQueries = _mediaQueries;
var oldDeclarationName = _declarationName;
Expand All @@ -674,7 +697,7 @@ class _EvaluateVisitor
var oldConfiguration = _configuration;
_importer = importer;
_stylesheet = stylesheet;
var root = _root = ModifiableCssStylesheet(stylesheet.span);
var root = __root = ModifiableCssStylesheet(stylesheet.span);
_parent = root;
_endOfImports = 0;
_outOfOrderImports = null;
Expand All @@ -693,12 +716,12 @@ class _EvaluateVisitor
: CssStylesheet(_addOutOfOrderImports(), stylesheet.span);

_importer = oldImporter;
_stylesheet = oldStylesheet;
_root = oldRoot;
_parent = oldParent;
_endOfImports = oldEndOfImports;
__stylesheet = oldStylesheet;
__root = oldRoot;
__parent = oldParent;
__endOfImports = oldEndOfImports;
_outOfOrderImports = oldOutOfOrderImports;
_extensionStore = oldExtensionStore;
__extensionStore = oldExtensionStore;
_styleRuleIgnoringAtRoot = oldStyleRule;
_mediaQueries = oldMediaQueries;
_declarationName = oldDeclarationName;
Expand Down Expand Up @@ -1084,7 +1107,7 @@ class _EvaluateVisitor
_parent.addChild(ModifiableCssDeclaration(name, cssValue, node.span,
parsedAsCustomProperty: node.isCustomProperty,
valueSpanForMap:
_sourceMap ? null : node.value.andThen(_expressionNode)?.span));
_sourceMap ? node.value.andThen(_expressionNode)?.span : null));
} else if (name.value.startsWith('--') && cssValue != null) {
throw _exception(
"Custom property values may not be empty.", cssValue.span);
Expand Down Expand Up @@ -1360,6 +1383,7 @@ class _EvaluateVisitor
// By definition, implicit configurations are allowed to only use a subset
// of their values.
if (configuration is! ExplicitConfiguration) return;
if (configuration.isEmpty) return;

var entry = configuration.values.entries.first;
throw _exception(
Expand Down Expand Up @@ -3084,7 +3108,7 @@ class _EvaluateVisitor
try {
return await callback();
} on SassRuntimeException catch (error) {
if (error.span.text.startsWith("@error")) rethrow;
if (!error.span.text.startsWith("@error")) rethrow;
throw SassRuntimeException(
error.message, nodeWithSpan.span, _stackTrace());
}
Expand Down

0 comments on commit aae8e6a

Please sign in to comment.