Skip to content

Commit

Permalink
Merge pull request #1283 from sass/nnbd
Browse files Browse the repository at this point in the history
Enable strict null checks
  • Loading branch information
nex3 committed Apr 15, 2021
2 parents 3d39f22 + c2e02a5 commit f681906
Show file tree
Hide file tree
Showing 219 changed files with 4,482 additions and 4,050 deletions.
28 changes: 18 additions & 10 deletions bin/sass.dart
Expand Up @@ -24,7 +24,7 @@ Future<void> main(List<String> args) async {
// has been printed to stderr.
//
// If [trace] is passed, its terse representation is printed after the error.
void printError(String error, StackTrace stackTrace) {
void printError(String error, StackTrace? stackTrace) {
if (printedError) stderr.writeln();
printedError = true;
stderr.writeln(error);
Expand All @@ -35,7 +35,7 @@ Future<void> main(List<String> args) async {
}
}

ExecutableOptions options;
ExecutableOptions? options;
try {
options = ExecutableOptions.parse(args);
term_glyph.ascii = !options.unicode;
Expand All @@ -52,7 +52,7 @@ Future<void> main(List<String> args) async {
}

var graph = StylesheetGraph(
ImportCache([], loadPaths: options.loadPaths, logger: options.logger));
ImportCache(loadPaths: options.loadPaths, logger: options.logger));
if (options.watch) {
await watch(options, graph);
return;
Expand All @@ -68,7 +68,9 @@ Future<void> main(List<String> args) async {
// dart-lang/sdk#33400.
() {
try {
if (destination != null && !options.emitErrorCss) {
if (destination != null &&
// dart-lang/sdk#45348
!options!.emitErrorCss) {
deleteFile(destination);
}
} on FileSystemException {
Expand All @@ -86,7 +88,11 @@ Future<void> main(List<String> args) async {
if (exitCode != 66) exitCode = 65;
if (options.stopOnError) return;
} on FileSystemException catch (error, stackTrace) {
printError("Error reading ${p.relative(error.path)}: ${error.message}.",
var path = error.path;
printError(
path == null
? error.message
: "Error reading ${p.relative(path)}: ${error.message}.",
options.trace ? stackTrace : null);

// Error 66 indicates no input.
Expand Down Expand Up @@ -115,12 +121,14 @@ Future<void> main(List<String> args) async {

/// Loads and returns the current version of Sass.
Future<String> _loadVersion() async {
var version = const String.fromEnvironment('version');
if (const bool.fromEnvironment('node')) {
version += " compiled with dart2js "
"${const String.fromEnvironment('dart-version')}";
if (const bool.hasEnvironment('version')) {
var version = const String.fromEnvironment('version');
if (const bool.fromEnvironment('node')) {
version += " compiled with dart2js "
"${const String.fromEnvironment('dart-version')}";
}
return version;
}
if (version != null) return version;

var libDir =
p.fromUri(await Isolate.resolvePackageUri(Uri.parse('package:sass/')));
Expand Down
111 changes: 58 additions & 53 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,8 +15,8 @@ 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/util/nullable.dart';
import 'src/visitor/serialize.dart';

export 'src/callable.dart' show Callable, AsyncCallable;
Expand Down Expand Up @@ -48,11 +49,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 @@ -87,26 +88,27 @@ export 'src/warn.dart' show warn;
/// Throws a [SassException] if conversion fails.
String compile(String path,
{bool color = false,
Logger logger,
Iterable<Importer> importers,
Iterable<String> loadPaths,
SyncPackageResolver packageResolver,
Iterable<Callable> functions,
OutputStyle style,
void sourceMap(SingleMapping map),
Logger? logger,
Iterable<Importer>? importers,
Iterable<String>? loadPaths,
PackageConfig? packageConfig,
Iterable<Callable>? functions,
OutputStyle? style,
void sourceMap(SingleMapping map)?,
bool charset = true}) {
logger ??= Logger.stderr(color: color);
var result = c.compile(path,
logger: logger,
importCache: ImportCache(importers,
importCache: ImportCache(
importers: importers,
logger: logger,
loadPaths: loadPaths,
packageResolver: packageResolver),
packageConfig: packageConfig),
functions: functions,
style: style,
sourceMap: sourceMap != null,
charset: charset);
if (sourceMap != null) sourceMap(result.sourceMap);
result.sourceMap.andThen(sourceMap);
return result.css;
}

Expand All @@ -132,11 +134,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 @@ -174,34 +176,35 @@ String compile(String path,
///
/// Throws a [SassException] if conversion fails.
String compileString(String source,
{Syntax syntax,
{Syntax? syntax,
bool color = false,
Logger logger,
Iterable<Importer> importers,
SyncPackageResolver packageResolver,
Iterable<String> loadPaths,
Iterable<Callable> functions,
OutputStyle style,
Importer importer,
Object url,
void sourceMap(SingleMapping map),
Logger? logger,
Iterable<Importer>? importers,
PackageConfig? packageConfig,
Iterable<String>? loadPaths,
Iterable<Callable>? functions,
OutputStyle? style,
Importer? importer,
Object? url,
void sourceMap(SingleMapping map)?,
bool charset = true,
@Deprecated("Use syntax instead.") bool indented = false}) {
logger ??= Logger.stderr(color: color);
var result = c.compileString(source,
syntax: syntax ?? (indented ? Syntax.sass : Syntax.scss),
logger: logger,
importCache: ImportCache(importers,
importCache: ImportCache(
importers: importers,
logger: logger,
packageResolver: packageResolver,
packageConfig: packageConfig,
loadPaths: loadPaths),
functions: functions,
style: style,
importer: importer,
url: url,
sourceMap: sourceMap != null,
charset: charset);
if (sourceMap != null) sourceMap(result.sourceMap);
result.sourceMap.andThen(sourceMap);
return result.css;
}

Expand All @@ -212,24 +215,25 @@ String compileString(String source,
/// slower, so [compile] should be preferred if possible.
Future<String> compileAsync(String path,
{bool color = false,
Logger logger,
Iterable<AsyncImporter> importers,
SyncPackageResolver packageResolver,
Iterable<String> loadPaths,
Iterable<AsyncCallable> functions,
OutputStyle style,
void sourceMap(SingleMapping map)}) async {
Logger? logger,
Iterable<AsyncImporter>? importers,
PackageConfig? packageConfig,
Iterable<String>? loadPaths,
Iterable<AsyncCallable>? functions,
OutputStyle? style,
void sourceMap(SingleMapping map)?}) async {
logger ??= Logger.stderr(color: color);
var result = await c.compileAsync(path,
logger: logger,
importCache: AsyncImportCache(importers,
importCache: AsyncImportCache(
importers: importers,
logger: logger,
loadPaths: loadPaths,
packageResolver: packageResolver),
packageConfig: packageConfig),
functions: functions,
style: style,
sourceMap: sourceMap != null);
if (sourceMap != null) sourceMap(result.sourceMap);
result.sourceMap.andThen(sourceMap);
return result.css;
}

Expand All @@ -239,33 +243,34 @@ Future<String> compileAsync(String path,
/// synchronous [Importer]s. However, running asynchronously is also somewhat
/// slower, so [compileString] should be preferred if possible.
Future<String> compileStringAsync(String source,
{Syntax syntax,
{Syntax? syntax,
bool color = false,
Logger logger,
Iterable<AsyncImporter> importers,
SyncPackageResolver packageResolver,
Iterable<String> loadPaths,
Iterable<AsyncCallable> functions,
OutputStyle style,
AsyncImporter importer,
Object url,
void sourceMap(SingleMapping map),
Logger? logger,
Iterable<AsyncImporter>? importers,
PackageConfig? packageConfig,
Iterable<String>? loadPaths,
Iterable<AsyncCallable>? functions,
OutputStyle? style,
AsyncImporter? importer,
Object? url,
void sourceMap(SingleMapping map)?,
bool charset = true,
@Deprecated("Use syntax instead.") bool indented = false}) async {
logger ??= Logger.stderr(color: color);
var result = await c.compileStringAsync(source,
syntax: syntax ?? (indented ? Syntax.sass : Syntax.scss),
logger: logger,
importCache: AsyncImportCache(importers,
importCache: AsyncImportCache(
importers: importers,
logger: logger,
packageResolver: packageResolver,
packageConfig: packageConfig,
loadPaths: loadPaths),
functions: functions,
style: style,
importer: importer,
url: url,
sourceMap: sourceMap != null,
charset: charset);
if (sourceMap != null) sourceMap(result.sourceMap);
result.sourceMap.andThen(sourceMap);
return result.css;
}
2 changes: 1 addition & 1 deletion lib/src/ast/css/at_rule.dart
Expand Up @@ -12,7 +12,7 @@ abstract class CssAtRule extends CssParentNode {
CssValue<String> get name;

/// The value of this rule.
CssValue<String> get value;
CssValue<String>? get value;

/// Whether the rule has no children.
///
Expand Down
4 changes: 2 additions & 2 deletions lib/src/ast/css/import.dart
Expand Up @@ -15,10 +15,10 @@ abstract class CssImport extends CssNode {
CssValue<String> get url;

/// The supports condition attached to this import.
CssValue<String> get supports;
CssValue<String>? get supports;

/// The media query attached to this import.
List<CssMediaQuery> get media;
List<CssMediaQuery>? get media;

T accept<T>(CssVisitor<T> visitor) => visitor.visitCssImport(this);
}
12 changes: 6 additions & 6 deletions lib/src/ast/css/media_query.dart
Expand Up @@ -11,12 +11,12 @@ class CssMediaQuery {
/// The modifier, probably either "not" or "only".
///
/// This may be `null` if no modifier is in use.
final String modifier;
final String? modifier;

/// The media type, for example "screen" or "print".
///
/// This may be `null`. If so, [features] will not be empty.
final String type;
final String? type;

/// Feature queries, including parentheses.
final List<String> features;
Expand All @@ -33,11 +33,11 @@ class CssMediaQuery {
///
/// Throws a [SassFormatException] if parsing fails.
static List<CssMediaQuery> parseList(String contents,
{Object url, Logger logger}) =>
{Object? url, Logger? logger}) =>
MediaQueryParser(contents, url: url, logger: logger).parse();

/// Creates a media query specifies a type and, optionally, features.
CssMediaQuery(this.type, {this.modifier, Iterable<String> features})
CssMediaQuery(this.type, {this.modifier, Iterable<String>? features})
: features = features == null ? const [] : List.unmodifiable(features);

/// Creates a media query that only specifies features.
Expand All @@ -59,8 +59,8 @@ class CssMediaQuery {
CssMediaQuery.condition([...this.features, ...other.features]));
}

String modifier;
String type;
String? modifier;
String? type;
List<String> features;
if ((ourModifier == 'not') != (theirModifier == 'not')) {
if (ourType == theirType) {
Expand Down
2 changes: 1 addition & 1 deletion lib/src/ast/css/modifiable/at_rule.dart
Expand Up @@ -12,7 +12,7 @@ import 'node.dart';
/// A modifiable version of [CssAtRule] for use in the evaluation step.
class ModifiableCssAtRule extends ModifiableCssParentNode implements CssAtRule {
final CssValue<String> name;
final CssValue<String> value;
final CssValue<String>? value;
final bool isChildless;
final FileSpan span;

Expand Down
5 changes: 2 additions & 3 deletions lib/src/ast/css/modifiable/declaration.dart
Expand Up @@ -2,7 +2,6 @@
// MIT-style license that can be found in the LICENSE file or at
// https://opensource.org/licenses/MIT.

import 'package:meta/meta.dart';
import 'package:source_span/source_span.dart';

import '../../../value.dart';
Expand All @@ -24,9 +23,9 @@ class ModifiableCssDeclaration extends ModifiableCssNode

/// Returns a new CSS declaration with the given properties.
ModifiableCssDeclaration(this.name, this.value, this.span,
{@required bool parsedAsCustomProperty, FileSpan valueSpanForMap})
{required bool parsedAsCustomProperty, FileSpan? valueSpanForMap})
: parsedAsCustomProperty = parsedAsCustomProperty,
valueSpanForMap = valueSpanForMap ?? span {
valueSpanForMap = valueSpanForMap ?? value.span {
if (parsedAsCustomProperty) {
if (!isCustomProperty) {
throw ArgumentError(
Expand Down
6 changes: 3 additions & 3 deletions lib/src/ast/css/modifiable/import.dart
Expand Up @@ -18,15 +18,15 @@ class ModifiableCssImport extends ModifiableCssNode implements CssImport {
final CssValue<String> url;

/// The supports condition attached to this import.
final CssValue<String> supports;
final CssValue<String>? supports;

/// The media query attached to this import.
final List<CssMediaQuery> media;
final List<CssMediaQuery>? media;

final FileSpan span;

ModifiableCssImport(this.url, this.span,
{this.supports, Iterable<CssMediaQuery> media})
{this.supports, Iterable<CssMediaQuery>? media})
: media = media == null ? null : List.unmodifiable(media);

T accept<T>(ModifiableCssVisitor<T> visitor) => visitor.visitCssImport(this);
Expand Down

0 comments on commit f681906

Please sign in to comment.