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

Complete implementation the deprecations API #2207

Merged
merged 11 commits into from
Apr 3, 2024
Merged
45 changes: 45 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,48 @@
## 1.74.0

### JS API

* Add a new top-level `deprecations` object, which contains various
`Deprecation` objects that define the different types of deprecation used by
the Sass compiler and can be passed to the options below.

* Add a new `fatalDeprecations` compiler option that causes the compiler to
error if any deprecation warnings of the provided types are encountered. You
can also pass in a `Version` object to treat all deprecations that were active
in that Dart Sass version as fatal.

* Add a new `futureDeprecations` compiler option that allows you to opt-in to
certain deprecations early (currently just `import`).

* Add a new `silenceDeprecations` compiler option to ignore any deprecation
warnings of the provided types.

### Command-Line Interface

* Add a new `--silence-deprecation` flag, which causes the compiler to ignore
any deprecation warnings of the provided types.

* Previously, if a future deprecation was passed to `--fatal-deprecation` but
not `--future-deprecation`, it would be treated as fatal despite not being
enabled. Both flags are now required to treat a future deprecation as fatal
with a warning emitted if `--fatal-deprecation` is passed without
`--future-deprecation`, matching the JS API's behavior.

### Dart API

* The `compile` methods now take in a `silenceDeprecations` parameter, which
causes the compiler to ignore any deprecation warnings of the provided types.

* Add `Deprecation.obsoleteIn` to match the JS API. This is currently null for
all deprecations, but will be used once some deprecations become obsolete in
Dart Sass 2.0.0.

* **Potentially breaking bug fix:** Fix a bug where `compileStringToResultAsync`
ignored `fatalDeprecations` and `futureDeprecations`.

* The behavior around making future deprecations fatal mentioned in the CLI
section above has also been changed in the Dart API.

## 1.73.0

* Add support for nesting in plain CSS files. This is not processed by Sass at
Expand Down
5 changes: 3 additions & 2 deletions bin/sass.dart
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ import 'package:sass/src/executable/watch.dart';
import 'package:sass/src/import_cache.dart';
import 'package:sass/src/importer/filesystem.dart';
import 'package:sass/src/io.dart';
import 'package:sass/src/logger/deprecation_handling.dart';
import 'package:sass/src/logger/deprecation_processing.dart';
import 'package:sass/src/stylesheet_graph.dart';
import 'package:sass/src/utils.dart';
import 'package:sass/src/embedded/executable.dart'
Expand Down Expand Up @@ -53,7 +53,8 @@ Future<void> main(List<String> args) async {
// limit repetition. A separate DeprecationHandlingLogger is created for
// each compilation, which will limit repetition if verbose is not
// passed in addition to handling fatal/future deprecations.
logger: DeprecationHandlingLogger(options.logger,
logger: DeprecationProcessingLogger(options.logger,
silenceDeprecations: options.silenceDeprecations,
fatalDeprecations: options.fatalDeprecations,
futureDeprecations: options.futureDeprecations,
limitRepetition: false)));
Expand Down
12 changes: 11 additions & 1 deletion lib/sass.dart
Original file line number Diff line number Diff line change
Expand Up @@ -108,6 +108,7 @@ CompileResult compileToResult(String path,
bool verbose = false,
bool sourceMap = false,
bool charset = true,
Iterable<Deprecation>? silenceDeprecations,
Iterable<Deprecation>? fatalDeprecations,
Iterable<Deprecation>? futureDeprecations}) =>
c.compile(path,
Expand All @@ -123,6 +124,7 @@ CompileResult compileToResult(String path,
verbose: verbose,
sourceMap: sourceMap,
charset: charset,
silenceDeprecations: silenceDeprecations,
fatalDeprecations: fatalDeprecations,
futureDeprecations: futureDeprecations);

Expand Down Expand Up @@ -207,6 +209,7 @@ CompileResult compileStringToResult(String source,
bool verbose = false,
bool sourceMap = false,
bool charset = true,
Iterable<Deprecation>? silenceDeprecations,
Iterable<Deprecation>? fatalDeprecations,
Iterable<Deprecation>? futureDeprecations}) =>
c.compileString(source,
Expand All @@ -225,6 +228,7 @@ CompileResult compileStringToResult(String source,
verbose: verbose,
sourceMap: sourceMap,
charset: charset,
silenceDeprecations: silenceDeprecations,
fatalDeprecations: fatalDeprecations,
futureDeprecations: futureDeprecations);

Expand All @@ -245,6 +249,7 @@ Future<CompileResult> compileToResultAsync(String path,
bool verbose = false,
bool sourceMap = false,
bool charset = true,
Iterable<Deprecation>? silenceDeprecations,
Iterable<Deprecation>? fatalDeprecations,
Iterable<Deprecation>? futureDeprecations}) =>
c.compileAsync(path,
Expand All @@ -260,6 +265,7 @@ Future<CompileResult> compileToResultAsync(String path,
verbose: verbose,
sourceMap: sourceMap,
charset: charset,
silenceDeprecations: silenceDeprecations,
fatalDeprecations: fatalDeprecations,
futureDeprecations: futureDeprecations);

Expand All @@ -285,6 +291,7 @@ Future<CompileResult> compileStringToResultAsync(String source,
bool verbose = false,
bool sourceMap = false,
bool charset = true,
Iterable<Deprecation>? silenceDeprecations,
Iterable<Deprecation>? fatalDeprecations,
Iterable<Deprecation>? futureDeprecations}) =>
c.compileStringAsync(source,
Expand All @@ -302,7 +309,10 @@ Future<CompileResult> compileStringToResultAsync(String source,
quietDeps: quietDeps,
verbose: verbose,
sourceMap: sourceMap,
charset: charset);
charset: charset,
silenceDeprecations: silenceDeprecations,
fatalDeprecations: fatalDeprecations,
futureDeprecations: futureDeprecations);

