Indicate the original configuration location for multi-config errors

This commit is contained in:
Natalie Weizenbaum 2020-01-11 00:12:38 -08:00
parent c2baede4db
commit d67f341a17
5 changed files with 48 additions and 19 deletions

View File

@ -799,7 +799,7 @@ class AsyncEnvironment {
configuration[name] = ConfiguredValue(values[name], null, nodes[name]);
}
}
return Configuration(configuration, isImplicit: true);
return Configuration.implicit(configuration);
}
/// Returns a module that represents the top-level members defined in [this],

View File

@ -4,6 +4,7 @@
import 'dart:collection';
import 'ast/node.dart';
import 'ast/sass.dart';
import 'configured_value.dart';
import 'util/limited_map_view.dart';
@ -19,6 +20,11 @@ class Configuration {
Map<String, ConfiguredValue> get values => UnmodifiableMapView(_values);
final Map<String, ConfiguredValue> _values;
/// The node whose span indicates where the configuration was declared.
///
/// This is `null` for implicit configurations.
final AstNode nodeWithSpan;
/// Whether or not this configuration is implicit.
///
/// Implicit configurations are created when a file containing a `@forward`
@ -31,8 +37,18 @@ class Configuration {
/// silently ignored in this case.
final bool isImplicit;
Configuration(Map<String, ConfiguredValue> values, {this.isImplicit = false})
: _values = values;
/// Creates an explicit configuration with the given [values].
Configuration(Map<String, ConfiguredValue> values, this.nodeWithSpan)
: _values = values,
isImplicit = false;
/// Creates an implicit configuration with the given [values].
///
/// See [isImplicit] for details.
Configuration.implicit(Map<String, ConfiguredValue> values)
: _values = values,
nodeWithSpan = null,
isImplicit = true;
/// The empty configuration, which indicates that the module has not been
/// configured.
@ -41,6 +57,7 @@ class Configuration {
/// ignored if the module has already been loaded.
const Configuration.empty()
: _values = const {},
nodeWithSpan = null,
isImplicit = true;
bool get isEmpty => values.isEmpty;
@ -67,6 +84,8 @@ class Configuration {
} else if (forward.hiddenVariables?.isNotEmpty ?? false) {
newValues = LimitedMapView.blocklist(newValues, forward.hiddenVariables);
}
return Configuration(newValues, isImplicit: isImplicit);
return isImplicit
? Configuration.implicit(newValues)
: Configuration(newValues, nodeWithSpan);
}
}

View File

@ -5,7 +5,7 @@
// DO NOT EDIT. This file was generated from async_environment.dart.
// See tool/grind/synchronize.dart for details.
//
// Checksum: 6e375d7e8ccaafe80c33ec5a220bc4acf5dbc3d0
// Checksum: e0f39c1b98cb2adf98116bd51bf03d492be953c3
//
// ignore_for_file: unused_import
@ -804,7 +804,7 @@ class Environment {
configuration[name] = ConfiguredValue(values[name], null, nodes[name]);
}
}
return Configuration(configuration, isImplicit: true);
return Configuration.implicit(configuration);
}
/// Returns a module that represents the top-level members defined in [this],

View File

@ -437,7 +437,7 @@ class _EvaluateVisitor
values[name] = ConfiguredValue(value, span);
});
configuration = Configuration(values);
configuration = Configuration(values, _callableNode);
}
await _loadModule(url, "load-css()", _callableNode,
@ -625,10 +625,15 @@ class _EvaluateVisitor
"\"with\".";
var existingNode = _moduleNodes[url];
throw existingNode == null
var secondarySpans = {
if (existingNode != null) existingNode.span: "original load",
if (configuration == null)
_configuration.nodeWithSpan.span: "configuration"
};
throw secondarySpans.isEmpty
? _exception(message)
: _multiSpanException(
message, "new load", {existingNode.span: "original load"});
: _multiSpanException(message, "new load", secondarySpans);
}
return alreadyLoaded;
@ -1274,7 +1279,7 @@ class _EvaluateVisitor
_expressionNode(variable.expression));
}
return Configuration(newValues);
return Configuration(newValues, node);
}
/// Remove configured values from [upstream] that have been removed from
@ -1876,7 +1881,7 @@ class _EvaluateVisitor
(await variable.expression.accept(this)).withoutSlash(),
variable.span,
_expressionNode(variable.expression))
});
}, node);
await _loadModule(node.url, "@use", node, (module) {
_environment.addModule(module, node, namespace: node.namespace);

View File

@ -5,7 +5,7 @@
// DO NOT EDIT. This file was generated from async_evaluate.dart.
// See tool/grind/synchronize.dart for details.
//
// Checksum: b2a6756fe0f47ed5aec3b92b74f021198d7a770a
// Checksum: eb095e782e2983223945d189caadc649b081a676
//
// ignore_for_file: unused_import
@ -442,7 +442,7 @@ class _EvaluateVisitor
values[name] = ConfiguredValue(value, span);
});
configuration = Configuration(values);
configuration = Configuration(values, _callableNode);
}
_loadModule(url, "load-css()", _callableNode,
@ -628,10 +628,15 @@ class _EvaluateVisitor
"\"with\".";
var existingNode = _moduleNodes[url];
throw existingNode == null
var secondarySpans = {
if (existingNode != null) existingNode.span: "original load",
if (configuration == null)
_configuration.nodeWithSpan.span: "configuration"
};
throw secondarySpans.isEmpty
? _exception(message)
: _multiSpanException(
message, "new load", {existingNode.span: "original load"});
: _multiSpanException(message, "new load", secondarySpans);
}
return alreadyLoaded;
@ -1272,7 +1277,7 @@ class _EvaluateVisitor
_expressionNode(variable.expression));
}
return Configuration(newValues);
return Configuration(newValues, node);
}
/// Remove configured values from [upstream] that have been removed from
@ -1866,7 +1871,7 @@ class _EvaluateVisitor
variable.expression.accept(this).withoutSlash(),
variable.span,
_expressionNode(variable.expression))
});
}, node);
_loadModule(node.url, "@use", node, (module) {
_environment.addModule(module, node, namespace: node.namespace);