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

Cache separate canonical URLs for @use and @import #908

Merged
merged 4 commits into from Jan 2, 2020
Merged

Conversation

jathak
Copy link
Member

@jathak jathak commented Dec 26, 2019

Fixes #899.

The cache for canonical URLs is now keyed on both the rule URL and
whether that URL was canonicalized for an @import rule.

lib/src/async_import_cache.dart Outdated Show resolved Hide resolved
lib/src/importer/utils.dart Outdated Show resolved Hide resolved
@@ -92,14 +93,17 @@ class StylesheetGraph {

/// Returns a map from non-canonicalized imported URLs in [stylesheet], which
Copy link
Contributor

Choose a reason for hiding this comment

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

Document the new map value.

Copy link
Contributor

Choose a reason for hiding this comment

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

It looks like this doc comment still needs to be updated.

@@ -237,8 +242,9 @@ class StylesheetNode {
/// stylesheets those imports refer to.
///
/// This may have `null` values, which indicate failed imports.
Map<Uri, StylesheetNode> get upstream => UnmodifiableMapView(_upstream);
Map<Uri, StylesheetNode> _upstream;
Map<Tuple2<Uri, bool>, StylesheetNode> get upstream =>
Copy link
Contributor

Choose a reason for hiding this comment

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

It's plausible that we'll want to expose this class publicly relatively soon, and I really don't want to have to break this API once we remove imports. WDYT about making upstream refer only to @use and @import, and have a separate upstreamImports field that only contains imports?

Copy link
Member Author

Choose a reason for hiding this comment

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

Yeah, that makes sense. I went back and forth on whether to key on a tuple or just have two maps while I was writing this. Would it make sense to do the same in ImportCache for consistency?

Copy link
Contributor

Choose a reason for hiding this comment

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

Since ImportCache's map isn't part of its public API, I think it's fine to have it stay as tuple-keyed.

@jathak jathak requested a review from nex3 December 27, 2019 23:31
Fixes #899.

The cache for canonical URLs is now keyed on *both* the rule URL and
whether that URL was canonicalized for an `@import` rule.
}
}

node.upstream.forEach(recanonicalize);
forImport = true;
Copy link
Contributor

Choose a reason for hiding this comment

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

Rather than using this as implicit state, I'd just pass it to recanonicalize(). It does mean you'll have to expand those forEach() calls, but I think the clarity of flow is worth it.

for (var upstream in node.upstream.values) {
for (var upstream in {
...node.upstream.values,
...node.upstreamImports.values
Copy link
Contributor

Choose a reason for hiding this comment

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

I'd use Iterable.followedBy() here to avoid copying everything into a set eagerly. There's a possibility we'll visit a file twice, but that seems unlikely and it won't affect the result.

Similar below.

@@ -92,14 +93,17 @@ class StylesheetGraph {

/// Returns a map from non-canonicalized imported URLs in [stylesheet], which
Copy link
Contributor

Choose a reason for hiding this comment

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

It looks like this doc comment still needs to be updated.

///
/// The first is a list of URLs from all `@use` and `@forward` rules in
/// [stylesheet]. The second is a list of all imports in [stylesheet].
Tuple2<List<Uri>, List<DynamicImport>> findDependencies(
Copy link
Contributor

Choose a reason for hiding this comment

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

Why aren't imports represented as Uris as well?

/// A map from non-canonicalized import URLs in [stylesheet] to the
/// stylesheets those imports refer to.
/// A map from non-canonicalized `@use` and `@forward` URLs in [stylesheet] to
/// the stylesheets those rules refer to.
///
/// This may have `null` values, which indicate failed imports.
Copy link
Contributor

Choose a reason for hiding this comment

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

Suggested change
/// This may have `null` values, which indicate failed imports.
/// This may have `null` values, which indicate failed loads.

@jathak
Copy link
Member Author

jathak commented Jan 2, 2020

@nex3: Can you restart the AppVeyor build? I don't think I have permission

@nex3
Copy link
Contributor

nex3 commented Jan 2, 2020

Done.

@jathak jathak requested a review from nex3 January 2, 2020 20:41
@@ -288,8 +288,8 @@ class _Watcher {
var changed = <StylesheetNode>[];
for (var node in _graph.nodes.values) {
var importChanged = false;
for (var url in node.upstream.keys) {
if (_name(p.url.basename(url.path)) != name) continue;
void recanonicalize(Uri url, StylesheetNode upstream, bool forImport) {
Copy link
Contributor

Choose a reason for hiding this comment

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

Nit:

Suggested change
void recanonicalize(Uri url, StylesheetNode upstream, bool forImport) {
void recanonicalize(Uri url, StylesheetNode upstream, {@required bool forImport}) {

This just helps make it clearer at the callsite what the boolean means.

@jathak jathak merged commit 79d9a73 into master Jan 2, 2020
@jathak jathak deleted the cache-fix branch January 2, 2020 23:25
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Incorrect behavior when a stylesheet in a load path is loaded by both @use and @import
2 participants