Skip to content
Open
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
20 changes: 20 additions & 0 deletions lib/sass.dart
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ import 'src/import_cache.dart';
import 'src/importer.dart';
import 'src/importer/utils.dart';
import 'src/logger.dart';
import 'src/source_map_include_sources.dart';
import 'src/syntax.dart';
import 'src/util/nullable.dart';
import 'src/visitor/serialize.dart';
Expand All @@ -26,6 +27,7 @@ export 'src/deprecation.dart';
export 'src/exception.dart' show SassException;
export 'src/importer.dart';
export 'src/logger.dart' show Logger;
export 'src/source_map_include_sources.dart';
export 'src/syntax.dart';
export 'src/value.dart'
hide
Expand Down Expand Up @@ -90,6 +92,9 @@ export 'src/evaluation_context.dart' show warn;
///
/// [`source_maps`]: https://pub.dartlang.org/packages/source_maps
///
/// The [sourceMapIncludeSources] parameter controls the ways in which the
/// compiler can choose to include source contents in the source map.
///
/// If [charset] is `true`, this will include a `@charset` declaration or a
/// UTF-8 [byte-order mark][] if the stylesheet contains any non-ASCII
/// characters. Otherwise, it will never include a `@charset` declaration or a
Expand All @@ -112,6 +117,8 @@ CompileResult compileToResult(
bool quietDeps = false,
bool verbose = false,
bool sourceMap = false,
SourceMapIncludeSources sourceMapIncludeSources =
SourceMapIncludeSources.always,
bool charset = true,
Iterable<Deprecation>? silenceDeprecations,
Iterable<Deprecation>? fatalDeprecations,
Expand All @@ -130,6 +137,7 @@ CompileResult compileToResult(
quietDeps: quietDeps,
verbose: verbose,
sourceMap: sourceMap,
sourceMapIncludeSources: sourceMapIncludeSources,
charset: charset,
silenceDeprecations: silenceDeprecations,
fatalDeprecations: fatalDeprecations,
Expand Down Expand Up @@ -199,6 +207,9 @@ CompileResult compileToResult(
///
/// [`source_maps`]: https://pub.dartlang.org/packages/source_maps
///
/// The [sourceMapIncludeSources] parameter controls the ways in which the
/// compiler can choose to include source contents in the source map.
///
/// If [charset] is `true`, this will include a `@charset` declaration or a
/// UTF-8 [byte-order mark][] if the stylesheet contains any non-ASCII
/// characters. Otherwise, it will never include a `@charset` declaration or a
Expand All @@ -224,6 +235,8 @@ CompileResult compileStringToResult(
bool quietDeps = false,
bool verbose = false,
bool sourceMap = false,
SourceMapIncludeSources sourceMapIncludeSources =
SourceMapIncludeSources.always,
bool charset = true,
Iterable<Deprecation>? silenceDeprecations,
Iterable<Deprecation>? fatalDeprecations,
Expand All @@ -245,6 +258,7 @@ CompileResult compileStringToResult(
quietDeps: quietDeps,
verbose: verbose,
sourceMap: sourceMap,
sourceMapIncludeSources: sourceMapIncludeSources,
charset: charset,
silenceDeprecations: silenceDeprecations,
fatalDeprecations: fatalDeprecations,
Expand All @@ -268,6 +282,8 @@ Future<CompileResult> compileToResultAsync(
bool quietDeps = false,
bool verbose = false,
bool sourceMap = false,
SourceMapIncludeSources sourceMapIncludeSources =
SourceMapIncludeSources.always,
bool charset = true,
Iterable<Deprecation>? silenceDeprecations,
Iterable<Deprecation>? fatalDeprecations,
Expand All @@ -286,6 +302,7 @@ Future<CompileResult> compileToResultAsync(
quietDeps: quietDeps,
verbose: verbose,
sourceMap: sourceMap,
sourceMapIncludeSources: sourceMapIncludeSources,
charset: charset,
silenceDeprecations: silenceDeprecations,
fatalDeprecations: fatalDeprecations,
Expand Down Expand Up @@ -314,6 +331,8 @@ Future<CompileResult> compileStringToResultAsync(
bool quietDeps = false,
bool verbose = false,
bool sourceMap = false,
SourceMapIncludeSources sourceMapIncludeSources =
SourceMapIncludeSources.always,
bool charset = true,
Iterable<Deprecation>? silenceDeprecations,
Iterable<Deprecation>? fatalDeprecations,
Expand All @@ -335,6 +354,7 @@ Future<CompileResult> compileStringToResultAsync(
quietDeps: quietDeps,
verbose: verbose,
sourceMap: sourceMap,
sourceMapIncludeSources: sourceMapIncludeSources,
charset: charset,
silenceDeprecations: silenceDeprecations,
fatalDeprecations: fatalDeprecations,
Expand Down
54 changes: 41 additions & 13 deletions lib/src/async_compile.dart
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,6 @@
// MIT-style license that can be found in the LICENSE file or at
// https://opensource.org/licenses/MIT.

import 'dart:convert';

import 'package:cli_pkg/js.dart';
import 'package:path/path.dart' as p;

Expand All @@ -18,8 +16,8 @@ import 'importer/no_op.dart';
import 'io.dart';
import 'logger.dart';
import 'logger/deprecation_processing.dart';
import 'source_map_include_sources.dart';
import 'syntax.dart';
import 'utils.dart';
import 'visitor/async_evaluate.dart';
import 'visitor/serialize.dart';

Expand All @@ -42,6 +40,8 @@ Future<CompileResult> compileAsync(
bool quietDeps = false,
bool verbose = false,
bool sourceMap = false,
SourceMapIncludeSources sourceMapIncludeSources =
SourceMapIncludeSources.always,
Comment on lines +43 to +44
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Shouldn't this default to auto?

Also, in Dart it's generally a good practice to avoid default parameters for anything other than booleans, because it breaks the ability for callers to pass in null for "do the default behavior". Better to make this nullable and handle the fallback in the method body.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The previous behavior of Dart API without this option is effectively “always”, the previous “auto” behavior is done via post processing in Dart-JS code only.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm okay with changing the default here for Dart Sass callers, since the previous default didn't make a lot of sense anyway. Either way, this should by nullable and handle the default in the body.

bool charset = true,
Iterable<Deprecation>? silenceDeprecations,
Iterable<Deprecation>? fatalDeprecations,
Expand Down Expand Up @@ -88,6 +88,7 @@ Future<CompileResult> compileAsync(
lineFeed,
quietDeps,
sourceMap,
sourceMapIncludeSources,
charset,
);

Expand Down Expand Up @@ -117,6 +118,8 @@ Future<CompileResult> compileStringAsync(
bool quietDeps = false,
bool verbose = false,
bool sourceMap = false,
SourceMapIncludeSources sourceMapIncludeSources =
SourceMapIncludeSources.always,
bool charset = true,
Iterable<Deprecation>? silenceDeprecations,
Iterable<Deprecation>? fatalDeprecations,
Expand Down Expand Up @@ -156,6 +159,7 @@ Future<CompileResult> compileStringAsync(
lineFeed,
quietDeps,
sourceMap,
sourceMapIncludeSources,
charset,
);

Expand All @@ -179,6 +183,7 @@ Future<CompileResult> _compileStylesheet(
LineFeed? lineFeed,
bool quietDeps,
bool sourceMap,
SourceMapIncludeSources sourceMapIncludeSources,
bool charset,
) async {
if (nodeImporter != null) {
Expand All @@ -188,6 +193,23 @@ Future<CompileResult> _compileStylesheet(
'Dart Sass 2.0.0.\n\n'
'More info: https://sass-lang.com/d/legacy-js-api',
);
} else {
if (sourceMapIncludeSources == SourceMapIncludeSources.true_ ||
sourceMapIncludeSources == SourceMapIncludeSources.false_) {
var boolean = sourceMapIncludeSources == SourceMapIncludeSources.true_;
var suggestion = boolean ? 'always' : 'never';
logger?.warnForDeprecation(
Deprecation.sourceMapIncludeSourcesBoolean,
'Passing a boolean value for Options.sourceMapIncludeSources is '
'deprecated and will be removed in Dart Sass 2.0.0.\n'
"Please use '$suggestion' instead of $boolean.\n\n"
'More info: https://sass-lang.com/d/source-map-include-sources-boolean',
);
Comment on lines +201 to +207
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This should be handled at the JS level.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The logger object isn’t available at JS level. Also throwing it here allow us to only need to throw in a single code path, instead of need to duplicate it in multiple code paths.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In fact, if you just look at a few lines above, the legacy JS API warning is done here, instead of in the JS API code, I think for exactly same reason...

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think that's probably something we'll need to fix sooner or later anyway as APIs evolve over time. The DeprecationProcessingLogger initialization isn't that complex; we should be able to copy it into the JS code and then check if the logger that's passed in to compile*Async is already deprecation-processing and avoid rewrapping if so.

Either way, we shouldn't expose immediately-deprecated enum fields in a new Dart API. If we had to handle that, we should either make this parameter Object or have two separate enums.

sourceMapIncludeSources =
sourceMapIncludeSources == SourceMapIncludeSources.true_
? SourceMapIncludeSources.always
: SourceMapIncludeSources.never;
}
}
var evaluateResult = await evaluateAsync(
stylesheet,
Expand All @@ -212,16 +234,22 @@ Future<CompileResult> _compileStylesheet(
);

var resultSourceMap = serializeResult.sourceMap;
if (resultSourceMap != null && importCache != null) {
mapInPlace(
resultSourceMap.urls,
(url) => url == ''
? Uri.dataFromString(
stylesheet.span.file.getText(0),
encoding: utf8,
).toString()
: importCache.sourceMapUrl(Uri.parse(url)).toString(),
);
if (resultSourceMap != null) {
if (importCache != null) {
for (var i = 0, length = resultSourceMap.urls.length; i < length; i++) {
var canonicalUrl = Uri.parse(resultSourceMap.urls[i]);
var sourceMapUrl = importCache.sourceMapUrlOrNull(canonicalUrl);
if (sourceMapUrl != null) {
resultSourceMap.urls[i] = sourceMapUrl.toString();
if (sourceMapIncludeSources == SourceMapIncludeSources.auto) {
resultSourceMap.files[i] = null;
}
}
}
}
if (sourceMapIncludeSources == SourceMapIncludeSources.never) {
resultSourceMap.files.fillRange(0, resultSourceMap.files.length, null);
}
}

return CompileResult(evaluateResult, serializeResult);
Expand Down
7 changes: 7 additions & 0 deletions lib/src/async_import_cache.dart
Original file line number Diff line number Diff line change
Expand Up @@ -371,9 +371,16 @@ final class AsyncImportCache {
/// Returns the URL to use in the source map to refer to [canonicalUrl].
///
/// Returns [canonicalUrl] as-is if it hasn't been loaded by this cache.
@Deprecated('Use sourceMapUrlOrNull instead.')
Uri sourceMapUrl(Uri canonicalUrl) =>
_resultsCache[canonicalUrl]?.sourceMapUrl ?? canonicalUrl;

/// Returns the URL to use in the source map to refer to [canonicalUrl].
///
/// Returns `null` if it hasn't been loaded by this cache.
Uri? sourceMapUrlOrNull(Uri canonicalUrl) =>
_resultsCache[canonicalUrl]?.sourceMapUrl;

/// Returns the most recent time the stylesheet at [canonicalUrl] was loaded
/// from its importer, or `null` if it has never been loaded.
@internal
Expand Down
56 changes: 42 additions & 14 deletions lib/src/compile.dart
Original file line number Diff line number Diff line change
Expand Up @@ -5,14 +5,12 @@
// DO NOT EDIT. This file was generated from async_compile.dart.
// See tool/grind/synchronize.dart for details.
//
// Checksum: d305a0f75e329a29f5aff734ac31ce145fd3b8d5
// Checksum: 1ff55074bb0b91ced8c0ad971324a48a71a8213a
//
// ignore_for_file: unused_import

export 'async_compile.dart';

import 'dart:convert';

import 'package:cli_pkg/js.dart';
import 'package:path/path.dart' as p;

Expand All @@ -27,8 +25,8 @@ import 'importer/no_op.dart';
import 'io.dart';
import 'logger.dart';
import 'logger/deprecation_processing.dart';
import 'source_map_include_sources.dart';
import 'syntax.dart';
import 'utils.dart';
import 'visitor/evaluate.dart';
import 'visitor/serialize.dart';

Expand All @@ -51,6 +49,8 @@ CompileResult compile(
bool quietDeps = false,
bool verbose = false,
bool sourceMap = false,
SourceMapIncludeSources sourceMapIncludeSources =
SourceMapIncludeSources.always,
bool charset = true,
Iterable<Deprecation>? silenceDeprecations,
Iterable<Deprecation>? fatalDeprecations,
Expand Down Expand Up @@ -97,6 +97,7 @@ CompileResult compile(
lineFeed,
quietDeps,
sourceMap,
sourceMapIncludeSources,
charset,
);

Expand Down Expand Up @@ -126,6 +127,8 @@ CompileResult compileString(
bool quietDeps = false,
bool verbose = false,
bool sourceMap = false,
SourceMapIncludeSources sourceMapIncludeSources =
SourceMapIncludeSources.always,
bool charset = true,
Iterable<Deprecation>? silenceDeprecations,
Iterable<Deprecation>? fatalDeprecations,
Expand Down Expand Up @@ -165,6 +168,7 @@ CompileResult compileString(
lineFeed,
quietDeps,
sourceMap,
sourceMapIncludeSources,
charset,
);

Expand All @@ -188,6 +192,7 @@ CompileResult _compileStylesheet(
LineFeed? lineFeed,
bool quietDeps,
bool sourceMap,
SourceMapIncludeSources sourceMapIncludeSources,
bool charset,
) {
if (nodeImporter != null) {
Expand All @@ -197,6 +202,23 @@ CompileResult _compileStylesheet(
'Dart Sass 2.0.0.\n\n'
'More info: https://sass-lang.com/d/legacy-js-api',
);
} else {
if (sourceMapIncludeSources == SourceMapIncludeSources.true_ ||
sourceMapIncludeSources == SourceMapIncludeSources.false_) {
var boolean = sourceMapIncludeSources == SourceMapIncludeSources.true_;
var suggestion = boolean ? 'always' : 'never';
logger?.warnForDeprecation(
Deprecation.sourceMapIncludeSourcesBoolean,
'Passing a boolean value for Options.sourceMapIncludeSources is '
'deprecated and will be removed in Dart Sass 2.0.0.\n'
"Please use '$suggestion' instead of $boolean.\n\n"
'More info: https://sass-lang.com/d/source-map-include-sources-boolean',
);
sourceMapIncludeSources =
sourceMapIncludeSources == SourceMapIncludeSources.true_
? SourceMapIncludeSources.always
: SourceMapIncludeSources.never;
}
}
var evaluateResult = evaluate(
stylesheet,
Expand All @@ -221,16 +243,22 @@ CompileResult _compileStylesheet(
);

var resultSourceMap = serializeResult.sourceMap;
if (resultSourceMap != null && importCache != null) {
mapInPlace(
resultSourceMap.urls,
(url) => url == ''
? Uri.dataFromString(
stylesheet.span.file.getText(0),
encoding: utf8,
).toString()
: importCache.sourceMapUrl(Uri.parse(url)).toString(),
);
if (resultSourceMap != null) {
if (importCache != null) {
for (var i = 0, length = resultSourceMap.urls.length; i < length; i++) {
var canonicalUrl = Uri.parse(resultSourceMap.urls[i]);
var sourceMapUrl = importCache.sourceMapUrlOrNull(canonicalUrl);
if (sourceMapUrl != null) {
resultSourceMap.urls[i] = sourceMapUrl.toString();
if (sourceMapIncludeSources == SourceMapIncludeSources.auto) {
resultSourceMap.files[i] = null;
}
}
}
}
if (sourceMapIncludeSources == SourceMapIncludeSources.never) {
resultSourceMap.files.fillRange(0, resultSourceMap.files.length, null);
}
}

return CompileResult(evaluateResult, serializeResult);
Expand Down
8 changes: 7 additions & 1 deletion lib/src/deprecation.dart
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ enum Deprecation {
// DO NOT EDIT. This section was generated from the language repo.
// See tool/grind/generate_deprecations.dart for details.
//
// Checksum: 6fc524360d067b73c243c666e27a9a9ea7e08841
// Checksum: d6dc089a2bcab991dd117a6592f2f55d1caafccd

/// Deprecation for passing a string directly to meta.call().
callString('call-string',
Expand Down Expand Up @@ -151,6 +151,12 @@ enum Deprecation {
deprecatedIn: '1.95.0',
description: 'The Sass if(\$condition, \$if-true, \$if-false) function.'),

/// Deprecation for passing a boolean value to as Options.sourceMapIncludeSources.
sourceMapIncludeSourcesBoolean('source-map-include-sources-boolean',
deprecatedIn: '1.99.0',
description:
'Passing a boolean value to as Options.sourceMapIncludeSources.'),

// END AUTOGENERATED CODE

/// Used for deprecations coming from user-authored code.
Expand Down
Loading