respect $module
argument to get-function
This commit is contained in:
parent
a03ad51b71
commit
a7325436ca
@ -1,7 +1,5 @@
|
||||
use super::{Builtin, GlobalFunctionMap, GLOBAL_FUNCTIONS};
|
||||
|
||||
use codemap::Spanned;
|
||||
|
||||
use crate::{
|
||||
args::CallArgs,
|
||||
common::{Identifier, QuoteKind},
|
||||
@ -166,7 +164,8 @@ pub(crate) fn get_function(mut args: CallArgs, parser: &mut Parser<'_>) -> SassR
|
||||
}
|
||||
};
|
||||
|
||||
if module.is_some() && css {
|
||||
let func = match if let Some(module_name) = module {
|
||||
if css {
|
||||
return Err((
|
||||
"$css and $module may not both be passed at once.",
|
||||
args.span(),
|
||||
@ -174,13 +173,13 @@ pub(crate) fn get_function(mut args: CallArgs, parser: &mut Parser<'_>) -> SassR
|
||||
.into());
|
||||
}
|
||||
|
||||
let func = match parser.scopes.get_fn(
|
||||
Spanned {
|
||||
node: name,
|
||||
span: args.span(),
|
||||
},
|
||||
parser.global_scope,
|
||||
) {
|
||||
parser
|
||||
.modules
|
||||
.get(module_name.into(), args.span())?
|
||||
.get_fn(name)
|
||||
} else {
|
||||
parser.scopes.get_fn(name, parser.global_scope)
|
||||
} {
|
||||
Some(f) => f,
|
||||
None => match GLOBAL_FUNCTIONS.get(name.as_str()) {
|
||||
Some(f) => SassFunction::Builtin(f.clone(), name),
|
||||
|
@ -32,14 +32,7 @@ fn module_functions(mut args: CallArgs, parser: &mut Parser<'_>) -> SassResult<V
|
||||
};
|
||||
|
||||
Ok(Value::Map(
|
||||
parser
|
||||
.modules
|
||||
.get(&module)
|
||||
.ok_or((
|
||||
format!("There is no module with the namespace \"{}\".", module),
|
||||
args.span(),
|
||||
))?
|
||||
.functions(),
|
||||
parser.modules.get(module.into(), args.span())?.functions(),
|
||||
))
|
||||
}
|
||||
|
||||
@ -58,14 +51,7 @@ fn module_variables(mut args: CallArgs, parser: &mut Parser<'_>) -> SassResult<V
|
||||
};
|
||||
|
||||
Ok(Value::Map(
|
||||
parser
|
||||
.modules
|
||||
.get(&module)
|
||||
.ok_or((
|
||||
format!("There is no module with the namespace \"{}\".", module),
|
||||
args.span(),
|
||||
))?
|
||||
.variables(),
|
||||
parser.modules.get(module.into(), args.span())?.variables(),
|
||||
))
|
||||
}
|
||||
|
||||
|
@ -2,7 +2,7 @@
|
||||
|
||||
use std::collections::BTreeMap;
|
||||
|
||||
use codemap::Spanned;
|
||||
use codemap::{Span, Spanned};
|
||||
|
||||
use crate::{
|
||||
args::CallArgs,
|
||||
@ -26,6 +26,29 @@ mod string;
|
||||
#[derive(Debug, Default)]
|
||||
pub(crate) struct Module(pub Scope);
|
||||
|
||||
#[derive(Debug, Default)]
|
||||
pub(crate) struct Modules(BTreeMap<Identifier, Module>);
|
||||
|
||||
impl Modules {
|
||||
pub fn insert(&mut self, name: Identifier, module: Module) {
|
||||
self.0.insert(name, module);
|
||||
}
|
||||
|
||||
pub fn get(&self, name: Identifier, span: Span) -> SassResult<&Module> {
|
||||
match self.0.get(&name) {
|
||||
Some(v) => Ok(v),
|
||||
None => Err((
|
||||
format!(
|
||||
"There is no module with the namespace \"{}\".",
|
||||
name.as_str()
|
||||
),
|
||||
span,
|
||||
)
|
||||
.into()),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl Module {
|
||||
pub fn get_var(&self, name: Spanned<Identifier>) -> SassResult<&Value> {
|
||||
match self.0.vars.get(&name.node) {
|
||||
|
@ -81,7 +81,7 @@ grass input.scss
|
||||
)]
|
||||
#![cfg_attr(feature = "nightly", feature(track_caller))]
|
||||
#![cfg_attr(feature = "profiling", inline(never))]
|
||||
use std::{collections::HashMap, fs, path::Path};
|
||||
use std::{fs, path::Path};
|
||||
|
||||
#[cfg(feature = "wasm")]
|
||||
use wasm_bindgen::prelude::*;
|
||||
@ -95,6 +95,7 @@ use peekmore::PeekMore;
|
||||
pub use crate::error::{SassError as Error, SassResult as Result};
|
||||
pub(crate) use crate::token::Token;
|
||||
use crate::{
|
||||
builtin::modules::Modules,
|
||||
lexer::Lexer,
|
||||
output::Css,
|
||||
parse::{
|
||||
@ -293,7 +294,7 @@ pub fn from_path(p: &str, options: &Options) -> Result<String> {
|
||||
extender: &mut Extender::new(empty_span),
|
||||
content_scopes: &mut Scopes::new(),
|
||||
options,
|
||||
modules: &mut HashMap::new(),
|
||||
modules: &mut Modules::default(),
|
||||
}
|
||||
.parse()
|
||||
.map_err(|e| raw_to_parse_error(&map, *e, options.unicode_error_messages))?;
|
||||
@ -338,7 +339,7 @@ pub fn from_string(p: String, options: &Options) -> Result<String> {
|
||||
extender: &mut Extender::new(empty_span),
|
||||
content_scopes: &mut Scopes::new(),
|
||||
options,
|
||||
modules: &mut HashMap::new(),
|
||||
modules: &mut Modules::default(),
|
||||
}
|
||||
.parse()
|
||||
.map_err(|e| raw_to_parse_error(&map, *e, options.unicode_error_messages))?;
|
||||
@ -374,7 +375,7 @@ pub fn from_string(p: String) -> std::result::Result<String, JsValue> {
|
||||
extender: &mut Extender::new(empty_span),
|
||||
content_scopes: &mut Scopes::new(),
|
||||
options: &Options::default(),
|
||||
modules: &mut HashMap::new(),
|
||||
modules: &mut Modules::default(),
|
||||
}
|
||||
.parse()
|
||||
.map_err(|e| raw_to_parse_error(&map, *e, true).to_string())?;
|
||||
|
@ -1,4 +1,4 @@
|
||||
use std::{collections::HashMap, convert::TryFrom, fs, path::Path, vec::IntoIter};
|
||||
use std::{convert::TryFrom, fs, path::Path, vec::IntoIter};
|
||||
|
||||
use codemap::{CodeMap, Span, Spanned};
|
||||
use peekmore::{PeekMore, PeekMoreIterator};
|
||||
@ -11,7 +11,7 @@ use crate::{
|
||||
},
|
||||
builtin::modules::{
|
||||
declare_module_color, declare_module_list, declare_module_map, declare_module_math,
|
||||
declare_module_meta, declare_module_selector, declare_module_string, Module,
|
||||
declare_module_meta, declare_module_selector, declare_module_string, Module, Modules,
|
||||
},
|
||||
error::SassResult,
|
||||
lexer::Lexer,
|
||||
@ -92,7 +92,7 @@ pub(crate) struct Parser<'a> {
|
||||
|
||||
pub options: &'a Options<'a>,
|
||||
|
||||
pub modules: &'a mut HashMap<String, Module>,
|
||||
pub modules: &'a mut Modules,
|
||||
}
|
||||
|
||||
impl<'a> Parser<'a> {
|
||||
@ -262,7 +262,7 @@ impl<'a> Parser<'a> {
|
||||
},
|
||||
};
|
||||
|
||||
self.modules.insert(module_name, module);
|
||||
self.modules.insert(module_name.into(), module);
|
||||
}
|
||||
Some(Token { kind: '/', .. }) => {
|
||||
self.toks.next();
|
||||
|
@ -261,14 +261,7 @@ impl<'a> Parser<'a> {
|
||||
|
||||
module_span = module_span.merge(var.span);
|
||||
|
||||
let value = self
|
||||
.modules
|
||||
.get(module)
|
||||
.ok_or((
|
||||
format!("There is no module with the namespace \"{}\".", module),
|
||||
module_span,
|
||||
))?
|
||||
.get_var(var)?;
|
||||
let value = self.modules.get(module.into(), module_span)?.get_var(var)?;
|
||||
HigherIntermediateValue::Literal(value.clone())
|
||||
} else {
|
||||
let fn_name = self
|
||||
@ -277,11 +270,7 @@ impl<'a> Parser<'a> {
|
||||
|
||||
let function = self
|
||||
.modules
|
||||
.get(module)
|
||||
.ok_or((
|
||||
format!("There is no module with the namespace \"{}\".", module),
|
||||
module_span,
|
||||
))?
|
||||
.get(module.into(), module_span)?
|
||||
.get_fn(fn_name.node)
|
||||
.ok_or(("Undefined function.", fn_name.span))?;
|
||||
|
||||
@ -341,13 +330,7 @@ impl<'a> Parser<'a> {
|
||||
}
|
||||
|
||||
let as_ident = Identifier::from(&s);
|
||||
let func = match self.scopes.get_fn(
|
||||
Spanned {
|
||||
node: as_ident,
|
||||
span,
|
||||
},
|
||||
self.global_scope,
|
||||
) {
|
||||
let func = match self.scopes.get_fn(as_ident, self.global_scope) {
|
||||
Some(f) => f,
|
||||
None => {
|
||||
if let Some(f) = GLOBAL_FUNCTIONS.get(as_ident.as_str()) {
|
||||
|
12
src/scope.rs
12
src/scope.rs
@ -230,17 +230,13 @@ impl Scopes {
|
||||
}
|
||||
}
|
||||
|
||||
pub fn get_fn<'a>(
|
||||
&'a self,
|
||||
name: Spanned<Identifier>,
|
||||
global_scope: &'a Scope,
|
||||
) -> Option<SassFunction> {
|
||||
pub fn get_fn<'a>(&'a self, name: Identifier, global_scope: &'a Scope) -> Option<SassFunction> {
|
||||
for scope in self.0.iter().rev() {
|
||||
if scope.fn_exists(name.node) {
|
||||
return scope.get_fn(name.node);
|
||||
if scope.fn_exists(name) {
|
||||
return scope.get_fn(name);
|
||||
}
|
||||
}
|
||||
global_scope.get_fn(name.node)
|
||||
global_scope.get_fn(name)
|
||||
}
|
||||
|
||||
pub fn fn_exists(&self, name: Identifier, global_scope: &Scope) -> bool {
|
||||
|
@ -121,3 +121,8 @@ test!(
|
||||
"a {\n color: call(call(get-function(get-function), darken), red, 10%);\n}\n",
|
||||
"a {\n color: #cc0000;\n}\n"
|
||||
);
|
||||
test!(
|
||||
get_function_of_module,
|
||||
"@use 'sass:math';\na {\n color: call(get-function(cos, $module: math), 2);\n}\n",
|
||||
"a {\n color: -0.4161468365;\n}\n"
|
||||
);
|
||||
|
Loading…
x
Reference in New Issue
Block a user