forked from sass/node-sass
-
Notifications
You must be signed in to change notification settings - Fork 2
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Move misc functions to own compile unit
- clean up definitions of function macros
- Loading branch information
Showing
13 changed files
with
313 additions
and
292 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,252 @@ | ||
#include "ast.hpp" | ||
#include "expand.hpp" | ||
#include "fn_utils.hpp" | ||
#include "fn_miscs.hpp" | ||
#include "debugger.hpp" | ||
|
||
namespace Sass { | ||
|
||
namespace Functions { | ||
|
||
// features | ||
static std::set<std::string> features { | ||
"global-variable-shadowing", | ||
"extend-selector-pseudoclass", | ||
"at-error", | ||
"units-level-3", | ||
"custom-property" | ||
}; | ||
|
||
////////////////////////// | ||
// INTROSPECTION FUNCTIONS | ||
////////////////////////// | ||
|
||
Signature type_of_sig = "type-of($value)"; | ||
BUILT_IN(type_of) | ||
{ | ||
Expression_Ptr v = ARG("$value", Expression); | ||
return SASS_MEMORY_NEW(String_Quoted, pstate, v->type()); | ||
} | ||
|
||
Signature variable_exists_sig = "variable-exists($name)"; | ||
BUILT_IN(variable_exists) | ||
{ | ||
std::string s = Util::normalize_underscores(unquote(ARG("$name", String_Constant)->value())); | ||
|
||
if(d_env.has("$"+s)) { | ||
return SASS_MEMORY_NEW(Boolean, pstate, true); | ||
} | ||
else { | ||
return SASS_MEMORY_NEW(Boolean, pstate, false); | ||
} | ||
} | ||
|
||
Signature global_variable_exists_sig = "global-variable-exists($name)"; | ||
BUILT_IN(global_variable_exists) | ||
{ | ||
std::string s = Util::normalize_underscores(unquote(ARG("$name", String_Constant)->value())); | ||
|
||
if(d_env.has_global("$"+s)) { | ||
return SASS_MEMORY_NEW(Boolean, pstate, true); | ||
} | ||
else { | ||
return SASS_MEMORY_NEW(Boolean, pstate, false); | ||
} | ||
} | ||
|
||
Signature function_exists_sig = "function-exists($name)"; | ||
BUILT_IN(function_exists) | ||
{ | ||
String_Constant_Ptr ss = Cast<String_Constant>(env["$name"]); | ||
if (!ss) { | ||
error("$name: " + (env["$name"]->to_string()) + " is not a string for `function-exists'", pstate, traces); | ||
} | ||
|
||
std::string name = Util::normalize_underscores(unquote(ss->value())); | ||
|
||
if(d_env.has_global(name+"[f]")) { | ||
return SASS_MEMORY_NEW(Boolean, pstate, true); | ||
} | ||
else { | ||
return SASS_MEMORY_NEW(Boolean, pstate, false); | ||
} | ||
} | ||
|
||
Signature mixin_exists_sig = "mixin-exists($name)"; | ||
BUILT_IN(mixin_exists) | ||
{ | ||
std::string s = Util::normalize_underscores(unquote(ARG("$name", String_Constant)->value())); | ||
|
||
if(d_env.has_global(s+"[m]")) { | ||
return SASS_MEMORY_NEW(Boolean, pstate, true); | ||
} | ||
else { | ||
return SASS_MEMORY_NEW(Boolean, pstate, false); | ||
} | ||
} | ||
|
||
Signature feature_exists_sig = "feature-exists($name)"; | ||
BUILT_IN(feature_exists) | ||
{ | ||
std::string s = unquote(ARG("$name", String_Constant)->value()); | ||
|
||
if(features.find(s) == features.end()) { | ||
return SASS_MEMORY_NEW(Boolean, pstate, false); | ||
} | ||
else { | ||
return SASS_MEMORY_NEW(Boolean, pstate, true); | ||
} | ||
} | ||
|
||
Signature call_sig = "call($name, $args...)"; | ||
BUILT_IN(call) | ||
{ | ||
std::string name; | ||
Function_Ptr ff = Cast<Function>(env["$name"]); | ||
String_Constant_Ptr ss = Cast<String_Constant>(env["$name"]); | ||
|
||
if (ss) { | ||
name = Util::normalize_underscores(unquote(ss->value())); | ||
std::cerr << "DEPRECATION WARNING: "; | ||
std::cerr << "Passing a string to call() is deprecated and will be illegal" << std::endl; | ||
std::cerr << "in Sass 4.0. Use call(get-function(" + quote(name) + ")) instead." << std::endl; | ||
std::cerr << std::endl; | ||
} else if (ff) { | ||
name = ff->name(); | ||
} | ||
|
||
List_Obj arglist = SASS_MEMORY_COPY(ARG("$args", List)); | ||
|
||
Arguments_Obj args = SASS_MEMORY_NEW(Arguments, pstate); | ||
// std::string full_name(name + "[f]"); | ||
// Definition_Ptr def = d_env.has(full_name) ? Cast<Definition>((d_env)[full_name]) : 0; | ||
// Parameters_Ptr params = def ? def->parameters() : 0; | ||
// size_t param_size = params ? params->length() : 0; | ||
for (size_t i = 0, L = arglist->length(); i < L; ++i) { | ||
Expression_Obj expr = arglist->value_at_index(i); | ||
// if (params && params->has_rest_parameter()) { | ||
// Parameter_Obj p = param_size > i ? (*params)[i] : 0; | ||
// List_Ptr list = Cast<List>(expr); | ||
// if (list && p && !p->is_rest_parameter()) expr = (*list)[0]; | ||
// } | ||
if (arglist->is_arglist()) { | ||
Expression_Obj obj = arglist->at(i); | ||
Argument_Obj arg = (Argument_Ptr) obj.ptr(); // XXX | ||
args->append(SASS_MEMORY_NEW(Argument, | ||
pstate, | ||
expr, | ||
arg ? arg->name() : "", | ||
arg ? arg->is_rest_argument() : false, | ||
arg ? arg->is_keyword_argument() : false)); | ||
} else { | ||
args->append(SASS_MEMORY_NEW(Argument, pstate, expr)); | ||
} | ||
} | ||
Function_Call_Obj func = SASS_MEMORY_NEW(Function_Call, pstate, name, args); | ||
Expand expand(ctx, &d_env, &selector_stack); | ||
func->via_call(true); // calc invoke is allowed | ||
if (ff) func->func(ff); | ||
return func->perform(&expand.eval); | ||
} | ||
|
||
//////////////////// | ||
// BOOLEAN FUNCTIONS | ||
//////////////////// | ||
|
||
Signature not_sig = "not($value)"; | ||
BUILT_IN(sass_not) | ||
{ | ||
return SASS_MEMORY_NEW(Boolean, pstate, ARG("$value", Expression)->is_false()); | ||
} | ||
|
||
Signature if_sig = "if($condition, $if-true, $if-false)"; | ||
// BUILT_IN(sass_if) | ||
// { return ARG("$condition", Expression)->is_false() ? ARG("$if-false", Expression) : ARG("$if-true", Expression); } | ||
BUILT_IN(sass_if) | ||
{ | ||
Expand expand(ctx, &d_env, &selector_stack); | ||
Expression_Obj cond = ARG("$condition", Expression)->perform(&expand.eval); | ||
bool is_true = !cond->is_false(); | ||
Expression_Obj res = ARG(is_true ? "$if-true" : "$if-false", Expression); | ||
Value_Obj qwe = Cast<Value>(res->perform(&expand.eval)); | ||
// if (qwe == 0) debug_ast(res); | ||
// res = res->perform(&expand.eval.val_eval); | ||
qwe->set_delayed(false); // clone? | ||
return qwe.detach(); | ||
} | ||
|
||
////////////////////////// | ||
// MISCELLANEOUS FUNCTIONS | ||
////////////////////////// | ||
|
||
// value.check_deprecated_interp if value.is_a?(Sass::Script::Value::String) | ||
// unquoted_string(value.to_sass) | ||
|
||
Signature inspect_sig = "inspect($value)"; | ||
BUILT_IN(inspect) | ||
{ | ||
Expression_Ptr v = ARG("$value", Expression); | ||
if (v->concrete_type() == Expression::NULL_VAL) { | ||
return SASS_MEMORY_NEW(String_Quoted, pstate, "null"); | ||
} else if (v->concrete_type() == Expression::BOOLEAN && v->is_false()) { | ||
return SASS_MEMORY_NEW(String_Quoted, pstate, "false"); | ||
} else if (v->concrete_type() == Expression::STRING) { | ||
return Cast<String>(v); | ||
} else { | ||
// ToDo: fix to_sass for nested parentheses | ||
Sass_Output_Style old_style; | ||
old_style = ctx.c_options.output_style; | ||
ctx.c_options.output_style = TO_SASS; | ||
Emitter emitter(ctx.c_options); | ||
Inspect i(emitter); | ||
i.in_declaration = false; | ||
v->perform(&i); | ||
ctx.c_options.output_style = old_style; | ||
return SASS_MEMORY_NEW(String_Quoted, pstate, i.get_buffer()); | ||
} | ||
// return v; | ||
} | ||
|
||
Signature content_exists_sig = "content-exists()"; | ||
BUILT_IN(content_exists) | ||
{ | ||
if (!d_env.has_global("is_in_mixin")) { | ||
error("Cannot call content-exists() except within a mixin.", pstate, traces); | ||
} | ||
return SASS_MEMORY_NEW(Boolean, pstate, d_env.has_lexical("@content[m]")); | ||
} | ||
|
||
Signature get_function_sig = "get-function($name, $css: false)"; | ||
BUILT_IN(get_function) | ||
{ | ||
String_Constant_Ptr ss = Cast<String_Constant>(env["$name"]); | ||
if (!ss) { | ||
error("$name: " + (env["$name"]->to_string()) + " is not a string for `get-function'", pstate, traces); | ||
} | ||
|
||
std::string name = Util::normalize_underscores(unquote(ss->value())); | ||
std::string full_name = name + "[f]"; | ||
|
||
Boolean_Obj css = ARG("$css", Boolean); | ||
if (!css->is_false()) { | ||
Definition_Ptr def = SASS_MEMORY_NEW(Definition, | ||
pstate, | ||
name, | ||
SASS_MEMORY_NEW(Parameters, pstate), | ||
SASS_MEMORY_NEW(Block, pstate, 0, false), | ||
Definition::FUNCTION); | ||
return SASS_MEMORY_NEW(Function, pstate, def, true); | ||
} | ||
|
||
|
||
if (!d_env.has_global(full_name)) { | ||
error("Function not found: " + name, pstate, traces); | ||
} | ||
|
||
Definition_Ptr def = Cast<Definition>(d_env[full_name]); | ||
return SASS_MEMORY_NEW(Function, pstate, def, false); | ||
} | ||
|
||
} | ||
|
||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,40 @@ | ||
#ifndef SASS_FN_MISCS_H | ||
#define SASS_FN_MISCS_H | ||
|
||
#include "fn_utils.hpp" | ||
|
||
namespace Sass { | ||
|
||
namespace Functions { | ||
|
||
extern Signature type_of_sig; | ||
extern Signature variable_exists_sig; | ||
extern Signature global_variable_exists_sig; | ||
extern Signature function_exists_sig; | ||
extern Signature mixin_exists_sig; | ||
extern Signature feature_exists_sig; | ||
extern Signature call_sig; | ||
extern Signature not_sig; | ||
extern Signature if_sig; | ||
extern Signature set_nth_sig; | ||
extern Signature content_exists_sig; | ||
extern Signature get_function_sig; | ||
|
||
BUILT_IN(type_of); | ||
BUILT_IN(variable_exists); | ||
BUILT_IN(global_variable_exists); | ||
BUILT_IN(function_exists); | ||
BUILT_IN(mixin_exists); | ||
BUILT_IN(feature_exists); | ||
BUILT_IN(call); | ||
BUILT_IN(sass_not); | ||
BUILT_IN(sass_if); | ||
BUILT_IN(set_nth); | ||
BUILT_IN(content_exists); | ||
BUILT_IN(get_function); | ||
|
||
} | ||
|
||
} | ||
|
||
#endif |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.