Skip to content

Commit 9ee5408

Browse files
jamesnwjgerigmeyer
andauthored
[Package Importer] Dart Implementation (#2130)
Co-authored-by: Jonny Gerig Meyer <[email protected]>
1 parent 9423aa5 commit 9ee5408

23 files changed

+512
-69
lines changed

lib/src/async_compile.dart

+5-4
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,8 @@ import 'visitor/serialize.dart';
2626
/// Like [compileAsync] in `lib/sass.dart`, but provides more options to support
2727
/// the node-sass compatible API and the executable.
2828
///
29-
/// At most one of `importCache` and `nodeImporter` may be provided at once.
29+
/// If both `importCache` and `nodeImporter` are provided, the importers in
30+
/// `importCache` will be evaluated before `nodeImporter`.
3031
Future<CompileResult> compileAsync(String path,
3132
{Syntax? syntax,
3233
Logger? logger,
@@ -56,7 +57,7 @@ Future<CompileResult> compileAsync(String path,
5657
(syntax == null || syntax == Syntax.forPath(path))) {
5758
importCache ??= AsyncImportCache.none(logger: logger);
5859
stylesheet = (await importCache.importCanonical(
59-
FilesystemImporter('.'), p.toUri(canonicalize(path)),
60+
FilesystemImporter.cwd, p.toUri(canonicalize(path)),
6061
originalUrl: p.toUri(path)))!;
6162
} else {
6263
stylesheet = Stylesheet.parse(
@@ -69,7 +70,7 @@ Future<CompileResult> compileAsync(String path,
6970
logger,
7071
importCache,
7172
nodeImporter,
72-
FilesystemImporter('.'),
73+
FilesystemImporter.cwd,
7374
functions,
7475
style,
7576
useSpaces,
@@ -121,7 +122,7 @@ Future<CompileResult> compileStringAsync(String source,
121122
logger,
122123
importCache,
123124
nodeImporter,
124-
importer ?? (isBrowser ? NoOpImporter() : FilesystemImporter('.')),
125+
importer ?? (isBrowser ? NoOpImporter() : FilesystemImporter.cwd),
125126
functions,
126127
style,
127128
useSpaces,

lib/src/async_import_cache.dart

+6
Original file line numberDiff line numberDiff line change
@@ -104,6 +104,12 @@ final class AsyncImportCache {
104104
: _importers = const [],
105105
_logger = logger ?? const Logger.stderr();
106106

107+
/// Creates an import cache without any globally-available importers, and only
108+
/// the passed in importers.
109+
AsyncImportCache.only(Iterable<AsyncImporter> importers, {Logger? logger})
110+
: _importers = List.unmodifiable(importers),
111+
_logger = logger ?? const Logger.stderr();
112+
107113
/// Converts the user's [importers], [loadPaths], and [packageConfig]
108114
/// options into a single list of importers.
109115
static List<AsyncImporter> _toImporters(Iterable<AsyncImporter>? importers,

lib/src/compile.dart

+6-5
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: 5178e366228bde7854df12221393857bb3022628
8+
// Checksum: a9421a2975e79ad591ae32474cd076e1379d0e75
99
//
1010
// ignore_for_file: unused_import
1111

@@ -35,7 +35,8 @@ import 'visitor/serialize.dart';
3535
/// Like [compile] in `lib/sass.dart`, but provides more options to support
3636
/// the node-sass compatible API and the executable.
3737
///
38-
/// At most one of `importCache` and `nodeImporter` may be provided at once.
38+
/// If both `importCache` and `nodeImporter` are provided, the importers in
39+
/// `importCache` will be evaluated before `nodeImporter`.
3940
CompileResult compile(String path,
4041
{Syntax? syntax,
4142
Logger? logger,
@@ -65,7 +66,7 @@ CompileResult compile(String path,
6566
(syntax == null || syntax == Syntax.forPath(path))) {
6667
importCache ??= ImportCache.none(logger: logger);
6768
stylesheet = importCache.importCanonical(
68-
FilesystemImporter('.'), p.toUri(canonicalize(path)),
69+
FilesystemImporter.cwd, p.toUri(canonicalize(path)),
6970
originalUrl: p.toUri(path))!;
7071
} else {
7172
stylesheet = Stylesheet.parse(
@@ -78,7 +79,7 @@ CompileResult compile(String path,
7879
logger,
7980
importCache,
8081
nodeImporter,
81-
FilesystemImporter('.'),
82+
FilesystemImporter.cwd,
8283
functions,
8384
style,
8485
useSpaces,
@@ -130,7 +131,7 @@ CompileResult compileString(String source,
130131
logger,
131132
importCache,
132133
nodeImporter,
133-
importer ?? (isBrowser ? NoOpImporter() : FilesystemImporter('.')),
134+
importer ?? (isBrowser ? NoOpImporter() : FilesystemImporter.cwd),
134135
functions,
135136
style,
136137
useSpaces,

lib/src/embedded/compilation_dispatcher.dart

+5
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ import 'package:native_synchronization/mailbox.dart';
1111
import 'package:path/path.dart' as p;
1212
import 'package:protobuf/protobuf.dart';
1313
import 'package:sass/sass.dart' as sass;
14+
import 'package:sass/src/importer/node_package.dart' as npi;
1415

1516
import '../logger.dart';
1617
import '../value/function.dart';
@@ -226,6 +227,10 @@ final class CompilationDispatcher {
226227
case InboundMessage_CompileRequest_Importer_Importer.notSet:
227228
_checkNoNonCanonicalScheme(importer);
228229
return null;
230+
231+
case InboundMessage_CompileRequest_Importer_Importer.nodePackageImporter:
232+
return npi.NodePackageImporter(
233+
importer.nodePackageImporter.entryPointDirectory);
229234
}
230235
}
231236

lib/src/embedded/importer/file.dart

+3-9
Original file line numberDiff line numberDiff line change
@@ -6,12 +6,6 @@ import '../../importer.dart';
66
import '../embedded_sass.pb.dart' hide SourceSpan;
77
import 'base.dart';
88

9-
/// A filesystem importer to use for most implementation details of
10-
/// [FileImporter].
11-
///
12-
/// This allows us to avoid duplicating logic between the two importers.
13-
final _filesystemImporter = FilesystemImporter('.');
14-
159
/// An importer that asks the host to resolve imports in a simplified,
1610
/// file-system-centric way.
1711
final class FileImporter extends ImporterBase {
@@ -21,7 +15,7 @@ final class FileImporter extends ImporterBase {
2115
FileImporter(super.dispatcher, this._importerId);
2216

2317
Uri? canonicalize(Uri url) {
24-
if (url.scheme == 'file') return _filesystemImporter.canonicalize(url);
18+
if (url.scheme == 'file') return FilesystemImporter.cwd.canonicalize(url);
2519

2620
var request = OutboundMessage_FileImportRequest()
2721
..importerId = _importerId
@@ -39,7 +33,7 @@ final class FileImporter extends ImporterBase {
3933
throw 'The file importer must return a file: URL, was "$url"';
4034
}
4135

42-
return _filesystemImporter.canonicalize(url);
36+
return FilesystemImporter.cwd.canonicalize(url);
4337

4438
case InboundMessage_FileImportResponse_Result.error:
4539
throw response.error;
@@ -49,7 +43,7 @@ final class FileImporter extends ImporterBase {
4943
}
5044
}
5145

52-
ImporterResult? load(Uri url) => _filesystemImporter.load(url);
46+
ImporterResult? load(Uri url) => FilesystemImporter.cwd.load(url);
5347

5448
bool isNonCanonicalScheme(String scheme) => scheme != 'file';
5549

lib/src/executable/compile_stylesheet.dart

+3-3
Original file line numberDiff line numberDiff line change
@@ -68,7 +68,7 @@ Future<(int, String, String?)?> compileStylesheet(ExecutableOptions options,
6868
Future<void> _compileStylesheetWithoutErrorHandling(ExecutableOptions options,
6969
StylesheetGraph graph, String? source, String? destination,
7070
{bool ifModified = false}) async {
71-
var importer = FilesystemImporter('.');
71+
var importer = FilesystemImporter.cwd;
7272
if (ifModified) {
7373
try {
7474
if (source != null &&
@@ -102,7 +102,7 @@ Future<void> _compileStylesheetWithoutErrorHandling(ExecutableOptions options,
102102
syntax: syntax,
103103
logger: options.logger,
104104
importCache: importCache,
105-
importer: FilesystemImporter('.'),
105+
importer: FilesystemImporter.cwd,
106106
style: options.style,
107107
quietDeps: options.quietDeps,
108108
verbose: options.verbose,
@@ -127,7 +127,7 @@ Future<void> _compileStylesheetWithoutErrorHandling(ExecutableOptions options,
127127
syntax: syntax,
128128
logger: options.logger,
129129
importCache: graph.importCache,
130-
importer: FilesystemImporter('.'),
130+
importer: FilesystemImporter.cwd,
131131
style: options.style,
132132
quietDeps: options.quietDeps,
133133
verbose: options.verbose,

lib/src/executable/repl.dart

+1-1
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@ Future<void> repl(ExecutableOptions options) async {
2222
var repl = Repl(prompt: '>> ');
2323
var logger = TrackingLogger(options.logger);
2424
var evaluator = Evaluator(
25-
importer: FilesystemImporter('.'),
25+
importer: FilesystemImporter.cwd,
2626
importCache: ImportCache(loadPaths: options.loadPaths, logger: logger),
2727
logger: logger);
2828
await for (String line in repl.runAsync()) {

lib/src/executable/watch.dart

+3-3
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,7 @@ Future<void> watch(ExecutableOptions options, StylesheetGraph graph) async {
3939
var sourcesToDestinations = _sourcesToDestinations(options);
4040
for (var source in sourcesToDestinations.keys) {
4141
graph.addCanonical(
42-
FilesystemImporter('.'), p.toUri(canonicalize(source)), p.toUri(source),
42+
FilesystemImporter.cwd, p.toUri(canonicalize(source)), p.toUri(source),
4343
recanonicalize: false);
4444
}
4545
var success = await compileStylesheets(options, graph, sourcesToDestinations,
@@ -130,7 +130,7 @@ final class _Watcher {
130130
await compileStylesheets(_options, _graph, {path: destination},
131131
ifModified: true);
132132
var downstream = _graph.addCanonical(
133-
FilesystemImporter('.'), _canonicalize(path), p.toUri(path));
133+
FilesystemImporter.cwd, _canonicalize(path), p.toUri(path));
134134
return await _recompileDownstream(downstream) && success;
135135
}
136136

@@ -144,7 +144,7 @@ final class _Watcher {
144144
if (_destinationFor(path) case var destination?) _delete(destination);
145145
}
146146

147-
var downstream = _graph.remove(FilesystemImporter('.'), url);
147+
var downstream = _graph.remove(FilesystemImporter.cwd, url);
148148
return await _recompileDownstream(downstream);
149149
}
150150

lib/src/import_cache.dart

+7-1
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55
// DO NOT EDIT. This file was generated from async_import_cache.dart.
66
// See tool/grind/synchronize.dart for details.
77
//
8-
// Checksum: 342e907cf10e1dd80d7045fc32db43c74376654e
8+
// Checksum: d157b83599dbc07a80ac6cb5ffdf5dde03b60376
99
//
1010
// ignore_for_file: unused_import
1111

@@ -106,6 +106,12 @@ final class ImportCache {
106106
: _importers = const [],
107107
_logger = logger ?? const Logger.stderr();
108108

109+
/// Creates an import cache without any globally-available importers, and only
110+
/// the passed in importers.
111+
ImportCache.only(Iterable<Importer> importers, {Logger? logger})
112+
: _importers = List.unmodifiable(importers),
113+
_logger = logger ?? const Logger.stderr();
114+
109115
/// Converts the user's [importers], [loadPaths], and [packageConfig]
110116
/// options into a single list of importers.
111117
static List<Importer> _toImporters(Iterable<Importer>? importers,

lib/src/importer/filesystem.dart

+3
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,9 @@ class FilesystemImporter extends Importer {
2222
/// Creates an importer that loads files relative to [loadPath].
2323
FilesystemImporter(String loadPath) : _loadPath = p.absolute(loadPath);
2424

25+
/// Creates an importer relative to the current working directory.
26+
static final cwd = FilesystemImporter('.');
27+
2528
Uri? canonicalize(Uri url) {
2629
if (url.scheme != 'file' && url.scheme != '') return null;
2730
return resolveImportPath(p.join(_loadPath, p.fromUri(url)))

lib/src/importer/js_to_dart/async_file.dart

+5-11
Original file line numberDiff line numberDiff line change
@@ -17,12 +17,6 @@ import '../filesystem.dart';
1717
import '../result.dart';
1818
import '../utils.dart';
1919

20-
/// A filesystem importer to use for most implementation details of
21-
/// [JSToDartAsyncFileImporter].
22-
///
23-
/// This allows us to avoid duplicating logic between the two importers.
24-
final _filesystemImporter = FilesystemImporter('.');
25-
2620
/// A wrapper for a potentially-asynchronous JS API file importer that exposes
2721
/// it as a Dart [AsyncImporter].
2822
final class JSToDartAsyncFileImporter extends AsyncImporter {
@@ -32,7 +26,7 @@ final class JSToDartAsyncFileImporter extends AsyncImporter {
3226
JSToDartAsyncFileImporter(this._findFileUrl);
3327

3428
FutureOr<Uri?> canonicalize(Uri url) async {
35-
if (url.scheme == 'file') return _filesystemImporter.canonicalize(url);
29+
if (url.scheme == 'file') return FilesystemImporter.cwd.canonicalize(url);
3630

3731
var result = wrapJSExceptions(() => _findFileUrl(
3832
url.toString(),
@@ -52,16 +46,16 @@ final class JSToDartAsyncFileImporter extends AsyncImporter {
5246
'"$url".'));
5347
}
5448

55-
return _filesystemImporter.canonicalize(resultUrl);
49+
return FilesystemImporter.cwd.canonicalize(resultUrl);
5650
}
5751

58-
ImporterResult? load(Uri url) => _filesystemImporter.load(url);
52+
ImporterResult? load(Uri url) => FilesystemImporter.cwd.load(url);
5953

6054
DateTime modificationTime(Uri url) =>
61-
_filesystemImporter.modificationTime(url);
55+
FilesystemImporter.cwd.modificationTime(url);
6256

6357
bool couldCanonicalize(Uri url, Uri canonicalUrl) =>
64-
_filesystemImporter.couldCanonicalize(url, canonicalUrl);
58+
FilesystemImporter.cwd.couldCanonicalize(url, canonicalUrl);
6559

6660
bool isNonCanonicalScheme(String scheme) => scheme != 'file';
6761
}

lib/src/importer/js_to_dart/file.dart

+5-11
Original file line numberDiff line numberDiff line change
@@ -12,12 +12,6 @@ import '../../js/utils.dart';
1212
import '../../util/nullable.dart';
1313
import '../utils.dart';
1414

15-
/// A filesystem importer to use for most implementation details of
16-
/// [JSToDartAsyncFileImporter].
17-
///
18-
/// This allows us to avoid duplicating logic between the two importers.
19-
final _filesystemImporter = FilesystemImporter('.');
20-
2115
/// A wrapper for a potentially-asynchronous JS API file importer that exposes
2216
/// it as a Dart [AsyncImporter].
2317
final class JSToDartFileImporter extends Importer {
@@ -27,7 +21,7 @@ final class JSToDartFileImporter extends Importer {
2721
JSToDartFileImporter(this._findFileUrl);
2822

2923
Uri? canonicalize(Uri url) {
30-
if (url.scheme == 'file') return _filesystemImporter.canonicalize(url);
24+
if (url.scheme == 'file') return FilesystemImporter.cwd.canonicalize(url);
3125

3226
var result = wrapJSExceptions(() => _findFileUrl(
3327
url.toString(),
@@ -51,16 +45,16 @@ final class JSToDartFileImporter extends Importer {
5145
'"$url".'));
5246
}
5347

54-
return _filesystemImporter.canonicalize(resultUrl);
48+
return FilesystemImporter.cwd.canonicalize(resultUrl);
5549
}
5650

57-
ImporterResult? load(Uri url) => _filesystemImporter.load(url);
51+
ImporterResult? load(Uri url) => FilesystemImporter.cwd.load(url);
5852

5953
DateTime modificationTime(Uri url) =>
60-
_filesystemImporter.modificationTime(url);
54+
FilesystemImporter.cwd.modificationTime(url);
6155

6256
bool couldCanonicalize(Uri url, Uri canonicalUrl) =>
63-
_filesystemImporter.couldCanonicalize(url, canonicalUrl);
57+
FilesystemImporter.cwd.couldCanonicalize(url, canonicalUrl);
6458

6559
bool isNonCanonicalScheme(String scheme) => scheme != 'file';
6660
}

0 commit comments

Comments
 (0)