/// Like [compileToResult], but returns [CompileResult.css] rather than
/// returning [CompileResult] directly.
Expand Down
14 changes: 9 additions & 5 deletions lib/src/async_compile.dart
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ import 'importer/legacy_node.dart';
import 'importer/no_op.dart';
import 'io.dart';
import 'logger.dart';
import 'logger/deprecation_handling.dart';
import 'logger/deprecation_processing.dart';
import 'syntax.dart';
import 'utils.dart';
import 'visitor/async_evaluate.dart';
Expand All @@ -42,10 +42,12 @@ Future<CompileResult> compileAsync(String path,
bool verbose = false,
bool sourceMap = false,
bool charset = true,
Iterable<Deprecation>? silenceDeprecations,
Iterable<Deprecation>? fatalDeprecations,
Iterable<Deprecation>? futureDeprecations}) async {
DeprecationHandlingLogger deprecationLogger = logger =
DeprecationHandlingLogger(logger ?? Logger.stderr(),
DeprecationProcessingLogger deprecationLogger = logger =
DeprecationProcessingLogger(logger ?? Logger.stderr(),
silenceDeprecations: {...?silenceDeprecations},
fatalDeprecations: {...?fatalDeprecations},
futureDeprecations: {...?futureDeprecations},
limitRepetition: !verbose);
Expand Down Expand Up @@ -106,10 +108,12 @@ Future<CompileResult> compileStringAsync(String source,
bool verbose = false,
bool sourceMap = false,
bool charset = true,
Iterable<Deprecation>? silenceDeprecations,
Iterable<Deprecation>? fatalDeprecations,
Iterable<Deprecation>? futureDeprecations}) async {
DeprecationHandlingLogger deprecationLogger = logger =
DeprecationHandlingLogger(logger ?? Logger.stderr(),
DeprecationProcessingLogger deprecationLogger = logger =
DeprecationProcessingLogger(logger ?? Logger.stderr(),
silenceDeprecations: {...?silenceDeprecations},
fatalDeprecations: {...?fatalDeprecations},
futureDeprecations: {...?futureDeprecations},
limitRepetition: !verbose);
Expand Down
16 changes: 10 additions & 6 deletions lib/src/compile.dart
Original file line number Diff line number Diff line change
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: a9421a2975e79ad591ae32474cd076e1379d0e75
// Checksum: ab2c6fa2588988a86abdbe87512134098e01b39e
//
// ignore_for_file: unused_import

Expand All @@ -26,7 +26,7 @@ import 'importer/legacy_node.dart';
import 'importer/no_op.dart';
import 'io.dart';
import 'logger.dart';
import 'logger/deprecation_handling.dart';
import 'logger/deprecation_processing.dart';
import 'syntax.dart';
import 'utils.dart';
import 'visitor/evaluate.dart';
Expand All @@ -51,10 +51,12 @@ CompileResult compile(String path,
bool verbose = false,
bool sourceMap = false,
bool charset = true,
Iterable<Deprecation>? silenceDeprecations,
Iterable<Deprecation>? fatalDeprecations,
Iterable<Deprecation>? futureDeprecations}) {
DeprecationHandlingLogger deprecationLogger = logger =
DeprecationHandlingLogger(logger ?? Logger.stderr(),
DeprecationProcessingLogger deprecationLogger = logger =
DeprecationProcessingLogger(logger ?? Logger.stderr(),
silenceDeprecations: {...?silenceDeprecations},
fatalDeprecations: {...?fatalDeprecations},
futureDeprecations: {...?futureDeprecations},
limitRepetition: !verbose);
Expand Down Expand Up @@ -115,10 +117,12 @@ CompileResult compileString(String source,
bool verbose = false,
bool sourceMap = false,
bool charset = true,
Iterable<Deprecation>? silenceDeprecations,
Iterable<Deprecation>? fatalDeprecations,
Iterable<Deprecation>? futureDeprecations}) {
DeprecationHandlingLogger deprecationLogger = logger =
DeprecationHandlingLogger(logger ?? Logger.stderr(),
DeprecationProcessingLogger deprecationLogger = logger =
DeprecationProcessingLogger(logger ?? Logger.stderr(),
silenceDeprecations: {...?silenceDeprecations},
fatalDeprecations: {...?fatalDeprecations},
futureDeprecations: {...?futureDeprecations},
limitRepetition: !verbose);
Expand Down
14 changes: 14 additions & 0 deletions lib/src/deprecation.dart
Original file line number Diff line number Diff line change
Expand Up @@ -112,14 +112,28 @@ enum Deprecation {
/// what version of Dart Sass this deprecation will be live in.
final bool isFuture;

/// Underlying version string used by [obsoleteIn].
///
/// This is necessary because [Version] doesn't have a constant constructor,
/// so we can't use it directly as an enum property.
final String? _obsoleteIn;

/// The Dart Sass version this feature was fully removed in, making the
/// deprecation obsolete.
///
/// For deprecations that are not yet obsolete, this should be null.
Version? get obsoleteIn => _obsoleteIn?.andThen(Version.parse);

/// Constructs a regular deprecation.
const Deprecation(this.id, {required String? deprecatedIn, this.description})
: _deprecatedIn = deprecatedIn,
_obsoleteIn = null,
isFuture = false;

/// Constructs a future deprecation.
const Deprecation.future(this.id, {this.description})
: _deprecatedIn = null,
_obsoleteIn = null,
isFuture = true;

@override
Expand Down
22 changes: 22 additions & 0 deletions lib/src/embedded/compilation_dispatcher.dart
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import 'dart:io';
import 'dart:isolate';
import 'dart:typed_data';

import 'package:collection/collection.dart';
import 'package:native_synchronization/mailbox.dart';
import 'package:path/path.dart' as p;
import 'package:protobuf/protobuf.dart';
Expand Down Expand Up @@ -124,6 +125,21 @@ final class CompilationDispatcher {
: EmbeddedLogger(this,
color: request.alertColor, ascii: request.alertAscii);

sass.Deprecation? deprecationOrWarn(String id) {
var deprecation = sass.Deprecation.fromId(id);
if (deprecation == null) {
logger.warn('Invalid deprecation "$id".');
}
return deprecation;
}

var fatalDeprecations =
request.fatalDeprecation.map(deprecationOrWarn).whereNotNull();
var silenceDeprecations =
request.silenceDeprecation.map(deprecationOrWarn).whereNotNull();
var futureDeprecations =
request.futureDeprecation.map(deprecationOrWarn).whereNotNull();

try {
var importers = request.importers.map((importer) =>
_decodeImporter(request, importer) ??
Expand All @@ -148,6 +164,9 @@ final class CompilationDispatcher {
url: input.url.isEmpty ? null : input.url,
quietDeps: request.quietDeps,
verbose: request.verbose,
fatalDeprecations: fatalDeprecations,
silenceDeprecations: silenceDeprecations,
futureDeprecations: futureDeprecations,
sourceMap: request.sourceMap,
charset: request.charset);

Expand All @@ -165,6 +184,9 @@ final class CompilationDispatcher {
style: style,
quietDeps: request.quietDeps,
verbose: request.verbose,
fatalDeprecations: fatalDeprecations,
silenceDeprecations: silenceDeprecations,
futureDeprecations: futureDeprecations,
sourceMap: request.sourceMap,
charset: request.charset);
} on FileSystemException catch (error) {
Expand Down
17 changes: 10 additions & 7 deletions lib/src/embedded/logger.dart
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import 'package:path/path.dart' as p;
import 'package:source_span/source_span.dart';
import 'package:stack_trace/stack_trace.dart';

import '../deprecation.dart';
import '../logger.dart';
import '../util/nullable.dart';
import '../utils.dart';
Expand All @@ -14,7 +15,7 @@ import 'embedded_sass.pb.dart' hide SourceSpan;
import 'utils.dart';

/// A Sass logger that sends log messages as `LogEvent`s.
final class EmbeddedLogger implements Logger {
final class EmbeddedLogger extends LoggerWithDeprecationType {
/// The [CompilationDispatcher] to which to send events.
final CompilationDispatcher _dispatcher;

Expand All @@ -39,16 +40,16 @@ final class EmbeddedLogger implements Logger {
': $message\n');
}

void warn(String message,
{FileSpan? span, Trace? trace, bool deprecation = false}) {
void internalWarn(String message,
{FileSpan? span, Trace? trace, Deprecation? deprecation}) {
var formatted = withGlyphs(() {
var buffer = StringBuffer();
if (_color) {
buffer.write('\u001b[33m\u001b[1m');
if (deprecation) buffer.write('Deprecation ');
if (deprecation != null) buffer.write('Deprecation ');
buffer.write('Warning\u001b[0m');
} else {
if (deprecation) buffer.write('DEPRECATION ');
if (deprecation != null) buffer.write('DEPRECATION ');
buffer.write('WARNING');
}
if (span == null) {
Expand All @@ -65,12 +66,14 @@ final class EmbeddedLogger implements Logger {
}, ascii: _ascii);

var event = OutboundMessage_LogEvent()
..type =
deprecation ? LogEventType.DEPRECATION_WARNING : LogEventType.WARNING
..type = deprecation != null
? LogEventType.DEPRECATION_WARNING
: LogEventType.WARNING
..message = message
..formatted = formatted;
if (span != null) event.span = protofySpan(span);
if (trace != null) event.stackTrace = trace.toString();
if (deprecation != null) event.deprecationType = deprecation.id;
_dispatcher.sendLog(event);
}
}