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

Enable strict null checks #1283

Merged
merged 19 commits into from Apr 15, 2021
Merged
Show file tree
Hide file tree
Changes from 4 commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
38 changes: 15 additions & 23 deletions lib/sass.dart
Expand Up @@ -5,6 +5,7 @@
/// We strongly recommend importing this library with the prefix `sass`.
library sass;

import 'package:package_config/package_config_types.dart';
import 'package:source_maps/source_maps.dart';

import 'src/async_import_cache.dart';
Expand All @@ -14,7 +15,6 @@ import 'src/exception.dart';
import 'src/import_cache.dart';
import 'src/importer.dart';
import 'src/logger.dart';
import 'src/sync_package_resolver.dart';
import 'src/syntax.dart';
import 'src/visitor/serialize.dart';

Expand Down Expand Up @@ -48,11 +48,11 @@ export 'src/warn.dart' show warn;
/// * Each load path specified in the `SASS_PATH` environment variable, which
/// should be semicolon-separated on Windows and colon-separated elsewhere.
///
/// * `package:` resolution using [packageResolver], which is a
/// [`SyncPackageResolver`][] from the `package_resolver` package. Note that
/// * `package:` resolution using [packageConfig], which is a
/// [`PackageConfig`][] from the `package_resolver` package. Note that
/// this is a shorthand for adding a [PackageImporter] to [importers].
///
/// [`SyncPackageResolver`]: https://www.dartdocs.org/documentation/package_resolver/latest/package_resolver/SyncPackageResolver-class.html
/// [`PackageConfig`]: https://pub.dev/documentation/package_config/latest/package_config.package_config/PackageConfig-class.html
///
/// Dart functions that can be called from Sass may be passed using [functions].
/// Each [Callable] defines a top-level function that will be invoked when the
Expand Down Expand Up @@ -90,7 +90,7 @@ String compile(String path,
Logger logger,
Iterable<Importer> importers,
Iterable<String> loadPaths,
SyncPackageResolver packageResolver,
PackageConfig packageConfig,
Iterable<Callable> functions,
OutputStyle style,
void sourceMap(SingleMapping map),
Expand All @@ -99,9 +99,7 @@ String compile(String path,
var result = c.compile(path,
logger: logger,
importCache: ImportCache(importers,
logger: logger,
loadPaths: loadPaths,
packageResolver: packageResolver),
logger: logger, loadPaths: loadPaths, packageConfig: packageConfig),
functions: functions,
style: style,
sourceMap: sourceMap != null,
Expand Down Expand Up @@ -132,11 +130,11 @@ String compile(String path,
/// * Each load path specified in the `SASS_PATH` environment variable, which
/// should be semicolon-separated on Windows and colon-separated elsewhere.
///
/// * `package:` resolution using [packageResolver], which is a
/// [`SyncPackageResolver`][] from the `package_resolver` package. Note that
/// * `package:` resolution using [packageConfig], which is a
/// [`PackageConfig`][] from the `package_resolver` package. Note that
/// this is a shorthand for adding a [PackageImporter] to [importers].
///
/// [`SyncPackageResolver`]: https://www.dartdocs.org/documentation/package_resolver/latest/package_resolver/SyncPackageResolver-class.html
/// [`PackageConfig`]: https://pub.dev/documentation/package_config/latest/package_config.package_config/PackageConfig-class.html
///
/// Dart functions that can be called from Sass may be passed using [functions].
/// Each [Callable] defines a top-level function that will be invoked when the
Expand Down Expand Up @@ -178,7 +176,7 @@ String compileString(String source,
bool color = false,
Logger logger,
Iterable<Importer> importers,
SyncPackageResolver packageResolver,
PackageConfig packageConfig,
Iterable<String> loadPaths,
Iterable<Callable> functions,
OutputStyle style,
Expand All @@ -192,9 +190,7 @@ String compileString(String source,
syntax: syntax ?? (indented ? Syntax.sass : Syntax.scss),
logger: logger,
importCache: ImportCache(importers,
logger: logger,
packageResolver: packageResolver,
loadPaths: loadPaths),
logger: logger, packageConfig: packageConfig, loadPaths: loadPaths),
functions: functions,
style: style,
importer: importer,
Expand All @@ -214,7 +210,7 @@ Future<String> compileAsync(String path,
{bool color = false,
Logger logger,
Iterable<AsyncImporter> importers,
SyncPackageResolver packageResolver,
PackageConfig packageConfig,
Iterable<String> loadPaths,
Iterable<AsyncCallable> functions,
OutputStyle style,
Expand All @@ -223,9 +219,7 @@ Future<String> compileAsync(String path,
var result = await c.compileAsync(path,
logger: logger,
importCache: AsyncImportCache(importers,
logger: logger,
loadPaths: loadPaths,
packageResolver: packageResolver),
logger: logger, loadPaths: loadPaths, packageConfig: packageConfig),
functions: functions,
style: style,
sourceMap: sourceMap != null);
Expand All @@ -243,7 +237,7 @@ Future<String> compileStringAsync(String source,
bool color = false,
Logger logger,
Iterable<AsyncImporter> importers,
SyncPackageResolver packageResolver,
PackageConfig packageConfig,
Iterable<String> loadPaths,
Iterable<AsyncCallable> functions,
OutputStyle style,
Expand All @@ -257,9 +251,7 @@ Future<String> compileStringAsync(String source,
syntax: syntax ?? (indented ? Syntax.sass : Syntax.scss),
logger: logger,
importCache: AsyncImportCache(importers,
logger: logger,
packageResolver: packageResolver,
loadPaths: loadPaths),
logger: logger, packageConfig: packageConfig, loadPaths: loadPaths),
functions: functions,
style: style,
importer: importer,
Expand Down
2 changes: 1 addition & 1 deletion lib/src/ast/sass/argument_declaration.dart
Expand Up @@ -113,7 +113,7 @@ class ArgumentDeclaration implements SassNode {
"Only ${arguments.length} "
"${names.isEmpty ? '' : 'positional '}"
"${pluralize('argument', arguments.length)} allowed, but "
"${positional} ${pluralize('was', positional, plural: 'were')} "
"$positional ${pluralize('was', positional, plural: 'were')} "
"passed.",
"invocation",
{spanWithName: "declaration"});
Expand Down
2 changes: 1 addition & 1 deletion lib/src/ast/sass/expression/number.dart
Expand Up @@ -22,5 +22,5 @@ class NumberExpression implements Expression {
T accept<T>(ExpressionVisitor<T> visitor) =>
visitor.visitNumberExpression(this);

String toString() => "${value}${unit ?? ''}";
String toString() => "$value${unit ?? ''}";
}
2 changes: 1 addition & 1 deletion lib/src/ast/sass/statement/declaration.dart
Expand Up @@ -36,7 +36,7 @@ class Declaration extends ParentStatement {
if (isCustomProperty && value is! StringExpression) {
throw ArgumentError(
'Declarations whose names begin with "--" must have StringExpression '
'values (was `${value}` of type ${value.runtimeType}).');
'values (was `$value` of type ${value.runtimeType}).');
}
}

Expand Down
57 changes: 32 additions & 25 deletions lib/src/ast/sass/statement/if_rule.dart
Expand Up @@ -27,55 +27,62 @@ class IfRule implements Statement {
/// The final, unconditional `@else` clause.
///
/// This is `null` if there is no unconditional `@else`.
final IfClause lastClause;
final ElseClause lastClause;

final FileSpan span;

IfRule(Iterable<IfClause> clauses, this.span, {this.lastClause})
: clauses = List.unmodifiable(clauses) {
assert(clauses.every((clause) => clause.expression != null));
assert(lastClause?.expression == null);
}
: clauses = List.unmodifiable(clauses);

T accept<T>(StatementVisitor<T> visitor) => visitor.visitIfRule(this);

String toString() {
var first = true;
return clauses.map((clause) {
var name = first ? 'if' : 'else';
first = false;
return '@$name ${clause.expression} {${clause.children.join(" ")}}';
}).join(' ');
var result = clauses
.map((clause) =>
"@${first ? 'if' : 'else if'} {${clause.children.join(' ')}}")
.join(' ');

var lastClause = this.lastClause;
if (lastClause != null) result += " $lastClause";
return result;
}
}

/// A single clause in an `@if` rule.
class IfClause {
/// The expression to evaluate to determine whether to run this rule, or
/// `null` if this is the final unconditional `@else` clause.
final Expression expression;

/// The superclass of `@if` and `@else` clauses.
abstract class IfRuleClause {
/// The statements to evaluate if this clause matches.
final List<Statement> children;

/// Whether any of [children] is a variable, function, or mixin declaration.
final bool hasDeclarations;

IfClause(Expression expression, Iterable<Statement> children)
: this._(expression, List.unmodifiable(children));

IfClause.last(Iterable<Statement> children)
: this._(null, List.unmodifiable(children));
IfRuleClause(Iterable<Statement /*!*/ > children)
: this._(List.unmodifiable(children));

IfClause._(this.expression, this.children)
IfRuleClause._(this.children)
: hasDeclarations = children.any((child) =>
child is VariableDeclaration ||
child is FunctionRule ||
child is MixinRule ||
(child is ImportRule &&
child.imports.any((import) => import is DynamicImport)));
}

/// An `@if` or `@else if` clause in an `@if` rule.
class IfClause extends IfRuleClause {
/// The expression to evaluate to determine whether to run this rule.
final Expression expression;

IfClause(this.expression, Iterable<Statement /*!*/ > children)
: super(children);

String toString() => "@if $expression {${children.join(' ')}}";
}

/// An `@else` clause in an `@if` rule.
class ElseClause extends IfRuleClause {
ElseClause(Iterable<Statement /*!*/ > children) : super(children);

String toString() =>
(expression == null ? "@else" : "@if $expression") +
" {${children.join(' ')}}";
String toString() => "@else {${children.join(' ')}}";
}
2 changes: 1 addition & 1 deletion lib/src/ast/sass/supports_condition/operation.dart
Expand Up @@ -31,7 +31,7 @@ class SupportsOperation implements SupportsCondition {
}

String toString() =>
"${_parenthesize(left)} ${operator} ${_parenthesize(right)}";
"${_parenthesize(left)} $operator ${_parenthesize(right)}";

String _parenthesize(SupportsCondition condition) =>
condition is SupportsNegation ||
Expand Down
2 changes: 0 additions & 2 deletions lib/src/async_compile.dart
Expand Up @@ -15,7 +15,6 @@ import 'importer.dart';
import 'importer/node.dart';
import 'io.dart';
import 'logger.dart';
import 'sync_package_resolver.dart';
import 'syntax.dart';
import 'utils.dart';
import 'visitor/async_evaluate.dart';
Expand Down Expand Up @@ -77,7 +76,6 @@ Future<CompileResult> compileStringAsync(String source,
NodeImporter nodeImporter,
Iterable<AsyncImporter> importers,
Iterable<String> loadPaths,
SyncPackageResolver packageResolver,
AsyncImporter importer,
Iterable<AsyncCallable> functions,
OutputStyle style,
Expand Down
22 changes: 10 additions & 12 deletions lib/src/async_import_cache.dart
Expand Up @@ -3,6 +3,7 @@
// https://opensource.org/licenses/MIT.

import 'package:collection/collection.dart';
import 'package:package_config/package_config_types.dart';
import 'package:path/path.dart' as p;
import 'package:tuple/tuple.dart';

Expand All @@ -11,8 +12,7 @@ import 'importer.dart';
import 'importer/utils.dart';
import 'io.dart';
import 'logger.dart';
import 'sync_package_resolver.dart';
import 'utils.dart'; // ignore: unused_import
import 'utils.dart';

/// An in-memory cache of parsed stylesheets that have been imported by Sass.
class AsyncImportCache {
Expand Down Expand Up @@ -52,16 +52,14 @@ class AsyncImportCache {
/// * Each load path specified in the `SASS_PATH` environment variable, which
/// should be semicolon-separated on Windows and colon-separated elsewhere.
///
/// * `package:` resolution using [packageResolver], which is a
/// [`SyncPackageResolver`][] from the `package_resolver` package. Note that
/// * `package:` resolution using [packageConfig], which is a
/// [`PackageConfig`][] from the `package_config` package. Note that
/// this is a shorthand for adding a [PackageImporter] to [importers].
///
/// [`SyncPackageResolver`]: https://www.dartdocs.org/documentation/package_resolver/latest/package_resolver/SyncPackageResolver-class.html
/// [`PackageConfig`]: https://pub.dev/documentation/package_config/latest/package_config.package_config/PackageConfig-class.html
AsyncImportCache(Iterable<AsyncImporter> importers,
{Iterable<String> loadPaths,
SyncPackageResolver packageResolver,
Logger logger})
: _importers = _toImporters(importers, loadPaths, packageResolver),
{Iterable<String> loadPaths, PackageConfig packageConfig, Logger logger})
: _importers = _toImporters(importers, loadPaths, packageConfig),
_logger = logger ?? const Logger.stderr(),
_canonicalizeCache = {},
_importCache = {},
Expand All @@ -75,10 +73,10 @@ class AsyncImportCache {
_importCache = {},
_resultsCache = {};

/// Converts the user's [importers], [loadPaths], and [packageResolver]
/// Converts the user's [importers], [loadPaths], and [packageConfig]
/// options into a single list of importers.
static List<AsyncImporter> _toImporters(Iterable<AsyncImporter> importers,
Iterable<String> loadPaths, SyncPackageResolver packageResolver) {
Iterable<String> loadPaths, PackageConfig packageConfig) {
var sassPath = getEnvironmentVariable('SASS_PATH');
return [
...?importers,
Expand All @@ -87,7 +85,7 @@ class AsyncImportCache {
if (sassPath != null)
for (var path in sassPath.split(isWindows ? ';' : ':'))
FilesystemImporter(path),
if (packageResolver != null) PackageImporter(packageResolver)
if (packageConfig != null) PackageImporter(packageConfig)
];
}

Expand Down
4 changes: 1 addition & 3 deletions lib/src/compile.dart
Expand Up @@ -5,7 +5,7 @@
// DO NOT EDIT. This file was generated from async_compile.dart.
// See tool/grind/synchronize.dart for details.
//
// Checksum: b2cd6037efa37e300daa45ebed20cb4b61526161
// Checksum: ef27d750f1d5305373fe9e712cf99697a21e0689
//
// ignore_for_file: unused_import

Expand All @@ -25,7 +25,6 @@ import 'importer.dart';
import 'importer/node.dart';
import 'io.dart';
import 'logger.dart';
import 'sync_package_resolver.dart';
import 'syntax.dart';
import 'utils.dart';
import 'visitor/evaluate.dart';
Expand Down Expand Up @@ -87,7 +86,6 @@ CompileResult compileString(String source,
NodeImporter nodeImporter,
Iterable<Importer> importers,
Iterable<String> loadPaths,
SyncPackageResolver packageResolver,
Importer importer,
Iterable<Callable> functions,
OutputStyle style,
Expand Down