Skip to content

Commit d9220d9

Browse files
authored
Complete implementation the deprecations API (#2207)
1 parent 783c248 commit d9220d9

23 files changed

+430
-87
lines changed

CHANGELOG.md

Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,48 @@
1+
## 1.74.0
2+
3+
### JS API
4+
5+
* Add a new top-level `deprecations` object, which contains various
6+
`Deprecation` objects that define the different types of deprecation used by
7+
the Sass compiler and can be passed to the options below.
8+
9+
* Add a new `fatalDeprecations` compiler option that causes the compiler to
10+
error if any deprecation warnings of the provided types are encountered. You
11+
can also pass in a `Version` object to treat all deprecations that were active
12+
in that Dart Sass version as fatal.
13+
14+
* Add a new `futureDeprecations` compiler option that allows you to opt-in to
15+
certain deprecations early (currently just `import`).
16+
17+
* Add a new `silenceDeprecations` compiler option to ignore any deprecation
18+
warnings of the provided types.
19+
20+
### Command-Line Interface
21+
22+
* Add a new `--silence-deprecation` flag, which causes the compiler to ignore
23+
any deprecation warnings of the provided types.
24+
25+
* Previously, if a future deprecation was passed to `--fatal-deprecation` but
26+
not `--future-deprecation`, it would be treated as fatal despite not being
27+
enabled. Both flags are now required to treat a future deprecation as fatal
28+
with a warning emitted if `--fatal-deprecation` is passed without
29+
`--future-deprecation`, matching the JS API's behavior.
30+
31+
### Dart API
32+
33+
* The `compile` methods now take in a `silenceDeprecations` parameter, which
34+
causes the compiler to ignore any deprecation warnings of the provided types.
35+
36+
* Add `Deprecation.obsoleteIn` to match the JS API. This is currently null for
37+
all deprecations, but will be used once some deprecations become obsolete in
38+
Dart Sass 2.0.0.
39+
40+
* **Potentially breaking bug fix:** Fix a bug where `compileStringToResultAsync`
41+
ignored `fatalDeprecations` and `futureDeprecations`.
42+
43+
* The behavior around making future deprecations fatal mentioned in the CLI
44+
section above has also been changed in the Dart API.
45+
146
## 1.73.0
247

348
* Add support for nesting in plain CSS files. This is not processed by Sass at

bin/sass.dart

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ import 'package:sass/src/executable/watch.dart';
1515
import 'package:sass/src/import_cache.dart';
1616
import 'package:sass/src/importer/filesystem.dart';
1717
import 'package:sass/src/io.dart';
18-
import 'package:sass/src/logger/deprecation_handling.dart';
18+
import 'package:sass/src/logger/deprecation_processing.dart';
1919
import 'package:sass/src/stylesheet_graph.dart';
2020
import 'package:sass/src/utils.dart';
2121
import 'package:sass/src/embedded/executable.dart'
@@ -53,7 +53,8 @@ Future<void> main(List<String> args) async {
5353
// limit repetition. A separate DeprecationHandlingLogger is created for
5454
// each compilation, which will limit repetition if verbose is not
5555
// passed in addition to handling fatal/future deprecations.
56-
logger: DeprecationHandlingLogger(options.logger,
56+
logger: DeprecationProcessingLogger(options.logger,
57+
silenceDeprecations: options.silenceDeprecations,
5758
fatalDeprecations: options.fatalDeprecations,
5859
futureDeprecations: options.futureDeprecations,
5960
limitRepetition: false)));

lib/sass.dart

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -108,6 +108,7 @@ CompileResult compileToResult(String path,
108108
bool verbose = false,
109109
bool sourceMap = false,
110110
bool charset = true,
111+
Iterable<Deprecation>? silenceDeprecations,
111112
Iterable<Deprecation>? fatalDeprecations,
112113
Iterable<Deprecation>? futureDeprecations}) =>
113114
c.compile(path,
@@ -123,6 +124,7 @@ CompileResult compileToResult(String path,
123124
verbose: verbose,
124125
sourceMap: sourceMap,
125126
charset: charset,
127+
silenceDeprecations: silenceDeprecations,
126128
fatalDeprecations: fatalDeprecations,
127129
futureDeprecations: futureDeprecations);
128130

@@ -207,6 +209,7 @@ CompileResult compileStringToResult(String source,
207209
bool verbose = false,
208210
bool sourceMap = false,
209211
bool charset = true,
212+
Iterable<Deprecation>? silenceDeprecations,
210213
Iterable<Deprecation>? fatalDeprecations,
211214
Iterable<Deprecation>? futureDeprecations}) =>
212215
c.compileString(source,
@@ -225,6 +228,7 @@ CompileResult compileStringToResult(String source,
225228
verbose: verbose,
226229
sourceMap: sourceMap,
227230
charset: charset,
231+
silenceDeprecations: silenceDeprecations,
228232
fatalDeprecations: fatalDeprecations,
229233
futureDeprecations: futureDeprecations);
230234

@@ -245,6 +249,7 @@ Future<CompileResult> compileToResultAsync(String path,
245249
bool verbose = false,
246250
bool sourceMap = false,
247251
bool charset = true,
252+
Iterable<Deprecation>? silenceDeprecations,
248253
Iterable<Deprecation>? fatalDeprecations,
249254
Iterable<Deprecation>? futureDeprecations}) =>
250255
c.compileAsync(path,
@@ -260,6 +265,7 @@ Future<CompileResult> compileToResultAsync(String path,
260265
verbose: verbose,
261266
sourceMap: sourceMap,
262267
charset: charset,
268+
silenceDeprecations: silenceDeprecations,
263269
fatalDeprecations: fatalDeprecations,
264270
futureDeprecations: futureDeprecations);
265271

@@ -285,6 +291,7 @@ Future<CompileResult> compileStringToResultAsync(String source,
285291
bool verbose = false,
286292
bool sourceMap = false,
287293
bool charset = true,
294+
Iterable<Deprecation>? silenceDeprecations,
288295
Iterable<Deprecation>? fatalDeprecations,
289296
Iterable<Deprecation>? futureDeprecations}) =>
290297
c.compileStringAsync(source,
@@ -302,7 +309,10 @@ Future<CompileResult> compileStringToResultAsync(String source,
302309
quietDeps: quietDeps,
303310
verbose: verbose,
304311
sourceMap: sourceMap,
305-
charset: charset);
312+
charset: charset,
313+
silenceDeprecations: silenceDeprecations,
314+
fatalDeprecations: fatalDeprecations,
315+
futureDeprecations: futureDeprecations);
306316

