Add new module-system features for existing functions (#720)

This commit is contained in:
Natalie Weizenbaum 2019-06-18 12:03:12 -07:00 committed by GitHub
parent 6600de2dfe
commit 4716349a0e
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
9 changed files with 100 additions and 27 deletions

View File

@ -1,3 +1,10 @@
## 1.22.0
### Dart API
* Add a `Value.realNull` getter, which returns Dart's `null` if the value is
Sass's null.
## 1.21.0
### Dart API

View File

@ -403,7 +403,13 @@ class AsyncEnvironment {
bool variableExists(String name) => getVariable(name) != null;
/// Returns whether a global variable named [name] exists.
bool globalVariableExists(String name) {
///
/// Throws a [SassScriptException] if there is no module named [namespace], or
/// if multiple global modules expose functions named [name].
bool globalVariableExists(String name, {String namespace}) {
if (namespace != null) {
return _getModule(namespace).variables.containsKey(name);
}
if (_variables.first.containsKey(name)) return true;
return _getVariableFromGlobalModule(name) != null;
}
@ -536,7 +542,11 @@ class AsyncEnvironment {
}
/// Returns whether a function named [name] exists.
bool functionExists(String name) => getFunction(name) != null;
///
/// Throws a [SassScriptException] if there is no module named [namespace], or
/// if multiple global modules expose functions named [name].
bool functionExists(String name, {String namespace}) =>
getFunction(name, namespace: namespace) != null;
/// Sets the variable named [name] to [value] in the current scope.
void setFunction(AsyncCallable callable) {
@ -581,7 +591,11 @@ class AsyncEnvironment {
}
/// Returns whether a mixin named [name] exists.
bool mixinExists(String name) => getMixin(name) != null;
///
/// Throws a [SassScriptException] if there is no module named [namespace], or
/// if multiple global modules expose functions named [name].
bool mixinExists(String name, {String namespace}) =>
getMixin(name, namespace: namespace) != null;
/// Sets the variable named [name] to [value] in the current scope.
void setMixin(AsyncCallable callable) {

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: c1515ac728ab32d953e902e2608f1cc97411e57d
// Checksum: 9037d898096d2eb998be8f01a65739ee34bec024
//
// ignore_for_file: unused_import
@ -408,7 +408,13 @@ class Environment {
bool variableExists(String name) => getVariable(name) != null;
/// Returns whether a global variable named [name] exists.
bool globalVariableExists(String name) {
///
/// Throws a [SassScriptException] if there is no module named [namespace], or
/// if multiple global modules expose functions named [name].
bool globalVariableExists(String name, {String namespace}) {
if (namespace != null) {
return _getModule(namespace).variables.containsKey(name);
}
if (_variables.first.containsKey(name)) return true;
return _getVariableFromGlobalModule(name) != null;
}
@ -541,7 +547,11 @@ class Environment {
}
/// Returns whether a function named [name] exists.
bool functionExists(String name) => getFunction(name) != null;
///
/// Throws a [SassScriptException] if there is no module named [namespace], or
/// if multiple global modules expose functions named [name].
bool functionExists(String name, {String namespace}) =>
getFunction(name, namespace: namespace) != null;
/// Sets the variable named [name] to [value] in the current scope.
void setFunction(Callable callable) {
@ -586,7 +596,11 @@ class Environment {
}
/// Returns whether a mixin named [name] exists.
bool mixinExists(String name) => getMixin(name) != null;
///
/// Throws a [SassScriptException] if there is no module named [namespace], or
/// if multiple global modules expose functions named [name].
bool mixinExists(String name, {String namespace}) =>
getMixin(name, namespace: namespace) != null;
/// Sets the variable named [name] to [value] in the current scope.
void setMixin(Callable callable) {

View File

@ -62,6 +62,10 @@ abstract class Value implements ext.Value {
/// these arguments are passed in.
bool get isVar => false;
/// Returns Dart's `null` value if this is [sassNull], and returns [this]
/// otherwise.
Value get realNull => this;
const Value();
/// Calls the appropriate visit method on [visitor].

View File

@ -61,6 +61,10 @@ abstract class Value {
/// and all other values count as single-value lists.
List<Value> get asList;
/// Returns Dart's `null` value if this is [sassNull], and returns [this]
/// otherwise.
Value get realNull;
/// Converts [sassIndex] into a Dart-style index into the list returned by
/// [asList].
///

View File

@ -16,6 +16,8 @@ class SassNull extends Value {
bool get isBlank => true;
Value get realNull => null;
const SassNull._();
T accept<T>(ValueVisitor<T> visitor) => visitor.visitNull(this);

View File

@ -253,9 +253,12 @@ class _EvaluateVisitor
var metaFunctions = [
// These functions are defined in the context of the evaluator because
// they need access to the [_environment] or other local state.
BuiltInCallable("global-variable-exists", r"$name", (arguments) {
BuiltInCallable("global-variable-exists", r"$name, $module: null",
(arguments) {
var variable = arguments[0].assertString("name");
return SassBoolean(_environment.globalVariableExists(variable.text));
var module = arguments[1].realNull?.assertString("module");
return SassBoolean(_environment.globalVariableExists(variable.text,
namespace: module?.text));
}),
BuiltInCallable("variable-exists", r"$name", (arguments) {
@ -263,15 +266,19 @@ class _EvaluateVisitor
return SassBoolean(_environment.variableExists(variable.text));
}),
BuiltInCallable("function-exists", r"$name", (arguments) {
BuiltInCallable("function-exists", r"$name, $module: null", (arguments) {
var variable = arguments[0].assertString("name");
return SassBoolean(_environment.functionExists(variable.text) ||
var module = arguments[1].realNull?.assertString("module");
return SassBoolean(_environment.functionExists(variable.text,
namespace: module?.text) ||
_builtInFunctions.containsKey(variable.text));
}),
BuiltInCallable("mixin-exists", r"$name", (arguments) {
BuiltInCallable("mixin-exists", r"$name, $module: null", (arguments) {
var variable = arguments[0].assertString("name");
return SassBoolean(_environment.mixinExists(variable.text));
var module = arguments[1].realNull?.assertString("module");
return SassBoolean(
_environment.mixinExists(variable.text, namespace: module?.text));
}),
BuiltInCallable("content-exists", "", (arguments) {
@ -282,16 +289,23 @@ class _EvaluateVisitor
return SassBoolean(_environment.content != null);
}),
BuiltInCallable("get-function", r"$name, $css: false", (arguments) {
BuiltInCallable("get-function", r"$name, $css: false, $module: null",
(arguments) {
var name = arguments[0].assertString("name");
var css = arguments[1].isTruthy;
var module = arguments[2].realNull?.assertString("module");
if (css && module != null) {
throw r"$css and $module may not both be passed at once.";
}
var callable = css
? PlainCssCallable(name.text)
: _addExceptionSpan(_callableNode, () => _getFunction(name.text));
: _addExceptionSpan(_callableNode,
() => _getFunction(name.text, namespace: module?.text));
if (callable != null) return SassFunction(callable);
throw SassScriptException("Function not found: $name");
throw "Function not found: $name";
}),
AsyncBuiltInCallable("call", r"$function, $args...", (arguments) async {

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: 948db9d9efe2ed5572ecc0d2763817a56df88bd6
// Checksum: f6dcd674164d13633df1359d5a4cfc215f3a3469
//
// ignore_for_file: unused_import
@ -261,9 +261,12 @@ class _EvaluateVisitor
var metaFunctions = [
// These functions are defined in the context of the evaluator because
// they need access to the [_environment] or other local state.
BuiltInCallable("global-variable-exists", r"$name", (arguments) {
BuiltInCallable("global-variable-exists", r"$name, $module: null",
(arguments) {
var variable = arguments[0].assertString("name");
return SassBoolean(_environment.globalVariableExists(variable.text));
var module = arguments[1].realNull?.assertString("module");
return SassBoolean(_environment.globalVariableExists(variable.text,
namespace: module?.text));
}),
BuiltInCallable("variable-exists", r"$name", (arguments) {
@ -271,15 +274,19 @@ class _EvaluateVisitor
return SassBoolean(_environment.variableExists(variable.text));
}),
BuiltInCallable("function-exists", r"$name", (arguments) {
BuiltInCallable("function-exists", r"$name, $module: null", (arguments) {
var variable = arguments[0].assertString("name");
return SassBoolean(_environment.functionExists(variable.text) ||
var module = arguments[1].realNull?.assertString("module");
return SassBoolean(_environment.functionExists(variable.text,
namespace: module?.text) ||
_builtInFunctions.containsKey(variable.text));
}),
BuiltInCallable("mixin-exists", r"$name", (arguments) {
BuiltInCallable("mixin-exists", r"$name, $module: null", (arguments) {
var variable = arguments[0].assertString("name");
return SassBoolean(_environment.mixinExists(variable.text));
var module = arguments[1].realNull?.assertString("module");
return SassBoolean(
_environment.mixinExists(variable.text, namespace: module?.text));
}),
BuiltInCallable("content-exists", "", (arguments) {
@ -290,16 +297,23 @@ class _EvaluateVisitor
return SassBoolean(_environment.content != null);
}),
BuiltInCallable("get-function", r"$name, $css: false", (arguments) {
BuiltInCallable("get-function", r"$name, $css: false, $module: null",
(arguments) {
var name = arguments[0].assertString("name");
var css = arguments[1].isTruthy;
var module = arguments[2].realNull?.assertString("module");
if (css && module != null) {
throw r"$css and $module may not both be passed at once.";
}
var callable = css
? PlainCssCallable(name.text)
: _addExceptionSpan(_callableNode, () => _getFunction(name.text));
: _addExceptionSpan(_callableNode,
() => _getFunction(name.text, namespace: module?.text));
if (callable != null) return SassFunction(callable);
throw SassScriptException("Function not found: $name");
throw "Function not found: $name";
}),
BuiltInCallable("call", r"$function, $args...", (arguments) {

View File

@ -1,5 +1,5 @@
name: sass
version: 1.21.0
version: 1.22.0-dev
description: A Sass implementation in Dart.
author: Dart Team <misc@dartlang.org>
homepage: https://github.com/sass/dart-sass