Skip to content

Commit

Permalink
[Package Importer] Dart Implementation (sass#2130)
Browse files Browse the repository at this point in the history
Co-authored-by: Jonny Gerig Meyer <jonny@oddbird.net>
  • Loading branch information
2 people authored and Ludwig Meysel committed Feb 20, 2024
1 parent 13cdd84 commit 7007621
Show file tree
Hide file tree
Showing 23 changed files with 512 additions and 69 deletions.
9 changes: 5 additions & 4 deletions lib/src/async_compile.dart
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,8 @@ import 'visitor/serialize.dart';
/// Like [compileAsync] in `lib/sass.dart`, but provides more options to support
/// the node-sass compatible API and the executable.
///
/// At most one of `importCache` and `nodeImporter` may be provided at once.
/// If both `importCache` and `nodeImporter` are provided, the importers in
/// `importCache` will be evaluated before `nodeImporter`.
Future<CompileResult> compileAsync(String path,
{Syntax? syntax,
Logger? logger,
Expand Down Expand Up @@ -56,7 +57,7 @@ Future<CompileResult> compileAsync(String path,
(syntax == null || syntax == Syntax.forPath(path))) {
importCache ??= AsyncImportCache.none(logger: logger);
stylesheet = (await importCache.importCanonical(
FilesystemImporter('.'), p.toUri(canonicalize(path)),
FilesystemImporter.cwd, p.toUri(canonicalize(path)),
originalUrl: p.toUri(path)))!;
} else {
stylesheet = Stylesheet.parse(
Expand All @@ -69,7 +70,7 @@ Future<CompileResult> compileAsync(String path,
logger,
importCache,
nodeImporter,
FilesystemImporter('.'),
FilesystemImporter.cwd,
functions,
style,
useSpaces,
Expand Down Expand Up @@ -121,7 +122,7 @@ Future<CompileResult> compileStringAsync(String source,
logger,
importCache,
nodeImporter,
importer ?? (isBrowser ? NoOpImporter() : FilesystemImporter('.')),
importer ?? (isBrowser ? NoOpImporter() : FilesystemImporter.cwd),
functions,
style,
useSpaces,
Expand Down
6 changes: 6 additions & 0 deletions lib/src/async_import_cache.dart
Original file line number Diff line number Diff line change
Expand Up @@ -104,6 +104,12 @@ final class AsyncImportCache {
: _importers = const [],
_logger = logger ?? const Logger.stderr();

/// Creates an import cache without any globally-available importers, and only
/// the passed in importers.
AsyncImportCache.only(Iterable<AsyncImporter> importers, {Logger? logger})
: _importers = List.unmodifiable(importers),
_logger = logger ?? const Logger.stderr();

/// Converts the user's [importers], [loadPaths], and [packageConfig]
/// options into a single list of importers.
static List<AsyncImporter> _toImporters(Iterable<AsyncImporter>? importers,
Expand Down
11 changes: 6 additions & 5 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: 5178e366228bde7854df12221393857bb3022628
// Checksum: a9421a2975e79ad591ae32474cd076e1379d0e75
//
// ignore_for_file: unused_import

Expand Down Expand Up @@ -35,7 +35,8 @@ import 'visitor/serialize.dart';
/// Like [compile] in `lib/sass.dart`, but provides more options to support
/// the node-sass compatible API and the executable.
///
/// At most one of `importCache` and `nodeImporter` may be provided at once.
/// If both `importCache` and `nodeImporter` are provided, the importers in
/// `importCache` will be evaluated before `nodeImporter`.
CompileResult compile(String path,
{Syntax? syntax,
Logger? logger,
Expand Down Expand Up @@ -65,7 +66,7 @@ CompileResult compile(String path,
(syntax == null || syntax == Syntax.forPath(path))) {
importCache ??= ImportCache.none(logger: logger);
stylesheet = importCache.importCanonical(
FilesystemImporter('.'), p.toUri(canonicalize(path)),
FilesystemImporter.cwd, p.toUri(canonicalize(path)),
originalUrl: p.toUri(path))!;
} else {
stylesheet = Stylesheet.parse(
Expand All @@ -78,7 +79,7 @@ CompileResult compile(String path,
logger,
importCache,
nodeImporter,
FilesystemImporter('.'),
FilesystemImporter.cwd,
functions,
style,
useSpaces,
Expand Down Expand Up @@ -130,7 +131,7 @@ CompileResult compileString(String source,
logger,
importCache,
nodeImporter,
importer ?? (isBrowser ? NoOpImporter() : FilesystemImporter('.')),
importer ?? (isBrowser ? NoOpImporter() : FilesystemImporter.cwd),
functions,
style,
useSpaces,
Expand Down
5 changes: 5 additions & 0 deletions lib/src/embedded/compilation_dispatcher.dart
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ import 'package:native_synchronization/mailbox.dart';
import 'package:path/path.dart' as p;
import 'package:protobuf/protobuf.dart';
import 'package:sass/sass.dart' as sass;
import 'package:sass/src/importer/node_package.dart' as npi;

import '../logger.dart';
import '../value/function.dart';
Expand Down Expand Up @@ -226,6 +227,10 @@ final class CompilationDispatcher {
case InboundMessage_CompileRequest_Importer_Importer.notSet:
_checkNoNonCanonicalScheme(importer);
return null;

case InboundMessage_CompileRequest_Importer_Importer.nodePackageImporter:
return npi.NodePackageImporter(
importer.nodePackageImporter.entryPointDirectory);
}
}

Expand Down
12 changes: 3 additions & 9 deletions lib/src/embedded/importer/file.dart
Original file line number Diff line number Diff line change
Expand Up @@ -6,12 +6,6 @@ import '../../importer.dart';
import '../embedded_sass.pb.dart' hide SourceSpan;
import 'base.dart';

/// A filesystem importer to use for most implementation details of
/// [FileImporter].
///
/// This allows us to avoid duplicating logic between the two importers.
final _filesystemImporter = FilesystemImporter('.');

/// An importer that asks the host to resolve imports in a simplified,
/// file-system-centric way.
final class FileImporter extends ImporterBase {
Expand All @@ -21,7 +15,7 @@ final class FileImporter extends ImporterBase {
FileImporter(super.dispatcher, this._importerId);

Uri? canonicalize(Uri url) {
if (url.scheme == 'file') return _filesystemImporter.canonicalize(url);
if (url.scheme == 'file') return FilesystemImporter.cwd.canonicalize(url);

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

return _filesystemImporter.canonicalize(url);
return FilesystemImporter.cwd.canonicalize(url);

case InboundMessage_FileImportResponse_Result.error:
throw response.error;
Expand All @@ -49,7 +43,7 @@ final class FileImporter extends ImporterBase {
}
}

ImporterResult? load(Uri url) => _filesystemImporter.load(url);
ImporterResult? load(Uri url) => FilesystemImporter.cwd.load(url);

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

Expand Down
6 changes: 3 additions & 3 deletions lib/src/executable/compile_stylesheet.dart
Original file line number Diff line number Diff line change
Expand Up @@ -69,7 +69,7 @@ Future<(int, String, String?)?> compileStylesheet(ExecutableOptions options,
Future<void> _compileStylesheetWithoutErrorHandling(ExecutableOptions options,
StylesheetGraph graph, String? source, String? destination,
{bool ifModified = false}) async {
var importer = FilesystemImporter('.');
var importer = FilesystemImporter.cwd;
if (ifModified) {
try {
if (source != null &&
Expand Down Expand Up @@ -103,7 +103,7 @@ Future<void> _compileStylesheetWithoutErrorHandling(ExecutableOptions options,
syntax: syntax,
logger: options.logger,
importCache: importCache,
importer: FilesystemImporter('.'),
importer: FilesystemImporter.cwd,
style: options.style,
quietDeps: options.quietDeps,
verbose: options.verbose,
Expand All @@ -128,7 +128,7 @@ Future<void> _compileStylesheetWithoutErrorHandling(ExecutableOptions options,
syntax: syntax,
logger: options.logger,
importCache: graph.importCache,
importer: FilesystemImporter('.'),
importer: FilesystemImporter.cwd,
style: options.style,
quietDeps: options.quietDeps,
verbose: options.verbose,
Expand Down
2 changes: 1 addition & 1 deletion lib/src/executable/repl.dart
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ Future<void> repl(ExecutableOptions options) async {
var repl = Repl(prompt: '>> ');
var logger = TrackingLogger(options.logger);
var evaluator = Evaluator(
importer: FilesystemImporter('.'),
importer: FilesystemImporter.cwd,
importCache: ImportCache(loadPaths: options.loadPaths, logger: logger),
logger: logger);
await for (String line in repl.runAsync()) {
Expand Down
6 changes: 3 additions & 3 deletions lib/src/executable/watch.dart
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ Future<void> watch(ExecutableOptions options, StylesheetGraph graph) async {
var sourcesToDestinations = _sourcesToDestinations(options);
for (var source in sourcesToDestinations.keys) {
graph.addCanonical(
FilesystemImporter('.'), p.toUri(canonicalize(source)), p.toUri(source),
FilesystemImporter.cwd, p.toUri(canonicalize(source)), p.toUri(source),
recanonicalize: false);
}
var success = await compileStylesheets(options, graph, sourcesToDestinations,
Expand Down Expand Up @@ -130,7 +130,7 @@ final class _Watcher {
await compileStylesheets(_options, _graph, {path: destination},
ifModified: true);
var downstream = _graph.addCanonical(
FilesystemImporter('.'), _canonicalize(path), p.toUri(path));
FilesystemImporter.cwd, _canonicalize(path), p.toUri(path));
return await _recompileDownstream(downstream) && success;
}

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

var downstream = _graph.remove(FilesystemImporter('.'), url);
var downstream = _graph.remove(FilesystemImporter.cwd, url);
return await _recompileDownstream(downstream);
}

Expand Down
8 changes: 7 additions & 1 deletion lib/src/import_cache.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_import_cache.dart.
// See tool/grind/synchronize.dart for details.
//
// Checksum: 342e907cf10e1dd80d7045fc32db43c74376654e
// Checksum: d157b83599dbc07a80ac6cb5ffdf5dde03b60376
//
// ignore_for_file: unused_import

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

/// Creates an import cache without any globally-available importers, and only
/// the passed in importers.
ImportCache.only(Iterable<Importer> importers, {Logger? logger})
: _importers = List.unmodifiable(importers),
_logger = logger ?? const Logger.stderr();

/// Converts the user's [importers], [loadPaths], and [packageConfig]
/// options into a single list of importers.
static List<Importer> _toImporters(Iterable<Importer>? importers,
Expand Down
3 changes: 3 additions & 0 deletions lib/src/importer/filesystem.dart
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,9 @@ class FilesystemImporter extends Importer {
/// Creates an importer that loads files relative to [loadPath].
FilesystemImporter(String loadPath) : _loadPath = p.absolute(loadPath);

/// Creates an importer relative to the current working directory.
static final cwd = FilesystemImporter('.');

Uri? canonicalize(Uri url) {
if (url.scheme != 'file' && url.scheme != '') return null;
return resolveImportPath(p.join(_loadPath, p.fromUri(url)))
Expand Down
16 changes: 5 additions & 11 deletions lib/src/importer/js_to_dart/async_file.dart
Original file line number Diff line number Diff line change
Expand Up @@ -17,12 +17,6 @@ import '../filesystem.dart';
import '../result.dart';
import '../utils.dart';

/// A filesystem importer to use for most implementation details of
/// [JSToDartAsyncFileImporter].
///
/// This allows us to avoid duplicating logic between the two importers.
final _filesystemImporter = FilesystemImporter('.');

/// A wrapper for a potentially-asynchronous JS API file importer that exposes
/// it as a Dart [AsyncImporter].
final class JSToDartAsyncFileImporter extends AsyncImporter {
Expand All @@ -32,7 +26,7 @@ final class JSToDartAsyncFileImporter extends AsyncImporter {
JSToDartAsyncFileImporter(this._findFileUrl);

FutureOr<Uri?> canonicalize(Uri url) async {
if (url.scheme == 'file') return _filesystemImporter.canonicalize(url);
if (url.scheme == 'file') return FilesystemImporter.cwd.canonicalize(url);

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

return _filesystemImporter.canonicalize(resultUrl);
return FilesystemImporter.cwd.canonicalize(resultUrl);
}

ImporterResult? load(Uri url) => _filesystemImporter.load(url);
ImporterResult? load(Uri url) => FilesystemImporter.cwd.load(url);

DateTime modificationTime(Uri url) =>
_filesystemImporter.modificationTime(url);
FilesystemImporter.cwd.modificationTime(url);

bool couldCanonicalize(Uri url, Uri canonicalUrl) =>
_filesystemImporter.couldCanonicalize(url, canonicalUrl);
FilesystemImporter.cwd.couldCanonicalize(url, canonicalUrl);

bool isNonCanonicalScheme(String scheme) => scheme != 'file';
}
16 changes: 5 additions & 11 deletions lib/src/importer/js_to_dart/file.dart
Original file line number Diff line number Diff line change
Expand Up @@ -12,12 +12,6 @@ import '../../js/utils.dart';
import '../../util/nullable.dart';
import '../utils.dart';

/// A filesystem importer to use for most implementation details of
/// [JSToDartAsyncFileImporter].
///
/// This allows us to avoid duplicating logic between the two importers.
final _filesystemImporter = FilesystemImporter('.');

/// A wrapper for a potentially-asynchronous JS API file importer that exposes
/// it as a Dart [AsyncImporter].
final class JSToDartFileImporter extends Importer {
Expand All @@ -27,7 +21,7 @@ final class JSToDartFileImporter extends Importer {
JSToDartFileImporter(this._findFileUrl);

Uri? canonicalize(Uri url) {
if (url.scheme == 'file') return _filesystemImporter.canonicalize(url);
if (url.scheme == 'file') return FilesystemImporter.cwd.canonicalize(url);

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

return _filesystemImporter.canonicalize(resultUrl);
return FilesystemImporter.cwd.canonicalize(resultUrl);
}

ImporterResult? load(Uri url) => _filesystemImporter.load(url);
ImporterResult? load(Uri url) => FilesystemImporter.cwd.load(url);

DateTime modificationTime(Uri url) =>
_filesystemImporter.modificationTime(url);
FilesystemImporter.cwd.modificationTime(url);

bool couldCanonicalize(Uri url, Uri canonicalUrl) =>
_filesystemImporter.couldCanonicalize(url, canonicalUrl);
FilesystemImporter.cwd.couldCanonicalize(url, canonicalUrl);

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

0 comments on commit 7007621

Please sign in to comment.