307317
/// Like [compileToResult], but returns [CompileResult.css] rather than
308318
/// returning [CompileResult] directly.

lib/src/async_compile.dart

Lines changed: 9 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ import 'importer/legacy_node.dart';
1717
import 'importer/no_op.dart';
1818
import 'io.dart';
1919
import 'logger.dart';
20-
import 'logger/deprecation_handling.dart';
20+
import 'logger/deprecation_processing.dart';
2121
import 'syntax.dart';
2222
import 'utils.dart';
2323
import 'visitor/async_evaluate.dart';
@@ -42,10 +42,12 @@ Future<CompileResult> compileAsync(String path,
4242
bool verbose = false,
4343
bool sourceMap = false,
4444
bool charset = true,
45+
Iterable<Deprecation>? silenceDeprecations,
4546
Iterable<Deprecation>? fatalDeprecations,
4647
Iterable<Deprecation>? futureDeprecations}) async {
47-
DeprecationHandlingLogger deprecationLogger = logger =
48-
DeprecationHandlingLogger(logger ?? Logger.stderr(),
48+
DeprecationProcessingLogger deprecationLogger = logger =
49+
DeprecationProcessingLogger(logger ?? Logger.stderr(),
50+
silenceDeprecations: {...?silenceDeprecations},
4951
fatalDeprecations: {...?fatalDeprecations},
5052
futureDeprecations: {...?futureDeprecations},
5153
limitRepetition: !verbose);
@@ -106,10 +108,12 @@ Future<CompileResult> compileStringAsync(String source,
106108
bool verbose = false,
107109
bool sourceMap = false,
108110
bool charset = true,
111+
Iterable<Deprecation>? silenceDeprecations,
109112
Iterable<Deprecation>? fatalDeprecations,
110113
Iterable<Deprecation>? futureDeprecations}) async {
111-
DeprecationHandlingLogger deprecationLogger = logger =
112-
DeprecationHandlingLogger(logger ?? Logger.stderr(),
114+
DeprecationProcessingLogger deprecationLogger = logger =
115+
DeprecationProcessingLogger(logger ?? Logger.stderr(),
116+
silenceDeprecations: {...?silenceDeprecations},
113117
fatalDeprecations: {...?fatalDeprecations},
114118
futureDeprecations: {...?futureDeprecations},
115119
limitRepetition: !verbose);

lib/src/compile.dart

Lines changed: 10 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55
// DO NOT EDIT. This file was generated from async_compile.dart.
66
// See tool/grind/synchronize.dart for details.
77
//
8-
// Checksum: a9421a2975e79ad591ae32474cd076e1379d0e75
8+
// Checksum: ab2c6fa2588988a86abdbe87512134098e01b39e
99
//
1010
// ignore_for_file: unused_import
1111

@@ -26,7 +26,7 @@ import 'importer/legacy_node.dart';
2626
import 'importer/no_op.dart';
2727
import 'io.dart';
2828
import 'logger.dart';
29-
import 'logger/deprecation_handling.dart';
29+
import 'logger/deprecation_processing.dart';
3030
import 'syntax.dart';
3131
import 'utils.dart';
3232
import 'visitor/evaluate.dart';
@@ -51,10 +51,12 @@ CompileResult compile(String path,
5151
bool verbose = false,
5252
bool sourceMap = false,
5353
bool charset = true,
54+
Iterable<Deprecation>? silenceDeprecations,
5455
Iterable<Deprecation>? fatalDeprecations,
5556
Iterable<Deprecation>? futureDeprecations}) {
56-
DeprecationHandlingLogger deprecationLogger = logger =
57-
DeprecationHandlingLogger(logger ?? Logger.stderr(),
57+
DeprecationProcessingLogger deprecationLogger = logger =
58+
DeprecationProcessingLogger(logger ?? Logger.stderr(),
59+
silenceDeprecations: {...?silenceDeprecations},
5860
fatalDeprecations: {...?fatalDeprecations},
5961
futureDeprecations: {...?futureDeprecations},
6062
limitRepetition: !verbose);
@@ -115,10 +117,12 @@ CompileResult compileString(String source,
115117
bool verbose = false,
116118
bool sourceMap = false,
117119
bool charset = true,
120+
Iterable<Deprecation>? silenceDeprecations,
118121
Iterable<Deprecation>? fatalDeprecations,
119122
Iterable<Deprecation>? futureDeprecations}) {
120-
DeprecationHandlingLogger deprecationLogger = logger =
121-
DeprecationHandlingLogger(logger ?? Logger.stderr(),
123+
DeprecationProcessingLogger deprecationLogger = logger =
124+
DeprecationProcessingLogger(logger ?? Logger.stderr(),
125+
silenceDeprecations: {...?silenceDeprecations},
122126
fatalDeprecations: {...?fatalDeprecations},
123127
futureDeprecations: {...?futureDeprecations},
124128
limitRepetition: !verbose);

lib/src/deprecation.dart

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -112,14 +112,28 @@ enum Deprecation {
112112
/// what version of Dart Sass this deprecation will be live in.
113113
final bool isFuture;
114114

115+
/// Underlying version string used by [obsoleteIn].
116+
///
117+
/// This is necessary because [Version] doesn't have a constant constructor,
118+
/// so we can't use it directly as an enum property.
119+
final String? _obsoleteIn;
120+
121+
/// The Dart Sass version this feature was fully removed in, making the
122+
/// deprecation obsolete.
123+
///
124+
/// For deprecations that are not yet obsolete, this should be null.
125+
Version? get obsoleteIn => _obsoleteIn?.andThen(Version.parse);
126+
115127
/// Constructs a regular deprecation.
116128
const Deprecation(this.id, {required String? deprecatedIn, this.description})
117129
: _deprecatedIn = deprecatedIn,
130+
_obsoleteIn = null,
118131
isFuture = false;
119132

120133
/// Constructs a future deprecation.
121134
const Deprecation.future(this.id, {this.description})
122135
: _deprecatedIn = null,
136+
_obsoleteIn = null,
123137
isFuture = true;
124138

125139
@override

lib/src/embedded/compilation_dispatcher.dart

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ import 'dart:io';
77
import 'dart:isolate';
88
import 'dart:typed_data';
99

10+
import 'package:collection/collection.dart';
1011
import 'package:native_synchronization/mailbox.dart';
1112
import 'package:path/path.dart' as p;
1213
import 'package:protobuf/protobuf.dart';
@@ -124,6 +125,21 @@ final class CompilationDispatcher {
124125
: EmbeddedLogger(this,
125126
color: request.alertColor, ascii: request.alertAscii);
126127

128+
sass.Deprecation? deprecationOrWarn(String id) {
129+
var deprecation = sass.Deprecation.fromId(id);
130+
if (deprecation == null) {
131+
logger.warn('Invalid deprecation "$id".');
132+
}
133+
return deprecation;
134+
}
135+
136+
var fatalDeprecations =
137+
request.fatalDeprecation.map(deprecationOrWarn).whereNotNull();
138+
var silenceDeprecations =
139+
request.silenceDeprecation.map(deprecationOrWarn).whereNotNull();
140+
var futureDeprecations =
141+
request.futureDeprecation.map(deprecationOrWarn).whereNotNull();
142+
127143
try {
128144
var importers = request.importers.map((importer) =>
129145
_decodeImporter(request, importer) ??
@@ -148,6 +164,9 @@ final class CompilationDispatcher {
148164
url: input.url.isEmpty ? null : input.url,
149165
quietDeps: request.quietDeps,
150166
verbose: request.verbose,
167+
fatalDeprecations: fatalDeprecations,
168+
silenceDeprecations: silenceDeprecations,
169+
futureDeprecations: futureDeprecations,
151170
sourceMap: request.sourceMap,
152171
charset: request.charset);
153172

@@ -165,6 +184,9 @@ final class CompilationDispatcher {
165184
style: style,
166185
quietDeps: request.quietDeps,
167186
verbose: request.verbose,
187+
fatalDeprecations: fatalDeprecations,
188+
silenceDeprecations: silenceDeprecations,
189+
futureDeprecations: futureDeprecations,
168190
sourceMap: request.sourceMap,
169191
charset: request.charset);
170192
} on FileSystemException catch (error) {

lib/src/embedded/logger.dart

Lines changed: 10 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ import 'package:path/path.dart' as p;
66
import 'package:source_span/source_span.dart';
77
import 'package:stack_trace/stack_trace.dart';
88

9+
import '../deprecation.dart';
910
import '../logger.dart';
1011
import '../util/nullable.dart';
1112
import '../utils.dart';
@@ -14,7 +15,7 @@ import 'embedded_sass.pb.dart' hide SourceSpan;
1415
import 'utils.dart';
1516

1617
/// A Sass logger that sends log messages as `LogEvent`s.
17-
final class EmbeddedLogger implements Logger {
18+
final class EmbeddedLogger extends LoggerWithDeprecationType {
1819
/// The [CompilationDispatcher] to which to send events.
1920
final CompilationDispatcher _dispatcher;
2021

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

42-
void warn(String message,
43-
{FileSpan? span, Trace? trace, bool deprecation = false}) {
43+
void internalWarn(String message,
44+
{FileSpan? span, Trace? trace, Deprecation? deprecation}) {
4445
var formatted = withGlyphs(() {
4546
var buffer = StringBuffer();
4647
if (_color) {
4748
buffer.write('\u001b[33m\u001b[1m');
48-
if (deprecation) buffer.write('Deprecation ');
49+
if (deprecation != null) buffer.write('Deprecation ');
4950
buffer.write('Warning\u001b[0m');
5051
} else {
51-
if (deprecation) buffer.write('DEPRECATION ');
52+
if (deprecation != null) buffer.write('DEPRECATION ');
5253
buffer.write('WARNING');
5354
}
5455
if (span == null) {
@@ -65,12 +66,14 @@ final class EmbeddedLogger implements Logger {
6566
}, ascii: _ascii);
6667

6768
var event = OutboundMessage_LogEvent()
68-
..type =
69-
deprecation ? LogEventType.DEPRECATION_WARNING : LogEventType.WARNING
69+
..type = deprecation != null
70+
? LogEventType.DEPRECATION_WARNING
71+
: LogEventType.WARNING
7072
..message = message
7173
..formatted = formatted;
7274
if (span != null) event.span = protofySpan(span);
7375
if (trace != null) event.stackTrace = trace.toString();
76+
if (deprecation != null) event.deprecationType = deprecation.id;
7477
_dispatcher.sendLog(event);
7578
}
7679
}

0 commit comments

Comments
 (0)