mirror of
https://github.com/bitwarden/help
synced 2025-12-27 05:33:14 +00:00
Promote to Master (#748)
* initial commit
* adding quotes for the array error
* Create Gemfile
* Create Gemfile.lock
* add .nvmrc and .node-version
* removed /article from URL
* update links to work with netlify
* more fixed links
* link fixes
* update bad links
* Update netlify.toml
toml test for redirects
* article redirect
* link fixes
* Update index.html
* Update netlify.toml
* Update _config.yml
* Update netlify.toml
* Update netlify.toml
* Update netlify.toml
* Update netlify.toml
* Update netlify.toml
* add article back into URL for launch
* Update netlify.toml
* Update netlify.toml
* add order to categories front matter
* Update netlify.toml
* update
* sidemenu update
* Revert "sidemenu update"
This reverts commit 5441c3d35c.
* update order prop
* Navbar updates per Gary and compiler warnings
* font/style tweaks
* Update sidebar.html
* Stage Release Documentation (#739)
* initial drafts
* rewrite Custom Fields article to prioritize new context-menu option & better organize ancillary information
* edit
* edit
* Custom Field Context Menu & CAPTCHA item in release notes
* SSO relink event
* update rn
* small edits
* improve release notes titles
* fix side menu
* Edits courtest of mportune!
* update order
* link fixes
* link cleanup
* image updates and a link
* fix trailing slash
Co-authored-by: DanHillesheim <79476558+DanHillesheim@users.noreply.github.com>
This commit is contained in:
committed by
GitHub
parent
63f78e8979
commit
906e2ca0dd
1
vendor/bundle/ruby/2.6.0/gems/sassc-2.4.0/ext/libsass/VERSION
vendored
Normal file
1
vendor/bundle/ruby/2.6.0/gems/sassc-2.4.0/ext/libsass/VERSION
vendored
Normal file
@@ -0,0 +1 @@
|
||||
3.6.4
|
||||
60
vendor/bundle/ruby/2.6.0/gems/sassc-2.4.0/ext/libsass/contrib/plugin.cpp
vendored
Normal file
60
vendor/bundle/ruby/2.6.0/gems/sassc-2.4.0/ext/libsass/contrib/plugin.cpp
vendored
Normal file
@@ -0,0 +1,60 @@
|
||||
#include <cstring>
|
||||
#include <iostream>
|
||||
#include <stdint.h>
|
||||
#include <sass.h>
|
||||
|
||||
// gcc: g++ -shared plugin.cpp -o plugin.so -fPIC -Llib -lsass
|
||||
// mingw: g++ -shared plugin.cpp -o plugin.dll -Llib -lsass
|
||||
|
||||
extern "C" const char* ADDCALL libsass_get_version() {
|
||||
return libsass_version();
|
||||
}
|
||||
|
||||
union Sass_Value* custom_function(const union Sass_Value* s_args, Sass_Function_Entry cb, struct Sass_Compiler* comp)
|
||||
{
|
||||
// get context/option struct associated with this compiler
|
||||
struct Sass_Context* ctx = sass_compiler_get_context(comp);
|
||||
struct Sass_Options* opts = sass_compiler_get_options(comp);
|
||||
// get the cookie from function descriptor
|
||||
void* cookie = sass_function_get_cookie(cb);
|
||||
// we actually abuse the void* to store an "int"
|
||||
return sass_make_number((intptr_t)cookie, "px");
|
||||
}
|
||||
|
||||
extern "C" Sass_Function_List ADDCALL libsass_load_functions()
|
||||
{
|
||||
// allocate a custom function caller
|
||||
Sass_Function_Entry c_func =
|
||||
sass_make_function("foo()", custom_function, (void*)42);
|
||||
// create list of all custom functions
|
||||
Sass_Function_List fn_list = sass_make_function_list(1);
|
||||
// put the only function in this plugin to the list
|
||||
sass_function_set_list_entry(fn_list, 0, c_func);
|
||||
// return the list
|
||||
return fn_list;
|
||||
}
|
||||
|
||||
Sass_Import_List custom_importer(const char* cur_path, Sass_Importer_Entry cb, struct Sass_Compiler* comp)
|
||||
{
|
||||
// get the cookie from importer descriptor
|
||||
void* cookie = sass_importer_get_cookie(cb);
|
||||
// create a list to hold our import entries
|
||||
Sass_Import_List incs = sass_make_import_list(1);
|
||||
// create our only import entry (route path back)
|
||||
incs[0] = sass_make_import_entry(cur_path, 0, 0);
|
||||
// return imports
|
||||
return incs;
|
||||
}
|
||||
|
||||
extern "C" Sass_Importer_List ADDCALL libsass_load_importers()
|
||||
{
|
||||
// allocate a custom function caller
|
||||
Sass_Importer_Entry c_imp =
|
||||
sass_make_importer(custom_importer, - 99, (void*)42);
|
||||
// create list of all custom functions
|
||||
Sass_Importer_List imp_list = sass_make_importer_list(1);
|
||||
// put the only function in this plugin to the list
|
||||
sass_importer_set_list_entry(imp_list, 0, c_imp);
|
||||
// return the list
|
||||
return imp_list;
|
||||
}
|
||||
15
vendor/bundle/ruby/2.6.0/gems/sassc-2.4.0/ext/libsass/include/sass.h
vendored
Normal file
15
vendor/bundle/ruby/2.6.0/gems/sassc-2.4.0/ext/libsass/include/sass.h
vendored
Normal file
@@ -0,0 +1,15 @@
|
||||
#ifndef SASS_H
|
||||
#define SASS_H
|
||||
|
||||
// #define DEBUG 1
|
||||
|
||||
// include API headers
|
||||
#include <sass/base.h>
|
||||
#include <sass/version.h>
|
||||
#include <sass/values.h>
|
||||
#include <sass/functions.h>
|
||||
#include <sass/context.h>
|
||||
#include <sass2scss.h>
|
||||
|
||||
#endif
|
||||
|
||||
97
vendor/bundle/ruby/2.6.0/gems/sassc-2.4.0/ext/libsass/include/sass/base.h
vendored
Normal file
97
vendor/bundle/ruby/2.6.0/gems/sassc-2.4.0/ext/libsass/include/sass/base.h
vendored
Normal file
@@ -0,0 +1,97 @@
|
||||
#ifndef SASS_BASE_H
|
||||
#define SASS_BASE_H
|
||||
|
||||
// #define DEBUG
|
||||
// #define DEBUG_SHARED_PTR
|
||||
|
||||
#ifdef _MSC_VER
|
||||
#pragma warning(disable : 4503)
|
||||
#ifndef _SCL_SECURE_NO_WARNINGS
|
||||
#define _SCL_SECURE_NO_WARNINGS
|
||||
#endif
|
||||
#ifndef _CRT_SECURE_NO_WARNINGS
|
||||
#define _CRT_SECURE_NO_WARNINGS
|
||||
#endif
|
||||
#ifndef _CRT_NONSTDC_NO_DEPRECATE
|
||||
#define _CRT_NONSTDC_NO_DEPRECATE
|
||||
#endif
|
||||
#endif
|
||||
|
||||
// Work around lack of `noexcept` keyword support in VS2013
|
||||
#if defined(_MSC_VER) && (_MSC_VER <= 1800) && !defined(_ALLOW_KEYWORD_MACROS)
|
||||
#define _ALLOW_KEYWORD_MACROS 1
|
||||
#define noexcept throw( )
|
||||
#endif
|
||||
|
||||
#include <stddef.h>
|
||||
#include <stdbool.h>
|
||||
|
||||
#ifdef __GNUC__
|
||||
#define DEPRECATED(func) func __attribute__ ((deprecated))
|
||||
#elif defined(_MSC_VER)
|
||||
#define DEPRECATED(func) __declspec(deprecated) func
|
||||
#else
|
||||
#pragma message("WARNING: You need to implement DEPRECATED for this compiler")
|
||||
#define DEPRECATED(func) func
|
||||
#endif
|
||||
|
||||
#ifdef _WIN32
|
||||
|
||||
/* You should define ADD_EXPORTS *only* when building the DLL. */
|
||||
#ifdef ADD_EXPORTS
|
||||
#define ADDAPI __declspec(dllexport)
|
||||
#define ADDCALL __cdecl
|
||||
#else
|
||||
#define ADDAPI
|
||||
#define ADDCALL
|
||||
#endif
|
||||
|
||||
#else /* _WIN32 not defined. */
|
||||
|
||||
/* Define with no value on non-Windows OSes. */
|
||||
#define ADDAPI
|
||||
#define ADDCALL
|
||||
|
||||
#endif
|
||||
|
||||
/* Make sure functions are exported with C linkage under C++ compilers. */
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
|
||||
// Different render styles
|
||||
enum Sass_Output_Style {
|
||||
SASS_STYLE_NESTED,
|
||||
SASS_STYLE_EXPANDED,
|
||||
SASS_STYLE_COMPACT,
|
||||
SASS_STYLE_COMPRESSED,
|
||||
// only used internaly
|
||||
SASS_STYLE_INSPECT,
|
||||
SASS_STYLE_TO_SASS,
|
||||
SASS_STYLE_TO_CSS
|
||||
};
|
||||
|
||||
// to allocate buffer to be filled
|
||||
ADDAPI void* ADDCALL sass_alloc_memory(size_t size);
|
||||
// to allocate a buffer from existing string
|
||||
ADDAPI char* ADDCALL sass_copy_c_string(const char* str);
|
||||
// to free overtaken memory when done
|
||||
ADDAPI void ADDCALL sass_free_memory(void* ptr);
|
||||
|
||||
// Some convenient string helper function
|
||||
ADDAPI char* ADDCALL sass_string_quote (const char* str, const char quote_mark);
|
||||
ADDAPI char* ADDCALL sass_string_unquote (const char* str);
|
||||
|
||||
// Implemented sass language version
|
||||
// Hardcoded version 3.4 for time being
|
||||
ADDAPI const char* ADDCALL libsass_version(void);
|
||||
|
||||
// Get compiled libsass language
|
||||
ADDAPI const char* ADDCALL libsass_language_version(void);
|
||||
|
||||
#ifdef __cplusplus
|
||||
} // __cplusplus defined.
|
||||
#endif
|
||||
|
||||
#endif
|
||||
174
vendor/bundle/ruby/2.6.0/gems/sassc-2.4.0/ext/libsass/include/sass/context.h
vendored
Normal file
174
vendor/bundle/ruby/2.6.0/gems/sassc-2.4.0/ext/libsass/include/sass/context.h
vendored
Normal file
@@ -0,0 +1,174 @@
|
||||
#ifndef SASS_C_CONTEXT_H
|
||||
#define SASS_C_CONTEXT_H
|
||||
|
||||
#include <stddef.h>
|
||||
#include <stdbool.h>
|
||||
#include <sass/base.h>
|
||||
#include <sass/values.h>
|
||||
#include <sass/functions.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
|
||||
// Forward declaration
|
||||
struct Sass_Compiler;
|
||||
|
||||
// Forward declaration
|
||||
struct Sass_Options; // base struct
|
||||
struct Sass_Context; // : Sass_Options
|
||||
struct Sass_File_Context; // : Sass_Context
|
||||
struct Sass_Data_Context; // : Sass_Context
|
||||
|
||||
// Compiler states
|
||||
enum Sass_Compiler_State {
|
||||
SASS_COMPILER_CREATED,
|
||||
SASS_COMPILER_PARSED,
|
||||
SASS_COMPILER_EXECUTED
|
||||
};
|
||||
|
||||
// Create and initialize an option struct
|
||||
ADDAPI struct Sass_Options* ADDCALL sass_make_options (void);
|
||||
// Create and initialize a specific context
|
||||
ADDAPI struct Sass_File_Context* ADDCALL sass_make_file_context (const char* input_path);
|
||||
ADDAPI struct Sass_Data_Context* ADDCALL sass_make_data_context (char* source_string);
|
||||
|
||||
// Call the compilation step for the specific context
|
||||
ADDAPI int ADDCALL sass_compile_file_context (struct Sass_File_Context* ctx);
|
||||
ADDAPI int ADDCALL sass_compile_data_context (struct Sass_Data_Context* ctx);
|
||||
|
||||
// Create a sass compiler instance for more control
|
||||
ADDAPI struct Sass_Compiler* ADDCALL sass_make_file_compiler (struct Sass_File_Context* file_ctx);
|
||||
ADDAPI struct Sass_Compiler* ADDCALL sass_make_data_compiler (struct Sass_Data_Context* data_ctx);
|
||||
|
||||
// Execute the different compilation steps individually
|
||||
// Useful if you only want to query the included files
|
||||
ADDAPI int ADDCALL sass_compiler_parse(struct Sass_Compiler* compiler);
|
||||
ADDAPI int ADDCALL sass_compiler_execute(struct Sass_Compiler* compiler);
|
||||
|
||||
// Release all memory allocated with the compiler
|
||||
// This does _not_ include any contexts or options
|
||||
ADDAPI void ADDCALL sass_delete_compiler(struct Sass_Compiler* compiler);
|
||||
ADDAPI void ADDCALL sass_delete_options(struct Sass_Options* options);
|
||||
|
||||
// Release all memory allocated and also ourself
|
||||
ADDAPI void ADDCALL sass_delete_file_context (struct Sass_File_Context* ctx);
|
||||
ADDAPI void ADDCALL sass_delete_data_context (struct Sass_Data_Context* ctx);
|
||||
|
||||
// Getters for context from specific implementation
|
||||
ADDAPI struct Sass_Context* ADDCALL sass_file_context_get_context (struct Sass_File_Context* file_ctx);
|
||||
ADDAPI struct Sass_Context* ADDCALL sass_data_context_get_context (struct Sass_Data_Context* data_ctx);
|
||||
|
||||
// Getters for Context_Options from Sass_Context
|
||||
ADDAPI struct Sass_Options* ADDCALL sass_context_get_options (struct Sass_Context* ctx);
|
||||
ADDAPI struct Sass_Options* ADDCALL sass_file_context_get_options (struct Sass_File_Context* file_ctx);
|
||||
ADDAPI struct Sass_Options* ADDCALL sass_data_context_get_options (struct Sass_Data_Context* data_ctx);
|
||||
ADDAPI void ADDCALL sass_file_context_set_options (struct Sass_File_Context* file_ctx, struct Sass_Options* opt);
|
||||
ADDAPI void ADDCALL sass_data_context_set_options (struct Sass_Data_Context* data_ctx, struct Sass_Options* opt);
|
||||
|
||||
|
||||
// Getters for Context_Option values
|
||||
ADDAPI int ADDCALL sass_option_get_precision (struct Sass_Options* options);
|
||||
ADDAPI enum Sass_Output_Style ADDCALL sass_option_get_output_style (struct Sass_Options* options);
|
||||
ADDAPI bool ADDCALL sass_option_get_source_comments (struct Sass_Options* options);
|
||||
ADDAPI bool ADDCALL sass_option_get_source_map_embed (struct Sass_Options* options);
|
||||
ADDAPI bool ADDCALL sass_option_get_source_map_contents (struct Sass_Options* options);
|
||||
ADDAPI bool ADDCALL sass_option_get_source_map_file_urls (struct Sass_Options* options);
|
||||
ADDAPI bool ADDCALL sass_option_get_omit_source_map_url (struct Sass_Options* options);
|
||||
ADDAPI bool ADDCALL sass_option_get_is_indented_syntax_src (struct Sass_Options* options);
|
||||
ADDAPI const char* ADDCALL sass_option_get_indent (struct Sass_Options* options);
|
||||
ADDAPI const char* ADDCALL sass_option_get_linefeed (struct Sass_Options* options);
|
||||
ADDAPI const char* ADDCALL sass_option_get_input_path (struct Sass_Options* options);
|
||||
ADDAPI const char* ADDCALL sass_option_get_output_path (struct Sass_Options* options);
|
||||
ADDAPI const char* ADDCALL sass_option_get_source_map_file (struct Sass_Options* options);
|
||||
ADDAPI const char* ADDCALL sass_option_get_source_map_root (struct Sass_Options* options);
|
||||
ADDAPI Sass_Importer_List ADDCALL sass_option_get_c_headers (struct Sass_Options* options);
|
||||
ADDAPI Sass_Importer_List ADDCALL sass_option_get_c_importers (struct Sass_Options* options);
|
||||
ADDAPI Sass_Function_List ADDCALL sass_option_get_c_functions (struct Sass_Options* options);
|
||||
|
||||
// Setters for Context_Option values
|
||||
ADDAPI void ADDCALL sass_option_set_precision (struct Sass_Options* options, int precision);
|
||||
ADDAPI void ADDCALL sass_option_set_output_style (struct Sass_Options* options, enum Sass_Output_Style output_style);
|
||||
ADDAPI void ADDCALL sass_option_set_source_comments (struct Sass_Options* options, bool source_comments);
|
||||
ADDAPI void ADDCALL sass_option_set_source_map_embed (struct Sass_Options* options, bool source_map_embed);
|
||||
ADDAPI void ADDCALL sass_option_set_source_map_contents (struct Sass_Options* options, bool source_map_contents);
|
||||
ADDAPI void ADDCALL sass_option_set_source_map_file_urls (struct Sass_Options* options, bool source_map_file_urls);
|
||||
ADDAPI void ADDCALL sass_option_set_omit_source_map_url (struct Sass_Options* options, bool omit_source_map_url);
|
||||
ADDAPI void ADDCALL sass_option_set_is_indented_syntax_src (struct Sass_Options* options, bool is_indented_syntax_src);
|
||||
ADDAPI void ADDCALL sass_option_set_indent (struct Sass_Options* options, const char* indent);
|
||||
ADDAPI void ADDCALL sass_option_set_linefeed (struct Sass_Options* options, const char* linefeed);
|
||||
ADDAPI void ADDCALL sass_option_set_input_path (struct Sass_Options* options, const char* input_path);
|
||||
ADDAPI void ADDCALL sass_option_set_output_path (struct Sass_Options* options, const char* output_path);
|
||||
ADDAPI void ADDCALL sass_option_set_plugin_path (struct Sass_Options* options, const char* plugin_path);
|
||||
ADDAPI void ADDCALL sass_option_set_include_path (struct Sass_Options* options, const char* include_path);
|
||||
ADDAPI void ADDCALL sass_option_set_source_map_file (struct Sass_Options* options, const char* source_map_file);
|
||||
ADDAPI void ADDCALL sass_option_set_source_map_root (struct Sass_Options* options, const char* source_map_root);
|
||||
ADDAPI void ADDCALL sass_option_set_c_headers (struct Sass_Options* options, Sass_Importer_List c_headers);
|
||||
ADDAPI void ADDCALL sass_option_set_c_importers (struct Sass_Options* options, Sass_Importer_List c_importers);
|
||||
ADDAPI void ADDCALL sass_option_set_c_functions (struct Sass_Options* options, Sass_Function_List c_functions);
|
||||
|
||||
|
||||
// Getters for Sass_Context values
|
||||
ADDAPI const char* ADDCALL sass_context_get_output_string (struct Sass_Context* ctx);
|
||||
ADDAPI int ADDCALL sass_context_get_error_status (struct Sass_Context* ctx);
|
||||
ADDAPI const char* ADDCALL sass_context_get_error_json (struct Sass_Context* ctx);
|
||||
ADDAPI const char* ADDCALL sass_context_get_error_text (struct Sass_Context* ctx);
|
||||
ADDAPI const char* ADDCALL sass_context_get_error_message (struct Sass_Context* ctx);
|
||||
ADDAPI const char* ADDCALL sass_context_get_error_file (struct Sass_Context* ctx);
|
||||
ADDAPI const char* ADDCALL sass_context_get_error_src (struct Sass_Context* ctx);
|
||||
ADDAPI size_t ADDCALL sass_context_get_error_line (struct Sass_Context* ctx);
|
||||
ADDAPI size_t ADDCALL sass_context_get_error_column (struct Sass_Context* ctx);
|
||||
ADDAPI const char* ADDCALL sass_context_get_source_map_string (struct Sass_Context* ctx);
|
||||
ADDAPI char** ADDCALL sass_context_get_included_files (struct Sass_Context* ctx);
|
||||
|
||||
// Getters for options include path array
|
||||
ADDAPI size_t ADDCALL sass_option_get_include_path_size(struct Sass_Options* options);
|
||||
ADDAPI const char* ADDCALL sass_option_get_include_path(struct Sass_Options* options, size_t i);
|
||||
// Plugin paths to load dynamic libraries work the same
|
||||
ADDAPI size_t ADDCALL sass_option_get_plugin_path_size(struct Sass_Options* options);
|
||||
ADDAPI const char* ADDCALL sass_option_get_plugin_path(struct Sass_Options* options, size_t i);
|
||||
|
||||
// Calculate the size of the stored null terminated array
|
||||
ADDAPI size_t ADDCALL sass_context_get_included_files_size (struct Sass_Context* ctx);
|
||||
|
||||
// Take ownership of memory (value on context is set to 0)
|
||||
ADDAPI char* ADDCALL sass_context_take_error_json (struct Sass_Context* ctx);
|
||||
ADDAPI char* ADDCALL sass_context_take_error_text (struct Sass_Context* ctx);
|
||||
ADDAPI char* ADDCALL sass_context_take_error_message (struct Sass_Context* ctx);
|
||||
ADDAPI char* ADDCALL sass_context_take_error_file (struct Sass_Context* ctx);
|
||||
ADDAPI char* ADDCALL sass_context_take_error_src (struct Sass_Context* ctx);
|
||||
ADDAPI char* ADDCALL sass_context_take_output_string (struct Sass_Context* ctx);
|
||||
ADDAPI char* ADDCALL sass_context_take_source_map_string (struct Sass_Context* ctx);
|
||||
ADDAPI char** ADDCALL sass_context_take_included_files (struct Sass_Context* ctx);
|
||||
|
||||
// Getters for Sass_Compiler options
|
||||
ADDAPI enum Sass_Compiler_State ADDCALL sass_compiler_get_state(struct Sass_Compiler* compiler);
|
||||
ADDAPI struct Sass_Context* ADDCALL sass_compiler_get_context(struct Sass_Compiler* compiler);
|
||||
ADDAPI struct Sass_Options* ADDCALL sass_compiler_get_options(struct Sass_Compiler* compiler);
|
||||
ADDAPI size_t ADDCALL sass_compiler_get_import_stack_size(struct Sass_Compiler* compiler);
|
||||
ADDAPI Sass_Import_Entry ADDCALL sass_compiler_get_last_import(struct Sass_Compiler* compiler);
|
||||
ADDAPI Sass_Import_Entry ADDCALL sass_compiler_get_import_entry(struct Sass_Compiler* compiler, size_t idx);
|
||||
ADDAPI size_t ADDCALL sass_compiler_get_callee_stack_size(struct Sass_Compiler* compiler);
|
||||
ADDAPI Sass_Callee_Entry ADDCALL sass_compiler_get_last_callee(struct Sass_Compiler* compiler);
|
||||
ADDAPI Sass_Callee_Entry ADDCALL sass_compiler_get_callee_entry(struct Sass_Compiler* compiler, size_t idx);
|
||||
|
||||
// Push function for paths (no manipulation support for now)
|
||||
ADDAPI void ADDCALL sass_option_push_plugin_path (struct Sass_Options* options, const char* path);
|
||||
ADDAPI void ADDCALL sass_option_push_include_path (struct Sass_Options* options, const char* path);
|
||||
|
||||
// Resolve a file via the given include paths in the sass option struct
|
||||
// find_file looks for the exact file name while find_include does a regular sass include
|
||||
ADDAPI char* ADDCALL sass_find_file (const char* path, struct Sass_Options* opt);
|
||||
ADDAPI char* ADDCALL sass_find_include (const char* path, struct Sass_Options* opt);
|
||||
|
||||
// Resolve a file relative to last import or include paths in the sass option struct
|
||||
// find_file looks for the exact file name while find_include does a regular sass include
|
||||
ADDAPI char* ADDCALL sass_compiler_find_file (const char* path, struct Sass_Compiler* compiler);
|
||||
ADDAPI char* ADDCALL sass_compiler_find_include (const char* path, struct Sass_Compiler* compiler);
|
||||
|
||||
#ifdef __cplusplus
|
||||
} // __cplusplus defined.
|
||||
#endif
|
||||
|
||||
#endif
|
||||
139
vendor/bundle/ruby/2.6.0/gems/sassc-2.4.0/ext/libsass/include/sass/functions.h
vendored
Normal file
139
vendor/bundle/ruby/2.6.0/gems/sassc-2.4.0/ext/libsass/include/sass/functions.h
vendored
Normal file
@@ -0,0 +1,139 @@
|
||||
#ifndef SASS_C_FUNCTIONS_H
|
||||
#define SASS_C_FUNCTIONS_H
|
||||
|
||||
#include <stddef.h>
|
||||
#include <stdbool.h>
|
||||
#include <sass/base.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
|
||||
// Forward declaration
|
||||
struct Sass_Env;
|
||||
struct Sass_Callee;
|
||||
struct Sass_Import;
|
||||
struct Sass_Options;
|
||||
struct Sass_Compiler;
|
||||
struct Sass_Importer;
|
||||
struct Sass_Function;
|
||||
|
||||
// Typedef helpers for callee lists
|
||||
typedef struct Sass_Env (*Sass_Env_Frame);
|
||||
// Typedef helpers for callee lists
|
||||
typedef struct Sass_Callee (*Sass_Callee_Entry);
|
||||
// Typedef helpers for import lists
|
||||
typedef struct Sass_Import (*Sass_Import_Entry);
|
||||
typedef struct Sass_Import* (*Sass_Import_List);
|
||||
// Typedef helpers for custom importer lists
|
||||
typedef struct Sass_Importer (*Sass_Importer_Entry);
|
||||
typedef struct Sass_Importer* (*Sass_Importer_List);
|
||||
// Typedef defining importer signature and return type
|
||||
typedef Sass_Import_List (*Sass_Importer_Fn)
|
||||
(const char* url, Sass_Importer_Entry cb, struct Sass_Compiler* compiler);
|
||||
|
||||
// Typedef helpers for custom functions lists
|
||||
typedef struct Sass_Function (*Sass_Function_Entry);
|
||||
typedef struct Sass_Function* (*Sass_Function_List);
|
||||
// Typedef defining function signature and return type
|
||||
typedef union Sass_Value* (*Sass_Function_Fn)
|
||||
(const union Sass_Value*, Sass_Function_Entry cb, struct Sass_Compiler* compiler);
|
||||
|
||||
// Type of function calls
|
||||
enum Sass_Callee_Type {
|
||||
SASS_CALLEE_MIXIN,
|
||||
SASS_CALLEE_FUNCTION,
|
||||
SASS_CALLEE_C_FUNCTION,
|
||||
};
|
||||
|
||||
// Creator for sass custom importer return argument list
|
||||
ADDAPI Sass_Importer_List ADDCALL sass_make_importer_list (size_t length);
|
||||
ADDAPI Sass_Importer_Entry ADDCALL sass_importer_get_list_entry (Sass_Importer_List list, size_t idx);
|
||||
ADDAPI void ADDCALL sass_importer_set_list_entry (Sass_Importer_List list, size_t idx, Sass_Importer_Entry entry);
|
||||
ADDAPI void ADDCALL sass_delete_importer_list (Sass_Importer_List list);
|
||||
|
||||
|
||||
// Creators for custom importer callback (with some additional pointer)
|
||||
// The pointer is mostly used to store the callback into the actual binding
|
||||
ADDAPI Sass_Importer_Entry ADDCALL sass_make_importer (Sass_Importer_Fn importer, double priority, void* cookie);
|
||||
|
||||
// Getters for import function descriptors
|
||||
ADDAPI Sass_Importer_Fn ADDCALL sass_importer_get_function (Sass_Importer_Entry cb);
|
||||
ADDAPI double ADDCALL sass_importer_get_priority (Sass_Importer_Entry cb);
|
||||
ADDAPI void* ADDCALL sass_importer_get_cookie (Sass_Importer_Entry cb);
|
||||
|
||||
// Deallocator for associated memory
|
||||
ADDAPI void ADDCALL sass_delete_importer (Sass_Importer_Entry cb);
|
||||
|
||||
// Creator for sass custom importer return argument list
|
||||
ADDAPI Sass_Import_List ADDCALL sass_make_import_list (size_t length);
|
||||
// Creator for a single import entry returned by the custom importer inside the list
|
||||
ADDAPI Sass_Import_Entry ADDCALL sass_make_import_entry (const char* path, char* source, char* srcmap);
|
||||
ADDAPI Sass_Import_Entry ADDCALL sass_make_import (const char* imp_path, const char* abs_base, char* source, char* srcmap);
|
||||
// set error message to abort import and to print out a message (path from existing object is used in output)
|
||||
ADDAPI Sass_Import_Entry ADDCALL sass_import_set_error(Sass_Import_Entry import, const char* message, size_t line, size_t col);
|
||||
|
||||
// Setters to insert an entry into the import list (you may also use [] access directly)
|
||||
// Since we are dealing with pointers they should have a guaranteed and fixed size
|
||||
ADDAPI void ADDCALL sass_import_set_list_entry (Sass_Import_List list, size_t idx, Sass_Import_Entry entry);
|
||||
ADDAPI Sass_Import_Entry ADDCALL sass_import_get_list_entry (Sass_Import_List list, size_t idx);
|
||||
|
||||
// Getters for callee entry
|
||||
ADDAPI const char* ADDCALL sass_callee_get_name (Sass_Callee_Entry);
|
||||
ADDAPI const char* ADDCALL sass_callee_get_path (Sass_Callee_Entry);
|
||||
ADDAPI size_t ADDCALL sass_callee_get_line (Sass_Callee_Entry);
|
||||
ADDAPI size_t ADDCALL sass_callee_get_column (Sass_Callee_Entry);
|
||||
ADDAPI enum Sass_Callee_Type ADDCALL sass_callee_get_type (Sass_Callee_Entry);
|
||||
ADDAPI Sass_Env_Frame ADDCALL sass_callee_get_env (Sass_Callee_Entry);
|
||||
|
||||
// Getters and Setters for environments (lexical, local and global)
|
||||
ADDAPI union Sass_Value* ADDCALL sass_env_get_lexical (Sass_Env_Frame, const char*);
|
||||
ADDAPI void ADDCALL sass_env_set_lexical (Sass_Env_Frame, const char*, union Sass_Value*);
|
||||
ADDAPI union Sass_Value* ADDCALL sass_env_get_local (Sass_Env_Frame, const char*);
|
||||
ADDAPI void ADDCALL sass_env_set_local (Sass_Env_Frame, const char*, union Sass_Value*);
|
||||
ADDAPI union Sass_Value* ADDCALL sass_env_get_global (Sass_Env_Frame, const char*);
|
||||
ADDAPI void ADDCALL sass_env_set_global (Sass_Env_Frame, const char*, union Sass_Value*);
|
||||
|
||||
// Getters for import entry
|
||||
ADDAPI const char* ADDCALL sass_import_get_imp_path (Sass_Import_Entry);
|
||||
ADDAPI const char* ADDCALL sass_import_get_abs_path (Sass_Import_Entry);
|
||||
ADDAPI const char* ADDCALL sass_import_get_source (Sass_Import_Entry);
|
||||
ADDAPI const char* ADDCALL sass_import_get_srcmap (Sass_Import_Entry);
|
||||
// Explicit functions to take ownership of these items
|
||||
// The property on our struct will be reset to NULL
|
||||
ADDAPI char* ADDCALL sass_import_take_source (Sass_Import_Entry);
|
||||
ADDAPI char* ADDCALL sass_import_take_srcmap (Sass_Import_Entry);
|
||||
// Getters from import error entry
|
||||
ADDAPI size_t ADDCALL sass_import_get_error_line (Sass_Import_Entry);
|
||||
ADDAPI size_t ADDCALL sass_import_get_error_column (Sass_Import_Entry);
|
||||
ADDAPI const char* ADDCALL sass_import_get_error_message (Sass_Import_Entry);
|
||||
|
||||
// Deallocator for associated memory (incl. entries)
|
||||
ADDAPI void ADDCALL sass_delete_import_list (Sass_Import_List);
|
||||
// Just in case we have some stray import structs
|
||||
ADDAPI void ADDCALL sass_delete_import (Sass_Import_Entry);
|
||||
|
||||
|
||||
|
||||
// Creators for sass function list and function descriptors
|
||||
ADDAPI Sass_Function_List ADDCALL sass_make_function_list (size_t length);
|
||||
ADDAPI Sass_Function_Entry ADDCALL sass_make_function (const char* signature, Sass_Function_Fn cb, void* cookie);
|
||||
ADDAPI void ADDCALL sass_delete_function (Sass_Function_Entry entry);
|
||||
ADDAPI void ADDCALL sass_delete_function_list (Sass_Function_List list);
|
||||
|
||||
// Setters and getters for callbacks on function lists
|
||||
ADDAPI Sass_Function_Entry ADDCALL sass_function_get_list_entry(Sass_Function_List list, size_t pos);
|
||||
ADDAPI void ADDCALL sass_function_set_list_entry(Sass_Function_List list, size_t pos, Sass_Function_Entry cb);
|
||||
|
||||
// Getters for custom function descriptors
|
||||
ADDAPI const char* ADDCALL sass_function_get_signature (Sass_Function_Entry cb);
|
||||
ADDAPI Sass_Function_Fn ADDCALL sass_function_get_function (Sass_Function_Entry cb);
|
||||
ADDAPI void* ADDCALL sass_function_get_cookie (Sass_Function_Entry cb);
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
} // __cplusplus defined.
|
||||
#endif
|
||||
|
||||
#endif
|
||||
145
vendor/bundle/ruby/2.6.0/gems/sassc-2.4.0/ext/libsass/include/sass/values.h
vendored
Normal file
145
vendor/bundle/ruby/2.6.0/gems/sassc-2.4.0/ext/libsass/include/sass/values.h
vendored
Normal file
@@ -0,0 +1,145 @@
|
||||
#ifndef SASS_C_VALUES_H
|
||||
#define SASS_C_VALUES_H
|
||||
|
||||
#include <stddef.h>
|
||||
#include <stdbool.h>
|
||||
#include <sass/base.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
|
||||
// Forward declaration
|
||||
union Sass_Value;
|
||||
|
||||
// Type for Sass values
|
||||
enum Sass_Tag {
|
||||
SASS_BOOLEAN,
|
||||
SASS_NUMBER,
|
||||
SASS_COLOR,
|
||||
SASS_STRING,
|
||||
SASS_LIST,
|
||||
SASS_MAP,
|
||||
SASS_NULL,
|
||||
SASS_ERROR,
|
||||
SASS_WARNING
|
||||
};
|
||||
|
||||
// Tags for denoting Sass list separators
|
||||
enum Sass_Separator {
|
||||
SASS_COMMA,
|
||||
SASS_SPACE,
|
||||
// only used internally to represent a hash map before evaluation
|
||||
// otherwise we would be too early to check for duplicate keys
|
||||
SASS_HASH
|
||||
};
|
||||
|
||||
// Value Operators
|
||||
enum Sass_OP {
|
||||
AND, OR, // logical connectives
|
||||
EQ, NEQ, GT, GTE, LT, LTE, // arithmetic relations
|
||||
ADD, SUB, MUL, DIV, MOD, // arithmetic functions
|
||||
NUM_OPS // so we know how big to make the op table
|
||||
};
|
||||
|
||||
// Creator functions for all value types
|
||||
ADDAPI union Sass_Value* ADDCALL sass_make_null (void);
|
||||
ADDAPI union Sass_Value* ADDCALL sass_make_boolean (bool val);
|
||||
ADDAPI union Sass_Value* ADDCALL sass_make_string (const char* val);
|
||||
ADDAPI union Sass_Value* ADDCALL sass_make_qstring (const char* val);
|
||||
ADDAPI union Sass_Value* ADDCALL sass_make_number (double val, const char* unit);
|
||||
ADDAPI union Sass_Value* ADDCALL sass_make_color (double r, double g, double b, double a);
|
||||
ADDAPI union Sass_Value* ADDCALL sass_make_list (size_t len, enum Sass_Separator sep, bool is_bracketed);
|
||||
ADDAPI union Sass_Value* ADDCALL sass_make_map (size_t len);
|
||||
ADDAPI union Sass_Value* ADDCALL sass_make_error (const char* msg);
|
||||
ADDAPI union Sass_Value* ADDCALL sass_make_warning (const char* msg);
|
||||
|
||||
// Generic destructor function for all types
|
||||
// Will release memory of all associated Sass_Values
|
||||
// Means we will delete recursively for lists and maps
|
||||
ADDAPI void ADDCALL sass_delete_value (union Sass_Value* val);
|
||||
|
||||
// Make a deep cloned copy of the given sass value
|
||||
ADDAPI union Sass_Value* ADDCALL sass_clone_value (const union Sass_Value* val);
|
||||
|
||||
// Execute an operation for two Sass_Values and return the result as a Sass_Value too
|
||||
ADDAPI union Sass_Value* ADDCALL sass_value_op (enum Sass_OP op, const union Sass_Value* a, const union Sass_Value* b);
|
||||
|
||||
// Stringify a Sass_Values and also return the result as a Sass_Value (of type STRING)
|
||||
ADDAPI union Sass_Value* ADDCALL sass_value_stringify (const union Sass_Value* a, bool compressed, int precision);
|
||||
|
||||
// Return the sass tag for a generic sass value
|
||||
// Check is needed before accessing specific values!
|
||||
ADDAPI enum Sass_Tag ADDCALL sass_value_get_tag (const union Sass_Value* v);
|
||||
|
||||
// Check value to be of a specific type
|
||||
// Can also be used before accessing properties!
|
||||
ADDAPI bool ADDCALL sass_value_is_null (const union Sass_Value* v);
|
||||
ADDAPI bool ADDCALL sass_value_is_number (const union Sass_Value* v);
|
||||
ADDAPI bool ADDCALL sass_value_is_string (const union Sass_Value* v);
|
||||
ADDAPI bool ADDCALL sass_value_is_boolean (const union Sass_Value* v);
|
||||
ADDAPI bool ADDCALL sass_value_is_color (const union Sass_Value* v);
|
||||
ADDAPI bool ADDCALL sass_value_is_list (const union Sass_Value* v);
|
||||
ADDAPI bool ADDCALL sass_value_is_map (const union Sass_Value* v);
|
||||
ADDAPI bool ADDCALL sass_value_is_error (const union Sass_Value* v);
|
||||
ADDAPI bool ADDCALL sass_value_is_warning (const union Sass_Value* v);
|
||||
|
||||
// Getters and setters for Sass_Number
|
||||
ADDAPI double ADDCALL sass_number_get_value (const union Sass_Value* v);
|
||||
ADDAPI void ADDCALL sass_number_set_value (union Sass_Value* v, double value);
|
||||
ADDAPI const char* ADDCALL sass_number_get_unit (const union Sass_Value* v);
|
||||
ADDAPI void ADDCALL sass_number_set_unit (union Sass_Value* v, char* unit);
|
||||
|
||||
// Getters and setters for Sass_String
|
||||
ADDAPI const char* ADDCALL sass_string_get_value (const union Sass_Value* v);
|
||||
ADDAPI void ADDCALL sass_string_set_value (union Sass_Value* v, char* value);
|
||||
ADDAPI bool ADDCALL sass_string_is_quoted(const union Sass_Value* v);
|
||||
ADDAPI void ADDCALL sass_string_set_quoted(union Sass_Value* v, bool quoted);
|
||||
|
||||
// Getters and setters for Sass_Boolean
|
||||
ADDAPI bool ADDCALL sass_boolean_get_value (const union Sass_Value* v);
|
||||
ADDAPI void ADDCALL sass_boolean_set_value (union Sass_Value* v, bool value);
|
||||
|
||||
// Getters and setters for Sass_Color
|
||||
ADDAPI double ADDCALL sass_color_get_r (const union Sass_Value* v);
|
||||
ADDAPI void ADDCALL sass_color_set_r (union Sass_Value* v, double r);
|
||||
ADDAPI double ADDCALL sass_color_get_g (const union Sass_Value* v);
|
||||
ADDAPI void ADDCALL sass_color_set_g (union Sass_Value* v, double g);
|
||||
ADDAPI double ADDCALL sass_color_get_b (const union Sass_Value* v);
|
||||
ADDAPI void ADDCALL sass_color_set_b (union Sass_Value* v, double b);
|
||||
ADDAPI double ADDCALL sass_color_get_a (const union Sass_Value* v);
|
||||
ADDAPI void ADDCALL sass_color_set_a (union Sass_Value* v, double a);
|
||||
|
||||
// Getter for the number of items in list
|
||||
ADDAPI size_t ADDCALL sass_list_get_length (const union Sass_Value* v);
|
||||
// Getters and setters for Sass_List
|
||||
ADDAPI enum Sass_Separator ADDCALL sass_list_get_separator (const union Sass_Value* v);
|
||||
ADDAPI void ADDCALL sass_list_set_separator (union Sass_Value* v, enum Sass_Separator value);
|
||||
ADDAPI bool ADDCALL sass_list_get_is_bracketed (const union Sass_Value* v);
|
||||
ADDAPI void ADDCALL sass_list_set_is_bracketed (union Sass_Value* v, bool value);
|
||||
// Getters and setters for Sass_List values
|
||||
ADDAPI union Sass_Value* ADDCALL sass_list_get_value (const union Sass_Value* v, size_t i);
|
||||
ADDAPI void ADDCALL sass_list_set_value (union Sass_Value* v, size_t i, union Sass_Value* value);
|
||||
|
||||
// Getter for the number of items in map
|
||||
ADDAPI size_t ADDCALL sass_map_get_length (const union Sass_Value* v);
|
||||
// Getters and setters for Sass_Map keys and values
|
||||
ADDAPI union Sass_Value* ADDCALL sass_map_get_key (const union Sass_Value* v, size_t i);
|
||||
ADDAPI void ADDCALL sass_map_set_key (union Sass_Value* v, size_t i, union Sass_Value*);
|
||||
ADDAPI union Sass_Value* ADDCALL sass_map_get_value (const union Sass_Value* v, size_t i);
|
||||
ADDAPI void ADDCALL sass_map_set_value (union Sass_Value* v, size_t i, union Sass_Value*);
|
||||
|
||||
// Getters and setters for Sass_Error
|
||||
ADDAPI char* ADDCALL sass_error_get_message (const union Sass_Value* v);
|
||||
ADDAPI void ADDCALL sass_error_set_message (union Sass_Value* v, char* msg);
|
||||
|
||||
// Getters and setters for Sass_Warning
|
||||
ADDAPI char* ADDCALL sass_warning_get_message (const union Sass_Value* v);
|
||||
ADDAPI void ADDCALL sass_warning_set_message (union Sass_Value* v, char* msg);
|
||||
|
||||
#ifdef __cplusplus
|
||||
} // __cplusplus defined.
|
||||
#endif
|
||||
|
||||
#endif
|
||||
12
vendor/bundle/ruby/2.6.0/gems/sassc-2.4.0/ext/libsass/include/sass/version.h
vendored
Normal file
12
vendor/bundle/ruby/2.6.0/gems/sassc-2.4.0/ext/libsass/include/sass/version.h
vendored
Normal file
@@ -0,0 +1,12 @@
|
||||
#ifndef SASS_VERSION_H
|
||||
#define SASS_VERSION_H
|
||||
|
||||
#ifndef LIBSASS_VERSION
|
||||
#define LIBSASS_VERSION "[NA]"
|
||||
#endif
|
||||
|
||||
#ifndef LIBSASS_LANGUAGE_VERSION
|
||||
#define LIBSASS_LANGUAGE_VERSION "3.5"
|
||||
#endif
|
||||
|
||||
#endif
|
||||
120
vendor/bundle/ruby/2.6.0/gems/sassc-2.4.0/ext/libsass/include/sass2scss.h
vendored
Normal file
120
vendor/bundle/ruby/2.6.0/gems/sassc-2.4.0/ext/libsass/include/sass2scss.h
vendored
Normal file
@@ -0,0 +1,120 @@
|
||||
/**
|
||||
* sass2scss
|
||||
* Licensed under the MIT License
|
||||
* Copyright (c) Marcel Greter
|
||||
*/
|
||||
|
||||
#ifndef SASS2SCSS_H
|
||||
#define SASS2SCSS_H
|
||||
|
||||
#ifdef _WIN32
|
||||
|
||||
/* You should define ADD_EXPORTS *only* when building the DLL. */
|
||||
#ifdef ADD_EXPORTS
|
||||
#define ADDAPI __declspec(dllexport)
|
||||
#define ADDCALL __cdecl
|
||||
#else
|
||||
#define ADDAPI
|
||||
#define ADDCALL
|
||||
#endif
|
||||
|
||||
#else /* _WIN32 not defined. */
|
||||
|
||||
/* Define with no value on non-Windows OSes. */
|
||||
#define ADDAPI
|
||||
#define ADDCALL
|
||||
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
|
||||
#include <stack>
|
||||
#include <string>
|
||||
#include <cstring>
|
||||
#include <sstream>
|
||||
#include <iostream>
|
||||
|
||||
#ifndef SASS2SCSS_VERSION
|
||||
// Hardcode once the file is copied from
|
||||
// https://github.com/mgreter/sass2scss
|
||||
#define SASS2SCSS_VERSION "1.1.1"
|
||||
#endif
|
||||
|
||||
// add namespace for c++
|
||||
namespace Sass
|
||||
{
|
||||
|
||||
// pretty print options
|
||||
const int SASS2SCSS_PRETTIFY_0 = 0;
|
||||
const int SASS2SCSS_PRETTIFY_1 = 1;
|
||||
const int SASS2SCSS_PRETTIFY_2 = 2;
|
||||
const int SASS2SCSS_PRETTIFY_3 = 3;
|
||||
|
||||
// remove one-line comment
|
||||
const int SASS2SCSS_KEEP_COMMENT = 32;
|
||||
// remove multi-line comments
|
||||
const int SASS2SCSS_STRIP_COMMENT = 64;
|
||||
// convert one-line to multi-line
|
||||
const int SASS2SCSS_CONVERT_COMMENT = 128;
|
||||
|
||||
// String for finding something interesting
|
||||
const std::string SASS2SCSS_FIND_WHITESPACE = " \t\n\v\f\r";
|
||||
|
||||
// converter struct
|
||||
// holding all states
|
||||
struct converter
|
||||
{
|
||||
// bit options
|
||||
int options;
|
||||
// is selector
|
||||
bool selector;
|
||||
// concat lists
|
||||
bool comma;
|
||||
// has property
|
||||
bool property;
|
||||
// has semicolon
|
||||
bool semicolon;
|
||||
// comment context
|
||||
std::string comment;
|
||||
// flag end of file
|
||||
bool end_of_file;
|
||||
// whitespace buffer
|
||||
std::string whitespace;
|
||||
// context/block stack
|
||||
std::stack<std::string> indents;
|
||||
};
|
||||
|
||||
// function only available in c++ code
|
||||
char* sass2scss (const std::string& sass, const int options);
|
||||
|
||||
}
|
||||
// EO namespace
|
||||
|
||||
// declare for c
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
// prettyfy print options
|
||||
#define SASS2SCSS_PRETTIFY_0 0
|
||||
#define SASS2SCSS_PRETTIFY_1 1
|
||||
#define SASS2SCSS_PRETTIFY_2 2
|
||||
#define SASS2SCSS_PRETTIFY_3 3
|
||||
|
||||
// keep one-line comments
|
||||
#define SASS2SCSS_KEEP_COMMENT 32
|
||||
// remove multi-line comments
|
||||
#define SASS2SCSS_STRIP_COMMENT 64
|
||||
// convert one-line to multi-line
|
||||
#define SASS2SCSS_CONVERT_COMMENT 128
|
||||
|
||||
// available to c and c++ code
|
||||
ADDAPI char* ADDCALL sass2scss (const char* sass, const int options);
|
||||
|
||||
// Get compiled sass2scss version
|
||||
ADDAPI const char* ADDCALL sass2scss_version(void);
|
||||
|
||||
#ifdef __cplusplus
|
||||
} // __cplusplus defined.
|
||||
#endif
|
||||
|
||||
#endif
|
||||
91
vendor/bundle/ruby/2.6.0/gems/sassc-2.4.0/ext/libsass/src/MurmurHash2.hpp
vendored
Normal file
91
vendor/bundle/ruby/2.6.0/gems/sassc-2.4.0/ext/libsass/src/MurmurHash2.hpp
vendored
Normal file
@@ -0,0 +1,91 @@
|
||||
//-----------------------------------------------------------------------------
|
||||
// MurmurHash2 was written by Austin Appleby, and is placed in the public
|
||||
// domain. The author hereby disclaims copyright to this source code.
|
||||
//-----------------------------------------------------------------------------
|
||||
// LibSass only needs MurmurHash2, so we made this header only
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
#ifndef _MURMURHASH2_H_
|
||||
#define _MURMURHASH2_H_
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Platform-specific functions and macros
|
||||
|
||||
// Microsoft Visual Studio
|
||||
|
||||
#if defined(_MSC_VER) && (_MSC_VER < 1600)
|
||||
|
||||
typedef unsigned char uint8_t;
|
||||
typedef unsigned int uint32_t;
|
||||
typedef unsigned __int64 uint64_t;
|
||||
|
||||
// Other compilers
|
||||
|
||||
#else // defined(_MSC_VER)
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
#endif // !defined(_MSC_VER)
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
inline uint32_t MurmurHash2 ( const void * key, int len, uint32_t seed )
|
||||
{
|
||||
// 'm' and 'r' are mixing constants generated offline.
|
||||
// They're not really 'magic', they just happen to work well.
|
||||
|
||||
const uint32_t m = 0x5bd1e995;
|
||||
const int r = 24;
|
||||
|
||||
// Initialize the hash to a 'random' value
|
||||
|
||||
uint32_t h = seed ^ len;
|
||||
|
||||
// Mix 4 bytes at a time into the hash
|
||||
|
||||
const unsigned char * data = (const unsigned char *)key;
|
||||
|
||||
while(len >= 4)
|
||||
{
|
||||
uint32_t k = *(uint32_t*)data;
|
||||
|
||||
k *= m;
|
||||
k ^= k >> r;
|
||||
k *= m;
|
||||
|
||||
h *= m;
|
||||
h ^= k;
|
||||
|
||||
data += 4;
|
||||
len -= 4;
|
||||
}
|
||||
|
||||
// Handle the last few bytes of the input array
|
||||
|
||||
switch(len)
|
||||
{
|
||||
case 3:
|
||||
h ^= data[2] << 16;
|
||||
/* fall through */
|
||||
case 2:
|
||||
h ^= data[1] << 8;
|
||||
/* fall through */
|
||||
case 1:
|
||||
h ^= data[0];
|
||||
h *= m;
|
||||
};
|
||||
|
||||
// Do a few final mixes of the hash to ensure the last few
|
||||
// bytes are well-incorporated.
|
||||
|
||||
h ^= h >> 13;
|
||||
h *= m;
|
||||
h ^= h >> 15;
|
||||
|
||||
return h;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
#endif // _MURMURHASH2_H_
|
||||
|
||||
953
vendor/bundle/ruby/2.6.0/gems/sassc-2.4.0/ext/libsass/src/ast.cpp
vendored
Normal file
953
vendor/bundle/ruby/2.6.0/gems/sassc-2.4.0/ext/libsass/src/ast.cpp
vendored
Normal file
@@ -0,0 +1,953 @@
|
||||
// sass.hpp must go before all system headers to get the
|
||||
// __EXTENSIONS__ fix on Solaris.
|
||||
#include "sass.hpp"
|
||||
|
||||
#include "ast.hpp"
|
||||
|
||||
namespace Sass {
|
||||
|
||||
static Null sass_null(SourceSpan("null"));
|
||||
|
||||
const char* sass_op_to_name(enum Sass_OP op) {
|
||||
switch (op) {
|
||||
case AND: return "and";
|
||||
case OR: return "or";
|
||||
case EQ: return "eq";
|
||||
case NEQ: return "neq";
|
||||
case GT: return "gt";
|
||||
case GTE: return "gte";
|
||||
case LT: return "lt";
|
||||
case LTE: return "lte";
|
||||
case ADD: return "plus";
|
||||
case SUB: return "minus";
|
||||
case MUL: return "times";
|
||||
case DIV: return "div";
|
||||
case MOD: return "mod";
|
||||
// this is only used internally!
|
||||
case NUM_OPS: return "[OPS]";
|
||||
default: return "invalid";
|
||||
}
|
||||
}
|
||||
|
||||
const char* sass_op_separator(enum Sass_OP op) {
|
||||
switch (op) {
|
||||
case AND: return "&&";
|
||||
case OR: return "||";
|
||||
case EQ: return "==";
|
||||
case NEQ: return "!=";
|
||||
case GT: return ">";
|
||||
case GTE: return ">=";
|
||||
case LT: return "<";
|
||||
case LTE: return "<=";
|
||||
case ADD: return "+";
|
||||
case SUB: return "-";
|
||||
case MUL: return "*";
|
||||
case DIV: return "/";
|
||||
case MOD: return "%";
|
||||
// this is only used internally!
|
||||
case NUM_OPS: return "[OPS]";
|
||||
default: return "invalid";
|
||||
}
|
||||
}
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////
|
||||
/////////////////////////////////////////////////////////////////////////
|
||||
|
||||
void AST_Node::update_pstate(const SourceSpan& pstate)
|
||||
{
|
||||
pstate_.offset += pstate.position - pstate_.position + pstate.offset;
|
||||
}
|
||||
|
||||
sass::string AST_Node::to_string(Sass_Inspect_Options opt) const
|
||||
{
|
||||
Sass_Output_Options out(opt);
|
||||
Emitter emitter(out);
|
||||
Inspect i(emitter);
|
||||
i.in_declaration = true;
|
||||
// ToDo: inspect should be const
|
||||
const_cast<AST_Node*>(this)->perform(&i);
|
||||
return i.get_buffer();
|
||||
}
|
||||
|
||||
sass::string AST_Node::to_css(Sass_Inspect_Options opt) const
|
||||
{
|
||||
opt.output_style = TO_CSS;
|
||||
Sass_Output_Options out(opt);
|
||||
Emitter emitter(out);
|
||||
Inspect i(emitter);
|
||||
i.in_declaration = true;
|
||||
// ToDo: inspect should be const
|
||||
const_cast<AST_Node*>(this)->perform(&i);
|
||||
return i.get_buffer();
|
||||
}
|
||||
|
||||
sass::string AST_Node::to_string() const
|
||||
{
|
||||
return to_string({ NESTED, 5 });
|
||||
}
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////
|
||||
/////////////////////////////////////////////////////////////////////////
|
||||
|
||||
Statement::Statement(SourceSpan pstate, Type st, size_t t)
|
||||
: AST_Node(pstate), statement_type_(st), tabs_(t), group_end_(false)
|
||||
{ }
|
||||
Statement::Statement(const Statement* ptr)
|
||||
: AST_Node(ptr),
|
||||
statement_type_(ptr->statement_type_),
|
||||
tabs_(ptr->tabs_),
|
||||
group_end_(ptr->group_end_)
|
||||
{ }
|
||||
|
||||
bool Statement::bubbles()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
bool Statement::has_content()
|
||||
{
|
||||
return statement_type_ == CONTENT;
|
||||
}
|
||||
|
||||
bool Statement::is_invisible() const
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////
|
||||
/////////////////////////////////////////////////////////////////////////
|
||||
|
||||
Block::Block(SourceSpan pstate, size_t s, bool r)
|
||||
: Statement(pstate),
|
||||
Vectorized<Statement_Obj>(s),
|
||||
is_root_(r)
|
||||
{ }
|
||||
Block::Block(const Block* ptr)
|
||||
: Statement(ptr),
|
||||
Vectorized<Statement_Obj>(*ptr),
|
||||
is_root_(ptr->is_root_)
|
||||
{ }
|
||||
|
||||
bool Block::isInvisible() const
|
||||
{
|
||||
for (auto& item : elements()) {
|
||||
if (!item->is_invisible()) return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
bool Block::has_content()
|
||||
{
|
||||
for (size_t i = 0, L = elements().size(); i < L; ++i) {
|
||||
if (elements()[i]->has_content()) return true;
|
||||
}
|
||||
return Statement::has_content();
|
||||
}
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////
|
||||
/////////////////////////////////////////////////////////////////////////
|
||||
|
||||
ParentStatement::ParentStatement(SourceSpan pstate, Block_Obj b)
|
||||
: Statement(pstate), block_(b)
|
||||
{ }
|
||||
ParentStatement::ParentStatement(const ParentStatement* ptr)
|
||||
: Statement(ptr), block_(ptr->block_)
|
||||
{ }
|
||||
|
||||
bool ParentStatement::has_content()
|
||||
{
|
||||
return (block_ && block_->has_content()) || Statement::has_content();
|
||||
}
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////
|
||||
/////////////////////////////////////////////////////////////////////////
|
||||
|
||||
StyleRule::StyleRule(SourceSpan pstate, SelectorListObj s, Block_Obj b)
|
||||
: ParentStatement(pstate, b), selector_(s), schema_(), is_root_(false)
|
||||
{ statement_type(RULESET); }
|
||||
StyleRule::StyleRule(const StyleRule* ptr)
|
||||
: ParentStatement(ptr),
|
||||
selector_(ptr->selector_),
|
||||
schema_(ptr->schema_),
|
||||
is_root_(ptr->is_root_)
|
||||
{ statement_type(RULESET); }
|
||||
|
||||
bool StyleRule::is_invisible() const {
|
||||
if (const SelectorList * sl = Cast<SelectorList>(selector())) {
|
||||
for (size_t i = 0, L = sl->length(); i < L; i += 1)
|
||||
if (!(*sl)[i]->isInvisible()) return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////
|
||||
/////////////////////////////////////////////////////////////////////////
|
||||
|
||||
Bubble::Bubble(SourceSpan pstate, Statement_Obj n, Statement_Obj g, size_t t)
|
||||
: Statement(pstate, Statement::BUBBLE, t), node_(n), group_end_(g == nullptr)
|
||||
{ }
|
||||
Bubble::Bubble(const Bubble* ptr)
|
||||
: Statement(ptr),
|
||||
node_(ptr->node_),
|
||||
group_end_(ptr->group_end_)
|
||||
{ }
|
||||
|
||||
bool Bubble::bubbles()
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////
|
||||
/////////////////////////////////////////////////////////////////////////
|
||||
|
||||
Trace::Trace(SourceSpan pstate, sass::string n, Block_Obj b, char type)
|
||||
: ParentStatement(pstate, b), type_(type), name_(n)
|
||||
{ }
|
||||
Trace::Trace(const Trace* ptr)
|
||||
: ParentStatement(ptr),
|
||||
type_(ptr->type_),
|
||||
name_(ptr->name_)
|
||||
{ }
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////
|
||||
/////////////////////////////////////////////////////////////////////////
|
||||
|
||||
AtRule::AtRule(SourceSpan pstate, sass::string kwd, SelectorListObj sel, Block_Obj b, ExpressionObj val)
|
||||
: ParentStatement(pstate, b), keyword_(kwd), selector_(sel), value_(val) // set value manually if needed
|
||||
{ statement_type(DIRECTIVE); }
|
||||
AtRule::AtRule(const AtRule* ptr)
|
||||
: ParentStatement(ptr),
|
||||
keyword_(ptr->keyword_),
|
||||
selector_(ptr->selector_),
|
||||
value_(ptr->value_) // set value manually if needed
|
||||
{ statement_type(DIRECTIVE); }
|
||||
|
||||
bool AtRule::bubbles() { return is_keyframes() || is_media(); }
|
||||
|
||||
bool AtRule::is_media() {
|
||||
return keyword_.compare("@-webkit-media") == 0 ||
|
||||
keyword_.compare("@-moz-media") == 0 ||
|
||||
keyword_.compare("@-o-media") == 0 ||
|
||||
keyword_.compare("@media") == 0;
|
||||
}
|
||||
bool AtRule::is_keyframes() {
|
||||
return keyword_.compare("@-webkit-keyframes") == 0 ||
|
||||
keyword_.compare("@-moz-keyframes") == 0 ||
|
||||
keyword_.compare("@-o-keyframes") == 0 ||
|
||||
keyword_.compare("@keyframes") == 0;
|
||||
}
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////
|
||||
/////////////////////////////////////////////////////////////////////////
|
||||
|
||||
Keyframe_Rule::Keyframe_Rule(SourceSpan pstate, Block_Obj b)
|
||||
: ParentStatement(pstate, b), name_()
|
||||
{ statement_type(KEYFRAMERULE); }
|
||||
Keyframe_Rule::Keyframe_Rule(const Keyframe_Rule* ptr)
|
||||
: ParentStatement(ptr), name_(ptr->name_)
|
||||
{ statement_type(KEYFRAMERULE); }
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////
|
||||
/////////////////////////////////////////////////////////////////////////
|
||||
|
||||
Declaration::Declaration(SourceSpan pstate, String_Obj prop, ExpressionObj val, bool i, bool c, Block_Obj b)
|
||||
: ParentStatement(pstate, b), property_(prop), value_(val), is_important_(i), is_custom_property_(c), is_indented_(false)
|
||||
{ statement_type(DECLARATION); }
|
||||
Declaration::Declaration(const Declaration* ptr)
|
||||
: ParentStatement(ptr),
|
||||
property_(ptr->property_),
|
||||
value_(ptr->value_),
|
||||
is_important_(ptr->is_important_),
|
||||
is_custom_property_(ptr->is_custom_property_),
|
||||
is_indented_(ptr->is_indented_)
|
||||
{ statement_type(DECLARATION); }
|
||||
|
||||
bool Declaration::is_invisible() const
|
||||
{
|
||||
if (is_custom_property()) return false;
|
||||
return !(value_ && !Cast<Null>(value_));
|
||||
}
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////
|
||||
/////////////////////////////////////////////////////////////////////////
|
||||
|
||||
Assignment::Assignment(SourceSpan pstate, sass::string var, ExpressionObj val, bool is_default, bool is_global)
|
||||
: Statement(pstate), variable_(var), value_(val), is_default_(is_default), is_global_(is_global)
|
||||
{ statement_type(ASSIGNMENT); }
|
||||
Assignment::Assignment(const Assignment* ptr)
|
||||
: Statement(ptr),
|
||||
variable_(ptr->variable_),
|
||||
value_(ptr->value_),
|
||||
is_default_(ptr->is_default_),
|
||||
is_global_(ptr->is_global_)
|
||||
{ statement_type(ASSIGNMENT); }
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////
|
||||
/////////////////////////////////////////////////////////////////////////
|
||||
|
||||
Import::Import(SourceSpan pstate)
|
||||
: Statement(pstate),
|
||||
urls_(sass::vector<ExpressionObj>()),
|
||||
incs_(sass::vector<Include>()),
|
||||
import_queries_()
|
||||
{ statement_type(IMPORT); }
|
||||
Import::Import(const Import* ptr)
|
||||
: Statement(ptr),
|
||||
urls_(ptr->urls_),
|
||||
incs_(ptr->incs_),
|
||||
import_queries_(ptr->import_queries_)
|
||||
{ statement_type(IMPORT); }
|
||||
|
||||
sass::vector<Include>& Import::incs() { return incs_; }
|
||||
sass::vector<ExpressionObj>& Import::urls() { return urls_; }
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////
|
||||
/////////////////////////////////////////////////////////////////////////
|
||||
|
||||
Import_Stub::Import_Stub(SourceSpan pstate, Include res)
|
||||
: Statement(pstate), resource_(res)
|
||||
{ statement_type(IMPORT_STUB); }
|
||||
Import_Stub::Import_Stub(const Import_Stub* ptr)
|
||||
: Statement(ptr), resource_(ptr->resource_)
|
||||
{ statement_type(IMPORT_STUB); }
|
||||
Include Import_Stub::resource() { return resource_; };
|
||||
sass::string Import_Stub::imp_path() { return resource_.imp_path; };
|
||||
sass::string Import_Stub::abs_path() { return resource_.abs_path; };
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////
|
||||
/////////////////////////////////////////////////////////////////////////
|
||||
|
||||
WarningRule::WarningRule(SourceSpan pstate, ExpressionObj msg)
|
||||
: Statement(pstate), message_(msg)
|
||||
{ statement_type(WARNING); }
|
||||
WarningRule::WarningRule(const WarningRule* ptr)
|
||||
: Statement(ptr), message_(ptr->message_)
|
||||
{ statement_type(WARNING); }
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////
|
||||
/////////////////////////////////////////////////////////////////////////
|
||||
|
||||
ErrorRule::ErrorRule(SourceSpan pstate, ExpressionObj msg)
|
||||
: Statement(pstate), message_(msg)
|
||||
{ statement_type(ERROR); }
|
||||
ErrorRule::ErrorRule(const ErrorRule* ptr)
|
||||
: Statement(ptr), message_(ptr->message_)
|
||||
{ statement_type(ERROR); }
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////
|
||||
/////////////////////////////////////////////////////////////////////////
|
||||
|
||||
DebugRule::DebugRule(SourceSpan pstate, ExpressionObj val)
|
||||
: Statement(pstate), value_(val)
|
||||
{ statement_type(DEBUGSTMT); }
|
||||
DebugRule::DebugRule(const DebugRule* ptr)
|
||||
: Statement(ptr), value_(ptr->value_)
|
||||
{ statement_type(DEBUGSTMT); }
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////
|
||||
/////////////////////////////////////////////////////////////////////////
|
||||
|
||||
Comment::Comment(SourceSpan pstate, String_Obj txt, bool is_important)
|
||||
: Statement(pstate), text_(txt), is_important_(is_important)
|
||||
{ statement_type(COMMENT); }
|
||||
Comment::Comment(const Comment* ptr)
|
||||
: Statement(ptr),
|
||||
text_(ptr->text_),
|
||||
is_important_(ptr->is_important_)
|
||||
{ statement_type(COMMENT); }
|
||||
|
||||
bool Comment::is_invisible() const
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////
|
||||
/////////////////////////////////////////////////////////////////////////
|
||||
|
||||
If::If(SourceSpan pstate, ExpressionObj pred, Block_Obj con, Block_Obj alt)
|
||||
: ParentStatement(pstate, con), predicate_(pred), alternative_(alt)
|
||||
{ statement_type(IF); }
|
||||
If::If(const If* ptr)
|
||||
: ParentStatement(ptr),
|
||||
predicate_(ptr->predicate_),
|
||||
alternative_(ptr->alternative_)
|
||||
{ statement_type(IF); }
|
||||
|
||||
bool If::has_content()
|
||||
{
|
||||
return ParentStatement::has_content() || (alternative_ && alternative_->has_content());
|
||||
}
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////
|
||||
/////////////////////////////////////////////////////////////////////////
|
||||
|
||||
ForRule::ForRule(SourceSpan pstate,
|
||||
sass::string var, ExpressionObj lo, ExpressionObj hi, Block_Obj b, bool inc)
|
||||
: ParentStatement(pstate, b),
|
||||
variable_(var), lower_bound_(lo), upper_bound_(hi), is_inclusive_(inc)
|
||||
{ statement_type(FOR); }
|
||||
ForRule::ForRule(const ForRule* ptr)
|
||||
: ParentStatement(ptr),
|
||||
variable_(ptr->variable_),
|
||||
lower_bound_(ptr->lower_bound_),
|
||||
upper_bound_(ptr->upper_bound_),
|
||||
is_inclusive_(ptr->is_inclusive_)
|
||||
{ statement_type(FOR); }
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////
|
||||
/////////////////////////////////////////////////////////////////////////
|
||||
|
||||
EachRule::EachRule(SourceSpan pstate, sass::vector<sass::string> vars, ExpressionObj lst, Block_Obj b)
|
||||
: ParentStatement(pstate, b), variables_(vars), list_(lst)
|
||||
{ statement_type(EACH); }
|
||||
EachRule::EachRule(const EachRule* ptr)
|
||||
: ParentStatement(ptr), variables_(ptr->variables_), list_(ptr->list_)
|
||||
{ statement_type(EACH); }
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////
|
||||
/////////////////////////////////////////////////////////////////////////
|
||||
|
||||
WhileRule::WhileRule(SourceSpan pstate, ExpressionObj pred, Block_Obj b)
|
||||
: ParentStatement(pstate, b), predicate_(pred)
|
||||
{ statement_type(WHILE); }
|
||||
WhileRule::WhileRule(const WhileRule* ptr)
|
||||
: ParentStatement(ptr), predicate_(ptr->predicate_)
|
||||
{ statement_type(WHILE); }
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////
|
||||
/////////////////////////////////////////////////////////////////////////
|
||||
|
||||
Return::Return(SourceSpan pstate, ExpressionObj val)
|
||||
: Statement(pstate), value_(val)
|
||||
{ statement_type(RETURN); }
|
||||
Return::Return(const Return* ptr)
|
||||
: Statement(ptr), value_(ptr->value_)
|
||||
{ statement_type(RETURN); }
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////
|
||||
/////////////////////////////////////////////////////////////////////////
|
||||
|
||||
ExtendRule::ExtendRule(SourceSpan pstate, SelectorListObj s)
|
||||
: Statement(pstate), isOptional_(false), selector_(s), schema_()
|
||||
{ statement_type(EXTEND); }
|
||||
ExtendRule::ExtendRule(SourceSpan pstate, Selector_Schema_Obj s)
|
||||
: Statement(pstate), isOptional_(false), selector_(), schema_(s)
|
||||
{
|
||||
statement_type(EXTEND);
|
||||
}
|
||||
ExtendRule::ExtendRule(const ExtendRule* ptr)
|
||||
: Statement(ptr),
|
||||
isOptional_(ptr->isOptional_),
|
||||
selector_(ptr->selector_),
|
||||
schema_(ptr->schema_)
|
||||
{ statement_type(EXTEND); }
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////
|
||||
/////////////////////////////////////////////////////////////////////////
|
||||
|
||||
Definition::Definition(const Definition* ptr)
|
||||
: ParentStatement(ptr),
|
||||
name_(ptr->name_),
|
||||
parameters_(ptr->parameters_),
|
||||
environment_(ptr->environment_),
|
||||
type_(ptr->type_),
|
||||
native_function_(ptr->native_function_),
|
||||
c_function_(ptr->c_function_),
|
||||
cookie_(ptr->cookie_),
|
||||
is_overload_stub_(ptr->is_overload_stub_),
|
||||
signature_(ptr->signature_)
|
||||
{ }
|
||||
|
||||
Definition::Definition(SourceSpan pstate,
|
||||
sass::string n,
|
||||
Parameters_Obj params,
|
||||
Block_Obj b,
|
||||
Type t)
|
||||
: ParentStatement(pstate, b),
|
||||
name_(n),
|
||||
parameters_(params),
|
||||
environment_(0),
|
||||
type_(t),
|
||||
native_function_(0),
|
||||
c_function_(0),
|
||||
cookie_(0),
|
||||
is_overload_stub_(false),
|
||||
signature_(0)
|
||||
{ }
|
||||
|
||||
Definition::Definition(SourceSpan pstate,
|
||||
Signature sig,
|
||||
sass::string n,
|
||||
Parameters_Obj params,
|
||||
Native_Function func_ptr,
|
||||
bool overload_stub)
|
||||
: ParentStatement(pstate, {}),
|
||||
name_(n),
|
||||
parameters_(params),
|
||||
environment_(0),
|
||||
type_(FUNCTION),
|
||||
native_function_(func_ptr),
|
||||
c_function_(0),
|
||||
cookie_(0),
|
||||
is_overload_stub_(overload_stub),
|
||||
signature_(sig)
|
||||
{ }
|
||||
|
||||
Definition::Definition(SourceSpan pstate,
|
||||
Signature sig,
|
||||
sass::string n,
|
||||
Parameters_Obj params,
|
||||
Sass_Function_Entry c_func)
|
||||
: ParentStatement(pstate, {}),
|
||||
name_(n),
|
||||
parameters_(params),
|
||||
environment_(0),
|
||||
type_(FUNCTION),
|
||||
native_function_(0),
|
||||
c_function_(c_func),
|
||||
cookie_(sass_function_get_cookie(c_func)),
|
||||
is_overload_stub_(false),
|
||||
signature_(sig)
|
||||
{ }
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////
|
||||
/////////////////////////////////////////////////////////////////////////
|
||||
|
||||
Mixin_Call::Mixin_Call(SourceSpan pstate, sass::string n, Arguments_Obj args, Parameters_Obj b_params, Block_Obj b)
|
||||
: ParentStatement(pstate, b), name_(n), arguments_(args), block_parameters_(b_params)
|
||||
{ }
|
||||
Mixin_Call::Mixin_Call(const Mixin_Call* ptr)
|
||||
: ParentStatement(ptr),
|
||||
name_(ptr->name_),
|
||||
arguments_(ptr->arguments_),
|
||||
block_parameters_(ptr->block_parameters_)
|
||||
{ }
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////
|
||||
/////////////////////////////////////////////////////////////////////////
|
||||
|
||||
Content::Content(SourceSpan pstate, Arguments_Obj args)
|
||||
: Statement(pstate),
|
||||
arguments_(args)
|
||||
{ statement_type(CONTENT); }
|
||||
Content::Content(const Content* ptr)
|
||||
: Statement(ptr),
|
||||
arguments_(ptr->arguments_)
|
||||
{ statement_type(CONTENT); }
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////
|
||||
/////////////////////////////////////////////////////////////////////////
|
||||
|
||||
Expression::Expression(SourceSpan pstate, bool d, bool e, bool i, Type ct)
|
||||
: AST_Node(pstate),
|
||||
is_delayed_(d),
|
||||
is_expanded_(e),
|
||||
is_interpolant_(i),
|
||||
concrete_type_(ct)
|
||||
{ }
|
||||
|
||||
Expression::Expression(const Expression* ptr)
|
||||
: AST_Node(ptr),
|
||||
is_delayed_(ptr->is_delayed_),
|
||||
is_expanded_(ptr->is_expanded_),
|
||||
is_interpolant_(ptr->is_interpolant_),
|
||||
concrete_type_(ptr->concrete_type_)
|
||||
{ }
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////
|
||||
/////////////////////////////////////////////////////////////////////////
|
||||
|
||||
Unary_Expression::Unary_Expression(SourceSpan pstate, Type t, ExpressionObj o)
|
||||
: Expression(pstate), optype_(t), operand_(o), hash_(0)
|
||||
{ }
|
||||
Unary_Expression::Unary_Expression(const Unary_Expression* ptr)
|
||||
: Expression(ptr),
|
||||
optype_(ptr->optype_),
|
||||
operand_(ptr->operand_),
|
||||
hash_(ptr->hash_)
|
||||
{ }
|
||||
const sass::string Unary_Expression::type_name() {
|
||||
switch (optype_) {
|
||||
case PLUS: return "plus";
|
||||
case MINUS: return "minus";
|
||||
case SLASH: return "slash";
|
||||
case NOT: return "not";
|
||||
default: return "invalid";
|
||||
}
|
||||
}
|
||||
bool Unary_Expression::operator==(const Expression& rhs) const
|
||||
{
|
||||
try
|
||||
{
|
||||
const Unary_Expression* m = Cast<Unary_Expression>(&rhs);
|
||||
if (m == 0) return false;
|
||||
return type() == m->type() &&
|
||||
*operand() == *m->operand();
|
||||
}
|
||||
catch (std::bad_cast&)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
catch (...) { throw; }
|
||||
}
|
||||
size_t Unary_Expression::hash() const
|
||||
{
|
||||
if (hash_ == 0) {
|
||||
hash_ = std::hash<size_t>()(optype_);
|
||||
hash_combine(hash_, operand()->hash());
|
||||
};
|
||||
return hash_;
|
||||
}
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////
|
||||
/////////////////////////////////////////////////////////////////////////
|
||||
|
||||
Argument::Argument(SourceSpan pstate, ExpressionObj val, sass::string n, bool rest, bool keyword)
|
||||
: Expression(pstate), value_(val), name_(n), is_rest_argument_(rest), is_keyword_argument_(keyword), hash_(0)
|
||||
{
|
||||
if (!name_.empty() && is_rest_argument_) {
|
||||
coreError("variable-length argument may not be passed by name", pstate_);
|
||||
}
|
||||
}
|
||||
Argument::Argument(const Argument* ptr)
|
||||
: Expression(ptr),
|
||||
value_(ptr->value_),
|
||||
name_(ptr->name_),
|
||||
is_rest_argument_(ptr->is_rest_argument_),
|
||||
is_keyword_argument_(ptr->is_keyword_argument_),
|
||||
hash_(ptr->hash_)
|
||||
{
|
||||
if (!name_.empty() && is_rest_argument_) {
|
||||
coreError("variable-length argument may not be passed by name", pstate_);
|
||||
}
|
||||
}
|
||||
|
||||
void Argument::set_delayed(bool delayed)
|
||||
{
|
||||
if (value_) value_->set_delayed(delayed);
|
||||
is_delayed(delayed);
|
||||
}
|
||||
|
||||
bool Argument::operator==(const Expression& rhs) const
|
||||
{
|
||||
try
|
||||
{
|
||||
const Argument* m = Cast<Argument>(&rhs);
|
||||
if (!(m && name() == m->name())) return false;
|
||||
return *value() == *m->value();
|
||||
}
|
||||
catch (std::bad_cast&)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
catch (...) { throw; }
|
||||
}
|
||||
|
||||
size_t Argument::hash() const
|
||||
{
|
||||
if (hash_ == 0) {
|
||||
hash_ = std::hash<sass::string>()(name());
|
||||
hash_combine(hash_, value()->hash());
|
||||
}
|
||||
return hash_;
|
||||
}
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////
|
||||
/////////////////////////////////////////////////////////////////////////
|
||||
|
||||
Arguments::Arguments(SourceSpan pstate)
|
||||
: Expression(pstate),
|
||||
Vectorized<Argument_Obj>(),
|
||||
has_named_arguments_(false),
|
||||
has_rest_argument_(false),
|
||||
has_keyword_argument_(false)
|
||||
{ }
|
||||
Arguments::Arguments(const Arguments* ptr)
|
||||
: Expression(ptr),
|
||||
Vectorized<Argument_Obj>(*ptr),
|
||||
has_named_arguments_(ptr->has_named_arguments_),
|
||||
has_rest_argument_(ptr->has_rest_argument_),
|
||||
has_keyword_argument_(ptr->has_keyword_argument_)
|
||||
{ }
|
||||
|
||||
void Arguments::set_delayed(bool delayed)
|
||||
{
|
||||
for (Argument_Obj arg : elements()) {
|
||||
if (arg) arg->set_delayed(delayed);
|
||||
}
|
||||
is_delayed(delayed);
|
||||
}
|
||||
|
||||
Argument_Obj Arguments::get_rest_argument()
|
||||
{
|
||||
if (this->has_rest_argument()) {
|
||||
for (Argument_Obj arg : this->elements()) {
|
||||
if (arg->is_rest_argument()) {
|
||||
return arg;
|
||||
}
|
||||
}
|
||||
}
|
||||
return {};
|
||||
}
|
||||
|
||||
Argument_Obj Arguments::get_keyword_argument()
|
||||
{
|
||||
if (this->has_keyword_argument()) {
|
||||
for (Argument_Obj arg : this->elements()) {
|
||||
if (arg->is_keyword_argument()) {
|
||||
return arg;
|
||||
}
|
||||
}
|
||||
}
|
||||
return {};
|
||||
}
|
||||
|
||||
void Arguments::adjust_after_pushing(Argument_Obj a)
|
||||
{
|
||||
if (!a->name().empty()) {
|
||||
if (has_keyword_argument()) {
|
||||
coreError("named arguments must precede variable-length argument", a->pstate());
|
||||
}
|
||||
has_named_arguments(true);
|
||||
}
|
||||
else if (a->is_rest_argument()) {
|
||||
if (has_rest_argument()) {
|
||||
coreError("functions and mixins may only be called with one variable-length argument", a->pstate());
|
||||
}
|
||||
if (has_keyword_argument_) {
|
||||
coreError("only keyword arguments may follow variable arguments", a->pstate());
|
||||
}
|
||||
has_rest_argument(true);
|
||||
}
|
||||
else if (a->is_keyword_argument()) {
|
||||
if (has_keyword_argument()) {
|
||||
coreError("functions and mixins may only be called with one keyword argument", a->pstate());
|
||||
}
|
||||
has_keyword_argument(true);
|
||||
}
|
||||
else {
|
||||
if (has_rest_argument()) {
|
||||
coreError("ordinal arguments must precede variable-length arguments", a->pstate());
|
||||
}
|
||||
if (has_named_arguments()) {
|
||||
coreError("ordinal arguments must precede named arguments", a->pstate());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////
|
||||
/////////////////////////////////////////////////////////////////////////
|
||||
|
||||
Media_Query::Media_Query(SourceSpan pstate, String_Obj t, size_t s, bool n, bool r)
|
||||
: Expression(pstate), Vectorized<Media_Query_ExpressionObj>(s),
|
||||
media_type_(t), is_negated_(n), is_restricted_(r)
|
||||
{ }
|
||||
Media_Query::Media_Query(const Media_Query* ptr)
|
||||
: Expression(ptr),
|
||||
Vectorized<Media_Query_ExpressionObj>(*ptr),
|
||||
media_type_(ptr->media_type_),
|
||||
is_negated_(ptr->is_negated_),
|
||||
is_restricted_(ptr->is_restricted_)
|
||||
{ }
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////
|
||||
/////////////////////////////////////////////////////////////////////////
|
||||
|
||||
Media_Query_Expression::Media_Query_Expression(SourceSpan pstate,
|
||||
ExpressionObj f, ExpressionObj v, bool i)
|
||||
: Expression(pstate), feature_(f), value_(v), is_interpolated_(i)
|
||||
{ }
|
||||
Media_Query_Expression::Media_Query_Expression(const Media_Query_Expression* ptr)
|
||||
: Expression(ptr),
|
||||
feature_(ptr->feature_),
|
||||
value_(ptr->value_),
|
||||
is_interpolated_(ptr->is_interpolated_)
|
||||
{ }
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////
|
||||
/////////////////////////////////////////////////////////////////////////
|
||||
|
||||
At_Root_Query::At_Root_Query(SourceSpan pstate, ExpressionObj f, ExpressionObj v, bool i)
|
||||
: Expression(pstate), feature_(f), value_(v)
|
||||
{ }
|
||||
At_Root_Query::At_Root_Query(const At_Root_Query* ptr)
|
||||
: Expression(ptr),
|
||||
feature_(ptr->feature_),
|
||||
value_(ptr->value_)
|
||||
{ }
|
||||
|
||||
bool At_Root_Query::exclude(sass::string str)
|
||||
{
|
||||
bool with = feature() && unquote(feature()->to_string()).compare("with") == 0;
|
||||
List* l = static_cast<List*>(value().ptr());
|
||||
sass::string v;
|
||||
|
||||
if (with)
|
||||
{
|
||||
if (!l || l->length() == 0) return str.compare("rule") != 0;
|
||||
for (size_t i = 0, L = l->length(); i < L; ++i)
|
||||
{
|
||||
v = unquote((*l)[i]->to_string());
|
||||
if (v.compare("all") == 0 || v == str) return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (!l || !l->length()) return str.compare("rule") == 0;
|
||||
for (size_t i = 0, L = l->length(); i < L; ++i)
|
||||
{
|
||||
v = unquote((*l)[i]->to_string());
|
||||
if (v.compare("all") == 0 || v == str) return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////
|
||||
/////////////////////////////////////////////////////////////////////////
|
||||
|
||||
AtRootRule::AtRootRule(SourceSpan pstate, Block_Obj b, At_Root_Query_Obj e)
|
||||
: ParentStatement(pstate, b), expression_(e)
|
||||
{ statement_type(ATROOT); }
|
||||
AtRootRule::AtRootRule(const AtRootRule* ptr)
|
||||
: ParentStatement(ptr), expression_(ptr->expression_)
|
||||
{ statement_type(ATROOT); }
|
||||
|
||||
bool AtRootRule::bubbles() {
|
||||
return true;
|
||||
}
|
||||
|
||||
bool AtRootRule::exclude_node(Statement_Obj s) {
|
||||
if (expression() == nullptr)
|
||||
{
|
||||
return s->statement_type() == Statement::RULESET;
|
||||
}
|
||||
|
||||
if (s->statement_type() == Statement::DIRECTIVE)
|
||||
{
|
||||
if (AtRuleObj dir = Cast<AtRule>(s))
|
||||
{
|
||||
sass::string keyword(dir->keyword());
|
||||
if (keyword.length() > 0) keyword.erase(0, 1);
|
||||
return expression()->exclude(keyword);
|
||||
}
|
||||
}
|
||||
if (s->statement_type() == Statement::MEDIA)
|
||||
{
|
||||
return expression()->exclude("media");
|
||||
}
|
||||
if (s->statement_type() == Statement::RULESET)
|
||||
{
|
||||
return expression()->exclude("rule");
|
||||
}
|
||||
if (s->statement_type() == Statement::SUPPORTS)
|
||||
{
|
||||
return expression()->exclude("supports");
|
||||
}
|
||||
if (AtRuleObj dir = Cast<AtRule>(s))
|
||||
{
|
||||
if (dir->is_keyframes()) return expression()->exclude("keyframes");
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////
|
||||
/////////////////////////////////////////////////////////////////////////
|
||||
|
||||
Parameter::Parameter(SourceSpan pstate, sass::string n, ExpressionObj def, bool rest)
|
||||
: AST_Node(pstate), name_(n), default_value_(def), is_rest_parameter_(rest)
|
||||
{ }
|
||||
Parameter::Parameter(const Parameter* ptr)
|
||||
: AST_Node(ptr),
|
||||
name_(ptr->name_),
|
||||
default_value_(ptr->default_value_),
|
||||
is_rest_parameter_(ptr->is_rest_parameter_)
|
||||
{ }
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////
|
||||
/////////////////////////////////////////////////////////////////////////
|
||||
|
||||
Parameters::Parameters(SourceSpan pstate)
|
||||
: AST_Node(pstate),
|
||||
Vectorized<Parameter_Obj>(),
|
||||
has_optional_parameters_(false),
|
||||
has_rest_parameter_(false)
|
||||
{ }
|
||||
Parameters::Parameters(const Parameters* ptr)
|
||||
: AST_Node(ptr),
|
||||
Vectorized<Parameter_Obj>(*ptr),
|
||||
has_optional_parameters_(ptr->has_optional_parameters_),
|
||||
has_rest_parameter_(ptr->has_rest_parameter_)
|
||||
{ }
|
||||
|
||||
void Parameters::adjust_after_pushing(Parameter_Obj p)
|
||||
{
|
||||
if (p->default_value()) {
|
||||
if (has_rest_parameter()) {
|
||||
coreError("optional parameters may not be combined with variable-length parameters", p->pstate());
|
||||
}
|
||||
has_optional_parameters(true);
|
||||
}
|
||||
else if (p->is_rest_parameter()) {
|
||||
if (has_rest_parameter()) {
|
||||
coreError("functions and mixins cannot have more than one variable-length parameter", p->pstate());
|
||||
}
|
||||
has_rest_parameter(true);
|
||||
}
|
||||
else {
|
||||
if (has_rest_parameter()) {
|
||||
coreError("required parameters must precede variable-length parameters", p->pstate());
|
||||
}
|
||||
if (has_optional_parameters()) {
|
||||
coreError("required parameters must precede optional parameters", p->pstate());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////
|
||||
/////////////////////////////////////////////////////////////////////////
|
||||
|
||||
// If you forget to add a class here you will get
|
||||
// undefined reference to `vtable for Sass::Class'
|
||||
|
||||
IMPLEMENT_AST_OPERATORS(StyleRule);
|
||||
IMPLEMENT_AST_OPERATORS(MediaRule);
|
||||
IMPLEMENT_AST_OPERATORS(CssMediaRule);
|
||||
IMPLEMENT_AST_OPERATORS(CssMediaQuery);
|
||||
IMPLEMENT_AST_OPERATORS(Import);
|
||||
IMPLEMENT_AST_OPERATORS(Import_Stub);
|
||||
IMPLEMENT_AST_OPERATORS(AtRule);
|
||||
IMPLEMENT_AST_OPERATORS(AtRootRule);
|
||||
IMPLEMENT_AST_OPERATORS(WhileRule);
|
||||
IMPLEMENT_AST_OPERATORS(EachRule);
|
||||
IMPLEMENT_AST_OPERATORS(ForRule);
|
||||
IMPLEMENT_AST_OPERATORS(If);
|
||||
IMPLEMENT_AST_OPERATORS(Mixin_Call);
|
||||
IMPLEMENT_AST_OPERATORS(ExtendRule);
|
||||
IMPLEMENT_AST_OPERATORS(Media_Query);
|
||||
IMPLEMENT_AST_OPERATORS(Media_Query_Expression);
|
||||
IMPLEMENT_AST_OPERATORS(DebugRule);
|
||||
IMPLEMENT_AST_OPERATORS(ErrorRule);
|
||||
IMPLEMENT_AST_OPERATORS(WarningRule);
|
||||
IMPLEMENT_AST_OPERATORS(Assignment);
|
||||
IMPLEMENT_AST_OPERATORS(Return);
|
||||
IMPLEMENT_AST_OPERATORS(At_Root_Query);
|
||||
IMPLEMENT_AST_OPERATORS(Comment);
|
||||
IMPLEMENT_AST_OPERATORS(Parameters);
|
||||
IMPLEMENT_AST_OPERATORS(Parameter);
|
||||
IMPLEMENT_AST_OPERATORS(Arguments);
|
||||
IMPLEMENT_AST_OPERATORS(Argument);
|
||||
IMPLEMENT_AST_OPERATORS(Unary_Expression);
|
||||
IMPLEMENT_AST_OPERATORS(Block);
|
||||
IMPLEMENT_AST_OPERATORS(Content);
|
||||
IMPLEMENT_AST_OPERATORS(Trace);
|
||||
IMPLEMENT_AST_OPERATORS(Keyframe_Rule);
|
||||
IMPLEMENT_AST_OPERATORS(Bubble);
|
||||
IMPLEMENT_AST_OPERATORS(Definition);
|
||||
IMPLEMENT_AST_OPERATORS(Declaration);
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////
|
||||
/////////////////////////////////////////////////////////////////////////
|
||||
|
||||
}
|
||||
1064
vendor/bundle/ruby/2.6.0/gems/sassc-2.4.0/ext/libsass/src/ast.hpp
vendored
Normal file
1064
vendor/bundle/ruby/2.6.0/gems/sassc-2.4.0/ext/libsass/src/ast.hpp
vendored
Normal file
File diff suppressed because it is too large
Load Diff
80
vendor/bundle/ruby/2.6.0/gems/sassc-2.4.0/ext/libsass/src/ast2c.cpp
vendored
Normal file
80
vendor/bundle/ruby/2.6.0/gems/sassc-2.4.0/ext/libsass/src/ast2c.cpp
vendored
Normal file
@@ -0,0 +1,80 @@
|
||||
// sass.hpp must go before all system headers to get the
|
||||
// __EXTENSIONS__ fix on Solaris.
|
||||
#include "sass.hpp"
|
||||
|
||||
#include "ast2c.hpp"
|
||||
#include "ast.hpp"
|
||||
|
||||
namespace Sass {
|
||||
|
||||
union Sass_Value* AST2C::operator()(Boolean* b)
|
||||
{ return sass_make_boolean(b->value()); }
|
||||
|
||||
union Sass_Value* AST2C::operator()(Number* n)
|
||||
{ return sass_make_number(n->value(), n->unit().c_str()); }
|
||||
|
||||
union Sass_Value* AST2C::operator()(Custom_Warning* w)
|
||||
{ return sass_make_warning(w->message().c_str()); }
|
||||
|
||||
union Sass_Value* AST2C::operator()(Custom_Error* e)
|
||||
{ return sass_make_error(e->message().c_str()); }
|
||||
|
||||
union Sass_Value* AST2C::operator()(Color_RGBA* c)
|
||||
{ return sass_make_color(c->r(), c->g(), c->b(), c->a()); }
|
||||
|
||||
union Sass_Value* AST2C::operator()(Color_HSLA* c)
|
||||
{
|
||||
Color_RGBA_Obj rgba = c->copyAsRGBA();
|
||||
return operator()(rgba.ptr());
|
||||
}
|
||||
|
||||
union Sass_Value* AST2C::operator()(String_Constant* s)
|
||||
{
|
||||
if (s->quote_mark()) {
|
||||
return sass_make_qstring(s->value().c_str());
|
||||
} else {
|
||||
return sass_make_string(s->value().c_str());
|
||||
}
|
||||
}
|
||||
|
||||
union Sass_Value* AST2C::operator()(String_Quoted* s)
|
||||
{ return sass_make_qstring(s->value().c_str()); }
|
||||
|
||||
union Sass_Value* AST2C::operator()(List* l)
|
||||
{
|
||||
union Sass_Value* v = sass_make_list(l->length(), l->separator(), l->is_bracketed());
|
||||
for (size_t i = 0, L = l->length(); i < L; ++i) {
|
||||
sass_list_set_value(v, i, (*l)[i]->perform(this));
|
||||
}
|
||||
return v;
|
||||
}
|
||||
|
||||
union Sass_Value* AST2C::operator()(Map* m)
|
||||
{
|
||||
union Sass_Value* v = sass_make_map(m->length());
|
||||
int i = 0;
|
||||
for (auto key : m->keys()) {
|
||||
sass_map_set_key(v, i, key->perform(this));
|
||||
sass_map_set_value(v, i, m->at(key)->perform(this));
|
||||
i++;
|
||||
}
|
||||
return v;
|
||||
}
|
||||
|
||||
union Sass_Value* AST2C::operator()(Arguments* a)
|
||||
{
|
||||
union Sass_Value* v = sass_make_list(a->length(), SASS_COMMA, false);
|
||||
for (size_t i = 0, L = a->length(); i < L; ++i) {
|
||||
sass_list_set_value(v, i, (*a)[i]->perform(this));
|
||||
}
|
||||
return v;
|
||||
}
|
||||
|
||||
union Sass_Value* AST2C::operator()(Argument* a)
|
||||
{ return a->value()->perform(this); }
|
||||
|
||||
// not strictly necessary because of the fallback
|
||||
union Sass_Value* AST2C::operator()(Null* n)
|
||||
{ return sass_make_null(); }
|
||||
|
||||
};
|
||||
39
vendor/bundle/ruby/2.6.0/gems/sassc-2.4.0/ext/libsass/src/ast2c.hpp
vendored
Normal file
39
vendor/bundle/ruby/2.6.0/gems/sassc-2.4.0/ext/libsass/src/ast2c.hpp
vendored
Normal file
@@ -0,0 +1,39 @@
|
||||
#ifndef SASS_AST2C_H
|
||||
#define SASS_AST2C_H
|
||||
|
||||
#include "ast_fwd_decl.hpp"
|
||||
#include "operation.hpp"
|
||||
#include "sass/values.h"
|
||||
|
||||
namespace Sass {
|
||||
|
||||
class AST2C : public Operation_CRTP<union Sass_Value*, AST2C> {
|
||||
|
||||
public:
|
||||
|
||||
AST2C() { }
|
||||
~AST2C() { }
|
||||
|
||||
union Sass_Value* operator()(Boolean*);
|
||||
union Sass_Value* operator()(Number*);
|
||||
union Sass_Value* operator()(Color_RGBA*);
|
||||
union Sass_Value* operator()(Color_HSLA*);
|
||||
union Sass_Value* operator()(String_Constant*);
|
||||
union Sass_Value* operator()(String_Quoted*);
|
||||
union Sass_Value* operator()(Custom_Warning*);
|
||||
union Sass_Value* operator()(Custom_Error*);
|
||||
union Sass_Value* operator()(List*);
|
||||
union Sass_Value* operator()(Map*);
|
||||
union Sass_Value* operator()(Null*);
|
||||
union Sass_Value* operator()(Arguments*);
|
||||
union Sass_Value* operator()(Argument*);
|
||||
|
||||
// return sass error if type is not supported
|
||||
union Sass_Value* fallback(AST_Node* x)
|
||||
{ return sass_make_error("unknown type for C-API"); }
|
||||
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
140
vendor/bundle/ruby/2.6.0/gems/sassc-2.4.0/ext/libsass/src/ast_def_macros.hpp
vendored
Normal file
140
vendor/bundle/ruby/2.6.0/gems/sassc-2.4.0/ext/libsass/src/ast_def_macros.hpp
vendored
Normal file
@@ -0,0 +1,140 @@
|
||||
#ifndef SASS_AST_DEF_MACROS_H
|
||||
#define SASS_AST_DEF_MACROS_H
|
||||
|
||||
// Helper class to switch a flag and revert once we go out of scope
|
||||
template <class T>
|
||||
class LocalOption {
|
||||
private:
|
||||
T* var; // pointer to original variable
|
||||
T orig; // copy of the original option
|
||||
public:
|
||||
LocalOption(T& var)
|
||||
{
|
||||
this->var = &var;
|
||||
this->orig = var;
|
||||
}
|
||||
LocalOption(T& var, T orig)
|
||||
{
|
||||
this->var = &var;
|
||||
this->orig = var;
|
||||
*(this->var) = orig;
|
||||
}
|
||||
void reset()
|
||||
{
|
||||
*(this->var) = this->orig;
|
||||
}
|
||||
~LocalOption() {
|
||||
*(this->var) = this->orig;
|
||||
}
|
||||
};
|
||||
|
||||
#define LOCAL_FLAG(name,opt) LocalOption<bool> flag_##name(name, opt)
|
||||
#define LOCAL_COUNT(name,opt) LocalOption<size_t> cnt_##name(name, opt)
|
||||
|
||||
#define NESTING_GUARD(name) \
|
||||
LocalOption<size_t> cnt_##name(name, name + 1); \
|
||||
if (name > MAX_NESTING) throw Exception::NestingLimitError(pstate, traces); \
|
||||
|
||||
#define ADD_PROPERTY(type, name)\
|
||||
protected:\
|
||||
type name##_;\
|
||||
public:\
|
||||
type name() const { return name##_; }\
|
||||
type name(type name##__) { return name##_ = name##__; }\
|
||||
private:
|
||||
|
||||
#define HASH_PROPERTY(type, name)\
|
||||
protected:\
|
||||
type name##_;\
|
||||
public:\
|
||||
type name() const { return name##_; }\
|
||||
type name(type name##__) { hash_ = 0; return name##_ = name##__; }\
|
||||
private:
|
||||
|
||||
#define ADD_CONSTREF(type, name) \
|
||||
protected: \
|
||||
type name##_; \
|
||||
public: \
|
||||
const type& name() const { return name##_; } \
|
||||
void name(type name##__) { name##_ = name##__; } \
|
||||
private:
|
||||
|
||||
#define HASH_CONSTREF(type, name) \
|
||||
protected: \
|
||||
type name##_; \
|
||||
public: \
|
||||
const type& name() const { return name##_; } \
|
||||
void name(type name##__) { hash_ = 0; name##_ = name##__; } \
|
||||
private:
|
||||
|
||||
#ifdef DEBUG_SHARED_PTR
|
||||
|
||||
#define ATTACH_ABSTRACT_AST_OPERATIONS(klass) \
|
||||
virtual klass* copy(sass::string, size_t) const = 0; \
|
||||
virtual klass* clone(sass::string, size_t) const = 0; \
|
||||
|
||||
#define ATTACH_VIRTUAL_AST_OPERATIONS(klass) \
|
||||
klass(const klass* ptr); \
|
||||
virtual klass* copy(sass::string, size_t) const override = 0; \
|
||||
virtual klass* clone(sass::string, size_t) const override = 0; \
|
||||
|
||||
#define ATTACH_AST_OPERATIONS(klass) \
|
||||
klass(const klass* ptr); \
|
||||
virtual klass* copy(sass::string, size_t) const override; \
|
||||
virtual klass* clone(sass::string, size_t) const override; \
|
||||
|
||||
#else
|
||||
|
||||
#define ATTACH_ABSTRACT_AST_OPERATIONS(klass) \
|
||||
virtual klass* copy() const = 0; \
|
||||
virtual klass* clone() const = 0; \
|
||||
|
||||
#define ATTACH_VIRTUAL_AST_OPERATIONS(klass) \
|
||||
klass(const klass* ptr); \
|
||||
virtual klass* copy() const override = 0; \
|
||||
virtual klass* clone() const override = 0; \
|
||||
|
||||
#define ATTACH_AST_OPERATIONS(klass) \
|
||||
klass(const klass* ptr); \
|
||||
virtual klass* copy() const override; \
|
||||
virtual klass* clone() const override; \
|
||||
|
||||
#endif
|
||||
|
||||
#define ATTACH_VIRTUAL_CMP_OPERATIONS(klass) \
|
||||
virtual bool operator==(const klass& rhs) const = 0; \
|
||||
virtual bool operator!=(const klass& rhs) const { return !(*this == rhs); }; \
|
||||
|
||||
#define ATTACH_CMP_OPERATIONS(klass) \
|
||||
virtual bool operator==(const klass& rhs) const; \
|
||||
virtual bool operator!=(const klass& rhs) const { return !(*this == rhs); }; \
|
||||
|
||||
#ifdef DEBUG_SHARED_PTR
|
||||
|
||||
#define IMPLEMENT_AST_OPERATORS(klass) \
|
||||
klass* klass::copy(sass::string file, size_t line) const { \
|
||||
klass* cpy = SASS_MEMORY_NEW(klass, this); \
|
||||
cpy->trace(file, line); \
|
||||
return cpy; \
|
||||
} \
|
||||
klass* klass::clone(sass::string file, size_t line) const { \
|
||||
klass* cpy = copy(file, line); \
|
||||
cpy->cloneChildren(); \
|
||||
return cpy; \
|
||||
} \
|
||||
|
||||
#else
|
||||
|
||||
#define IMPLEMENT_AST_OPERATORS(klass) \
|
||||
klass* klass::copy() const { \
|
||||
return SASS_MEMORY_NEW(klass, this); \
|
||||
} \
|
||||
klass* klass::clone() const { \
|
||||
klass* cpy = copy(); \
|
||||
cpy->cloneChildren(); \
|
||||
return cpy; \
|
||||
} \
|
||||
|
||||
#endif
|
||||
|
||||
#endif
|
||||
31
vendor/bundle/ruby/2.6.0/gems/sassc-2.4.0/ext/libsass/src/ast_fwd_decl.cpp
vendored
Normal file
31
vendor/bundle/ruby/2.6.0/gems/sassc-2.4.0/ext/libsass/src/ast_fwd_decl.cpp
vendored
Normal file
@@ -0,0 +1,31 @@
|
||||
#include "ast.hpp"
|
||||
|
||||
namespace Sass {
|
||||
|
||||
#define IMPLEMENT_BASE_CAST(T) \
|
||||
template<> \
|
||||
T* Cast(AST_Node* ptr) { \
|
||||
return dynamic_cast<T*>(ptr); \
|
||||
}; \
|
||||
\
|
||||
template<> \
|
||||
const T* Cast(const AST_Node* ptr) { \
|
||||
return dynamic_cast<const T*>(ptr); \
|
||||
}; \
|
||||
|
||||
IMPLEMENT_BASE_CAST(AST_Node)
|
||||
IMPLEMENT_BASE_CAST(Expression)
|
||||
IMPLEMENT_BASE_CAST(Statement)
|
||||
IMPLEMENT_BASE_CAST(ParentStatement)
|
||||
IMPLEMENT_BASE_CAST(PreValue)
|
||||
IMPLEMENT_BASE_CAST(Value)
|
||||
IMPLEMENT_BASE_CAST(Color)
|
||||
IMPLEMENT_BASE_CAST(List)
|
||||
IMPLEMENT_BASE_CAST(String)
|
||||
IMPLEMENT_BASE_CAST(String_Constant)
|
||||
IMPLEMENT_BASE_CAST(SupportsCondition)
|
||||
IMPLEMENT_BASE_CAST(Selector)
|
||||
IMPLEMENT_BASE_CAST(SelectorComponent)
|
||||
IMPLEMENT_BASE_CAST(SimpleSelector)
|
||||
|
||||
}
|
||||
274
vendor/bundle/ruby/2.6.0/gems/sassc-2.4.0/ext/libsass/src/ast_fwd_decl.hpp
vendored
Normal file
274
vendor/bundle/ruby/2.6.0/gems/sassc-2.4.0/ext/libsass/src/ast_fwd_decl.hpp
vendored
Normal file
@@ -0,0 +1,274 @@
|
||||
#ifndef SASS_AST_FWD_DECL_H
|
||||
#define SASS_AST_FWD_DECL_H
|
||||
|
||||
// sass.hpp must go before all system headers to get the
|
||||
// __EXTENSIONS__ fix on Solaris.
|
||||
#include "sass.hpp"
|
||||
#include "memory.hpp"
|
||||
#include "sass/functions.h"
|
||||
|
||||
/////////////////////////////////////////////
|
||||
// Forward declarations for the AST visitors.
|
||||
/////////////////////////////////////////////
|
||||
namespace Sass {
|
||||
|
||||
class SourceData;
|
||||
class SourceFile;
|
||||
class SynthFile;
|
||||
class ItplFile;
|
||||
|
||||
class AST_Node;
|
||||
|
||||
class ParentStatement;
|
||||
|
||||
class SimpleSelector;
|
||||
|
||||
class Parent_Reference;
|
||||
|
||||
class PreValue;
|
||||
class Block;
|
||||
class Expression;
|
||||
class Statement;
|
||||
class Value;
|
||||
class Declaration;
|
||||
class StyleRule;
|
||||
class Bubble;
|
||||
class Trace;
|
||||
|
||||
class MediaRule;
|
||||
class CssMediaRule;
|
||||
class CssMediaQuery;
|
||||
|
||||
class SupportsRule;
|
||||
class AtRule;
|
||||
|
||||
class Keyframe_Rule;
|
||||
class AtRootRule;
|
||||
class Assignment;
|
||||
|
||||
class Import;
|
||||
class Import_Stub;
|
||||
class WarningRule;
|
||||
|
||||
class ErrorRule;
|
||||
class DebugRule;
|
||||
class Comment;
|
||||
|
||||
class If;
|
||||
class ForRule;
|
||||
class EachRule;
|
||||
class WhileRule;
|
||||
class Return;
|
||||
class Content;
|
||||
class ExtendRule;
|
||||
class Definition;
|
||||
|
||||
class List;
|
||||
class Map;
|
||||
class Function;
|
||||
|
||||
class Mixin_Call;
|
||||
class Binary_Expression;
|
||||
class Unary_Expression;
|
||||
class Function_Call;
|
||||
class Custom_Warning;
|
||||
class Custom_Error;
|
||||
|
||||
class Variable;
|
||||
class Number;
|
||||
class Color;
|
||||
class Color_RGBA;
|
||||
class Color_HSLA;
|
||||
class Boolean;
|
||||
class String;
|
||||
class Null;
|
||||
|
||||
class String_Schema;
|
||||
class String_Constant;
|
||||
class String_Quoted;
|
||||
|
||||
class Media_Query;
|
||||
class Media_Query_Expression;
|
||||
class SupportsCondition;
|
||||
class SupportsOperation;
|
||||
class SupportsNegation;
|
||||
class SupportsDeclaration;
|
||||
class Supports_Interpolation;
|
||||
|
||||
class At_Root_Query;
|
||||
class Parameter;
|
||||
class Parameters;
|
||||
class Argument;
|
||||
class Arguments;
|
||||
class Selector;
|
||||
|
||||
|
||||
class Selector_Schema;
|
||||
class PlaceholderSelector;
|
||||
class TypeSelector;
|
||||
class ClassSelector;
|
||||
class IDSelector;
|
||||
class AttributeSelector;
|
||||
|
||||
class PseudoSelector;
|
||||
|
||||
class SelectorComponent;
|
||||
class SelectorCombinator;
|
||||
class CompoundSelector;
|
||||
class ComplexSelector;
|
||||
class SelectorList;
|
||||
|
||||
// common classes
|
||||
class Context;
|
||||
class Expand;
|
||||
class Eval;
|
||||
|
||||
class Extension;
|
||||
|
||||
// declare classes that are instances of memory nodes
|
||||
// Note: also add a mapping without underscore
|
||||
// ToDo: move to camelCase vars in the future
|
||||
#define IMPL_MEM_OBJ(type) \
|
||||
typedef SharedImpl<type> type##Obj; \
|
||||
typedef SharedImpl<type> type##_Obj; \
|
||||
|
||||
IMPL_MEM_OBJ(SourceData);
|
||||
IMPL_MEM_OBJ(SourceFile);
|
||||
IMPL_MEM_OBJ(SynthFile);
|
||||
IMPL_MEM_OBJ(ItplFile);
|
||||
|
||||
IMPL_MEM_OBJ(AST_Node);
|
||||
IMPL_MEM_OBJ(Statement);
|
||||
IMPL_MEM_OBJ(Block);
|
||||
IMPL_MEM_OBJ(StyleRule);
|
||||
IMPL_MEM_OBJ(Bubble);
|
||||
IMPL_MEM_OBJ(Trace);
|
||||
IMPL_MEM_OBJ(MediaRule);
|
||||
IMPL_MEM_OBJ(CssMediaRule);
|
||||
IMPL_MEM_OBJ(CssMediaQuery);
|
||||
IMPL_MEM_OBJ(SupportsRule);
|
||||
IMPL_MEM_OBJ(AtRule);
|
||||
IMPL_MEM_OBJ(Keyframe_Rule);
|
||||
IMPL_MEM_OBJ(AtRootRule);
|
||||
IMPL_MEM_OBJ(Declaration);
|
||||
IMPL_MEM_OBJ(Assignment);
|
||||
IMPL_MEM_OBJ(Import);
|
||||
IMPL_MEM_OBJ(Import_Stub);
|
||||
IMPL_MEM_OBJ(WarningRule);
|
||||
IMPL_MEM_OBJ(ErrorRule);
|
||||
IMPL_MEM_OBJ(DebugRule);
|
||||
IMPL_MEM_OBJ(Comment);
|
||||
IMPL_MEM_OBJ(PreValue);
|
||||
IMPL_MEM_OBJ(ParentStatement);
|
||||
IMPL_MEM_OBJ(If);
|
||||
IMPL_MEM_OBJ(ForRule);
|
||||
IMPL_MEM_OBJ(EachRule);
|
||||
IMPL_MEM_OBJ(WhileRule);
|
||||
IMPL_MEM_OBJ(Return);
|
||||
IMPL_MEM_OBJ(Content);
|
||||
IMPL_MEM_OBJ(ExtendRule);
|
||||
IMPL_MEM_OBJ(Definition);
|
||||
IMPL_MEM_OBJ(Mixin_Call);
|
||||
IMPL_MEM_OBJ(Value);
|
||||
IMPL_MEM_OBJ(Expression);
|
||||
IMPL_MEM_OBJ(List);
|
||||
IMPL_MEM_OBJ(Map);
|
||||
IMPL_MEM_OBJ(Function);
|
||||
IMPL_MEM_OBJ(Binary_Expression);
|
||||
IMPL_MEM_OBJ(Unary_Expression);
|
||||
IMPL_MEM_OBJ(Function_Call);
|
||||
IMPL_MEM_OBJ(Custom_Warning);
|
||||
IMPL_MEM_OBJ(Custom_Error);
|
||||
IMPL_MEM_OBJ(Variable);
|
||||
IMPL_MEM_OBJ(Number);
|
||||
IMPL_MEM_OBJ(Color);
|
||||
IMPL_MEM_OBJ(Color_RGBA);
|
||||
IMPL_MEM_OBJ(Color_HSLA);
|
||||
IMPL_MEM_OBJ(Boolean);
|
||||
IMPL_MEM_OBJ(String_Schema);
|
||||
IMPL_MEM_OBJ(String);
|
||||
IMPL_MEM_OBJ(String_Constant);
|
||||
IMPL_MEM_OBJ(String_Quoted);
|
||||
IMPL_MEM_OBJ(Media_Query);
|
||||
IMPL_MEM_OBJ(Media_Query_Expression);
|
||||
IMPL_MEM_OBJ(SupportsCondition);
|
||||
IMPL_MEM_OBJ(SupportsOperation);
|
||||
IMPL_MEM_OBJ(SupportsNegation);
|
||||
IMPL_MEM_OBJ(SupportsDeclaration);
|
||||
IMPL_MEM_OBJ(Supports_Interpolation);
|
||||
IMPL_MEM_OBJ(At_Root_Query);
|
||||
IMPL_MEM_OBJ(Null);
|
||||
IMPL_MEM_OBJ(Parent_Reference);
|
||||
IMPL_MEM_OBJ(Parameter);
|
||||
IMPL_MEM_OBJ(Parameters);
|
||||
IMPL_MEM_OBJ(Argument);
|
||||
IMPL_MEM_OBJ(Arguments);
|
||||
IMPL_MEM_OBJ(Selector);
|
||||
IMPL_MEM_OBJ(Selector_Schema);
|
||||
IMPL_MEM_OBJ(SimpleSelector);
|
||||
IMPL_MEM_OBJ(PlaceholderSelector);
|
||||
IMPL_MEM_OBJ(TypeSelector);
|
||||
IMPL_MEM_OBJ(ClassSelector);
|
||||
IMPL_MEM_OBJ(IDSelector);
|
||||
IMPL_MEM_OBJ(AttributeSelector);
|
||||
IMPL_MEM_OBJ(PseudoSelector);
|
||||
|
||||
IMPL_MEM_OBJ(SelectorComponent);
|
||||
IMPL_MEM_OBJ(SelectorCombinator);
|
||||
IMPL_MEM_OBJ(CompoundSelector);
|
||||
IMPL_MEM_OBJ(ComplexSelector);
|
||||
IMPL_MEM_OBJ(SelectorList);
|
||||
|
||||
// ###########################################################################
|
||||
// some often used typedefs
|
||||
// ###########################################################################
|
||||
|
||||
typedef sass::vector<Block*> BlockStack;
|
||||
typedef sass::vector<Sass_Callee> CalleeStack;
|
||||
typedef sass::vector<AST_Node_Obj> CallStack;
|
||||
typedef sass::vector<CssMediaRuleObj> MediaStack;
|
||||
typedef sass::vector<SelectorListObj> SelectorStack;
|
||||
typedef sass::vector<Sass_Import_Entry> ImporterStack;
|
||||
|
||||
// only to switch implementations for testing
|
||||
#define environment_map std::map
|
||||
|
||||
// ###########################################################################
|
||||
// explicit type conversion functions
|
||||
// ###########################################################################
|
||||
|
||||
template<class T>
|
||||
T* Cast(AST_Node* ptr);
|
||||
|
||||
template<class T>
|
||||
const T* Cast(const AST_Node* ptr);
|
||||
|
||||
// sometimes you know the class you want to cast to is final
|
||||
// in this case a simple typeid check is faster and safe to use
|
||||
|
||||
#define DECLARE_BASE_CAST(T) \
|
||||
template<> T* Cast(AST_Node* ptr); \
|
||||
template<> const T* Cast(const AST_Node* ptr); \
|
||||
|
||||
// ###########################################################################
|
||||
// implement specialization for final classes
|
||||
// ###########################################################################
|
||||
|
||||
DECLARE_BASE_CAST(AST_Node)
|
||||
DECLARE_BASE_CAST(Expression)
|
||||
DECLARE_BASE_CAST(Statement)
|
||||
DECLARE_BASE_CAST(ParentStatement)
|
||||
DECLARE_BASE_CAST(PreValue)
|
||||
DECLARE_BASE_CAST(Value)
|
||||
DECLARE_BASE_CAST(List)
|
||||
DECLARE_BASE_CAST(Color)
|
||||
DECLARE_BASE_CAST(String)
|
||||
DECLARE_BASE_CAST(String_Constant)
|
||||
DECLARE_BASE_CAST(SupportsCondition)
|
||||
DECLARE_BASE_CAST(Selector)
|
||||
DECLARE_BASE_CAST(SimpleSelector)
|
||||
DECLARE_BASE_CAST(SelectorComponent)
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
292
vendor/bundle/ruby/2.6.0/gems/sassc-2.4.0/ext/libsass/src/ast_helpers.hpp
vendored
Normal file
292
vendor/bundle/ruby/2.6.0/gems/sassc-2.4.0/ext/libsass/src/ast_helpers.hpp
vendored
Normal file
@@ -0,0 +1,292 @@
|
||||
#ifndef SASS_AST_HELPERS_H
|
||||
#define SASS_AST_HELPERS_H
|
||||
|
||||
// sass.hpp must go before all system headers to get the
|
||||
// __EXTENSIONS__ fix on Solaris.
|
||||
#include "sass.hpp"
|
||||
#include <algorithm>
|
||||
#include <functional>
|
||||
#include "util_string.hpp"
|
||||
|
||||
namespace Sass {
|
||||
|
||||
// ###########################################################################
|
||||
// ###########################################################################
|
||||
|
||||
// easier to search with name
|
||||
const bool DELAYED = true;
|
||||
|
||||
// ToDo: should this really be hardcoded
|
||||
// Note: most methods follow precision option
|
||||
const double NUMBER_EPSILON = 1e-12;
|
||||
|
||||
// macro to test if numbers are equal within a small error margin
|
||||
#define NEAR_EQUAL(lhs, rhs) std::fabs(lhs - rhs) < NUMBER_EPSILON
|
||||
|
||||
// ###########################################################################
|
||||
// We define various functions and functors here.
|
||||
// Functions satisfy the BinaryPredicate requirement
|
||||
// Functors are structs used for e.g. unordered_map
|
||||
// ###########################################################################
|
||||
|
||||
// ###########################################################################
|
||||
// Implement compare and hashing operations for raw pointers
|
||||
// ###########################################################################
|
||||
|
||||
template <class T>
|
||||
size_t PtrHashFn(const T* ptr) {
|
||||
return std::hash<std::size_t>()((size_t)ptr);
|
||||
}
|
||||
|
||||
struct PtrHash {
|
||||
template <class T>
|
||||
size_t operator() (const T* ptr) const {
|
||||
return PtrHashFn(ptr);
|
||||
}
|
||||
};
|
||||
|
||||
template <class T>
|
||||
bool PtrEqualityFn(const T* lhs, const T* rhs) {
|
||||
return lhs == rhs; // compare raw pointers
|
||||
}
|
||||
|
||||
struct PtrEquality {
|
||||
template <class T>
|
||||
bool operator() (const T* lhs, const T* rhs) const {
|
||||
return PtrEqualityFn<T>(lhs, rhs);
|
||||
}
|
||||
};
|
||||
|
||||
// ###########################################################################
|
||||
// Implement compare and hashing operations for AST Nodes
|
||||
// ###########################################################################
|
||||
|
||||
// TODO: get rid of funtions and use ObjEquality<T>
|
||||
|
||||
template <class T>
|
||||
// Hash the raw pointer instead of object
|
||||
size_t ObjPtrHashFn(const T& obj) {
|
||||
return PtrHashFn(obj.ptr());
|
||||
}
|
||||
|
||||
struct ObjPtrHash {
|
||||
template <class T>
|
||||
// Hash the raw pointer instead of object
|
||||
size_t operator() (const T& obj) const {
|
||||
return ObjPtrHashFn(obj);
|
||||
}
|
||||
};
|
||||
|
||||
template <class T>
|
||||
// Hash the object and its content
|
||||
size_t ObjHashFn(const T& obj) {
|
||||
return obj ? obj->hash() : 0;
|
||||
}
|
||||
|
||||
struct ObjHash {
|
||||
template <class T>
|
||||
// Hash the object and its content
|
||||
size_t operator() (const T& obj) const {
|
||||
return ObjHashFn(obj);
|
||||
}
|
||||
};
|
||||
|
||||
template <class T>
|
||||
// Hash the object behind pointer
|
||||
size_t PtrObjHashFn(const T* obj) {
|
||||
return obj ? obj->hash() : 0;
|
||||
}
|
||||
|
||||
struct PtrObjHash {
|
||||
template <class T>
|
||||
// Hash the object behind pointer
|
||||
size_t operator() (const T* obj) const {
|
||||
return PtrObjHashFn(obj);
|
||||
}
|
||||
};
|
||||
|
||||
template <class T>
|
||||
// Compare raw pointers to the object
|
||||
bool ObjPtrEqualityFn(const T& lhs, const T& rhs) {
|
||||
return PtrEqualityFn(lhs.ptr(), rhs.ptr());
|
||||
}
|
||||
|
||||
struct ObjPtrEquality {
|
||||
template <class T>
|
||||
// Compare raw pointers to the object
|
||||
bool operator() (const T& lhs, const T& rhs) const {
|
||||
return ObjPtrEqualityFn<T>(lhs, rhs);
|
||||
}
|
||||
};
|
||||
|
||||
template <class T>
|
||||
// Compare the objects behind the pointers
|
||||
bool PtrObjEqualityFn(const T* lhs, const T* rhs) {
|
||||
if (lhs == nullptr) return rhs == nullptr;
|
||||
else if (rhs == nullptr) return false;
|
||||
else return *lhs == *rhs;
|
||||
}
|
||||
|
||||
struct PtrObjEquality {
|
||||
template <class T>
|
||||
// Compare the objects behind the pointers
|
||||
bool operator() (const T* lhs, const T* rhs) const {
|
||||
return PtrObjEqualityFn<T>(lhs, rhs);
|
||||
}
|
||||
};
|
||||
|
||||
template <class T>
|
||||
// Compare the objects and its contents
|
||||
bool ObjEqualityFn(const T& lhs, const T& rhs) {
|
||||
return PtrObjEqualityFn(lhs.ptr(), rhs.ptr());
|
||||
}
|
||||
|
||||
struct ObjEquality {
|
||||
template <class T>
|
||||
// Compare the objects and its contents
|
||||
bool operator() (const T& lhs, const T& rhs) const {
|
||||
return ObjEqualityFn<T>(lhs, rhs);
|
||||
}
|
||||
};
|
||||
|
||||
// ###########################################################################
|
||||
// Implement ordering operations for AST Nodes
|
||||
// ###########################################################################
|
||||
|
||||
template <class T>
|
||||
// Compare the objects behind pointers
|
||||
bool PtrObjLessThanFn(const T* lhs, const T* rhs) {
|
||||
if (lhs == nullptr) return rhs != nullptr;
|
||||
else if (rhs == nullptr) return false;
|
||||
else return *lhs < *rhs;
|
||||
}
|
||||
|
||||
struct PtrObjLessThan {
|
||||
template <class T>
|
||||
// Compare the objects behind pointers
|
||||
bool operator() (const T* lhs, const T* rhs) const {
|
||||
return PtrObjLessThanFn<T>(lhs, rhs);
|
||||
}
|
||||
};
|
||||
|
||||
template <class T>
|
||||
// Compare the objects and its content
|
||||
bool ObjLessThanFn(const T& lhs, const T& rhs) {
|
||||
return PtrObjLessThanFn(lhs.ptr(), rhs.ptr());
|
||||
};
|
||||
|
||||
struct ObjLessThan {
|
||||
template <class T>
|
||||
// Compare the objects and its content
|
||||
bool operator() (const T& lhs, const T& rhs) const {
|
||||
return ObjLessThanFn<T>(lhs, rhs);
|
||||
}
|
||||
};
|
||||
|
||||
// ###########################################################################
|
||||
// Some STL helper functions
|
||||
// ###########################################################################
|
||||
|
||||
// Check if all elements are equal
|
||||
template <class X, class Y,
|
||||
typename XT = typename X::value_type,
|
||||
typename YT = typename Y::value_type>
|
||||
bool ListEquality(const X& lhs, const Y& rhs,
|
||||
bool(*cmp)(const XT*, const YT*))
|
||||
{
|
||||
return lhs.size() == rhs.size() &&
|
||||
std::equal(lhs.begin(), lhs.end(),
|
||||
rhs.begin(), cmp);
|
||||
}
|
||||
|
||||
// Return if Vector is empty
|
||||
template <class T>
|
||||
bool listIsEmpty(T* cnt) {
|
||||
return cnt && cnt->empty();
|
||||
}
|
||||
|
||||
// Erase items from vector that match predicate
|
||||
template<class T, class UnaryPredicate>
|
||||
void listEraseItemIf(T& vec, UnaryPredicate* predicate)
|
||||
{
|
||||
vec.erase(std::remove_if(vec.begin(), vec.end(), predicate), vec.end());
|
||||
}
|
||||
|
||||
// Check that every item in `lhs` is also in `rhs`
|
||||
// Note: this works by comparing the raw pointers
|
||||
template <typename T>
|
||||
bool listIsSubsetOrEqual(const T& lhs, const T& rhs) {
|
||||
for (const auto& item : lhs) {
|
||||
if (std::find(rhs.begin(), rhs.end(), item) == rhs.end())
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
// ##########################################################################
|
||||
// Returns whether [name] is the name of a pseudo-element
|
||||
// that can be written with pseudo-class syntax (CSS2 vs CSS3):
|
||||
// `:before`, `:after`, `:first-line`, or `:first-letter`
|
||||
// ##########################################################################
|
||||
inline bool isFakePseudoElement(const sass::string& name)
|
||||
{
|
||||
return Util::equalsLiteral("after", name)
|
||||
|| Util::equalsLiteral("before", name)
|
||||
|| Util::equalsLiteral("first-line", name)
|
||||
|| Util::equalsLiteral("first-letter", name);
|
||||
}
|
||||
|
||||
// ##########################################################################
|
||||
// Names of pseudo selectors that take selectors as arguments,
|
||||
// and that are subselectors of their arguments.
|
||||
// For example, `.foo` is a superselector of `:matches(.foo)`.
|
||||
// ##########################################################################
|
||||
inline bool isSubselectorPseudo(const sass::string& norm)
|
||||
{
|
||||
return Util::equalsLiteral("any", norm)
|
||||
|| Util::equalsLiteral("matches", norm)
|
||||
|| Util::equalsLiteral("nth-child", norm)
|
||||
|| Util::equalsLiteral("nth-last-child", norm);
|
||||
}
|
||||
// EO isSubselectorPseudo
|
||||
|
||||
// ###########################################################################
|
||||
// Pseudo-class selectors that take unadorned selectors as arguments.
|
||||
// ###########################################################################
|
||||
inline bool isSelectorPseudoClass(const sass::string& test)
|
||||
{
|
||||
return Util::equalsLiteral("not", test)
|
||||
|| Util::equalsLiteral("matches", test)
|
||||
|| Util::equalsLiteral("current", test)
|
||||
|| Util::equalsLiteral("any", test)
|
||||
|| Util::equalsLiteral("has", test)
|
||||
|| Util::equalsLiteral("host", test)
|
||||
|| Util::equalsLiteral("host-context", test);
|
||||
}
|
||||
// EO isSelectorPseudoClass
|
||||
|
||||
// ###########################################################################
|
||||
// Pseudo-element selectors that take unadorned selectors as arguments.
|
||||
// ###########################################################################
|
||||
inline bool isSelectorPseudoElement(const sass::string& test)
|
||||
{
|
||||
return Util::equalsLiteral("slotted", test);
|
||||
}
|
||||
// EO isSelectorPseudoElement
|
||||
|
||||
// ###########################################################################
|
||||
// Pseudo-element selectors that has binominals
|
||||
// ###########################################################################
|
||||
inline bool isSelectorPseudoBinominal(const sass::string& test)
|
||||
{
|
||||
return Util::equalsLiteral("nth-child", test)
|
||||
|| Util::equalsLiteral("nth-last-child", test);
|
||||
}
|
||||
// isSelectorPseudoBinominal
|
||||
|
||||
// ###########################################################################
|
||||
// ###########################################################################
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
396
vendor/bundle/ruby/2.6.0/gems/sassc-2.4.0/ext/libsass/src/ast_sel_cmp.cpp
vendored
Normal file
396
vendor/bundle/ruby/2.6.0/gems/sassc-2.4.0/ext/libsass/src/ast_sel_cmp.cpp
vendored
Normal file
@@ -0,0 +1,396 @@
|
||||
// sass.hpp must go before all system headers to get the
|
||||
// __EXTENSIONS__ fix on Solaris.
|
||||
#include "sass.hpp"
|
||||
|
||||
#include "ast_selectors.hpp"
|
||||
|
||||
namespace Sass {
|
||||
|
||||
/*#########################################################################*/
|
||||
// Compare against base class on right hand side
|
||||
// try to find the most specialized implementation
|
||||
/*#########################################################################*/
|
||||
|
||||
// Selector lists can be compared to comma lists
|
||||
bool SelectorList::operator== (const Expression& rhs) const
|
||||
{
|
||||
if (auto l = Cast<List>(&rhs)) { return *this == *l; }
|
||||
if (auto s = Cast<Selector>(&rhs)) { return *this == *s; }
|
||||
if (Cast<String>(&rhs) || Cast<Null>(&rhs)) { return false; }
|
||||
throw std::runtime_error("invalid selector base classes to compare");
|
||||
}
|
||||
|
||||
// Selector lists can be compared to comma lists
|
||||
bool SelectorList::operator== (const Selector& rhs) const
|
||||
{
|
||||
if (auto sel = Cast<SelectorList>(&rhs)) { return *this == *sel; }
|
||||
if (auto sel = Cast<ComplexSelector>(&rhs)) { return *this == *sel; }
|
||||
if (auto sel = Cast<CompoundSelector>(&rhs)) { return *this == *sel; }
|
||||
if (auto sel = Cast<SimpleSelector>(&rhs)) { return *this == *sel; }
|
||||
if (auto list = Cast<List>(&rhs)) { return *this == *list; }
|
||||
throw std::runtime_error("invalid selector base classes to compare");
|
||||
}
|
||||
|
||||
bool ComplexSelector::operator== (const Selector& rhs) const
|
||||
{
|
||||
if (auto sel = Cast<SelectorList>(&rhs)) { return *this == *sel; }
|
||||
if (auto sel = Cast<ComplexSelector>(&rhs)) { return *sel == *this; }
|
||||
if (auto sel = Cast<CompoundSelector>(&rhs)) { return *this == *sel; }
|
||||
if (auto sel = Cast<SimpleSelector>(&rhs)) { return *this == *sel; }
|
||||
throw std::runtime_error("invalid selector base classes to compare");
|
||||
}
|
||||
|
||||
bool SelectorCombinator::operator== (const Selector& rhs) const
|
||||
{
|
||||
if (auto cpx = Cast<SelectorCombinator>(&rhs)) { return *this == *cpx; }
|
||||
return false;
|
||||
}
|
||||
|
||||
bool CompoundSelector::operator== (const Selector& rhs) const
|
||||
{
|
||||
if (auto sel = Cast<SimpleSelector>(&rhs)) { return *this == *sel; }
|
||||
if (auto sel = Cast<SelectorList>(&rhs)) { return *this == *sel; }
|
||||
if (auto sel = Cast<ComplexSelector>(&rhs)) { return *this == *sel; }
|
||||
if (auto sel = Cast<CompoundSelector>(&rhs)) { return *this == *sel; }
|
||||
throw std::runtime_error("invalid selector base classes to compare");
|
||||
}
|
||||
|
||||
bool SimpleSelector::operator== (const Selector& rhs) const
|
||||
{
|
||||
if (auto sel = Cast<SelectorList>(&rhs)) { return *this == *sel; }
|
||||
if (auto sel = Cast<ComplexSelector>(&rhs)) { return *this == *sel; }
|
||||
if (auto sel = Cast<CompoundSelector>(&rhs)) { return *this == *sel; }
|
||||
if (auto sel = Cast<SimpleSelector>(&rhs)) return *this == *sel;
|
||||
throw std::runtime_error("invalid selector base classes to compare");
|
||||
}
|
||||
|
||||
/*#########################################################################*/
|
||||
/*#########################################################################*/
|
||||
|
||||
bool SelectorList::operator== (const SelectorList& rhs) const
|
||||
{
|
||||
if (&rhs == this) return true;
|
||||
if (rhs.length() != length()) return false;
|
||||
std::unordered_set<const ComplexSelector*, PtrObjHash, PtrObjEquality> lhs_set;
|
||||
lhs_set.reserve(length());
|
||||
for (const ComplexSelectorObj& element : elements()) {
|
||||
lhs_set.insert(element.ptr());
|
||||
}
|
||||
for (const ComplexSelectorObj& element : rhs.elements()) {
|
||||
if (lhs_set.find(element.ptr()) == lhs_set.end()) return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*#########################################################################*/
|
||||
// Compare SelectorList against all other selector types
|
||||
/*#########################################################################*/
|
||||
|
||||
bool SelectorList::operator== (const ComplexSelector& rhs) const
|
||||
{
|
||||
// If both are empty they are equal
|
||||
if (empty() && rhs.empty()) return true;
|
||||
// Must have exactly one item
|
||||
if (length() != 1) return false;
|
||||
// Compare simple selectors
|
||||
return *get(0) == rhs;
|
||||
}
|
||||
|
||||
bool SelectorList::operator== (const CompoundSelector& rhs) const
|
||||
{
|
||||
// If both are empty they are equal
|
||||
if (empty() && rhs.empty()) return true;
|
||||
// Must have exactly one item
|
||||
if (length() != 1) return false;
|
||||
// Compare simple selectors
|
||||
return *get(0) == rhs;
|
||||
}
|
||||
|
||||
bool SelectorList::operator== (const SimpleSelector& rhs) const
|
||||
{
|
||||
// If both are empty they are equal
|
||||
if (empty() && rhs.empty()) return true;
|
||||
// Must have exactly one item
|
||||
if (length() != 1) return false;
|
||||
// Compare simple selectors
|
||||
return *get(0) == rhs;
|
||||
}
|
||||
|
||||
/*#########################################################################*/
|
||||
// Compare ComplexSelector against itself
|
||||
/*#########################################################################*/
|
||||
|
||||
bool ComplexSelector::operator== (const ComplexSelector& rhs) const
|
||||
{
|
||||
size_t len = length();
|
||||
size_t rlen = rhs.length();
|
||||
if (len != rlen) return false;
|
||||
for (size_t i = 0; i < len; i += 1) {
|
||||
if (*get(i) != *rhs.get(i)) return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
/*#########################################################################*/
|
||||
// Compare ComplexSelector against all other selector types
|
||||
/*#########################################################################*/
|
||||
|
||||
bool ComplexSelector::operator== (const SelectorList& rhs) const
|
||||
{
|
||||
// If both are empty they are equal
|
||||
if (empty() && rhs.empty()) return true;
|
||||
// Must have exactly one item
|
||||
if (rhs.length() != 1) return false;
|
||||
// Compare complex selector
|
||||
return *this == *rhs.get(0);
|
||||
}
|
||||
|
||||
bool ComplexSelector::operator== (const CompoundSelector& rhs) const
|
||||
{
|
||||
// If both are empty they are equal
|
||||
if (empty() && rhs.empty()) return true;
|
||||
// Must have exactly one item
|
||||
if (length() != 1) return false;
|
||||
// Compare compound selector
|
||||
return *get(0) == rhs;
|
||||
}
|
||||
|
||||
bool ComplexSelector::operator== (const SimpleSelector& rhs) const
|
||||
{
|
||||
// If both are empty they are equal
|
||||
if (empty() && rhs.empty()) return true;
|
||||
// Must have exactly one item
|
||||
if (length() != 1) return false;
|
||||
// Compare simple selectors
|
||||
return *get(0) == rhs;
|
||||
}
|
||||
|
||||
/*#########################################################################*/
|
||||
// Compare SelectorCombinator against itself
|
||||
/*#########################################################################*/
|
||||
|
||||
bool SelectorCombinator::operator==(const SelectorCombinator& rhs) const
|
||||
{
|
||||
return combinator() == rhs.combinator();
|
||||
}
|
||||
|
||||
/*#########################################################################*/
|
||||
// Compare SelectorCombinator against SelectorComponent
|
||||
/*#########################################################################*/
|
||||
|
||||
bool SelectorCombinator::operator==(const SelectorComponent& rhs) const
|
||||
{
|
||||
if (const SelectorCombinator * sel = rhs.getCombinator()) {
|
||||
return *this == *sel;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
bool CompoundSelector::operator==(const SelectorComponent& rhs) const
|
||||
{
|
||||
if (const CompoundSelector * sel = rhs.getCompound()) {
|
||||
return *this == *sel;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/*#########################################################################*/
|
||||
// Compare CompoundSelector against itself
|
||||
/*#########################################################################*/
|
||||
// ToDo: Verifiy implementation
|
||||
/*#########################################################################*/
|
||||
|
||||
bool CompoundSelector::operator== (const CompoundSelector& rhs) const
|
||||
{
|
||||
// std::cerr << "comp vs comp\n";
|
||||
if (&rhs == this) return true;
|
||||
if (rhs.length() != length()) return false;
|
||||
std::unordered_set<const SimpleSelector*, PtrObjHash, PtrObjEquality> lhs_set;
|
||||
lhs_set.reserve(length());
|
||||
for (const SimpleSelectorObj& element : elements()) {
|
||||
lhs_set.insert(element.ptr());
|
||||
}
|
||||
// there is no break?!
|
||||
for (const SimpleSelectorObj& element : rhs.elements()) {
|
||||
if (lhs_set.find(element.ptr()) == lhs_set.end()) return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
/*#########################################################################*/
|
||||
// Compare CompoundSelector against all other selector types
|
||||
/*#########################################################################*/
|
||||
|
||||
bool CompoundSelector::operator== (const SelectorList& rhs) const
|
||||
{
|
||||
// If both are empty they are equal
|
||||
if (empty() && rhs.empty()) return true;
|
||||
// Must have exactly one item
|
||||
if (rhs.length() != 1) return false;
|
||||
// Compare complex selector
|
||||
return *this == *rhs.get(0);
|
||||
}
|
||||
|
||||
bool CompoundSelector::operator== (const ComplexSelector& rhs) const
|
||||
{
|
||||
// If both are empty they are equal
|
||||
if (empty() && rhs.empty()) return true;
|
||||
// Must have exactly one item
|
||||
if (rhs.length() != 1) return false;
|
||||
// Compare compound selector
|
||||
return *this == *rhs.get(0);
|
||||
}
|
||||
|
||||
bool CompoundSelector::operator== (const SimpleSelector& rhs) const
|
||||
{
|
||||
// If both are empty they are equal
|
||||
if (empty() && rhs.empty()) return false;
|
||||
// Must have exactly one item
|
||||
size_t rlen = length();
|
||||
if (rlen > 1) return false;
|
||||
if (rlen == 0) return true;
|
||||
// Compare simple selectors
|
||||
return *get(0) < rhs;
|
||||
}
|
||||
|
||||
/*#########################################################################*/
|
||||
// Compare SimpleSelector against itself (upcast from abstract base)
|
||||
/*#########################################################################*/
|
||||
|
||||
// DOES NOT EXIST FOR ABSTRACT BASE CLASS
|
||||
|
||||
/*#########################################################################*/
|
||||
// Compare SimpleSelector against all other selector types
|
||||
/*#########################################################################*/
|
||||
|
||||
bool SimpleSelector::operator== (const SelectorList& rhs) const
|
||||
{
|
||||
// If both are empty they are equal
|
||||
if (empty() && rhs.empty()) return true;
|
||||
// Must have exactly one item
|
||||
if (rhs.length() != 1) return false;
|
||||
// Compare complex selector
|
||||
return *this == *rhs.get(0);
|
||||
}
|
||||
|
||||
bool SimpleSelector::operator== (const ComplexSelector& rhs) const
|
||||
{
|
||||
// If both are empty they are equal
|
||||
if (empty() && rhs.empty()) return true;
|
||||
// Must have exactly one item
|
||||
if (rhs.length() != 1) return false;
|
||||
// Compare compound selector
|
||||
return *this == *rhs.get(0);
|
||||
}
|
||||
|
||||
bool SimpleSelector::operator== (const CompoundSelector& rhs) const
|
||||
{
|
||||
// If both are empty they are equal
|
||||
if (empty() && rhs.empty()) return false;
|
||||
// Must have exactly one item
|
||||
if (rhs.length() != 1) return false;
|
||||
// Compare simple selector
|
||||
return *this == *rhs.get(0);
|
||||
}
|
||||
|
||||
/*#########################################################################*/
|
||||
/*#########################################################################*/
|
||||
|
||||
bool IDSelector::operator== (const SimpleSelector& rhs) const
|
||||
{
|
||||
auto sel = Cast<IDSelector>(&rhs);
|
||||
return sel ? *this == *sel : false;
|
||||
}
|
||||
|
||||
bool TypeSelector::operator== (const SimpleSelector& rhs) const
|
||||
{
|
||||
auto sel = Cast<TypeSelector>(&rhs);
|
||||
return sel ? *this == *sel : false;
|
||||
}
|
||||
|
||||
bool ClassSelector::operator== (const SimpleSelector& rhs) const
|
||||
{
|
||||
auto sel = Cast<ClassSelector>(&rhs);
|
||||
return sel ? *this == *sel : false;
|
||||
}
|
||||
|
||||
bool PseudoSelector::operator== (const SimpleSelector& rhs) const
|
||||
{
|
||||
auto sel = Cast<PseudoSelector>(&rhs);
|
||||
return sel ? *this == *sel : false;
|
||||
}
|
||||
|
||||
bool AttributeSelector::operator== (const SimpleSelector& rhs) const
|
||||
{
|
||||
auto sel = Cast<AttributeSelector>(&rhs);
|
||||
return sel ? *this == *sel : false;
|
||||
}
|
||||
|
||||
bool PlaceholderSelector::operator== (const SimpleSelector& rhs) const
|
||||
{
|
||||
auto sel = Cast<PlaceholderSelector>(&rhs);
|
||||
return sel ? *this == *sel : false;
|
||||
}
|
||||
|
||||
/*#########################################################################*/
|
||||
/*#########################################################################*/
|
||||
|
||||
bool IDSelector::operator== (const IDSelector& rhs) const
|
||||
{
|
||||
// ID has no namespacing
|
||||
return name() == rhs.name();
|
||||
}
|
||||
|
||||
bool TypeSelector::operator== (const TypeSelector& rhs) const
|
||||
{
|
||||
return is_ns_eq(rhs) && name() == rhs.name();
|
||||
}
|
||||
|
||||
bool ClassSelector::operator== (const ClassSelector& rhs) const
|
||||
{
|
||||
// Class has no namespacing
|
||||
return name() == rhs.name();
|
||||
}
|
||||
|
||||
bool PlaceholderSelector::operator== (const PlaceholderSelector& rhs) const
|
||||
{
|
||||
// Placeholder has no namespacing
|
||||
return name() == rhs.name();
|
||||
}
|
||||
|
||||
bool AttributeSelector::operator== (const AttributeSelector& rhs) const
|
||||
{
|
||||
// smaller return, equal go on, bigger abort
|
||||
if (is_ns_eq(rhs)) {
|
||||
if (name() != rhs.name()) return false;
|
||||
if (matcher() != rhs.matcher()) return false;
|
||||
if (modifier() != rhs.modifier()) return false;
|
||||
const String* lhs_val = value();
|
||||
const String* rhs_val = rhs.value();
|
||||
return PtrObjEquality()(lhs_val, rhs_val);
|
||||
}
|
||||
else { return false; }
|
||||
}
|
||||
|
||||
bool PseudoSelector::operator== (const PseudoSelector& rhs) const
|
||||
{
|
||||
if (is_ns_eq(rhs)) {
|
||||
if (name() != rhs.name()) return false;
|
||||
if (isElement() != rhs.isElement()) return false;
|
||||
const String* lhs_arg = argument();
|
||||
const String* rhs_arg = rhs.argument();
|
||||
if (!PtrObjEquality()(lhs_arg, rhs_arg)) return false;
|
||||
const SelectorList* lhs_sel = selector();
|
||||
const SelectorList* rhs_sel = rhs.selector();
|
||||
return PtrObjEquality()(lhs_sel, rhs_sel);
|
||||
}
|
||||
else { return false; }
|
||||
}
|
||||
|
||||
/*#########################################################################*/
|
||||
/*#########################################################################*/
|
||||
|
||||
}
|
||||
539
vendor/bundle/ruby/2.6.0/gems/sassc-2.4.0/ext/libsass/src/ast_sel_super.cpp
vendored
Normal file
539
vendor/bundle/ruby/2.6.0/gems/sassc-2.4.0/ext/libsass/src/ast_sel_super.cpp
vendored
Normal file
@@ -0,0 +1,539 @@
|
||||
// sass.hpp must go before all system headers to get the
|
||||
// __EXTENSIONS__ fix on Solaris.
|
||||
#include "sass.hpp"
|
||||
#include "ast.hpp"
|
||||
|
||||
#include "util_string.hpp"
|
||||
|
||||
namespace Sass {
|
||||
|
||||
// ##########################################################################
|
||||
// To compare/debug against libsass you can use debugger.hpp:
|
||||
// c++: std::cerr << "result " << debug_vec(compound) << "\n";
|
||||
// dart: stderr.writeln("result " + compound.toString());
|
||||
// ##########################################################################
|
||||
|
||||
// ##########################################################################
|
||||
// Returns whether [list1] is a superselector of [list2].
|
||||
// That is, whether [list1] matches every element that
|
||||
// [list2] matches, as well as possibly additional elements.
|
||||
// ##########################################################################
|
||||
bool listIsSuperslector(
|
||||
const sass::vector<ComplexSelectorObj>& list1,
|
||||
const sass::vector<ComplexSelectorObj>& list2);
|
||||
|
||||
// ##########################################################################
|
||||
// Returns whether [complex1] is a superselector of [complex2].
|
||||
// That is, whether [complex1] matches every element that
|
||||
// [complex2] matches, as well as possibly additional elements.
|
||||
// ##########################################################################
|
||||
bool complexIsSuperselector(
|
||||
const sass::vector<SelectorComponentObj>& complex1,
|
||||
const sass::vector<SelectorComponentObj>& complex2);
|
||||
|
||||
// ##########################################################################
|
||||
// Returns all pseudo selectors in [compound] that have
|
||||
// a selector argument, and that have the given [name].
|
||||
// ##########################################################################
|
||||
sass::vector<PseudoSelectorObj> selectorPseudoNamed(
|
||||
CompoundSelectorObj compound, sass::string name)
|
||||
{
|
||||
sass::vector<PseudoSelectorObj> rv;
|
||||
for (SimpleSelectorObj sel : compound->elements()) {
|
||||
if (PseudoSelectorObj pseudo = Cast<PseudoSelector>(sel)) {
|
||||
if (pseudo->isClass() && pseudo->selector()) {
|
||||
if (sel->name() == name) {
|
||||
rv.push_back(sel);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return rv;
|
||||
}
|
||||
// EO selectorPseudoNamed
|
||||
|
||||
// ##########################################################################
|
||||
// Returns whether [simple1] is a superselector of [simple2].
|
||||
// That is, whether [simple1] matches every element that
|
||||
// [simple2] matches, as well as possibly additional elements.
|
||||
// ##########################################################################
|
||||
bool simpleIsSuperselector(
|
||||
const SimpleSelectorObj& simple1,
|
||||
const SimpleSelectorObj& simple2)
|
||||
{
|
||||
// If they are equal they are superselectors
|
||||
if (ObjEqualityFn(simple1, simple2)) {
|
||||
return true;
|
||||
}
|
||||
// Some selector pseudoclasses can match normal selectors.
|
||||
if (const PseudoSelector* pseudo = Cast<PseudoSelector>(simple2)) {
|
||||
if (pseudo->selector() && isSubselectorPseudo(pseudo->normalized())) {
|
||||
for (auto complex : pseudo->selector()->elements()) {
|
||||
// Make sure we have exacly one items
|
||||
if (complex->length() != 1) {
|
||||
return false;
|
||||
}
|
||||
// That items must be a compound selector
|
||||
if (auto compound = Cast<CompoundSelector>(complex->at(0))) {
|
||||
// It must contain the lhs simple selector
|
||||
if (!compound->contains(simple1)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
// EO simpleIsSuperselector
|
||||
|
||||
// ##########################################################################
|
||||
// Returns whether [simple] is a superselector of [compound].
|
||||
// That is, whether [simple] matches every element that
|
||||
// [compound] matches, as well as possibly additional elements.
|
||||
// ##########################################################################
|
||||
bool simpleIsSuperselectorOfCompound(
|
||||
const SimpleSelectorObj& simple,
|
||||
const CompoundSelectorObj& compound)
|
||||
{
|
||||
for (SimpleSelectorObj simple2 : compound->elements()) {
|
||||
if (simpleIsSuperselector(simple, simple2)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
// EO simpleIsSuperselectorOfCompound
|
||||
|
||||
// ##########################################################################
|
||||
// ##########################################################################
|
||||
bool typeIsSuperselectorOfCompound(
|
||||
const TypeSelectorObj& type,
|
||||
const CompoundSelectorObj& compound)
|
||||
{
|
||||
for (const SimpleSelectorObj& simple : compound->elements()) {
|
||||
if (const TypeSelectorObj& rhs = Cast<TypeSelector>(simple)) {
|
||||
if (*type != *rhs) return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
// EO typeIsSuperselectorOfCompound
|
||||
|
||||
// ##########################################################################
|
||||
// ##########################################################################
|
||||
bool idIsSuperselectorOfCompound(
|
||||
const IDSelectorObj& id,
|
||||
const CompoundSelectorObj& compound)
|
||||
{
|
||||
for (const SimpleSelectorObj& simple : compound->elements()) {
|
||||
if (const IDSelectorObj& rhs = Cast<IDSelector>(simple)) {
|
||||
if (*id != *rhs) return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
// EO idIsSuperselectorOfCompound
|
||||
|
||||
// ##########################################################################
|
||||
// ##########################################################################
|
||||
bool pseudoIsSuperselectorOfPseudo(
|
||||
const PseudoSelectorObj& pseudo1,
|
||||
const PseudoSelectorObj& pseudo2,
|
||||
const ComplexSelectorObj& parent
|
||||
)
|
||||
{
|
||||
if (!pseudo2->selector()) return false;
|
||||
if (pseudo1->name() == pseudo2->name()) {
|
||||
SelectorListObj list = pseudo2->selector();
|
||||
return listIsSuperslector(list->elements(), { parent });
|
||||
}
|
||||
return false;
|
||||
}
|
||||
// EO pseudoIsSuperselectorOfPseudo
|
||||
|
||||
// ##########################################################################
|
||||
// ##########################################################################
|
||||
bool pseudoNotIsSuperselectorOfCompound(
|
||||
const PseudoSelectorObj& pseudo1,
|
||||
const CompoundSelectorObj& compound2,
|
||||
const ComplexSelectorObj& parent)
|
||||
{
|
||||
for (const SimpleSelectorObj& simple2 : compound2->elements()) {
|
||||
if (const TypeSelectorObj& type2 = Cast<TypeSelector>(simple2)) {
|
||||
if (const CompoundSelectorObj& compound1 = Cast<CompoundSelector>(parent->last())) {
|
||||
if (typeIsSuperselectorOfCompound(type2, compound1)) return true;
|
||||
}
|
||||
}
|
||||
else if (const IDSelectorObj& id2 = Cast<IDSelector>(simple2)) {
|
||||
if (const CompoundSelectorObj& compound1 = Cast<CompoundSelector>(parent->last())) {
|
||||
if (idIsSuperselectorOfCompound(id2, compound1)) return true;
|
||||
}
|
||||
}
|
||||
else if (const PseudoSelectorObj& pseudo2 = Cast<PseudoSelector>(simple2)) {
|
||||
if (pseudoIsSuperselectorOfPseudo(pseudo1, pseudo2, parent)) return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
// pseudoNotIsSuperselectorOfCompound
|
||||
|
||||
// ##########################################################################
|
||||
// Returns whether [pseudo1] is a superselector of [compound2].
|
||||
// That is, whether [pseudo1] matches every element that [compound2]
|
||||
// matches, as well as possibly additional elements. This assumes that
|
||||
// [pseudo1]'s `selector` argument is not `null`. If [parents] is passed,
|
||||
// it represents the parents of [compound2]. This is relevant for pseudo
|
||||
// selectors with selector arguments, where we may need to know if the
|
||||
// parent selectors in the selector argument match [parents].
|
||||
// ##########################################################################
|
||||
bool selectorPseudoIsSuperselector(
|
||||
const PseudoSelectorObj& pseudo1,
|
||||
const CompoundSelectorObj& compound2,
|
||||
// ToDo: is this really the most convenient way to do this?
|
||||
sass::vector<SelectorComponentObj>::const_iterator parents_from,
|
||||
sass::vector<SelectorComponentObj>::const_iterator parents_to)
|
||||
{
|
||||
|
||||
// ToDo: move normalization function
|
||||
sass::string name(Util::unvendor(pseudo1->name()));
|
||||
|
||||
if (name == "matches" || name == "any") {
|
||||
sass::vector<PseudoSelectorObj> pseudos =
|
||||
selectorPseudoNamed(compound2, pseudo1->name());
|
||||
SelectorListObj selector1 = pseudo1->selector();
|
||||
for (PseudoSelectorObj pseudo2 : pseudos) {
|
||||
SelectorListObj selector = pseudo2->selector();
|
||||
if (selector1->isSuperselectorOf(selector)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
for (ComplexSelectorObj complex1 : selector1->elements()) {
|
||||
sass::vector<SelectorComponentObj> parents;
|
||||
for (auto cur = parents_from; cur != parents_to; cur++) {
|
||||
parents.push_back(*cur);
|
||||
}
|
||||
parents.push_back(compound2);
|
||||
if (complexIsSuperselector(complex1->elements(), parents)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
else if (name == "has" || name == "host" || name == "host-context" || name == "slotted") {
|
||||
sass::vector<PseudoSelectorObj> pseudos =
|
||||
selectorPseudoNamed(compound2, pseudo1->name());
|
||||
SelectorListObj selector1 = pseudo1->selector();
|
||||
for (PseudoSelectorObj pseudo2 : pseudos) {
|
||||
SelectorListObj selector = pseudo2->selector();
|
||||
if (selector1->isSuperselectorOf(selector)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
else if (name == "not") {
|
||||
for (ComplexSelectorObj complex : pseudo1->selector()->elements()) {
|
||||
if (!pseudoNotIsSuperselectorOfCompound(pseudo1, compound2, complex)) return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
else if (name == "current") {
|
||||
sass::vector<PseudoSelectorObj> pseudos =
|
||||
selectorPseudoNamed(compound2, "current");
|
||||
for (PseudoSelectorObj pseudo2 : pseudos) {
|
||||
if (ObjEqualityFn(pseudo1, pseudo2)) return true;
|
||||
}
|
||||
|
||||
}
|
||||
else if (name == "nth-child" || name == "nth-last-child") {
|
||||
for (auto simple2 : compound2->elements()) {
|
||||
if (PseudoSelectorObj pseudo2 = simple2->getPseudoSelector()) {
|
||||
if (pseudo1->name() != pseudo2->name()) continue;
|
||||
if (!ObjEqualityFn(pseudo1->argument(), pseudo2->argument())) continue;
|
||||
if (pseudo1->selector()->isSuperselectorOf(pseudo2->selector())) return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
return false;
|
||||
|
||||
}
|
||||
// EO selectorPseudoIsSuperselector
|
||||
|
||||
// ##########################################################################
|
||||
// Returns whether [compound1] is a superselector of [compound2].
|
||||
// That is, whether [compound1] matches every element that [compound2]
|
||||
// matches, as well as possibly additional elements. If [parents] is
|
||||
// passed, it represents the parents of [compound2]. This is relevant
|
||||
// for pseudo selectors with selector arguments, where we may need to
|
||||
// know if the parent selectors in the selector argument match [parents].
|
||||
// ##########################################################################
|
||||
bool compoundIsSuperselector(
|
||||
const CompoundSelectorObj& compound1,
|
||||
const CompoundSelectorObj& compound2,
|
||||
// ToDo: is this really the most convenient way to do this?
|
||||
const sass::vector<SelectorComponentObj>::const_iterator parents_from,
|
||||
const sass::vector<SelectorComponentObj>::const_iterator parents_to)
|
||||
{
|
||||
// Every selector in [compound1.components] must have
|
||||
// a matching selector in [compound2.components].
|
||||
for (SimpleSelectorObj simple1 : compound1->elements()) {
|
||||
PseudoSelectorObj pseudo1 = Cast<PseudoSelector>(simple1);
|
||||
if (pseudo1 && pseudo1->selector()) {
|
||||
if (!selectorPseudoIsSuperselector(pseudo1, compound2, parents_from, parents_to)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
else if (!simpleIsSuperselectorOfCompound(simple1, compound2)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
// [compound1] can't be a superselector of a selector
|
||||
// with pseudo-elements that [compound2] doesn't share.
|
||||
for (SimpleSelectorObj simple2 : compound2->elements()) {
|
||||
PseudoSelectorObj pseudo2 = Cast<PseudoSelector>(simple2);
|
||||
if (pseudo2 && pseudo2->isElement()) {
|
||||
if (!simpleIsSuperselectorOfCompound(pseudo2, compound1)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
// EO compoundIsSuperselector
|
||||
|
||||
// ##########################################################################
|
||||
// Returns whether [compound1] is a superselector of [compound2].
|
||||
// That is, whether [compound1] matches every element that [compound2]
|
||||
// matches, as well as possibly additional elements. If [parents] is
|
||||
// passed, it represents the parents of [compound2]. This is relevant
|
||||
// for pseudo selectors with selector arguments, where we may need to
|
||||
// know if the parent selectors in the selector argument match [parents].
|
||||
// ##########################################################################
|
||||
bool compoundIsSuperselector(
|
||||
const CompoundSelectorObj& compound1,
|
||||
const CompoundSelectorObj& compound2,
|
||||
const sass::vector<SelectorComponentObj>& parents)
|
||||
{
|
||||
return compoundIsSuperselector(
|
||||
compound1, compound2,
|
||||
parents.begin(), parents.end()
|
||||
);
|
||||
}
|
||||
// EO compoundIsSuperselector
|
||||
|
||||
// ##########################################################################
|
||||
// Returns whether [complex1] is a superselector of [complex2].
|
||||
// That is, whether [complex1] matches every element that
|
||||
// [complex2] matches, as well as possibly additional elements.
|
||||
// ##########################################################################
|
||||
bool complexIsSuperselector(
|
||||
const sass::vector<SelectorComponentObj>& complex1,
|
||||
const sass::vector<SelectorComponentObj>& complex2)
|
||||
{
|
||||
|
||||
// Selectors with trailing operators are neither superselectors nor subselectors.
|
||||
if (!complex1.empty() && Cast<SelectorCombinator>(complex1.back())) return false;
|
||||
if (!complex2.empty() && Cast<SelectorCombinator>(complex2.back())) return false;
|
||||
|
||||
size_t i1 = 0, i2 = 0;
|
||||
while (true) {
|
||||
|
||||
size_t remaining1 = complex1.size() - i1;
|
||||
size_t remaining2 = complex2.size() - i2;
|
||||
|
||||
if (remaining1 == 0 || remaining2 == 0) {
|
||||
return false;
|
||||
}
|
||||
// More complex selectors are never
|
||||
// superselectors of less complex ones.
|
||||
if (remaining1 > remaining2) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// Selectors with leading operators are
|
||||
// neither superselectors nor subselectors.
|
||||
if (Cast<SelectorCombinator>(complex1[i1])) {
|
||||
return false;
|
||||
}
|
||||
if (Cast<SelectorCombinator>(complex2[i2])) {
|
||||
return false;
|
||||
}
|
||||
|
||||
CompoundSelectorObj compound1 = Cast<CompoundSelector>(complex1[i1]);
|
||||
CompoundSelectorObj compound2 = Cast<CompoundSelector>(complex2.back());
|
||||
|
||||
if (remaining1 == 1) {
|
||||
sass::vector<SelectorComponentObj>::const_iterator parents_to = complex2.end();
|
||||
sass::vector<SelectorComponentObj>::const_iterator parents_from = complex2.begin();
|
||||
std::advance(parents_from, i2 + 1); // equivalent to dart `.skip(i2 + 1)`
|
||||
bool rv = compoundIsSuperselector(compound1, compound2, parents_from, parents_to);
|
||||
sass::vector<SelectorComponentObj> pp;
|
||||
|
||||
sass::vector<SelectorComponentObj>::const_iterator end = parents_to;
|
||||
sass::vector<SelectorComponentObj>::const_iterator beg = parents_from;
|
||||
while (beg != end) {
|
||||
pp.push_back(*beg);
|
||||
beg++;
|
||||
}
|
||||
|
||||
return rv;
|
||||
}
|
||||
|
||||
// Find the first index where `complex2.sublist(i2, afterSuperselector)`
|
||||
// is a subselector of [compound1]. We stop before the superselector
|
||||
// would encompass all of [complex2] because we know [complex1] has
|
||||
// more than one element, and consuming all of [complex2] wouldn't
|
||||
// leave anything for the rest of [complex1] to match.
|
||||
size_t afterSuperselector = i2 + 1;
|
||||
for (; afterSuperselector < complex2.size(); afterSuperselector++) {
|
||||
SelectorComponentObj component2 = complex2[afterSuperselector - 1];
|
||||
if (CompoundSelectorObj compound2 = Cast<CompoundSelector>(component2)) {
|
||||
sass::vector<SelectorComponentObj>::const_iterator parents_to = complex2.begin();
|
||||
sass::vector<SelectorComponentObj>::const_iterator parents_from = complex2.begin();
|
||||
// complex2.take(afterSuperselector - 1).skip(i2 + 1)
|
||||
std::advance(parents_from, i2 + 1); // equivalent to dart `.skip`
|
||||
std::advance(parents_to, afterSuperselector); // equivalent to dart `.take`
|
||||
if (compoundIsSuperselector(compound1, compound2, parents_from, parents_to)) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (afterSuperselector == complex2.size()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
SelectorComponentObj component1 = complex1[i1 + 1],
|
||||
component2 = complex2[afterSuperselector];
|
||||
|
||||
SelectorCombinatorObj combinator1 = Cast<SelectorCombinator>(component1);
|
||||
SelectorCombinatorObj combinator2 = Cast<SelectorCombinator>(component2);
|
||||
|
||||
if (!combinator1.isNull()) {
|
||||
|
||||
if (combinator2.isNull()) {
|
||||
return false;
|
||||
}
|
||||
// `.a ~ .b` is a superselector of `.a + .b`,
|
||||
// but otherwise the combinators must match.
|
||||
if (combinator1->isGeneralCombinator()) {
|
||||
if (combinator2->isChildCombinator()) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
else if (*combinator1 != *combinator2) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// `.foo > .baz` is not a superselector of `.foo > .bar > .baz` or
|
||||
// `.foo > .bar .baz`, despite the fact that `.baz` is a superselector of
|
||||
// `.bar > .baz` and `.bar .baz`. Same goes for `+` and `~`.
|
||||
if (remaining1 == 3 && remaining2 > 3) {
|
||||
return false;
|
||||
}
|
||||
|
||||
i1 += 2; i2 = afterSuperselector + 1;
|
||||
|
||||
}
|
||||
else if (!combinator2.isNull()) {
|
||||
if (!combinator2->isChildCombinator()) {
|
||||
return false;
|
||||
}
|
||||
i1 += 1; i2 = afterSuperselector + 1;
|
||||
}
|
||||
else {
|
||||
i1 += 1; i2 = afterSuperselector;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
|
||||
}
|
||||
// EO complexIsSuperselector
|
||||
|
||||
// ##########################################################################
|
||||
// Like [complexIsSuperselector], but compares [complex1]
|
||||
// and [complex2] as though they shared an implicit base
|
||||
// [SimpleSelector]. For example, `B` is not normally a
|
||||
// superselector of `B A`, since it doesn't match elements
|
||||
// that match `A`. However, it *is* a parent superselector,
|
||||
// since `B X` is a superselector of `B A X`.
|
||||
// ##########################################################################
|
||||
bool complexIsParentSuperselector(
|
||||
const sass::vector<SelectorComponentObj>& complex1,
|
||||
const sass::vector<SelectorComponentObj>& complex2)
|
||||
{
|
||||
// Try some simple heuristics to see if we can avoid allocations.
|
||||
if (complex1.empty() && complex2.empty()) return false;
|
||||
if (Cast<SelectorCombinator>(complex1.front())) return false;
|
||||
if (Cast<SelectorCombinator>(complex2.front())) return false;
|
||||
if (complex1.size() > complex2.size()) return false;
|
||||
// TODO(nweiz): There's got to be a way to do this without a bunch of extra allocations...
|
||||
sass::vector<SelectorComponentObj> cplx1(complex1);
|
||||
sass::vector<SelectorComponentObj> cplx2(complex2);
|
||||
CompoundSelectorObj base = SASS_MEMORY_NEW(CompoundSelector, "[tmp]");
|
||||
cplx1.push_back(base); cplx2.push_back(base);
|
||||
return complexIsSuperselector(cplx1, cplx2);
|
||||
}
|
||||
// EO complexIsParentSuperselector
|
||||
|
||||
// ##########################################################################
|
||||
// Returns whether [list] has a superselector for [complex].
|
||||
// That is, whether an item in [list] matches every element that
|
||||
// [complex] matches, as well as possibly additional elements.
|
||||
// ##########################################################################
|
||||
bool listHasSuperslectorForComplex(
|
||||
sass::vector<ComplexSelectorObj> list,
|
||||
ComplexSelectorObj complex)
|
||||
{
|
||||
// Return true if every [complex] selector on [list2]
|
||||
// is a super selector of the full selector [list1].
|
||||
for (ComplexSelectorObj lhs : list) {
|
||||
if (complexIsSuperselector(lhs->elements(), complex->elements())) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
// listIsSuperslectorOfComplex
|
||||
|
||||
// ##########################################################################
|
||||
// Returns whether [list1] is a superselector of [list2].
|
||||
// That is, whether [list1] matches every element that
|
||||
// [list2] matches, as well as possibly additional elements.
|
||||
// ##########################################################################
|
||||
bool listIsSuperslector(
|
||||
const sass::vector<ComplexSelectorObj>& list1,
|
||||
const sass::vector<ComplexSelectorObj>& list2)
|
||||
{
|
||||
// Return true if every [complex] selector on [list2]
|
||||
// is a super selector of the full selector [list1].
|
||||
for (ComplexSelectorObj complex : list2) {
|
||||
if (!listHasSuperslectorForComplex(list1, complex)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
// EO listIsSuperslector
|
||||
|
||||
// ##########################################################################
|
||||
// Implement selector methods (dispatch to functions)
|
||||
// ##########################################################################
|
||||
bool SelectorList::isSuperselectorOf(const SelectorList* sub) const
|
||||
{
|
||||
return listIsSuperslector(elements(), sub->elements());
|
||||
}
|
||||
bool ComplexSelector::isSuperselectorOf(const ComplexSelector* sub) const
|
||||
{
|
||||
return complexIsSuperselector(elements(), sub->elements());
|
||||
}
|
||||
|
||||
// ##########################################################################
|
||||
// ##########################################################################
|
||||
|
||||
}
|
||||
275
vendor/bundle/ruby/2.6.0/gems/sassc-2.4.0/ext/libsass/src/ast_sel_unify.cpp
vendored
Normal file
275
vendor/bundle/ruby/2.6.0/gems/sassc-2.4.0/ext/libsass/src/ast_sel_unify.cpp
vendored
Normal file
@@ -0,0 +1,275 @@
|
||||
// sass.hpp must go before all system headers to get the
|
||||
// __EXTENSIONS__ fix on Solaris.
|
||||
#include "sass.hpp"
|
||||
|
||||
#include "ast.hpp"
|
||||
|
||||
namespace Sass {
|
||||
|
||||
// ##########################################################################
|
||||
// Returns the contents of a [SelectorList] that matches only
|
||||
// elements that are matched by both [complex1] and [complex2].
|
||||
// If no such list can be produced, returns `null`.
|
||||
// ##########################################################################
|
||||
// ToDo: fine-tune API to avoid unnecessary wrapper allocations
|
||||
// ##########################################################################
|
||||
sass::vector<sass::vector<SelectorComponentObj>> unifyComplex(
|
||||
const sass::vector<sass::vector<SelectorComponentObj>>& complexes)
|
||||
{
|
||||
|
||||
SASS_ASSERT(!complexes.empty(), "Can't unify empty list");
|
||||
if (complexes.size() == 1) return complexes;
|
||||
|
||||
CompoundSelectorObj unifiedBase = SASS_MEMORY_NEW(CompoundSelector, SourceSpan("[phony]"));
|
||||
for (auto complex : complexes) {
|
||||
SelectorComponentObj base = complex.back();
|
||||
if (CompoundSelector * comp = base->getCompound()) {
|
||||
if (unifiedBase->empty()) {
|
||||
unifiedBase->concat(comp);
|
||||
}
|
||||
else {
|
||||
for (SimpleSelectorObj simple : comp->elements()) {
|
||||
unifiedBase = simple->unifyWith(unifiedBase);
|
||||
if (unifiedBase.isNull()) return {};
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
return {};
|
||||
}
|
||||
}
|
||||
|
||||
sass::vector<sass::vector<SelectorComponentObj>> complexesWithoutBases;
|
||||
for (size_t i = 0; i < complexes.size(); i += 1) {
|
||||
sass::vector<SelectorComponentObj> sel = complexes[i];
|
||||
sel.pop_back(); // remove last item (base) from the list
|
||||
complexesWithoutBases.push_back(std::move(sel));
|
||||
}
|
||||
|
||||
complexesWithoutBases.back().push_back(unifiedBase);
|
||||
|
||||
return weave(complexesWithoutBases);
|
||||
|
||||
}
|
||||
// EO unifyComplex
|
||||
|
||||
// ##########################################################################
|
||||
// Returns a [CompoundSelector] that matches only elements
|
||||
// that are matched by both [compound1] and [compound2].
|
||||
// If no such selector can be produced, returns `null`.
|
||||
// ##########################################################################
|
||||
CompoundSelector* CompoundSelector::unifyWith(CompoundSelector* rhs)
|
||||
{
|
||||
if (empty()) return rhs;
|
||||
CompoundSelectorObj unified = SASS_MEMORY_COPY(rhs);
|
||||
for (const SimpleSelectorObj& sel : elements()) {
|
||||
unified = sel->unifyWith(unified);
|
||||
if (unified.isNull()) break;
|
||||
}
|
||||
return unified.detach();
|
||||
}
|
||||
// EO CompoundSelector::unifyWith(CompoundSelector*)
|
||||
|
||||
// ##########################################################################
|
||||
// Returns the compoments of a [CompoundSelector] that matches only elements
|
||||
// matched by both this and [compound]. By default, this just returns a copy
|
||||
// of [compound] with this selector added to the end, or returns the original
|
||||
// array if this selector already exists in it. Returns `null` if unification
|
||||
// is impossible—for example, if there are multiple ID selectors.
|
||||
// ##########################################################################
|
||||
// This is implemented in `selector/simple.dart` as `SimpleSelector::unify`
|
||||
// ##########################################################################
|
||||
CompoundSelector* SimpleSelector::unifyWith(CompoundSelector* rhs)
|
||||
{
|
||||
|
||||
if (rhs->length() == 1) {
|
||||
if (rhs->get(0)->is_universal()) {
|
||||
CompoundSelector* this_compound = SASS_MEMORY_NEW(CompoundSelector, pstate());
|
||||
this_compound->append(SASS_MEMORY_COPY(this));
|
||||
CompoundSelector* unified = rhs->get(0)->unifyWith(this_compound);
|
||||
if (unified == nullptr || unified != this_compound) delete this_compound;
|
||||
return unified;
|
||||
}
|
||||
}
|
||||
for (const SimpleSelectorObj& sel : rhs->elements()) {
|
||||
if (*this == *sel) {
|
||||
return rhs;
|
||||
}
|
||||
}
|
||||
|
||||
CompoundSelectorObj result = SASS_MEMORY_NEW(CompoundSelector, rhs->pstate());
|
||||
|
||||
bool addedThis = false;
|
||||
for (auto simple : rhs->elements()) {
|
||||
// Make sure pseudo selectors always come last.
|
||||
if (!addedThis && simple->getPseudoSelector()) {
|
||||
result->append(this);
|
||||
addedThis = true;
|
||||
}
|
||||
result->append(simple);
|
||||
}
|
||||
|
||||
if (!addedThis) {
|
||||
result->append(this);
|
||||
}
|
||||
return result.detach();
|
||||
|
||||
}
|
||||
// EO SimpleSelector::unifyWith(CompoundSelector*)
|
||||
|
||||
// ##########################################################################
|
||||
// This is implemented in `selector/type.dart` as `PseudoSelector::unify`
|
||||
// ##########################################################################
|
||||
CompoundSelector* TypeSelector::unifyWith(CompoundSelector* rhs)
|
||||
{
|
||||
if (rhs->empty()) {
|
||||
rhs->append(this);
|
||||
return rhs;
|
||||
}
|
||||
TypeSelector* type = Cast<TypeSelector>(rhs->at(0));
|
||||
if (type != nullptr) {
|
||||
SimpleSelector* unified = unifyWith(type);
|
||||
if (unified == nullptr) {
|
||||
return nullptr;
|
||||
}
|
||||
rhs->elements()[0] = unified;
|
||||
}
|
||||
else if (!is_universal() || (has_ns_ && ns_ != "*")) {
|
||||
rhs->insert(rhs->begin(), this);
|
||||
}
|
||||
return rhs;
|
||||
}
|
||||
|
||||
// ##########################################################################
|
||||
// This is implemented in `selector/id.dart` as `PseudoSelector::unify`
|
||||
// ##########################################################################
|
||||
CompoundSelector* IDSelector::unifyWith(CompoundSelector* rhs)
|
||||
{
|
||||
for (const SimpleSelector* sel : rhs->elements()) {
|
||||
if (const IDSelector* id_sel = Cast<IDSelector>(sel)) {
|
||||
if (id_sel->name() != name()) return nullptr;
|
||||
}
|
||||
}
|
||||
return SimpleSelector::unifyWith(rhs);
|
||||
}
|
||||
|
||||
// ##########################################################################
|
||||
// This is implemented in `selector/pseudo.dart` as `PseudoSelector::unify`
|
||||
// ##########################################################################
|
||||
CompoundSelector* PseudoSelector::unifyWith(CompoundSelector* compound)
|
||||
{
|
||||
|
||||
if (compound->length() == 1 && compound->first()->is_universal()) {
|
||||
// std::cerr << "implement universal pseudo\n";
|
||||
}
|
||||
|
||||
for (const SimpleSelectorObj& sel : compound->elements()) {
|
||||
if (*this == *sel) {
|
||||
return compound;
|
||||
}
|
||||
}
|
||||
|
||||
CompoundSelectorObj result = SASS_MEMORY_NEW(CompoundSelector, compound->pstate());
|
||||
|
||||
bool addedThis = false;
|
||||
for (auto simple : compound->elements()) {
|
||||
// Make sure pseudo selectors always come last.
|
||||
if (PseudoSelectorObj pseudo = simple->getPseudoSelector()) {
|
||||
if (pseudo->isElement()) {
|
||||
// A given compound selector may only contain one pseudo element. If
|
||||
// [compound] has a different one than [this], unification fails.
|
||||
if (isElement()) {
|
||||
return {};
|
||||
}
|
||||
// Otherwise, this is a pseudo selector and
|
||||
// should come before pseduo elements.
|
||||
result->append(this);
|
||||
addedThis = true;
|
||||
}
|
||||
}
|
||||
result->append(simple);
|
||||
}
|
||||
|
||||
if (!addedThis) {
|
||||
result->append(this);
|
||||
}
|
||||
|
||||
return result.detach();
|
||||
|
||||
}
|
||||
// EO PseudoSelector::unifyWith(CompoundSelector*
|
||||
|
||||
// ##########################################################################
|
||||
// This is implemented in `extend/functions.dart` as `unifyUniversalAndElement`
|
||||
// Returns a [SimpleSelector] that matches only elements that are matched by
|
||||
// both [selector1] and [selector2], which must both be either [UniversalSelector]s
|
||||
// or [TypeSelector]s. If no such selector can be produced, returns `null`.
|
||||
// Note: libsass handles universal selector directly within the type selector
|
||||
// ##########################################################################
|
||||
SimpleSelector* TypeSelector::unifyWith(const SimpleSelector* rhs)
|
||||
{
|
||||
bool rhs_ns = false;
|
||||
if (!(is_ns_eq(*rhs) || rhs->is_universal_ns())) {
|
||||
if (!is_universal_ns()) {
|
||||
return nullptr;
|
||||
}
|
||||
rhs_ns = true;
|
||||
}
|
||||
bool rhs_name = false;
|
||||
if (!(name_ == rhs->name() || rhs->is_universal())) {
|
||||
if (!(is_universal())) {
|
||||
return nullptr;
|
||||
}
|
||||
rhs_name = true;
|
||||
}
|
||||
if (rhs_ns) {
|
||||
ns(rhs->ns());
|
||||
has_ns(rhs->has_ns());
|
||||
}
|
||||
if (rhs_name) name(rhs->name());
|
||||
return this;
|
||||
}
|
||||
// EO TypeSelector::unifyWith(const SimpleSelector*)
|
||||
|
||||
// ##########################################################################
|
||||
// Unify two complex selectors. Internally calls `unifyComplex`
|
||||
// and then wraps the result in newly create ComplexSelectors.
|
||||
// ##########################################################################
|
||||
SelectorList* ComplexSelector::unifyWith(ComplexSelector* rhs)
|
||||
{
|
||||
SelectorListObj list = SASS_MEMORY_NEW(SelectorList, pstate());
|
||||
sass::vector<sass::vector<SelectorComponentObj>> rv =
|
||||
unifyComplex({ elements(), rhs->elements() });
|
||||
for (sass::vector<SelectorComponentObj> items : rv) {
|
||||
ComplexSelectorObj sel = SASS_MEMORY_NEW(ComplexSelector, pstate());
|
||||
sel->elements() = std::move(items);
|
||||
list->append(sel);
|
||||
}
|
||||
return list.detach();
|
||||
}
|
||||
// EO ComplexSelector::unifyWith(ComplexSelector*)
|
||||
|
||||
// ##########################################################################
|
||||
// only called from the sass function `selector-unify`
|
||||
// ##########################################################################
|
||||
SelectorList* SelectorList::unifyWith(SelectorList* rhs)
|
||||
{
|
||||
SelectorList* slist = SASS_MEMORY_NEW(SelectorList, pstate());
|
||||
// Unify all of children with RHS's children,
|
||||
// storing the results in `unified_complex_selectors`
|
||||
for (ComplexSelectorObj& seq1 : elements()) {
|
||||
for (ComplexSelectorObj& seq2 : rhs->elements()) {
|
||||
if (SelectorListObj unified = seq1->unifyWith(seq2)) {
|
||||
std::move(unified->begin(), unified->end(),
|
||||
std::inserter(slist->elements(), slist->end()));
|
||||
}
|
||||
}
|
||||
}
|
||||
return slist;
|
||||
}
|
||||
// EO SelectorList::unifyWith(SelectorList*)
|
||||
|
||||
// ##########################################################################
|
||||
// ##########################################################################
|
||||
|
||||
}
|
||||
616
vendor/bundle/ruby/2.6.0/gems/sassc-2.4.0/ext/libsass/src/ast_sel_weave.cpp
vendored
Normal file
616
vendor/bundle/ruby/2.6.0/gems/sassc-2.4.0/ext/libsass/src/ast_sel_weave.cpp
vendored
Normal file
@@ -0,0 +1,616 @@
|
||||
// sass.hpp must go before all system headers to get the
|
||||
// __EXTENSIONS__ fix on Solaris.
|
||||
#include "sass.hpp"
|
||||
|
||||
#include "ast.hpp"
|
||||
#include "permutate.hpp"
|
||||
#include "dart_helpers.hpp"
|
||||
|
||||
namespace Sass {
|
||||
|
||||
// ##########################################################################
|
||||
// Returns whether or not [compound] contains a `::root` selector.
|
||||
// ##########################################################################
|
||||
bool hasRoot(const CompoundSelector* compound)
|
||||
{
|
||||
// Libsass does not yet know the root selector
|
||||
return false;
|
||||
}
|
||||
// EO hasRoot
|
||||
|
||||
// ##########################################################################
|
||||
// Returns whether a [CompoundSelector] may contain only
|
||||
// one simple selector of the same type as [simple].
|
||||
// ##########################################################################
|
||||
bool isUnique(const SimpleSelector* simple)
|
||||
{
|
||||
if (Cast<IDSelector>(simple)) return true;
|
||||
if (const PseudoSelector * pseudo = Cast<PseudoSelector>(simple)) {
|
||||
if (pseudo->is_pseudo_element()) return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
// EO isUnique
|
||||
|
||||
// ##########################################################################
|
||||
// Returns whether [complex1] and [complex2] need to be unified to
|
||||
// produce a valid combined selector. This is necessary when both
|
||||
// selectors contain the same unique simple selector, such as an ID.
|
||||
// ##########################################################################
|
||||
bool mustUnify(
|
||||
const sass::vector<SelectorComponentObj>& complex1,
|
||||
const sass::vector<SelectorComponentObj>& complex2)
|
||||
{
|
||||
|
||||
sass::vector<const SimpleSelector*> uniqueSelectors1;
|
||||
for (const SelectorComponent* component : complex1) {
|
||||
if (const CompoundSelector * compound = component->getCompound()) {
|
||||
for (const SimpleSelector* sel : compound->elements()) {
|
||||
if (isUnique(sel)) {
|
||||
uniqueSelectors1.push_back(sel);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if (uniqueSelectors1.empty()) return false;
|
||||
|
||||
// ToDo: unsure if this is correct
|
||||
for (const SelectorComponent* component : complex2) {
|
||||
if (const CompoundSelector * compound = component->getCompound()) {
|
||||
for (const SimpleSelector* sel : compound->elements()) {
|
||||
if (isUnique(sel)) {
|
||||
for (auto check : uniqueSelectors1) {
|
||||
if (*check == *sel) return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
|
||||
}
|
||||
// EO isUnique
|
||||
|
||||
// ##########################################################################
|
||||
// Helper function used by `weaveParents`
|
||||
// ##########################################################################
|
||||
bool cmpGroups(
|
||||
const sass::vector<SelectorComponentObj>& group1,
|
||||
const sass::vector<SelectorComponentObj>& group2,
|
||||
sass::vector<SelectorComponentObj>& select)
|
||||
{
|
||||
|
||||
if (group1.size() == group2.size() && std::equal(group1.begin(), group1.end(), group2.begin(), PtrObjEqualityFn<SelectorComponent>)) {
|
||||
select = group1;
|
||||
return true;
|
||||
}
|
||||
|
||||
if (!Cast<CompoundSelector>(group1.front())) {
|
||||
select = {};
|
||||
return false;
|
||||
}
|
||||
if (!Cast<CompoundSelector>(group2.front())) {
|
||||
select = {};
|
||||
return false;
|
||||
}
|
||||
|
||||
if (complexIsParentSuperselector(group1, group2)) {
|
||||
select = group2;
|
||||
return true;
|
||||
}
|
||||
if (complexIsParentSuperselector(group2, group1)) {
|
||||
select = group1;
|
||||
return true;
|
||||
}
|
||||
|
||||
if (!mustUnify(group1, group2)) {
|
||||
select = {};
|
||||
return false;
|
||||
}
|
||||
|
||||
sass::vector<sass::vector<SelectorComponentObj>> unified
|
||||
= unifyComplex({ group1, group2 });
|
||||
if (unified.empty()) return false;
|
||||
if (unified.size() > 1) return false;
|
||||
select = unified.front();
|
||||
return true;
|
||||
}
|
||||
// EO cmpGroups
|
||||
|
||||
// ##########################################################################
|
||||
// Helper function used by `weaveParents`
|
||||
// ##########################################################################
|
||||
template <class T>
|
||||
bool checkForEmptyChild(const T& item) {
|
||||
return item.empty();
|
||||
}
|
||||
// EO checkForEmptyChild
|
||||
|
||||
// ##########################################################################
|
||||
// Helper function used by `weaveParents`
|
||||
// ##########################################################################
|
||||
bool cmpChunkForEmptySequence(
|
||||
const sass::vector<sass::vector<SelectorComponentObj>>& seq,
|
||||
const sass::vector<SelectorComponentObj>& group)
|
||||
{
|
||||
return seq.empty();
|
||||
}
|
||||
// EO cmpChunkForEmptySequence
|
||||
|
||||
// ##########################################################################
|
||||
// Helper function used by `weaveParents`
|
||||
// ##########################################################################
|
||||
bool cmpChunkForParentSuperselector(
|
||||
const sass::vector<sass::vector<SelectorComponentObj>>& seq,
|
||||
const sass::vector<SelectorComponentObj>& group)
|
||||
{
|
||||
return seq.empty() || complexIsParentSuperselector(seq.front(), group);
|
||||
}
|
||||
// EO cmpChunkForParentSuperselector
|
||||
|
||||
// ##########################################################################
|
||||
// Returns all orderings of initial subseqeuences of [queue1] and [queue2].
|
||||
// The [done] callback is used to determine the extent of the initial
|
||||
// subsequences. It's called with each queue until it returns `true`.
|
||||
// Destructively removes the initial subsequences of [queue1] and [queue2].
|
||||
// For example, given `(A B C | D E)` and `(1 2 | 3 4 5)` (with `|` denoting
|
||||
// the boundary of the initial subsequence), this would return `[(A B C 1 2),
|
||||
// (1 2 A B C)]`. The queues would then contain `(D E)` and `(3 4 5)`.
|
||||
// ##########################################################################
|
||||
template <class T>
|
||||
sass::vector<sass::vector<T>> getChunks(
|
||||
sass::vector<T>& queue1, sass::vector<T>& queue2,
|
||||
const T& group, bool(*done)(const sass::vector<T>&, const T&)
|
||||
) {
|
||||
|
||||
sass::vector<T> chunk1;
|
||||
while (!done(queue1, group)) {
|
||||
chunk1.push_back(queue1.front());
|
||||
queue1.erase(queue1.begin());
|
||||
}
|
||||
|
||||
sass::vector<T> chunk2;
|
||||
while (!done(queue2, group)) {
|
||||
chunk2.push_back(queue2.front());
|
||||
queue2.erase(queue2.begin());
|
||||
}
|
||||
|
||||
if (chunk1.empty() && chunk2.empty()) return {};
|
||||
else if (chunk1.empty()) return { chunk2 };
|
||||
else if (chunk2.empty()) return { chunk1 };
|
||||
|
||||
sass::vector<T> choice1(chunk1), choice2(chunk2);
|
||||
std::move(std::begin(chunk2), std::end(chunk2),
|
||||
std::inserter(choice1, std::end(choice1)));
|
||||
std::move(std::begin(chunk1), std::end(chunk1),
|
||||
std::inserter(choice2, std::end(choice2)));
|
||||
return { choice1, choice2 };
|
||||
}
|
||||
// EO getChunks
|
||||
|
||||
// ##########################################################################
|
||||
// If the first element of [queue] has a `::root`
|
||||
// selector, removes and returns that element.
|
||||
// ##########################################################################
|
||||
CompoundSelectorObj getFirstIfRoot(sass::vector<SelectorComponentObj>& queue) {
|
||||
if (queue.empty()) return {};
|
||||
SelectorComponent* first = queue.front();
|
||||
if (CompoundSelector* sel = Cast<CompoundSelector>(first)) {
|
||||
if (!hasRoot(sel)) return {};
|
||||
queue.erase(queue.begin());
|
||||
return sel;
|
||||
}
|
||||
return {};
|
||||
}
|
||||
// EO getFirstIfRoot
|
||||
|
||||
// ##########################################################################
|
||||
// Returns [complex], grouped into sub-lists such that no sub-list
|
||||
// contains two adjacent [ComplexSelector]s. For example,
|
||||
// `(A B > C D + E ~ > G)` is grouped into `[(A) (B > C) (D + E ~ > G)]`.
|
||||
// ##########################################################################
|
||||
sass::vector<sass::vector<SelectorComponentObj>> groupSelectors(
|
||||
const sass::vector<SelectorComponentObj>& components)
|
||||
{
|
||||
bool lastWasCompound = false;
|
||||
sass::vector<SelectorComponentObj> group;
|
||||
sass::vector<sass::vector<SelectorComponentObj>> groups;
|
||||
for (size_t i = 0; i < components.size(); i += 1) {
|
||||
if (CompoundSelector* compound = components[i]->getCompound()) {
|
||||
if (lastWasCompound) {
|
||||
groups.push_back(group);
|
||||
group.clear();
|
||||
}
|
||||
group.push_back(compound);
|
||||
lastWasCompound = true;
|
||||
}
|
||||
else if (SelectorCombinator* combinator = components[i]->getCombinator()) {
|
||||
group.push_back(combinator);
|
||||
lastWasCompound = false;
|
||||
}
|
||||
}
|
||||
if (!group.empty()) {
|
||||
groups.push_back(group);
|
||||
}
|
||||
return groups;
|
||||
}
|
||||
// EO groupSelectors
|
||||
|
||||
// ##########################################################################
|
||||
// Extracts leading [Combinator]s from [components1] and [components2]
|
||||
// and merges them together into a single list of combinators.
|
||||
// If there are no combinators to be merged, returns an empty list.
|
||||
// If the combinators can't be merged, returns `null`.
|
||||
// ##########################################################################
|
||||
bool mergeInitialCombinators(
|
||||
sass::vector<SelectorComponentObj>& components1,
|
||||
sass::vector<SelectorComponentObj>& components2,
|
||||
sass::vector<SelectorComponentObj>& result)
|
||||
{
|
||||
|
||||
sass::vector<SelectorComponentObj> combinators1;
|
||||
while (!components1.empty() && Cast<SelectorCombinator>(components1.front())) {
|
||||
SelectorCombinatorObj front = Cast<SelectorCombinator>(components1.front());
|
||||
components1.erase(components1.begin());
|
||||
combinators1.push_back(front);
|
||||
}
|
||||
|
||||
sass::vector<SelectorComponentObj> combinators2;
|
||||
while (!components2.empty() && Cast<SelectorCombinator>(components2.front())) {
|
||||
SelectorCombinatorObj front = Cast<SelectorCombinator>(components2.front());
|
||||
components2.erase(components2.begin());
|
||||
combinators2.push_back(front);
|
||||
}
|
||||
|
||||
// If neither sequence of combinators is a subsequence
|
||||
// of the other, they cannot be merged successfully.
|
||||
sass::vector<SelectorComponentObj> LCS = lcs<SelectorComponentObj>(combinators1, combinators2);
|
||||
|
||||
if (ListEquality(LCS, combinators1, PtrObjEqualityFn<SelectorComponent>)) {
|
||||
result = combinators2;
|
||||
return true;
|
||||
}
|
||||
if (ListEquality(LCS, combinators2, PtrObjEqualityFn<SelectorComponent>)) {
|
||||
result = combinators1;
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
|
||||
}
|
||||
// EO mergeInitialCombinators
|
||||
|
||||
// ##########################################################################
|
||||
// Extracts trailing [Combinator]s, and the selectors to which they apply,
|
||||
// from [components1] and [components2] and merges them together into a
|
||||
// single list. If there are no combinators to be merged, returns an
|
||||
// empty list. If the sequences can't be merged, returns `null`.
|
||||
// ##########################################################################
|
||||
bool mergeFinalCombinators(
|
||||
sass::vector<SelectorComponentObj>& components1,
|
||||
sass::vector<SelectorComponentObj>& components2,
|
||||
sass::vector<sass::vector<sass::vector<SelectorComponentObj>>>& result)
|
||||
{
|
||||
|
||||
if (components1.empty() || !Cast<SelectorCombinator>(components1.back())) {
|
||||
if (components2.empty() || !Cast<SelectorCombinator>(components2.back())) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
sass::vector<SelectorComponentObj> combinators1;
|
||||
while (!components1.empty() && Cast<SelectorCombinator>(components1.back())) {
|
||||
SelectorCombinatorObj back = Cast<SelectorCombinator>(components1.back());
|
||||
components1.erase(components1.end() - 1);
|
||||
combinators1.push_back(back);
|
||||
}
|
||||
|
||||
sass::vector<SelectorComponentObj> combinators2;
|
||||
while (!components2.empty() && Cast<SelectorCombinator>(components2.back())) {
|
||||
SelectorCombinatorObj back = Cast<SelectorCombinator>(components2.back());
|
||||
components2.erase(components2.end() - 1);
|
||||
combinators2.push_back(back);
|
||||
}
|
||||
|
||||
// reverse now as we used push_back (faster than new alloc)
|
||||
std::reverse(combinators1.begin(), combinators1.end());
|
||||
std::reverse(combinators2.begin(), combinators2.end());
|
||||
|
||||
if (combinators1.size() > 1 || combinators2.size() > 1) {
|
||||
// If there are multiple combinators, something hacky's going on. If one
|
||||
// is a supersequence of the other, use that, otherwise give up.
|
||||
auto LCS = lcs<SelectorComponentObj>(combinators1, combinators2);
|
||||
if (ListEquality(LCS, combinators1, PtrObjEqualityFn<SelectorComponent>)) {
|
||||
result.push_back({ combinators2 });
|
||||
}
|
||||
else if (ListEquality(LCS, combinators2, PtrObjEqualityFn<SelectorComponent>)) {
|
||||
result.push_back({ combinators1 });
|
||||
}
|
||||
else {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
// This code looks complicated, but it's actually just a bunch of special
|
||||
// cases for interactions between different combinators.
|
||||
SelectorCombinatorObj combinator1, combinator2;
|
||||
if (!combinators1.empty()) combinator1 = combinators1.back();
|
||||
if (!combinators2.empty()) combinator2 = combinators2.back();
|
||||
|
||||
if (!combinator1.isNull() && !combinator2.isNull()) {
|
||||
|
||||
CompoundSelector* compound1 = Cast<CompoundSelector>(components1.back());
|
||||
CompoundSelector* compound2 = Cast<CompoundSelector>(components2.back());
|
||||
|
||||
components1.pop_back();
|
||||
components2.pop_back();
|
||||
|
||||
if (combinator1->isGeneralCombinator() && combinator2->isGeneralCombinator()) {
|
||||
|
||||
if (compound1->isSuperselectorOf(compound2)) {
|
||||
result.push_back({ { compound2, combinator2 } });
|
||||
}
|
||||
else if (compound2->isSuperselectorOf(compound1)) {
|
||||
result.push_back({ { compound1, combinator1 } });
|
||||
}
|
||||
else {
|
||||
sass::vector<sass::vector<SelectorComponentObj>> choices;
|
||||
choices.push_back({ compound1, combinator1, compound2, combinator2 });
|
||||
choices.push_back({ compound2, combinator2, compound1, combinator1 });
|
||||
if (CompoundSelector* unified = compound1->unifyWith(compound2)) {
|
||||
choices.push_back({ unified, combinator1 });
|
||||
}
|
||||
result.push_back(choices);
|
||||
}
|
||||
}
|
||||
else if ((combinator1->isGeneralCombinator() && combinator2->isAdjacentCombinator()) ||
|
||||
(combinator1->isAdjacentCombinator() && combinator2->isGeneralCombinator())) {
|
||||
|
||||
CompoundSelector* followingSiblingSelector = combinator1->isGeneralCombinator() ? compound1 : compound2;
|
||||
CompoundSelector* nextSiblingSelector = combinator1->isGeneralCombinator() ? compound2 : compound1;
|
||||
SelectorCombinator* followingSiblingCombinator = combinator1->isGeneralCombinator() ? combinator1 : combinator2;
|
||||
SelectorCombinator* nextSiblingCombinator = combinator1->isGeneralCombinator() ? combinator2 : combinator1;
|
||||
|
||||
if (followingSiblingSelector->isSuperselectorOf(nextSiblingSelector)) {
|
||||
result.push_back({ { nextSiblingSelector, nextSiblingCombinator } });
|
||||
}
|
||||
else {
|
||||
CompoundSelectorObj unified = compound1->unifyWith(compound2);
|
||||
sass::vector<sass::vector<SelectorComponentObj>> items;
|
||||
|
||||
if (!unified.isNull()) {
|
||||
items.push_back({
|
||||
unified, nextSiblingCombinator
|
||||
});
|
||||
}
|
||||
|
||||
items.insert(items.begin(), {
|
||||
followingSiblingSelector,
|
||||
followingSiblingCombinator,
|
||||
nextSiblingSelector,
|
||||
nextSiblingCombinator,
|
||||
});
|
||||
|
||||
result.push_back(items);
|
||||
}
|
||||
|
||||
}
|
||||
else if (combinator1->isChildCombinator() && (combinator2->isAdjacentCombinator() || combinator2->isGeneralCombinator())) {
|
||||
result.push_back({ { compound2, combinator2 } });
|
||||
components1.push_back(compound1);
|
||||
components1.push_back(combinator1);
|
||||
}
|
||||
else if (combinator2->isChildCombinator() && (combinator1->isAdjacentCombinator() || combinator1->isGeneralCombinator())) {
|
||||
result.push_back({ { compound1, combinator1 } });
|
||||
components2.push_back(compound2);
|
||||
components2.push_back(combinator2);
|
||||
}
|
||||
else if (*combinator1 == *combinator2) {
|
||||
CompoundSelectorObj unified = compound1->unifyWith(compound2);
|
||||
if (unified.isNull()) return false;
|
||||
result.push_back({ { unified, combinator1 } });
|
||||
}
|
||||
else {
|
||||
return false;
|
||||
}
|
||||
|
||||
return mergeFinalCombinators(components1, components2, result);
|
||||
|
||||
}
|
||||
else if (!combinator1.isNull()) {
|
||||
|
||||
if (combinator1->isChildCombinator() && !components2.empty()) {
|
||||
const CompoundSelector* back1 = Cast<CompoundSelector>(components1.back());
|
||||
const CompoundSelector* back2 = Cast<CompoundSelector>(components2.back());
|
||||
if (back1 && back2 && back2->isSuperselectorOf(back1)) {
|
||||
components2.pop_back();
|
||||
}
|
||||
}
|
||||
|
||||
result.push_back({ { components1.back(), combinator1 } });
|
||||
|
||||
components1.pop_back();
|
||||
|
||||
return mergeFinalCombinators(components1, components2, result);
|
||||
|
||||
}
|
||||
|
||||
if (combinator2->isChildCombinator() && !components1.empty()) {
|
||||
const CompoundSelector* back1 = Cast<CompoundSelector>(components1.back());
|
||||
const CompoundSelector* back2 = Cast<CompoundSelector>(components2.back());
|
||||
if (back1 && back2 && back1->isSuperselectorOf(back2)) {
|
||||
components1.pop_back();
|
||||
}
|
||||
}
|
||||
|
||||
result.push_back({ { components2.back(), combinator2 } });
|
||||
|
||||
components2.pop_back();
|
||||
|
||||
return mergeFinalCombinators(components1, components2, result);
|
||||
|
||||
}
|
||||
// EO mergeFinalCombinators
|
||||
|
||||
// ##########################################################################
|
||||
// Expands "parenthesized selectors" in [complexes]. That is, if
|
||||
// we have `.A .B {@extend .C}` and `.D .C {...}`, this conceptually
|
||||
// expands into `.D .C, .D (.A .B)`, and this function translates
|
||||
// `.D (.A .B)` into `.D .A .B, .A .D .B`. For thoroughness, `.A.D .B`
|
||||
// would also be required, but including merged selectors results in
|
||||
// exponential output for very little gain. The selector `.D (.A .B)`
|
||||
// is represented as the list `[[.D], [.A, .B]]`.
|
||||
// ##########################################################################
|
||||
sass::vector<sass::vector<SelectorComponentObj>> weave(
|
||||
const sass::vector<sass::vector<SelectorComponentObj>>& complexes) {
|
||||
|
||||
sass::vector<sass::vector<SelectorComponentObj>> prefixes;
|
||||
|
||||
prefixes.push_back(complexes.at(0));
|
||||
|
||||
for (size_t i = 1; i < complexes.size(); i += 1) {
|
||||
|
||||
if (complexes[i].empty()) {
|
||||
continue;
|
||||
}
|
||||
const sass::vector<SelectorComponentObj>& complex = complexes[i];
|
||||
SelectorComponent* target = complex.back();
|
||||
if (complex.size() == 1) {
|
||||
for (auto& prefix : prefixes) {
|
||||
prefix.push_back(target);
|
||||
}
|
||||
continue;
|
||||
}
|
||||
|
||||
sass::vector<SelectorComponentObj> parents(complex);
|
||||
|
||||
parents.pop_back();
|
||||
|
||||
sass::vector<sass::vector<SelectorComponentObj>> newPrefixes;
|
||||
for (sass::vector<SelectorComponentObj> prefix : prefixes) {
|
||||
sass::vector<sass::vector<SelectorComponentObj>>
|
||||
parentPrefixes = weaveParents(prefix, parents);
|
||||
if (parentPrefixes.empty()) continue;
|
||||
for (auto& parentPrefix : parentPrefixes) {
|
||||
parentPrefix.push_back(target);
|
||||
newPrefixes.push_back(parentPrefix);
|
||||
}
|
||||
}
|
||||
prefixes = newPrefixes;
|
||||
|
||||
}
|
||||
return prefixes;
|
||||
|
||||
}
|
||||
// EO weave
|
||||
|
||||
// ##########################################################################
|
||||
// Interweaves [parents1] and [parents2] as parents of the same target
|
||||
// selector. Returns all possible orderings of the selectors in the
|
||||
// inputs (including using unification) that maintain the relative
|
||||
// ordering of the input. For example, given `.foo .bar` and `.baz .bang`,
|
||||
// this would return `.foo .bar .baz .bang`, `.foo .bar.baz .bang`,
|
||||
// `.foo .baz .bar .bang`, `.foo .baz .bar.bang`, `.foo .baz .bang .bar`,
|
||||
// and so on until `.baz .bang .foo .bar`. Semantically, for selectors A
|
||||
// and B, this returns all selectors `AB_i` such that the union over all i
|
||||
// of elements matched by `AB_i X` is identical to the intersection of all
|
||||
// elements matched by `A X` and all elements matched by `B X`. Some `AB_i`
|
||||
// are elided to reduce the size of the output.
|
||||
// ##########################################################################
|
||||
sass::vector<sass::vector<SelectorComponentObj>> weaveParents(
|
||||
sass::vector<SelectorComponentObj> queue1,
|
||||
sass::vector<SelectorComponentObj> queue2)
|
||||
{
|
||||
|
||||
sass::vector<SelectorComponentObj> leads;
|
||||
sass::vector<sass::vector<sass::vector<SelectorComponentObj>>> trails;
|
||||
if (!mergeInitialCombinators(queue1, queue2, leads)) return {};
|
||||
if (!mergeFinalCombinators(queue1, queue2, trails)) return {};
|
||||
// list comes out in reverse order for performance
|
||||
std::reverse(trails.begin(), trails.end());
|
||||
|
||||
// Make sure there's at most one `:root` in the output.
|
||||
// Note: does not yet do anything in libsass (no root selector)
|
||||
CompoundSelectorObj root1 = getFirstIfRoot(queue1);
|
||||
CompoundSelectorObj root2 = getFirstIfRoot(queue2);
|
||||
|
||||
if (!root1.isNull() && !root2.isNull()) {
|
||||
CompoundSelectorObj root = root1->unifyWith(root2);
|
||||
if (root.isNull()) return {}; // null
|
||||
queue1.insert(queue1.begin(), root);
|
||||
queue2.insert(queue2.begin(), root);
|
||||
}
|
||||
else if (!root1.isNull()) {
|
||||
queue2.insert(queue2.begin(), root1);
|
||||
}
|
||||
else if (!root2.isNull()) {
|
||||
queue1.insert(queue1.begin(), root2);
|
||||
}
|
||||
|
||||
// group into sub-lists so no sub-list contains two adjacent ComplexSelectors.
|
||||
sass::vector<sass::vector<SelectorComponentObj>> groups1 = groupSelectors(queue1);
|
||||
sass::vector<sass::vector<SelectorComponentObj>> groups2 = groupSelectors(queue2);
|
||||
|
||||
// The main array to store our choices that will be permutated
|
||||
sass::vector<sass::vector<sass::vector<SelectorComponentObj>>> choices;
|
||||
|
||||
// append initial combinators
|
||||
choices.push_back({ leads });
|
||||
|
||||
sass::vector<sass::vector<SelectorComponentObj>> LCS =
|
||||
lcs<sass::vector<SelectorComponentObj>>(groups1, groups2, cmpGroups);
|
||||
|
||||
for (auto group : LCS) {
|
||||
|
||||
// Create junks from groups1 and groups2
|
||||
sass::vector<sass::vector<sass::vector<SelectorComponentObj>>>
|
||||
chunks = getChunks<sass::vector<SelectorComponentObj>>(
|
||||
groups1, groups2, group, cmpChunkForParentSuperselector);
|
||||
|
||||
// Create expanded array by flattening chunks2 inner
|
||||
sass::vector<sass::vector<SelectorComponentObj>>
|
||||
expanded = flattenInner(chunks);
|
||||
|
||||
// Prepare data structures
|
||||
choices.push_back(expanded);
|
||||
choices.push_back({ group });
|
||||
if (!groups1.empty()) {
|
||||
groups1.erase(groups1.begin());
|
||||
}
|
||||
if (!groups2.empty()) {
|
||||
groups2.erase(groups2.begin());
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// Create junks from groups1 and groups2
|
||||
sass::vector<sass::vector<sass::vector<SelectorComponentObj>>>
|
||||
chunks = getChunks<sass::vector<SelectorComponentObj>>(
|
||||
groups1, groups2, {}, cmpChunkForEmptySequence);
|
||||
|
||||
// Append chunks with inner arrays flattened
|
||||
choices.emplace_back(flattenInner(chunks));
|
||||
|
||||
// append all trailing selectors to choices
|
||||
std::move(std::begin(trails), std::end(trails),
|
||||
std::inserter(choices, std::end(choices)));
|
||||
|
||||
// move all non empty items to the front, then erase the trailing ones
|
||||
choices.erase(std::remove_if(choices.begin(), choices.end(), checkForEmptyChild
|
||||
<sass::vector<sass::vector<SelectorComponentObj>>>), choices.end());
|
||||
|
||||
// permutate all possible paths through selectors
|
||||
sass::vector<sass::vector<SelectorComponentObj>>
|
||||
results = flattenInner(permutate(choices));
|
||||
|
||||
return results;
|
||||
|
||||
}
|
||||
// EO weaveParents
|
||||
|
||||
// ##########################################################################
|
||||
// ##########################################################################
|
||||
|
||||
}
|
||||
1043
vendor/bundle/ruby/2.6.0/gems/sassc-2.4.0/ext/libsass/src/ast_selectors.cpp
vendored
Normal file
1043
vendor/bundle/ruby/2.6.0/gems/sassc-2.4.0/ext/libsass/src/ast_selectors.cpp
vendored
Normal file
File diff suppressed because it is too large
Load Diff
522
vendor/bundle/ruby/2.6.0/gems/sassc-2.4.0/ext/libsass/src/ast_selectors.hpp
vendored
Normal file
522
vendor/bundle/ruby/2.6.0/gems/sassc-2.4.0/ext/libsass/src/ast_selectors.hpp
vendored
Normal file
@@ -0,0 +1,522 @@
|
||||
#ifndef SASS_AST_SEL_H
|
||||
#define SASS_AST_SEL_H
|
||||
|
||||
// sass.hpp must go before all system headers to get the
|
||||
// __EXTENSIONS__ fix on Solaris.
|
||||
#include "sass.hpp"
|
||||
#include "ast.hpp"
|
||||
|
||||
namespace Sass {
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////
|
||||
// Some helper functions
|
||||
/////////////////////////////////////////////////////////////////////////
|
||||
|
||||
bool compoundIsSuperselector(
|
||||
const CompoundSelectorObj& compound1,
|
||||
const CompoundSelectorObj& compound2,
|
||||
const sass::vector<SelectorComponentObj>& parents);
|
||||
|
||||
bool complexIsParentSuperselector(
|
||||
const sass::vector<SelectorComponentObj>& complex1,
|
||||
const sass::vector<SelectorComponentObj>& complex2);
|
||||
|
||||
sass::vector<sass::vector<SelectorComponentObj>> weave(
|
||||
const sass::vector<sass::vector<SelectorComponentObj>>& complexes);
|
||||
|
||||
sass::vector<sass::vector<SelectorComponentObj>> weaveParents(
|
||||
sass::vector<SelectorComponentObj> parents1,
|
||||
sass::vector<SelectorComponentObj> parents2);
|
||||
|
||||
sass::vector<SimpleSelectorObj> unifyCompound(
|
||||
const sass::vector<SimpleSelectorObj>& compound1,
|
||||
const sass::vector<SimpleSelectorObj>& compound2);
|
||||
|
||||
sass::vector<sass::vector<SelectorComponentObj>> unifyComplex(
|
||||
const sass::vector<sass::vector<SelectorComponentObj>>& complexes);
|
||||
|
||||
/////////////////////////////////////////
|
||||
// Abstract base class for CSS selectors.
|
||||
/////////////////////////////////////////
|
||||
class Selector : public Expression {
|
||||
protected:
|
||||
mutable size_t hash_;
|
||||
public:
|
||||
Selector(SourceSpan pstate);
|
||||
virtual ~Selector() = 0;
|
||||
size_t hash() const override = 0;
|
||||
virtual bool has_real_parent_ref() const;
|
||||
// you should reset this to null on containers
|
||||
virtual unsigned long specificity() const = 0;
|
||||
// by default we return the regular specificity
|
||||
// you must override this for all containers
|
||||
virtual size_t maxSpecificity() const { return specificity(); }
|
||||
virtual size_t minSpecificity() const { return specificity(); }
|
||||
// dispatch to correct handlers
|
||||
ATTACH_VIRTUAL_CMP_OPERATIONS(Selector)
|
||||
ATTACH_VIRTUAL_AST_OPERATIONS(Selector)
|
||||
};
|
||||
inline Selector::~Selector() { }
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////
|
||||
// Interpolated selectors -- the interpolated String will be expanded and
|
||||
// re-parsed into a normal selector class.
|
||||
/////////////////////////////////////////////////////////////////////////
|
||||
class Selector_Schema final : public AST_Node {
|
||||
ADD_PROPERTY(String_Schema_Obj, contents)
|
||||
ADD_PROPERTY(bool, connect_parent);
|
||||
// store computed hash
|
||||
mutable size_t hash_;
|
||||
public:
|
||||
Selector_Schema(SourceSpan pstate, String_Obj c);
|
||||
|
||||
bool has_real_parent_ref() const;
|
||||
// selector schema is not yet a final selector, so we do not
|
||||
// have a specificity for it yet. We need to
|
||||
virtual unsigned long specificity() const;
|
||||
size_t hash() const override;
|
||||
ATTACH_AST_OPERATIONS(Selector_Schema)
|
||||
ATTACH_CRTP_PERFORM_METHODS()
|
||||
};
|
||||
|
||||
////////////////////////////////////////////
|
||||
// Abstract base class for simple selectors.
|
||||
////////////////////////////////////////////
|
||||
class SimpleSelector : public Selector {
|
||||
public:
|
||||
enum Simple_Type {
|
||||
ID_SEL,
|
||||
TYPE_SEL,
|
||||
CLASS_SEL,
|
||||
PSEUDO_SEL,
|
||||
ATTRIBUTE_SEL,
|
||||
PLACEHOLDER_SEL,
|
||||
};
|
||||
public:
|
||||
HASH_CONSTREF(sass::string, ns)
|
||||
HASH_CONSTREF(sass::string, name)
|
||||
ADD_PROPERTY(Simple_Type, simple_type)
|
||||
HASH_PROPERTY(bool, has_ns)
|
||||
public:
|
||||
SimpleSelector(SourceSpan pstate, sass::string n = "");
|
||||
// ordering within parent (peudos go last)
|
||||
virtual int getSortOrder() const = 0;
|
||||
virtual sass::string ns_name() const;
|
||||
size_t hash() const override;
|
||||
virtual bool empty() const;
|
||||
// namespace compare functions
|
||||
bool is_ns_eq(const SimpleSelector& r) const;
|
||||
// namespace query functions
|
||||
bool is_universal_ns() const;
|
||||
bool is_empty_ns() const;
|
||||
bool has_empty_ns() const;
|
||||
bool has_qualified_ns() const;
|
||||
// name query functions
|
||||
bool is_universal() const;
|
||||
virtual bool has_placeholder();
|
||||
|
||||
virtual ~SimpleSelector() = 0;
|
||||
virtual CompoundSelector* unifyWith(CompoundSelector*);
|
||||
|
||||
/* helper function for syntax sugar */
|
||||
virtual IDSelector* getIdSelector() { return NULL; }
|
||||
virtual TypeSelector* getTypeSelector() { return NULL; }
|
||||
virtual PseudoSelector* getPseudoSelector() { return NULL; }
|
||||
|
||||
ComplexSelectorObj wrapInComplex();
|
||||
CompoundSelectorObj wrapInCompound();
|
||||
|
||||
virtual bool isInvisible() const { return false; }
|
||||
virtual bool is_pseudo_element() const;
|
||||
virtual bool has_real_parent_ref() const override;
|
||||
|
||||
bool operator==(const Selector& rhs) const final override;
|
||||
|
||||
virtual bool operator==(const SelectorList& rhs) const;
|
||||
virtual bool operator==(const ComplexSelector& rhs) const;
|
||||
virtual bool operator==(const CompoundSelector& rhs) const;
|
||||
|
||||
ATTACH_VIRTUAL_CMP_OPERATIONS(SimpleSelector);
|
||||
ATTACH_VIRTUAL_AST_OPERATIONS(SimpleSelector);
|
||||
ATTACH_CRTP_PERFORM_METHODS();
|
||||
|
||||
};
|
||||
inline SimpleSelector::~SimpleSelector() { }
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////
|
||||
// Placeholder selectors (e.g., "%foo") for use in extend-only selectors.
|
||||
/////////////////////////////////////////////////////////////////////////
|
||||
class PlaceholderSelector final : public SimpleSelector {
|
||||
public:
|
||||
PlaceholderSelector(SourceSpan pstate, sass::string n);
|
||||
int getSortOrder() const override final { return 0; }
|
||||
bool isInvisible() const override { return true; }
|
||||
virtual unsigned long specificity() const override;
|
||||
virtual bool has_placeholder() override;
|
||||
bool operator==(const SimpleSelector& rhs) const override;
|
||||
ATTACH_CMP_OPERATIONS(PlaceholderSelector)
|
||||
ATTACH_AST_OPERATIONS(PlaceholderSelector)
|
||||
ATTACH_CRTP_PERFORM_METHODS()
|
||||
};
|
||||
|
||||
/////////////////////////////////////////////////////////////////////
|
||||
// Type selectors (and the universal selector) -- e.g., div, span, *.
|
||||
/////////////////////////////////////////////////////////////////////
|
||||
class TypeSelector final : public SimpleSelector {
|
||||
public:
|
||||
TypeSelector(SourceSpan pstate, sass::string n);
|
||||
int getSortOrder() const override final { return 1; }
|
||||
virtual unsigned long specificity() const override;
|
||||
SimpleSelector* unifyWith(const SimpleSelector*);
|
||||
CompoundSelector* unifyWith(CompoundSelector*) override;
|
||||
TypeSelector* getTypeSelector() override { return this; }
|
||||
bool operator==(const SimpleSelector& rhs) const final override;
|
||||
ATTACH_CMP_OPERATIONS(TypeSelector)
|
||||
ATTACH_AST_OPERATIONS(TypeSelector)
|
||||
ATTACH_CRTP_PERFORM_METHODS()
|
||||
};
|
||||
|
||||
////////////////////////////////////////////////
|
||||
// Class selectors -- i.e., .foo.
|
||||
////////////////////////////////////////////////
|
||||
class ClassSelector final : public SimpleSelector {
|
||||
public:
|
||||
ClassSelector(SourceSpan pstate, sass::string n);
|
||||
int getSortOrder() const override final { return 3; }
|
||||
virtual unsigned long specificity() const override;
|
||||
bool operator==(const SimpleSelector& rhs) const final override;
|
||||
ATTACH_CMP_OPERATIONS(ClassSelector)
|
||||
ATTACH_AST_OPERATIONS(ClassSelector)
|
||||
ATTACH_CRTP_PERFORM_METHODS()
|
||||
};
|
||||
|
||||
////////////////////////////////////////////////
|
||||
// ID selectors -- i.e., #foo.
|
||||
////////////////////////////////////////////////
|
||||
class IDSelector final : public SimpleSelector {
|
||||
public:
|
||||
IDSelector(SourceSpan pstate, sass::string n);
|
||||
int getSortOrder() const override final { return 2; }
|
||||
virtual unsigned long specificity() const override;
|
||||
CompoundSelector* unifyWith(CompoundSelector*) override;
|
||||
IDSelector* getIdSelector() final override { return this; }
|
||||
bool operator==(const SimpleSelector& rhs) const final override;
|
||||
ATTACH_CMP_OPERATIONS(IDSelector)
|
||||
ATTACH_AST_OPERATIONS(IDSelector)
|
||||
ATTACH_CRTP_PERFORM_METHODS()
|
||||
};
|
||||
|
||||
///////////////////////////////////////////////////
|
||||
// Attribute selectors -- e.g., [src*=".jpg"], etc.
|
||||
///////////////////////////////////////////////////
|
||||
class AttributeSelector final : public SimpleSelector {
|
||||
ADD_CONSTREF(sass::string, matcher)
|
||||
// this cannot be changed to obj atm!!!!!!????!!!!!!!
|
||||
ADD_PROPERTY(String_Obj, value) // might be interpolated
|
||||
ADD_PROPERTY(char, modifier);
|
||||
public:
|
||||
AttributeSelector(SourceSpan pstate, sass::string n, sass::string m, String_Obj v, char o = 0);
|
||||
int getSortOrder() const override final { return 4; }
|
||||
size_t hash() const override;
|
||||
virtual unsigned long specificity() const override;
|
||||
bool operator==(const SimpleSelector& rhs) const final override;
|
||||
ATTACH_CMP_OPERATIONS(AttributeSelector)
|
||||
ATTACH_AST_OPERATIONS(AttributeSelector)
|
||||
ATTACH_CRTP_PERFORM_METHODS()
|
||||
};
|
||||
|
||||
//////////////////////////////////////////////////////////////////
|
||||
// Pseudo selectors -- e.g., :first-child, :nth-of-type(...), etc.
|
||||
//////////////////////////////////////////////////////////////////
|
||||
// Pseudo Selector cannot have any namespace?
|
||||
class PseudoSelector final : public SimpleSelector {
|
||||
ADD_PROPERTY(sass::string, normalized)
|
||||
ADD_PROPERTY(String_Obj, argument)
|
||||
ADD_PROPERTY(SelectorListObj, selector)
|
||||
ADD_PROPERTY(bool, isSyntacticClass)
|
||||
ADD_PROPERTY(bool, isClass)
|
||||
public:
|
||||
PseudoSelector(SourceSpan pstate, sass::string n, bool element = false);
|
||||
int getSortOrder() const override final { return 5; }
|
||||
virtual bool is_pseudo_element() const override;
|
||||
size_t hash() const override;
|
||||
|
||||
bool empty() const override;
|
||||
|
||||
bool has_real_parent_ref() const override;
|
||||
|
||||
// Whether this is a pseudo-element selector.
|
||||
// This is `true` if and only if [isClass] is `false`.
|
||||
bool isElement() const { return !isClass(); }
|
||||
|
||||
// Whether this is syntactically a pseudo-element selector.
|
||||
// This is `true` if and only if [isSyntacticClass] is `false`.
|
||||
bool isSyntacticElement() const { return !isSyntacticClass(); }
|
||||
|
||||
virtual unsigned long specificity() const override;
|
||||
PseudoSelectorObj withSelector(SelectorListObj selector);
|
||||
|
||||
CompoundSelector* unifyWith(CompoundSelector*) override;
|
||||
PseudoSelector* getPseudoSelector() final override { return this; }
|
||||
bool operator==(const SimpleSelector& rhs) const final override;
|
||||
ATTACH_CMP_OPERATIONS(PseudoSelector)
|
||||
ATTACH_AST_OPERATIONS(PseudoSelector)
|
||||
void cloneChildren() override;
|
||||
ATTACH_CRTP_PERFORM_METHODS()
|
||||
};
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////
|
||||
// Complex Selectors are the most important class of selectors.
|
||||
// A Selector List consists of Complex Selectors (separated by comma)
|
||||
// Complex Selectors are itself a list of Compounds and Combinators
|
||||
// Between each item there is an implicit ancestor of combinator
|
||||
////////////////////////////////////////////////////////////////////////////
|
||||
class ComplexSelector final : public Selector, public Vectorized<SelectorComponentObj> {
|
||||
ADD_PROPERTY(bool, chroots)
|
||||
// line break before list separator
|
||||
ADD_PROPERTY(bool, hasPreLineFeed)
|
||||
public:
|
||||
ComplexSelector(SourceSpan pstate);
|
||||
|
||||
// Returns true if the first components
|
||||
// is a compound selector and fullfills
|
||||
// a few other criteria.
|
||||
bool isInvisible() const;
|
||||
|
||||
size_t hash() const override;
|
||||
void cloneChildren() override;
|
||||
bool has_placeholder() const;
|
||||
bool has_real_parent_ref() const override;
|
||||
|
||||
SelectorList* resolve_parent_refs(SelectorStack pstack, Backtraces& traces, bool implicit_parent = true);
|
||||
virtual unsigned long specificity() const override;
|
||||
|
||||
SelectorList* unifyWith(ComplexSelector* rhs);
|
||||
|
||||
bool isSuperselectorOf(const ComplexSelector* sub) const;
|
||||
|
||||
SelectorListObj wrapInList();
|
||||
|
||||
size_t maxSpecificity() const override;
|
||||
size_t minSpecificity() const override;
|
||||
|
||||
bool operator==(const Selector& rhs) const override;
|
||||
bool operator==(const SelectorList& rhs) const;
|
||||
bool operator==(const CompoundSelector& rhs) const;
|
||||
bool operator==(const SimpleSelector& rhs) const;
|
||||
|
||||
ATTACH_CMP_OPERATIONS(ComplexSelector)
|
||||
ATTACH_AST_OPERATIONS(ComplexSelector)
|
||||
ATTACH_CRTP_PERFORM_METHODS()
|
||||
};
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////
|
||||
// Base class for complex selector components
|
||||
////////////////////////////////////////////////////////////////////////////
|
||||
class SelectorComponent : public Selector {
|
||||
// line break after list separator
|
||||
ADD_PROPERTY(bool, hasPostLineBreak)
|
||||
public:
|
||||
SelectorComponent(SourceSpan pstate, bool postLineBreak = false);
|
||||
size_t hash() const override = 0;
|
||||
void cloneChildren() override;
|
||||
|
||||
|
||||
// By default we consider instances not empty
|
||||
virtual bool empty() const { return false; }
|
||||
|
||||
virtual bool has_placeholder() const = 0;
|
||||
bool has_real_parent_ref() const override = 0;
|
||||
|
||||
ComplexSelector* wrapInComplex();
|
||||
|
||||
size_t maxSpecificity() const override { return 0; }
|
||||
size_t minSpecificity() const override { return 0; }
|
||||
|
||||
virtual bool isCompound() const { return false; };
|
||||
virtual bool isCombinator() const { return false; };
|
||||
|
||||
/* helper function for syntax sugar */
|
||||
virtual CompoundSelector* getCompound() { return NULL; }
|
||||
virtual SelectorCombinator* getCombinator() { return NULL; }
|
||||
virtual const CompoundSelector* getCompound() const { return NULL; }
|
||||
virtual const SelectorCombinator* getCombinator() const { return NULL; }
|
||||
|
||||
virtual unsigned long specificity() const override;
|
||||
bool operator==(const Selector& rhs) const override = 0;
|
||||
ATTACH_VIRTUAL_CMP_OPERATIONS(SelectorComponent);
|
||||
ATTACH_VIRTUAL_AST_OPERATIONS(SelectorComponent);
|
||||
};
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////
|
||||
// A specific combinator between compound selectors
|
||||
////////////////////////////////////////////////////////////////////////////
|
||||
class SelectorCombinator final : public SelectorComponent {
|
||||
public:
|
||||
|
||||
// Enumerate all possible selector combinators. There is some
|
||||
// discrepancy with dart-sass. Opted to name them as in CSS33
|
||||
enum Combinator { CHILD /* > */, GENERAL /* ~ */, ADJACENT /* + */};
|
||||
|
||||
private:
|
||||
|
||||
// Store the type of this combinator
|
||||
HASH_CONSTREF(Combinator, combinator)
|
||||
|
||||
public:
|
||||
SelectorCombinator(SourceSpan pstate, Combinator combinator, bool postLineBreak = false);
|
||||
|
||||
bool has_real_parent_ref() const override { return false; }
|
||||
bool has_placeholder() const override { return false; }
|
||||
|
||||
/* helper function for syntax sugar */
|
||||
SelectorCombinator* getCombinator() final override { return this; }
|
||||
const SelectorCombinator* getCombinator() const final override { return this; }
|
||||
|
||||
// Query type of combinator
|
||||
bool isCombinator() const override { return true; };
|
||||
|
||||
// Matches the right-hand selector if it's a direct child of the left-
|
||||
// hand selector in the DOM tree. Dart-sass also calls this `child`
|
||||
// https://developer.mozilla.org/en-US/docs/Web/CSS/Child_combinator
|
||||
bool isChildCombinator() const { return combinator_ == CHILD; } // >
|
||||
|
||||
// Matches the right-hand selector if it comes after the left-hand
|
||||
// selector in the DOM tree. Dart-sass class this `followingSibling`
|
||||
// https://developer.mozilla.org/en-US/docs/Web/CSS/General_sibling_combinator
|
||||
bool isGeneralCombinator() const { return combinator_ == GENERAL; } // ~
|
||||
|
||||
// Matches the right-hand selector if it's immediately adjacent to the
|
||||
// left-hand selector in the DOM tree. Dart-sass calls this `nextSibling`
|
||||
// https://developer.mozilla.org/en-US/docs/Web/CSS/Adjacent_sibling_combinator
|
||||
bool isAdjacentCombinator() const { return combinator_ == ADJACENT; } // +
|
||||
|
||||
size_t maxSpecificity() const override { return 0; }
|
||||
size_t minSpecificity() const override { return 0; }
|
||||
|
||||
size_t hash() const override {
|
||||
return std::hash<int>()(combinator_);
|
||||
}
|
||||
void cloneChildren() override;
|
||||
virtual unsigned long specificity() const override;
|
||||
bool operator==(const Selector& rhs) const override;
|
||||
bool operator==(const SelectorComponent& rhs) const override;
|
||||
|
||||
ATTACH_CMP_OPERATIONS(SelectorCombinator)
|
||||
ATTACH_AST_OPERATIONS(SelectorCombinator)
|
||||
ATTACH_CRTP_PERFORM_METHODS()
|
||||
};
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////
|
||||
// A compound selector consists of multiple simple selectors
|
||||
////////////////////////////////////////////////////////////////////////////
|
||||
class CompoundSelector final : public SelectorComponent, public Vectorized<SimpleSelectorObj> {
|
||||
ADD_PROPERTY(bool, hasRealParent)
|
||||
ADD_PROPERTY(bool, extended)
|
||||
public:
|
||||
CompoundSelector(SourceSpan pstate, bool postLineBreak = false);
|
||||
|
||||
// Returns true if this compound selector
|
||||
// fullfills various criteria.
|
||||
bool isInvisible() const;
|
||||
|
||||
bool empty() const override {
|
||||
return Vectorized::empty();
|
||||
}
|
||||
|
||||
size_t hash() const override;
|
||||
CompoundSelector* unifyWith(CompoundSelector* rhs);
|
||||
|
||||
/* helper function for syntax sugar */
|
||||
CompoundSelector* getCompound() final override { return this; }
|
||||
const CompoundSelector* getCompound() const final override { return this; }
|
||||
|
||||
bool isSuperselectorOf(const CompoundSelector* sub, sass::string wrapped = "") const;
|
||||
|
||||
void cloneChildren() override;
|
||||
bool has_real_parent_ref() const override;
|
||||
bool has_placeholder() const override;
|
||||
sass::vector<ComplexSelectorObj> resolve_parent_refs(SelectorStack pstack, Backtraces& traces, bool implicit_parent = true);
|
||||
|
||||
virtual bool isCompound() const override { return true; };
|
||||
virtual unsigned long specificity() const override;
|
||||
|
||||
size_t maxSpecificity() const override;
|
||||
size_t minSpecificity() const override;
|
||||
|
||||
bool operator==(const Selector& rhs) const override;
|
||||
|
||||
bool operator==(const SelectorComponent& rhs) const override;
|
||||
|
||||
bool operator==(const SelectorList& rhs) const;
|
||||
bool operator==(const ComplexSelector& rhs) const;
|
||||
bool operator==(const SimpleSelector& rhs) const;
|
||||
|
||||
void sortChildren();
|
||||
|
||||
ATTACH_CMP_OPERATIONS(CompoundSelector)
|
||||
ATTACH_AST_OPERATIONS(CompoundSelector)
|
||||
ATTACH_CRTP_PERFORM_METHODS()
|
||||
};
|
||||
|
||||
///////////////////////////////////
|
||||
// Comma-separated selector groups.
|
||||
///////////////////////////////////
|
||||
class SelectorList final : public Selector, public Vectorized<ComplexSelectorObj> {
|
||||
private:
|
||||
// maybe we have optional flag
|
||||
// ToDo: should be at ExtendRule?
|
||||
ADD_PROPERTY(bool, is_optional)
|
||||
public:
|
||||
SelectorList(SourceSpan pstate, size_t s = 0);
|
||||
sass::string type() const override { return "list"; }
|
||||
size_t hash() const override;
|
||||
|
||||
SelectorList* unifyWith(SelectorList*);
|
||||
|
||||
// Returns true if all complex selectors
|
||||
// can have real parents, meaning every
|
||||
// first component does allow for it
|
||||
bool isInvisible() const;
|
||||
|
||||
void cloneChildren() override;
|
||||
bool has_real_parent_ref() const override;
|
||||
SelectorList* resolve_parent_refs(SelectorStack pstack, Backtraces& traces, bool implicit_parent = true);
|
||||
virtual unsigned long specificity() const override;
|
||||
|
||||
bool isSuperselectorOf(const SelectorList* sub) const;
|
||||
|
||||
size_t maxSpecificity() const override;
|
||||
size_t minSpecificity() const override;
|
||||
|
||||
bool operator==(const Selector& rhs) const override;
|
||||
bool operator==(const ComplexSelector& rhs) const;
|
||||
bool operator==(const CompoundSelector& rhs) const;
|
||||
bool operator==(const SimpleSelector& rhs) const;
|
||||
// Selector Lists can be compared to comma lists
|
||||
bool operator==(const Expression& rhs) const override;
|
||||
|
||||
ATTACH_CMP_OPERATIONS(SelectorList)
|
||||
ATTACH_AST_OPERATIONS(SelectorList)
|
||||
ATTACH_CRTP_PERFORM_METHODS()
|
||||
};
|
||||
|
||||
////////////////////////////////
|
||||
// The Sass `@extend` directive.
|
||||
////////////////////////////////
|
||||
class ExtendRule final : public Statement {
|
||||
ADD_PROPERTY(bool, isOptional)
|
||||
// This should be a simple selector only!
|
||||
ADD_PROPERTY(SelectorListObj, selector)
|
||||
ADD_PROPERTY(Selector_Schema_Obj, schema)
|
||||
public:
|
||||
ExtendRule(SourceSpan pstate, SelectorListObj s);
|
||||
ExtendRule(SourceSpan pstate, Selector_Schema_Obj s);
|
||||
ATTACH_AST_OPERATIONS(ExtendRule)
|
||||
ATTACH_CRTP_PERFORM_METHODS()
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
114
vendor/bundle/ruby/2.6.0/gems/sassc-2.4.0/ext/libsass/src/ast_supports.cpp
vendored
Normal file
114
vendor/bundle/ruby/2.6.0/gems/sassc-2.4.0/ext/libsass/src/ast_supports.cpp
vendored
Normal file
@@ -0,0 +1,114 @@
|
||||
// sass.hpp must go before all system headers to get the
|
||||
// __EXTENSIONS__ fix on Solaris.
|
||||
#include "sass.hpp"
|
||||
#include "ast.hpp"
|
||||
|
||||
|
||||
namespace Sass {
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////
|
||||
/////////////////////////////////////////////////////////////////////////
|
||||
|
||||
SupportsRule::SupportsRule(SourceSpan pstate, SupportsConditionObj condition, Block_Obj block)
|
||||
: ParentStatement(pstate, block), condition_(condition)
|
||||
{ statement_type(SUPPORTS); }
|
||||
SupportsRule::SupportsRule(const SupportsRule* ptr)
|
||||
: ParentStatement(ptr), condition_(ptr->condition_)
|
||||
{ statement_type(SUPPORTS); }
|
||||
bool SupportsRule::bubbles() { return true; }
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////
|
||||
/////////////////////////////////////////////////////////////////////////
|
||||
|
||||
SupportsCondition::SupportsCondition(SourceSpan pstate)
|
||||
: Expression(pstate)
|
||||
{ }
|
||||
|
||||
SupportsCondition::SupportsCondition(const SupportsCondition* ptr)
|
||||
: Expression(ptr)
|
||||
{ }
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////
|
||||
/////////////////////////////////////////////////////////////////////////
|
||||
|
||||
SupportsOperation::SupportsOperation(SourceSpan pstate, SupportsConditionObj l, SupportsConditionObj r, Operand o)
|
||||
: SupportsCondition(pstate), left_(l), right_(r), operand_(o)
|
||||
{ }
|
||||
SupportsOperation::SupportsOperation(const SupportsOperation* ptr)
|
||||
: SupportsCondition(ptr),
|
||||
left_(ptr->left_),
|
||||
right_(ptr->right_),
|
||||
operand_(ptr->operand_)
|
||||
{ }
|
||||
|
||||
bool SupportsOperation::needs_parens(SupportsConditionObj cond) const
|
||||
{
|
||||
if (SupportsOperationObj op = Cast<SupportsOperation>(cond)) {
|
||||
return op->operand() != operand();
|
||||
}
|
||||
return Cast<SupportsNegation>(cond) != NULL;
|
||||
}
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////
|
||||
/////////////////////////////////////////////////////////////////////////
|
||||
|
||||
SupportsNegation::SupportsNegation(SourceSpan pstate, SupportsConditionObj c)
|
||||
: SupportsCondition(pstate), condition_(c)
|
||||
{ }
|
||||
SupportsNegation::SupportsNegation(const SupportsNegation* ptr)
|
||||
: SupportsCondition(ptr), condition_(ptr->condition_)
|
||||
{ }
|
||||
|
||||
bool SupportsNegation::needs_parens(SupportsConditionObj cond) const
|
||||
{
|
||||
return Cast<SupportsNegation>(cond) ||
|
||||
Cast<SupportsOperation>(cond);
|
||||
}
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////
|
||||
/////////////////////////////////////////////////////////////////////////
|
||||
|
||||
SupportsDeclaration::SupportsDeclaration(SourceSpan pstate, ExpressionObj f, ExpressionObj v)
|
||||
: SupportsCondition(pstate), feature_(f), value_(v)
|
||||
{ }
|
||||
SupportsDeclaration::SupportsDeclaration(const SupportsDeclaration* ptr)
|
||||
: SupportsCondition(ptr),
|
||||
feature_(ptr->feature_),
|
||||
value_(ptr->value_)
|
||||
{ }
|
||||
|
||||
bool SupportsDeclaration::needs_parens(SupportsConditionObj cond) const
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////
|
||||
/////////////////////////////////////////////////////////////////////////
|
||||
|
||||
Supports_Interpolation::Supports_Interpolation(SourceSpan pstate, ExpressionObj v)
|
||||
: SupportsCondition(pstate), value_(v)
|
||||
{ }
|
||||
Supports_Interpolation::Supports_Interpolation(const Supports_Interpolation* ptr)
|
||||
: SupportsCondition(ptr),
|
||||
value_(ptr->value_)
|
||||
{ }
|
||||
|
||||
bool Supports_Interpolation::needs_parens(SupportsConditionObj cond) const
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////
|
||||
/////////////////////////////////////////////////////////////////////////
|
||||
|
||||
IMPLEMENT_AST_OPERATORS(SupportsRule);
|
||||
IMPLEMENT_AST_OPERATORS(SupportsCondition);
|
||||
IMPLEMENT_AST_OPERATORS(SupportsOperation);
|
||||
IMPLEMENT_AST_OPERATORS(SupportsNegation);
|
||||
IMPLEMENT_AST_OPERATORS(SupportsDeclaration);
|
||||
IMPLEMENT_AST_OPERATORS(Supports_Interpolation);
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////
|
||||
/////////////////////////////////////////////////////////////////////////
|
||||
|
||||
}
|
||||
121
vendor/bundle/ruby/2.6.0/gems/sassc-2.4.0/ext/libsass/src/ast_supports.hpp
vendored
Normal file
121
vendor/bundle/ruby/2.6.0/gems/sassc-2.4.0/ext/libsass/src/ast_supports.hpp
vendored
Normal file
@@ -0,0 +1,121 @@
|
||||
#ifndef SASS_AST_SUPPORTS_H
|
||||
#define SASS_AST_SUPPORTS_H
|
||||
|
||||
// sass.hpp must go before all system headers to get the
|
||||
// __EXTENSIONS__ fix on Solaris.
|
||||
#include "sass.hpp"
|
||||
|
||||
#include <set>
|
||||
#include <deque>
|
||||
#include <vector>
|
||||
#include <string>
|
||||
#include <sstream>
|
||||
#include <iostream>
|
||||
#include <typeinfo>
|
||||
#include <algorithm>
|
||||
#include "sass/base.h"
|
||||
#include "ast_fwd_decl.hpp"
|
||||
|
||||
#include "util.hpp"
|
||||
#include "units.hpp"
|
||||
#include "context.hpp"
|
||||
#include "position.hpp"
|
||||
#include "constants.hpp"
|
||||
#include "operation.hpp"
|
||||
#include "position.hpp"
|
||||
#include "inspect.hpp"
|
||||
#include "source_map.hpp"
|
||||
#include "environment.hpp"
|
||||
#include "error_handling.hpp"
|
||||
#include "ast_def_macros.hpp"
|
||||
#include "ast_fwd_decl.hpp"
|
||||
#include "source_map.hpp"
|
||||
#include "fn_utils.hpp"
|
||||
|
||||
#include "sass.h"
|
||||
|
||||
namespace Sass {
|
||||
|
||||
////////////////////
|
||||
// `@supports` rule.
|
||||
////////////////////
|
||||
class SupportsRule : public ParentStatement {
|
||||
ADD_PROPERTY(SupportsConditionObj, condition)
|
||||
public:
|
||||
SupportsRule(SourceSpan pstate, SupportsConditionObj condition, Block_Obj block = {});
|
||||
bool bubbles() override;
|
||||
ATTACH_AST_OPERATIONS(SupportsRule)
|
||||
ATTACH_CRTP_PERFORM_METHODS()
|
||||
};
|
||||
|
||||
//////////////////////////////////////////////////////
|
||||
// The abstract superclass of all Supports conditions.
|
||||
//////////////////////////////////////////////////////
|
||||
class SupportsCondition : public Expression {
|
||||
public:
|
||||
SupportsCondition(SourceSpan pstate);
|
||||
virtual bool needs_parens(SupportsConditionObj cond) const { return false; }
|
||||
ATTACH_AST_OPERATIONS(SupportsCondition)
|
||||
ATTACH_CRTP_PERFORM_METHODS()
|
||||
};
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
// An operator condition (e.g. `CONDITION1 and CONDITION2`).
|
||||
////////////////////////////////////////////////////////////
|
||||
class SupportsOperation : public SupportsCondition {
|
||||
public:
|
||||
enum Operand { AND, OR };
|
||||
private:
|
||||
ADD_PROPERTY(SupportsConditionObj, left);
|
||||
ADD_PROPERTY(SupportsConditionObj, right);
|
||||
ADD_PROPERTY(Operand, operand);
|
||||
public:
|
||||
SupportsOperation(SourceSpan pstate, SupportsConditionObj l, SupportsConditionObj r, Operand o);
|
||||
virtual bool needs_parens(SupportsConditionObj cond) const override;
|
||||
ATTACH_AST_OPERATIONS(SupportsOperation)
|
||||
ATTACH_CRTP_PERFORM_METHODS()
|
||||
};
|
||||
|
||||
//////////////////////////////////////////
|
||||
// A negation condition (`not CONDITION`).
|
||||
//////////////////////////////////////////
|
||||
class SupportsNegation : public SupportsCondition {
|
||||
private:
|
||||
ADD_PROPERTY(SupportsConditionObj, condition);
|
||||
public:
|
||||
SupportsNegation(SourceSpan pstate, SupportsConditionObj c);
|
||||
virtual bool needs_parens(SupportsConditionObj cond) const override;
|
||||
ATTACH_AST_OPERATIONS(SupportsNegation)
|
||||
ATTACH_CRTP_PERFORM_METHODS()
|
||||
};
|
||||
|
||||
/////////////////////////////////////////////////////
|
||||
// A declaration condition (e.g. `(feature: value)`).
|
||||
/////////////////////////////////////////////////////
|
||||
class SupportsDeclaration : public SupportsCondition {
|
||||
private:
|
||||
ADD_PROPERTY(ExpressionObj, feature);
|
||||
ADD_PROPERTY(ExpressionObj, value);
|
||||
public:
|
||||
SupportsDeclaration(SourceSpan pstate, ExpressionObj f, ExpressionObj v);
|
||||
virtual bool needs_parens(SupportsConditionObj cond) const override;
|
||||
ATTACH_AST_OPERATIONS(SupportsDeclaration)
|
||||
ATTACH_CRTP_PERFORM_METHODS()
|
||||
};
|
||||
|
||||
///////////////////////////////////////////////
|
||||
// An interpolation condition (e.g. `#{$var}`).
|
||||
///////////////////////////////////////////////
|
||||
class Supports_Interpolation : public SupportsCondition {
|
||||
private:
|
||||
ADD_PROPERTY(ExpressionObj, value);
|
||||
public:
|
||||
Supports_Interpolation(SourceSpan pstate, ExpressionObj v);
|
||||
virtual bool needs_parens(SupportsConditionObj cond) const override;
|
||||
ATTACH_AST_OPERATIONS(Supports_Interpolation)
|
||||
ATTACH_CRTP_PERFORM_METHODS()
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
1154
vendor/bundle/ruby/2.6.0/gems/sassc-2.4.0/ext/libsass/src/ast_values.cpp
vendored
Normal file
1154
vendor/bundle/ruby/2.6.0/gems/sassc-2.4.0/ext/libsass/src/ast_values.cpp
vendored
Normal file
File diff suppressed because it is too large
Load Diff
498
vendor/bundle/ruby/2.6.0/gems/sassc-2.4.0/ext/libsass/src/ast_values.hpp
vendored
Normal file
498
vendor/bundle/ruby/2.6.0/gems/sassc-2.4.0/ext/libsass/src/ast_values.hpp
vendored
Normal file
@@ -0,0 +1,498 @@
|
||||
#ifndef SASS_AST_VALUES_H
|
||||
#define SASS_AST_VALUES_H
|
||||
|
||||
// sass.hpp must go before all system headers to get the
|
||||
// __EXTENSIONS__ fix on Solaris.
|
||||
#include "sass.hpp"
|
||||
#include "ast.hpp"
|
||||
|
||||
namespace Sass {
|
||||
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
// Still just an expression, but with a to_string method
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
class PreValue : public Expression {
|
||||
public:
|
||||
PreValue(SourceSpan pstate, bool d = false, bool e = false, bool i = false, Type ct = NONE);
|
||||
ATTACH_VIRTUAL_AST_OPERATIONS(PreValue);
|
||||
virtual ~PreValue() { }
|
||||
};
|
||||
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
// base class for values that support operations
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
class Value : public PreValue {
|
||||
public:
|
||||
Value(SourceSpan pstate, bool d = false, bool e = false, bool i = false, Type ct = NONE);
|
||||
|
||||
// Some obects are not meant to be compared
|
||||
// ToDo: maybe fallback to pointer comparison?
|
||||
virtual bool operator< (const Expression& rhs) const override = 0;
|
||||
virtual bool operator== (const Expression& rhs) const override = 0;
|
||||
|
||||
// We can give some reasonable implementations by using
|
||||
// inverst operators on the specialized implementations
|
||||
virtual bool operator> (const Expression& rhs) const {
|
||||
return rhs < *this;
|
||||
}
|
||||
virtual bool operator!= (const Expression& rhs) const {
|
||||
return !(*this == rhs);
|
||||
}
|
||||
|
||||
ATTACH_VIRTUAL_AST_OPERATIONS(Value);
|
||||
|
||||
};
|
||||
|
||||
///////////////////////////////////////////////////////////////////////
|
||||
// Lists of values, both comma- and space-separated (distinguished by a
|
||||
// type-tag.) Also used to represent variable-length argument lists.
|
||||
///////////////////////////////////////////////////////////////////////
|
||||
class List : public Value, public Vectorized<ExpressionObj> {
|
||||
void adjust_after_pushing(ExpressionObj e) override { is_expanded(false); }
|
||||
private:
|
||||
ADD_PROPERTY(enum Sass_Separator, separator)
|
||||
ADD_PROPERTY(bool, is_arglist)
|
||||
ADD_PROPERTY(bool, is_bracketed)
|
||||
ADD_PROPERTY(bool, from_selector)
|
||||
public:
|
||||
List(SourceSpan pstate, size_t size = 0, enum Sass_Separator sep = SASS_SPACE, bool argl = false, bool bracket = false);
|
||||
sass::string type() const override { return is_arglist_ ? "arglist" : "list"; }
|
||||
static sass::string type_name() { return "list"; }
|
||||
const char* sep_string(bool compressed = false) const {
|
||||
return separator() == SASS_SPACE ?
|
||||
" " : (compressed ? "," : ", ");
|
||||
}
|
||||
bool is_invisible() const override { return empty() && !is_bracketed(); }
|
||||
ExpressionObj value_at_index(size_t i);
|
||||
|
||||
virtual size_t hash() const override;
|
||||
virtual size_t size() const;
|
||||
virtual void set_delayed(bool delayed) override;
|
||||
|
||||
virtual bool operator< (const Expression& rhs) const override;
|
||||
virtual bool operator== (const Expression& rhs) const override;
|
||||
|
||||
ATTACH_AST_OPERATIONS(List)
|
||||
ATTACH_CRTP_PERFORM_METHODS()
|
||||
};
|
||||
|
||||
///////////////////////////////////////////////////////////////////////
|
||||
// Key value paris.
|
||||
///////////////////////////////////////////////////////////////////////
|
||||
class Map : public Value, public Hashed<ExpressionObj, ExpressionObj, Map_Obj> {
|
||||
void adjust_after_pushing(std::pair<ExpressionObj, ExpressionObj> p) override { is_expanded(false); }
|
||||
public:
|
||||
Map(SourceSpan pstate, size_t size = 0);
|
||||
sass::string type() const override { return "map"; }
|
||||
static sass::string type_name() { return "map"; }
|
||||
bool is_invisible() const override { return empty(); }
|
||||
List_Obj to_list(SourceSpan& pstate);
|
||||
|
||||
virtual size_t hash() const override;
|
||||
|
||||
virtual bool operator< (const Expression& rhs) const override;
|
||||
virtual bool operator== (const Expression& rhs) const override;
|
||||
|
||||
ATTACH_AST_OPERATIONS(Map)
|
||||
ATTACH_CRTP_PERFORM_METHODS()
|
||||
};
|
||||
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
// Binary expressions. Represents logical, relational, and arithmetic
|
||||
// operations. Templatized to avoid large switch statements and repetitive
|
||||
// subclassing.
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
class Binary_Expression : public PreValue {
|
||||
private:
|
||||
HASH_PROPERTY(Operand, op)
|
||||
HASH_PROPERTY(ExpressionObj, left)
|
||||
HASH_PROPERTY(ExpressionObj, right)
|
||||
mutable size_t hash_;
|
||||
public:
|
||||
Binary_Expression(SourceSpan pstate,
|
||||
Operand op, ExpressionObj lhs, ExpressionObj rhs);
|
||||
|
||||
const sass::string type_name();
|
||||
const sass::string separator();
|
||||
bool is_left_interpolant(void) const override;
|
||||
bool is_right_interpolant(void) const override;
|
||||
bool has_interpolant() const override;
|
||||
|
||||
virtual void set_delayed(bool delayed) override;
|
||||
|
||||
virtual bool operator< (const Expression& rhs) const override;
|
||||
virtual bool operator==(const Expression& rhs) const override;
|
||||
|
||||
virtual size_t hash() const override;
|
||||
enum Sass_OP optype() const { return op_.operand; }
|
||||
ATTACH_AST_OPERATIONS(Binary_Expression)
|
||||
ATTACH_CRTP_PERFORM_METHODS()
|
||||
};
|
||||
|
||||
////////////////////////////////////////////////////
|
||||
// Function reference.
|
||||
////////////////////////////////////////////////////
|
||||
class Function final : public Value {
|
||||
public:
|
||||
ADD_PROPERTY(Definition_Obj, definition)
|
||||
ADD_PROPERTY(bool, is_css)
|
||||
public:
|
||||
Function(SourceSpan pstate, Definition_Obj def, bool css);
|
||||
|
||||
sass::string type() const override { return "function"; }
|
||||
static sass::string type_name() { return "function"; }
|
||||
bool is_invisible() const override { return true; }
|
||||
|
||||
sass::string name();
|
||||
|
||||
bool operator< (const Expression& rhs) const override;
|
||||
bool operator== (const Expression& rhs) const override;
|
||||
|
||||
ATTACH_AST_OPERATIONS(Function)
|
||||
ATTACH_CRTP_PERFORM_METHODS()
|
||||
};
|
||||
|
||||
//////////////////
|
||||
// Function calls.
|
||||
//////////////////
|
||||
class Function_Call final : public PreValue {
|
||||
HASH_CONSTREF(String_Obj, sname)
|
||||
HASH_PROPERTY(Arguments_Obj, arguments)
|
||||
HASH_PROPERTY(Function_Obj, func)
|
||||
ADD_PROPERTY(bool, via_call)
|
||||
ADD_PROPERTY(void*, cookie)
|
||||
mutable size_t hash_;
|
||||
public:
|
||||
Function_Call(SourceSpan pstate, sass::string n, Arguments_Obj args, void* cookie);
|
||||
Function_Call(SourceSpan pstate, sass::string n, Arguments_Obj args, Function_Obj func);
|
||||
Function_Call(SourceSpan pstate, sass::string n, Arguments_Obj args);
|
||||
|
||||
Function_Call(SourceSpan pstate, String_Obj n, Arguments_Obj args, void* cookie);
|
||||
Function_Call(SourceSpan pstate, String_Obj n, Arguments_Obj args, Function_Obj func);
|
||||
Function_Call(SourceSpan pstate, String_Obj n, Arguments_Obj args);
|
||||
|
||||
sass::string name() const;
|
||||
bool is_css();
|
||||
|
||||
bool operator==(const Expression& rhs) const override;
|
||||
|
||||
size_t hash() const override;
|
||||
|
||||
ATTACH_AST_OPERATIONS(Function_Call)
|
||||
ATTACH_CRTP_PERFORM_METHODS()
|
||||
};
|
||||
|
||||
///////////////////////
|
||||
// Variable references.
|
||||
///////////////////////
|
||||
class Variable final : public PreValue {
|
||||
ADD_CONSTREF(sass::string, name)
|
||||
public:
|
||||
Variable(SourceSpan pstate, sass::string n);
|
||||
virtual bool operator==(const Expression& rhs) const override;
|
||||
virtual size_t hash() const override;
|
||||
ATTACH_AST_OPERATIONS(Variable)
|
||||
ATTACH_CRTP_PERFORM_METHODS()
|
||||
};
|
||||
|
||||
////////////////////////////////////////////////
|
||||
// Numbers, percentages, dimensions, and colors.
|
||||
////////////////////////////////////////////////
|
||||
class Number final : public Value, public Units {
|
||||
HASH_PROPERTY(double, value)
|
||||
ADD_PROPERTY(bool, zero)
|
||||
mutable size_t hash_;
|
||||
public:
|
||||
Number(SourceSpan pstate, double val, sass::string u = "", bool zero = true);
|
||||
|
||||
bool zero() { return zero_; }
|
||||
|
||||
sass::string type() const override { return "number"; }
|
||||
static sass::string type_name() { return "number"; }
|
||||
|
||||
// cancel out unnecessary units
|
||||
// result will be in input units
|
||||
void reduce();
|
||||
|
||||
// normalize units to defaults
|
||||
// needed to compare two numbers
|
||||
void normalize();
|
||||
|
||||
size_t hash() const override;
|
||||
|
||||
bool operator< (const Number& rhs) const;
|
||||
bool operator== (const Number& rhs) const;
|
||||
bool operator< (const Expression& rhs) const override;
|
||||
bool operator== (const Expression& rhs) const override;
|
||||
ATTACH_AST_OPERATIONS(Number)
|
||||
ATTACH_CRTP_PERFORM_METHODS()
|
||||
};
|
||||
|
||||
//////////
|
||||
// Colors.
|
||||
//////////
|
||||
class Color : public Value {
|
||||
ADD_CONSTREF(sass::string, disp)
|
||||
HASH_PROPERTY(double, a)
|
||||
protected:
|
||||
mutable size_t hash_;
|
||||
public:
|
||||
Color(SourceSpan pstate, double a = 1, const sass::string disp = "");
|
||||
|
||||
sass::string type() const override { return "color"; }
|
||||
static sass::string type_name() { return "color"; }
|
||||
|
||||
virtual size_t hash() const override = 0;
|
||||
|
||||
bool operator< (const Expression& rhs) const override;
|
||||
bool operator== (const Expression& rhs) const override;
|
||||
|
||||
virtual Color_RGBA* copyAsRGBA() const = 0;
|
||||
virtual Color_RGBA* toRGBA() = 0;
|
||||
|
||||
virtual Color_HSLA* copyAsHSLA() const = 0;
|
||||
virtual Color_HSLA* toHSLA() = 0;
|
||||
|
||||
ATTACH_VIRTUAL_AST_OPERATIONS(Color)
|
||||
};
|
||||
|
||||
//////////
|
||||
// Colors.
|
||||
//////////
|
||||
class Color_RGBA final : public Color {
|
||||
HASH_PROPERTY(double, r)
|
||||
HASH_PROPERTY(double, g)
|
||||
HASH_PROPERTY(double, b)
|
||||
public:
|
||||
Color_RGBA(SourceSpan pstate, double r, double g, double b, double a = 1, const sass::string disp = "");
|
||||
|
||||
sass::string type() const override { return "color"; }
|
||||
static sass::string type_name() { return "color"; }
|
||||
|
||||
size_t hash() const override;
|
||||
|
||||
Color_RGBA* copyAsRGBA() const override;
|
||||
Color_RGBA* toRGBA() override { return this; }
|
||||
|
||||
Color_HSLA* copyAsHSLA() const override;
|
||||
Color_HSLA* toHSLA() override { return copyAsHSLA(); }
|
||||
|
||||
bool operator< (const Expression& rhs) const override;
|
||||
bool operator== (const Expression& rhs) const override;
|
||||
|
||||
ATTACH_AST_OPERATIONS(Color_RGBA)
|
||||
ATTACH_CRTP_PERFORM_METHODS()
|
||||
};
|
||||
|
||||
|
||||
//////////
|
||||
// Colors.
|
||||
//////////
|
||||
class Color_HSLA final : public Color {
|
||||
HASH_PROPERTY(double, h)
|
||||
HASH_PROPERTY(double, s)
|
||||
HASH_PROPERTY(double, l)
|
||||
public:
|
||||
Color_HSLA(SourceSpan pstate, double h, double s, double l, double a = 1, const sass::string disp = "");
|
||||
|
||||
sass::string type() const override { return "color"; }
|
||||
static sass::string type_name() { return "color"; }
|
||||
|
||||
size_t hash() const override;
|
||||
|
||||
Color_RGBA* copyAsRGBA() const override;
|
||||
Color_RGBA* toRGBA() override { return copyAsRGBA(); }
|
||||
|
||||
Color_HSLA* copyAsHSLA() const override;
|
||||
Color_HSLA* toHSLA() override { return this; }
|
||||
|
||||
bool operator< (const Expression& rhs) const override;
|
||||
bool operator== (const Expression& rhs) const override;
|
||||
|
||||
ATTACH_AST_OPERATIONS(Color_HSLA)
|
||||
ATTACH_CRTP_PERFORM_METHODS()
|
||||
};
|
||||
|
||||
//////////////////////////////
|
||||
// Errors from Sass_Values.
|
||||
//////////////////////////////
|
||||
class Custom_Error final : public Value {
|
||||
ADD_CONSTREF(sass::string, message)
|
||||
public:
|
||||
Custom_Error(SourceSpan pstate, sass::string msg);
|
||||
bool operator< (const Expression& rhs) const override;
|
||||
bool operator== (const Expression& rhs) const override;
|
||||
ATTACH_AST_OPERATIONS(Custom_Error)
|
||||
ATTACH_CRTP_PERFORM_METHODS()
|
||||
};
|
||||
|
||||
//////////////////////////////
|
||||
// Warnings from Sass_Values.
|
||||
//////////////////////////////
|
||||
class Custom_Warning final : public Value {
|
||||
ADD_CONSTREF(sass::string, message)
|
||||
public:
|
||||
Custom_Warning(SourceSpan pstate, sass::string msg);
|
||||
bool operator< (const Expression& rhs) const override;
|
||||
bool operator== (const Expression& rhs) const override;
|
||||
ATTACH_AST_OPERATIONS(Custom_Warning)
|
||||
ATTACH_CRTP_PERFORM_METHODS()
|
||||
};
|
||||
|
||||
////////////
|
||||
// Booleans.
|
||||
////////////
|
||||
class Boolean final : public Value {
|
||||
HASH_PROPERTY(bool, value)
|
||||
mutable size_t hash_;
|
||||
public:
|
||||
Boolean(SourceSpan pstate, bool val);
|
||||
operator bool() override { return value_; }
|
||||
|
||||
sass::string type() const override { return "bool"; }
|
||||
static sass::string type_name() { return "bool"; }
|
||||
|
||||
size_t hash() const override;
|
||||
|
||||
bool is_false() override { return !value_; }
|
||||
|
||||
bool operator< (const Expression& rhs) const override;
|
||||
bool operator== (const Expression& rhs) const override;
|
||||
|
||||
ATTACH_AST_OPERATIONS(Boolean)
|
||||
ATTACH_CRTP_PERFORM_METHODS()
|
||||
};
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
// Abstract base class for Sass string values. Includes interpolated and
|
||||
// "flat" strings.
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
class String : public Value {
|
||||
public:
|
||||
String(SourceSpan pstate, bool delayed = false);
|
||||
static sass::string type_name() { return "string"; }
|
||||
virtual ~String() = 0;
|
||||
virtual void rtrim() = 0;
|
||||
virtual bool operator<(const Expression& rhs) const override {
|
||||
return this->to_string() < rhs.to_string();
|
||||
};
|
||||
virtual bool operator==(const Expression& rhs) const override {
|
||||
return this->to_string() == rhs.to_string();
|
||||
};
|
||||
ATTACH_VIRTUAL_AST_OPERATIONS(String);
|
||||
ATTACH_CRTP_PERFORM_METHODS()
|
||||
};
|
||||
inline String::~String() { };
|
||||
|
||||
///////////////////////////////////////////////////////////////////////
|
||||
// Interpolated strings. Meant to be reduced to flat strings during the
|
||||
// evaluation phase.
|
||||
///////////////////////////////////////////////////////////////////////
|
||||
class String_Schema final : public String, public Vectorized<PreValueObj> {
|
||||
ADD_PROPERTY(bool, css)
|
||||
mutable size_t hash_;
|
||||
public:
|
||||
String_Schema(SourceSpan pstate, size_t size = 0, bool css = true);
|
||||
|
||||
sass::string type() const override { return "string"; }
|
||||
static sass::string type_name() { return "string"; }
|
||||
|
||||
bool is_left_interpolant(void) const override;
|
||||
bool is_right_interpolant(void) const override;
|
||||
|
||||
bool has_interpolants();
|
||||
void rtrim() override;
|
||||
size_t hash() const override;
|
||||
virtual void set_delayed(bool delayed) override;
|
||||
|
||||
bool operator< (const Expression& rhs) const override;
|
||||
bool operator==(const Expression& rhs) const override;
|
||||
ATTACH_AST_OPERATIONS(String_Schema)
|
||||
ATTACH_CRTP_PERFORM_METHODS()
|
||||
};
|
||||
|
||||
////////////////////////////////////////////////////////
|
||||
// Flat strings -- the lowest level of raw textual data.
|
||||
////////////////////////////////////////////////////////
|
||||
class String_Constant : public String {
|
||||
ADD_PROPERTY(char, quote_mark)
|
||||
HASH_CONSTREF(sass::string, value)
|
||||
protected:
|
||||
mutable size_t hash_;
|
||||
public:
|
||||
String_Constant(SourceSpan pstate, sass::string val, bool css = true);
|
||||
String_Constant(SourceSpan pstate, const char* beg, bool css = true);
|
||||
String_Constant(SourceSpan pstate, const char* beg, const char* end, bool css = true);
|
||||
String_Constant(SourceSpan pstate, const Token& tok, bool css = true);
|
||||
sass::string type() const override { return "string"; }
|
||||
static sass::string type_name() { return "string"; }
|
||||
bool is_invisible() const override;
|
||||
virtual void rtrim() override;
|
||||
size_t hash() const override;
|
||||
bool operator< (const Expression& rhs) const override;
|
||||
bool operator==(const Expression& rhs) const override;
|
||||
// quotes are forced on inspection
|
||||
virtual sass::string inspect() const override;
|
||||
ATTACH_AST_OPERATIONS(String_Constant)
|
||||
ATTACH_CRTP_PERFORM_METHODS()
|
||||
};
|
||||
|
||||
////////////////////////////////////////////////////////
|
||||
// Possibly quoted string (unquote on instantiation)
|
||||
////////////////////////////////////////////////////////
|
||||
class String_Quoted final : public String_Constant {
|
||||
public:
|
||||
String_Quoted(SourceSpan pstate, sass::string val, char q = 0,
|
||||
bool keep_utf8_escapes = false, bool skip_unquoting = false,
|
||||
bool strict_unquoting = true, bool css = true);
|
||||
bool operator< (const Expression& rhs) const override;
|
||||
bool operator==(const Expression& rhs) const override;
|
||||
// quotes are forced on inspection
|
||||
sass::string inspect() const override;
|
||||
ATTACH_AST_OPERATIONS(String_Quoted)
|
||||
ATTACH_CRTP_PERFORM_METHODS()
|
||||
};
|
||||
|
||||
//////////////////
|
||||
// The null value.
|
||||
//////////////////
|
||||
class Null final : public Value {
|
||||
public:
|
||||
Null(SourceSpan pstate);
|
||||
sass::string type() const override { return "null"; }
|
||||
static sass::string type_name() { return "null"; }
|
||||
bool is_invisible() const override { return true; }
|
||||
operator bool() override { return false; }
|
||||
bool is_false() override { return true; }
|
||||
|
||||
size_t hash() const override;
|
||||
|
||||
bool operator< (const Expression& rhs) const override;
|
||||
bool operator== (const Expression& rhs) const override;
|
||||
|
||||
ATTACH_AST_OPERATIONS(Null)
|
||||
ATTACH_CRTP_PERFORM_METHODS()
|
||||
};
|
||||
|
||||
//////////////////////////////////
|
||||
// The Parent Reference Expression.
|
||||
//////////////////////////////////
|
||||
class Parent_Reference final : public Value {
|
||||
public:
|
||||
Parent_Reference(SourceSpan pstate);
|
||||
sass::string type() const override { return "parent"; }
|
||||
static sass::string type_name() { return "parent"; }
|
||||
bool operator< (const Expression& rhs) const override {
|
||||
return false; // they are always equal
|
||||
}
|
||||
bool operator==(const Expression& rhs) const override {
|
||||
return true; // they are always equal
|
||||
};
|
||||
ATTACH_AST_OPERATIONS(Parent_Reference)
|
||||
ATTACH_CRTP_PERFORM_METHODS()
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
32
vendor/bundle/ruby/2.6.0/gems/sassc-2.4.0/ext/libsass/src/b64/cencode.h
vendored
Normal file
32
vendor/bundle/ruby/2.6.0/gems/sassc-2.4.0/ext/libsass/src/b64/cencode.h
vendored
Normal file
@@ -0,0 +1,32 @@
|
||||
/*
|
||||
cencode.h - c header for a base64 encoding algorithm
|
||||
|
||||
This is part of the libb64 project, and has been placed in the public domain.
|
||||
For details, see http://sourceforge.net/projects/libb64
|
||||
*/
|
||||
|
||||
#ifndef BASE64_CENCODE_H
|
||||
#define BASE64_CENCODE_H
|
||||
|
||||
typedef enum
|
||||
{
|
||||
step_A, step_B, step_C
|
||||
} base64_encodestep;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
base64_encodestep step;
|
||||
char result;
|
||||
int stepcount;
|
||||
} base64_encodestate;
|
||||
|
||||
void base64_init_encodestate(base64_encodestate* state_in);
|
||||
|
||||
char base64_encode_value(char value_in);
|
||||
|
||||
int base64_encode_block(const char* plaintext_in, int length_in, char* code_out, base64_encodestate* state_in);
|
||||
|
||||
int base64_encode_blockend(char* code_out, base64_encodestate* state_in);
|
||||
|
||||
#endif /* BASE64_CENCODE_H */
|
||||
|
||||
79
vendor/bundle/ruby/2.6.0/gems/sassc-2.4.0/ext/libsass/src/b64/encode.h
vendored
Normal file
79
vendor/bundle/ruby/2.6.0/gems/sassc-2.4.0/ext/libsass/src/b64/encode.h
vendored
Normal file
@@ -0,0 +1,79 @@
|
||||
// :mode=c++:
|
||||
/*
|
||||
encode.h - c++ wrapper for a base64 encoding algorithm
|
||||
|
||||
This is part of the libb64 project, and has been placed in the public domain.
|
||||
For details, see http://sourceforge.net/projects/libb64
|
||||
*/
|
||||
#ifndef BASE64_ENCODE_H
|
||||
#define BASE64_ENCODE_H
|
||||
|
||||
#include <iostream>
|
||||
|
||||
namespace base64
|
||||
{
|
||||
extern "C"
|
||||
{
|
||||
#include "cencode.h"
|
||||
}
|
||||
|
||||
struct encoder
|
||||
{
|
||||
base64_encodestate _state;
|
||||
int _buffersize;
|
||||
|
||||
encoder(int buffersize_in = BUFFERSIZE)
|
||||
: _buffersize(buffersize_in)
|
||||
{
|
||||
base64_init_encodestate(&_state);
|
||||
}
|
||||
|
||||
int encode(char value_in)
|
||||
{
|
||||
return base64_encode_value(value_in);
|
||||
}
|
||||
|
||||
int encode(const char* code_in, const int length_in, char* plaintext_out)
|
||||
{
|
||||
return base64_encode_block(code_in, length_in, plaintext_out, &_state);
|
||||
}
|
||||
|
||||
int encode_end(char* plaintext_out)
|
||||
{
|
||||
return base64_encode_blockend(plaintext_out, &_state);
|
||||
}
|
||||
|
||||
void encode(std::istream& istream_in, std::ostream& ostream_in)
|
||||
{
|
||||
base64_init_encodestate(&_state);
|
||||
//
|
||||
const int N = _buffersize;
|
||||
char* plaintext = new char[N];
|
||||
char* code = new char[2*N];
|
||||
int plainlength;
|
||||
int codelength;
|
||||
|
||||
do
|
||||
{
|
||||
istream_in.read(plaintext, N);
|
||||
plainlength = static_cast<int>(istream_in.gcount());
|
||||
//
|
||||
codelength = encode(plaintext, plainlength, code);
|
||||
ostream_in.write(code, codelength);
|
||||
}
|
||||
while (istream_in.good() && plainlength > 0);
|
||||
|
||||
codelength = encode_end(code);
|
||||
ostream_in.write(code, codelength);
|
||||
//
|
||||
base64_init_encodestate(&_state);
|
||||
|
||||
delete [] code;
|
||||
delete [] plaintext;
|
||||
}
|
||||
};
|
||||
|
||||
} // namespace base64
|
||||
|
||||
#endif // BASE64_ENCODE_H
|
||||
|
||||
50
vendor/bundle/ruby/2.6.0/gems/sassc-2.4.0/ext/libsass/src/backtrace.cpp
vendored
Normal file
50
vendor/bundle/ruby/2.6.0/gems/sassc-2.4.0/ext/libsass/src/backtrace.cpp
vendored
Normal file
@@ -0,0 +1,50 @@
|
||||
#include "backtrace.hpp"
|
||||
|
||||
namespace Sass {
|
||||
|
||||
const sass::string traces_to_string(Backtraces traces, sass::string indent) {
|
||||
|
||||
sass::ostream ss;
|
||||
sass::string cwd(File::get_cwd());
|
||||
|
||||
bool first = true;
|
||||
size_t i_beg = traces.size() - 1;
|
||||
size_t i_end = sass::string::npos;
|
||||
for (size_t i = i_beg; i != i_end; i --) {
|
||||
|
||||
const Backtrace& trace = traces[i];
|
||||
|
||||
// make path relative to the current directory
|
||||
sass::string rel_path(File::abs2rel(trace.pstate.getPath(), cwd, cwd));
|
||||
|
||||
// skip functions on error cases (unsure why ruby sass does this)
|
||||
// if (trace.caller.substr(0, 6) == ", in f") continue;
|
||||
|
||||
if (first) {
|
||||
ss << indent;
|
||||
ss << "on line ";
|
||||
ss << trace.pstate.getLine();
|
||||
ss << ":";
|
||||
ss << trace.pstate.getColumn();
|
||||
ss << " of " << rel_path;
|
||||
// ss << trace.caller;
|
||||
first = false;
|
||||
} else {
|
||||
ss << trace.caller;
|
||||
ss << std::endl;
|
||||
ss << indent;
|
||||
ss << "from line ";
|
||||
ss << trace.pstate.getLine();
|
||||
ss << ":";
|
||||
ss << trace.pstate.getColumn();
|
||||
ss << " of " << rel_path;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
ss << std::endl;
|
||||
return ss.str();
|
||||
|
||||
}
|
||||
|
||||
};
|
||||
29
vendor/bundle/ruby/2.6.0/gems/sassc-2.4.0/ext/libsass/src/backtrace.hpp
vendored
Normal file
29
vendor/bundle/ruby/2.6.0/gems/sassc-2.4.0/ext/libsass/src/backtrace.hpp
vendored
Normal file
@@ -0,0 +1,29 @@
|
||||
#ifndef SASS_BACKTRACE_H
|
||||
#define SASS_BACKTRACE_H
|
||||
|
||||
#include <vector>
|
||||
#include <sstream>
|
||||
#include "file.hpp"
|
||||
#include "position.hpp"
|
||||
|
||||
namespace Sass {
|
||||
|
||||
struct Backtrace {
|
||||
|
||||
SourceSpan pstate;
|
||||
sass::string caller;
|
||||
|
||||
Backtrace(SourceSpan pstate, sass::string c = "")
|
||||
: pstate(pstate),
|
||||
caller(c)
|
||||
{ }
|
||||
|
||||
};
|
||||
|
||||
typedef sass::vector<Backtrace> Backtraces;
|
||||
|
||||
const sass::string traces_to_string(Backtraces traces, sass::string indent = "\t");
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
47
vendor/bundle/ruby/2.6.0/gems/sassc-2.4.0/ext/libsass/src/base64vlq.cpp
vendored
Normal file
47
vendor/bundle/ruby/2.6.0/gems/sassc-2.4.0/ext/libsass/src/base64vlq.cpp
vendored
Normal file
@@ -0,0 +1,47 @@
|
||||
// sass.hpp must go before all system headers to get the
|
||||
// __EXTENSIONS__ fix on Solaris.
|
||||
#include "sass.hpp"
|
||||
|
||||
#include "base64vlq.hpp"
|
||||
|
||||
namespace Sass {
|
||||
|
||||
sass::string Base64VLQ::encode(const int number) const
|
||||
{
|
||||
sass::string encoded = "";
|
||||
|
||||
int vlq = to_vlq_signed(number);
|
||||
|
||||
do {
|
||||
int digit = vlq & VLQ_BASE_MASK;
|
||||
vlq >>= VLQ_BASE_SHIFT;
|
||||
if (vlq > 0) {
|
||||
digit |= VLQ_CONTINUATION_BIT;
|
||||
}
|
||||
encoded += base64_encode(digit);
|
||||
} while (vlq > 0);
|
||||
|
||||
return encoded;
|
||||
}
|
||||
|
||||
char Base64VLQ::base64_encode(const int number) const
|
||||
{
|
||||
int index = number;
|
||||
if (index < 0) index = 0;
|
||||
if (index > 63) index = 63;
|
||||
return CHARACTERS[index];
|
||||
}
|
||||
|
||||
int Base64VLQ::to_vlq_signed(const int number) const
|
||||
{
|
||||
return (number < 0) ? ((-number) << 1) + 1 : (number << 1) + 0;
|
||||
}
|
||||
|
||||
const char* Base64VLQ::CHARACTERS = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
|
||||
|
||||
const int Base64VLQ::VLQ_BASE_SHIFT = 5;
|
||||
const int Base64VLQ::VLQ_BASE = 1 << VLQ_BASE_SHIFT;
|
||||
const int Base64VLQ::VLQ_BASE_MASK = VLQ_BASE - 1;
|
||||
const int Base64VLQ::VLQ_CONTINUATION_BIT = VLQ_BASE;
|
||||
|
||||
}
|
||||
30
vendor/bundle/ruby/2.6.0/gems/sassc-2.4.0/ext/libsass/src/base64vlq.hpp
vendored
Normal file
30
vendor/bundle/ruby/2.6.0/gems/sassc-2.4.0/ext/libsass/src/base64vlq.hpp
vendored
Normal file
@@ -0,0 +1,30 @@
|
||||
#ifndef SASS_BASE64VLQ_H
|
||||
#define SASS_BASE64VLQ_H
|
||||
|
||||
#include <string>
|
||||
|
||||
namespace Sass {
|
||||
|
||||
class Base64VLQ {
|
||||
|
||||
public:
|
||||
|
||||
sass::string encode(const int number) const;
|
||||
|
||||
private:
|
||||
|
||||
char base64_encode(const int number) const;
|
||||
|
||||
int to_vlq_signed(const int number) const;
|
||||
|
||||
static const char* CHARACTERS;
|
||||
|
||||
static const int VLQ_BASE_SHIFT;
|
||||
static const int VLQ_BASE;
|
||||
static const int VLQ_BASE_MASK;
|
||||
static const int VLQ_CONTINUATION_BIT;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
312
vendor/bundle/ruby/2.6.0/gems/sassc-2.4.0/ext/libsass/src/bind.cpp
vendored
Normal file
312
vendor/bundle/ruby/2.6.0/gems/sassc-2.4.0/ext/libsass/src/bind.cpp
vendored
Normal file
@@ -0,0 +1,312 @@
|
||||
#include "sass.hpp"
|
||||
#include "bind.hpp"
|
||||
#include "ast.hpp"
|
||||
#include "backtrace.hpp"
|
||||
#include "context.hpp"
|
||||
#include "expand.hpp"
|
||||
#include "eval.hpp"
|
||||
#include <map>
|
||||
#include <iostream>
|
||||
#include <sstream>
|
||||
|
||||
namespace Sass {
|
||||
|
||||
void bind(sass::string type, sass::string name, Parameters_Obj ps, Arguments_Obj as, Env* env, Eval* eval, Backtraces& traces)
|
||||
{
|
||||
sass::string callee(type + " " + name);
|
||||
|
||||
std::map<sass::string, Parameter_Obj> param_map;
|
||||
List_Obj varargs = SASS_MEMORY_NEW(List, as->pstate());
|
||||
varargs->is_arglist(true); // enable keyword size handling
|
||||
|
||||
for (size_t i = 0, L = as->length(); i < L; ++i) {
|
||||
if (auto str = Cast<String_Quoted>((*as)[i]->value())) {
|
||||
// force optional quotes (only if needed)
|
||||
if (str->quote_mark()) {
|
||||
str->quote_mark('*');
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Set up a map to ensure named arguments refer to actual parameters. Also
|
||||
// eval each default value left-to-right, wrt env, populating env as we go.
|
||||
for (size_t i = 0, L = ps->length(); i < L; ++i) {
|
||||
Parameter_Obj p = ps->at(i);
|
||||
param_map[p->name()] = p;
|
||||
// if (p->default_value()) {
|
||||
// env->local_frame()[p->name()] = p->default_value()->perform(eval->with(env));
|
||||
// }
|
||||
}
|
||||
|
||||
// plug in all args; if we have leftover params, deal with it later
|
||||
size_t ip = 0, LP = ps->length();
|
||||
size_t ia = 0, LA = as->length();
|
||||
while (ia < LA) {
|
||||
Argument_Obj a = as->at(ia);
|
||||
if (ip >= LP) {
|
||||
// skip empty rest arguments
|
||||
if (a->is_rest_argument()) {
|
||||
if (List_Obj l = Cast<List>(a->value())) {
|
||||
if (l->length() == 0) {
|
||||
++ ia; continue;
|
||||
}
|
||||
}
|
||||
}
|
||||
sass::ostream msg;
|
||||
msg << "wrong number of arguments (" << LA << " for " << LP << ")";
|
||||
msg << " for `" << name << "'";
|
||||
return error(msg.str(), as->pstate(), traces);
|
||||
}
|
||||
Parameter_Obj p = ps->at(ip);
|
||||
|
||||
// If the current parameter is the rest parameter, process and break the loop
|
||||
if (p->is_rest_parameter()) {
|
||||
// The next argument by coincidence provides a rest argument
|
||||
if (a->is_rest_argument()) {
|
||||
|
||||
// We should always get a list for rest arguments
|
||||
if (List_Obj rest = Cast<List>(a->value())) {
|
||||
// create a new list object for wrapped items
|
||||
List* arglist = SASS_MEMORY_NEW(List,
|
||||
p->pstate(),
|
||||
0,
|
||||
rest->separator(),
|
||||
true);
|
||||
// wrap each item from list as an argument
|
||||
for (ExpressionObj item : rest->elements()) {
|
||||
if (Argument_Obj arg = Cast<Argument>(item)) {
|
||||
arglist->append(SASS_MEMORY_COPY(arg)); // copy
|
||||
} else {
|
||||
arglist->append(SASS_MEMORY_NEW(Argument,
|
||||
item->pstate(),
|
||||
item,
|
||||
"",
|
||||
false,
|
||||
false));
|
||||
}
|
||||
}
|
||||
// assign new arglist to environment
|
||||
env->local_frame()[p->name()] = arglist;
|
||||
}
|
||||
// invalid state
|
||||
else {
|
||||
throw std::runtime_error("invalid state");
|
||||
}
|
||||
} else if (a->is_keyword_argument()) {
|
||||
|
||||
// expand keyword arguments into their parameters
|
||||
List* arglist = SASS_MEMORY_NEW(List, p->pstate(), 0, SASS_COMMA, true);
|
||||
env->local_frame()[p->name()] = arglist;
|
||||
Map_Obj argmap = Cast<Map>(a->value());
|
||||
for (auto key : argmap->keys()) {
|
||||
if (String_Constant_Obj str = Cast<String_Constant>(key)) {
|
||||
sass::string param = unquote(str->value());
|
||||
arglist->append(SASS_MEMORY_NEW(Argument,
|
||||
key->pstate(),
|
||||
argmap->at(key),
|
||||
"$" + param,
|
||||
false,
|
||||
false));
|
||||
} else {
|
||||
traces.push_back(Backtrace(key->pstate()));
|
||||
throw Exception::InvalidVarKwdType(key->pstate(), traces, key->inspect(), a);
|
||||
}
|
||||
}
|
||||
|
||||
} else {
|
||||
|
||||
// create a new list object for wrapped items
|
||||
List_Obj arglist = SASS_MEMORY_NEW(List,
|
||||
p->pstate(),
|
||||
0,
|
||||
SASS_COMMA,
|
||||
true);
|
||||
// consume the next args
|
||||
while (ia < LA) {
|
||||
// get and post inc
|
||||
a = (*as)[ia++];
|
||||
// maybe we have another list as argument
|
||||
List_Obj ls = Cast<List>(a->value());
|
||||
// skip any list completely if empty
|
||||
if (ls && ls->empty() && a->is_rest_argument()) continue;
|
||||
|
||||
ExpressionObj value = a->value();
|
||||
if (Argument_Obj arg = Cast<Argument>(value)) {
|
||||
arglist->append(arg);
|
||||
}
|
||||
// check if we have rest argument
|
||||
else if (a->is_rest_argument()) {
|
||||
// preserve the list separator from rest args
|
||||
if (List_Obj rest = Cast<List>(a->value())) {
|
||||
arglist->separator(rest->separator());
|
||||
|
||||
for (size_t i = 0, L = rest->length(); i < L; ++i) {
|
||||
ExpressionObj obj = rest->value_at_index(i);
|
||||
arglist->append(SASS_MEMORY_NEW(Argument,
|
||||
obj->pstate(),
|
||||
obj,
|
||||
"",
|
||||
false,
|
||||
false));
|
||||
}
|
||||
}
|
||||
// no more arguments
|
||||
break;
|
||||
}
|
||||
// wrap all other value types into Argument
|
||||
else {
|
||||
arglist->append(SASS_MEMORY_NEW(Argument,
|
||||
a->pstate(),
|
||||
a->value(),
|
||||
a->name(),
|
||||
false,
|
||||
false));
|
||||
}
|
||||
}
|
||||
// assign new arglist to environment
|
||||
env->local_frame()[p->name()] = arglist;
|
||||
}
|
||||
// consumed parameter
|
||||
++ip;
|
||||
// no more parameters
|
||||
break;
|
||||
}
|
||||
|
||||
// If the current argument is the rest argument, extract a value for processing
|
||||
else if (a->is_rest_argument()) {
|
||||
// normal param and rest arg
|
||||
List_Obj arglist = Cast<List>(a->value());
|
||||
if (!arglist) {
|
||||
if (ExpressionObj arg = Cast<Expression>(a->value())) {
|
||||
arglist = SASS_MEMORY_NEW(List, a->pstate(), 1);
|
||||
arglist->append(arg);
|
||||
}
|
||||
}
|
||||
|
||||
// empty rest arg - treat all args as default values
|
||||
if (!arglist || !arglist->length()) {
|
||||
break;
|
||||
} else {
|
||||
if (arglist->length() > LP - ip && !ps->has_rest_parameter()) {
|
||||
size_t arg_count = (arglist->length() + LA - 1);
|
||||
sass::ostream msg;
|
||||
msg << callee << " takes " << LP;
|
||||
msg << (LP == 1 ? " argument" : " arguments");
|
||||
msg << " but " << arg_count;
|
||||
msg << (arg_count == 1 ? " was passed" : " were passed.");
|
||||
deprecated_bind(msg.str(), as->pstate());
|
||||
|
||||
while (arglist->length() > LP - ip) {
|
||||
arglist->elements().erase(arglist->elements().end() - 1);
|
||||
}
|
||||
}
|
||||
}
|
||||
// otherwise move one of the rest args into the param, converting to argument if necessary
|
||||
ExpressionObj obj = arglist->at(0);
|
||||
if (!(a = Cast<Argument>(obj))) {
|
||||
Expression* a_to_convert = obj;
|
||||
a = SASS_MEMORY_NEW(Argument,
|
||||
a_to_convert->pstate(),
|
||||
a_to_convert,
|
||||
"",
|
||||
false,
|
||||
false);
|
||||
}
|
||||
arglist->elements().erase(arglist->elements().begin());
|
||||
if (!arglist->length() || (!arglist->is_arglist() && ip + 1 == LP)) {
|
||||
++ia;
|
||||
}
|
||||
|
||||
} else if (a->is_keyword_argument()) {
|
||||
Map_Obj argmap = Cast<Map>(a->value());
|
||||
|
||||
for (auto key : argmap->keys()) {
|
||||
String_Constant* val = Cast<String_Constant>(key);
|
||||
if (val == NULL) {
|
||||
traces.push_back(Backtrace(key->pstate()));
|
||||
throw Exception::InvalidVarKwdType(key->pstate(), traces, key->inspect(), a);
|
||||
}
|
||||
sass::string param = "$" + unquote(val->value());
|
||||
|
||||
if (!param_map.count(param)) {
|
||||
sass::ostream msg;
|
||||
msg << callee << " has no parameter named " << param;
|
||||
error(msg.str(), a->pstate(), traces);
|
||||
}
|
||||
env->local_frame()[param] = argmap->at(key);
|
||||
}
|
||||
++ia;
|
||||
continue;
|
||||
} else {
|
||||
++ia;
|
||||
}
|
||||
|
||||
if (a->name().empty()) {
|
||||
if (env->has_local(p->name())) {
|
||||
sass::ostream msg;
|
||||
msg << "parameter " << p->name()
|
||||
<< " provided more than once in call to " << callee;
|
||||
error(msg.str(), a->pstate(), traces);
|
||||
}
|
||||
// ordinal arg -- bind it to the next param
|
||||
env->local_frame()[p->name()] = a->value();
|
||||
++ip;
|
||||
}
|
||||
else {
|
||||
// named arg -- bind it to the appropriately named param
|
||||
if (!param_map.count(a->name())) {
|
||||
if (ps->has_rest_parameter()) {
|
||||
varargs->append(a);
|
||||
} else {
|
||||
sass::ostream msg;
|
||||
msg << callee << " has no parameter named " << a->name();
|
||||
error(msg.str(), a->pstate(), traces);
|
||||
}
|
||||
}
|
||||
if (param_map[a->name()]) {
|
||||
if (param_map[a->name()]->is_rest_parameter()) {
|
||||
sass::ostream msg;
|
||||
msg << "argument " << a->name() << " of " << callee
|
||||
<< "cannot be used as named argument";
|
||||
error(msg.str(), a->pstate(), traces);
|
||||
}
|
||||
}
|
||||
if (env->has_local(a->name())) {
|
||||
sass::ostream msg;
|
||||
msg << "parameter " << p->name()
|
||||
<< "provided more than once in call to " << callee;
|
||||
error(msg.str(), a->pstate(), traces);
|
||||
}
|
||||
env->local_frame()[a->name()] = a->value();
|
||||
}
|
||||
}
|
||||
// EO while ia
|
||||
|
||||
// If we make it here, we're out of args but may have leftover params.
|
||||
// That's only okay if they have default values, or were already bound by
|
||||
// named arguments, or if it's a single rest-param.
|
||||
for (size_t i = ip; i < LP; ++i) {
|
||||
Parameter_Obj leftover = ps->at(i);
|
||||
// cerr << "env for default params:" << endl;
|
||||
// env->print();
|
||||
// cerr << "********" << endl;
|
||||
if (!env->has_local(leftover->name())) {
|
||||
if (leftover->is_rest_parameter()) {
|
||||
env->local_frame()[leftover->name()] = varargs;
|
||||
}
|
||||
else if (leftover->default_value()) {
|
||||
Expression* dv = leftover->default_value()->perform(eval);
|
||||
env->local_frame()[leftover->name()] = dv;
|
||||
}
|
||||
else {
|
||||
// param is unbound and has no default value -- error
|
||||
throw Exception::MissingArgument(as->pstate(), traces, name, leftover->name(), type);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
15
vendor/bundle/ruby/2.6.0/gems/sassc-2.4.0/ext/libsass/src/bind.hpp
vendored
Normal file
15
vendor/bundle/ruby/2.6.0/gems/sassc-2.4.0/ext/libsass/src/bind.hpp
vendored
Normal file
@@ -0,0 +1,15 @@
|
||||
#ifndef SASS_BIND_H
|
||||
#define SASS_BIND_H
|
||||
|
||||
#include <string>
|
||||
#include "backtrace.hpp"
|
||||
#include "environment.hpp"
|
||||
#include "ast_fwd_decl.hpp"
|
||||
|
||||
namespace Sass {
|
||||
|
||||
void bind(sass::string type, sass::string name, Parameters_Obj, Arguments_Obj, Env*, Eval*, Backtraces& traces);
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
64
vendor/bundle/ruby/2.6.0/gems/sassc-2.4.0/ext/libsass/src/c2ast.cpp
vendored
Normal file
64
vendor/bundle/ruby/2.6.0/gems/sassc-2.4.0/ext/libsass/src/c2ast.cpp
vendored
Normal file
@@ -0,0 +1,64 @@
|
||||
#include "ast.hpp"
|
||||
#include "units.hpp"
|
||||
#include "position.hpp"
|
||||
#include "backtrace.hpp"
|
||||
#include "sass/values.h"
|
||||
#include "ast_fwd_decl.hpp"
|
||||
#include "error_handling.hpp"
|
||||
|
||||
namespace Sass {
|
||||
|
||||
Value* c2ast(union Sass_Value* v, Backtraces traces, SourceSpan pstate)
|
||||
{
|
||||
using std::strlen;
|
||||
using std::strcpy;
|
||||
Value* e = NULL;
|
||||
switch (sass_value_get_tag(v)) {
|
||||
case SASS_BOOLEAN: {
|
||||
e = SASS_MEMORY_NEW(Boolean, pstate, !!sass_boolean_get_value(v));
|
||||
} break;
|
||||
case SASS_NUMBER: {
|
||||
e = SASS_MEMORY_NEW(Number, pstate, sass_number_get_value(v), sass_number_get_unit(v));
|
||||
} break;
|
||||
case SASS_COLOR: {
|
||||
e = SASS_MEMORY_NEW(Color_RGBA, pstate, sass_color_get_r(v), sass_color_get_g(v), sass_color_get_b(v), sass_color_get_a(v));
|
||||
} break;
|
||||
case SASS_STRING: {
|
||||
if (sass_string_is_quoted(v))
|
||||
e = SASS_MEMORY_NEW(String_Quoted, pstate, sass_string_get_value(v));
|
||||
else {
|
||||
e = SASS_MEMORY_NEW(String_Constant, pstate, sass_string_get_value(v));
|
||||
}
|
||||
} break;
|
||||
case SASS_LIST: {
|
||||
List* l = SASS_MEMORY_NEW(List, pstate, sass_list_get_length(v), sass_list_get_separator(v));
|
||||
for (size_t i = 0, L = sass_list_get_length(v); i < L; ++i) {
|
||||
l->append(c2ast(sass_list_get_value(v, i), traces, pstate));
|
||||
}
|
||||
l->is_bracketed(sass_list_get_is_bracketed(v));
|
||||
e = l;
|
||||
} break;
|
||||
case SASS_MAP: {
|
||||
Map* m = SASS_MEMORY_NEW(Map, pstate);
|
||||
for (size_t i = 0, L = sass_map_get_length(v); i < L; ++i) {
|
||||
*m << std::make_pair(
|
||||
c2ast(sass_map_get_key(v, i), traces, pstate),
|
||||
c2ast(sass_map_get_value(v, i), traces, pstate));
|
||||
}
|
||||
e = m;
|
||||
} break;
|
||||
case SASS_NULL: {
|
||||
e = SASS_MEMORY_NEW(Null, pstate);
|
||||
} break;
|
||||
case SASS_ERROR: {
|
||||
error("Error in C function: " + sass::string(sass_error_get_message(v)), pstate, traces);
|
||||
} break;
|
||||
case SASS_WARNING: {
|
||||
error("Warning in C function: " + sass::string(sass_warning_get_message(v)), pstate, traces);
|
||||
} break;
|
||||
default: break;
|
||||
}
|
||||
return e;
|
||||
}
|
||||
|
||||
}
|
||||
14
vendor/bundle/ruby/2.6.0/gems/sassc-2.4.0/ext/libsass/src/c2ast.hpp
vendored
Normal file
14
vendor/bundle/ruby/2.6.0/gems/sassc-2.4.0/ext/libsass/src/c2ast.hpp
vendored
Normal file
@@ -0,0 +1,14 @@
|
||||
#ifndef SASS_C2AST_H
|
||||
#define SASS_C2AST_H
|
||||
|
||||
#include "position.hpp"
|
||||
#include "backtrace.hpp"
|
||||
#include "ast_fwd_decl.hpp"
|
||||
|
||||
namespace Sass {
|
||||
|
||||
Value* c2ast(union Sass_Value* v, Backtraces traces, SourceSpan pstate);
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
54
vendor/bundle/ruby/2.6.0/gems/sassc-2.4.0/ext/libsass/src/c99func.c
vendored
Normal file
54
vendor/bundle/ruby/2.6.0/gems/sassc-2.4.0/ext/libsass/src/c99func.c
vendored
Normal file
@@ -0,0 +1,54 @@
|
||||
/*
|
||||
Copyright (C) 2011 Joseph A. Adams (joeyadams3.14159@gmail.com)
|
||||
All rights reserved.
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in
|
||||
all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#if defined(_MSC_VER) && _MSC_VER < 1900
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdarg.h>
|
||||
|
||||
static int c99_vsnprintf(char* str, size_t size, const char* format, va_list ap)
|
||||
{
|
||||
int count = -1;
|
||||
|
||||
if (size != 0)
|
||||
count = _vsnprintf_s(str, size, _TRUNCATE, format, ap);
|
||||
if (count == -1)
|
||||
count = _vscprintf(format, ap);
|
||||
|
||||
return count;
|
||||
}
|
||||
|
||||
int snprintf(char* str, size_t size, const char* format, ...)
|
||||
{
|
||||
int count;
|
||||
va_list ap;
|
||||
|
||||
va_start(ap, format);
|
||||
count = c99_vsnprintf(str, size, format, ap);
|
||||
va_end(ap);
|
||||
|
||||
return count;
|
||||
}
|
||||
|
||||
#endif
|
||||
106
vendor/bundle/ruby/2.6.0/gems/sassc-2.4.0/ext/libsass/src/cencode.c
vendored
Normal file
106
vendor/bundle/ruby/2.6.0/gems/sassc-2.4.0/ext/libsass/src/cencode.c
vendored
Normal file
@@ -0,0 +1,106 @@
|
||||
/*
|
||||
cencoder.c - c source to a base64 encoding algorithm implementation
|
||||
|
||||
This is part of the libb64 project, and has been placed in the public domain.
|
||||
For details, see http://sourceforge.net/projects/libb64
|
||||
*/
|
||||
|
||||
#include "b64/cencode.h"
|
||||
|
||||
void base64_init_encodestate(base64_encodestate* state_in)
|
||||
{
|
||||
state_in->step = step_A;
|
||||
state_in->result = 0;
|
||||
state_in->stepcount = 0;
|
||||
}
|
||||
|
||||
char base64_encode_value(char value_in)
|
||||
{
|
||||
static const char* encoding = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
|
||||
if (value_in > 63) return '=';
|
||||
return encoding[(int)value_in];
|
||||
}
|
||||
|
||||
int base64_encode_block(const char* plaintext_in, int length_in, char* code_out, base64_encodestate* state_in)
|
||||
{
|
||||
const char* plainchar = plaintext_in;
|
||||
const char* const plaintextend = plaintext_in + length_in;
|
||||
char* codechar = code_out;
|
||||
char result;
|
||||
char fragment;
|
||||
|
||||
result = state_in->result;
|
||||
|
||||
switch (state_in->step)
|
||||
{
|
||||
while (1)
|
||||
{
|
||||
case step_A:
|
||||
if (plainchar == plaintextend)
|
||||
{
|
||||
state_in->result = result;
|
||||
state_in->step = step_A;
|
||||
return (int)(codechar - code_out);
|
||||
}
|
||||
fragment = *plainchar++;
|
||||
result = (fragment & 0x0fc) >> 2;
|
||||
*codechar++ = base64_encode_value(result);
|
||||
result = (fragment & 0x003) << 4;
|
||||
/* fall through */
|
||||
|
||||
case step_B:
|
||||
if (plainchar == plaintextend)
|
||||
{
|
||||
state_in->result = result;
|
||||
state_in->step = step_B;
|
||||
return (int)(codechar - code_out);
|
||||
}
|
||||
fragment = *plainchar++;
|
||||
result |= (fragment & 0x0f0) >> 4;
|
||||
*codechar++ = base64_encode_value(result);
|
||||
result = (fragment & 0x00f) << 2;
|
||||
/* fall through */
|
||||
|
||||
case step_C:
|
||||
if (plainchar == plaintextend)
|
||||
{
|
||||
state_in->result = result;
|
||||
state_in->step = step_C;
|
||||
return (int)(codechar - code_out);
|
||||
}
|
||||
fragment = *plainchar++;
|
||||
result |= (fragment & 0x0c0) >> 6;
|
||||
*codechar++ = base64_encode_value(result);
|
||||
result = (fragment & 0x03f) >> 0;
|
||||
*codechar++ = base64_encode_value(result);
|
||||
|
||||
++(state_in->stepcount);
|
||||
}
|
||||
}
|
||||
/* control should not reach here */
|
||||
return (int)(codechar - code_out);
|
||||
}
|
||||
|
||||
int base64_encode_blockend(char* code_out, base64_encodestate* state_in)
|
||||
{
|
||||
char* codechar = code_out;
|
||||
|
||||
switch (state_in->step)
|
||||
{
|
||||
case step_B:
|
||||
*codechar++ = base64_encode_value(state_in->result);
|
||||
*codechar++ = '=';
|
||||
*codechar++ = '=';
|
||||
break;
|
||||
case step_C:
|
||||
*codechar++ = base64_encode_value(state_in->result);
|
||||
*codechar++ = '=';
|
||||
break;
|
||||
case step_A:
|
||||
break;
|
||||
}
|
||||
*codechar++ = '\n';
|
||||
|
||||
return (int)(codechar - code_out);
|
||||
}
|
||||
|
||||
393
vendor/bundle/ruby/2.6.0/gems/sassc-2.4.0/ext/libsass/src/check_nesting.cpp
vendored
Normal file
393
vendor/bundle/ruby/2.6.0/gems/sassc-2.4.0/ext/libsass/src/check_nesting.cpp
vendored
Normal file
@@ -0,0 +1,393 @@
|
||||
// sass.hpp must go before all system headers to get the
|
||||
// __EXTENSIONS__ fix on Solaris.
|
||||
#include "sass.hpp"
|
||||
#include "ast.hpp"
|
||||
#include "check_nesting.hpp"
|
||||
|
||||
namespace Sass {
|
||||
|
||||
CheckNesting::CheckNesting()
|
||||
: parents(sass::vector<Statement*>()),
|
||||
traces(sass::vector<Backtrace>()),
|
||||
parent(0), current_mixin_definition(0)
|
||||
{ }
|
||||
|
||||
void error(AST_Node* node, Backtraces traces, sass::string msg) {
|
||||
traces.push_back(Backtrace(node->pstate()));
|
||||
throw Exception::InvalidSass(node->pstate(), traces, msg);
|
||||
}
|
||||
|
||||
Statement* CheckNesting::visit_children(Statement* parent)
|
||||
{
|
||||
Statement* old_parent = this->parent;
|
||||
|
||||
if (AtRootRule* root = Cast<AtRootRule>(parent)) {
|
||||
sass::vector<Statement*> old_parents = this->parents;
|
||||
sass::vector<Statement*> new_parents;
|
||||
|
||||
for (size_t i = 0, L = this->parents.size(); i < L; i++) {
|
||||
Statement* p = this->parents.at(i);
|
||||
if (!root->exclude_node(p)) {
|
||||
new_parents.push_back(p);
|
||||
}
|
||||
}
|
||||
this->parents = new_parents;
|
||||
|
||||
for (size_t i = this->parents.size(); i > 0; i--) {
|
||||
Statement* p = 0;
|
||||
Statement* gp = 0;
|
||||
if (i > 0) p = this->parents.at(i - 1);
|
||||
if (i > 1) gp = this->parents.at(i - 2);
|
||||
|
||||
if (!this->is_transparent_parent(p, gp)) {
|
||||
this->parent = p;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
AtRootRule* ar = Cast<AtRootRule>(parent);
|
||||
Block* ret = ar->block();
|
||||
|
||||
if (ret != NULL) {
|
||||
for (auto n : ret->elements()) {
|
||||
n->perform(this);
|
||||
}
|
||||
}
|
||||
|
||||
this->parent = old_parent;
|
||||
this->parents = old_parents;
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
if (!this->is_transparent_parent(parent, old_parent)) {
|
||||
this->parent = parent;
|
||||
}
|
||||
|
||||
this->parents.push_back(parent);
|
||||
|
||||
Block* b = Cast<Block>(parent);
|
||||
|
||||
if (Trace* trace = Cast<Trace>(parent)) {
|
||||
if (trace->type() == 'i') {
|
||||
this->traces.push_back(Backtrace(trace->pstate()));
|
||||
}
|
||||
}
|
||||
|
||||
if (!b) {
|
||||
if (ParentStatement* bb = Cast<ParentStatement>(parent)) {
|
||||
b = bb->block();
|
||||
}
|
||||
}
|
||||
|
||||
if (b) {
|
||||
for (auto n : b->elements()) {
|
||||
n->perform(this);
|
||||
}
|
||||
}
|
||||
|
||||
this->parent = old_parent;
|
||||
this->parents.pop_back();
|
||||
|
||||
if (Trace* trace = Cast<Trace>(parent)) {
|
||||
if (trace->type() == 'i') {
|
||||
this->traces.pop_back();
|
||||
}
|
||||
}
|
||||
|
||||
return b;
|
||||
}
|
||||
|
||||
|
||||
Statement* CheckNesting::operator()(Block* b)
|
||||
{
|
||||
return this->visit_children(b);
|
||||
}
|
||||
|
||||
Statement* CheckNesting::operator()(Definition* n)
|
||||
{
|
||||
if (!this->should_visit(n)) return NULL;
|
||||
if (!is_mixin(n)) {
|
||||
visit_children(n);
|
||||
return n;
|
||||
}
|
||||
|
||||
Definition* old_mixin_definition = this->current_mixin_definition;
|
||||
this->current_mixin_definition = n;
|
||||
|
||||
visit_children(n);
|
||||
|
||||
this->current_mixin_definition = old_mixin_definition;
|
||||
|
||||
return n;
|
||||
}
|
||||
|
||||
Statement* CheckNesting::operator()(If* i)
|
||||
{
|
||||
this->visit_children(i);
|
||||
|
||||
if (Block* b = Cast<Block>(i->alternative())) {
|
||||
for (auto n : b->elements()) n->perform(this);
|
||||
}
|
||||
|
||||
return i;
|
||||
}
|
||||
|
||||
bool CheckNesting::should_visit(Statement* node)
|
||||
{
|
||||
if (!this->parent) return true;
|
||||
|
||||
if (Cast<Content>(node))
|
||||
{ this->invalid_content_parent(this->parent, node); }
|
||||
|
||||
if (is_charset(node))
|
||||
{ this->invalid_charset_parent(this->parent, node); }
|
||||
|
||||
if (Cast<ExtendRule>(node))
|
||||
{ this->invalid_extend_parent(this->parent, node); }
|
||||
|
||||
// if (Cast<Import>(node))
|
||||
// { this->invalid_import_parent(this->parent); }
|
||||
|
||||
if (this->is_mixin(node))
|
||||
{ this->invalid_mixin_definition_parent(this->parent, node); }
|
||||
|
||||
if (this->is_function(node))
|
||||
{ this->invalid_function_parent(this->parent, node); }
|
||||
|
||||
if (this->is_function(this->parent))
|
||||
{ this->invalid_function_child(node); }
|
||||
|
||||
if (Declaration* d = Cast<Declaration>(node))
|
||||
{
|
||||
this->invalid_prop_parent(this->parent, node);
|
||||
this->invalid_value_child(d->value());
|
||||
}
|
||||
|
||||
if (Cast<Declaration>(this->parent))
|
||||
{ this->invalid_prop_child(node); }
|
||||
|
||||
if (Cast<Return>(node))
|
||||
{ this->invalid_return_parent(this->parent, node); }
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void CheckNesting::invalid_content_parent(Statement* parent, AST_Node* node)
|
||||
{
|
||||
if (!this->current_mixin_definition) {
|
||||
error(node, traces, "@content may only be used within a mixin.");
|
||||
}
|
||||
}
|
||||
|
||||
void CheckNesting::invalid_charset_parent(Statement* parent, AST_Node* node)
|
||||
{
|
||||
if (!(
|
||||
is_root_node(parent)
|
||||
)) {
|
||||
error(node, traces, "@charset may only be used at the root of a document.");
|
||||
}
|
||||
}
|
||||
|
||||
void CheckNesting::invalid_extend_parent(Statement* parent, AST_Node* node)
|
||||
{
|
||||
if (!(
|
||||
Cast<StyleRule>(parent) ||
|
||||
Cast<Mixin_Call>(parent) ||
|
||||
is_mixin(parent)
|
||||
)) {
|
||||
error(node, traces, "Extend directives may only be used within rules.");
|
||||
}
|
||||
}
|
||||
|
||||
// void CheckNesting::invalid_import_parent(Statement* parent, AST_Node* node)
|
||||
// {
|
||||
// for (auto pp : this->parents) {
|
||||
// if (
|
||||
// Cast<EachRule>(pp) ||
|
||||
// Cast<ForRule>(pp) ||
|
||||
// Cast<If>(pp) ||
|
||||
// Cast<WhileRule>(pp) ||
|
||||
// Cast<Trace>(pp) ||
|
||||
// Cast<Mixin_Call>(pp) ||
|
||||
// is_mixin(pp)
|
||||
// ) {
|
||||
// error(node, traces, "Import directives may not be defined within control directives or other mixins.");
|
||||
// }
|
||||
// }
|
||||
|
||||
// if (this->is_root_node(parent)) {
|
||||
// return;
|
||||
// }
|
||||
|
||||
// if (false/*n.css_import?*/) {
|
||||
// error(node, traces, "CSS import directives may only be used at the root of a document.");
|
||||
// }
|
||||
// }
|
||||
|
||||
void CheckNesting::invalid_mixin_definition_parent(Statement* parent, AST_Node* node)
|
||||
{
|
||||
for (Statement* pp : this->parents) {
|
||||
if (
|
||||
Cast<EachRule>(pp) ||
|
||||
Cast<ForRule>(pp) ||
|
||||
Cast<If>(pp) ||
|
||||
Cast<WhileRule>(pp) ||
|
||||
Cast<Trace>(pp) ||
|
||||
Cast<Mixin_Call>(pp) ||
|
||||
is_mixin(pp)
|
||||
) {
|
||||
error(node, traces, "Mixins may not be defined within control directives or other mixins.");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void CheckNesting::invalid_function_parent(Statement* parent, AST_Node* node)
|
||||
{
|
||||
for (Statement* pp : this->parents) {
|
||||
if (
|
||||
Cast<EachRule>(pp) ||
|
||||
Cast<ForRule>(pp) ||
|
||||
Cast<If>(pp) ||
|
||||
Cast<WhileRule>(pp) ||
|
||||
Cast<Trace>(pp) ||
|
||||
Cast<Mixin_Call>(pp) ||
|
||||
is_mixin(pp)
|
||||
) {
|
||||
error(node, traces, "Functions may not be defined within control directives or other mixins.");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void CheckNesting::invalid_function_child(Statement* child)
|
||||
{
|
||||
if (!(
|
||||
Cast<EachRule>(child) ||
|
||||
Cast<ForRule>(child) ||
|
||||
Cast<If>(child) ||
|
||||
Cast<WhileRule>(child) ||
|
||||
Cast<Trace>(child) ||
|
||||
Cast<Comment>(child) ||
|
||||
Cast<DebugRule>(child) ||
|
||||
Cast<Return>(child) ||
|
||||
Cast<Variable>(child) ||
|
||||
// Ruby Sass doesn't distinguish variables and assignments
|
||||
Cast<Assignment>(child) ||
|
||||
Cast<WarningRule>(child) ||
|
||||
Cast<ErrorRule>(child)
|
||||
)) {
|
||||
error(child, traces, "Functions can only contain variable declarations and control directives.");
|
||||
}
|
||||
}
|
||||
|
||||
void CheckNesting::invalid_prop_child(Statement* child)
|
||||
{
|
||||
if (!(
|
||||
Cast<EachRule>(child) ||
|
||||
Cast<ForRule>(child) ||
|
||||
Cast<If>(child) ||
|
||||
Cast<WhileRule>(child) ||
|
||||
Cast<Trace>(child) ||
|
||||
Cast<Comment>(child) ||
|
||||
Cast<Declaration>(child) ||
|
||||
Cast<Mixin_Call>(child)
|
||||
)) {
|
||||
error(child, traces, "Illegal nesting: Only properties may be nested beneath properties.");
|
||||
}
|
||||
}
|
||||
|
||||
void CheckNesting::invalid_prop_parent(Statement* parent, AST_Node* node)
|
||||
{
|
||||
if (!(
|
||||
is_mixin(parent) ||
|
||||
is_directive_node(parent) ||
|
||||
Cast<StyleRule>(parent) ||
|
||||
Cast<Keyframe_Rule>(parent) ||
|
||||
Cast<Declaration>(parent) ||
|
||||
Cast<Mixin_Call>(parent)
|
||||
)) {
|
||||
error(node, traces, "Properties are only allowed within rules, directives, mixin includes, or other properties.");
|
||||
}
|
||||
}
|
||||
|
||||
void CheckNesting::invalid_value_child(AST_Node* d)
|
||||
{
|
||||
if (Map* m = Cast<Map>(d)) {
|
||||
traces.push_back(Backtrace(m->pstate()));
|
||||
throw Exception::InvalidValue(traces, *m);
|
||||
}
|
||||
if (Number* n = Cast<Number>(d)) {
|
||||
if (!n->is_valid_css_unit()) {
|
||||
traces.push_back(Backtrace(n->pstate()));
|
||||
throw Exception::InvalidValue(traces, *n);
|
||||
}
|
||||
}
|
||||
|
||||
// error(dbg + " isn't a valid CSS value.", m->pstate(),);
|
||||
|
||||
}
|
||||
|
||||
void CheckNesting::invalid_return_parent(Statement* parent, AST_Node* node)
|
||||
{
|
||||
if (!this->is_function(parent)) {
|
||||
error(node, traces, "@return may only be used within a function.");
|
||||
}
|
||||
}
|
||||
|
||||
bool CheckNesting::is_transparent_parent(Statement* parent, Statement* grandparent)
|
||||
{
|
||||
bool parent_bubbles = parent && parent->bubbles();
|
||||
|
||||
bool valid_bubble_node = parent_bubbles &&
|
||||
!is_root_node(grandparent) &&
|
||||
!is_at_root_node(grandparent);
|
||||
|
||||
return Cast<Import>(parent) ||
|
||||
Cast<EachRule>(parent) ||
|
||||
Cast<ForRule>(parent) ||
|
||||
Cast<If>(parent) ||
|
||||
Cast<WhileRule>(parent) ||
|
||||
Cast<Trace>(parent) ||
|
||||
valid_bubble_node;
|
||||
}
|
||||
|
||||
bool CheckNesting::is_charset(Statement* n)
|
||||
{
|
||||
AtRule* d = Cast<AtRule>(n);
|
||||
return d && d->keyword() == "charset";
|
||||
}
|
||||
|
||||
bool CheckNesting::is_mixin(Statement* n)
|
||||
{
|
||||
Definition* def = Cast<Definition>(n);
|
||||
return def && def->type() == Definition::MIXIN;
|
||||
}
|
||||
|
||||
bool CheckNesting::is_function(Statement* n)
|
||||
{
|
||||
Definition* def = Cast<Definition>(n);
|
||||
return def && def->type() == Definition::FUNCTION;
|
||||
}
|
||||
|
||||
bool CheckNesting::is_root_node(Statement* n)
|
||||
{
|
||||
if (Cast<StyleRule>(n)) return false;
|
||||
|
||||
Block* b = Cast<Block>(n);
|
||||
return b && b->is_root();
|
||||
}
|
||||
|
||||
bool CheckNesting::is_at_root_node(Statement* n)
|
||||
{
|
||||
return Cast<AtRootRule>(n) != NULL;
|
||||
}
|
||||
|
||||
bool CheckNesting::is_directive_node(Statement* n)
|
||||
{
|
||||
return Cast<AtRule>(n) ||
|
||||
Cast<Import>(n) ||
|
||||
Cast<MediaRule>(n) ||
|
||||
Cast<CssMediaRule>(n) ||
|
||||
Cast<SupportsRule>(n);
|
||||
}
|
||||
}
|
||||
70
vendor/bundle/ruby/2.6.0/gems/sassc-2.4.0/ext/libsass/src/check_nesting.hpp
vendored
Normal file
70
vendor/bundle/ruby/2.6.0/gems/sassc-2.4.0/ext/libsass/src/check_nesting.hpp
vendored
Normal file
@@ -0,0 +1,70 @@
|
||||
#ifndef SASS_CHECK_NESTING_H
|
||||
#define SASS_CHECK_NESTING_H
|
||||
|
||||
// sass.hpp must go before all system headers to get the
|
||||
// __EXTENSIONS__ fix on Solaris.
|
||||
#include "sass.hpp"
|
||||
#include "ast.hpp"
|
||||
#include "operation.hpp"
|
||||
#include <vector>
|
||||
|
||||
namespace Sass {
|
||||
|
||||
class CheckNesting : public Operation_CRTP<Statement*, CheckNesting> {
|
||||
|
||||
sass::vector<Statement*> parents;
|
||||
Backtraces traces;
|
||||
Statement* parent;
|
||||
Definition* current_mixin_definition;
|
||||
|
||||
Statement* before(Statement*);
|
||||
Statement* visit_children(Statement*);
|
||||
|
||||
public:
|
||||
CheckNesting();
|
||||
~CheckNesting() { }
|
||||
|
||||
Statement* operator()(Block*);
|
||||
Statement* operator()(Definition*);
|
||||
Statement* operator()(If*);
|
||||
|
||||
template <typename U>
|
||||
Statement* fallback(U x) {
|
||||
Statement* s = Cast<Statement>(x);
|
||||
if (s && this->should_visit(s)) {
|
||||
Block* b1 = Cast<Block>(s);
|
||||
ParentStatement* b2 = Cast<ParentStatement>(s);
|
||||
if (b1 || b2) return visit_children(s);
|
||||
}
|
||||
return s;
|
||||
}
|
||||
|
||||
private:
|
||||
void invalid_content_parent(Statement*, AST_Node*);
|
||||
void invalid_charset_parent(Statement*, AST_Node*);
|
||||
void invalid_extend_parent(Statement*, AST_Node*);
|
||||
// void invalid_import_parent(Statement*);
|
||||
void invalid_mixin_definition_parent(Statement*, AST_Node*);
|
||||
void invalid_function_parent(Statement*, AST_Node*);
|
||||
|
||||
void invalid_function_child(Statement*);
|
||||
void invalid_prop_child(Statement*);
|
||||
void invalid_prop_parent(Statement*, AST_Node*);
|
||||
void invalid_return_parent(Statement*, AST_Node*);
|
||||
void invalid_value_child(AST_Node*);
|
||||
|
||||
bool is_transparent_parent(Statement*, Statement*);
|
||||
|
||||
bool should_visit(Statement*);
|
||||
|
||||
bool is_charset(Statement*);
|
||||
bool is_mixin(Statement*);
|
||||
bool is_function(Statement*);
|
||||
bool is_root_node(Statement*);
|
||||
bool is_at_root_node(Statement*);
|
||||
bool is_directive_node(Statement*);
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
652
vendor/bundle/ruby/2.6.0/gems/sassc-2.4.0/ext/libsass/src/color_maps.cpp
vendored
Normal file
652
vendor/bundle/ruby/2.6.0/gems/sassc-2.4.0/ext/libsass/src/color_maps.cpp
vendored
Normal file
@@ -0,0 +1,652 @@
|
||||
// sass.hpp must go before all system headers to get the
|
||||
// __EXTENSIONS__ fix on Solaris.
|
||||
#include "sass.hpp"
|
||||
|
||||
#include "ast.hpp"
|
||||
#include "color_maps.hpp"
|
||||
#include "util_string.hpp"
|
||||
|
||||
namespace Sass {
|
||||
|
||||
namespace ColorNames
|
||||
{
|
||||
const char aliceblue [] = "aliceblue";
|
||||
const char antiquewhite [] = "antiquewhite";
|
||||
const char cyan [] = "cyan";
|
||||
const char aqua [] = "aqua";
|
||||
const char aquamarine [] = "aquamarine";
|
||||
const char azure [] = "azure";
|
||||
const char beige [] = "beige";
|
||||
const char bisque [] = "bisque";
|
||||
const char black [] = "black";
|
||||
const char blanchedalmond [] = "blanchedalmond";
|
||||
const char blue [] = "blue";
|
||||
const char blueviolet [] = "blueviolet";
|
||||
const char brown [] = "brown";
|
||||
const char burlywood [] = "burlywood";
|
||||
const char cadetblue [] = "cadetblue";
|
||||
const char chartreuse [] = "chartreuse";
|
||||
const char chocolate [] = "chocolate";
|
||||
const char coral [] = "coral";
|
||||
const char cornflowerblue [] = "cornflowerblue";
|
||||
const char cornsilk [] = "cornsilk";
|
||||
const char crimson [] = "crimson";
|
||||
const char darkblue [] = "darkblue";
|
||||
const char darkcyan [] = "darkcyan";
|
||||
const char darkgoldenrod [] = "darkgoldenrod";
|
||||
const char darkgray [] = "darkgray";
|
||||
const char darkgrey [] = "darkgrey";
|
||||
const char darkgreen [] = "darkgreen";
|
||||
const char darkkhaki [] = "darkkhaki";
|
||||
const char darkmagenta [] = "darkmagenta";
|
||||
const char darkolivegreen [] = "darkolivegreen";
|
||||
const char darkorange [] = "darkorange";
|
||||
const char darkorchid [] = "darkorchid";
|
||||
const char darkred [] = "darkred";
|
||||
const char darksalmon [] = "darksalmon";
|
||||
const char darkseagreen [] = "darkseagreen";
|
||||
const char darkslateblue [] = "darkslateblue";
|
||||
const char darkslategray [] = "darkslategray";
|
||||
const char darkslategrey [] = "darkslategrey";
|
||||
const char darkturquoise [] = "darkturquoise";
|
||||
const char darkviolet [] = "darkviolet";
|
||||
const char deeppink [] = "deeppink";
|
||||
const char deepskyblue [] = "deepskyblue";
|
||||
const char dimgray [] = "dimgray";
|
||||
const char dimgrey [] = "dimgrey";
|
||||
const char dodgerblue [] = "dodgerblue";
|
||||
const char firebrick [] = "firebrick";
|
||||
const char floralwhite [] = "floralwhite";
|
||||
const char forestgreen [] = "forestgreen";
|
||||
const char magenta [] = "magenta";
|
||||
const char fuchsia [] = "fuchsia";
|
||||
const char gainsboro [] = "gainsboro";
|
||||
const char ghostwhite [] = "ghostwhite";
|
||||
const char gold [] = "gold";
|
||||
const char goldenrod [] = "goldenrod";
|
||||
const char gray [] = "gray";
|
||||
const char grey [] = "grey";
|
||||
const char green [] = "green";
|
||||
const char greenyellow [] = "greenyellow";
|
||||
const char honeydew [] = "honeydew";
|
||||
const char hotpink [] = "hotpink";
|
||||
const char indianred [] = "indianred";
|
||||
const char indigo [] = "indigo";
|
||||
const char ivory [] = "ivory";
|
||||
const char khaki [] = "khaki";
|
||||
const char lavender [] = "lavender";
|
||||
const char lavenderblush [] = "lavenderblush";
|
||||
const char lawngreen [] = "lawngreen";
|
||||
const char lemonchiffon [] = "lemonchiffon";
|
||||
const char lightblue [] = "lightblue";
|
||||
const char lightcoral [] = "lightcoral";
|
||||
const char lightcyan [] = "lightcyan";
|
||||
const char lightgoldenrodyellow [] = "lightgoldenrodyellow";
|
||||
const char lightgray [] = "lightgray";
|
||||
const char lightgrey [] = "lightgrey";
|
||||
const char lightgreen [] = "lightgreen";
|
||||
const char lightpink [] = "lightpink";
|
||||
const char lightsalmon [] = "lightsalmon";
|
||||
const char lightseagreen [] = "lightseagreen";
|
||||
const char lightskyblue [] = "lightskyblue";
|
||||
const char lightslategray [] = "lightslategray";
|
||||
const char lightslategrey [] = "lightslategrey";
|
||||
const char lightsteelblue [] = "lightsteelblue";
|
||||
const char lightyellow [] = "lightyellow";
|
||||
const char lime [] = "lime";
|
||||
const char limegreen [] = "limegreen";
|
||||
const char linen [] = "linen";
|
||||
const char maroon [] = "maroon";
|
||||
const char mediumaquamarine [] = "mediumaquamarine";
|
||||
const char mediumblue [] = "mediumblue";
|
||||
const char mediumorchid [] = "mediumorchid";
|
||||
const char mediumpurple [] = "mediumpurple";
|
||||
const char mediumseagreen [] = "mediumseagreen";
|
||||
const char mediumslateblue [] = "mediumslateblue";
|
||||
const char mediumspringgreen [] = "mediumspringgreen";
|
||||
const char mediumturquoise [] = "mediumturquoise";
|
||||
const char mediumvioletred [] = "mediumvioletred";
|
||||
const char midnightblue [] = "midnightblue";
|
||||
const char mintcream [] = "mintcream";
|
||||
const char mistyrose [] = "mistyrose";
|
||||
const char moccasin [] = "moccasin";
|
||||
const char navajowhite [] = "navajowhite";
|
||||
const char navy [] = "navy";
|
||||
const char oldlace [] = "oldlace";
|
||||
const char olive [] = "olive";
|
||||
const char olivedrab [] = "olivedrab";
|
||||
const char orange [] = "orange";
|
||||
const char orangered [] = "orangered";
|
||||
const char orchid [] = "orchid";
|
||||
const char palegoldenrod [] = "palegoldenrod";
|
||||
const char palegreen [] = "palegreen";
|
||||
const char paleturquoise [] = "paleturquoise";
|
||||
const char palevioletred [] = "palevioletred";
|
||||
const char papayawhip [] = "papayawhip";
|
||||
const char peachpuff [] = "peachpuff";
|
||||
const char peru [] = "peru";
|
||||
const char pink [] = "pink";
|
||||
const char plum [] = "plum";
|
||||
const char powderblue [] = "powderblue";
|
||||
const char purple [] = "purple";
|
||||
const char red [] = "red";
|
||||
const char rosybrown [] = "rosybrown";
|
||||
const char royalblue [] = "royalblue";
|
||||
const char saddlebrown [] = "saddlebrown";
|
||||
const char salmon [] = "salmon";
|
||||
const char sandybrown [] = "sandybrown";
|
||||
const char seagreen [] = "seagreen";
|
||||
const char seashell [] = "seashell";
|
||||
const char sienna [] = "sienna";
|
||||
const char silver [] = "silver";
|
||||
const char skyblue [] = "skyblue";
|
||||
const char slateblue [] = "slateblue";
|
||||
const char slategray [] = "slategray";
|
||||
const char slategrey [] = "slategrey";
|
||||
const char snow [] = "snow";
|
||||
const char springgreen [] = "springgreen";
|
||||
const char steelblue [] = "steelblue";
|
||||
const char tan [] = "tan";
|
||||
const char teal [] = "teal";
|
||||
const char thistle [] = "thistle";
|
||||
const char tomato [] = "tomato";
|
||||
const char turquoise [] = "turquoise";
|
||||
const char violet [] = "violet";
|
||||
const char wheat [] = "wheat";
|
||||
const char white [] = "white";
|
||||
const char whitesmoke [] = "whitesmoke";
|
||||
const char yellow [] = "yellow";
|
||||
const char yellowgreen [] = "yellowgreen";
|
||||
const char rebeccapurple [] = "rebeccapurple";
|
||||
const char transparent [] = "transparent";
|
||||
}
|
||||
|
||||
namespace Colors {
|
||||
const SourceSpan color_table("[COLOR TABLE]");
|
||||
const Color_RGBA aliceblue(color_table, 240, 248, 255, 1);
|
||||
const Color_RGBA antiquewhite(color_table, 250, 235, 215, 1);
|
||||
const Color_RGBA cyan(color_table, 0, 255, 255, 1);
|
||||
const Color_RGBA aqua(color_table, 0, 255, 255, 1);
|
||||
const Color_RGBA aquamarine(color_table, 127, 255, 212, 1);
|
||||
const Color_RGBA azure(color_table, 240, 255, 255, 1);
|
||||
const Color_RGBA beige(color_table, 245, 245, 220, 1);
|
||||
const Color_RGBA bisque(color_table, 255, 228, 196, 1);
|
||||
const Color_RGBA black(color_table, 0, 0, 0, 1);
|
||||
const Color_RGBA blanchedalmond(color_table, 255, 235, 205, 1);
|
||||
const Color_RGBA blue(color_table, 0, 0, 255, 1);
|
||||
const Color_RGBA blueviolet(color_table, 138, 43, 226, 1);
|
||||
const Color_RGBA brown(color_table, 165, 42, 42, 1);
|
||||
const Color_RGBA burlywood(color_table, 222, 184, 135, 1);
|
||||
const Color_RGBA cadetblue(color_table, 95, 158, 160, 1);
|
||||
const Color_RGBA chartreuse(color_table, 127, 255, 0, 1);
|
||||
const Color_RGBA chocolate(color_table, 210, 105, 30, 1);
|
||||
const Color_RGBA coral(color_table, 255, 127, 80, 1);
|
||||
const Color_RGBA cornflowerblue(color_table, 100, 149, 237, 1);
|
||||
const Color_RGBA cornsilk(color_table, 255, 248, 220, 1);
|
||||
const Color_RGBA crimson(color_table, 220, 20, 60, 1);
|
||||
const Color_RGBA darkblue(color_table, 0, 0, 139, 1);
|
||||
const Color_RGBA darkcyan(color_table, 0, 139, 139, 1);
|
||||
const Color_RGBA darkgoldenrod(color_table, 184, 134, 11, 1);
|
||||
const Color_RGBA darkgray(color_table, 169, 169, 169, 1);
|
||||
const Color_RGBA darkgrey(color_table, 169, 169, 169, 1);
|
||||
const Color_RGBA darkgreen(color_table, 0, 100, 0, 1);
|
||||
const Color_RGBA darkkhaki(color_table, 189, 183, 107, 1);
|
||||
const Color_RGBA darkmagenta(color_table, 139, 0, 139, 1);
|
||||
const Color_RGBA darkolivegreen(color_table, 85, 107, 47, 1);
|
||||
const Color_RGBA darkorange(color_table, 255, 140, 0, 1);
|
||||
const Color_RGBA darkorchid(color_table, 153, 50, 204, 1);
|
||||
const Color_RGBA darkred(color_table, 139, 0, 0, 1);
|
||||
const Color_RGBA darksalmon(color_table, 233, 150, 122, 1);
|
||||
const Color_RGBA darkseagreen(color_table, 143, 188, 143, 1);
|
||||
const Color_RGBA darkslateblue(color_table, 72, 61, 139, 1);
|
||||
const Color_RGBA darkslategray(color_table, 47, 79, 79, 1);
|
||||
const Color_RGBA darkslategrey(color_table, 47, 79, 79, 1);
|
||||
const Color_RGBA darkturquoise(color_table, 0, 206, 209, 1);
|
||||
const Color_RGBA darkviolet(color_table, 148, 0, 211, 1);
|
||||
const Color_RGBA deeppink(color_table, 255, 20, 147, 1);
|
||||
const Color_RGBA deepskyblue(color_table, 0, 191, 255, 1);
|
||||
const Color_RGBA dimgray(color_table, 105, 105, 105, 1);
|
||||
const Color_RGBA dimgrey(color_table, 105, 105, 105, 1);
|
||||
const Color_RGBA dodgerblue(color_table, 30, 144, 255, 1);
|
||||
const Color_RGBA firebrick(color_table, 178, 34, 34, 1);
|
||||
const Color_RGBA floralwhite(color_table, 255, 250, 240, 1);
|
||||
const Color_RGBA forestgreen(color_table, 34, 139, 34, 1);
|
||||
const Color_RGBA magenta(color_table, 255, 0, 255, 1);
|
||||
const Color_RGBA fuchsia(color_table, 255, 0, 255, 1);
|
||||
const Color_RGBA gainsboro(color_table, 220, 220, 220, 1);
|
||||
const Color_RGBA ghostwhite(color_table, 248, 248, 255, 1);
|
||||
const Color_RGBA gold(color_table, 255, 215, 0, 1);
|
||||
const Color_RGBA goldenrod(color_table, 218, 165, 32, 1);
|
||||
const Color_RGBA gray(color_table, 128, 128, 128, 1);
|
||||
const Color_RGBA grey(color_table, 128, 128, 128, 1);
|
||||
const Color_RGBA green(color_table, 0, 128, 0, 1);
|
||||
const Color_RGBA greenyellow(color_table, 173, 255, 47, 1);
|
||||
const Color_RGBA honeydew(color_table, 240, 255, 240, 1);
|
||||
const Color_RGBA hotpink(color_table, 255, 105, 180, 1);
|
||||
const Color_RGBA indianred(color_table, 205, 92, 92, 1);
|
||||
const Color_RGBA indigo(color_table, 75, 0, 130, 1);
|
||||
const Color_RGBA ivory(color_table, 255, 255, 240, 1);
|
||||
const Color_RGBA khaki(color_table, 240, 230, 140, 1);
|
||||
const Color_RGBA lavender(color_table, 230, 230, 250, 1);
|
||||
const Color_RGBA lavenderblush(color_table, 255, 240, 245, 1);
|
||||
const Color_RGBA lawngreen(color_table, 124, 252, 0, 1);
|
||||
const Color_RGBA lemonchiffon(color_table, 255, 250, 205, 1);
|
||||
const Color_RGBA lightblue(color_table, 173, 216, 230, 1);
|
||||
const Color_RGBA lightcoral(color_table, 240, 128, 128, 1);
|
||||
const Color_RGBA lightcyan(color_table, 224, 255, 255, 1);
|
||||
const Color_RGBA lightgoldenrodyellow(color_table, 250, 250, 210, 1);
|
||||
const Color_RGBA lightgray(color_table, 211, 211, 211, 1);
|
||||
const Color_RGBA lightgrey(color_table, 211, 211, 211, 1);
|
||||
const Color_RGBA lightgreen(color_table, 144, 238, 144, 1);
|
||||
const Color_RGBA lightpink(color_table, 255, 182, 193, 1);
|
||||
const Color_RGBA lightsalmon(color_table, 255, 160, 122, 1);
|
||||
const Color_RGBA lightseagreen(color_table, 32, 178, 170, 1);
|
||||
const Color_RGBA lightskyblue(color_table, 135, 206, 250, 1);
|
||||
const Color_RGBA lightslategray(color_table, 119, 136, 153, 1);
|
||||
const Color_RGBA lightslategrey(color_table, 119, 136, 153, 1);
|
||||
const Color_RGBA lightsteelblue(color_table, 176, 196, 222, 1);
|
||||
const Color_RGBA lightyellow(color_table, 255, 255, 224, 1);
|
||||
const Color_RGBA lime(color_table, 0, 255, 0, 1);
|
||||
const Color_RGBA limegreen(color_table, 50, 205, 50, 1);
|
||||
const Color_RGBA linen(color_table, 250, 240, 230, 1);
|
||||
const Color_RGBA maroon(color_table, 128, 0, 0, 1);
|
||||
const Color_RGBA mediumaquamarine(color_table, 102, 205, 170, 1);
|
||||
const Color_RGBA mediumblue(color_table, 0, 0, 205, 1);
|
||||
const Color_RGBA mediumorchid(color_table, 186, 85, 211, 1);
|
||||
const Color_RGBA mediumpurple(color_table, 147, 112, 219, 1);
|
||||
const Color_RGBA mediumseagreen(color_table, 60, 179, 113, 1);
|
||||
const Color_RGBA mediumslateblue(color_table, 123, 104, 238, 1);
|
||||
const Color_RGBA mediumspringgreen(color_table, 0, 250, 154, 1);
|
||||
const Color_RGBA mediumturquoise(color_table, 72, 209, 204, 1);
|
||||
const Color_RGBA mediumvioletred(color_table, 199, 21, 133, 1);
|
||||
const Color_RGBA midnightblue(color_table, 25, 25, 112, 1);
|
||||
const Color_RGBA mintcream(color_table, 245, 255, 250, 1);
|
||||
const Color_RGBA mistyrose(color_table, 255, 228, 225, 1);
|
||||
const Color_RGBA moccasin(color_table, 255, 228, 181, 1);
|
||||
const Color_RGBA navajowhite(color_table, 255, 222, 173, 1);
|
||||
const Color_RGBA navy(color_table, 0, 0, 128, 1);
|
||||
const Color_RGBA oldlace(color_table, 253, 245, 230, 1);
|
||||
const Color_RGBA olive(color_table, 128, 128, 0, 1);
|
||||
const Color_RGBA olivedrab(color_table, 107, 142, 35, 1);
|
||||
const Color_RGBA orange(color_table, 255, 165, 0, 1);
|
||||
const Color_RGBA orangered(color_table, 255, 69, 0, 1);
|
||||
const Color_RGBA orchid(color_table, 218, 112, 214, 1);
|
||||
const Color_RGBA palegoldenrod(color_table, 238, 232, 170, 1);
|
||||
const Color_RGBA palegreen(color_table, 152, 251, 152, 1);
|
||||
const Color_RGBA paleturquoise(color_table, 175, 238, 238, 1);
|
||||
const Color_RGBA palevioletred(color_table, 219, 112, 147, 1);
|
||||
const Color_RGBA papayawhip(color_table, 255, 239, 213, 1);
|
||||
const Color_RGBA peachpuff(color_table, 255, 218, 185, 1);
|
||||
const Color_RGBA peru(color_table, 205, 133, 63, 1);
|
||||
const Color_RGBA pink(color_table, 255, 192, 203, 1);
|
||||
const Color_RGBA plum(color_table, 221, 160, 221, 1);
|
||||
const Color_RGBA powderblue(color_table, 176, 224, 230, 1);
|
||||
const Color_RGBA purple(color_table, 128, 0, 128, 1);
|
||||
const Color_RGBA red(color_table, 255, 0, 0, 1);
|
||||
const Color_RGBA rosybrown(color_table, 188, 143, 143, 1);
|
||||
const Color_RGBA royalblue(color_table, 65, 105, 225, 1);
|
||||
const Color_RGBA saddlebrown(color_table, 139, 69, 19, 1);
|
||||
const Color_RGBA salmon(color_table, 250, 128, 114, 1);
|
||||
const Color_RGBA sandybrown(color_table, 244, 164, 96, 1);
|
||||
const Color_RGBA seagreen(color_table, 46, 139, 87, 1);
|
||||
const Color_RGBA seashell(color_table, 255, 245, 238, 1);
|
||||
const Color_RGBA sienna(color_table, 160, 82, 45, 1);
|
||||
const Color_RGBA silver(color_table, 192, 192, 192, 1);
|
||||
const Color_RGBA skyblue(color_table, 135, 206, 235, 1);
|
||||
const Color_RGBA slateblue(color_table, 106, 90, 205, 1);
|
||||
const Color_RGBA slategray(color_table, 112, 128, 144, 1);
|
||||
const Color_RGBA slategrey(color_table, 112, 128, 144, 1);
|
||||
const Color_RGBA snow(color_table, 255, 250, 250, 1);
|
||||
const Color_RGBA springgreen(color_table, 0, 255, 127, 1);
|
||||
const Color_RGBA steelblue(color_table, 70, 130, 180, 1);
|
||||
const Color_RGBA tan(color_table, 210, 180, 140, 1);
|
||||
const Color_RGBA teal(color_table, 0, 128, 128, 1);
|
||||
const Color_RGBA thistle(color_table, 216, 191, 216, 1);
|
||||
const Color_RGBA tomato(color_table, 255, 99, 71, 1);
|
||||
const Color_RGBA turquoise(color_table, 64, 224, 208, 1);
|
||||
const Color_RGBA violet(color_table, 238, 130, 238, 1);
|
||||
const Color_RGBA wheat(color_table, 245, 222, 179, 1);
|
||||
const Color_RGBA white(color_table, 255, 255, 255, 1);
|
||||
const Color_RGBA whitesmoke(color_table, 245, 245, 245, 1);
|
||||
const Color_RGBA yellow(color_table, 255, 255, 0, 1);
|
||||
const Color_RGBA yellowgreen(color_table, 154, 205, 50, 1);
|
||||
const Color_RGBA rebeccapurple(color_table, 102, 51, 153, 1);
|
||||
const Color_RGBA transparent(color_table, 0, 0, 0, 0);
|
||||
}
|
||||
|
||||
static const auto* const colors_to_names = new std::unordered_map<int, const char*> {
|
||||
{ 240 * 0x10000 + 248 * 0x100 + 255, ColorNames::aliceblue },
|
||||
{ 250 * 0x10000 + 235 * 0x100 + 215, ColorNames::antiquewhite },
|
||||
{ 0 * 0x10000 + 255 * 0x100 + 255, ColorNames::cyan },
|
||||
{ 127 * 0x10000 + 255 * 0x100 + 212, ColorNames::aquamarine },
|
||||
{ 240 * 0x10000 + 255 * 0x100 + 255, ColorNames::azure },
|
||||
{ 245 * 0x10000 + 245 * 0x100 + 220, ColorNames::beige },
|
||||
{ 255 * 0x10000 + 228 * 0x100 + 196, ColorNames::bisque },
|
||||
{ 0 * 0x10000 + 0 * 0x100 + 0, ColorNames::black },
|
||||
{ 255 * 0x10000 + 235 * 0x100 + 205, ColorNames::blanchedalmond },
|
||||
{ 0 * 0x10000 + 0 * 0x100 + 255, ColorNames::blue },
|
||||
{ 138 * 0x10000 + 43 * 0x100 + 226, ColorNames::blueviolet },
|
||||
{ 165 * 0x10000 + 42 * 0x100 + 42, ColorNames::brown },
|
||||
{ 222 * 0x10000 + 184 * 0x100 + 135, ColorNames::burlywood },
|
||||
{ 95 * 0x10000 + 158 * 0x100 + 160, ColorNames::cadetblue },
|
||||
{ 127 * 0x10000 + 255 * 0x100 + 0, ColorNames::chartreuse },
|
||||
{ 210 * 0x10000 + 105 * 0x100 + 30, ColorNames::chocolate },
|
||||
{ 255 * 0x10000 + 127 * 0x100 + 80, ColorNames::coral },
|
||||
{ 100 * 0x10000 + 149 * 0x100 + 237, ColorNames::cornflowerblue },
|
||||
{ 255 * 0x10000 + 248 * 0x100 + 220, ColorNames::cornsilk },
|
||||
{ 220 * 0x10000 + 20 * 0x100 + 60, ColorNames::crimson },
|
||||
{ 0 * 0x10000 + 0 * 0x100 + 139, ColorNames::darkblue },
|
||||
{ 0 * 0x10000 + 139 * 0x100 + 139, ColorNames::darkcyan },
|
||||
{ 184 * 0x10000 + 134 * 0x100 + 11, ColorNames::darkgoldenrod },
|
||||
{ 169 * 0x10000 + 169 * 0x100 + 169, ColorNames::darkgray },
|
||||
{ 0 * 0x10000 + 100 * 0x100 + 0, ColorNames::darkgreen },
|
||||
{ 189 * 0x10000 + 183 * 0x100 + 107, ColorNames::darkkhaki },
|
||||
{ 139 * 0x10000 + 0 * 0x100 + 139, ColorNames::darkmagenta },
|
||||
{ 85 * 0x10000 + 107 * 0x100 + 47, ColorNames::darkolivegreen },
|
||||
{ 255 * 0x10000 + 140 * 0x100 + 0, ColorNames::darkorange },
|
||||
{ 153 * 0x10000 + 50 * 0x100 + 204, ColorNames::darkorchid },
|
||||
{ 139 * 0x10000 + 0 * 0x100 + 0, ColorNames::darkred },
|
||||
{ 233 * 0x10000 + 150 * 0x100 + 122, ColorNames::darksalmon },
|
||||
{ 143 * 0x10000 + 188 * 0x100 + 143, ColorNames::darkseagreen },
|
||||
{ 72 * 0x10000 + 61 * 0x100 + 139, ColorNames::darkslateblue },
|
||||
{ 47 * 0x10000 + 79 * 0x100 + 79, ColorNames::darkslategray },
|
||||
{ 0 * 0x10000 + 206 * 0x100 + 209, ColorNames::darkturquoise },
|
||||
{ 148 * 0x10000 + 0 * 0x100 + 211, ColorNames::darkviolet },
|
||||
{ 255 * 0x10000 + 20 * 0x100 + 147, ColorNames::deeppink },
|
||||
{ 0 * 0x10000 + 191 * 0x100 + 255, ColorNames::deepskyblue },
|
||||
{ 105 * 0x10000 + 105 * 0x100 + 105, ColorNames::dimgray },
|
||||
{ 30 * 0x10000 + 144 * 0x100 + 255, ColorNames::dodgerblue },
|
||||
{ 178 * 0x10000 + 34 * 0x100 + 34, ColorNames::firebrick },
|
||||
{ 255 * 0x10000 + 250 * 0x100 + 240, ColorNames::floralwhite },
|
||||
{ 34 * 0x10000 + 139 * 0x100 + 34, ColorNames::forestgreen },
|
||||
{ 255 * 0x10000 + 0 * 0x100 + 255, ColorNames::magenta },
|
||||
{ 220 * 0x10000 + 220 * 0x100 + 220, ColorNames::gainsboro },
|
||||
{ 248 * 0x10000 + 248 * 0x100 + 255, ColorNames::ghostwhite },
|
||||
{ 255 * 0x10000 + 215 * 0x100 + 0, ColorNames::gold },
|
||||
{ 218 * 0x10000 + 165 * 0x100 + 32, ColorNames::goldenrod },
|
||||
{ 128 * 0x10000 + 128 * 0x100 + 128, ColorNames::gray },
|
||||
{ 0 * 0x10000 + 128 * 0x100 + 0, ColorNames::green },
|
||||
{ 173 * 0x10000 + 255 * 0x100 + 47, ColorNames::greenyellow },
|
||||
{ 240 * 0x10000 + 255 * 0x100 + 240, ColorNames::honeydew },
|
||||
{ 255 * 0x10000 + 105 * 0x100 + 180, ColorNames::hotpink },
|
||||
{ 205 * 0x10000 + 92 * 0x100 + 92, ColorNames::indianred },
|
||||
{ 75 * 0x10000 + 0 * 0x100 + 130, ColorNames::indigo },
|
||||
{ 255 * 0x10000 + 255 * 0x100 + 240, ColorNames::ivory },
|
||||
{ 240 * 0x10000 + 230 * 0x100 + 140, ColorNames::khaki },
|
||||
{ 230 * 0x10000 + 230 * 0x100 + 250, ColorNames::lavender },
|
||||
{ 255 * 0x10000 + 240 * 0x100 + 245, ColorNames::lavenderblush },
|
||||
{ 124 * 0x10000 + 252 * 0x100 + 0, ColorNames::lawngreen },
|
||||
{ 255 * 0x10000 + 250 * 0x100 + 205, ColorNames::lemonchiffon },
|
||||
{ 173 * 0x10000 + 216 * 0x100 + 230, ColorNames::lightblue },
|
||||
{ 240 * 0x10000 + 128 * 0x100 + 128, ColorNames::lightcoral },
|
||||
{ 224 * 0x10000 + 255 * 0x100 + 255, ColorNames::lightcyan },
|
||||
{ 250 * 0x10000 + 250 * 0x100 + 210, ColorNames::lightgoldenrodyellow },
|
||||
{ 211 * 0x10000 + 211 * 0x100 + 211, ColorNames::lightgray },
|
||||
{ 144 * 0x10000 + 238 * 0x100 + 144, ColorNames::lightgreen },
|
||||
{ 255 * 0x10000 + 182 * 0x100 + 193, ColorNames::lightpink },
|
||||
{ 255 * 0x10000 + 160 * 0x100 + 122, ColorNames::lightsalmon },
|
||||
{ 32 * 0x10000 + 178 * 0x100 + 170, ColorNames::lightseagreen },
|
||||
{ 135 * 0x10000 + 206 * 0x100 + 250, ColorNames::lightskyblue },
|
||||
{ 119 * 0x10000 + 136 * 0x100 + 153, ColorNames::lightslategray },
|
||||
{ 176 * 0x10000 + 196 * 0x100 + 222, ColorNames::lightsteelblue },
|
||||
{ 255 * 0x10000 + 255 * 0x100 + 224, ColorNames::lightyellow },
|
||||
{ 0 * 0x10000 + 255 * 0x100 + 0, ColorNames::lime },
|
||||
{ 50 * 0x10000 + 205 * 0x100 + 50, ColorNames::limegreen },
|
||||
{ 250 * 0x10000 + 240 * 0x100 + 230, ColorNames::linen },
|
||||
{ 128 * 0x10000 + 0 * 0x100 + 0, ColorNames::maroon },
|
||||
{ 102 * 0x10000 + 205 * 0x100 + 170, ColorNames::mediumaquamarine },
|
||||
{ 0 * 0x10000 + 0 * 0x100 + 205, ColorNames::mediumblue },
|
||||
{ 186 * 0x10000 + 85 * 0x100 + 211, ColorNames::mediumorchid },
|
||||
{ 147 * 0x10000 + 112 * 0x100 + 219, ColorNames::mediumpurple },
|
||||
{ 60 * 0x10000 + 179 * 0x100 + 113, ColorNames::mediumseagreen },
|
||||
{ 123 * 0x10000 + 104 * 0x100 + 238, ColorNames::mediumslateblue },
|
||||
{ 0 * 0x10000 + 250 * 0x100 + 154, ColorNames::mediumspringgreen },
|
||||
{ 72 * 0x10000 + 209 * 0x100 + 204, ColorNames::mediumturquoise },
|
||||
{ 199 * 0x10000 + 21 * 0x100 + 133, ColorNames::mediumvioletred },
|
||||
{ 25 * 0x10000 + 25 * 0x100 + 112, ColorNames::midnightblue },
|
||||
{ 245 * 0x10000 + 255 * 0x100 + 250, ColorNames::mintcream },
|
||||
{ 255 * 0x10000 + 228 * 0x100 + 225, ColorNames::mistyrose },
|
||||
{ 255 * 0x10000 + 228 * 0x100 + 181, ColorNames::moccasin },
|
||||
{ 255 * 0x10000 + 222 * 0x100 + 173, ColorNames::navajowhite },
|
||||
{ 0 * 0x10000 + 0 * 0x100 + 128, ColorNames::navy },
|
||||
{ 253 * 0x10000 + 245 * 0x100 + 230, ColorNames::oldlace },
|
||||
{ 128 * 0x10000 + 128 * 0x100 + 0, ColorNames::olive },
|
||||
{ 107 * 0x10000 + 142 * 0x100 + 35, ColorNames::olivedrab },
|
||||
{ 255 * 0x10000 + 165 * 0x100 + 0, ColorNames::orange },
|
||||
{ 255 * 0x10000 + 69 * 0x100 + 0, ColorNames::orangered },
|
||||
{ 218 * 0x10000 + 112 * 0x100 + 214, ColorNames::orchid },
|
||||
{ 238 * 0x10000 + 232 * 0x100 + 170, ColorNames::palegoldenrod },
|
||||
{ 152 * 0x10000 + 251 * 0x100 + 152, ColorNames::palegreen },
|
||||
{ 175 * 0x10000 + 238 * 0x100 + 238, ColorNames::paleturquoise },
|
||||
{ 219 * 0x10000 + 112 * 0x100 + 147, ColorNames::palevioletred },
|
||||
{ 255 * 0x10000 + 239 * 0x100 + 213, ColorNames::papayawhip },
|
||||
{ 255 * 0x10000 + 218 * 0x100 + 185, ColorNames::peachpuff },
|
||||
{ 205 * 0x10000 + 133 * 0x100 + 63, ColorNames::peru },
|
||||
{ 255 * 0x10000 + 192 * 0x100 + 203, ColorNames::pink },
|
||||
{ 221 * 0x10000 + 160 * 0x100 + 221, ColorNames::plum },
|
||||
{ 176 * 0x10000 + 224 * 0x100 + 230, ColorNames::powderblue },
|
||||
{ 128 * 0x10000 + 0 * 0x100 + 128, ColorNames::purple },
|
||||
{ 255 * 0x10000 + 0 * 0x100 + 0, ColorNames::red },
|
||||
{ 188 * 0x10000 + 143 * 0x100 + 143, ColorNames::rosybrown },
|
||||
{ 65 * 0x10000 + 105 * 0x100 + 225, ColorNames::royalblue },
|
||||
{ 139 * 0x10000 + 69 * 0x100 + 19, ColorNames::saddlebrown },
|
||||
{ 250 * 0x10000 + 128 * 0x100 + 114, ColorNames::salmon },
|
||||
{ 244 * 0x10000 + 164 * 0x100 + 96, ColorNames::sandybrown },
|
||||
{ 46 * 0x10000 + 139 * 0x100 + 87, ColorNames::seagreen },
|
||||
{ 255 * 0x10000 + 245 * 0x100 + 238, ColorNames::seashell },
|
||||
{ 160 * 0x10000 + 82 * 0x100 + 45, ColorNames::sienna },
|
||||
{ 192 * 0x10000 + 192 * 0x100 + 192, ColorNames::silver },
|
||||
{ 135 * 0x10000 + 206 * 0x100 + 235, ColorNames::skyblue },
|
||||
{ 106 * 0x10000 + 90 * 0x100 + 205, ColorNames::slateblue },
|
||||
{ 112 * 0x10000 + 128 * 0x100 + 144, ColorNames::slategray },
|
||||
{ 255 * 0x10000 + 250 * 0x100 + 250, ColorNames::snow },
|
||||
{ 0 * 0x10000 + 255 * 0x100 + 127, ColorNames::springgreen },
|
||||
{ 70 * 0x10000 + 130 * 0x100 + 180, ColorNames::steelblue },
|
||||
{ 210 * 0x10000 + 180 * 0x100 + 140, ColorNames::tan },
|
||||
{ 0 * 0x10000 + 128 * 0x100 + 128, ColorNames::teal },
|
||||
{ 216 * 0x10000 + 191 * 0x100 + 216, ColorNames::thistle },
|
||||
{ 255 * 0x10000 + 99 * 0x100 + 71, ColorNames::tomato },
|
||||
{ 64 * 0x10000 + 224 * 0x100 + 208, ColorNames::turquoise },
|
||||
{ 238 * 0x10000 + 130 * 0x100 + 238, ColorNames::violet },
|
||||
{ 245 * 0x10000 + 222 * 0x100 + 179, ColorNames::wheat },
|
||||
{ 255 * 0x10000 + 255 * 0x100 + 255, ColorNames::white },
|
||||
{ 245 * 0x10000 + 245 * 0x100 + 245, ColorNames::whitesmoke },
|
||||
{ 255 * 0x10000 + 255 * 0x100 + 0, ColorNames::yellow },
|
||||
{ 154 * 0x10000 + 205 * 0x100 + 50, ColorNames::yellowgreen },
|
||||
{ 102 * 0x10000 + 51 * 0x100 + 153, ColorNames::rebeccapurple }
|
||||
};
|
||||
|
||||
static const auto *const names_to_colors = new std::unordered_map<sass::string, const Color_RGBA*>
|
||||
{
|
||||
{ ColorNames::aliceblue, &Colors::aliceblue },
|
||||
{ ColorNames::antiquewhite, &Colors::antiquewhite },
|
||||
{ ColorNames::cyan, &Colors::cyan },
|
||||
{ ColorNames::aqua, &Colors::aqua },
|
||||
{ ColorNames::aquamarine, &Colors::aquamarine },
|
||||
{ ColorNames::azure, &Colors::azure },
|
||||
{ ColorNames::beige, &Colors::beige },
|
||||
{ ColorNames::bisque, &Colors::bisque },
|
||||
{ ColorNames::black, &Colors::black },
|
||||
{ ColorNames::blanchedalmond, &Colors::blanchedalmond },
|
||||
{ ColorNames::blue, &Colors::blue },
|
||||
{ ColorNames::blueviolet, &Colors::blueviolet },
|
||||
{ ColorNames::brown, &Colors::brown },
|
||||
{ ColorNames::burlywood, &Colors::burlywood },
|
||||
{ ColorNames::cadetblue, &Colors::cadetblue },
|
||||
{ ColorNames::chartreuse, &Colors::chartreuse },
|
||||
{ ColorNames::chocolate, &Colors::chocolate },
|
||||
{ ColorNames::coral, &Colors::coral },
|
||||
{ ColorNames::cornflowerblue, &Colors::cornflowerblue },
|
||||
{ ColorNames::cornsilk, &Colors::cornsilk },
|
||||
{ ColorNames::crimson, &Colors::crimson },
|
||||
{ ColorNames::darkblue, &Colors::darkblue },
|
||||
{ ColorNames::darkcyan, &Colors::darkcyan },
|
||||
{ ColorNames::darkgoldenrod, &Colors::darkgoldenrod },
|
||||
{ ColorNames::darkgray, &Colors::darkgray },
|
||||
{ ColorNames::darkgrey, &Colors::darkgrey },
|
||||
{ ColorNames::darkgreen, &Colors::darkgreen },
|
||||
{ ColorNames::darkkhaki, &Colors::darkkhaki },
|
||||
{ ColorNames::darkmagenta, &Colors::darkmagenta },
|
||||
{ ColorNames::darkolivegreen, &Colors::darkolivegreen },
|
||||
{ ColorNames::darkorange, &Colors::darkorange },
|
||||
{ ColorNames::darkorchid, &Colors::darkorchid },
|
||||
{ ColorNames::darkred, &Colors::darkred },
|
||||
{ ColorNames::darksalmon, &Colors::darksalmon },
|
||||
{ ColorNames::darkseagreen, &Colors::darkseagreen },
|
||||
{ ColorNames::darkslateblue, &Colors::darkslateblue },
|
||||
{ ColorNames::darkslategray, &Colors::darkslategray },
|
||||
{ ColorNames::darkslategrey, &Colors::darkslategrey },
|
||||
{ ColorNames::darkturquoise, &Colors::darkturquoise },
|
||||
{ ColorNames::darkviolet, &Colors::darkviolet },
|
||||
{ ColorNames::deeppink, &Colors::deeppink },
|
||||
{ ColorNames::deepskyblue, &Colors::deepskyblue },
|
||||
{ ColorNames::dimgray, &Colors::dimgray },
|
||||
{ ColorNames::dimgrey, &Colors::dimgrey },
|
||||
{ ColorNames::dodgerblue, &Colors::dodgerblue },
|
||||
{ ColorNames::firebrick, &Colors::firebrick },
|
||||
{ ColorNames::floralwhite, &Colors::floralwhite },
|
||||
{ ColorNames::forestgreen, &Colors::forestgreen },
|
||||
{ ColorNames::magenta, &Colors::magenta },
|
||||
{ ColorNames::fuchsia, &Colors::fuchsia },
|
||||
{ ColorNames::gainsboro, &Colors::gainsboro },
|
||||
{ ColorNames::ghostwhite, &Colors::ghostwhite },
|
||||
{ ColorNames::gold, &Colors::gold },
|
||||
{ ColorNames::goldenrod, &Colors::goldenrod },
|
||||
{ ColorNames::gray, &Colors::gray },
|
||||
{ ColorNames::grey, &Colors::grey },
|
||||
{ ColorNames::green, &Colors::green },
|
||||
{ ColorNames::greenyellow, &Colors::greenyellow },
|
||||
{ ColorNames::honeydew, &Colors::honeydew },
|
||||
{ ColorNames::hotpink, &Colors::hotpink },
|
||||
{ ColorNames::indianred, &Colors::indianred },
|
||||
{ ColorNames::indigo, &Colors::indigo },
|
||||
{ ColorNames::ivory, &Colors::ivory },
|
||||
{ ColorNames::khaki, &Colors::khaki },
|
||||
{ ColorNames::lavender, &Colors::lavender },
|
||||
{ ColorNames::lavenderblush, &Colors::lavenderblush },
|
||||
{ ColorNames::lawngreen, &Colors::lawngreen },
|
||||
{ ColorNames::lemonchiffon, &Colors::lemonchiffon },
|
||||
{ ColorNames::lightblue, &Colors::lightblue },
|
||||
{ ColorNames::lightcoral, &Colors::lightcoral },
|
||||
{ ColorNames::lightcyan, &Colors::lightcyan },
|
||||
{ ColorNames::lightgoldenrodyellow, &Colors::lightgoldenrodyellow },
|
||||
{ ColorNames::lightgray, &Colors::lightgray },
|
||||
{ ColorNames::lightgrey, &Colors::lightgrey },
|
||||
{ ColorNames::lightgreen, &Colors::lightgreen },
|
||||
{ ColorNames::lightpink, &Colors::lightpink },
|
||||
{ ColorNames::lightsalmon, &Colors::lightsalmon },
|
||||
{ ColorNames::lightseagreen, &Colors::lightseagreen },
|
||||
{ ColorNames::lightskyblue, &Colors::lightskyblue },
|
||||
{ ColorNames::lightslategray, &Colors::lightslategray },
|
||||
{ ColorNames::lightslategrey, &Colors::lightslategrey },
|
||||
{ ColorNames::lightsteelblue, &Colors::lightsteelblue },
|
||||
{ ColorNames::lightyellow, &Colors::lightyellow },
|
||||
{ ColorNames::lime, &Colors::lime },
|
||||
{ ColorNames::limegreen, &Colors::limegreen },
|
||||
{ ColorNames::linen, &Colors::linen },
|
||||
{ ColorNames::maroon, &Colors::maroon },
|
||||
{ ColorNames::mediumaquamarine, &Colors::mediumaquamarine },
|
||||
{ ColorNames::mediumblue, &Colors::mediumblue },
|
||||
{ ColorNames::mediumorchid, &Colors::mediumorchid },
|
||||
{ ColorNames::mediumpurple, &Colors::mediumpurple },
|
||||
{ ColorNames::mediumseagreen, &Colors::mediumseagreen },
|
||||
{ ColorNames::mediumslateblue, &Colors::mediumslateblue },
|
||||
{ ColorNames::mediumspringgreen, &Colors::mediumspringgreen },
|
||||
{ ColorNames::mediumturquoise, &Colors::mediumturquoise },
|
||||
{ ColorNames::mediumvioletred, &Colors::mediumvioletred },
|
||||
{ ColorNames::midnightblue, &Colors::midnightblue },
|
||||
{ ColorNames::mintcream, &Colors::mintcream },
|
||||
{ ColorNames::mistyrose, &Colors::mistyrose },
|
||||
{ ColorNames::moccasin, &Colors::moccasin },
|
||||
{ ColorNames::navajowhite, &Colors::navajowhite },
|
||||
{ ColorNames::navy, &Colors::navy },
|
||||
{ ColorNames::oldlace, &Colors::oldlace },
|
||||
{ ColorNames::olive, &Colors::olive },
|
||||
{ ColorNames::olivedrab, &Colors::olivedrab },
|
||||
{ ColorNames::orange, &Colors::orange },
|
||||
{ ColorNames::orangered, &Colors::orangered },
|
||||
{ ColorNames::orchid, &Colors::orchid },
|
||||
{ ColorNames::palegoldenrod, &Colors::palegoldenrod },
|
||||
{ ColorNames::palegreen, &Colors::palegreen },
|
||||
{ ColorNames::paleturquoise, &Colors::paleturquoise },
|
||||
{ ColorNames::palevioletred, &Colors::palevioletred },
|
||||
{ ColorNames::papayawhip, &Colors::papayawhip },
|
||||
{ ColorNames::peachpuff, &Colors::peachpuff },
|
||||
{ ColorNames::peru, &Colors::peru },
|
||||
{ ColorNames::pink, &Colors::pink },
|
||||
{ ColorNames::plum, &Colors::plum },
|
||||
{ ColorNames::powderblue, &Colors::powderblue },
|
||||
{ ColorNames::purple, &Colors::purple },
|
||||
{ ColorNames::red, &Colors::red },
|
||||
{ ColorNames::rosybrown, &Colors::rosybrown },
|
||||
{ ColorNames::royalblue, &Colors::royalblue },
|
||||
{ ColorNames::saddlebrown, &Colors::saddlebrown },
|
||||
{ ColorNames::salmon, &Colors::salmon },
|
||||
{ ColorNames::sandybrown, &Colors::sandybrown },
|
||||
{ ColorNames::seagreen, &Colors::seagreen },
|
||||
{ ColorNames::seashell, &Colors::seashell },
|
||||
{ ColorNames::sienna, &Colors::sienna },
|
||||
{ ColorNames::silver, &Colors::silver },
|
||||
{ ColorNames::skyblue, &Colors::skyblue },
|
||||
{ ColorNames::slateblue, &Colors::slateblue },
|
||||
{ ColorNames::slategray, &Colors::slategray },
|
||||
{ ColorNames::slategrey, &Colors::slategrey },
|
||||
{ ColorNames::snow, &Colors::snow },
|
||||
{ ColorNames::springgreen, &Colors::springgreen },
|
||||
{ ColorNames::steelblue, &Colors::steelblue },
|
||||
{ ColorNames::tan, &Colors::tan },
|
||||
{ ColorNames::teal, &Colors::teal },
|
||||
{ ColorNames::thistle, &Colors::thistle },
|
||||
{ ColorNames::tomato, &Colors::tomato },
|
||||
{ ColorNames::turquoise, &Colors::turquoise },
|
||||
{ ColorNames::violet, &Colors::violet },
|
||||
{ ColorNames::wheat, &Colors::wheat },
|
||||
{ ColorNames::white, &Colors::white },
|
||||
{ ColorNames::whitesmoke, &Colors::whitesmoke },
|
||||
{ ColorNames::yellow, &Colors::yellow },
|
||||
{ ColorNames::yellowgreen, &Colors::yellowgreen },
|
||||
{ ColorNames::rebeccapurple, &Colors::rebeccapurple },
|
||||
{ ColorNames::transparent, &Colors::transparent }
|
||||
};
|
||||
|
||||
const Color_RGBA* name_to_color(const char* key)
|
||||
{
|
||||
return name_to_color(sass::string(key));
|
||||
}
|
||||
|
||||
const Color_RGBA* name_to_color(const sass::string& key)
|
||||
{
|
||||
// case insensitive lookup. See #2462
|
||||
sass::string lower = key;
|
||||
Util::ascii_str_tolower(&lower);
|
||||
|
||||
auto p = names_to_colors->find(lower);
|
||||
if (p != names_to_colors->end()) {
|
||||
return p->second;
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
const char* color_to_name(const int key)
|
||||
{
|
||||
auto p = colors_to_names->find(key);
|
||||
if (p != colors_to_names->end()) {
|
||||
return p->second;
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
const char* color_to_name(const double key)
|
||||
{
|
||||
return color_to_name((int)key);
|
||||
}
|
||||
|
||||
const char* color_to_name(const Color_RGBA& c)
|
||||
{
|
||||
double key = c.r() * 0x10000
|
||||
+ c.g() * 0x100
|
||||
+ c.b();
|
||||
return color_to_name(key);
|
||||
}
|
||||
|
||||
}
|
||||
323
vendor/bundle/ruby/2.6.0/gems/sassc-2.4.0/ext/libsass/src/color_maps.hpp
vendored
Normal file
323
vendor/bundle/ruby/2.6.0/gems/sassc-2.4.0/ext/libsass/src/color_maps.hpp
vendored
Normal file
@@ -0,0 +1,323 @@
|
||||
|
||||
#ifndef SASS_COLOR_MAPS_H
|
||||
#define SASS_COLOR_MAPS_H
|
||||
|
||||
#include <map>
|
||||
#include "ast.hpp"
|
||||
|
||||
namespace Sass {
|
||||
|
||||
namespace ColorNames
|
||||
{
|
||||
extern const char aliceblue[];
|
||||
extern const char antiquewhite[];
|
||||
extern const char cyan[];
|
||||
extern const char aqua[];
|
||||
extern const char aquamarine[];
|
||||
extern const char azure[];
|
||||
extern const char beige[];
|
||||
extern const char bisque[];
|
||||
extern const char black[];
|
||||
extern const char blanchedalmond[];
|
||||
extern const char blue[];
|
||||
extern const char blueviolet[];
|
||||
extern const char brown[];
|
||||
extern const char burlywood[];
|
||||
extern const char cadetblue[];
|
||||
extern const char chartreuse[];
|
||||
extern const char chocolate[];
|
||||
extern const char coral[];
|
||||
extern const char cornflowerblue[];
|
||||
extern const char cornsilk[];
|
||||
extern const char crimson[];
|
||||
extern const char darkblue[];
|
||||
extern const char darkcyan[];
|
||||
extern const char darkgoldenrod[];
|
||||
extern const char darkgray[];
|
||||
extern const char darkgrey[];
|
||||
extern const char darkgreen[];
|
||||
extern const char darkkhaki[];
|
||||
extern const char darkmagenta[];
|
||||
extern const char darkolivegreen[];
|
||||
extern const char darkorange[];
|
||||
extern const char darkorchid[];
|
||||
extern const char darkred[];
|
||||
extern const char darksalmon[];
|
||||
extern const char darkseagreen[];
|
||||
extern const char darkslateblue[];
|
||||
extern const char darkslategray[];
|
||||
extern const char darkslategrey[];
|
||||
extern const char darkturquoise[];
|
||||
extern const char darkviolet[];
|
||||
extern const char deeppink[];
|
||||
extern const char deepskyblue[];
|
||||
extern const char dimgray[];
|
||||
extern const char dimgrey[];
|
||||
extern const char dodgerblue[];
|
||||
extern const char firebrick[];
|
||||
extern const char floralwhite[];
|
||||
extern const char forestgreen[];
|
||||
extern const char magenta[];
|
||||
extern const char fuchsia[];
|
||||
extern const char gainsboro[];
|
||||
extern const char ghostwhite[];
|
||||
extern const char gold[];
|
||||
extern const char goldenrod[];
|
||||
extern const char gray[];
|
||||
extern const char grey[];
|
||||
extern const char green[];
|
||||
extern const char greenyellow[];
|
||||
extern const char honeydew[];
|
||||
extern const char hotpink[];
|
||||
extern const char indianred[];
|
||||
extern const char indigo[];
|
||||
extern const char ivory[];
|
||||
extern const char khaki[];
|
||||
extern const char lavender[];
|
||||
extern const char lavenderblush[];
|
||||
extern const char lawngreen[];
|
||||
extern const char lemonchiffon[];
|
||||
extern const char lightblue[];
|
||||
extern const char lightcoral[];
|
||||
extern const char lightcyan[];
|
||||
extern const char lightgoldenrodyellow[];
|
||||
extern const char lightgray[];
|
||||
extern const char lightgrey[];
|
||||
extern const char lightgreen[];
|
||||
extern const char lightpink[];
|
||||
extern const char lightsalmon[];
|
||||
extern const char lightseagreen[];
|
||||
extern const char lightskyblue[];
|
||||
extern const char lightslategray[];
|
||||
extern const char lightslategrey[];
|
||||
extern const char lightsteelblue[];
|
||||
extern const char lightyellow[];
|
||||
extern const char lime[];
|
||||
extern const char limegreen[];
|
||||
extern const char linen[];
|
||||
extern const char maroon[];
|
||||
extern const char mediumaquamarine[];
|
||||
extern const char mediumblue[];
|
||||
extern const char mediumorchid[];
|
||||
extern const char mediumpurple[];
|
||||
extern const char mediumseagreen[];
|
||||
extern const char mediumslateblue[];
|
||||
extern const char mediumspringgreen[];
|
||||
extern const char mediumturquoise[];
|
||||
extern const char mediumvioletred[];
|
||||
extern const char midnightblue[];
|
||||
extern const char mintcream[];
|
||||
extern const char mistyrose[];
|
||||
extern const char moccasin[];
|
||||
extern const char navajowhite[];
|
||||
extern const char navy[];
|
||||
extern const char oldlace[];
|
||||
extern const char olive[];
|
||||
extern const char olivedrab[];
|
||||
extern const char orange[];
|
||||
extern const char orangered[];
|
||||
extern const char orchid[];
|
||||
extern const char palegoldenrod[];
|
||||
extern const char palegreen[];
|
||||
extern const char paleturquoise[];
|
||||
extern const char palevioletred[];
|
||||
extern const char papayawhip[];
|
||||
extern const char peachpuff[];
|
||||
extern const char peru[];
|
||||
extern const char pink[];
|
||||
extern const char plum[];
|
||||
extern const char powderblue[];
|
||||
extern const char purple[];
|
||||
extern const char red[];
|
||||
extern const char rosybrown[];
|
||||
extern const char royalblue[];
|
||||
extern const char saddlebrown[];
|
||||
extern const char salmon[];
|
||||
extern const char sandybrown[];
|
||||
extern const char seagreen[];
|
||||
extern const char seashell[];
|
||||
extern const char sienna[];
|
||||
extern const char silver[];
|
||||
extern const char skyblue[];
|
||||
extern const char slateblue[];
|
||||
extern const char slategray[];
|
||||
extern const char slategrey[];
|
||||
extern const char snow[];
|
||||
extern const char springgreen[];
|
||||
extern const char steelblue[];
|
||||
extern const char tan[];
|
||||
extern const char teal[];
|
||||
extern const char thistle[];
|
||||
extern const char tomato[];
|
||||
extern const char turquoise[];
|
||||
extern const char violet[];
|
||||
extern const char wheat[];
|
||||
extern const char white[];
|
||||
extern const char whitesmoke[];
|
||||
extern const char yellow[];
|
||||
extern const char yellowgreen[];
|
||||
extern const char rebeccapurple[];
|
||||
extern const char transparent[];
|
||||
}
|
||||
|
||||
namespace Colors {
|
||||
extern const Color_RGBA aliceblue;
|
||||
extern const Color_RGBA antiquewhite;
|
||||
extern const Color_RGBA cyan;
|
||||
extern const Color_RGBA aqua;
|
||||
extern const Color_RGBA aquamarine;
|
||||
extern const Color_RGBA azure;
|
||||
extern const Color_RGBA beige;
|
||||
extern const Color_RGBA bisque;
|
||||
extern const Color_RGBA black;
|
||||
extern const Color_RGBA blanchedalmond;
|
||||
extern const Color_RGBA blue;
|
||||
extern const Color_RGBA blueviolet;
|
||||
extern const Color_RGBA brown;
|
||||
extern const Color_RGBA burlywood;
|
||||
extern const Color_RGBA cadetblue;
|
||||
extern const Color_RGBA chartreuse;
|
||||
extern const Color_RGBA chocolate;
|
||||
extern const Color_RGBA coral;
|
||||
extern const Color_RGBA cornflowerblue;
|
||||
extern const Color_RGBA cornsilk;
|
||||
extern const Color_RGBA crimson;
|
||||
extern const Color_RGBA darkblue;
|
||||
extern const Color_RGBA darkcyan;
|
||||
extern const Color_RGBA darkgoldenrod;
|
||||
extern const Color_RGBA darkgray;
|
||||
extern const Color_RGBA darkgrey;
|
||||
extern const Color_RGBA darkgreen;
|
||||
extern const Color_RGBA darkkhaki;
|
||||
extern const Color_RGBA darkmagenta;
|
||||
extern const Color_RGBA darkolivegreen;
|
||||
extern const Color_RGBA darkorange;
|
||||
extern const Color_RGBA darkorchid;
|
||||
extern const Color_RGBA darkred;
|
||||
extern const Color_RGBA darksalmon;
|
||||
extern const Color_RGBA darkseagreen;
|
||||
extern const Color_RGBA darkslateblue;
|
||||
extern const Color_RGBA darkslategray;
|
||||
extern const Color_RGBA darkslategrey;
|
||||
extern const Color_RGBA darkturquoise;
|
||||
extern const Color_RGBA darkviolet;
|
||||
extern const Color_RGBA deeppink;
|
||||
extern const Color_RGBA deepskyblue;
|
||||
extern const Color_RGBA dimgray;
|
||||
extern const Color_RGBA dimgrey;
|
||||
extern const Color_RGBA dodgerblue;
|
||||
extern const Color_RGBA firebrick;
|
||||
extern const Color_RGBA floralwhite;
|
||||
extern const Color_RGBA forestgreen;
|
||||
extern const Color_RGBA magenta;
|
||||
extern const Color_RGBA fuchsia;
|
||||
extern const Color_RGBA gainsboro;
|
||||
extern const Color_RGBA ghostwhite;
|
||||
extern const Color_RGBA gold;
|
||||
extern const Color_RGBA goldenrod;
|
||||
extern const Color_RGBA gray;
|
||||
extern const Color_RGBA grey;
|
||||
extern const Color_RGBA green;
|
||||
extern const Color_RGBA greenyellow;
|
||||
extern const Color_RGBA honeydew;
|
||||
extern const Color_RGBA hotpink;
|
||||
extern const Color_RGBA indianred;
|
||||
extern const Color_RGBA indigo;
|
||||
extern const Color_RGBA ivory;
|
||||
extern const Color_RGBA khaki;
|
||||
extern const Color_RGBA lavender;
|
||||
extern const Color_RGBA lavenderblush;
|
||||
extern const Color_RGBA lawngreen;
|
||||
extern const Color_RGBA lemonchiffon;
|
||||
extern const Color_RGBA lightblue;
|
||||
extern const Color_RGBA lightcoral;
|
||||
extern const Color_RGBA lightcyan;
|
||||
extern const Color_RGBA lightgoldenrodyellow;
|
||||
extern const Color_RGBA lightgray;
|
||||
extern const Color_RGBA lightgrey;
|
||||
extern const Color_RGBA lightgreen;
|
||||
extern const Color_RGBA lightpink;
|
||||
extern const Color_RGBA lightsalmon;
|
||||
extern const Color_RGBA lightseagreen;
|
||||
extern const Color_RGBA lightskyblue;
|
||||
extern const Color_RGBA lightslategray;
|
||||
extern const Color_RGBA lightslategrey;
|
||||
extern const Color_RGBA lightsteelblue;
|
||||
extern const Color_RGBA lightyellow;
|
||||
extern const Color_RGBA lime;
|
||||
extern const Color_RGBA limegreen;
|
||||
extern const Color_RGBA linen;
|
||||
extern const Color_RGBA maroon;
|
||||
extern const Color_RGBA mediumaquamarine;
|
||||
extern const Color_RGBA mediumblue;
|
||||
extern const Color_RGBA mediumorchid;
|
||||
extern const Color_RGBA mediumpurple;
|
||||
extern const Color_RGBA mediumseagreen;
|
||||
extern const Color_RGBA mediumslateblue;
|
||||
extern const Color_RGBA mediumspringgreen;
|
||||
extern const Color_RGBA mediumturquoise;
|
||||
extern const Color_RGBA mediumvioletred;
|
||||
extern const Color_RGBA midnightblue;
|
||||
extern const Color_RGBA mintcream;
|
||||
extern const Color_RGBA mistyrose;
|
||||
extern const Color_RGBA moccasin;
|
||||
extern const Color_RGBA navajowhite;
|
||||
extern const Color_RGBA navy;
|
||||
extern const Color_RGBA oldlace;
|
||||
extern const Color_RGBA olive;
|
||||
extern const Color_RGBA olivedrab;
|
||||
extern const Color_RGBA orange;
|
||||
extern const Color_RGBA orangered;
|
||||
extern const Color_RGBA orchid;
|
||||
extern const Color_RGBA palegoldenrod;
|
||||
extern const Color_RGBA palegreen;
|
||||
extern const Color_RGBA paleturquoise;
|
||||
extern const Color_RGBA palevioletred;
|
||||
extern const Color_RGBA papayawhip;
|
||||
extern const Color_RGBA peachpuff;
|
||||
extern const Color_RGBA peru;
|
||||
extern const Color_RGBA pink;
|
||||
extern const Color_RGBA plum;
|
||||
extern const Color_RGBA powderblue;
|
||||
extern const Color_RGBA purple;
|
||||
extern const Color_RGBA red;
|
||||
extern const Color_RGBA rosybrown;
|
||||
extern const Color_RGBA royalblue;
|
||||
extern const Color_RGBA saddlebrown;
|
||||
extern const Color_RGBA salmon;
|
||||
extern const Color_RGBA sandybrown;
|
||||
extern const Color_RGBA seagreen;
|
||||
extern const Color_RGBA seashell;
|
||||
extern const Color_RGBA sienna;
|
||||
extern const Color_RGBA silver;
|
||||
extern const Color_RGBA skyblue;
|
||||
extern const Color_RGBA slateblue;
|
||||
extern const Color_RGBA slategray;
|
||||
extern const Color_RGBA slategrey;
|
||||
extern const Color_RGBA snow;
|
||||
extern const Color_RGBA springgreen;
|
||||
extern const Color_RGBA steelblue;
|
||||
extern const Color_RGBA tan;
|
||||
extern const Color_RGBA teal;
|
||||
extern const Color_RGBA thistle;
|
||||
extern const Color_RGBA tomato;
|
||||
extern const Color_RGBA turquoise;
|
||||
extern const Color_RGBA violet;
|
||||
extern const Color_RGBA wheat;
|
||||
extern const Color_RGBA white;
|
||||
extern const Color_RGBA whitesmoke;
|
||||
extern const Color_RGBA yellow;
|
||||
extern const Color_RGBA yellowgreen;
|
||||
extern const Color_RGBA rebeccapurple;
|
||||
extern const Color_RGBA transparent;
|
||||
}
|
||||
|
||||
const Color_RGBA* name_to_color(const char*);
|
||||
const Color_RGBA* name_to_color(const sass::string&);
|
||||
const char* color_to_name(const int);
|
||||
const char* color_to_name(const Color_RGBA&);
|
||||
const char* color_to_name(const double);
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
199
vendor/bundle/ruby/2.6.0/gems/sassc-2.4.0/ext/libsass/src/constants.cpp
vendored
Normal file
199
vendor/bundle/ruby/2.6.0/gems/sassc-2.4.0/ext/libsass/src/constants.cpp
vendored
Normal file
@@ -0,0 +1,199 @@
|
||||
// sass.hpp must go before all system headers to get the
|
||||
// __EXTENSIONS__ fix on Solaris.
|
||||
#include "sass.hpp"
|
||||
|
||||
#include "constants.hpp"
|
||||
|
||||
namespace Sass {
|
||||
namespace Constants {
|
||||
|
||||
extern const unsigned long MaxCallStack = 1024;
|
||||
|
||||
// https://github.com/sass/libsass/issues/592
|
||||
// https://developer.mozilla.org/en-US/docs/Web/CSS/Specificity
|
||||
// https://github.com/sass/sass/issues/1495#issuecomment-61189114
|
||||
extern const unsigned long Specificity_Star = 0;
|
||||
extern const unsigned long Specificity_Universal = 0;
|
||||
extern const unsigned long Specificity_Element = 1;
|
||||
extern const unsigned long Specificity_Base = 1000;
|
||||
extern const unsigned long Specificity_Class = 1000;
|
||||
extern const unsigned long Specificity_Attr = 1000;
|
||||
extern const unsigned long Specificity_Pseudo = 1000;
|
||||
extern const unsigned long Specificity_ID = 1000000;
|
||||
|
||||
extern const int UnificationOrder_Element = 1;
|
||||
extern const int UnificationOrder_Id = 2;
|
||||
extern const int UnificationOrder_Class = 2;
|
||||
extern const int UnificationOrder_Attribute = 3;
|
||||
extern const int UnificationOrder_PseudoClass = 4;
|
||||
extern const int UnificationOrder_Wrapped = 5;
|
||||
extern const int UnificationOrder_PseudoElement = 6;
|
||||
extern const int UnificationOrder_Placeholder = 7;
|
||||
|
||||
// sass keywords
|
||||
extern const char at_root_kwd[] = "@at-root";
|
||||
extern const char import_kwd[] = "@import";
|
||||
extern const char mixin_kwd[] = "@mixin";
|
||||
extern const char function_kwd[] = "@function";
|
||||
extern const char return_kwd[] = "@return";
|
||||
extern const char include_kwd[] = "@include";
|
||||
extern const char content_kwd[] = "@content";
|
||||
extern const char extend_kwd[] = "@extend";
|
||||
extern const char if_kwd[] = "@if";
|
||||
extern const char else_kwd[] = "@else";
|
||||
extern const char if_after_else_kwd[] = "if";
|
||||
extern const char for_kwd[] = "@for";
|
||||
extern const char from_kwd[] = "from";
|
||||
extern const char to_kwd[] = "to";
|
||||
extern const char of_kwd[] = "of";
|
||||
extern const char through_kwd[] = "through";
|
||||
extern const char each_kwd[] = "@each";
|
||||
extern const char in_kwd[] = "in";
|
||||
extern const char while_kwd[] = "@while";
|
||||
extern const char warn_kwd[] = "@warn";
|
||||
extern const char error_kwd[] = "@error";
|
||||
extern const char debug_kwd[] = "@debug";
|
||||
extern const char default_kwd[] = "default";
|
||||
extern const char global_kwd[] = "global";
|
||||
extern const char null_kwd[] = "null";
|
||||
extern const char optional_kwd[] = "optional";
|
||||
extern const char with_kwd[] = "with";
|
||||
extern const char without_kwd[] = "without";
|
||||
extern const char all_kwd[] = "all";
|
||||
extern const char rule_kwd[] = "rule";
|
||||
|
||||
// css standard units
|
||||
extern const char em_kwd[] = "em";
|
||||
extern const char ex_kwd[] = "ex";
|
||||
extern const char px_kwd[] = "px";
|
||||
extern const char cm_kwd[] = "cm";
|
||||
extern const char mm_kwd[] = "mm";
|
||||
extern const char pt_kwd[] = "pt";
|
||||
extern const char pc_kwd[] = "pc";
|
||||
extern const char deg_kwd[] = "deg";
|
||||
extern const char rad_kwd[] = "rad";
|
||||
extern const char grad_kwd[] = "grad";
|
||||
extern const char turn_kwd[] = "turn";
|
||||
extern const char ms_kwd[] = "ms";
|
||||
extern const char s_kwd[] = "s";
|
||||
extern const char Hz_kwd[] = "Hz";
|
||||
extern const char kHz_kwd[] = "kHz";
|
||||
|
||||
// vendor prefixes
|
||||
extern const char vendor_opera_kwd[] = "-o-";
|
||||
extern const char vendor_webkit_kwd[] = "-webkit-";
|
||||
extern const char vendor_mozilla_kwd[] = "-moz-";
|
||||
extern const char vendor_ms_kwd[] = "-ms-";
|
||||
extern const char vendor_khtml_kwd[] = "-khtml-";
|
||||
|
||||
// css functions and keywords
|
||||
extern const char charset_kwd[] = "@charset";
|
||||
extern const char media_kwd[] = "@media";
|
||||
extern const char supports_kwd[] = "@supports";
|
||||
extern const char keyframes_kwd[] = "keyframes";
|
||||
extern const char only_kwd[] = "only";
|
||||
extern const char rgb_fn_kwd[] = "rgb(";
|
||||
extern const char url_fn_kwd[] = "url(";
|
||||
extern const char url_kwd[] = "url";
|
||||
// extern const char url_prefix_fn_kwd[] = "url-prefix(";
|
||||
extern const char important_kwd[] = "important";
|
||||
extern const char pseudo_not_fn_kwd[] = ":not(";
|
||||
extern const char even_kwd[] = "even";
|
||||
extern const char odd_kwd[] = "odd";
|
||||
extern const char progid_kwd[] = "progid";
|
||||
extern const char expression_kwd[] = "expression";
|
||||
extern const char calc_fn_kwd[] = "calc";
|
||||
|
||||
extern const char almost_any_value_class[] = "\"'#!;{}";
|
||||
|
||||
// css selector keywords
|
||||
extern const char sel_deep_kwd[] = "/deep/";
|
||||
|
||||
// css attribute-matching operators
|
||||
extern const char tilde_equal[] = "~=";
|
||||
extern const char pipe_equal[] = "|=";
|
||||
extern const char caret_equal[] = "^=";
|
||||
extern const char dollar_equal[] = "$=";
|
||||
extern const char star_equal[] = "*=";
|
||||
|
||||
// relational & logical operators and constants
|
||||
extern const char and_kwd[] = "and";
|
||||
extern const char or_kwd[] = "or";
|
||||
extern const char not_kwd[] = "not";
|
||||
extern const char gt[] = ">";
|
||||
extern const char gte[] = ">=";
|
||||
extern const char lt[] = "<";
|
||||
extern const char lte[] = "<=";
|
||||
extern const char eq[] = "==";
|
||||
extern const char neq[] = "!=";
|
||||
extern const char true_kwd[] = "true";
|
||||
extern const char false_kwd[] = "false";
|
||||
|
||||
// definition keywords
|
||||
extern const char using_kwd[] = "using";
|
||||
|
||||
// miscellaneous punctuation and delimiters
|
||||
extern const char percent_str[] = "%";
|
||||
extern const char empty_str[] = "";
|
||||
extern const char slash_slash[] = "//";
|
||||
extern const char slash_star[] = "/*";
|
||||
extern const char star_slash[] = "*/";
|
||||
extern const char hash_lbrace[] = "#{";
|
||||
extern const char rbrace[] = "}";
|
||||
extern const char rparen[] = ")";
|
||||
extern const char sign_chars[] = "-+";
|
||||
extern const char op_chars[] = "-+";
|
||||
extern const char hyphen[] = "-";
|
||||
extern const char ellipsis[] = "...";
|
||||
// extern const char url_space_chars[] = " \t\r\n\f";
|
||||
// type names
|
||||
extern const char numeric_name[] = "numeric value";
|
||||
extern const char number_name[] = "number";
|
||||
extern const char percentage_name[] = "percentage";
|
||||
extern const char dimension_name[] = "numeric dimension";
|
||||
extern const char string_name[] = "string";
|
||||
extern const char bool_name[] = "bool";
|
||||
extern const char color_name[] = "color";
|
||||
extern const char list_name[] = "list";
|
||||
extern const char map_name[] = "map";
|
||||
extern const char arglist_name[] = "arglist";
|
||||
|
||||
// constants for uri parsing (RFC 3986 Appendix A.)
|
||||
extern const char uri_chars[] = ":;/?!%&#@|[]{}'`^\"*+-.,_=~";
|
||||
extern const char real_uri_chars[] = "#%&";
|
||||
|
||||
extern const char selector_combinator_child[] = ">";
|
||||
extern const char selector_combinator_general[] = "~";
|
||||
extern const char selector_combinator_adjacent[] = "+";
|
||||
|
||||
// some specific constant character classes
|
||||
// they must be static to be useable by lexer
|
||||
extern const char static_ops[] = "*/%";
|
||||
// some character classes for the parser
|
||||
extern const char selector_list_delims[] = "){};!";
|
||||
extern const char complex_selector_delims[] = ",){};!";
|
||||
extern const char selector_combinator_ops[] = "+~>";
|
||||
// optional modifiers for alternative compare context
|
||||
extern const char attribute_compare_modifiers[] = "~|^$*";
|
||||
extern const char selector_lookahead_ops[] = "*&%,()[]";
|
||||
|
||||
// byte order marks
|
||||
// (taken from http://en.wikipedia.org/wiki/Byte_order_mark)
|
||||
extern const unsigned char utf_8_bom[] = { 0xEF, 0xBB, 0xBF };
|
||||
extern const unsigned char utf_16_bom_be[] = { 0xFE, 0xFF };
|
||||
extern const unsigned char utf_16_bom_le[] = { 0xFF, 0xFE };
|
||||
extern const unsigned char utf_32_bom_be[] = { 0x00, 0x00, 0xFE, 0xFF };
|
||||
extern const unsigned char utf_32_bom_le[] = { 0xFF, 0xFE, 0x00, 0x00 };
|
||||
extern const unsigned char utf_7_bom_1[] = { 0x2B, 0x2F, 0x76, 0x38 };
|
||||
extern const unsigned char utf_7_bom_2[] = { 0x2B, 0x2F, 0x76, 0x39 };
|
||||
extern const unsigned char utf_7_bom_3[] = { 0x2B, 0x2F, 0x76, 0x2B };
|
||||
extern const unsigned char utf_7_bom_4[] = { 0x2B, 0x2F, 0x76, 0x2F };
|
||||
extern const unsigned char utf_7_bom_5[] = { 0x2B, 0x2F, 0x76, 0x38, 0x2D };
|
||||
extern const unsigned char utf_1_bom[] = { 0xF7, 0x64, 0x4C };
|
||||
extern const unsigned char utf_ebcdic_bom[] = { 0xDD, 0x73, 0x66, 0x73 };
|
||||
extern const unsigned char scsu_bom[] = { 0x0E, 0xFE, 0xFF };
|
||||
extern const unsigned char bocu_1_bom[] = { 0xFB, 0xEE, 0x28 };
|
||||
extern const unsigned char gb_18030_bom[] = { 0x84, 0x31, 0x95, 0x33 };
|
||||
|
||||
}
|
||||
}
|
||||
200
vendor/bundle/ruby/2.6.0/gems/sassc-2.4.0/ext/libsass/src/constants.hpp
vendored
Normal file
200
vendor/bundle/ruby/2.6.0/gems/sassc-2.4.0/ext/libsass/src/constants.hpp
vendored
Normal file
@@ -0,0 +1,200 @@
|
||||
#ifndef SASS_CONSTANTS_H
|
||||
#define SASS_CONSTANTS_H
|
||||
|
||||
namespace Sass {
|
||||
namespace Constants {
|
||||
|
||||
// The maximum call stack that can be created
|
||||
extern const unsigned long MaxCallStack;
|
||||
|
||||
// https://developer.mozilla.org/en-US/docs/Web/CSS/Specificity
|
||||
// The following list of selectors is by increasing specificity:
|
||||
extern const unsigned long Specificity_Star;
|
||||
extern const unsigned long Specificity_Universal;
|
||||
extern const unsigned long Specificity_Element;
|
||||
extern const unsigned long Specificity_Base;
|
||||
extern const unsigned long Specificity_Class;
|
||||
extern const unsigned long Specificity_Attr;
|
||||
extern const unsigned long Specificity_Pseudo;
|
||||
extern const unsigned long Specificity_ID;
|
||||
|
||||
// Selector unification order;
|
||||
extern const int UnificationOrder_Element;
|
||||
extern const int UnificationOrder_Id;
|
||||
extern const int UnificationOrder_Class;
|
||||
extern const int UnificationOrder_Attribute;
|
||||
extern const int UnificationOrder_PseudoClass;
|
||||
extern const int UnificationOrder_Wrapped;
|
||||
extern const int UnificationOrder_PseudoElement;
|
||||
extern const int UnificationOrder_Placeholder;
|
||||
|
||||
// sass keywords
|
||||
extern const char at_root_kwd[];
|
||||
extern const char import_kwd[];
|
||||
extern const char mixin_kwd[];
|
||||
extern const char function_kwd[];
|
||||
extern const char return_kwd[];
|
||||
extern const char include_kwd[];
|
||||
extern const char content_kwd[];
|
||||
extern const char extend_kwd[];
|
||||
extern const char if_kwd[];
|
||||
extern const char else_kwd[];
|
||||
extern const char if_after_else_kwd[];
|
||||
extern const char for_kwd[];
|
||||
extern const char from_kwd[];
|
||||
extern const char to_kwd[];
|
||||
extern const char of_kwd[];
|
||||
extern const char through_kwd[];
|
||||
extern const char each_kwd[];
|
||||
extern const char in_kwd[];
|
||||
extern const char while_kwd[];
|
||||
extern const char warn_kwd[];
|
||||
extern const char error_kwd[];
|
||||
extern const char debug_kwd[];
|
||||
extern const char default_kwd[];
|
||||
extern const char global_kwd[];
|
||||
extern const char null_kwd[];
|
||||
extern const char optional_kwd[];
|
||||
extern const char with_kwd[];
|
||||
extern const char without_kwd[];
|
||||
extern const char all_kwd[];
|
||||
extern const char rule_kwd[];
|
||||
|
||||
// css standard units
|
||||
extern const char em_kwd[];
|
||||
extern const char ex_kwd[];
|
||||
extern const char px_kwd[];
|
||||
extern const char cm_kwd[];
|
||||
extern const char mm_kwd[];
|
||||
extern const char pt_kwd[];
|
||||
extern const char pc_kwd[];
|
||||
extern const char deg_kwd[];
|
||||
extern const char rad_kwd[];
|
||||
extern const char grad_kwd[];
|
||||
extern const char turn_kwd[];
|
||||
extern const char ms_kwd[];
|
||||
extern const char s_kwd[];
|
||||
extern const char Hz_kwd[];
|
||||
extern const char kHz_kwd[];
|
||||
|
||||
// vendor prefixes
|
||||
extern const char vendor_opera_kwd[];
|
||||
extern const char vendor_webkit_kwd[];
|
||||
extern const char vendor_mozilla_kwd[];
|
||||
extern const char vendor_ms_kwd[];
|
||||
extern const char vendor_khtml_kwd[];
|
||||
|
||||
// css functions and keywords
|
||||
extern const char charset_kwd[];
|
||||
extern const char media_kwd[];
|
||||
extern const char supports_kwd[];
|
||||
extern const char keyframes_kwd[];
|
||||
extern const char only_kwd[];
|
||||
extern const char rgb_fn_kwd[];
|
||||
extern const char url_fn_kwd[];
|
||||
extern const char url_kwd[];
|
||||
// extern const char url_prefix_fn_kwd[];
|
||||
extern const char important_kwd[];
|
||||
extern const char pseudo_not_fn_kwd[];
|
||||
extern const char even_kwd[];
|
||||
extern const char odd_kwd[];
|
||||
extern const char progid_kwd[];
|
||||
extern const char expression_kwd[];
|
||||
extern const char calc_fn_kwd[];
|
||||
|
||||
// char classes for "regular expressions"
|
||||
extern const char almost_any_value_class[];
|
||||
|
||||
// css selector keywords
|
||||
extern const char sel_deep_kwd[];
|
||||
|
||||
// css attribute-matching operators
|
||||
extern const char tilde_equal[];
|
||||
extern const char pipe_equal[];
|
||||
extern const char caret_equal[];
|
||||
extern const char dollar_equal[];
|
||||
extern const char star_equal[];
|
||||
|
||||
// relational & logical operators and constants
|
||||
extern const char and_kwd[];
|
||||
extern const char or_kwd[];
|
||||
extern const char not_kwd[];
|
||||
extern const char gt[];
|
||||
extern const char gte[];
|
||||
extern const char lt[];
|
||||
extern const char lte[];
|
||||
extern const char eq[];
|
||||
extern const char neq[];
|
||||
extern const char true_kwd[];
|
||||
extern const char false_kwd[];
|
||||
|
||||
// definition keywords
|
||||
extern const char using_kwd[];
|
||||
|
||||
// miscellaneous punctuation and delimiters
|
||||
extern const char percent_str[];
|
||||
extern const char empty_str[];
|
||||
extern const char slash_slash[];
|
||||
extern const char slash_star[];
|
||||
extern const char star_slash[];
|
||||
extern const char hash_lbrace[];
|
||||
extern const char rbrace[];
|
||||
extern const char rparen[];
|
||||
extern const char sign_chars[];
|
||||
extern const char op_chars[];
|
||||
extern const char hyphen[];
|
||||
extern const char ellipsis[];
|
||||
// extern const char url_space_chars[];
|
||||
|
||||
// type names
|
||||
extern const char numeric_name[];
|
||||
extern const char number_name[];
|
||||
extern const char percentage_name[];
|
||||
extern const char dimension_name[];
|
||||
extern const char string_name[];
|
||||
extern const char bool_name[];
|
||||
extern const char color_name[];
|
||||
extern const char list_name[];
|
||||
extern const char map_name[];
|
||||
extern const char arglist_name[];
|
||||
|
||||
// constants for uri parsing (RFC 3986 Appendix A.)
|
||||
extern const char uri_chars[];
|
||||
extern const char real_uri_chars[];
|
||||
|
||||
// constants for selector combinators
|
||||
extern const char selector_combinator_child[];
|
||||
extern const char selector_combinator_general[];
|
||||
extern const char selector_combinator_adjacent[];
|
||||
|
||||
// some specific constant character classes
|
||||
// they must be static to be useable by lexer
|
||||
extern const char static_ops[];
|
||||
extern const char selector_list_delims[];
|
||||
extern const char complex_selector_delims[];
|
||||
extern const char selector_combinator_ops[];
|
||||
extern const char attribute_compare_modifiers[];
|
||||
extern const char selector_lookahead_ops[];
|
||||
|
||||
// byte order marks
|
||||
// (taken from http://en.wikipedia.org/wiki/Byte_order_mark)
|
||||
extern const unsigned char utf_8_bom[];
|
||||
extern const unsigned char utf_16_bom_be[];
|
||||
extern const unsigned char utf_16_bom_le[];
|
||||
extern const unsigned char utf_32_bom_be[];
|
||||
extern const unsigned char utf_32_bom_le[];
|
||||
extern const unsigned char utf_7_bom_1[];
|
||||
extern const unsigned char utf_7_bom_2[];
|
||||
extern const unsigned char utf_7_bom_3[];
|
||||
extern const unsigned char utf_7_bom_4[];
|
||||
extern const unsigned char utf_7_bom_5[];
|
||||
extern const unsigned char utf_1_bom[];
|
||||
extern const unsigned char utf_ebcdic_bom[];
|
||||
extern const unsigned char scsu_bom[];
|
||||
extern const unsigned char bocu_1_bom[];
|
||||
extern const unsigned char gb_18030_bom[];
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
863
vendor/bundle/ruby/2.6.0/gems/sassc-2.4.0/ext/libsass/src/context.cpp
vendored
Normal file
863
vendor/bundle/ruby/2.6.0/gems/sassc-2.4.0/ext/libsass/src/context.cpp
vendored
Normal file
@@ -0,0 +1,863 @@
|
||||
// sass.hpp must go before all system headers to get the
|
||||
// __EXTENSIONS__ fix on Solaris.
|
||||
#include "sass.hpp"
|
||||
#include "ast.hpp"
|
||||
|
||||
#include "remove_placeholders.hpp"
|
||||
#include "sass_functions.hpp"
|
||||
#include "check_nesting.hpp"
|
||||
#include "fn_selectors.hpp"
|
||||
#include "fn_strings.hpp"
|
||||
#include "fn_numbers.hpp"
|
||||
#include "fn_colors.hpp"
|
||||
#include "fn_miscs.hpp"
|
||||
#include "fn_lists.hpp"
|
||||
#include "fn_maps.hpp"
|
||||
#include "context.hpp"
|
||||
#include "expand.hpp"
|
||||
#include "parser.hpp"
|
||||
#include "cssize.hpp"
|
||||
#include "source.hpp"
|
||||
|
||||
namespace Sass {
|
||||
using namespace Constants;
|
||||
using namespace File;
|
||||
using namespace Sass;
|
||||
|
||||
inline bool sort_importers (const Sass_Importer_Entry& i, const Sass_Importer_Entry& j)
|
||||
{ return sass_importer_get_priority(i) > sass_importer_get_priority(j); }
|
||||
|
||||
static sass::string safe_input(const char* in_path)
|
||||
{
|
||||
if (in_path == nullptr || in_path[0] == '\0') return "stdin";
|
||||
return in_path;
|
||||
}
|
||||
|
||||
static sass::string safe_output(const char* out_path, sass::string input_path)
|
||||
{
|
||||
if (out_path == nullptr || out_path[0] == '\0') {
|
||||
if (input_path.empty()) return "stdout";
|
||||
return input_path.substr(0, input_path.find_last_of(".")) + ".css";
|
||||
}
|
||||
return out_path;
|
||||
}
|
||||
|
||||
Context::Context(struct Sass_Context& c_ctx)
|
||||
: CWD(File::get_cwd()),
|
||||
c_options(c_ctx),
|
||||
entry_path(""),
|
||||
head_imports(0),
|
||||
plugins(),
|
||||
emitter(c_options),
|
||||
|
||||
ast_gc(),
|
||||
strings(),
|
||||
resources(),
|
||||
sheets(),
|
||||
import_stack(),
|
||||
callee_stack(),
|
||||
traces(),
|
||||
extender(Extender::NORMAL, traces),
|
||||
c_compiler(NULL),
|
||||
|
||||
c_headers (sass::vector<Sass_Importer_Entry>()),
|
||||
c_importers (sass::vector<Sass_Importer_Entry>()),
|
||||
c_functions (sass::vector<Sass_Function_Entry>()),
|
||||
|
||||
indent (safe_str(c_options.indent, " ")),
|
||||
linefeed (safe_str(c_options.linefeed, "\n")),
|
||||
|
||||
input_path (make_canonical_path(safe_input(c_options.input_path))),
|
||||
output_path (make_canonical_path(safe_output(c_options.output_path, input_path))),
|
||||
source_map_file (make_canonical_path(safe_str(c_options.source_map_file, ""))),
|
||||
source_map_root (make_canonical_path(safe_str(c_options.source_map_root, "")))
|
||||
|
||||
{
|
||||
|
||||
// Sass 3.4: The current working directory will no longer be placed onto the Sass load path by default.
|
||||
// If you need the current working directory to be available, set SASS_PATH=. in your shell's environment.
|
||||
// include_paths.push_back(CWD);
|
||||
|
||||
// collect more paths from different options
|
||||
collect_include_paths(c_options.include_path);
|
||||
collect_include_paths(c_options.include_paths);
|
||||
collect_plugin_paths(c_options.plugin_path);
|
||||
collect_plugin_paths(c_options.plugin_paths);
|
||||
|
||||
// load plugins and register custom behaviors
|
||||
for(auto plug : plugin_paths) plugins.load_plugins(plug);
|
||||
for(auto fn : plugins.get_headers()) c_headers.push_back(fn);
|
||||
for(auto fn : plugins.get_importers()) c_importers.push_back(fn);
|
||||
for(auto fn : plugins.get_functions()) c_functions.push_back(fn);
|
||||
|
||||
// sort the items by priority (lowest first)
|
||||
sort (c_headers.begin(), c_headers.end(), sort_importers);
|
||||
sort (c_importers.begin(), c_importers.end(), sort_importers);
|
||||
|
||||
emitter.set_filename(abs2rel(output_path, source_map_file, CWD));
|
||||
|
||||
}
|
||||
|
||||
void Context::add_c_function(Sass_Function_Entry function)
|
||||
{
|
||||
c_functions.push_back(function);
|
||||
}
|
||||
void Context::add_c_header(Sass_Importer_Entry header)
|
||||
{
|
||||
c_headers.push_back(header);
|
||||
// need to sort the array afterwards (no big deal)
|
||||
sort (c_headers.begin(), c_headers.end(), sort_importers);
|
||||
}
|
||||
void Context::add_c_importer(Sass_Importer_Entry importer)
|
||||
{
|
||||
c_importers.push_back(importer);
|
||||
// need to sort the array afterwards (no big deal)
|
||||
sort (c_importers.begin(), c_importers.end(), sort_importers);
|
||||
}
|
||||
|
||||
Context::~Context()
|
||||
{
|
||||
// resources were allocated by malloc
|
||||
for (size_t i = 0; i < resources.size(); ++i) {
|
||||
free(resources[i].contents);
|
||||
free(resources[i].srcmap);
|
||||
}
|
||||
// free all strings we kept alive during compiler execution
|
||||
for (size_t n = 0; n < strings.size(); ++n) free(strings[n]);
|
||||
// everything that gets put into sources will be freed by us
|
||||
// this shouldn't have anything in it anyway!?
|
||||
for (size_t m = 0; m < import_stack.size(); ++m) {
|
||||
sass_import_take_source(import_stack[m]);
|
||||
sass_import_take_srcmap(import_stack[m]);
|
||||
sass_delete_import(import_stack[m]);
|
||||
}
|
||||
// clear inner structures (vectors) and input source
|
||||
resources.clear(); import_stack.clear();
|
||||
sheets.clear();
|
||||
}
|
||||
|
||||
Data_Context::~Data_Context()
|
||||
{
|
||||
// --> this will be freed by resources
|
||||
// make sure we free the source even if not processed!
|
||||
// if (resources.size() == 0 && source_c_str) free(source_c_str);
|
||||
// if (resources.size() == 0 && srcmap_c_str) free(srcmap_c_str);
|
||||
// source_c_str = 0; srcmap_c_str = 0;
|
||||
}
|
||||
|
||||
File_Context::~File_Context()
|
||||
{
|
||||
}
|
||||
|
||||
void Context::collect_include_paths(const char* paths_str)
|
||||
{
|
||||
if (paths_str) {
|
||||
const char* beg = paths_str;
|
||||
const char* end = Prelexer::find_first<PATH_SEP>(beg);
|
||||
|
||||
while (end) {
|
||||
sass::string path(beg, end - beg);
|
||||
if (!path.empty()) {
|
||||
if (*path.rbegin() != '/') path += '/';
|
||||
include_paths.push_back(path);
|
||||
}
|
||||
beg = end + 1;
|
||||
end = Prelexer::find_first<PATH_SEP>(beg);
|
||||
}
|
||||
|
||||
sass::string path(beg);
|
||||
if (!path.empty()) {
|
||||
if (*path.rbegin() != '/') path += '/';
|
||||
include_paths.push_back(path);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void Context::collect_include_paths(string_list* paths_array)
|
||||
{
|
||||
while (paths_array)
|
||||
{
|
||||
collect_include_paths(paths_array->string);
|
||||
paths_array = paths_array->next;
|
||||
}
|
||||
}
|
||||
|
||||
void Context::collect_plugin_paths(const char* paths_str)
|
||||
{
|
||||
if (paths_str) {
|
||||
const char* beg = paths_str;
|
||||
const char* end = Prelexer::find_first<PATH_SEP>(beg);
|
||||
|
||||
while (end) {
|
||||
sass::string path(beg, end - beg);
|
||||
if (!path.empty()) {
|
||||
if (*path.rbegin() != '/') path += '/';
|
||||
plugin_paths.push_back(path);
|
||||
}
|
||||
beg = end + 1;
|
||||
end = Prelexer::find_first<PATH_SEP>(beg);
|
||||
}
|
||||
|
||||
sass::string path(beg);
|
||||
if (!path.empty()) {
|
||||
if (*path.rbegin() != '/') path += '/';
|
||||
plugin_paths.push_back(path);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void Context::collect_plugin_paths(string_list* paths_array)
|
||||
{
|
||||
while (paths_array)
|
||||
{
|
||||
collect_plugin_paths(paths_array->string);
|
||||
paths_array = paths_array->next;
|
||||
}
|
||||
}
|
||||
|
||||
// resolve the imp_path in base_path or include_paths
|
||||
// looks for alternatives and returns a list from one directory
|
||||
sass::vector<Include> Context::find_includes(const Importer& import)
|
||||
{
|
||||
// make sure we resolve against an absolute path
|
||||
sass::string base_path(rel2abs(import.base_path));
|
||||
// first try to resolve the load path relative to the base path
|
||||
sass::vector<Include> vec(resolve_includes(base_path, import.imp_path));
|
||||
// then search in every include path (but only if nothing found yet)
|
||||
for (size_t i = 0, S = include_paths.size(); vec.size() == 0 && i < S; ++i)
|
||||
{
|
||||
// call resolve_includes and individual base path and append all results
|
||||
sass::vector<Include> resolved(resolve_includes(include_paths[i], import.imp_path));
|
||||
if (resolved.size()) vec.insert(vec.end(), resolved.begin(), resolved.end());
|
||||
}
|
||||
// return vector
|
||||
return vec;
|
||||
}
|
||||
|
||||
// register include with resolved path and its content
|
||||
// memory of the resources will be freed by us on exit
|
||||
void Context::register_resource(const Include& inc, const Resource& res)
|
||||
{
|
||||
|
||||
// do not parse same resource twice
|
||||
// maybe raise an error in this case
|
||||
// if (sheets.count(inc.abs_path)) {
|
||||
// free(res.contents); free(res.srcmap);
|
||||
// throw std::runtime_error("duplicate resource registered");
|
||||
// return;
|
||||
// }
|
||||
|
||||
// get index for this resource
|
||||
size_t idx = resources.size();
|
||||
|
||||
// tell emitter about new resource
|
||||
emitter.add_source_index(idx);
|
||||
|
||||
// put resources under our control
|
||||
// the memory will be freed later
|
||||
resources.push_back(res);
|
||||
|
||||
// add a relative link to the working directory
|
||||
included_files.push_back(inc.abs_path);
|
||||
// add a relative link to the source map output file
|
||||
srcmap_links.push_back(abs2rel(inc.abs_path, source_map_file, CWD));
|
||||
|
||||
// get pointer to the loaded content
|
||||
Sass_Import_Entry import = sass_make_import(
|
||||
inc.imp_path.c_str(),
|
||||
inc.abs_path.c_str(),
|
||||
res.contents,
|
||||
res.srcmap
|
||||
);
|
||||
// add the entry to the stack
|
||||
import_stack.push_back(import);
|
||||
|
||||
// get pointer to the loaded content
|
||||
const char* contents = resources[idx].contents;
|
||||
SourceFileObj source = SASS_MEMORY_NEW(SourceFile,
|
||||
inc.abs_path.c_str(), contents, idx);
|
||||
|
||||
// create the initial parser state from resource
|
||||
SourceSpan pstate(source);
|
||||
|
||||
// check existing import stack for possible recursion
|
||||
for (size_t i = 0; i < import_stack.size() - 2; ++i) {
|
||||
auto parent = import_stack[i];
|
||||
if (std::strcmp(parent->abs_path, import->abs_path) == 0) {
|
||||
sass::string cwd(File::get_cwd());
|
||||
// make path relative to the current directory
|
||||
sass::string stack("An @import loop has been found:");
|
||||
for (size_t n = 1; n < i + 2; ++n) {
|
||||
stack += "\n " + sass::string(File::abs2rel(import_stack[n]->abs_path, cwd, cwd)) +
|
||||
" imports " + sass::string(File::abs2rel(import_stack[n+1]->abs_path, cwd, cwd));
|
||||
}
|
||||
// implement error throw directly until we
|
||||
// decided how to handle full stack traces
|
||||
throw Exception::InvalidSyntax(pstate, traces, stack);
|
||||
// error(stack, prstate ? *prstate : pstate, import_stack);
|
||||
}
|
||||
}
|
||||
|
||||
// create a parser instance from the given c_str buffer
|
||||
Parser p(source, *this, traces);
|
||||
// do not yet dispose these buffers
|
||||
sass_import_take_source(import);
|
||||
sass_import_take_srcmap(import);
|
||||
// then parse the root block
|
||||
Block_Obj root = p.parse();
|
||||
// delete memory of current stack frame
|
||||
sass_delete_import(import_stack.back());
|
||||
// remove current stack frame
|
||||
import_stack.pop_back();
|
||||
// create key/value pair for ast node
|
||||
std::pair<const sass::string, StyleSheet>
|
||||
ast_pair(inc.abs_path, { res, root });
|
||||
// register resulting resource
|
||||
sheets.insert(ast_pair);
|
||||
}
|
||||
|
||||
// register include with resolved path and its content
|
||||
// memory of the resources will be freed by us on exit
|
||||
void Context::register_resource(const Include& inc, const Resource& res, SourceSpan& prstate)
|
||||
{
|
||||
traces.push_back(Backtrace(prstate));
|
||||
register_resource(inc, res);
|
||||
traces.pop_back();
|
||||
}
|
||||
|
||||
// Add a new import to the context (called from `import_url`)
|
||||
Include Context::load_import(const Importer& imp, SourceSpan pstate)
|
||||
{
|
||||
|
||||
// search for valid imports (ie. partials) on the filesystem
|
||||
// this may return more than one valid result (ambiguous imp_path)
|
||||
const sass::vector<Include> resolved(find_includes(imp));
|
||||
|
||||
// error nicely on ambiguous imp_path
|
||||
if (resolved.size() > 1) {
|
||||
sass::ostream msg_stream;
|
||||
msg_stream << "It's not clear which file to import for ";
|
||||
msg_stream << "'@import \"" << imp.imp_path << "\"'." << "\n";
|
||||
msg_stream << "Candidates:" << "\n";
|
||||
for (size_t i = 0, L = resolved.size(); i < L; ++i)
|
||||
{ msg_stream << " " << resolved[i].imp_path << "\n"; }
|
||||
msg_stream << "Please delete or rename all but one of these files." << "\n";
|
||||
error(msg_stream.str(), pstate, traces);
|
||||
}
|
||||
|
||||
// process the resolved entry
|
||||
else if (resolved.size() == 1) {
|
||||
bool use_cache = c_importers.size() == 0;
|
||||
// use cache for the resource loading
|
||||
if (use_cache && sheets.count(resolved[0].abs_path)) return resolved[0];
|
||||
// try to read the content of the resolved file entry
|
||||
// the memory buffer returned must be freed by us!
|
||||
if (char* contents = read_file(resolved[0].abs_path)) {
|
||||
// register the newly resolved file resource
|
||||
register_resource(resolved[0], { contents, 0 }, pstate);
|
||||
// return resolved entry
|
||||
return resolved[0];
|
||||
}
|
||||
}
|
||||
|
||||
// nothing found
|
||||
return { imp, "" };
|
||||
|
||||
}
|
||||
|
||||
void Context::import_url (Import* imp, sass::string load_path, const sass::string& ctx_path) {
|
||||
|
||||
SourceSpan pstate(imp->pstate());
|
||||
sass::string imp_path(unquote(load_path));
|
||||
sass::string protocol("file");
|
||||
|
||||
using namespace Prelexer;
|
||||
if (const char* proto = sequence< identifier, exactly<':'>, exactly<'/'>, exactly<'/'> >(imp_path.c_str())) {
|
||||
|
||||
protocol = sass::string(imp_path.c_str(), proto - 3);
|
||||
// if (protocol.compare("file") && true) { }
|
||||
}
|
||||
|
||||
// add urls (protocol other than file) and urls without protocol to `urls` member
|
||||
// ToDo: if ctx_path is already a file resource, we should not add it here?
|
||||
if (imp->import_queries() || protocol != "file" || imp_path.substr(0, 2) == "//") {
|
||||
imp->urls().push_back(SASS_MEMORY_NEW(String_Quoted, imp->pstate(), load_path));
|
||||
}
|
||||
else if (imp_path.length() > 4 && imp_path.substr(imp_path.length() - 4, 4) == ".css") {
|
||||
String_Constant* loc = SASS_MEMORY_NEW(String_Constant, pstate, unquote(load_path));
|
||||
Argument_Obj loc_arg = SASS_MEMORY_NEW(Argument, pstate, loc);
|
||||
Arguments_Obj loc_args = SASS_MEMORY_NEW(Arguments, pstate);
|
||||
loc_args->append(loc_arg);
|
||||
Function_Call* new_url = SASS_MEMORY_NEW(Function_Call, pstate, sass::string("url"), loc_args);
|
||||
imp->urls().push_back(new_url);
|
||||
}
|
||||
else {
|
||||
const Importer importer(imp_path, ctx_path);
|
||||
Include include(load_import(importer, pstate));
|
||||
if (include.abs_path.empty()) {
|
||||
error("File to import not found or unreadable: " + imp_path + ".", pstate, traces);
|
||||
}
|
||||
imp->incs().push_back(include);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
// call custom importers on the given (unquoted) load_path and eventually parse the resulting style_sheet
|
||||
bool Context::call_loader(const sass::string& load_path, const char* ctx_path, SourceSpan& pstate, Import* imp, sass::vector<Sass_Importer_Entry> importers, bool only_one)
|
||||
{
|
||||
// unique counter
|
||||
size_t count = 0;
|
||||
// need one correct import
|
||||
bool has_import = false;
|
||||
// process all custom importers (or custom headers)
|
||||
for (Sass_Importer_Entry& importer_ent : importers) {
|
||||
// int priority = sass_importer_get_priority(importer);
|
||||
Sass_Importer_Fn fn = sass_importer_get_function(importer_ent);
|
||||
// skip importer if it returns NULL
|
||||
if (Sass_Import_List includes =
|
||||
fn(load_path.c_str(), importer_ent, c_compiler)
|
||||
) {
|
||||
// get c pointer copy to iterate over
|
||||
Sass_Import_List it_includes = includes;
|
||||
while (*it_includes) { ++count;
|
||||
// create unique path to use as key
|
||||
sass::string uniq_path = load_path;
|
||||
if (!only_one && count) {
|
||||
sass::ostream path_strm;
|
||||
path_strm << uniq_path << ":" << count;
|
||||
uniq_path = path_strm.str();
|
||||
}
|
||||
// create the importer struct
|
||||
Importer importer(uniq_path, ctx_path);
|
||||
// query data from the current include
|
||||
Sass_Import_Entry include_ent = *it_includes;
|
||||
char* source = sass_import_take_source(include_ent);
|
||||
char* srcmap = sass_import_take_srcmap(include_ent);
|
||||
size_t line = sass_import_get_error_line(include_ent);
|
||||
size_t column = sass_import_get_error_column(include_ent);
|
||||
const char *abs_path = sass_import_get_abs_path(include_ent);
|
||||
// handle error message passed back from custom importer
|
||||
// it may (or may not) override the line and column info
|
||||
if (const char* err_message = sass_import_get_error_message(include_ent)) {
|
||||
if (source || srcmap) register_resource({ importer, uniq_path }, { source, srcmap }, pstate);
|
||||
if (line == sass::string::npos && column == sass::string::npos) error(err_message, pstate, traces);
|
||||
else { error(err_message, { pstate.source, { line, column } }, traces); }
|
||||
}
|
||||
// content for import was set
|
||||
else if (source) {
|
||||
// resolved abs_path should be set by custom importer
|
||||
// use the created uniq_path as fallback (maybe enforce)
|
||||
sass::string path_key(abs_path ? abs_path : uniq_path);
|
||||
// create the importer struct
|
||||
Include include(importer, path_key);
|
||||
// attach information to AST node
|
||||
imp->incs().push_back(include);
|
||||
// register the resource buffers
|
||||
register_resource(include, { source, srcmap }, pstate);
|
||||
}
|
||||
// only a path was retuned
|
||||
// try to load it like normal
|
||||
else if(abs_path) {
|
||||
// checks some urls to preserve
|
||||
// `http://`, `https://` and `//`
|
||||
// or dispatchs to `import_file`
|
||||
// which will check for a `.css` extension
|
||||
// or resolves the file on the filesystem
|
||||
// added and resolved via `add_file`
|
||||
// finally stores everything on `imp`
|
||||
import_url(imp, abs_path, ctx_path);
|
||||
}
|
||||
// move to next
|
||||
++it_includes;
|
||||
}
|
||||
// deallocate the returned memory
|
||||
sass_delete_import_list(includes);
|
||||
// set success flag
|
||||
has_import = true;
|
||||
// break out of loop
|
||||
if (only_one) break;
|
||||
}
|
||||
}
|
||||
// return result
|
||||
return has_import;
|
||||
}
|
||||
|
||||
void register_function(Context&, Signature sig, Native_Function f, Env* env);
|
||||
void register_function(Context&, Signature sig, Native_Function f, size_t arity, Env* env);
|
||||
void register_overload_stub(Context&, sass::string name, Env* env);
|
||||
void register_built_in_functions(Context&, Env* env);
|
||||
void register_c_functions(Context&, Env* env, Sass_Function_List);
|
||||
void register_c_function(Context&, Env* env, Sass_Function_Entry);
|
||||
|
||||
char* Context::render(Block_Obj root)
|
||||
{
|
||||
// check for valid block
|
||||
if (!root) return 0;
|
||||
// start the render process
|
||||
root->perform(&emitter);
|
||||
// finish emitter stream
|
||||
emitter.finalize();
|
||||
// get the resulting buffer from stream
|
||||
OutputBuffer emitted = emitter.get_buffer();
|
||||
// should we append a source map url?
|
||||
if (!c_options.omit_source_map_url) {
|
||||
// generate an embedded source map
|
||||
if (c_options.source_map_embed) {
|
||||
emitted.buffer += linefeed;
|
||||
emitted.buffer += format_embedded_source_map();
|
||||
}
|
||||
// or just link the generated one
|
||||
else if (source_map_file != "") {
|
||||
emitted.buffer += linefeed;
|
||||
emitted.buffer += format_source_mapping_url(source_map_file);
|
||||
}
|
||||
}
|
||||
// create a copy of the resulting buffer string
|
||||
// this must be freed or taken over by implementor
|
||||
return sass_copy_c_string(emitted.buffer.c_str());
|
||||
}
|
||||
|
||||
void Context::apply_custom_headers(Block_Obj root, const char* ctx_path, SourceSpan pstate)
|
||||
{
|
||||
// create a custom import to resolve headers
|
||||
Import_Obj imp = SASS_MEMORY_NEW(Import, pstate);
|
||||
// dispatch headers which will add custom functions
|
||||
// custom headers are added to the import instance
|
||||
call_headers(entry_path, ctx_path, pstate, imp);
|
||||
// increase head count to skip later
|
||||
head_imports += resources.size() - 1;
|
||||
// add the statement if we have urls
|
||||
if (!imp->urls().empty()) root->append(imp);
|
||||
// process all other resources (add Import_Stub nodes)
|
||||
for (size_t i = 0, S = imp->incs().size(); i < S; ++i) {
|
||||
root->append(SASS_MEMORY_NEW(Import_Stub, pstate, imp->incs()[i]));
|
||||
}
|
||||
}
|
||||
|
||||
Block_Obj File_Context::parse()
|
||||
{
|
||||
|
||||
// check if entry file is given
|
||||
if (input_path.empty()) return {};
|
||||
|
||||
// create absolute path from input filename
|
||||
// ToDo: this should be resolved via custom importers
|
||||
sass::string abs_path(rel2abs(input_path, CWD));
|
||||
|
||||
// try to load the entry file
|
||||
char* contents = read_file(abs_path);
|
||||
|
||||
// alternatively also look inside each include path folder
|
||||
// I think this differs from ruby sass (IMO too late to remove)
|
||||
for (size_t i = 0, S = include_paths.size(); contents == 0 && i < S; ++i) {
|
||||
// build absolute path for this include path entry
|
||||
abs_path = rel2abs(input_path, include_paths[i]);
|
||||
// try to load the resulting path
|
||||
contents = read_file(abs_path);
|
||||
}
|
||||
|
||||
// abort early if no content could be loaded (various reasons)
|
||||
if (!contents) throw std::runtime_error(
|
||||
"File to read not found or unreadable: "
|
||||
+ std::string(input_path.c_str()));
|
||||
|
||||
// store entry path
|
||||
entry_path = abs_path;
|
||||
|
||||
// create entry only for import stack
|
||||
Sass_Import_Entry import = sass_make_import(
|
||||
input_path.c_str(),
|
||||
entry_path.c_str(),
|
||||
contents,
|
||||
0
|
||||
);
|
||||
// add the entry to the stack
|
||||
import_stack.push_back(import);
|
||||
|
||||
// create the source entry for file entry
|
||||
register_resource({{ input_path, "." }, abs_path }, { contents, 0 });
|
||||
|
||||
// create root ast tree node
|
||||
return compile();
|
||||
|
||||
}
|
||||
|
||||
Block_Obj Data_Context::parse()
|
||||
{
|
||||
|
||||
// check if source string is given
|
||||
if (!source_c_str) return {};
|
||||
|
||||
// convert indented sass syntax
|
||||
if(c_options.is_indented_syntax_src) {
|
||||
// call sass2scss to convert the string
|
||||
char * converted = sass2scss(source_c_str,
|
||||
// preserve the structure as much as possible
|
||||
SASS2SCSS_PRETTIFY_1 | SASS2SCSS_KEEP_COMMENT);
|
||||
// replace old source_c_str with converted
|
||||
free(source_c_str); source_c_str = converted;
|
||||
}
|
||||
|
||||
// remember entry path (defaults to stdin for string)
|
||||
entry_path = input_path.empty() ? "stdin" : input_path;
|
||||
|
||||
// ToDo: this may be resolved via custom importers
|
||||
sass::string abs_path(rel2abs(entry_path));
|
||||
char* abs_path_c_str = sass_copy_c_string(abs_path.c_str());
|
||||
strings.push_back(abs_path_c_str);
|
||||
|
||||
// create entry only for the import stack
|
||||
Sass_Import_Entry import = sass_make_import(
|
||||
entry_path.c_str(),
|
||||
abs_path_c_str,
|
||||
source_c_str,
|
||||
srcmap_c_str
|
||||
);
|
||||
// add the entry to the stack
|
||||
import_stack.push_back(import);
|
||||
|
||||
// register a synthetic resource (path does not really exist, skip in includes)
|
||||
register_resource({{ input_path, "." }, input_path }, { source_c_str, srcmap_c_str });
|
||||
|
||||
// create root ast tree node
|
||||
return compile();
|
||||
}
|
||||
|
||||
// parse root block from includes
|
||||
Block_Obj Context::compile()
|
||||
{
|
||||
// abort if there is no data
|
||||
if (resources.size() == 0) return {};
|
||||
// get root block from the first style sheet
|
||||
Block_Obj root = sheets.at(entry_path).root;
|
||||
// abort on invalid root
|
||||
if (root.isNull()) return {};
|
||||
Env global; // create root environment
|
||||
// register built-in functions on env
|
||||
register_built_in_functions(*this, &global);
|
||||
// register custom functions (defined via C-API)
|
||||
for (size_t i = 0, S = c_functions.size(); i < S; ++i)
|
||||
{ register_c_function(*this, &global, c_functions[i]); }
|
||||
// create initial backtrace entry
|
||||
// create crtp visitor objects
|
||||
Expand expand(*this, &global);
|
||||
Cssize cssize(*this);
|
||||
CheckNesting check_nesting;
|
||||
// check nesting in all files
|
||||
for (auto sheet : sheets) {
|
||||
auto styles = sheet.second;
|
||||
check_nesting(styles.root);
|
||||
}
|
||||
// expand and eval the tree
|
||||
root = expand(root);
|
||||
|
||||
Extension unsatisfied;
|
||||
// check that all extends were used
|
||||
if (extender.checkForUnsatisfiedExtends(unsatisfied)) {
|
||||
throw Exception::UnsatisfiedExtend(traces, unsatisfied);
|
||||
}
|
||||
|
||||
// check nesting
|
||||
check_nesting(root);
|
||||
// merge and bubble certain rules
|
||||
root = cssize(root);
|
||||
|
||||
// clean up by removing empty placeholders
|
||||
// ToDo: maybe we can do this somewhere else?
|
||||
Remove_Placeholders remove_placeholders;
|
||||
root->perform(&remove_placeholders);
|
||||
|
||||
// return processed tree
|
||||
return root;
|
||||
}
|
||||
// EO compile
|
||||
|
||||
sass::string Context::format_embedded_source_map()
|
||||
{
|
||||
sass::string map = emitter.render_srcmap(*this);
|
||||
sass::istream is( map.c_str() );
|
||||
sass::ostream buffer;
|
||||
base64::encoder E;
|
||||
E.encode(is, buffer);
|
||||
sass::string url = "data:application/json;base64," + buffer.str();
|
||||
url.erase(url.size() - 1);
|
||||
return "/*# sourceMappingURL=" + url + " */";
|
||||
}
|
||||
|
||||
sass::string Context::format_source_mapping_url(const sass::string& file)
|
||||
{
|
||||
sass::string url = abs2rel(file, output_path, CWD);
|
||||
return "/*# sourceMappingURL=" + url + " */";
|
||||
}
|
||||
|
||||
char* Context::render_srcmap()
|
||||
{
|
||||
if (source_map_file == "") return 0;
|
||||
sass::string map = emitter.render_srcmap(*this);
|
||||
return sass_copy_c_string(map.c_str());
|
||||
}
|
||||
|
||||
|
||||
// for data context we want to start after "stdin"
|
||||
// we probably always want to skip the header includes?
|
||||
sass::vector<sass::string> Context::get_included_files(bool skip, size_t headers)
|
||||
{
|
||||
// create a copy of the vector for manipulations
|
||||
sass::vector<sass::string> includes = included_files;
|
||||
if (includes.size() == 0) return includes;
|
||||
if (skip) { includes.erase( includes.begin(), includes.begin() + 1 + headers); }
|
||||
else { includes.erase( includes.begin() + 1, includes.begin() + 1 + headers); }
|
||||
includes.erase( std::unique( includes.begin(), includes.end() ), includes.end() );
|
||||
std::sort( includes.begin() + (skip ? 0 : 1), includes.end() );
|
||||
return includes;
|
||||
}
|
||||
|
||||
void register_function(Context& ctx, Signature sig, Native_Function f, Env* env)
|
||||
{
|
||||
Definition* def = make_native_function(sig, f, ctx);
|
||||
def->environment(env);
|
||||
(*env)[def->name() + "[f]"] = def;
|
||||
}
|
||||
|
||||
void register_function(Context& ctx, Signature sig, Native_Function f, size_t arity, Env* env)
|
||||
{
|
||||
Definition* def = make_native_function(sig, f, ctx);
|
||||
sass::ostream ss;
|
||||
ss << def->name() << "[f]" << arity;
|
||||
def->environment(env);
|
||||
(*env)[ss.str()] = def;
|
||||
}
|
||||
|
||||
void register_overload_stub(Context& ctx, sass::string name, Env* env)
|
||||
{
|
||||
Definition* stub = SASS_MEMORY_NEW(Definition,
|
||||
SourceSpan{ "[built-in function]" },
|
||||
nullptr,
|
||||
name,
|
||||
Parameters_Obj{},
|
||||
nullptr,
|
||||
true);
|
||||
(*env)[name + "[f]"] = stub;
|
||||
}
|
||||
|
||||
|
||||
void register_built_in_functions(Context& ctx, Env* env)
|
||||
{
|
||||
using namespace Functions;
|
||||
// RGB Functions
|
||||
register_function(ctx, rgb_sig, rgb, env);
|
||||
register_overload_stub(ctx, "rgba", env);
|
||||
register_function(ctx, rgba_4_sig, rgba_4, 4, env);
|
||||
register_function(ctx, rgba_2_sig, rgba_2, 2, env);
|
||||
register_function(ctx, red_sig, red, env);
|
||||
register_function(ctx, green_sig, green, env);
|
||||
register_function(ctx, blue_sig, blue, env);
|
||||
register_function(ctx, mix_sig, mix, env);
|
||||
// HSL Functions
|
||||
register_function(ctx, hsl_sig, hsl, env);
|
||||
register_function(ctx, hsla_sig, hsla, env);
|
||||
register_function(ctx, hue_sig, hue, env);
|
||||
register_function(ctx, saturation_sig, saturation, env);
|
||||
register_function(ctx, lightness_sig, lightness, env);
|
||||
register_function(ctx, adjust_hue_sig, adjust_hue, env);
|
||||
register_function(ctx, lighten_sig, lighten, env);
|
||||
register_function(ctx, darken_sig, darken, env);
|
||||
register_function(ctx, saturate_sig, saturate, env);
|
||||
register_function(ctx, desaturate_sig, desaturate, env);
|
||||
register_function(ctx, grayscale_sig, grayscale, env);
|
||||
register_function(ctx, complement_sig, complement, env);
|
||||
register_function(ctx, invert_sig, invert, env);
|
||||
// Opacity Functions
|
||||
register_function(ctx, alpha_sig, alpha, env);
|
||||
register_function(ctx, opacity_sig, alpha, env);
|
||||
register_function(ctx, opacify_sig, opacify, env);
|
||||
register_function(ctx, fade_in_sig, opacify, env);
|
||||
register_function(ctx, transparentize_sig, transparentize, env);
|
||||
register_function(ctx, fade_out_sig, transparentize, env);
|
||||
// Other Color Functions
|
||||
register_function(ctx, adjust_color_sig, adjust_color, env);
|
||||
register_function(ctx, scale_color_sig, scale_color, env);
|
||||
register_function(ctx, change_color_sig, change_color, env);
|
||||
register_function(ctx, ie_hex_str_sig, ie_hex_str, env);
|
||||
// String Functions
|
||||
register_function(ctx, unquote_sig, sass_unquote, env);
|
||||
register_function(ctx, quote_sig, sass_quote, env);
|
||||
register_function(ctx, str_length_sig, str_length, env);
|
||||
register_function(ctx, str_insert_sig, str_insert, env);
|
||||
register_function(ctx, str_index_sig, str_index, env);
|
||||
register_function(ctx, str_slice_sig, str_slice, env);
|
||||
register_function(ctx, to_upper_case_sig, to_upper_case, env);
|
||||
register_function(ctx, to_lower_case_sig, to_lower_case, env);
|
||||
// Number Functions
|
||||
register_function(ctx, percentage_sig, percentage, env);
|
||||
register_function(ctx, round_sig, round, env);
|
||||
register_function(ctx, ceil_sig, ceil, env);
|
||||
register_function(ctx, floor_sig, floor, env);
|
||||
register_function(ctx, abs_sig, abs, env);
|
||||
register_function(ctx, min_sig, min, env);
|
||||
register_function(ctx, max_sig, max, env);
|
||||
register_function(ctx, random_sig, random, env);
|
||||
// List Functions
|
||||
register_function(ctx, length_sig, length, env);
|
||||
register_function(ctx, nth_sig, nth, env);
|
||||
register_function(ctx, set_nth_sig, set_nth, env);
|
||||
register_function(ctx, index_sig, index, env);
|
||||
register_function(ctx, join_sig, join, env);
|
||||
register_function(ctx, append_sig, append, env);
|
||||
register_function(ctx, zip_sig, zip, env);
|
||||
register_function(ctx, list_separator_sig, list_separator, env);
|
||||
register_function(ctx, is_bracketed_sig, is_bracketed, env);
|
||||
// Map Functions
|
||||
register_function(ctx, map_get_sig, map_get, env);
|
||||
register_function(ctx, map_merge_sig, map_merge, env);
|
||||
register_function(ctx, map_remove_sig, map_remove, env);
|
||||
register_function(ctx, map_keys_sig, map_keys, env);
|
||||
register_function(ctx, map_values_sig, map_values, env);
|
||||
register_function(ctx, map_has_key_sig, map_has_key, env);
|
||||
register_function(ctx, keywords_sig, keywords, env);
|
||||
// Introspection Functions
|
||||
register_function(ctx, type_of_sig, type_of, env);
|
||||
register_function(ctx, unit_sig, unit, env);
|
||||
register_function(ctx, unitless_sig, unitless, env);
|
||||
register_function(ctx, comparable_sig, comparable, env);
|
||||
register_function(ctx, variable_exists_sig, variable_exists, env);
|
||||
register_function(ctx, global_variable_exists_sig, global_variable_exists, env);
|
||||
register_function(ctx, function_exists_sig, function_exists, env);
|
||||
register_function(ctx, mixin_exists_sig, mixin_exists, env);
|
||||
register_function(ctx, feature_exists_sig, feature_exists, env);
|
||||
register_function(ctx, call_sig, call, env);
|
||||
register_function(ctx, content_exists_sig, content_exists, env);
|
||||
register_function(ctx, get_function_sig, get_function, env);
|
||||
// Boolean Functions
|
||||
register_function(ctx, not_sig, sass_not, env);
|
||||
register_function(ctx, if_sig, sass_if, env);
|
||||
// Misc Functions
|
||||
register_function(ctx, inspect_sig, inspect, env);
|
||||
register_function(ctx, unique_id_sig, unique_id, env);
|
||||
// Selector functions
|
||||
register_function(ctx, selector_nest_sig, selector_nest, env);
|
||||
register_function(ctx, selector_append_sig, selector_append, env);
|
||||
register_function(ctx, selector_extend_sig, selector_extend, env);
|
||||
register_function(ctx, selector_replace_sig, selector_replace, env);
|
||||
register_function(ctx, selector_unify_sig, selector_unify, env);
|
||||
register_function(ctx, is_superselector_sig, is_superselector, env);
|
||||
register_function(ctx, simple_selectors_sig, simple_selectors, env);
|
||||
register_function(ctx, selector_parse_sig, selector_parse, env);
|
||||
}
|
||||
|
||||
void register_c_functions(Context& ctx, Env* env, Sass_Function_List descrs)
|
||||
{
|
||||
while (descrs && *descrs) {
|
||||
register_c_function(ctx, env, *descrs);
|
||||
++descrs;
|
||||
}
|
||||
}
|
||||
void register_c_function(Context& ctx, Env* env, Sass_Function_Entry descr)
|
||||
{
|
||||
Definition* def = make_c_function(descr, ctx);
|
||||
def->environment(env);
|
||||
(*env)[def->name() + "[f]"] = def;
|
||||
}
|
||||
|
||||
}
|
||||
140
vendor/bundle/ruby/2.6.0/gems/sassc-2.4.0/ext/libsass/src/context.hpp
vendored
Normal file
140
vendor/bundle/ruby/2.6.0/gems/sassc-2.4.0/ext/libsass/src/context.hpp
vendored
Normal file
@@ -0,0 +1,140 @@
|
||||
#ifndef SASS_CONTEXT_H
|
||||
#define SASS_CONTEXT_H
|
||||
|
||||
// sass.hpp must go before all system headers to get the
|
||||
// __EXTENSIONS__ fix on Solaris.
|
||||
#include "sass.hpp"
|
||||
#include "ast.hpp"
|
||||
|
||||
|
||||
#define BUFFERSIZE 255
|
||||
#include "b64/encode.h"
|
||||
|
||||
#include "sass_context.hpp"
|
||||
#include "stylesheet.hpp"
|
||||
#include "plugins.hpp"
|
||||
#include "output.hpp"
|
||||
|
||||
namespace Sass {
|
||||
|
||||
class Context {
|
||||
public:
|
||||
void import_url (Import* imp, sass::string load_path, const sass::string& ctx_path);
|
||||
bool call_headers(const sass::string& load_path, const char* ctx_path, SourceSpan& pstate, Import* imp)
|
||||
{ return call_loader(load_path, ctx_path, pstate, imp, c_headers, false); };
|
||||
bool call_importers(const sass::string& load_path, const char* ctx_path, SourceSpan& pstate, Import* imp)
|
||||
{ return call_loader(load_path, ctx_path, pstate, imp, c_importers, true); };
|
||||
|
||||
private:
|
||||
bool call_loader(const sass::string& load_path, const char* ctx_path, SourceSpan& pstate, Import* imp, sass::vector<Sass_Importer_Entry> importers, bool only_one = true);
|
||||
|
||||
public:
|
||||
const sass::string CWD;
|
||||
struct Sass_Options& c_options;
|
||||
sass::string entry_path;
|
||||
size_t head_imports;
|
||||
Plugins plugins;
|
||||
Output emitter;
|
||||
|
||||
// generic ast node garbage container
|
||||
// used to avoid possible circular refs
|
||||
CallStack ast_gc;
|
||||
// resources add under our control
|
||||
// these are guaranteed to be freed
|
||||
sass::vector<char*> strings;
|
||||
sass::vector<Resource> resources;
|
||||
std::map<const sass::string, StyleSheet> sheets;
|
||||
ImporterStack import_stack;
|
||||
sass::vector<Sass_Callee> callee_stack;
|
||||
sass::vector<Backtrace> traces;
|
||||
Extender extender;
|
||||
|
||||
struct Sass_Compiler* c_compiler;
|
||||
|
||||
// absolute paths to includes
|
||||
sass::vector<sass::string> included_files;
|
||||
// relative includes for sourcemap
|
||||
sass::vector<sass::string> srcmap_links;
|
||||
// vectors above have same size
|
||||
|
||||
sass::vector<sass::string> plugin_paths; // relative paths to load plugins
|
||||
sass::vector<sass::string> include_paths; // lookup paths for includes
|
||||
|
||||
void apply_custom_headers(Block_Obj root, const char* path, SourceSpan pstate);
|
||||
|
||||
sass::vector<Sass_Importer_Entry> c_headers;
|
||||
sass::vector<Sass_Importer_Entry> c_importers;
|
||||
sass::vector<Sass_Function_Entry> c_functions;
|
||||
|
||||
void add_c_header(Sass_Importer_Entry header);
|
||||
void add_c_importer(Sass_Importer_Entry importer);
|
||||
void add_c_function(Sass_Function_Entry function);
|
||||
|
||||
const sass::string indent; // String to be used for indentation
|
||||
const sass::string linefeed; // String to be used for line feeds
|
||||
const sass::string input_path; // for relative paths in src-map
|
||||
const sass::string output_path; // for relative paths to the output
|
||||
const sass::string source_map_file; // path to source map file (enables feature)
|
||||
const sass::string source_map_root; // path for sourceRoot property (pass-through)
|
||||
|
||||
virtual ~Context();
|
||||
Context(struct Sass_Context&);
|
||||
virtual Block_Obj parse() = 0;
|
||||
virtual Block_Obj compile();
|
||||
virtual char* render(Block_Obj root);
|
||||
virtual char* render_srcmap();
|
||||
|
||||
void register_resource(const Include&, const Resource&);
|
||||
void register_resource(const Include&, const Resource&, SourceSpan&);
|
||||
sass::vector<Include> find_includes(const Importer& import);
|
||||
Include load_import(const Importer&, SourceSpan pstate);
|
||||
|
||||
Sass_Output_Style output_style() { return c_options.output_style; };
|
||||
sass::vector<sass::string> get_included_files(bool skip = false, size_t headers = 0);
|
||||
|
||||
private:
|
||||
void collect_plugin_paths(const char* paths_str);
|
||||
void collect_plugin_paths(string_list* paths_array);
|
||||
void collect_include_paths(const char* paths_str);
|
||||
void collect_include_paths(string_list* paths_array);
|
||||
sass::string format_embedded_source_map();
|
||||
sass::string format_source_mapping_url(const sass::string& out_path);
|
||||
|
||||
|
||||
// void register_built_in_functions(Env* env);
|
||||
// void register_function(Signature sig, Native_Function f, Env* env);
|
||||
// void register_function(Signature sig, Native_Function f, size_t arity, Env* env);
|
||||
// void register_overload_stub(sass::string name, Env* env);
|
||||
|
||||
public:
|
||||
const sass::string& cwd() { return CWD; };
|
||||
};
|
||||
|
||||
class File_Context : public Context {
|
||||
public:
|
||||
File_Context(struct Sass_File_Context& ctx)
|
||||
: Context(ctx)
|
||||
{ }
|
||||
virtual ~File_Context();
|
||||
virtual Block_Obj parse();
|
||||
};
|
||||
|
||||
class Data_Context : public Context {
|
||||
public:
|
||||
char* source_c_str;
|
||||
char* srcmap_c_str;
|
||||
Data_Context(struct Sass_Data_Context& ctx)
|
||||
: Context(ctx)
|
||||
{
|
||||
source_c_str = ctx.source_string;
|
||||
srcmap_c_str = ctx.srcmap_string;
|
||||
ctx.source_string = 0; // passed away
|
||||
ctx.srcmap_string = 0; // passed away
|
||||
}
|
||||
virtual ~Data_Context();
|
||||
virtual Block_Obj parse();
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
521
vendor/bundle/ruby/2.6.0/gems/sassc-2.4.0/ext/libsass/src/cssize.cpp
vendored
Normal file
521
vendor/bundle/ruby/2.6.0/gems/sassc-2.4.0/ext/libsass/src/cssize.cpp
vendored
Normal file
@@ -0,0 +1,521 @@
|
||||
// sass.hpp must go before all system headers to get the
|
||||
// __EXTENSIONS__ fix on Solaris.
|
||||
#include "sass.hpp"
|
||||
|
||||
#include <iostream>
|
||||
#include <typeinfo>
|
||||
#include <vector>
|
||||
|
||||
#include "cssize.hpp"
|
||||
#include "context.hpp"
|
||||
|
||||
namespace Sass {
|
||||
|
||||
Cssize::Cssize(Context& ctx)
|
||||
: traces(ctx.traces),
|
||||
block_stack(BlockStack()),
|
||||
p_stack(sass::vector<Statement*>())
|
||||
{ }
|
||||
|
||||
Statement* Cssize::parent()
|
||||
{
|
||||
return p_stack.size() ? p_stack.back() : block_stack.front();
|
||||
}
|
||||
|
||||
Block* Cssize::operator()(Block* b)
|
||||
{
|
||||
Block_Obj bb = SASS_MEMORY_NEW(Block, b->pstate(), b->length(), b->is_root());
|
||||
// bb->tabs(b->tabs());
|
||||
block_stack.push_back(bb);
|
||||
append_block(b, bb);
|
||||
block_stack.pop_back();
|
||||
return bb.detach();
|
||||
}
|
||||
|
||||
Statement* Cssize::operator()(Trace* t)
|
||||
{
|
||||
traces.push_back(Backtrace(t->pstate()));
|
||||
auto result = t->block()->perform(this);
|
||||
traces.pop_back();
|
||||
return result;
|
||||
}
|
||||
|
||||
Statement* Cssize::operator()(Declaration* d)
|
||||
{
|
||||
String_Obj property = Cast<String>(d->property());
|
||||
|
||||
if (Declaration* dd = Cast<Declaration>(parent())) {
|
||||
String_Obj parent_property = Cast<String>(dd->property());
|
||||
property = SASS_MEMORY_NEW(String_Constant,
|
||||
d->property()->pstate(),
|
||||
parent_property->to_string() + "-" + property->to_string());
|
||||
if (!dd->value()) {
|
||||
d->tabs(dd->tabs() + 1);
|
||||
}
|
||||
}
|
||||
|
||||
Declaration_Obj dd = SASS_MEMORY_NEW(Declaration,
|
||||
d->pstate(),
|
||||
property,
|
||||
d->value(),
|
||||
d->is_important(),
|
||||
d->is_custom_property());
|
||||
dd->is_indented(d->is_indented());
|
||||
dd->tabs(d->tabs());
|
||||
|
||||
p_stack.push_back(dd);
|
||||
Block_Obj bb = d->block() ? operator()(d->block()) : NULL;
|
||||
p_stack.pop_back();
|
||||
|
||||
if (bb && bb->length()) {
|
||||
if (dd->value() && !dd->value()->is_invisible()) {
|
||||
bb->unshift(dd);
|
||||
}
|
||||
return bb.detach();
|
||||
}
|
||||
else if (dd->value() && !dd->value()->is_invisible()) {
|
||||
return dd.detach();
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
Statement* Cssize::operator()(AtRule* r)
|
||||
{
|
||||
if (!r->block() || !r->block()->length()) return r;
|
||||
|
||||
if (parent()->statement_type() == Statement::RULESET)
|
||||
{
|
||||
return r->is_keyframes() ? SASS_MEMORY_NEW(Bubble, r->pstate(), r) : bubble(r);
|
||||
}
|
||||
|
||||
p_stack.push_back(r);
|
||||
AtRuleObj rr = SASS_MEMORY_NEW(AtRule,
|
||||
r->pstate(),
|
||||
r->keyword(),
|
||||
r->selector(),
|
||||
r->block() ? operator()(r->block()) : 0);
|
||||
if (r->value()) rr->value(r->value());
|
||||
p_stack.pop_back();
|
||||
|
||||
bool directive_exists = false;
|
||||
size_t L = rr->block() ? rr->block()->length() : 0;
|
||||
for (size_t i = 0; i < L && !directive_exists; ++i) {
|
||||
Statement_Obj s = r->block()->at(i);
|
||||
if (s->statement_type() != Statement::BUBBLE) directive_exists = true;
|
||||
else {
|
||||
Bubble_Obj s_obj = Cast<Bubble>(s);
|
||||
s = s_obj->node();
|
||||
if (s->statement_type() != Statement::DIRECTIVE) directive_exists = false;
|
||||
else directive_exists = (Cast<AtRule>(s)->keyword() == rr->keyword());
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
Block* result = SASS_MEMORY_NEW(Block, rr->pstate());
|
||||
if (!(directive_exists || rr->is_keyframes()))
|
||||
{
|
||||
AtRule* empty_node = Cast<AtRule>(rr);
|
||||
empty_node->block(SASS_MEMORY_NEW(Block, rr->block() ? rr->block()->pstate() : rr->pstate()));
|
||||
result->append(empty_node);
|
||||
}
|
||||
|
||||
Block_Obj db = rr->block();
|
||||
if (db.isNull()) db = SASS_MEMORY_NEW(Block, rr->pstate());
|
||||
Block_Obj ss = debubble(db, rr);
|
||||
for (size_t i = 0, L = ss->length(); i < L; ++i) {
|
||||
result->append(ss->at(i));
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
Statement* Cssize::operator()(Keyframe_Rule* r)
|
||||
{
|
||||
if (!r->block() || !r->block()->length()) return r;
|
||||
|
||||
Keyframe_Rule_Obj rr = SASS_MEMORY_NEW(Keyframe_Rule,
|
||||
r->pstate(),
|
||||
operator()(r->block()));
|
||||
if (!r->name().isNull()) rr->name(r->name());
|
||||
|
||||
return debubble(rr->block(), rr);
|
||||
}
|
||||
|
||||
Statement* Cssize::operator()(StyleRule* r)
|
||||
{
|
||||
p_stack.push_back(r);
|
||||
// this can return a string schema
|
||||
// string schema is not a statement!
|
||||
// r->block() is already a string schema
|
||||
// and that is coming from propset expand
|
||||
Block* bb = operator()(r->block());
|
||||
// this should protect us (at least a bit) from our mess
|
||||
// fixing this properly is harder that it should be ...
|
||||
if (Cast<Statement>(bb) == NULL) {
|
||||
error("Illegal nesting: Only properties may be nested beneath properties.", r->block()->pstate(), traces);
|
||||
}
|
||||
StyleRuleObj rr = SASS_MEMORY_NEW(StyleRule,
|
||||
r->pstate(),
|
||||
r->selector(),
|
||||
bb);
|
||||
|
||||
rr->is_root(r->is_root());
|
||||
// rr->tabs(r->block()->tabs());
|
||||
p_stack.pop_back();
|
||||
|
||||
if (!rr->block()) {
|
||||
error("Illegal nesting: Only properties may be nested beneath properties.", r->block()->pstate(), traces);
|
||||
}
|
||||
|
||||
Block_Obj props = SASS_MEMORY_NEW(Block, rr->block()->pstate());
|
||||
Block* rules = SASS_MEMORY_NEW(Block, rr->block()->pstate());
|
||||
for (size_t i = 0, L = rr->block()->length(); i < L; i++)
|
||||
{
|
||||
Statement* s = rr->block()->at(i);
|
||||
if (bubblable(s)) rules->append(s);
|
||||
if (!bubblable(s)) props->append(s);
|
||||
}
|
||||
|
||||
if (props->length())
|
||||
{
|
||||
Block_Obj pb = SASS_MEMORY_NEW(Block, rr->block()->pstate());
|
||||
pb->concat(props);
|
||||
rr->block(pb);
|
||||
|
||||
for (size_t i = 0, L = rules->length(); i < L; i++)
|
||||
{
|
||||
Statement* stm = rules->at(i);
|
||||
stm->tabs(stm->tabs() + 1);
|
||||
}
|
||||
|
||||
rules->unshift(rr);
|
||||
}
|
||||
|
||||
Block* ptr = rules;
|
||||
rules = debubble(rules);
|
||||
void* lp = ptr;
|
||||
void* rp = rules;
|
||||
if (lp != rp) {
|
||||
Block_Obj obj = ptr;
|
||||
}
|
||||
|
||||
if (!(!rules->length() ||
|
||||
!bubblable(rules->last()) ||
|
||||
parent()->statement_type() == Statement::RULESET))
|
||||
{
|
||||
rules->last()->group_end(true);
|
||||
}
|
||||
return rules;
|
||||
}
|
||||
|
||||
Statement* Cssize::operator()(Null* m)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
Statement* Cssize::operator()(CssMediaRule* m)
|
||||
{
|
||||
if (parent()->statement_type() == Statement::RULESET)
|
||||
{
|
||||
return bubble(m);
|
||||
}
|
||||
|
||||
if (parent()->statement_type() == Statement::MEDIA)
|
||||
{
|
||||
return SASS_MEMORY_NEW(Bubble, m->pstate(), m);
|
||||
}
|
||||
|
||||
p_stack.push_back(m);
|
||||
|
||||
CssMediaRuleObj mm = SASS_MEMORY_NEW(CssMediaRule, m->pstate(), m->block());
|
||||
mm->concat(m->elements());
|
||||
mm->block(operator()(m->block()));
|
||||
mm->tabs(m->tabs());
|
||||
|
||||
p_stack.pop_back();
|
||||
|
||||
return debubble(mm->block(), mm);
|
||||
}
|
||||
|
||||
Statement* Cssize::operator()(SupportsRule* m)
|
||||
{
|
||||
if (!m->block()->length())
|
||||
{ return m; }
|
||||
|
||||
if (parent()->statement_type() == Statement::RULESET)
|
||||
{ return bubble(m); }
|
||||
|
||||
p_stack.push_back(m);
|
||||
|
||||
SupportsRuleObj mm = SASS_MEMORY_NEW(SupportsRule,
|
||||
m->pstate(),
|
||||
m->condition(),
|
||||
operator()(m->block()));
|
||||
mm->tabs(m->tabs());
|
||||
|
||||
p_stack.pop_back();
|
||||
|
||||
return debubble(mm->block(), mm);
|
||||
}
|
||||
|
||||
Statement* Cssize::operator()(AtRootRule* m)
|
||||
{
|
||||
bool tmp = false;
|
||||
for (size_t i = 0, L = p_stack.size(); i < L; ++i) {
|
||||
Statement* s = p_stack[i];
|
||||
tmp |= m->exclude_node(s);
|
||||
}
|
||||
|
||||
if (!tmp && m->block())
|
||||
{
|
||||
Block* bb = operator()(m->block());
|
||||
for (size_t i = 0, L = bb->length(); i < L; ++i) {
|
||||
// (bb->elements())[i]->tabs(m->tabs());
|
||||
Statement_Obj stm = bb->at(i);
|
||||
if (bubblable(stm)) stm->tabs(stm->tabs() + m->tabs());
|
||||
}
|
||||
if (bb->length() && bubblable(bb->last())) bb->last()->group_end(m->group_end());
|
||||
return bb;
|
||||
}
|
||||
|
||||
if (m->exclude_node(parent()))
|
||||
{
|
||||
return SASS_MEMORY_NEW(Bubble, m->pstate(), m);
|
||||
}
|
||||
|
||||
return bubble(m);
|
||||
}
|
||||
|
||||
Statement* Cssize::bubble(AtRule* m)
|
||||
{
|
||||
Block* bb = SASS_MEMORY_NEW(Block, this->parent()->pstate());
|
||||
ParentStatementObj new_rule = Cast<ParentStatement>(SASS_MEMORY_COPY(this->parent()));
|
||||
new_rule->block(bb);
|
||||
new_rule->tabs(this->parent()->tabs());
|
||||
new_rule->block()->concat(m->block());
|
||||
|
||||
Block_Obj wrapper_block = SASS_MEMORY_NEW(Block, m->block() ? m->block()->pstate() : m->pstate());
|
||||
wrapper_block->append(new_rule);
|
||||
AtRuleObj mm = SASS_MEMORY_NEW(AtRule,
|
||||
m->pstate(),
|
||||
m->keyword(),
|
||||
m->selector(),
|
||||
wrapper_block);
|
||||
if (m->value()) mm->value(m->value());
|
||||
|
||||
Bubble* bubble = SASS_MEMORY_NEW(Bubble, mm->pstate(), mm);
|
||||
return bubble;
|
||||
}
|
||||
|
||||
Statement* Cssize::bubble(AtRootRule* m)
|
||||
{
|
||||
if (!m || !m->block()) return NULL;
|
||||
Block* bb = SASS_MEMORY_NEW(Block, this->parent()->pstate());
|
||||
ParentStatementObj new_rule = Cast<ParentStatement>(SASS_MEMORY_COPY(this->parent()));
|
||||
Block* wrapper_block = SASS_MEMORY_NEW(Block, m->block()->pstate());
|
||||
if (new_rule) {
|
||||
new_rule->block(bb);
|
||||
new_rule->tabs(this->parent()->tabs());
|
||||
new_rule->block()->concat(m->block());
|
||||
wrapper_block->append(new_rule);
|
||||
}
|
||||
|
||||
AtRootRule* mm = SASS_MEMORY_NEW(AtRootRule,
|
||||
m->pstate(),
|
||||
wrapper_block,
|
||||
m->expression());
|
||||
Bubble* bubble = SASS_MEMORY_NEW(Bubble, mm->pstate(), mm);
|
||||
return bubble;
|
||||
}
|
||||
|
||||
Statement* Cssize::bubble(SupportsRule* m)
|
||||
{
|
||||
StyleRuleObj parent = Cast<StyleRule>(SASS_MEMORY_COPY(this->parent()));
|
||||
|
||||
Block* bb = SASS_MEMORY_NEW(Block, parent->block()->pstate());
|
||||
StyleRule* new_rule = SASS_MEMORY_NEW(StyleRule,
|
||||
parent->pstate(),
|
||||
parent->selector(),
|
||||
bb);
|
||||
new_rule->tabs(parent->tabs());
|
||||
new_rule->block()->concat(m->block());
|
||||
|
||||
Block* wrapper_block = SASS_MEMORY_NEW(Block, m->block()->pstate());
|
||||
wrapper_block->append(new_rule);
|
||||
SupportsRule* mm = SASS_MEMORY_NEW(SupportsRule,
|
||||
m->pstate(),
|
||||
m->condition(),
|
||||
wrapper_block);
|
||||
|
||||
mm->tabs(m->tabs());
|
||||
|
||||
Bubble* bubble = SASS_MEMORY_NEW(Bubble, mm->pstate(), mm);
|
||||
return bubble;
|
||||
}
|
||||
|
||||
Statement* Cssize::bubble(CssMediaRule* m)
|
||||
{
|
||||
StyleRuleObj parent = Cast<StyleRule>(SASS_MEMORY_COPY(this->parent()));
|
||||
|
||||
Block* bb = SASS_MEMORY_NEW(Block, parent->block()->pstate());
|
||||
StyleRule* new_rule = SASS_MEMORY_NEW(StyleRule,
|
||||
parent->pstate(),
|
||||
parent->selector(),
|
||||
bb);
|
||||
new_rule->tabs(parent->tabs());
|
||||
new_rule->block()->concat(m->block());
|
||||
|
||||
Block* wrapper_block = SASS_MEMORY_NEW(Block, m->block()->pstate());
|
||||
wrapper_block->append(new_rule);
|
||||
CssMediaRuleObj mm = SASS_MEMORY_NEW(CssMediaRule,
|
||||
m->pstate(),
|
||||
wrapper_block);
|
||||
mm->concat(m->elements());
|
||||
|
||||
mm->tabs(m->tabs());
|
||||
|
||||
return SASS_MEMORY_NEW(Bubble, mm->pstate(), mm);
|
||||
}
|
||||
|
||||
bool Cssize::bubblable(Statement* s)
|
||||
{
|
||||
return Cast<StyleRule>(s) || (s && s->bubbles());
|
||||
}
|
||||
|
||||
Block* Cssize::flatten(const Block* b)
|
||||
{
|
||||
Block* result = SASS_MEMORY_NEW(Block, b->pstate(), 0, b->is_root());
|
||||
for (size_t i = 0, L = b->length(); i < L; ++i) {
|
||||
Statement* ss = b->at(i);
|
||||
if (const Block* bb = Cast<Block>(ss)) {
|
||||
Block_Obj bs = flatten(bb);
|
||||
for (size_t j = 0, K = bs->length(); j < K; ++j) {
|
||||
result->append(bs->at(j));
|
||||
}
|
||||
}
|
||||
else {
|
||||
result->append(ss);
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
sass::vector<std::pair<bool, Block_Obj>> Cssize::slice_by_bubble(Block* b)
|
||||
{
|
||||
sass::vector<std::pair<bool, Block_Obj>> results;
|
||||
|
||||
for (size_t i = 0, L = b->length(); i < L; ++i) {
|
||||
Statement_Obj value = b->at(i);
|
||||
bool key = Cast<Bubble>(value) != NULL;
|
||||
|
||||
if (!results.empty() && results.back().first == key)
|
||||
{
|
||||
Block_Obj wrapper_block = results.back().second;
|
||||
wrapper_block->append(value);
|
||||
}
|
||||
else
|
||||
{
|
||||
Block* wrapper_block = SASS_MEMORY_NEW(Block, value->pstate());
|
||||
wrapper_block->append(value);
|
||||
results.push_back(std::make_pair(key, wrapper_block));
|
||||
}
|
||||
}
|
||||
return results;
|
||||
}
|
||||
|
||||
Block* Cssize::debubble(Block* children, Statement* parent)
|
||||
{
|
||||
ParentStatementObj previous_parent;
|
||||
sass::vector<std::pair<bool, Block_Obj>> baz = slice_by_bubble(children);
|
||||
Block_Obj result = SASS_MEMORY_NEW(Block, children->pstate());
|
||||
|
||||
for (size_t i = 0, L = baz.size(); i < L; ++i) {
|
||||
bool is_bubble = baz[i].first;
|
||||
Block_Obj slice = baz[i].second;
|
||||
|
||||
if (!is_bubble) {
|
||||
if (!parent) {
|
||||
result->append(slice);
|
||||
}
|
||||
else if (previous_parent) {
|
||||
previous_parent->block()->concat(slice);
|
||||
}
|
||||
else {
|
||||
previous_parent = SASS_MEMORY_COPY(parent);
|
||||
previous_parent->block(slice);
|
||||
previous_parent->tabs(parent->tabs());
|
||||
|
||||
result->append(previous_parent);
|
||||
}
|
||||
continue;
|
||||
}
|
||||
|
||||
for (size_t j = 0, K = slice->length(); j < K; ++j)
|
||||
{
|
||||
Statement_Obj ss;
|
||||
Statement_Obj stm = slice->at(j);
|
||||
// this has to go now here (too bad)
|
||||
Bubble_Obj node = Cast<Bubble>(stm);
|
||||
|
||||
CssMediaRule* rule1 = NULL;
|
||||
CssMediaRule* rule2 = NULL;
|
||||
if (parent) rule1 = Cast<CssMediaRule>(parent);
|
||||
if (node) rule2 = Cast<CssMediaRule>(node->node());
|
||||
if (rule1 || rule2) {
|
||||
ss = node->node();
|
||||
}
|
||||
|
||||
ss = node->node();
|
||||
|
||||
if (!ss) {
|
||||
continue;
|
||||
}
|
||||
|
||||
ss->tabs(ss->tabs() + node->tabs());
|
||||
ss->group_end(node->group_end());
|
||||
|
||||
Block_Obj bb = SASS_MEMORY_NEW(Block,
|
||||
children->pstate(),
|
||||
children->length(),
|
||||
children->is_root());
|
||||
auto evaled = ss->perform(this);
|
||||
if (evaled) bb->append(evaled);
|
||||
|
||||
Block_Obj wrapper_block = SASS_MEMORY_NEW(Block,
|
||||
children->pstate(),
|
||||
children->length(),
|
||||
children->is_root());
|
||||
|
||||
Block* wrapper = flatten(bb);
|
||||
wrapper_block->append(wrapper);
|
||||
|
||||
if (wrapper->length()) {
|
||||
previous_parent = {};
|
||||
}
|
||||
|
||||
if (wrapper_block) {
|
||||
result->append(wrapper_block);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return flatten(result);
|
||||
}
|
||||
|
||||
void Cssize::append_block(Block* b, Block* cur)
|
||||
{
|
||||
for (size_t i = 0, L = b->length(); i < L; ++i) {
|
||||
Statement_Obj ith = b->at(i)->perform(this);
|
||||
if (Block_Obj bb = Cast<Block>(ith)) {
|
||||
for (size_t j = 0, K = bb->length(); j < K; ++j) {
|
||||
cur->append(bb->at(j));
|
||||
}
|
||||
}
|
||||
else if (ith) {
|
||||
cur->append(ith);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
71
vendor/bundle/ruby/2.6.0/gems/sassc-2.4.0/ext/libsass/src/cssize.hpp
vendored
Normal file
71
vendor/bundle/ruby/2.6.0/gems/sassc-2.4.0/ext/libsass/src/cssize.hpp
vendored
Normal file
@@ -0,0 +1,71 @@
|
||||
#ifndef SASS_CSSIZE_H
|
||||
#define SASS_CSSIZE_H
|
||||
|
||||
#include "ast.hpp"
|
||||
#include "context.hpp"
|
||||
#include "operation.hpp"
|
||||
#include "environment.hpp"
|
||||
|
||||
namespace Sass {
|
||||
|
||||
struct Backtrace;
|
||||
|
||||
class Cssize : public Operation_CRTP<Statement*, Cssize> {
|
||||
|
||||
Backtraces& traces;
|
||||
BlockStack block_stack;
|
||||
sass::vector<Statement*> p_stack;
|
||||
|
||||
public:
|
||||
Cssize(Context&);
|
||||
~Cssize() { }
|
||||
|
||||
Block* operator()(Block*);
|
||||
Statement* operator()(StyleRule*);
|
||||
// Statement* operator()(Bubble*);
|
||||
Statement* operator()(CssMediaRule*);
|
||||
Statement* operator()(SupportsRule*);
|
||||
Statement* operator()(AtRootRule*);
|
||||
Statement* operator()(AtRule*);
|
||||
Statement* operator()(Keyframe_Rule*);
|
||||
Statement* operator()(Trace*);
|
||||
Statement* operator()(Declaration*);
|
||||
// Statement* operator()(Assignment*);
|
||||
// Statement* operator()(Import*);
|
||||
// Statement* operator()(Import_Stub*);
|
||||
// Statement* operator()(WarningRule*);
|
||||
// Statement* operator()(Error*);
|
||||
// Statement* operator()(Comment*);
|
||||
// Statement* operator()(If*);
|
||||
// Statement* operator()(ForRule*);
|
||||
// Statement* operator()(EachRule*);
|
||||
// Statement* operator()(WhileRule*);
|
||||
// Statement* operator()(Return*);
|
||||
// Statement* operator()(ExtendRule*);
|
||||
// Statement* operator()(Definition*);
|
||||
// Statement* operator()(Mixin_Call*);
|
||||
// Statement* operator()(Content*);
|
||||
Statement* operator()(Null*);
|
||||
|
||||
Statement* parent();
|
||||
sass::vector<std::pair<bool, Block_Obj>> slice_by_bubble(Block*);
|
||||
Statement* bubble(AtRule*);
|
||||
Statement* bubble(AtRootRule*);
|
||||
Statement* bubble(CssMediaRule*);
|
||||
Statement* bubble(SupportsRule*);
|
||||
|
||||
Block* debubble(Block* children, Statement* parent = 0);
|
||||
Block* flatten(const Block*);
|
||||
bool bubblable(Statement*);
|
||||
|
||||
// generic fallback
|
||||
template <typename U>
|
||||
Statement* fallback(U x)
|
||||
{ return Cast<Statement>(x); }
|
||||
|
||||
void append_block(Block*, Block*);
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
199
vendor/bundle/ruby/2.6.0/gems/sassc-2.4.0/ext/libsass/src/dart_helpers.hpp
vendored
Normal file
199
vendor/bundle/ruby/2.6.0/gems/sassc-2.4.0/ext/libsass/src/dart_helpers.hpp
vendored
Normal file
@@ -0,0 +1,199 @@
|
||||
#ifndef SASS_DART_HELPERS_H
|
||||
#define SASS_DART_HELPERS_H
|
||||
|
||||
#include <vector>
|
||||
#include <utility>
|
||||
#include <iterator>
|
||||
#include <functional>
|
||||
|
||||
namespace Sass {
|
||||
|
||||
// ##########################################################################
|
||||
// Flatten `vector<vector<T>>` to `vector<T>`
|
||||
// ##########################################################################
|
||||
template <class T>
|
||||
T flatten(const sass::vector<T>& all)
|
||||
{
|
||||
T flattened;
|
||||
for (const auto& sub : all) {
|
||||
std::copy(std::begin(sub), std::end(sub),
|
||||
std::back_inserter(flattened));
|
||||
}
|
||||
return flattened;
|
||||
}
|
||||
|
||||
// ##########################################################################
|
||||
// Expands each element of this Iterable into zero or more elements.
|
||||
// Calls a function on every element and ads all results to flat array
|
||||
// ##########################################################################
|
||||
// Equivalent to dart `cnt.any`
|
||||
// Pass additional closure variables to `fn`
|
||||
template <class T, class U, typename ...Args>
|
||||
T expand(const T& cnt, U fn, Args... args) {
|
||||
T flattened;
|
||||
for (const auto& sub : cnt) {
|
||||
auto rv = fn(sub, args...);
|
||||
flattened.insert(flattened.end(),
|
||||
rv.begin(), rv.end());
|
||||
}
|
||||
return flattened;
|
||||
}
|
||||
|
||||
// ##########################################################################
|
||||
// ##########################################################################
|
||||
template <class T>
|
||||
T flattenInner(const sass::vector<T>& vec)
|
||||
{
|
||||
T outer;
|
||||
for (const auto& sub : vec) {
|
||||
outer.emplace_back(std::move(flatten(sub)));
|
||||
}
|
||||
return outer;
|
||||
}
|
||||
// EO flattenInner
|
||||
|
||||
// ##########################################################################
|
||||
// Equivalent to dart `cnt.any`
|
||||
// Pass additional closure variables to `fn`
|
||||
// ##########################################################################
|
||||
template <class T, class U, typename ...Args>
|
||||
bool hasAny(const T& cnt, U fn, Args... args) {
|
||||
for (const auto& sub : cnt) {
|
||||
if (fn(sub, args...)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
// EO hasAny
|
||||
|
||||
// ##########################################################################
|
||||
// Equivalent to dart `cnt.take(len).any`
|
||||
// Pass additional closure variables to `fn`
|
||||
// ##########################################################################
|
||||
template <class T, class U, typename ...Args>
|
||||
bool hasSubAny(const T& cnt, size_t len, U fn, Args... args) {
|
||||
for (size_t i = 0; i < len; i++) {
|
||||
if (fn(cnt[i], args...)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
// ##########################################################################
|
||||
// Default predicate for lcs algorithm
|
||||
// ##########################################################################
|
||||
template <class T>
|
||||
inline bool lcsIdentityCmp(const T& X, const T& Y, T& result)
|
||||
{
|
||||
// Assert equality
|
||||
if (!ObjEqualityFn(X, Y)) {
|
||||
return false;
|
||||
}
|
||||
// Store in reference
|
||||
result = X;
|
||||
// Return success
|
||||
return true;
|
||||
}
|
||||
// EO lcsIdentityCmp
|
||||
|
||||
// ##########################################################################
|
||||
// Longest common subsequence with predicate
|
||||
// ##########################################################################
|
||||
template <class T>
|
||||
sass::vector<T> lcs(
|
||||
const sass::vector<T>& X, const sass::vector<T>& Y,
|
||||
bool(*select)(const T&, const T&, T&) = lcsIdentityCmp<T>)
|
||||
{
|
||||
|
||||
std::size_t m = X.size(), mm = X.size() + 1;
|
||||
std::size_t n = Y.size(), nn = Y.size() + 1;
|
||||
|
||||
if (m == 0) return {};
|
||||
if (n == 0) return {};
|
||||
|
||||
// MSVC does not support variable-length arrays
|
||||
// To circumvent, allocate one array on the heap
|
||||
// Then use a macro to access via double index
|
||||
// e.g. `size_t L[m][n]` is supported by gcc
|
||||
size_t* len = new size_t[mm * nn + 1];
|
||||
bool* acc = new bool[mm * nn + 1];
|
||||
T* res = new T[mm * nn + 1];
|
||||
|
||||
#define LEN(x, y) len[(x) * nn + (y)]
|
||||
#define ACC(x, y) acc[(x) * nn + (y)]
|
||||
#define RES(x, y) res[(x) * nn + (y)]
|
||||
|
||||
/* Following steps build L[m+1][n+1] in bottom up fashion. Note
|
||||
that L[i][j] contains length of LCS of X[0..i-1] and Y[0..j-1] */
|
||||
for (size_t i = 0; i <= m; i++) {
|
||||
for (size_t j = 0; j <= n; j++) {
|
||||
if (i == 0 || j == 0)
|
||||
LEN(i, j) = 0;
|
||||
else {
|
||||
ACC(i - 1, j - 1) = select(X[i - 1], Y[j - 1], RES(i - 1, j - 1));
|
||||
if (ACC(i - 1, j - 1))
|
||||
LEN(i, j) = LEN(i - 1, j - 1) + 1;
|
||||
else
|
||||
LEN(i, j) = std::max(LEN(i - 1, j), LEN(i, j - 1));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Following code is used to print LCS
|
||||
sass::vector<T> lcs;
|
||||
std::size_t index = LEN(m, n);
|
||||
lcs.reserve(index);
|
||||
|
||||
// Start from the right-most-bottom-most corner
|
||||
// and one by one store objects in lcs[]
|
||||
std::size_t i = m, j = n;
|
||||
while (i > 0 && j > 0) {
|
||||
|
||||
// If current objects in X[] and Y are same,
|
||||
// then current object is part of LCS
|
||||
if (ACC(i - 1, j - 1))
|
||||
{
|
||||
// Put the stored object in result
|
||||
// Note: we push instead of unshift
|
||||
// Note: reverse the vector later
|
||||
// ToDo: is deque more performant?
|
||||
lcs.push_back(RES(i - 1, j - 1));
|
||||
// reduce values of i, j and index
|
||||
i -= 1; j -= 1; index -= 1;
|
||||
}
|
||||
|
||||
// If not same, then find the larger of two and
|
||||
// go in the direction of larger value
|
||||
else if (LEN(i - 1, j) > LEN(i, j - 1)) {
|
||||
i--;
|
||||
}
|
||||
else {
|
||||
j--;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// reverse now as we used push_back
|
||||
std::reverse(lcs.begin(), lcs.end());
|
||||
|
||||
// Delete temp memory on heap
|
||||
delete[] len;
|
||||
delete[] acc;
|
||||
delete[] res;
|
||||
|
||||
#undef LEN
|
||||
#undef ACC
|
||||
#undef RES
|
||||
|
||||
return lcs;
|
||||
}
|
||||
// EO lcs
|
||||
|
||||
// ##########################################################################
|
||||
// ##########################################################################
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
43
vendor/bundle/ruby/2.6.0/gems/sassc-2.4.0/ext/libsass/src/debug.hpp
vendored
Normal file
43
vendor/bundle/ruby/2.6.0/gems/sassc-2.4.0/ext/libsass/src/debug.hpp
vendored
Normal file
@@ -0,0 +1,43 @@
|
||||
#ifndef SASS_DEBUG_H
|
||||
#define SASS_DEBUG_H
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
#ifndef UINT32_MAX
|
||||
#define UINT32_MAX 0xffffffffU
|
||||
#endif
|
||||
|
||||
enum dbg_lvl_t : uint32_t {
|
||||
NONE = 0,
|
||||
TRIM = 1,
|
||||
CHUNKS = 2,
|
||||
SUBWEAVE = 4,
|
||||
WEAVE = 8,
|
||||
EXTEND_COMPOUND = 16,
|
||||
EXTEND_COMPLEX = 32,
|
||||
LCS = 64,
|
||||
EXTEND_OBJECT = 128,
|
||||
ALL = UINT32_MAX
|
||||
};
|
||||
|
||||
#ifdef DEBUG
|
||||
|
||||
#ifndef DEBUG_LVL
|
||||
const uint32_t debug_lvl = UINT32_MAX;
|
||||
#else
|
||||
const uint32_t debug_lvl = (DEBUG_LVL);
|
||||
#endif // DEBUG_LVL
|
||||
|
||||
#define DEBUG_PRINT(lvl, x) if((lvl) & debug_lvl) { std::cerr << x; }
|
||||
#define DEBUG_PRINTLN(lvl, x) if((lvl) & debug_lvl) { std::cerr << x << std::endl; }
|
||||
#define DEBUG_EXEC(lvl, x) if((lvl) & debug_lvl) { x; }
|
||||
|
||||
#else // DEBUG
|
||||
|
||||
#define DEBUG_PRINT(lvl, x)
|
||||
#define DEBUG_PRINTLN(lvl, x)
|
||||
#define DEBUG_EXEC(lvl, x)
|
||||
|
||||
#endif // DEBUG
|
||||
|
||||
#endif // SASS_DEBUG
|
||||
963
vendor/bundle/ruby/2.6.0/gems/sassc-2.4.0/ext/libsass/src/debugger.hpp
vendored
Normal file
963
vendor/bundle/ruby/2.6.0/gems/sassc-2.4.0/ext/libsass/src/debugger.hpp
vendored
Normal file
@@ -0,0 +1,963 @@
|
||||
#ifndef SASS_DEBUGGER_H
|
||||
#define SASS_DEBUGGER_H
|
||||
|
||||
// sass.hpp must go before all system headers to get the
|
||||
// __EXTENSIONS__ fix on Solaris.
|
||||
#include "sass.hpp"
|
||||
|
||||
#include <queue>
|
||||
#include <vector>
|
||||
#include <string>
|
||||
#include <sstream>
|
||||
#include "ast.hpp"
|
||||
#include "ast_fwd_decl.hpp"
|
||||
#include "extension.hpp"
|
||||
|
||||
#include "ordered_map.hpp"
|
||||
|
||||
using namespace Sass;
|
||||
|
||||
inline void debug_ast(AST_Node* node, sass::string ind = "", Env* env = 0);
|
||||
|
||||
inline sass::string debug_vec(const AST_Node* node) {
|
||||
if (node == NULL) return "null";
|
||||
else return node->to_string();
|
||||
}
|
||||
|
||||
inline sass::string debug_dude(sass::vector<sass::vector<int>> vec) {
|
||||
sass::sstream out;
|
||||
out << "{";
|
||||
bool joinOut = false;
|
||||
for (auto ct : vec) {
|
||||
if (joinOut) out << ", ";
|
||||
joinOut = true;
|
||||
out << "{";
|
||||
bool joinIn = false;
|
||||
for (auto nr : ct) {
|
||||
if (joinIn) out << ", ";
|
||||
joinIn = true;
|
||||
out << nr;
|
||||
}
|
||||
out << "}";
|
||||
}
|
||||
out << "}";
|
||||
return out.str();
|
||||
}
|
||||
|
||||
inline sass::string debug_vec(sass::string& str) {
|
||||
return str;
|
||||
}
|
||||
|
||||
inline sass::string debug_vec(Extension& ext) {
|
||||
sass::sstream out;
|
||||
out << debug_vec(ext.extender);
|
||||
out << " {@extend ";
|
||||
out << debug_vec(ext.target);
|
||||
if (ext.isOptional) {
|
||||
out << " !optional";
|
||||
}
|
||||
out << "}";
|
||||
return out.str();
|
||||
}
|
||||
|
||||
template <class T>
|
||||
inline sass::string debug_vec(sass::vector<T> vec) {
|
||||
sass::sstream out;
|
||||
out << "[";
|
||||
for (size_t i = 0; i < vec.size(); i += 1) {
|
||||
if (i > 0) out << ", ";
|
||||
out << debug_vec(vec[i]);
|
||||
}
|
||||
out << "]";
|
||||
return out.str();
|
||||
}
|
||||
|
||||
template <class T>
|
||||
inline sass::string debug_vec(std::queue<T> vec) {
|
||||
sass::sstream out;
|
||||
out << "{";
|
||||
for (size_t i = 0; i < vec.size(); i += 1) {
|
||||
if (i > 0) out << ", ";
|
||||
out << debug_vec(vec[i]);
|
||||
}
|
||||
out << "}";
|
||||
return out.str();
|
||||
}
|
||||
|
||||
template <class T, class U, class O>
|
||||
inline sass::string debug_vec(std::map<T, U, O> vec) {
|
||||
sass::sstream out;
|
||||
out << "{";
|
||||
bool joinit = false;
|
||||
for (auto it = vec.begin(); it != vec.end(); it++)
|
||||
{
|
||||
if (joinit) out << ", ";
|
||||
out << debug_vec(it->first) // string (key)
|
||||
<< ": "
|
||||
<< debug_vec(it->second); // string's value
|
||||
joinit = true;
|
||||
}
|
||||
out << "}";
|
||||
return out.str();
|
||||
}
|
||||
|
||||
template <class T, class U, class O, class V>
|
||||
inline sass::string debug_vec(const ordered_map<T, U, O, V>& vec) {
|
||||
sass::sstream out;
|
||||
out << "{";
|
||||
bool joinit = false;
|
||||
for (auto it = vec.begin(); it != vec.end(); it++)
|
||||
{
|
||||
if (joinit) out << ", ";
|
||||
out << debug_vec(*it); // string (key)
|
||||
// << debug_vec(it->second); // string's value
|
||||
joinit = true;
|
||||
}
|
||||
out << "}";
|
||||
return out.str();
|
||||
}
|
||||
|
||||
template <class T, class U, class O, class V>
|
||||
inline sass::string debug_vec(std::unordered_map<T, U, O, V> vec) {
|
||||
sass::sstream out;
|
||||
out << "{";
|
||||
bool joinit = false;
|
||||
for (auto it = vec.begin(); it != vec.end(); it++)
|
||||
{
|
||||
if (joinit) out << ", ";
|
||||
out << debug_vec(it->first) // string (key)
|
||||
<< ": "
|
||||
<< debug_vec(it->second); // string's value
|
||||
joinit = true;
|
||||
}
|
||||
out << "}";
|
||||
return out.str();
|
||||
}
|
||||
|
||||
template <class T, class U, class O, class V>
|
||||
inline sass::string debug_keys(std::unordered_map<T, U, O, V> vec) {
|
||||
sass::sstream out;
|
||||
out << "{";
|
||||
bool joinit = false;
|
||||
for (auto it = vec.begin(); it != vec.end(); it++)
|
||||
{
|
||||
if (joinit) out << ", ";
|
||||
out << debug_vec(it->first); // string (key)
|
||||
joinit = true;
|
||||
}
|
||||
out << "}";
|
||||
return out.str();
|
||||
}
|
||||
|
||||
inline sass::string debug_vec(ExtListSelSet& vec) {
|
||||
sass::sstream out;
|
||||
out << "{";
|
||||
bool joinit = false;
|
||||
for (auto it = vec.begin(); it != vec.end(); it++)
|
||||
{
|
||||
if (joinit) out << ", ";
|
||||
out << debug_vec(*it); // string (key)
|
||||
joinit = true;
|
||||
}
|
||||
out << "}";
|
||||
return out.str();
|
||||
}
|
||||
|
||||
/*
|
||||
template <class T, class U, class O, class V>
|
||||
inline sass::string debug_values(tsl::ordered_map<T, U, O, V> vec) {
|
||||
sass::sstream out;
|
||||
out << "{";
|
||||
bool joinit = false;
|
||||
for (auto it = vec.begin(); it != vec.end(); it++)
|
||||
{
|
||||
if (joinit) out << ", ";
|
||||
out << debug_vec(const_cast<U&>(it->second)); // string's value
|
||||
joinit = true;
|
||||
}
|
||||
out << "}";
|
||||
return out.str();
|
||||
}
|
||||
|
||||
template <class T, class U, class O, class V>
|
||||
inline sass::string debug_vec(tsl::ordered_map<T, U, O, V> vec) {
|
||||
sass::sstream out;
|
||||
out << "{";
|
||||
bool joinit = false;
|
||||
for (auto it = vec.begin(); it != vec.end(); it++)
|
||||
{
|
||||
if (joinit) out << ", ";
|
||||
out << debug_vec(it->first) // string (key)
|
||||
<< ": "
|
||||
<< debug_vec(const_cast<U&>(it->second)); // string's value
|
||||
joinit = true;
|
||||
}
|
||||
out << "}";
|
||||
return out.str();
|
||||
}
|
||||
|
||||
template <class T, class U, class O, class V>
|
||||
inline sass::string debug_vals(tsl::ordered_map<T, U, O, V> vec) {
|
||||
sass::sstream out;
|
||||
out << "{";
|
||||
bool joinit = false;
|
||||
for (auto it = vec.begin(); it != vec.end(); it++)
|
||||
{
|
||||
if (joinit) out << ", ";
|
||||
out << debug_vec(const_cast<U&>(it->second)); // string's value
|
||||
joinit = true;
|
||||
}
|
||||
out << "}";
|
||||
return out.str();
|
||||
}
|
||||
|
||||
template <class T, class U, class O, class V>
|
||||
inline sass::string debug_keys(tsl::ordered_map<T, U, O, V> vec) {
|
||||
sass::sstream out;
|
||||
out << "{";
|
||||
bool joinit = false;
|
||||
for (auto it = vec.begin(); it != vec.end(); it++)
|
||||
{
|
||||
if (joinit) out << ", ";
|
||||
out << debug_vec(it->first);
|
||||
joinit = true;
|
||||
}
|
||||
out << "}";
|
||||
return out.str();
|
||||
}
|
||||
*/
|
||||
|
||||
template <class T, class U>
|
||||
inline sass::string debug_vec(std::set<T, U> vec) {
|
||||
sass::sstream out;
|
||||
out << "{";
|
||||
bool joinit = false;
|
||||
for (auto item : vec) {
|
||||
if (joinit) out << ", ";
|
||||
out << debug_vec(item);
|
||||
joinit = true;
|
||||
}
|
||||
out << "}";
|
||||
return out.str();
|
||||
}
|
||||
|
||||
/*
|
||||
template <class T, class U, class O, class V>
|
||||
inline sass::string debug_vec(tsl::ordered_set<T, U, O, V> vec) {
|
||||
sass::sstream out;
|
||||
out << "{";
|
||||
bool joinit = false;
|
||||
for (auto item : vec) {
|
||||
if (joinit) out << ", ";
|
||||
out << debug_vec(item);
|
||||
joinit = true;
|
||||
}
|
||||
out << "}";
|
||||
return out.str();
|
||||
}
|
||||
*/
|
||||
|
||||
template <class T, class U, class O, class V>
|
||||
inline sass::string debug_vec(std::unordered_set<T, U, O, V> vec) {
|
||||
sass::sstream out;
|
||||
out << "{";
|
||||
bool joinit = false;
|
||||
for (auto item : vec) {
|
||||
if (joinit) out << ", ";
|
||||
out << debug_vec(item);
|
||||
joinit = true;
|
||||
}
|
||||
out << "}";
|
||||
return out.str();
|
||||
}
|
||||
|
||||
inline sass::string debug_bool(bool val) {
|
||||
return val ? "true" : "false";
|
||||
}
|
||||
inline sass::string debug_vec(ExtSmplSelSet* node) {
|
||||
if (node == NULL) return "null";
|
||||
else return debug_vec(*node);
|
||||
}
|
||||
|
||||
inline void debug_ast(const AST_Node* node, sass::string ind = "", Env* env = 0) {
|
||||
debug_ast(const_cast<AST_Node*>(node), ind, env);
|
||||
}
|
||||
|
||||
inline sass::string str_replace(sass::string str, const sass::string& oldStr, const sass::string& newStr)
|
||||
{
|
||||
size_t pos = 0;
|
||||
while((pos = str.find(oldStr, pos)) != sass::string::npos)
|
||||
{
|
||||
str.replace(pos, oldStr.length(), newStr);
|
||||
pos += newStr.length();
|
||||
}
|
||||
return str;
|
||||
}
|
||||
|
||||
inline sass::string prettyprint(const sass::string& str) {
|
||||
sass::string clean = str_replace(str, "\n", "\\n");
|
||||
clean = str_replace(clean, " ", "\\t");
|
||||
clean = str_replace(clean, "\r", "\\r");
|
||||
return clean;
|
||||
}
|
||||
|
||||
inline sass::string longToHex(long long t) {
|
||||
sass::sstream is;
|
||||
is << std::hex << t;
|
||||
return is.str();
|
||||
}
|
||||
|
||||
inline sass::string pstate_source_position(AST_Node* node)
|
||||
{
|
||||
sass::sstream str;
|
||||
Offset start(node->pstate().position);
|
||||
Offset end(start + node->pstate().offset);
|
||||
size_t file = node->pstate().getSrcId();
|
||||
str << (file == sass::string::npos ? 99999999 : file)
|
||||
<< "@[" << start.line << ":" << start.column << "]"
|
||||
<< "-[" << end.line << ":" << end.column << "]";
|
||||
#ifdef DEBUG_SHARED_PTR
|
||||
str << "x" << node->getRefCount() << ""
|
||||
<< " " << node->getDbgFile()
|
||||
<< "@" << node->getDbgLine();
|
||||
#endif
|
||||
return str.str();
|
||||
}
|
||||
|
||||
inline void debug_ast(AST_Node* node, sass::string ind, Env* env)
|
||||
{
|
||||
if (node == 0) return;
|
||||
if (ind == "") std::cerr << "####################################################################\n";
|
||||
if (Cast<Bubble>(node)) {
|
||||
Bubble* bubble = Cast<Bubble>(node);
|
||||
std::cerr << ind << "Bubble " << bubble;
|
||||
std::cerr << " (" << pstate_source_position(node) << ")";
|
||||
std::cerr << " " << bubble->tabs();
|
||||
std::cerr << std::endl;
|
||||
debug_ast(bubble->node(), ind + " ", env);
|
||||
} else if (Cast<Trace>(node)) {
|
||||
Trace* trace = Cast<Trace>(node);
|
||||
std::cerr << ind << "Trace " << trace;
|
||||
std::cerr << " (" << pstate_source_position(node) << ")"
|
||||
<< " [name:" << trace->name() << ", type: " << trace->type() << "]"
|
||||
<< std::endl;
|
||||
debug_ast(trace->block(), ind + " ", env);
|
||||
} else if (Cast<AtRootRule>(node)) {
|
||||
AtRootRule* root_block = Cast<AtRootRule>(node);
|
||||
std::cerr << ind << "AtRootRule " << root_block;
|
||||
std::cerr << " (" << pstate_source_position(node) << ")";
|
||||
std::cerr << " " << root_block->tabs();
|
||||
std::cerr << std::endl;
|
||||
debug_ast(root_block->expression(), ind + ":", env);
|
||||
debug_ast(root_block->block(), ind + " ", env);
|
||||
} else if (Cast<SelectorList>(node)) {
|
||||
SelectorList* selector = Cast<SelectorList>(node);
|
||||
std::cerr << ind << "SelectorList " << selector;
|
||||
std::cerr << " (" << pstate_source_position(node) << ")";
|
||||
std::cerr << " <" << selector->hash() << ">";
|
||||
std::cerr << (selector->is_invisible() ? " [is_invisible]" : " -");
|
||||
std::cerr << (selector->isInvisible() ? " [isInvisible]" : " -");
|
||||
std::cerr << (selector->has_real_parent_ref() ? " [real-parent]": " -");
|
||||
std::cerr << std::endl;
|
||||
|
||||
for(const ComplexSelector_Obj& i : selector->elements()) { debug_ast(i, ind + " ", env); }
|
||||
|
||||
} else if (Cast<ComplexSelector>(node)) {
|
||||
ComplexSelector* selector = Cast<ComplexSelector>(node);
|
||||
std::cerr << ind << "ComplexSelector " << selector
|
||||
<< " (" << pstate_source_position(node) << ")"
|
||||
<< " <" << selector->hash() << ">"
|
||||
<< " [" << (selector->chroots() ? "CHROOT" : "CONNECT") << "]"
|
||||
<< " [length:" << longToHex(selector->length()) << "]"
|
||||
<< " [weight:" << longToHex(selector->specificity()) << "]"
|
||||
<< (selector->is_invisible() ? " [is_invisible]" : " -")
|
||||
<< (selector->isInvisible() ? " [isInvisible]" : " -")
|
||||
<< (selector->hasPreLineFeed() ? " [hasPreLineFeed]" : " -")
|
||||
|
||||
// << (selector->is_invisible() ? " [INVISIBLE]": " -")
|
||||
// << (selector->has_placeholder() ? " [PLACEHOLDER]": " -")
|
||||
// << (selector->is_optional() ? " [is_optional]": " -")
|
||||
<< (selector->has_real_parent_ref() ? " [real parent]": " -")
|
||||
// << (selector->has_line_feed() ? " [line-feed]": " -")
|
||||
// << (selector->has_line_break() ? " [line-break]": " -")
|
||||
<< " -- \n";
|
||||
|
||||
for(const SelectorComponentObj& i : selector->elements()) { debug_ast(i, ind + " ", env); }
|
||||
|
||||
} else if (Cast<SelectorCombinator>(node)) {
|
||||
SelectorCombinator* selector = Cast<SelectorCombinator>(node);
|
||||
std::cerr << ind << "SelectorCombinator " << selector
|
||||
<< " (" << pstate_source_position(node) << ")"
|
||||
<< " <" << selector->hash() << ">"
|
||||
<< " [weight:" << longToHex(selector->specificity()) << "]"
|
||||
<< (selector->has_real_parent_ref() ? " [real parent]": " -")
|
||||
<< " -- ";
|
||||
|
||||
sass::string del;
|
||||
switch (selector->combinator()) {
|
||||
case SelectorCombinator::CHILD: del = ">"; break;
|
||||
case SelectorCombinator::GENERAL: del = "~"; break;
|
||||
case SelectorCombinator::ADJACENT: del = "+"; break;
|
||||
}
|
||||
|
||||
std::cerr << "[" << del << "]" << "\n";
|
||||
|
||||
} else if (Cast<CompoundSelector>(node)) {
|
||||
CompoundSelector* selector = Cast<CompoundSelector>(node);
|
||||
std::cerr << ind << "CompoundSelector " << selector;
|
||||
std::cerr << " (" << pstate_source_position(node) << ")";
|
||||
std::cerr << " <" << selector->hash() << ">";
|
||||
std::cerr << (selector->hasRealParent() ? " [REAL PARENT]" : "") << ">";
|
||||
std::cerr << " [weight:" << longToHex(selector->specificity()) << "]";
|
||||
std::cerr << (selector->hasPostLineBreak() ? " [hasPostLineBreak]" : " -");
|
||||
std::cerr << (selector->is_invisible() ? " [is_invisible]" : " -");
|
||||
std::cerr << (selector->isInvisible() ? " [isInvisible]" : " -");
|
||||
std::cerr << "\n";
|
||||
for(const SimpleSelector_Obj& i : selector->elements()) { debug_ast(i, ind + " ", env); }
|
||||
|
||||
} else if (Cast<Parent_Reference>(node)) {
|
||||
Parent_Reference* selector = Cast<Parent_Reference>(node);
|
||||
std::cerr << ind << "Parent_Reference " << selector;
|
||||
std::cerr << " (" << pstate_source_position(node) << ")";
|
||||
std::cerr << " <" << selector->hash() << ">";
|
||||
std::cerr << std::endl;
|
||||
|
||||
} else if (Cast<PseudoSelector>(node)) {
|
||||
PseudoSelector* selector = Cast<PseudoSelector>(node);
|
||||
std::cerr << ind << "PseudoSelector " << selector;
|
||||
std::cerr << " (" << pstate_source_position(node) << ")";
|
||||
std::cerr << " <" << selector->hash() << ">";
|
||||
std::cerr << " <<" << selector->ns_name() << ">>";
|
||||
std::cerr << (selector->isClass() ? " [isClass]": " -");
|
||||
std::cerr << (selector->isSyntacticClass() ? " [isSyntacticClass]": " -");
|
||||
std::cerr << std::endl;
|
||||
debug_ast(selector->argument(), ind + " <= ", env);
|
||||
debug_ast(selector->selector(), ind + " || ", env);
|
||||
} else if (Cast<AttributeSelector>(node)) {
|
||||
AttributeSelector* selector = Cast<AttributeSelector>(node);
|
||||
std::cerr << ind << "AttributeSelector " << selector;
|
||||
std::cerr << " (" << pstate_source_position(node) << ")";
|
||||
std::cerr << " <" << selector->hash() << ">";
|
||||
std::cerr << " <<" << selector->ns_name() << ">>";
|
||||
std::cerr << std::endl;
|
||||
debug_ast(selector->value(), ind + "[" + selector->matcher() + "] ", env);
|
||||
} else if (Cast<ClassSelector>(node)) {
|
||||
ClassSelector* selector = Cast<ClassSelector>(node);
|
||||
std::cerr << ind << "ClassSelector " << selector;
|
||||
std::cerr << " (" << pstate_source_position(node) << ")";
|
||||
std::cerr << " <" << selector->hash() << ">";
|
||||
std::cerr << " <<" << selector->ns_name() << ">>";
|
||||
std::cerr << std::endl;
|
||||
} else if (Cast<IDSelector>(node)) {
|
||||
IDSelector* selector = Cast<IDSelector>(node);
|
||||
std::cerr << ind << "IDSelector " << selector;
|
||||
std::cerr << " (" << pstate_source_position(node) << ")";
|
||||
std::cerr << " <" << selector->hash() << ">";
|
||||
std::cerr << " <<" << selector->ns_name() << ">>";
|
||||
std::cerr << std::endl;
|
||||
} else if (Cast<TypeSelector>(node)) {
|
||||
TypeSelector* selector = Cast<TypeSelector>(node);
|
||||
std::cerr << ind << "TypeSelector " << selector;
|
||||
std::cerr << " (" << pstate_source_position(node) << ")";
|
||||
std::cerr << " <" << selector->hash() << ">";
|
||||
std::cerr << " <<" << selector->ns_name() << ">>";
|
||||
std::cerr << std::endl;
|
||||
} else if (Cast<PlaceholderSelector>(node)) {
|
||||
|
||||
PlaceholderSelector* selector = Cast<PlaceholderSelector>(node);
|
||||
std::cerr << ind << "PlaceholderSelector [" << selector->ns_name() << "] " << selector;
|
||||
std::cerr << " (" << pstate_source_position(selector) << ")"
|
||||
<< " <" << selector->hash() << ">"
|
||||
<< (selector->isInvisible() ? " [isInvisible]" : " -")
|
||||
<< std::endl;
|
||||
|
||||
} else if (Cast<SimpleSelector>(node)) {
|
||||
SimpleSelector* selector = Cast<SimpleSelector>(node);
|
||||
std::cerr << ind << "SimpleSelector " << selector;
|
||||
std::cerr << " (" << pstate_source_position(node) << ")";
|
||||
|
||||
} else if (Cast<Selector_Schema>(node)) {
|
||||
Selector_Schema* selector = Cast<Selector_Schema>(node);
|
||||
std::cerr << ind << "Selector_Schema " << selector;
|
||||
std::cerr << " (" << pstate_source_position(node) << ")"
|
||||
<< (selector->connect_parent() ? " [connect-parent]": " -")
|
||||
<< std::endl;
|
||||
|
||||
debug_ast(selector->contents(), ind + " ");
|
||||
// for(auto i : selector->elements()) { debug_ast(i, ind + " ", env); }
|
||||
|
||||
} else if (Cast<Selector>(node)) {
|
||||
Selector* selector = Cast<Selector>(node);
|
||||
std::cerr << ind << "Selector " << selector;
|
||||
std::cerr << " (" << pstate_source_position(node) << ")"
|
||||
<< std::endl;
|
||||
|
||||
} else if (Cast<Media_Query_Expression>(node)) {
|
||||
Media_Query_Expression* block = Cast<Media_Query_Expression>(node);
|
||||
std::cerr << ind << "Media_Query_Expression " << block;
|
||||
std::cerr << " (" << pstate_source_position(node) << ")";
|
||||
std::cerr << (block->is_interpolated() ? " [is_interpolated]": " -")
|
||||
<< std::endl;
|
||||
debug_ast(block->feature(), ind + " feature) ");
|
||||
debug_ast(block->value(), ind + " value) ");
|
||||
|
||||
} else if (Cast<Media_Query>(node)) {
|
||||
Media_Query* block = Cast<Media_Query>(node);
|
||||
std::cerr << ind << "Media_Query " << block;
|
||||
std::cerr << " (" << pstate_source_position(node) << ")";
|
||||
std::cerr << (block->is_negated() ? " [is_negated]": " -")
|
||||
<< (block->is_restricted() ? " [is_restricted]": " -")
|
||||
<< std::endl;
|
||||
debug_ast(block->media_type(), ind + " ");
|
||||
for(const auto& i : block->elements()) { debug_ast(i, ind + " ", env); }
|
||||
}
|
||||
else if (Cast<MediaRule>(node)) {
|
||||
MediaRule* rule = Cast<MediaRule>(node);
|
||||
std::cerr << ind << "MediaRule " << rule;
|
||||
std::cerr << " (" << pstate_source_position(rule) << ")";
|
||||
std::cerr << " " << rule->tabs() << std::endl;
|
||||
debug_ast(rule->schema(), ind + " =@ ");
|
||||
debug_ast(rule->block(), ind + " ");
|
||||
}
|
||||
else if (Cast<CssMediaRule>(node)) {
|
||||
CssMediaRule* rule = Cast<CssMediaRule>(node);
|
||||
std::cerr << ind << "CssMediaRule " << rule;
|
||||
std::cerr << " (" << pstate_source_position(rule) << ")";
|
||||
std::cerr << " " << rule->tabs() << std::endl;
|
||||
for (auto item : rule->elements()) {
|
||||
debug_ast(item, ind + " == ");
|
||||
}
|
||||
debug_ast(rule->block(), ind + " ");
|
||||
}
|
||||
else if (Cast<CssMediaQuery>(node)) {
|
||||
CssMediaQuery* query = Cast<CssMediaQuery>(node);
|
||||
std::cerr << ind << "CssMediaQuery " << query;
|
||||
std::cerr << " (" << pstate_source_position(query) << ")";
|
||||
std::cerr << " [" << (query->modifier()) << "] ";
|
||||
std::cerr << " [" << (query->type()) << "] ";
|
||||
std::cerr << " " << debug_vec(query->features());
|
||||
std::cerr << std::endl;
|
||||
} else if (Cast<SupportsRule>(node)) {
|
||||
SupportsRule* block = Cast<SupportsRule>(node);
|
||||
std::cerr << ind << "SupportsRule " << block;
|
||||
std::cerr << " (" << pstate_source_position(node) << ")";
|
||||
std::cerr << " " << block->tabs() << std::endl;
|
||||
debug_ast(block->condition(), ind + " =@ ");
|
||||
debug_ast(block->block(), ind + " <>");
|
||||
} else if (Cast<SupportsOperation>(node)) {
|
||||
SupportsOperation* block = Cast<SupportsOperation>(node);
|
||||
std::cerr << ind << "SupportsOperation " << block;
|
||||
std::cerr << " (" << pstate_source_position(node) << ")"
|
||||
<< std::endl;
|
||||
debug_ast(block->left(), ind + " left) ");
|
||||
debug_ast(block->right(), ind + " right) ");
|
||||
} else if (Cast<SupportsNegation>(node)) {
|
||||
SupportsNegation* block = Cast<SupportsNegation>(node);
|
||||
std::cerr << ind << "SupportsNegation " << block;
|
||||
std::cerr << " (" << pstate_source_position(node) << ")"
|
||||
<< std::endl;
|
||||
debug_ast(block->condition(), ind + " condition) ");
|
||||
} else if (Cast<At_Root_Query>(node)) {
|
||||
At_Root_Query* block = Cast<At_Root_Query>(node);
|
||||
std::cerr << ind << "At_Root_Query " << block;
|
||||
std::cerr << " (" << pstate_source_position(node) << ")"
|
||||
<< std::endl;
|
||||
debug_ast(block->feature(), ind + " feature) ");
|
||||
debug_ast(block->value(), ind + " value) ");
|
||||
} else if (Cast<SupportsDeclaration>(node)) {
|
||||
SupportsDeclaration* block = Cast<SupportsDeclaration>(node);
|
||||
std::cerr << ind << "SupportsDeclaration " << block;
|
||||
std::cerr << " (" << pstate_source_position(node) << ")"
|
||||
<< std::endl;
|
||||
debug_ast(block->feature(), ind + " feature) ");
|
||||
debug_ast(block->value(), ind + " value) ");
|
||||
} else if (Cast<Block>(node)) {
|
||||
Block* root_block = Cast<Block>(node);
|
||||
std::cerr << ind << "Block " << root_block;
|
||||
std::cerr << " (" << pstate_source_position(node) << ")";
|
||||
if (root_block->is_root()) std::cerr << " [root]";
|
||||
if (root_block->isInvisible()) std::cerr << " [isInvisible]";
|
||||
std::cerr << " " << root_block->tabs() << std::endl;
|
||||
for(const Statement_Obj& i : root_block->elements()) { debug_ast(i, ind + " ", env); }
|
||||
} else if (Cast<WarningRule>(node)) {
|
||||
WarningRule* block = Cast<WarningRule>(node);
|
||||
std::cerr << ind << "WarningRule " << block;
|
||||
std::cerr << " (" << pstate_source_position(node) << ")";
|
||||
std::cerr << " " << block->tabs() << std::endl;
|
||||
debug_ast(block->message(), ind + " : ");
|
||||
} else if (Cast<ErrorRule>(node)) {
|
||||
ErrorRule* block = Cast<ErrorRule>(node);
|
||||
std::cerr << ind << "ErrorRule " << block;
|
||||
std::cerr << " (" << pstate_source_position(node) << ")";
|
||||
std::cerr << " " << block->tabs() << std::endl;
|
||||
} else if (Cast<DebugRule>(node)) {
|
||||
DebugRule* block = Cast<DebugRule>(node);
|
||||
std::cerr << ind << "DebugRule " << block;
|
||||
std::cerr << " (" << pstate_source_position(node) << ")";
|
||||
std::cerr << " " << block->tabs() << std::endl;
|
||||
debug_ast(block->value(), ind + " ");
|
||||
} else if (Cast<Comment>(node)) {
|
||||
Comment* block = Cast<Comment>(node);
|
||||
std::cerr << ind << "Comment " << block;
|
||||
std::cerr << " (" << pstate_source_position(node) << ")";
|
||||
std::cerr << " " << block->tabs() << std::endl;
|
||||
debug_ast(block->text(), ind + "// ", env);
|
||||
} else if (Cast<If>(node)) {
|
||||
If* block = Cast<If>(node);
|
||||
std::cerr << ind << "If " << block;
|
||||
std::cerr << " (" << pstate_source_position(node) << ")";
|
||||
std::cerr << " " << block->tabs() << std::endl;
|
||||
debug_ast(block->predicate(), ind + " = ");
|
||||
debug_ast(block->block(), ind + " <>");
|
||||
debug_ast(block->alternative(), ind + " ><");
|
||||
} else if (Cast<Return>(node)) {
|
||||
Return* block = Cast<Return>(node);
|
||||
std::cerr << ind << "Return " << block;
|
||||
std::cerr << " (" << pstate_source_position(node) << ")";
|
||||
std::cerr << " " << block->tabs();
|
||||
std::cerr << " [" << block->value()->to_string() << "]" << std::endl;
|
||||
} else if (Cast<ExtendRule>(node)) {
|
||||
ExtendRule* block = Cast<ExtendRule>(node);
|
||||
std::cerr << ind << "ExtendRule " << block;
|
||||
std::cerr << " (" << pstate_source_position(node) << ")";
|
||||
std::cerr << " " << block->tabs() << std::endl;
|
||||
debug_ast(block->selector(), ind + "-> ", env);
|
||||
} else if (Cast<Content>(node)) {
|
||||
Content* block = Cast<Content>(node);
|
||||
std::cerr << ind << "Content " << block;
|
||||
std::cerr << " (" << pstate_source_position(node) << ")";
|
||||
std::cerr << " " << block->tabs() << std::endl;
|
||||
debug_ast(block->arguments(), ind + " args: ", env);
|
||||
} else if (Cast<Import_Stub>(node)) {
|
||||
Import_Stub* block = Cast<Import_Stub>(node);
|
||||
std::cerr << ind << "Import_Stub " << block;
|
||||
std::cerr << " (" << pstate_source_position(node) << ")";
|
||||
std::cerr << " [" << block->imp_path() << "] ";
|
||||
std::cerr << " " << block->tabs() << std::endl;
|
||||
} else if (Cast<Import>(node)) {
|
||||
Import* block = Cast<Import>(node);
|
||||
std::cerr << ind << "Import " << block;
|
||||
std::cerr << " (" << pstate_source_position(node) << ")";
|
||||
std::cerr << " " << block->tabs() << std::endl;
|
||||
// sass::vector<sass::string> files_;
|
||||
for (auto imp : block->urls()) debug_ast(imp, ind + "@: ", env);
|
||||
debug_ast(block->import_queries(), ind + "@@ ");
|
||||
} else if (Cast<Assignment>(node)) {
|
||||
Assignment* block = Cast<Assignment>(node);
|
||||
std::cerr << ind << "Assignment " << block;
|
||||
std::cerr << " (" << pstate_source_position(node) << ")";
|
||||
std::cerr << " <<" << block->variable() << ">> " << block->tabs() << std::endl;
|
||||
debug_ast(block->value(), ind + "=", env);
|
||||
} else if (Cast<Declaration>(node)) {
|
||||
Declaration* block = Cast<Declaration>(node);
|
||||
std::cerr << ind << "Declaration " << block;
|
||||
std::cerr << " (" << pstate_source_position(node) << ")";
|
||||
std::cerr << " [is_custom_property: " << block->is_custom_property() << "] ";
|
||||
std::cerr << " " << block->tabs() << std::endl;
|
||||
debug_ast(block->property(), ind + " prop: ", env);
|
||||
debug_ast(block->value(), ind + " value: ", env);
|
||||
debug_ast(block->block(), ind + " ", env);
|
||||
} else if (Cast<Keyframe_Rule>(node)) {
|
||||
Keyframe_Rule* ParentStatement = Cast<Keyframe_Rule>(node);
|
||||
std::cerr << ind << "Keyframe_Rule " << ParentStatement;
|
||||
std::cerr << " (" << pstate_source_position(node) << ")";
|
||||
std::cerr << " " << ParentStatement->tabs() << std::endl;
|
||||
if (ParentStatement->name()) debug_ast(ParentStatement->name(), ind + "@");
|
||||
if (ParentStatement->block()) for(const Statement_Obj& i : ParentStatement->block()->elements()) { debug_ast(i, ind + " ", env); }
|
||||
} else if (Cast<AtRule>(node)) {
|
||||
AtRule* block = Cast<AtRule>(node);
|
||||
std::cerr << ind << "AtRule " << block;
|
||||
std::cerr << " (" << pstate_source_position(node) << ")";
|
||||
std::cerr << " [" << block->keyword() << "] " << block->tabs() << std::endl;
|
||||
debug_ast(block->selector(), ind + "~", env);
|
||||
debug_ast(block->value(), ind + "+", env);
|
||||
if (block->block()) for(const Statement_Obj& i : block->block()->elements()) { debug_ast(i, ind + " ", env); }
|
||||
} else if (Cast<EachRule>(node)) {
|
||||
EachRule* block = Cast<EachRule>(node);
|
||||
std::cerr << ind << "EachRule " << block;
|
||||
std::cerr << " (" << pstate_source_position(node) << ")";
|
||||
std::cerr << " " << block->tabs() << std::endl;
|
||||
if (block->block()) for(const Statement_Obj& i : block->block()->elements()) { debug_ast(i, ind + " ", env); }
|
||||
} else if (Cast<ForRule>(node)) {
|
||||
ForRule* block = Cast<ForRule>(node);
|
||||
std::cerr << ind << "ForRule " << block;
|
||||
std::cerr << " (" << pstate_source_position(node) << ")";
|
||||
std::cerr << " " << block->tabs() << std::endl;
|
||||
if (block->block()) for(const Statement_Obj& i : block->block()->elements()) { debug_ast(i, ind + " ", env); }
|
||||
} else if (Cast<WhileRule>(node)) {
|
||||
WhileRule* block = Cast<WhileRule>(node);
|
||||
std::cerr << ind << "WhileRule " << block;
|
||||
std::cerr << " (" << pstate_source_position(node) << ")";
|
||||
std::cerr << " " << block->tabs() << std::endl;
|
||||
if (block->block()) for(const Statement_Obj& i : block->block()->elements()) { debug_ast(i, ind + " ", env); }
|
||||
} else if (Cast<Definition>(node)) {
|
||||
Definition* block = Cast<Definition>(node);
|
||||
std::cerr << ind << "Definition " << block;
|
||||
std::cerr << " (" << pstate_source_position(node) << ")";
|
||||
std::cerr << " [name: " << block->name() << "] ";
|
||||
std::cerr << " [type: " << (block->type() == Sass::Definition::Type::MIXIN ? "Mixin " : "Function ") << "] ";
|
||||
// this seems to lead to segfaults some times?
|
||||
// std::cerr << " [signature: " << block->signature() << "] ";
|
||||
std::cerr << " [native: " << block->native_function() << "] ";
|
||||
std::cerr << " " << block->tabs() << std::endl;
|
||||
debug_ast(block->parameters(), ind + " params: ", env);
|
||||
if (block->block()) debug_ast(block->block(), ind + " ", env);
|
||||
} else if (Cast<Mixin_Call>(node)) {
|
||||
Mixin_Call* block = Cast<Mixin_Call>(node);
|
||||
std::cerr << ind << "Mixin_Call " << block << " " << block->tabs();
|
||||
std::cerr << " (" << pstate_source_position(block) << ")";
|
||||
std::cerr << " [" << block->name() << "]";
|
||||
std::cerr << " [has_content: " << block->has_content() << "] " << std::endl;
|
||||
debug_ast(block->arguments(), ind + " args: ", env);
|
||||
debug_ast(block->block_parameters(), ind + " block_params: ", env);
|
||||
if (block->block()) debug_ast(block->block(), ind + " ", env);
|
||||
} else if (StyleRule* ruleset = Cast<StyleRule>(node)) {
|
||||
std::cerr << ind << "StyleRule " << ruleset;
|
||||
std::cerr << " (" << pstate_source_position(node) << ")";
|
||||
std::cerr << " [indent: " << ruleset->tabs() << "]";
|
||||
std::cerr << (ruleset->is_invisible() ? " [INVISIBLE]" : "");
|
||||
std::cerr << (ruleset->is_root() ? " [root]" : "");
|
||||
std::cerr << std::endl;
|
||||
debug_ast(ruleset->selector(), ind + ">");
|
||||
debug_ast(ruleset->block(), ind + " ");
|
||||
} else if (Cast<Block>(node)) {
|
||||
Block* block = Cast<Block>(node);
|
||||
std::cerr << ind << "Block " << block;
|
||||
std::cerr << " (" << pstate_source_position(node) << ")";
|
||||
std::cerr << (block->is_invisible() ? " [INVISIBLE]" : "");
|
||||
std::cerr << " [indent: " << block->tabs() << "]" << std::endl;
|
||||
for(const Statement_Obj& i : block->elements()) { debug_ast(i, ind + " ", env); }
|
||||
} else if (Cast<Variable>(node)) {
|
||||
Variable* expression = Cast<Variable>(node);
|
||||
std::cerr << ind << "Variable " << expression;
|
||||
std::cerr << " [interpolant: " << expression->is_interpolant() << "] ";
|
||||
std::cerr << " (" << pstate_source_position(node) << ")";
|
||||
std::cerr << " [" << expression->name() << "]" << std::endl;
|
||||
sass::string name(expression->name());
|
||||
if (env && env->has(name)) debug_ast(Cast<Expression>((*env)[name]), ind + " -> ", env);
|
||||
} else if (Cast<Function_Call>(node)) {
|
||||
Function_Call* expression = Cast<Function_Call>(node);
|
||||
std::cerr << ind << "Function_Call " << expression;
|
||||
std::cerr << " [interpolant: " << expression->is_interpolant() << "] ";
|
||||
std::cerr << " (" << pstate_source_position(node) << ")";
|
||||
std::cerr << " [" << expression->name() << "]";
|
||||
if (expression->is_delayed()) std::cerr << " [delayed]";
|
||||
if (expression->is_interpolant()) std::cerr << " [interpolant]";
|
||||
if (expression->is_css()) std::cerr << " [css]";
|
||||
std::cerr << std::endl;
|
||||
debug_ast(expression->arguments(), ind + " args: ", env);
|
||||
debug_ast(expression->func(), ind + " func: ", env);
|
||||
} else if (Cast<Function>(node)) {
|
||||
Function* expression = Cast<Function>(node);
|
||||
std::cerr << ind << "Function " << expression;
|
||||
std::cerr << " (" << pstate_source_position(node) << ")";
|
||||
if (expression->is_css()) std::cerr << " [css]";
|
||||
std::cerr << std::endl;
|
||||
debug_ast(expression->definition(), ind + " definition: ", env);
|
||||
} else if (Cast<Arguments>(node)) {
|
||||
Arguments* expression = Cast<Arguments>(node);
|
||||
std::cerr << ind << "Arguments " << expression;
|
||||
if (expression->is_delayed()) std::cerr << " [delayed]";
|
||||
std::cerr << " (" << pstate_source_position(node) << ")";
|
||||
if (expression->has_named_arguments()) std::cerr << " [has_named_arguments]";
|
||||
if (expression->has_rest_argument()) std::cerr << " [has_rest_argument]";
|
||||
if (expression->has_keyword_argument()) std::cerr << " [has_keyword_argument]";
|
||||
std::cerr << std::endl;
|
||||
for(const Argument_Obj& i : expression->elements()) { debug_ast(i, ind + " ", env); }
|
||||
} else if (Cast<Argument>(node)) {
|
||||
Argument* expression = Cast<Argument>(node);
|
||||
std::cerr << ind << "Argument " << expression;
|
||||
std::cerr << " (" << pstate_source_position(node) << ")";
|
||||
std::cerr << " [" << expression->value().ptr() << "]";
|
||||
std::cerr << " [name: " << expression->name() << "] ";
|
||||
std::cerr << " [rest: " << expression->is_rest_argument() << "] ";
|
||||
std::cerr << " [keyword: " << expression->is_keyword_argument() << "] " << std::endl;
|
||||
debug_ast(expression->value(), ind + " value: ", env);
|
||||
} else if (Cast<Parameters>(node)) {
|
||||
Parameters* expression = Cast<Parameters>(node);
|
||||
std::cerr << ind << "Parameters " << expression;
|
||||
std::cerr << " (" << pstate_source_position(node) << ")";
|
||||
std::cerr << " [has_optional: " << expression->has_optional_parameters() << "] ";
|
||||
std::cerr << " [has_rest: " << expression->has_rest_parameter() << "] ";
|
||||
std::cerr << std::endl;
|
||||
for(const Parameter_Obj& i : expression->elements()) { debug_ast(i, ind + " ", env); }
|
||||
} else if (Cast<Parameter>(node)) {
|
||||
Parameter* expression = Cast<Parameter>(node);
|
||||
std::cerr << ind << "Parameter " << expression;
|
||||
std::cerr << " (" << pstate_source_position(node) << ")";
|
||||
std::cerr << " [name: " << expression->name() << "] ";
|
||||
std::cerr << " [default: " << expression->default_value().ptr() << "] ";
|
||||
std::cerr << " [rest: " << expression->is_rest_parameter() << "] " << std::endl;
|
||||
} else if (Cast<Unary_Expression>(node)) {
|
||||
Unary_Expression* expression = Cast<Unary_Expression>(node);
|
||||
std::cerr << ind << "Unary_Expression " << expression;
|
||||
std::cerr << " [interpolant: " << expression->is_interpolant() << "] ";
|
||||
std::cerr << " [delayed: " << expression->is_delayed() << "] ";
|
||||
std::cerr << " (" << pstate_source_position(node) << ")";
|
||||
std::cerr << " [" << expression->type() << "]" << std::endl;
|
||||
debug_ast(expression->operand(), ind + " operand: ", env);
|
||||
} else if (Cast<Binary_Expression>(node)) {
|
||||
Binary_Expression* expression = Cast<Binary_Expression>(node);
|
||||
std::cerr << ind << "Binary_Expression " << expression;
|
||||
if (expression->is_interpolant()) std::cerr << " [is interpolant] ";
|
||||
if (expression->is_left_interpolant()) std::cerr << " [left interpolant] ";
|
||||
if (expression->is_right_interpolant()) std::cerr << " [right interpolant] ";
|
||||
std::cerr << " [delayed: " << expression->is_delayed() << "] ";
|
||||
std::cerr << " [ws_before: " << expression->op().ws_before << "] ";
|
||||
std::cerr << " [ws_after: " << expression->op().ws_after << "] ";
|
||||
std::cerr << " (" << pstate_source_position(node) << ")";
|
||||
std::cerr << " [" << expression->type_name() << "]" << std::endl;
|
||||
debug_ast(expression->left(), ind + " left: ", env);
|
||||
debug_ast(expression->right(), ind + " right: ", env);
|
||||
} else if (Cast<Map>(node)) {
|
||||
Map* expression = Cast<Map>(node);
|
||||
std::cerr << ind << "Map " << expression;
|
||||
std::cerr << " [interpolant: " << expression->is_interpolant() << "] ";
|
||||
std::cerr << " (" << pstate_source_position(node) << ")";
|
||||
std::cerr << " [Hashed]" << std::endl;
|
||||
for (const auto& i : expression->elements()) {
|
||||
debug_ast(i.first, ind + " key: ");
|
||||
debug_ast(i.second, ind + " val: ");
|
||||
}
|
||||
} else if (Cast<List>(node)) {
|
||||
List* expression = Cast<List>(node);
|
||||
std::cerr << ind << "List " << expression;
|
||||
std::cerr << " (" << pstate_source_position(node) << ")";
|
||||
std::cerr << " (" << expression->length() << ") " <<
|
||||
(expression->separator() == SASS_COMMA ? "Comma " : expression->separator() == SASS_HASH ? "Map " : "Space ") <<
|
||||
" [delayed: " << expression->is_delayed() << "] " <<
|
||||
" [interpolant: " << expression->is_interpolant() << "] " <<
|
||||
" [listized: " << expression->from_selector() << "] " <<
|
||||
" [arglist: " << expression->is_arglist() << "] " <<
|
||||
" [bracketed: " << expression->is_bracketed() << "] " <<
|
||||
" [expanded: " << expression->is_expanded() << "] " <<
|
||||
" [hash: " << expression->hash() << "] " <<
|
||||
std::endl;
|
||||
for(const auto& i : expression->elements()) { debug_ast(i, ind + " ", env); }
|
||||
} else if (Cast<Boolean>(node)) {
|
||||
Boolean* expression = Cast<Boolean>(node);
|
||||
std::cerr << ind << "Boolean " << expression;
|
||||
std::cerr << " (" << pstate_source_position(node) << ")";
|
||||
std::cerr << " [interpolant: " << expression->is_interpolant() << "] ";
|
||||
std::cerr << " [" << expression->value() << "]" << std::endl;
|
||||
} else if (Cast<Color_RGBA>(node)) {
|
||||
Color_RGBA* expression = Cast<Color_RGBA>(node);
|
||||
std::cerr << ind << "Color " << expression;
|
||||
std::cerr << " (" << pstate_source_position(node) << ")";
|
||||
std::cerr << " [name: " << expression->disp() << "] ";
|
||||
std::cerr << " [delayed: " << expression->is_delayed() << "] ";
|
||||
std::cerr << " [interpolant: " << expression->is_interpolant() << "] ";
|
||||
std::cerr << " rgba[" << expression->r() << ":" << expression->g() << ":" << expression->b() << "@" << expression->a() << "]" << std::endl;
|
||||
} else if (Cast<Color_HSLA>(node)) {
|
||||
Color_HSLA* expression = Cast<Color_HSLA>(node);
|
||||
std::cerr << ind << "Color " << expression;
|
||||
std::cerr << " (" << pstate_source_position(node) << ")";
|
||||
std::cerr << " [name: " << expression->disp() << "] ";
|
||||
std::cerr << " [delayed: " << expression->is_delayed() << "] ";
|
||||
std::cerr << " [interpolant: " << expression->is_interpolant() << "] ";
|
||||
std::cerr << " hsla[" << expression->h() << ":" << expression->s() << ":" << expression->l() << "@" << expression->a() << "]" << std::endl;
|
||||
} else if (Cast<Number>(node)) {
|
||||
Number* expression = Cast<Number>(node);
|
||||
std::cerr << ind << "Number " << expression;
|
||||
std::cerr << " (" << pstate_source_position(node) << ")";
|
||||
std::cerr << " [delayed: " << expression->is_delayed() << "] ";
|
||||
std::cerr << " [interpolant: " << expression->is_interpolant() << "] ";
|
||||
std::cerr << " [" << expression->value() << expression->unit() << "]" <<
|
||||
" [hash: " << expression->hash() << "] " <<
|
||||
std::endl;
|
||||
} else if (Cast<Null>(node)) {
|
||||
Null* expression = Cast<Null>(node);
|
||||
std::cerr << ind << "Null " << expression;
|
||||
std::cerr << " (" << pstate_source_position(node) << ")";
|
||||
std::cerr << " [interpolant: " << expression->is_interpolant() << "] "
|
||||
// " [hash: " << expression->hash() << "] "
|
||||
<< std::endl;
|
||||
} else if (Cast<String_Quoted>(node)) {
|
||||
String_Quoted* expression = Cast<String_Quoted>(node);
|
||||
std::cerr << ind << "String_Quoted " << expression;
|
||||
std::cerr << " (" << pstate_source_position(node) << ")";
|
||||
std::cerr << " [" << prettyprint(expression->value()) << "]";
|
||||
if (expression->is_delayed()) std::cerr << " [delayed]";
|
||||
if (expression->is_interpolant()) std::cerr << " [interpolant]";
|
||||
if (expression->quote_mark()) std::cerr << " [quote_mark: " << expression->quote_mark() << "]";
|
||||
std::cerr << std::endl;
|
||||
} else if (Cast<String_Constant>(node)) {
|
||||
String_Constant* expression = Cast<String_Constant>(node);
|
||||
std::cerr << ind << "String_Constant " << expression;
|
||||
if (expression->concrete_type()) {
|
||||
std::cerr << " " << expression->concrete_type();
|
||||
}
|
||||
std::cerr << " (" << pstate_source_position(node) << ")";
|
||||
std::cerr << " [" << prettyprint(expression->value()) << "]";
|
||||
if (expression->is_delayed()) std::cerr << " [delayed]";
|
||||
if (expression->is_interpolant()) std::cerr << " [interpolant]";
|
||||
std::cerr << std::endl;
|
||||
} else if (Cast<String_Schema>(node)) {
|
||||
String_Schema* expression = Cast<String_Schema>(node);
|
||||
std::cerr << ind << "String_Schema " << expression;
|
||||
std::cerr << " (" << pstate_source_position(expression) << ")";
|
||||
std::cerr << " " << expression->concrete_type();
|
||||
std::cerr << " (" << pstate_source_position(node) << ")";
|
||||
if (expression->css()) std::cerr << " [css]";
|
||||
if (expression->is_delayed()) std::cerr << " [delayed]";
|
||||
if (expression->is_interpolant()) std::cerr << " [is interpolant]";
|
||||
if (expression->has_interpolant()) std::cerr << " [has interpolant]";
|
||||
if (expression->is_left_interpolant()) std::cerr << " [left interpolant] ";
|
||||
if (expression->is_right_interpolant()) std::cerr << " [right interpolant] ";
|
||||
std::cerr << std::endl;
|
||||
for(const auto& i : expression->elements()) { debug_ast(i, ind + " ", env); }
|
||||
} else if (Cast<String>(node)) {
|
||||
String* expression = Cast<String>(node);
|
||||
std::cerr << ind << "String " << expression;
|
||||
std::cerr << " " << expression->concrete_type();
|
||||
std::cerr << " (" << pstate_source_position(node) << ")";
|
||||
if (expression->is_interpolant()) std::cerr << " [interpolant]";
|
||||
std::cerr << std::endl;
|
||||
} else if (Cast<Expression>(node)) {
|
||||
Expression* expression = Cast<Expression>(node);
|
||||
std::cerr << ind << "Expression " << expression;
|
||||
std::cerr << " (" << pstate_source_position(node) << ")";
|
||||
switch (expression->concrete_type()) {
|
||||
case Expression::Type::NONE: std::cerr << " [NONE]"; break;
|
||||
case Expression::Type::BOOLEAN: std::cerr << " [BOOLEAN]"; break;
|
||||
case Expression::Type::NUMBER: std::cerr << " [NUMBER]"; break;
|
||||
case Expression::Type::COLOR: std::cerr << " [COLOR]"; break;
|
||||
case Expression::Type::STRING: std::cerr << " [STRING]"; break;
|
||||
case Expression::Type::LIST: std::cerr << " [LIST]"; break;
|
||||
case Expression::Type::MAP: std::cerr << " [MAP]"; break;
|
||||
case Expression::Type::SELECTOR: std::cerr << " [SELECTOR]"; break;
|
||||
case Expression::Type::NULL_VAL: std::cerr << " [NULL_VAL]"; break;
|
||||
case Expression::Type::C_WARNING: std::cerr << " [C_WARNING]"; break;
|
||||
case Expression::Type::C_ERROR: std::cerr << " [C_ERROR]"; break;
|
||||
case Expression::Type::FUNCTION: std::cerr << " [FUNCTION]"; break;
|
||||
case Expression::Type::NUM_TYPES: std::cerr << " [NUM_TYPES]"; break;
|
||||
case Expression::Type::VARIABLE: std::cerr << " [VARIABLE]"; break;
|
||||
case Expression::Type::FUNCTION_VAL: std::cerr << " [FUNCTION_VAL]"; break;
|
||||
case Expression::Type::PARENT: std::cerr << " [PARENT]"; break;
|
||||
}
|
||||
std::cerr << std::endl;
|
||||
} else if (Cast<ParentStatement>(node)) {
|
||||
ParentStatement* parent = Cast<ParentStatement>(node);
|
||||
std::cerr << ind << "ParentStatement " << parent;
|
||||
std::cerr << " (" << pstate_source_position(node) << ")";
|
||||
std::cerr << " " << parent->tabs() << std::endl;
|
||||
if (parent->block()) for(const Statement_Obj& i : parent->block()->elements()) { debug_ast(i, ind + " ", env); }
|
||||
} else if (Cast<Statement>(node)) {
|
||||
Statement* statement = Cast<Statement>(node);
|
||||
std::cerr << ind << "Statement " << statement;
|
||||
std::cerr << " (" << pstate_source_position(node) << ")";
|
||||
std::cerr << " " << statement->tabs() << std::endl;
|
||||
}
|
||||
|
||||
if (ind == "") std::cerr << "####################################################################\n";
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
inline void debug_ast(const AST_Node* node, sass::string ind = "", Env* env = 0)
|
||||
{
|
||||
debug_ast(const_cast<AST_Node*>(node), ind, env);
|
||||
}
|
||||
*/
|
||||
|
||||
#endif // SASS_DEBUGGER
|
||||
297
vendor/bundle/ruby/2.6.0/gems/sassc-2.4.0/ext/libsass/src/emitter.cpp
vendored
Normal file
297
vendor/bundle/ruby/2.6.0/gems/sassc-2.4.0/ext/libsass/src/emitter.cpp
vendored
Normal file
@@ -0,0 +1,297 @@
|
||||
// sass.hpp must go before all system headers to get the
|
||||
// __EXTENSIONS__ fix on Solaris.
|
||||
#include "sass.hpp"
|
||||
#include "emitter.hpp"
|
||||
#include "util_string.hpp"
|
||||
#include "util.hpp"
|
||||
|
||||
namespace Sass {
|
||||
|
||||
Emitter::Emitter(struct Sass_Output_Options& opt)
|
||||
: wbuf(),
|
||||
opt(opt),
|
||||
indentation(0),
|
||||
scheduled_space(0),
|
||||
scheduled_linefeed(0),
|
||||
scheduled_delimiter(false),
|
||||
scheduled_crutch(0),
|
||||
scheduled_mapping(0),
|
||||
in_custom_property(false),
|
||||
in_comment(false),
|
||||
in_wrapped(false),
|
||||
in_media_block(false),
|
||||
in_declaration(false),
|
||||
in_space_array(false),
|
||||
in_comma_array(false)
|
||||
{ }
|
||||
|
||||
// return buffer as string
|
||||
sass::string Emitter::get_buffer(void)
|
||||
{
|
||||
return wbuf.buffer;
|
||||
}
|
||||
|
||||
Sass_Output_Style Emitter::output_style(void) const
|
||||
{
|
||||
return opt.output_style;
|
||||
}
|
||||
|
||||
// PROXY METHODS FOR SOURCE MAPS
|
||||
|
||||
void Emitter::add_source_index(size_t idx)
|
||||
{ wbuf.smap.source_index.push_back(idx); }
|
||||
|
||||
sass::string Emitter::render_srcmap(Context &ctx)
|
||||
{ return wbuf.smap.render_srcmap(ctx); }
|
||||
|
||||
void Emitter::set_filename(const sass::string& str)
|
||||
{ wbuf.smap.file = str; }
|
||||
|
||||
void Emitter::schedule_mapping(const AST_Node* node)
|
||||
{ scheduled_mapping = node; }
|
||||
void Emitter::add_open_mapping(const AST_Node* node)
|
||||
{ wbuf.smap.add_open_mapping(node); }
|
||||
void Emitter::add_close_mapping(const AST_Node* node)
|
||||
{ wbuf.smap.add_close_mapping(node); }
|
||||
SourceSpan Emitter::remap(const SourceSpan& pstate)
|
||||
{ return wbuf.smap.remap(pstate); }
|
||||
|
||||
// MAIN BUFFER MANIPULATION
|
||||
|
||||
// add outstanding delimiter
|
||||
void Emitter::finalize(bool final)
|
||||
{
|
||||
scheduled_space = 0;
|
||||
if (output_style() == SASS_STYLE_COMPRESSED)
|
||||
if (final) scheduled_delimiter = false;
|
||||
if (scheduled_linefeed)
|
||||
scheduled_linefeed = 1;
|
||||
flush_schedules();
|
||||
}
|
||||
|
||||
// flush scheduled space/linefeed
|
||||
void Emitter::flush_schedules(void)
|
||||
{
|
||||
// check the schedule
|
||||
if (scheduled_linefeed) {
|
||||
sass::string linefeeds = "";
|
||||
|
||||
for (size_t i = 0; i < scheduled_linefeed; i++)
|
||||
linefeeds += opt.linefeed;
|
||||
scheduled_space = 0;
|
||||
scheduled_linefeed = 0;
|
||||
append_string(linefeeds);
|
||||
|
||||
} else if (scheduled_space) {
|
||||
sass::string spaces(scheduled_space, ' ');
|
||||
scheduled_space = 0;
|
||||
append_string(spaces);
|
||||
}
|
||||
if (scheduled_delimiter) {
|
||||
scheduled_delimiter = false;
|
||||
append_string(";");
|
||||
}
|
||||
}
|
||||
|
||||
// prepend some text or token to the buffer
|
||||
void Emitter::prepend_output(const OutputBuffer& output)
|
||||
{
|
||||
wbuf.smap.prepend(output);
|
||||
wbuf.buffer = output.buffer + wbuf.buffer;
|
||||
}
|
||||
|
||||
// prepend some text or token to the buffer
|
||||
void Emitter::prepend_string(const sass::string& text)
|
||||
{
|
||||
// do not adjust mappings for utf8 bom
|
||||
// seems they are not counted in any UA
|
||||
if (text.compare("\xEF\xBB\xBF") != 0) {
|
||||
wbuf.smap.prepend(Offset(text));
|
||||
}
|
||||
wbuf.buffer = text + wbuf.buffer;
|
||||
}
|
||||
|
||||
char Emitter::last_char()
|
||||
{
|
||||
return wbuf.buffer.back();
|
||||
}
|
||||
|
||||
// append a single char to the buffer
|
||||
void Emitter::append_char(const char chr)
|
||||
{
|
||||
// write space/lf
|
||||
flush_schedules();
|
||||
// add to buffer
|
||||
wbuf.buffer += chr;
|
||||
// account for data in source-maps
|
||||
wbuf.smap.append(Offset(chr));
|
||||
}
|
||||
|
||||
// append some text or token to the buffer
|
||||
void Emitter::append_string(const sass::string& text)
|
||||
{
|
||||
|
||||
// write space/lf
|
||||
flush_schedules();
|
||||
|
||||
if (in_comment) {
|
||||
sass::string out = Util::normalize_newlines(text);
|
||||
if (output_style() == COMPACT) {
|
||||
out = comment_to_compact_string(out);
|
||||
}
|
||||
wbuf.smap.append(Offset(out));
|
||||
wbuf.buffer += std::move(out);
|
||||
} else {
|
||||
// add to buffer
|
||||
wbuf.buffer += text;
|
||||
// account for data in source-maps
|
||||
wbuf.smap.append(Offset(text));
|
||||
}
|
||||
}
|
||||
|
||||
// append some white-space only text
|
||||
void Emitter::append_wspace(const sass::string& text)
|
||||
{
|
||||
if (text.empty()) return;
|
||||
if (peek_linefeed(text.c_str())) {
|
||||
scheduled_space = 0;
|
||||
append_mandatory_linefeed();
|
||||
}
|
||||
}
|
||||
|
||||
// append some text or token to the buffer
|
||||
// this adds source-mappings for node start and end
|
||||
void Emitter::append_token(const sass::string& text, const AST_Node* node)
|
||||
{
|
||||
flush_schedules();
|
||||
add_open_mapping(node);
|
||||
// hotfix for browser issues
|
||||
// this is pretty ugly indeed
|
||||
if (scheduled_crutch) {
|
||||
add_open_mapping(scheduled_crutch);
|
||||
scheduled_crutch = 0;
|
||||
}
|
||||
append_string(text);
|
||||
add_close_mapping(node);
|
||||
}
|
||||
|
||||
// HELPER METHODS
|
||||
|
||||
void Emitter::append_indentation()
|
||||
{
|
||||
if (output_style() == COMPRESSED) return;
|
||||
if (output_style() == COMPACT) return;
|
||||
if (in_declaration && in_comma_array) return;
|
||||
if (scheduled_linefeed && indentation)
|
||||
scheduled_linefeed = 1;
|
||||
sass::string indent = "";
|
||||
for (size_t i = 0; i < indentation; i++)
|
||||
indent += opt.indent;
|
||||
append_string(indent);
|
||||
}
|
||||
|
||||
void Emitter::append_delimiter()
|
||||
{
|
||||
scheduled_delimiter = true;
|
||||
if (output_style() == COMPACT) {
|
||||
if (indentation == 0) {
|
||||
append_mandatory_linefeed();
|
||||
} else {
|
||||
append_mandatory_space();
|
||||
}
|
||||
} else if (output_style() != COMPRESSED) {
|
||||
append_optional_linefeed();
|
||||
}
|
||||
}
|
||||
|
||||
void Emitter::append_comma_separator()
|
||||
{
|
||||
// scheduled_space = 0;
|
||||
append_string(",");
|
||||
append_optional_space();
|
||||
}
|
||||
|
||||
void Emitter::append_colon_separator()
|
||||
{
|
||||
scheduled_space = 0;
|
||||
append_string(":");
|
||||
if (!in_custom_property) append_optional_space();
|
||||
}
|
||||
|
||||
void Emitter::append_mandatory_space()
|
||||
{
|
||||
scheduled_space = 1;
|
||||
}
|
||||
|
||||
void Emitter::append_optional_space()
|
||||
{
|
||||
if ((output_style() != COMPRESSED) && buffer().size()) {
|
||||
unsigned char lst = buffer().at(buffer().length() - 1);
|
||||
if (!isspace(lst) || scheduled_delimiter) {
|
||||
if (last_char() != '(') {
|
||||
append_mandatory_space();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void Emitter::append_special_linefeed()
|
||||
{
|
||||
if (output_style() == COMPACT) {
|
||||
append_mandatory_linefeed();
|
||||
for (size_t p = 0; p < indentation; p++)
|
||||
append_string(opt.indent);
|
||||
}
|
||||
}
|
||||
|
||||
void Emitter::append_optional_linefeed()
|
||||
{
|
||||
if (in_declaration && in_comma_array) return;
|
||||
if (output_style() == COMPACT) {
|
||||
append_mandatory_space();
|
||||
} else {
|
||||
append_mandatory_linefeed();
|
||||
}
|
||||
}
|
||||
|
||||
void Emitter::append_mandatory_linefeed()
|
||||
{
|
||||
if (output_style() != COMPRESSED) {
|
||||
scheduled_linefeed = 1;
|
||||
scheduled_space = 0;
|
||||
// flush_schedules();
|
||||
}
|
||||
}
|
||||
|
||||
void Emitter::append_scope_opener(AST_Node* node)
|
||||
{
|
||||
scheduled_linefeed = 0;
|
||||
append_optional_space();
|
||||
flush_schedules();
|
||||
if (node) add_open_mapping(node);
|
||||
append_string("{");
|
||||
append_optional_linefeed();
|
||||
// append_optional_space();
|
||||
++ indentation;
|
||||
}
|
||||
void Emitter::append_scope_closer(AST_Node* node)
|
||||
{
|
||||
-- indentation;
|
||||
scheduled_linefeed = 0;
|
||||
if (output_style() == COMPRESSED)
|
||||
scheduled_delimiter = false;
|
||||
if (output_style() == EXPANDED) {
|
||||
append_optional_linefeed();
|
||||
append_indentation();
|
||||
} else {
|
||||
append_optional_space();
|
||||
}
|
||||
append_string("}");
|
||||
if (node) add_close_mapping(node);
|
||||
append_optional_linefeed();
|
||||
if (indentation != 0) return;
|
||||
if (output_style() != COMPRESSED)
|
||||
scheduled_linefeed = 2;
|
||||
}
|
||||
|
||||
}
|
||||
101
vendor/bundle/ruby/2.6.0/gems/sassc-2.4.0/ext/libsass/src/emitter.hpp
vendored
Normal file
101
vendor/bundle/ruby/2.6.0/gems/sassc-2.4.0/ext/libsass/src/emitter.hpp
vendored
Normal file
@@ -0,0 +1,101 @@
|
||||
#ifndef SASS_EMITTER_H
|
||||
#define SASS_EMITTER_H
|
||||
|
||||
// sass.hpp must go before all system headers to get the
|
||||
// __EXTENSIONS__ fix on Solaris.
|
||||
#include "sass.hpp"
|
||||
|
||||
#include "sass/base.h"
|
||||
#include "source_map.hpp"
|
||||
#include "ast_fwd_decl.hpp"
|
||||
|
||||
namespace Sass {
|
||||
class Context;
|
||||
|
||||
class Emitter {
|
||||
|
||||
public:
|
||||
Emitter(struct Sass_Output_Options& opt);
|
||||
virtual ~Emitter() { }
|
||||
|
||||
protected:
|
||||
OutputBuffer wbuf;
|
||||
public:
|
||||
const sass::string& buffer(void) { return wbuf.buffer; }
|
||||
const SourceMap smap(void) { return wbuf.smap; }
|
||||
const OutputBuffer output(void) { return wbuf; }
|
||||
// proxy methods for source maps
|
||||
void add_source_index(size_t idx);
|
||||
void set_filename(const sass::string& str);
|
||||
void add_open_mapping(const AST_Node* node);
|
||||
void add_close_mapping(const AST_Node* node);
|
||||
void schedule_mapping(const AST_Node* node);
|
||||
sass::string render_srcmap(Context &ctx);
|
||||
SourceSpan remap(const SourceSpan& pstate);
|
||||
|
||||
public:
|
||||
struct Sass_Output_Options& opt;
|
||||
size_t indentation;
|
||||
size_t scheduled_space;
|
||||
size_t scheduled_linefeed;
|
||||
bool scheduled_delimiter;
|
||||
const AST_Node* scheduled_crutch;
|
||||
const AST_Node* scheduled_mapping;
|
||||
|
||||
public:
|
||||
// output strings different in custom css properties
|
||||
bool in_custom_property;
|
||||
// output strings different in comments
|
||||
bool in_comment;
|
||||
// selector list does not get linefeeds
|
||||
bool in_wrapped;
|
||||
// lists always get a space after delimiter
|
||||
bool in_media_block;
|
||||
// nested list must not have parentheses
|
||||
bool in_declaration;
|
||||
// nested lists need parentheses
|
||||
bool in_space_array;
|
||||
bool in_comma_array;
|
||||
|
||||
public:
|
||||
// return buffer as sass::string
|
||||
sass::string get_buffer(void);
|
||||
// flush scheduled space/linefeed
|
||||
Sass_Output_Style output_style(void) const;
|
||||
// add outstanding linefeed
|
||||
void finalize(bool final = true);
|
||||
// flush scheduled space/linefeed
|
||||
void flush_schedules(void);
|
||||
// prepend some text or token to the buffer
|
||||
void prepend_string(const sass::string& text);
|
||||
void prepend_output(const OutputBuffer& out);
|
||||
// append some text or token to the buffer
|
||||
void append_string(const sass::string& text);
|
||||
// append a single character to buffer
|
||||
void append_char(const char chr);
|
||||
// append some white-space only text
|
||||
void append_wspace(const sass::string& text);
|
||||
// append some text or token to the buffer
|
||||
// this adds source-mappings for node start and end
|
||||
void append_token(const sass::string& text, const AST_Node* node);
|
||||
// query last appended character
|
||||
char last_char();
|
||||
|
||||
public: // syntax sugar
|
||||
void append_indentation();
|
||||
void append_optional_space(void);
|
||||
void append_mandatory_space(void);
|
||||
void append_special_linefeed(void);
|
||||
void append_optional_linefeed(void);
|
||||
void append_mandatory_linefeed(void);
|
||||
void append_scope_opener(AST_Node* node = 0);
|
||||
void append_scope_closer(AST_Node* node = 0);
|
||||
void append_comma_separator(void);
|
||||
void append_colon_separator(void);
|
||||
void append_delimiter(void);
|
||||
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
260
vendor/bundle/ruby/2.6.0/gems/sassc-2.4.0/ext/libsass/src/environment.cpp
vendored
Normal file
260
vendor/bundle/ruby/2.6.0/gems/sassc-2.4.0/ext/libsass/src/environment.cpp
vendored
Normal file
@@ -0,0 +1,260 @@
|
||||
#include "sass.hpp"
|
||||
#include "ast.hpp"
|
||||
#include "environment.hpp"
|
||||
|
||||
namespace Sass {
|
||||
|
||||
template <typename T>
|
||||
Environment<T>::Environment(bool is_shadow)
|
||||
: local_frame_(environment_map<sass::string, T>()),
|
||||
parent_(0), is_shadow_(false)
|
||||
{ }
|
||||
template <typename T>
|
||||
Environment<T>::Environment(Environment<T>* env, bool is_shadow)
|
||||
: local_frame_(environment_map<sass::string, T>()),
|
||||
parent_(env), is_shadow_(is_shadow)
|
||||
{ }
|
||||
template <typename T>
|
||||
Environment<T>::Environment(Environment<T>& env, bool is_shadow)
|
||||
: local_frame_(environment_map<sass::string, T>()),
|
||||
parent_(&env), is_shadow_(is_shadow)
|
||||
{ }
|
||||
|
||||
// link parent to create a stack
|
||||
template <typename T>
|
||||
void Environment<T>::link(Environment& env) { parent_ = &env; }
|
||||
template <typename T>
|
||||
void Environment<T>::link(Environment* env) { parent_ = env; }
|
||||
|
||||
// this is used to find the global frame
|
||||
// which is the second last on the stack
|
||||
template <typename T>
|
||||
bool Environment<T>::is_lexical() const
|
||||
{
|
||||
return !! parent_ && parent_->parent_;
|
||||
}
|
||||
|
||||
// only match the real root scope
|
||||
// there is still a parent around
|
||||
// not sure what it is actually use for
|
||||
// I guess we store functions etc. there
|
||||
template <typename T>
|
||||
bool Environment<T>::is_global() const
|
||||
{
|
||||
return parent_ && ! parent_->parent_;
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
environment_map<sass::string, T>& Environment<T>::local_frame() {
|
||||
return local_frame_;
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
bool Environment<T>::has_local(const sass::string& key) const
|
||||
{ return local_frame_.find(key) != local_frame_.end(); }
|
||||
|
||||
template <typename T> EnvResult
|
||||
Environment<T>::find_local(const sass::string& key)
|
||||
{
|
||||
auto end = local_frame_.end();
|
||||
auto it = local_frame_.find(key);
|
||||
return EnvResult(it, it != end);
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
T& Environment<T>::get_local(const sass::string& key)
|
||||
{ return local_frame_[key]; }
|
||||
|
||||
template <typename T>
|
||||
void Environment<T>::set_local(const sass::string& key, const T& val)
|
||||
{
|
||||
local_frame_[key] = val;
|
||||
}
|
||||
template <typename T>
|
||||
void Environment<T>::set_local(const sass::string& key, T&& val)
|
||||
{
|
||||
local_frame_[key] = val;
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
void Environment<T>::del_local(const sass::string& key)
|
||||
{ local_frame_.erase(key); }
|
||||
|
||||
template <typename T>
|
||||
Environment<T>* Environment<T>::global_env()
|
||||
{
|
||||
Environment* cur = this;
|
||||
while (cur->is_lexical()) {
|
||||
cur = cur->parent_;
|
||||
}
|
||||
return cur;
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
bool Environment<T>::has_global(const sass::string& key)
|
||||
{ return global_env()->has(key); }
|
||||
|
||||
template <typename T>
|
||||
T& Environment<T>::get_global(const sass::string& key)
|
||||
{ return (*global_env())[key]; }
|
||||
|
||||
template <typename T>
|
||||
void Environment<T>::set_global(const sass::string& key, const T& val)
|
||||
{
|
||||
global_env()->local_frame_[key] = val;
|
||||
}
|
||||
template <typename T>
|
||||
void Environment<T>::set_global(const sass::string& key, T&& val)
|
||||
{
|
||||
global_env()->local_frame_[key] = val;
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
void Environment<T>::del_global(const sass::string& key)
|
||||
{ global_env()->local_frame_.erase(key); }
|
||||
|
||||
template <typename T>
|
||||
Environment<T>* Environment<T>::lexical_env(const sass::string& key)
|
||||
{
|
||||
Environment* cur = this;
|
||||
while (cur) {
|
||||
if (cur->has_local(key)) {
|
||||
return cur;
|
||||
}
|
||||
cur = cur->parent_;
|
||||
}
|
||||
return this;
|
||||
}
|
||||
|
||||
// see if we have a lexical variable
|
||||
// move down the stack but stop before we
|
||||
// reach the global frame (is not included)
|
||||
template <typename T>
|
||||
bool Environment<T>::has_lexical(const sass::string& key) const
|
||||
{
|
||||
auto cur = this;
|
||||
while (cur->is_lexical()) {
|
||||
if (cur->has_local(key)) return true;
|
||||
cur = cur->parent_;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
// see if we have a lexical we could update
|
||||
// either update already existing lexical value
|
||||
// or if flag is set, we create one if no lexical found
|
||||
template <typename T>
|
||||
void Environment<T>::set_lexical(const sass::string& key, const T& val)
|
||||
{
|
||||
Environment<T>* cur = this;
|
||||
bool shadow = false;
|
||||
while ((cur && cur->is_lexical()) || shadow) {
|
||||
EnvResult rv(cur->find_local(key));
|
||||
if (rv.found) {
|
||||
rv.it->second = val;
|
||||
return;
|
||||
}
|
||||
shadow = cur->is_shadow();
|
||||
cur = cur->parent_;
|
||||
}
|
||||
set_local(key, val);
|
||||
}
|
||||
// this one moves the value
|
||||
template <typename T>
|
||||
void Environment<T>::set_lexical(const sass::string& key, T&& val)
|
||||
{
|
||||
Environment<T>* cur = this;
|
||||
bool shadow = false;
|
||||
while ((cur && cur->is_lexical()) || shadow) {
|
||||
EnvResult rv(cur->find_local(key));
|
||||
if (rv.found) {
|
||||
rv.it->second = val;
|
||||
return;
|
||||
}
|
||||
shadow = cur->is_shadow();
|
||||
cur = cur->parent_;
|
||||
}
|
||||
set_local(key, val);
|
||||
}
|
||||
|
||||
// look on the full stack for key
|
||||
// include all scopes available
|
||||
template <typename T>
|
||||
bool Environment<T>::has(const sass::string& key) const
|
||||
{
|
||||
auto cur = this;
|
||||
while (cur) {
|
||||
if (cur->has_local(key)) {
|
||||
return true;
|
||||
}
|
||||
cur = cur->parent_;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
// look on the full stack for key
|
||||
// include all scopes available
|
||||
template <typename T> EnvResult
|
||||
Environment<T>::find(const sass::string& key)
|
||||
{
|
||||
auto cur = this;
|
||||
while (true) {
|
||||
EnvResult rv(cur->find_local(key));
|
||||
if (rv.found) return rv;
|
||||
cur = cur->parent_;
|
||||
if (!cur) return rv;
|
||||
}
|
||||
};
|
||||
|
||||
// use array access for getter and setter functions
|
||||
template <typename T>
|
||||
T& Environment<T>::get(const sass::string& key)
|
||||
{
|
||||
auto cur = this;
|
||||
while (cur) {
|
||||
if (cur->has_local(key)) {
|
||||
return cur->get_local(key);
|
||||
}
|
||||
cur = cur->parent_;
|
||||
}
|
||||
return get_local(key);
|
||||
}
|
||||
|
||||
// use array access for getter and setter functions
|
||||
template <typename T>
|
||||
T& Environment<T>::operator[](const sass::string& key)
|
||||
{
|
||||
auto cur = this;
|
||||
while (cur) {
|
||||
if (cur->has_local(key)) {
|
||||
return cur->get_local(key);
|
||||
}
|
||||
cur = cur->parent_;
|
||||
}
|
||||
return get_local(key);
|
||||
}
|
||||
/*
|
||||
#ifdef DEBUG
|
||||
template <typename T>
|
||||
size_t Environment<T>::print(sass::string prefix)
|
||||
{
|
||||
size_t indent = 0;
|
||||
if (parent_) indent = parent_->print(prefix) + 1;
|
||||
std::cerr << prefix << sass::string(indent, ' ') << "== " << this << std::endl;
|
||||
for (typename environment_map<sass::string, T>::iterator i = local_frame_.begin(); i != local_frame_.end(); ++i) {
|
||||
if (!ends_with(i->first, "[f]") && !ends_with(i->first, "[f]4") && !ends_with(i->first, "[f]2")) {
|
||||
std::cerr << prefix << sass::string(indent, ' ') << i->first << " " << i->second;
|
||||
if (Value* val = Cast<Value>(i->second))
|
||||
{ std::cerr << " : " << val->to_string(); }
|
||||
std::cerr << std::endl;
|
||||
}
|
||||
}
|
||||
return indent ;
|
||||
}
|
||||
#endif
|
||||
*/
|
||||
// compile implementation for AST_Node
|
||||
template class Environment<AST_Node_Obj>;
|
||||
|
||||
}
|
||||
|
||||
124
vendor/bundle/ruby/2.6.0/gems/sassc-2.4.0/ext/libsass/src/environment.hpp
vendored
Normal file
124
vendor/bundle/ruby/2.6.0/gems/sassc-2.4.0/ext/libsass/src/environment.hpp
vendored
Normal file
@@ -0,0 +1,124 @@
|
||||
#ifndef SASS_ENVIRONMENT_H
|
||||
#define SASS_ENVIRONMENT_H
|
||||
|
||||
// sass.hpp must go before all system headers to get the
|
||||
// __EXTENSIONS__ fix on Solaris.
|
||||
#include "sass.hpp"
|
||||
|
||||
#include <map>
|
||||
#include <string>
|
||||
#include "ast_fwd_decl.hpp"
|
||||
#include "ast_def_macros.hpp"
|
||||
|
||||
namespace Sass {
|
||||
|
||||
// this defeats the whole purpose of environment being templatable!!
|
||||
typedef environment_map<sass::string, AST_Node_Obj>::iterator EnvIter;
|
||||
|
||||
class EnvResult {
|
||||
public:
|
||||
EnvIter it;
|
||||
bool found;
|
||||
public:
|
||||
EnvResult(EnvIter it, bool found)
|
||||
: it(it), found(found) {}
|
||||
};
|
||||
|
||||
template <typename T>
|
||||
class Environment {
|
||||
// TODO: test with map
|
||||
environment_map<sass::string, T> local_frame_;
|
||||
ADD_PROPERTY(Environment*, parent)
|
||||
ADD_PROPERTY(bool, is_shadow)
|
||||
|
||||
public:
|
||||
Environment(bool is_shadow = false);
|
||||
Environment(Environment* env, bool is_shadow = false);
|
||||
Environment(Environment& env, bool is_shadow = false);
|
||||
|
||||
// link parent to create a stack
|
||||
void link(Environment& env);
|
||||
void link(Environment* env);
|
||||
|
||||
// this is used to find the global frame
|
||||
// which is the second last on the stack
|
||||
bool is_lexical() const;
|
||||
|
||||
// only match the real root scope
|
||||
// there is still a parent around
|
||||
// not sure what it is actually use for
|
||||
// I guess we store functions etc. there
|
||||
bool is_global() const;
|
||||
|
||||
// scope operates on the current frame
|
||||
|
||||
environment_map<sass::string, T>& local_frame();
|
||||
|
||||
bool has_local(const sass::string& key) const;
|
||||
|
||||
EnvResult find_local(const sass::string& key);
|
||||
|
||||
T& get_local(const sass::string& key);
|
||||
|
||||
// set variable on the current frame
|
||||
void set_local(const sass::string& key, const T& val);
|
||||
void set_local(const sass::string& key, T&& val);
|
||||
|
||||
void del_local(const sass::string& key);
|
||||
|
||||
// global operates on the global frame
|
||||
// which is the second last on the stack
|
||||
Environment* global_env();
|
||||
// get the env where the variable already exists
|
||||
// if it does not yet exist, we return current env
|
||||
Environment* lexical_env(const sass::string& key);
|
||||
|
||||
bool has_global(const sass::string& key);
|
||||
|
||||
T& get_global(const sass::string& key);
|
||||
|
||||
// set a variable on the global frame
|
||||
void set_global(const sass::string& key, const T& val);
|
||||
void set_global(const sass::string& key, T&& val);
|
||||
|
||||
void del_global(const sass::string& key);
|
||||
|
||||
// see if we have a lexical variable
|
||||
// move down the stack but stop before we
|
||||
// reach the global frame (is not included)
|
||||
bool has_lexical(const sass::string& key) const;
|
||||
|
||||
// see if we have a lexical we could update
|
||||
// either update already existing lexical value
|
||||
// or we create a new one on the current frame
|
||||
void set_lexical(const sass::string& key, T&& val);
|
||||
void set_lexical(const sass::string& key, const T& val);
|
||||
|
||||
// look on the full stack for key
|
||||
// include all scopes available
|
||||
bool has(const sass::string& key) const;
|
||||
|
||||
// look on the full stack for key
|
||||
// include all scopes available
|
||||
T& get(const sass::string& key);
|
||||
|
||||
// look on the full stack for key
|
||||
// include all scopes available
|
||||
EnvResult find(const sass::string& key);
|
||||
|
||||
// use array access for getter and setter functions
|
||||
T& operator[](const sass::string& key);
|
||||
|
||||
#ifdef DEBUG
|
||||
size_t print(sass::string prefix = "");
|
||||
#endif
|
||||
|
||||
};
|
||||
|
||||
// define typedef for our use case
|
||||
typedef Environment<AST_Node_Obj> Env;
|
||||
typedef sass::vector<Env*> EnvStack;
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
233
vendor/bundle/ruby/2.6.0/gems/sassc-2.4.0/ext/libsass/src/error_handling.cpp
vendored
Normal file
233
vendor/bundle/ruby/2.6.0/gems/sassc-2.4.0/ext/libsass/src/error_handling.cpp
vendored
Normal file
@@ -0,0 +1,233 @@
|
||||
// sass.hpp must go before all system headers to get the
|
||||
// __EXTENSIONS__ fix on Solaris.
|
||||
#include "sass.hpp"
|
||||
|
||||
#include "ast.hpp"
|
||||
#include "prelexer.hpp"
|
||||
#include "backtrace.hpp"
|
||||
#include "error_handling.hpp"
|
||||
|
||||
#include <iostream>
|
||||
|
||||
namespace Sass {
|
||||
|
||||
namespace Exception {
|
||||
|
||||
Base::Base(SourceSpan pstate, sass::string msg, Backtraces traces)
|
||||
: std::runtime_error(msg.c_str()), msg(msg),
|
||||
prefix("Error"), pstate(pstate), traces(traces)
|
||||
{ }
|
||||
|
||||
InvalidSass::InvalidSass(SourceSpan pstate, Backtraces traces, sass::string msg)
|
||||
: Base(pstate, msg, traces)
|
||||
{ }
|
||||
|
||||
|
||||
InvalidParent::InvalidParent(Selector* parent, Backtraces traces, Selector* selector)
|
||||
: Base(selector->pstate(), def_msg, traces), parent(parent), selector(selector)
|
||||
{
|
||||
msg = "Invalid parent selector for "
|
||||
"\"" + selector->to_string(Sass_Inspect_Options()) + "\": "
|
||||
"\"" + parent->to_string(Sass_Inspect_Options()) + "\"";
|
||||
}
|
||||
|
||||
InvalidVarKwdType::InvalidVarKwdType(SourceSpan pstate, Backtraces traces, sass::string name, const Argument* arg)
|
||||
: Base(pstate, def_msg, traces), name(name), arg(arg)
|
||||
{
|
||||
msg = "Variable keyword argument map must have string keys.\n" +
|
||||
name + " is not a string in " + arg->to_string() + ".";
|
||||
}
|
||||
|
||||
InvalidArgumentType::InvalidArgumentType(SourceSpan pstate, Backtraces traces, sass::string fn, sass::string arg, sass::string type, const Value* value)
|
||||
: Base(pstate, def_msg, traces), fn(fn), arg(arg), type(type), value(value)
|
||||
{
|
||||
msg = arg + ": \"";
|
||||
if (value) msg += value->to_string(Sass_Inspect_Options());
|
||||
msg += "\" is not a " + type + " for `" + fn + "'";
|
||||
}
|
||||
|
||||
MissingArgument::MissingArgument(SourceSpan pstate, Backtraces traces, sass::string fn, sass::string arg, sass::string fntype)
|
||||
: Base(pstate, def_msg, traces), fn(fn), arg(arg), fntype(fntype)
|
||||
{
|
||||
msg = fntype + " " + fn + " is missing argument " + arg + ".";
|
||||
}
|
||||
|
||||
InvalidSyntax::InvalidSyntax(SourceSpan pstate, Backtraces traces, sass::string msg)
|
||||
: Base(pstate, msg, traces)
|
||||
{ }
|
||||
|
||||
NestingLimitError::NestingLimitError(SourceSpan pstate, Backtraces traces, sass::string msg)
|
||||
: Base(pstate, msg, traces)
|
||||
{ }
|
||||
|
||||
DuplicateKeyError::DuplicateKeyError(Backtraces traces, const Map& dup, const Expression& org)
|
||||
: Base(org.pstate(), def_msg, traces), dup(dup), org(org)
|
||||
{
|
||||
msg = "Duplicate key " + dup.get_duplicate_key()->inspect() + " in map (" + org.inspect() + ").";
|
||||
}
|
||||
|
||||
TypeMismatch::TypeMismatch(Backtraces traces, const Expression& var, const sass::string type)
|
||||
: Base(var.pstate(), def_msg, traces), var(var), type(type)
|
||||
{
|
||||
msg = var.to_string() + " is not an " + type + ".";
|
||||
}
|
||||
|
||||
InvalidValue::InvalidValue(Backtraces traces, const Expression& val)
|
||||
: Base(val.pstate(), def_msg, traces), val(val)
|
||||
{
|
||||
msg = val.to_string() + " isn't a valid CSS value.";
|
||||
}
|
||||
|
||||
StackError::StackError(Backtraces traces, const AST_Node& node)
|
||||
: Base(node.pstate(), def_msg, traces), node(node)
|
||||
{
|
||||
msg = "stack level too deep";
|
||||
}
|
||||
|
||||
IncompatibleUnits::IncompatibleUnits(const Units& lhs, const Units& rhs)
|
||||
{
|
||||
msg = "Incompatible units: '" + rhs.unit() + "' and '" + lhs.unit() + "'.";
|
||||
}
|
||||
|
||||
IncompatibleUnits::IncompatibleUnits(const UnitType lhs, const UnitType rhs)
|
||||
{
|
||||
msg = sass::string("Incompatible units: '") + unit_to_string(rhs) + "' and '" + unit_to_string(lhs) + "'.";
|
||||
}
|
||||
|
||||
AlphaChannelsNotEqual::AlphaChannelsNotEqual(const Expression* lhs, const Expression* rhs, enum Sass_OP op)
|
||||
: OperationError(), lhs(lhs), rhs(rhs), op(op)
|
||||
{
|
||||
msg = "Alpha channels must be equal: " +
|
||||
lhs->to_string({ NESTED, 5 }) +
|
||||
" " + sass_op_to_name(op) + " " +
|
||||
rhs->to_string({ NESTED, 5 }) + ".";
|
||||
}
|
||||
|
||||
ZeroDivisionError::ZeroDivisionError(const Expression& lhs, const Expression& rhs)
|
||||
: OperationError(), lhs(lhs), rhs(rhs)
|
||||
{
|
||||
msg = "divided by 0";
|
||||
}
|
||||
|
||||
UndefinedOperation::UndefinedOperation(const Expression* lhs, const Expression* rhs, enum Sass_OP op)
|
||||
: OperationError(), lhs(lhs), rhs(rhs), op(op)
|
||||
{
|
||||
msg = def_op_msg + ": \"" +
|
||||
lhs->to_string({ NESTED, 5 }) +
|
||||
" " + sass_op_to_name(op) + " " +
|
||||
rhs->to_string({ TO_SASS, 5 }) +
|
||||
"\".";
|
||||
}
|
||||
|
||||
InvalidNullOperation::InvalidNullOperation(const Expression* lhs, const Expression* rhs, enum Sass_OP op)
|
||||
: UndefinedOperation(lhs, rhs, op)
|
||||
{
|
||||
msg = def_op_null_msg + ": \"" + lhs->inspect() + " " + sass_op_to_name(op) + " " + rhs->inspect() + "\".";
|
||||
}
|
||||
|
||||
SassValueError::SassValueError(Backtraces traces, SourceSpan pstate, OperationError& err)
|
||||
: Base(pstate, err.what(), traces)
|
||||
{
|
||||
msg = err.what();
|
||||
prefix = err.errtype();
|
||||
}
|
||||
|
||||
TopLevelParent::TopLevelParent(Backtraces traces, SourceSpan pstate)
|
||||
: Base(pstate, "Top-level selectors may not contain the parent selector \"&\".", traces)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
UnsatisfiedExtend::UnsatisfiedExtend(Backtraces traces, Extension extension)
|
||||
: Base(extension.target->pstate(), "The target selector was not found.\n"
|
||||
"Use \"@extend " + extension.target->to_string() + " !optional\" to avoid this error.", traces)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
ExtendAcrossMedia::ExtendAcrossMedia(Backtraces traces, Extension extension)
|
||||
: Base(extension.target->pstate(), "You may not @extend selectors across media queries.\n"
|
||||
"Use \"@extend " + extension.target->to_string() + " !optional\" to avoid this error.", traces)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
void warn(sass::string msg, SourceSpan pstate)
|
||||
{
|
||||
std::cerr << "Warning: " << msg << std::endl;
|
||||
}
|
||||
|
||||
void warning(sass::string msg, SourceSpan pstate)
|
||||
{
|
||||
sass::string cwd(Sass::File::get_cwd());
|
||||
sass::string abs_path(Sass::File::rel2abs(pstate.getPath(), cwd, cwd));
|
||||
sass::string rel_path(Sass::File::abs2rel(pstate.getPath(), cwd, cwd));
|
||||
sass::string output_path(Sass::File::path_for_console(rel_path, abs_path, pstate.getPath()));
|
||||
|
||||
std::cerr << "WARNING on line " << pstate.getLine() << ", column " << pstate.getColumn() << " of " << output_path << ":" << std::endl;
|
||||
std::cerr << msg << std::endl << std::endl;
|
||||
}
|
||||
|
||||
void warn(sass::string msg, SourceSpan pstate, Backtrace* bt)
|
||||
{
|
||||
warn(msg, pstate);
|
||||
}
|
||||
|
||||
void deprecated_function(sass::string msg, SourceSpan pstate)
|
||||
{
|
||||
sass::string cwd(Sass::File::get_cwd());
|
||||
sass::string abs_path(Sass::File::rel2abs(pstate.getPath(), cwd, cwd));
|
||||
sass::string rel_path(Sass::File::abs2rel(pstate.getPath(), cwd, cwd));
|
||||
sass::string output_path(Sass::File::path_for_console(rel_path, abs_path, pstate.getPath()));
|
||||
|
||||
std::cerr << "DEPRECATION WARNING: " << msg << std::endl;
|
||||
std::cerr << "will be an error in future versions of Sass." << std::endl;
|
||||
std::cerr << " on line " << pstate.getLine() << " of " << output_path << std::endl;
|
||||
}
|
||||
|
||||
void deprecated(sass::string msg, sass::string msg2, bool with_column, SourceSpan pstate)
|
||||
{
|
||||
sass::string cwd(Sass::File::get_cwd());
|
||||
sass::string abs_path(Sass::File::rel2abs(pstate.getPath(), cwd, cwd));
|
||||
sass::string rel_path(Sass::File::abs2rel(pstate.getPath(), cwd, cwd));
|
||||
sass::string output_path(Sass::File::path_for_console(rel_path, pstate.getPath(), pstate.getPath()));
|
||||
|
||||
std::cerr << "DEPRECATION WARNING on line " << pstate.getLine();
|
||||
// if (with_column) std::cerr << ", column " << pstate.column + pstate.offset.column + 1;
|
||||
if (output_path.length()) std::cerr << " of " << output_path;
|
||||
std::cerr << ":" << std::endl;
|
||||
std::cerr << msg << std::endl;
|
||||
if (msg2.length()) std::cerr << msg2 << std::endl;
|
||||
std::cerr << std::endl;
|
||||
}
|
||||
|
||||
void deprecated_bind(sass::string msg, SourceSpan pstate)
|
||||
{
|
||||
sass::string cwd(Sass::File::get_cwd());
|
||||
sass::string abs_path(Sass::File::rel2abs(pstate.getPath(), cwd, cwd));
|
||||
sass::string rel_path(Sass::File::abs2rel(pstate.getPath(), cwd, cwd));
|
||||
sass::string output_path(Sass::File::path_for_console(rel_path, abs_path, pstate.getPath()));
|
||||
|
||||
std::cerr << "WARNING: " << msg << std::endl;
|
||||
std::cerr << " on line " << pstate.getLine() << " of " << output_path << std::endl;
|
||||
std::cerr << "This will be an error in future versions of Sass." << std::endl;
|
||||
}
|
||||
|
||||
// should be replaced with error with backtraces
|
||||
void coreError(sass::string msg, SourceSpan pstate)
|
||||
{
|
||||
Backtraces traces;
|
||||
throw Exception::InvalidSyntax(pstate, traces, msg);
|
||||
}
|
||||
|
||||
void error(sass::string msg, SourceSpan pstate, Backtraces& traces)
|
||||
{
|
||||
traces.push_back(Backtrace(pstate));
|
||||
throw Exception::InvalidSyntax(pstate, traces, msg);
|
||||
}
|
||||
|
||||
}
|
||||
239
vendor/bundle/ruby/2.6.0/gems/sassc-2.4.0/ext/libsass/src/error_handling.hpp
vendored
Normal file
239
vendor/bundle/ruby/2.6.0/gems/sassc-2.4.0/ext/libsass/src/error_handling.hpp
vendored
Normal file
@@ -0,0 +1,239 @@
|
||||
#ifndef SASS_ERROR_HANDLING_H
|
||||
#define SASS_ERROR_HANDLING_H
|
||||
|
||||
// sass.hpp must go before all system headers to get the
|
||||
// __EXTENSIONS__ fix on Solaris.
|
||||
#include "sass.hpp"
|
||||
|
||||
#include <string>
|
||||
#include <sstream>
|
||||
#include <stdexcept>
|
||||
#include "units.hpp"
|
||||
#include "position.hpp"
|
||||
#include "backtrace.hpp"
|
||||
#include "ast_fwd_decl.hpp"
|
||||
#include "sass/functions.h"
|
||||
|
||||
namespace Sass {
|
||||
|
||||
struct Backtrace;
|
||||
|
||||
namespace Exception {
|
||||
|
||||
const sass::string def_msg = "Invalid sass detected";
|
||||
const sass::string def_op_msg = "Undefined operation";
|
||||
const sass::string def_op_null_msg = "Invalid null operation";
|
||||
const sass::string def_nesting_limit = "Code too deeply nested";
|
||||
|
||||
class Base : public std::runtime_error {
|
||||
protected:
|
||||
sass::string msg;
|
||||
sass::string prefix;
|
||||
public:
|
||||
SourceSpan pstate;
|
||||
Backtraces traces;
|
||||
public:
|
||||
Base(SourceSpan pstate, sass::string msg, Backtraces traces);
|
||||
virtual const char* errtype() const { return prefix.c_str(); }
|
||||
virtual const char* what() const throw() { return msg.c_str(); }
|
||||
virtual ~Base() throw() {};
|
||||
};
|
||||
|
||||
class InvalidSass : public Base {
|
||||
public:
|
||||
InvalidSass(SourceSpan pstate, Backtraces traces, sass::string msg);
|
||||
virtual ~InvalidSass() throw() {};
|
||||
};
|
||||
|
||||
class InvalidParent : public Base {
|
||||
protected:
|
||||
Selector* parent;
|
||||
Selector* selector;
|
||||
public:
|
||||
InvalidParent(Selector* parent, Backtraces traces, Selector* selector);
|
||||
virtual ~InvalidParent() throw() {};
|
||||
};
|
||||
|
||||
class MissingArgument : public Base {
|
||||
protected:
|
||||
sass::string fn;
|
||||
sass::string arg;
|
||||
sass::string fntype;
|
||||
public:
|
||||
MissingArgument(SourceSpan pstate, Backtraces traces, sass::string fn, sass::string arg, sass::string fntype);
|
||||
virtual ~MissingArgument() throw() {};
|
||||
};
|
||||
|
||||
class InvalidArgumentType : public Base {
|
||||
protected:
|
||||
sass::string fn;
|
||||
sass::string arg;
|
||||
sass::string type;
|
||||
const Value* value;
|
||||
public:
|
||||
InvalidArgumentType(SourceSpan pstate, Backtraces traces, sass::string fn, sass::string arg, sass::string type, const Value* value = 0);
|
||||
virtual ~InvalidArgumentType() throw() {};
|
||||
};
|
||||
|
||||
class InvalidVarKwdType : public Base {
|
||||
protected:
|
||||
sass::string name;
|
||||
const Argument* arg;
|
||||
public:
|
||||
InvalidVarKwdType(SourceSpan pstate, Backtraces traces, sass::string name, const Argument* arg = 0);
|
||||
virtual ~InvalidVarKwdType() throw() {};
|
||||
};
|
||||
|
||||
class InvalidSyntax : public Base {
|
||||
public:
|
||||
InvalidSyntax(SourceSpan pstate, Backtraces traces, sass::string msg);
|
||||
virtual ~InvalidSyntax() throw() {};
|
||||
};
|
||||
|
||||
class NestingLimitError : public Base {
|
||||
public:
|
||||
NestingLimitError(SourceSpan pstate, Backtraces traces, sass::string msg = def_nesting_limit);
|
||||
virtual ~NestingLimitError() throw() {};
|
||||
};
|
||||
|
||||
class DuplicateKeyError : public Base {
|
||||
protected:
|
||||
const Map& dup;
|
||||
const Expression& org;
|
||||
public:
|
||||
DuplicateKeyError(Backtraces traces, const Map& dup, const Expression& org);
|
||||
virtual const char* errtype() const { return "Error"; }
|
||||
virtual ~DuplicateKeyError() throw() {};
|
||||
};
|
||||
|
||||
class TypeMismatch : public Base {
|
||||
protected:
|
||||
const Expression& var;
|
||||
const sass::string type;
|
||||
public:
|
||||
TypeMismatch(Backtraces traces, const Expression& var, const sass::string type);
|
||||
virtual const char* errtype() const { return "Error"; }
|
||||
virtual ~TypeMismatch() throw() {};
|
||||
};
|
||||
|
||||
class InvalidValue : public Base {
|
||||
protected:
|
||||
const Expression& val;
|
||||
public:
|
||||
InvalidValue(Backtraces traces, const Expression& val);
|
||||
virtual const char* errtype() const { return "Error"; }
|
||||
virtual ~InvalidValue() throw() {};
|
||||
};
|
||||
|
||||
class StackError : public Base {
|
||||
protected:
|
||||
const AST_Node& node;
|
||||
public:
|
||||
StackError(Backtraces traces, const AST_Node& node);
|
||||
virtual const char* errtype() const { return "SystemStackError"; }
|
||||
virtual ~StackError() throw() {};
|
||||
};
|
||||
|
||||
/* common virtual base class (has no pstate or trace) */
|
||||
class OperationError : public std::runtime_error {
|
||||
protected:
|
||||
sass::string msg;
|
||||
public:
|
||||
OperationError(sass::string msg = def_op_msg)
|
||||
: std::runtime_error(msg.c_str()), msg(msg)
|
||||
{};
|
||||
public:
|
||||
virtual const char* errtype() const { return "Error"; }
|
||||
virtual const char* what() const throw() { return msg.c_str(); }
|
||||
virtual ~OperationError() throw() {};
|
||||
};
|
||||
|
||||
class ZeroDivisionError : public OperationError {
|
||||
protected:
|
||||
const Expression& lhs;
|
||||
const Expression& rhs;
|
||||
public:
|
||||
ZeroDivisionError(const Expression& lhs, const Expression& rhs);
|
||||
virtual const char* errtype() const { return "ZeroDivisionError"; }
|
||||
virtual ~ZeroDivisionError() throw() {};
|
||||
};
|
||||
|
||||
class IncompatibleUnits : public OperationError {
|
||||
protected:
|
||||
// const Sass::UnitType lhs;
|
||||
// const Sass::UnitType rhs;
|
||||
public:
|
||||
IncompatibleUnits(const Units& lhs, const Units& rhs);
|
||||
IncompatibleUnits(const UnitType lhs, const UnitType rhs);
|
||||
virtual ~IncompatibleUnits() throw() {};
|
||||
};
|
||||
|
||||
class UndefinedOperation : public OperationError {
|
||||
protected:
|
||||
const Expression* lhs;
|
||||
const Expression* rhs;
|
||||
const Sass_OP op;
|
||||
public:
|
||||
UndefinedOperation(const Expression* lhs, const Expression* rhs, enum Sass_OP op);
|
||||
// virtual const char* errtype() const { return "Error"; }
|
||||
virtual ~UndefinedOperation() throw() {};
|
||||
};
|
||||
|
||||
class InvalidNullOperation : public UndefinedOperation {
|
||||
public:
|
||||
InvalidNullOperation(const Expression* lhs, const Expression* rhs, enum Sass_OP op);
|
||||
virtual ~InvalidNullOperation() throw() {};
|
||||
};
|
||||
|
||||
class AlphaChannelsNotEqual : public OperationError {
|
||||
protected:
|
||||
const Expression* lhs;
|
||||
const Expression* rhs;
|
||||
const Sass_OP op;
|
||||
public:
|
||||
AlphaChannelsNotEqual(const Expression* lhs, const Expression* rhs, enum Sass_OP op);
|
||||
// virtual const char* errtype() const { return "Error"; }
|
||||
virtual ~AlphaChannelsNotEqual() throw() {};
|
||||
};
|
||||
|
||||
class SassValueError : public Base {
|
||||
public:
|
||||
SassValueError(Backtraces traces, SourceSpan pstate, OperationError& err);
|
||||
virtual ~SassValueError() throw() {};
|
||||
};
|
||||
|
||||
class TopLevelParent : public Base {
|
||||
public:
|
||||
TopLevelParent(Backtraces traces, SourceSpan pstate);
|
||||
virtual ~TopLevelParent() throw() {};
|
||||
};
|
||||
|
||||
class UnsatisfiedExtend : public Base {
|
||||
public:
|
||||
UnsatisfiedExtend(Backtraces traces, Extension extension);
|
||||
virtual ~UnsatisfiedExtend() throw() {};
|
||||
};
|
||||
|
||||
class ExtendAcrossMedia : public Base {
|
||||
public:
|
||||
ExtendAcrossMedia(Backtraces traces, Extension extension);
|
||||
virtual ~ExtendAcrossMedia() throw() {};
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
void warn(sass::string msg, SourceSpan pstate);
|
||||
void warn(sass::string msg, SourceSpan pstate, Backtrace* bt);
|
||||
void warning(sass::string msg, SourceSpan pstate);
|
||||
|
||||
void deprecated_function(sass::string msg, SourceSpan pstate);
|
||||
void deprecated(sass::string msg, sass::string msg2, bool with_column, SourceSpan pstate);
|
||||
void deprecated_bind(sass::string msg, SourceSpan pstate);
|
||||
// void deprecated(sass::string msg, SourceSpan pstate, Backtrace* bt);
|
||||
|
||||
void coreError(sass::string msg, SourceSpan pstate);
|
||||
void error(sass::string msg, SourceSpan pstate, Backtraces& traces);
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
1543
vendor/bundle/ruby/2.6.0/gems/sassc-2.4.0/ext/libsass/src/eval.cpp
vendored
Normal file
1543
vendor/bundle/ruby/2.6.0/gems/sassc-2.4.0/ext/libsass/src/eval.cpp
vendored
Normal file
File diff suppressed because it is too large
Load Diff
110
vendor/bundle/ruby/2.6.0/gems/sassc-2.4.0/ext/libsass/src/eval.hpp
vendored
Normal file
110
vendor/bundle/ruby/2.6.0/gems/sassc-2.4.0/ext/libsass/src/eval.hpp
vendored
Normal file
@@ -0,0 +1,110 @@
|
||||
#ifndef SASS_EVAL_H
|
||||
#define SASS_EVAL_H
|
||||
|
||||
// sass.hpp must go before all system headers to get the
|
||||
// __EXTENSIONS__ fix on Solaris.
|
||||
#include "sass.hpp"
|
||||
#include "ast.hpp"
|
||||
|
||||
#include "context.hpp"
|
||||
#include "listize.hpp"
|
||||
#include "operation.hpp"
|
||||
#include "environment.hpp"
|
||||
|
||||
namespace Sass {
|
||||
|
||||
class Expand;
|
||||
class Context;
|
||||
|
||||
class Eval : public Operation_CRTP<Expression*, Eval> {
|
||||
|
||||
public:
|
||||
Expand& exp;
|
||||
Context& ctx;
|
||||
Backtraces& traces;
|
||||
Eval(Expand& exp);
|
||||
~Eval();
|
||||
|
||||
bool force;
|
||||
bool is_in_comment;
|
||||
bool is_in_selector_schema;
|
||||
|
||||
Boolean_Obj bool_true;
|
||||
Boolean_Obj bool_false;
|
||||
|
||||
Env* environment();
|
||||
EnvStack& env_stack();
|
||||
const sass::string cwd();
|
||||
CalleeStack& callee_stack();
|
||||
struct Sass_Inspect_Options& options();
|
||||
struct Sass_Compiler* compiler();
|
||||
|
||||
// for evaluating function bodies
|
||||
Expression* operator()(Block*);
|
||||
Expression* operator()(Assignment*);
|
||||
Expression* operator()(If*);
|
||||
Expression* operator()(ForRule*);
|
||||
Expression* operator()(EachRule*);
|
||||
Expression* operator()(WhileRule*);
|
||||
Expression* operator()(Return*);
|
||||
Expression* operator()(WarningRule*);
|
||||
Expression* operator()(ErrorRule*);
|
||||
Expression* operator()(DebugRule*);
|
||||
|
||||
Expression* operator()(List*);
|
||||
Expression* operator()(Map*);
|
||||
Expression* operator()(Binary_Expression*);
|
||||
Expression* operator()(Unary_Expression*);
|
||||
Expression* operator()(Function_Call*);
|
||||
Expression* operator()(Variable*);
|
||||
Expression* operator()(Number*);
|
||||
Expression* operator()(Color_RGBA*);
|
||||
Expression* operator()(Color_HSLA*);
|
||||
Expression* operator()(Boolean*);
|
||||
Expression* operator()(String_Schema*);
|
||||
Expression* operator()(String_Quoted*);
|
||||
Expression* operator()(String_Constant*);
|
||||
Media_Query* operator()(Media_Query*);
|
||||
Expression* operator()(Media_Query_Expression*);
|
||||
Expression* operator()(At_Root_Query*);
|
||||
Expression* operator()(SupportsOperation*);
|
||||
Expression* operator()(SupportsNegation*);
|
||||
Expression* operator()(SupportsDeclaration*);
|
||||
Expression* operator()(Supports_Interpolation*);
|
||||
Expression* operator()(Null*);
|
||||
Expression* operator()(Argument*);
|
||||
Expression* operator()(Arguments*);
|
||||
Expression* operator()(Comment*);
|
||||
|
||||
// these will return selectors
|
||||
SelectorList* operator()(SelectorList*);
|
||||
SelectorList* operator()(ComplexSelector*);
|
||||
CompoundSelector* operator()(CompoundSelector*);
|
||||
SelectorComponent* operator()(SelectorComponent*);
|
||||
SimpleSelector* operator()(SimpleSelector* s);
|
||||
PseudoSelector* operator()(PseudoSelector* s);
|
||||
|
||||
// they don't have any specific implementation (yet)
|
||||
IDSelector* operator()(IDSelector* s) { return s; };
|
||||
ClassSelector* operator()(ClassSelector* s) { return s; };
|
||||
TypeSelector* operator()(TypeSelector* s) { return s; };
|
||||
AttributeSelector* operator()(AttributeSelector* s) { return s; };
|
||||
PlaceholderSelector* operator()(PlaceholderSelector* s) { return s; };
|
||||
|
||||
// actual evaluated selectors
|
||||
SelectorList* operator()(Selector_Schema*);
|
||||
Expression* operator()(Parent_Reference*);
|
||||
|
||||
// generic fallback
|
||||
template <typename U>
|
||||
Expression* fallback(U x)
|
||||
{ return Cast<Expression>(x); }
|
||||
|
||||
private:
|
||||
void interpolation(Context& ctx, sass::string& res, ExpressionObj ex, bool into_quotes, bool was_itpl = false);
|
||||
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
75
vendor/bundle/ruby/2.6.0/gems/sassc-2.4.0/ext/libsass/src/eval_selectors.cpp
vendored
Normal file
75
vendor/bundle/ruby/2.6.0/gems/sassc-2.4.0/ext/libsass/src/eval_selectors.cpp
vendored
Normal file
@@ -0,0 +1,75 @@
|
||||
// sass.hpp must go before all system headers to get the
|
||||
// __EXTENSIONS__ fix on Solaris.
|
||||
#include "sass.hpp"
|
||||
#include "expand.hpp"
|
||||
#include "eval.hpp"
|
||||
#include "ast.hpp"
|
||||
|
||||
|
||||
namespace Sass {
|
||||
|
||||
SelectorList* Eval::operator()(SelectorList* s)
|
||||
{
|
||||
sass::vector<SelectorListObj> rv;
|
||||
SelectorListObj sl = SASS_MEMORY_NEW(SelectorList, s->pstate());
|
||||
for (size_t i = 0, iL = s->length(); i < iL; ++i) {
|
||||
rv.push_back(operator()(s->get(i)));
|
||||
}
|
||||
|
||||
// we should actually permutate parent first
|
||||
// but here we have permutated the selector first
|
||||
size_t round = 0;
|
||||
while (round != sass::string::npos) {
|
||||
bool abort = true;
|
||||
for (size_t i = 0, iL = rv.size(); i < iL; ++i) {
|
||||
if (rv[i]->length() > round) {
|
||||
sl->append((*rv[i])[round]);
|
||||
abort = false;
|
||||
}
|
||||
}
|
||||
if (abort) {
|
||||
round = sass::string::npos;
|
||||
}
|
||||
else {
|
||||
++round;
|
||||
}
|
||||
|
||||
}
|
||||
return sl.detach();
|
||||
}
|
||||
|
||||
SelectorComponent* Eval::operator()(SelectorComponent* s)
|
||||
{
|
||||
return {};
|
||||
}
|
||||
|
||||
SelectorList* Eval::operator()(ComplexSelector* s)
|
||||
{
|
||||
bool implicit_parent = !exp.old_at_root_without_rule;
|
||||
if (is_in_selector_schema) exp.pushNullSelector();
|
||||
SelectorListObj other = s->resolve_parent_refs(
|
||||
exp.getOriginalStack(), traces, implicit_parent);
|
||||
if (is_in_selector_schema) exp.popNullSelector();
|
||||
|
||||
for (size_t i = 0; i < other->length(); i++) {
|
||||
ComplexSelectorObj sel = other->at(i);
|
||||
for (size_t n = 0; n < sel->length(); n++) {
|
||||
if (CompoundSelectorObj comp = Cast<CompoundSelector>(sel->at(n))) {
|
||||
sel->at(n) = operator()(comp);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return other.detach();
|
||||
}
|
||||
|
||||
CompoundSelector* Eval::operator()(CompoundSelector* s)
|
||||
{
|
||||
for (size_t i = 0; i < s->length(); i++) {
|
||||
SimpleSelector* ss = s->at(i);
|
||||
// skip parents here (called via resolve_parent_refs)
|
||||
s->at(i) = Cast<SimpleSelector>(ss->perform(this));
|
||||
}
|
||||
return s;
|
||||
}
|
||||
}
|
||||
875
vendor/bundle/ruby/2.6.0/gems/sassc-2.4.0/ext/libsass/src/expand.cpp
vendored
Normal file
875
vendor/bundle/ruby/2.6.0/gems/sassc-2.4.0/ext/libsass/src/expand.cpp
vendored
Normal file
@@ -0,0 +1,875 @@
|
||||
// sass.hpp must go before all system headers to get the
|
||||
// __EXTENSIONS__ fix on Solaris.
|
||||
#include "sass.hpp"
|
||||
|
||||
#include <iostream>
|
||||
#include <typeinfo>
|
||||
|
||||
#include "ast.hpp"
|
||||
#include "expand.hpp"
|
||||
#include "bind.hpp"
|
||||
#include "eval.hpp"
|
||||
#include "backtrace.hpp"
|
||||
#include "context.hpp"
|
||||
#include "parser.hpp"
|
||||
#include "sass_functions.hpp"
|
||||
#include "error_handling.hpp"
|
||||
|
||||
namespace Sass {
|
||||
|
||||
// simple endless recursion protection
|
||||
const size_t maxRecursion = 500;
|
||||
|
||||
Expand::Expand(Context& ctx, Env* env, SelectorStack* stack, SelectorStack* originals)
|
||||
: ctx(ctx),
|
||||
traces(ctx.traces),
|
||||
eval(Eval(*this)),
|
||||
recursions(0),
|
||||
in_keyframes(false),
|
||||
at_root_without_rule(false),
|
||||
old_at_root_without_rule(false),
|
||||
env_stack(),
|
||||
block_stack(),
|
||||
call_stack(),
|
||||
selector_stack(),
|
||||
originalStack(),
|
||||
mediaStack()
|
||||
{
|
||||
env_stack.push_back(nullptr);
|
||||
env_stack.push_back(env);
|
||||
block_stack.push_back(nullptr);
|
||||
call_stack.push_back({});
|
||||
if (stack == NULL) { pushToSelectorStack({}); }
|
||||
else {
|
||||
for (auto item : *stack) {
|
||||
if (item.isNull()) pushToSelectorStack({});
|
||||
else pushToSelectorStack(item);
|
||||
}
|
||||
}
|
||||
if (originals == NULL) { pushToOriginalStack({}); }
|
||||
else {
|
||||
for (auto item : *stack) {
|
||||
if (item.isNull()) pushToOriginalStack({});
|
||||
else pushToOriginalStack(item);
|
||||
}
|
||||
}
|
||||
mediaStack.push_back({});
|
||||
}
|
||||
|
||||
Env* Expand::environment()
|
||||
{
|
||||
if (env_stack.size() > 0)
|
||||
return env_stack.back();
|
||||
return 0;
|
||||
}
|
||||
|
||||
void Expand::pushNullSelector()
|
||||
{
|
||||
pushToSelectorStack({});
|
||||
pushToOriginalStack({});
|
||||
}
|
||||
|
||||
void Expand::popNullSelector()
|
||||
{
|
||||
popFromOriginalStack();
|
||||
popFromSelectorStack();
|
||||
}
|
||||
|
||||
SelectorStack Expand::getOriginalStack()
|
||||
{
|
||||
return originalStack;
|
||||
}
|
||||
|
||||
SelectorStack Expand::getSelectorStack()
|
||||
{
|
||||
return selector_stack;
|
||||
}
|
||||
|
||||
SelectorListObj& Expand::selector()
|
||||
{
|
||||
if (selector_stack.size() > 0) {
|
||||
auto& sel = selector_stack.back();
|
||||
if (sel.isNull()) return sel;
|
||||
return sel;
|
||||
}
|
||||
// Avoid the need to return copies
|
||||
// We always want an empty first item
|
||||
selector_stack.push_back({});
|
||||
return selector_stack.back();;
|
||||
}
|
||||
|
||||
SelectorListObj& Expand::original()
|
||||
{
|
||||
if (originalStack.size() > 0) {
|
||||
auto& sel = originalStack.back();
|
||||
if (sel.isNull()) return sel;
|
||||
return sel;
|
||||
}
|
||||
// Avoid the need to return copies
|
||||
// We always want an empty first item
|
||||
originalStack.push_back({});
|
||||
return originalStack.back();
|
||||
}
|
||||
|
||||
SelectorListObj Expand::popFromSelectorStack()
|
||||
{
|
||||
SelectorListObj last = selector_stack.back();
|
||||
if (selector_stack.size() > 0)
|
||||
selector_stack.pop_back();
|
||||
if (last.isNull()) return {};
|
||||
return last;
|
||||
}
|
||||
|
||||
void Expand::pushToSelectorStack(SelectorListObj selector)
|
||||
{
|
||||
selector_stack.push_back(selector);
|
||||
}
|
||||
|
||||
SelectorListObj Expand::popFromOriginalStack()
|
||||
{
|
||||
SelectorListObj last = originalStack.back();
|
||||
if (originalStack.size() > 0)
|
||||
originalStack.pop_back();
|
||||
if (last.isNull()) return {};
|
||||
return last;
|
||||
}
|
||||
|
||||
void Expand::pushToOriginalStack(SelectorListObj selector)
|
||||
{
|
||||
originalStack.push_back(selector);
|
||||
}
|
||||
|
||||
// blocks create new variable scopes
|
||||
Block* Expand::operator()(Block* b)
|
||||
{
|
||||
// create new local environment
|
||||
// set the current env as parent
|
||||
Env env(environment());
|
||||
// copy the block object (add items later)
|
||||
Block_Obj bb = SASS_MEMORY_NEW(Block,
|
||||
b->pstate(),
|
||||
b->length(),
|
||||
b->is_root());
|
||||
// setup block and env stack
|
||||
this->block_stack.push_back(bb);
|
||||
this->env_stack.push_back(&env);
|
||||
// operate on block
|
||||
// this may throw up!
|
||||
this->append_block(b);
|
||||
// revert block and env stack
|
||||
this->block_stack.pop_back();
|
||||
this->env_stack.pop_back();
|
||||
// return copy
|
||||
return bb.detach();
|
||||
}
|
||||
|
||||
Statement* Expand::operator()(StyleRule* r)
|
||||
{
|
||||
LOCAL_FLAG(old_at_root_without_rule, at_root_without_rule);
|
||||
|
||||
if (in_keyframes) {
|
||||
Block* bb = operator()(r->block());
|
||||
Keyframe_Rule_Obj k = SASS_MEMORY_NEW(Keyframe_Rule, r->pstate(), bb);
|
||||
if (r->schema()) {
|
||||
pushNullSelector();
|
||||
k->name(eval(r->schema()));
|
||||
popNullSelector();
|
||||
}
|
||||
else if (r->selector()) {
|
||||
if (SelectorListObj s = r->selector()) {
|
||||
pushNullSelector();
|
||||
k->name(eval(s));
|
||||
popNullSelector();
|
||||
}
|
||||
}
|
||||
|
||||
return k.detach();
|
||||
}
|
||||
|
||||
if (r->schema()) {
|
||||
SelectorListObj sel = eval(r->schema());
|
||||
r->selector(sel);
|
||||
for (auto complex : sel->elements()) {
|
||||
// ToDo: maybe we can get rid of chroots?
|
||||
complex->chroots(complex->has_real_parent_ref());
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// reset when leaving scope
|
||||
LOCAL_FLAG(at_root_without_rule, false);
|
||||
|
||||
SelectorListObj evaled = eval(r->selector());
|
||||
// do not connect parent again
|
||||
Env env(environment());
|
||||
if (block_stack.back()->is_root()) {
|
||||
env_stack.push_back(&env);
|
||||
}
|
||||
Block_Obj blk;
|
||||
pushToSelectorStack(evaled);
|
||||
// The copy is needed for parent reference evaluation
|
||||
// dart-sass stores it as `originalSelector` member
|
||||
pushToOriginalStack(SASS_MEMORY_COPY(evaled));
|
||||
ctx.extender.addSelector(evaled, mediaStack.back());
|
||||
if (r->block()) blk = operator()(r->block());
|
||||
popFromOriginalStack();
|
||||
popFromSelectorStack();
|
||||
StyleRule* rr = SASS_MEMORY_NEW(StyleRule,
|
||||
r->pstate(),
|
||||
evaled,
|
||||
blk);
|
||||
|
||||
if (block_stack.back()->is_root()) {
|
||||
env_stack.pop_back();
|
||||
}
|
||||
|
||||
rr->is_root(r->is_root());
|
||||
rr->tabs(r->tabs());
|
||||
|
||||
return rr;
|
||||
}
|
||||
|
||||
Statement* Expand::operator()(SupportsRule* f)
|
||||
{
|
||||
ExpressionObj condition = f->condition()->perform(&eval);
|
||||
SupportsRuleObj ff = SASS_MEMORY_NEW(SupportsRule,
|
||||
f->pstate(),
|
||||
Cast<SupportsCondition>(condition),
|
||||
operator()(f->block()));
|
||||
return ff.detach();
|
||||
}
|
||||
|
||||
sass::vector<CssMediaQuery_Obj> Expand::mergeMediaQueries(
|
||||
const sass::vector<CssMediaQuery_Obj>& lhs,
|
||||
const sass::vector<CssMediaQuery_Obj>& rhs)
|
||||
{
|
||||
sass::vector<CssMediaQuery_Obj> queries;
|
||||
for (CssMediaQuery_Obj query1 : lhs) {
|
||||
for (CssMediaQuery_Obj query2 : rhs) {
|
||||
CssMediaQuery_Obj result = query1->merge(query2);
|
||||
if (result && !result->empty()) {
|
||||
queries.push_back(result);
|
||||
}
|
||||
}
|
||||
}
|
||||
return queries;
|
||||
}
|
||||
|
||||
Statement* Expand::operator()(MediaRule* m)
|
||||
{
|
||||
ExpressionObj mq = eval(m->schema());
|
||||
sass::string str_mq(mq->to_css(ctx.c_options));
|
||||
ItplFile* source = SASS_MEMORY_NEW(ItplFile,
|
||||
str_mq.c_str(), m->pstate());
|
||||
Parser parser(source, ctx, traces);
|
||||
// Create a new CSS only representation of the media rule
|
||||
CssMediaRuleObj css = SASS_MEMORY_NEW(CssMediaRule, m->pstate(), m->block());
|
||||
sass::vector<CssMediaQuery_Obj> parsed = parser.parseCssMediaQueries();
|
||||
if (mediaStack.size() && mediaStack.back()) {
|
||||
auto& parent = mediaStack.back()->elements();
|
||||
css->concat(mergeMediaQueries(parent, parsed));
|
||||
}
|
||||
else {
|
||||
css->concat(parsed);
|
||||
}
|
||||
mediaStack.push_back(css);
|
||||
css->block(operator()(m->block()));
|
||||
mediaStack.pop_back();
|
||||
return css.detach();
|
||||
|
||||
}
|
||||
|
||||
Statement* Expand::operator()(AtRootRule* a)
|
||||
{
|
||||
Block_Obj ab = a->block();
|
||||
ExpressionObj ae = a->expression();
|
||||
|
||||
if (ae) ae = ae->perform(&eval);
|
||||
else ae = SASS_MEMORY_NEW(At_Root_Query, a->pstate());
|
||||
|
||||
LOCAL_FLAG(at_root_without_rule, Cast<At_Root_Query>(ae)->exclude("rule"));
|
||||
LOCAL_FLAG(in_keyframes, false);
|
||||
|
||||
;
|
||||
|
||||
Block_Obj bb = ab ? operator()(ab) : NULL;
|
||||
AtRootRuleObj aa = SASS_MEMORY_NEW(AtRootRule,
|
||||
a->pstate(),
|
||||
bb,
|
||||
Cast<At_Root_Query>(ae));
|
||||
return aa.detach();
|
||||
}
|
||||
|
||||
Statement* Expand::operator()(AtRule* a)
|
||||
{
|
||||
LOCAL_FLAG(in_keyframes, a->is_keyframes());
|
||||
Block* ab = a->block();
|
||||
SelectorList* as = a->selector();
|
||||
Expression* av = a->value();
|
||||
pushNullSelector();
|
||||
if (av) av = av->perform(&eval);
|
||||
if (as) as = eval(as);
|
||||
popNullSelector();
|
||||
Block* bb = ab ? operator()(ab) : NULL;
|
||||
AtRule* aa = SASS_MEMORY_NEW(AtRule,
|
||||
a->pstate(),
|
||||
a->keyword(),
|
||||
as,
|
||||
bb,
|
||||
av);
|
||||
return aa;
|
||||
}
|
||||
|
||||
Statement* Expand::operator()(Declaration* d)
|
||||
{
|
||||
Block_Obj ab = d->block();
|
||||
String_Obj old_p = d->property();
|
||||
ExpressionObj prop = old_p->perform(&eval);
|
||||
String_Obj new_p = Cast<String>(prop);
|
||||
// we might get a color back
|
||||
if (!new_p) {
|
||||
sass::string str(prop->to_string(ctx.c_options));
|
||||
new_p = SASS_MEMORY_NEW(String_Constant, old_p->pstate(), str);
|
||||
}
|
||||
ExpressionObj value = d->value();
|
||||
if (value) value = value->perform(&eval);
|
||||
Block_Obj bb = ab ? operator()(ab) : NULL;
|
||||
if (!bb) {
|
||||
if (!value || (value->is_invisible() && !d->is_important())) {
|
||||
if (d->is_custom_property()) {
|
||||
error("Custom property values may not be empty.", d->value()->pstate(), traces);
|
||||
} else {
|
||||
return nullptr;
|
||||
}
|
||||
}
|
||||
}
|
||||
Declaration* decl = SASS_MEMORY_NEW(Declaration,
|
||||
d->pstate(),
|
||||
new_p,
|
||||
value,
|
||||
d->is_important(),
|
||||
d->is_custom_property(),
|
||||
bb);
|
||||
decl->tabs(d->tabs());
|
||||
return decl;
|
||||
}
|
||||
|
||||
Statement* Expand::operator()(Assignment* a)
|
||||
{
|
||||
Env* env = environment();
|
||||
const sass::string& var(a->variable());
|
||||
if (a->is_global()) {
|
||||
if (!env->has_global(var)) {
|
||||
deprecated(
|
||||
"!global assignments won't be able to declare new variables in future versions.",
|
||||
"Consider adding `" + var + ": null` at the top level.",
|
||||
true, a->pstate());
|
||||
}
|
||||
if (a->is_default()) {
|
||||
if (env->has_global(var)) {
|
||||
ExpressionObj e = Cast<Expression>(env->get_global(var));
|
||||
if (!e || e->concrete_type() == Expression::NULL_VAL) {
|
||||
env->set_global(var, a->value()->perform(&eval));
|
||||
}
|
||||
}
|
||||
else {
|
||||
env->set_global(var, a->value()->perform(&eval));
|
||||
}
|
||||
}
|
||||
else {
|
||||
env->set_global(var, a->value()->perform(&eval));
|
||||
}
|
||||
}
|
||||
else if (a->is_default()) {
|
||||
if (env->has_lexical(var)) {
|
||||
auto cur = env;
|
||||
while (cur && cur->is_lexical()) {
|
||||
if (cur->has_local(var)) {
|
||||
if (AST_Node_Obj node = cur->get_local(var)) {
|
||||
ExpressionObj e = Cast<Expression>(node);
|
||||
if (!e || e->concrete_type() == Expression::NULL_VAL) {
|
||||
cur->set_local(var, a->value()->perform(&eval));
|
||||
}
|
||||
}
|
||||
else {
|
||||
throw std::runtime_error("Env not in sync");
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
cur = cur->parent();
|
||||
}
|
||||
throw std::runtime_error("Env not in sync");
|
||||
}
|
||||
else if (env->has_global(var)) {
|
||||
if (AST_Node_Obj node = env->get_global(var)) {
|
||||
ExpressionObj e = Cast<Expression>(node);
|
||||
if (!e || e->concrete_type() == Expression::NULL_VAL) {
|
||||
env->set_global(var, a->value()->perform(&eval));
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (env->is_lexical()) {
|
||||
env->set_local(var, a->value()->perform(&eval));
|
||||
}
|
||||
else {
|
||||
env->set_local(var, a->value()->perform(&eval));
|
||||
}
|
||||
}
|
||||
else {
|
||||
env->set_lexical(var, a->value()->perform(&eval));
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
Statement* Expand::operator()(Import* imp)
|
||||
{
|
||||
Import_Obj result = SASS_MEMORY_NEW(Import, imp->pstate());
|
||||
if (imp->import_queries() && imp->import_queries()->size()) {
|
||||
ExpressionObj ex = imp->import_queries()->perform(&eval);
|
||||
result->import_queries(Cast<List>(ex));
|
||||
}
|
||||
for ( size_t i = 0, S = imp->urls().size(); i < S; ++i) {
|
||||
result->urls().push_back(imp->urls()[i]->perform(&eval));
|
||||
}
|
||||
// all resources have been dropped for Input_Stubs
|
||||
// for ( size_t i = 0, S = imp->incs().size(); i < S; ++i) {}
|
||||
return result.detach();
|
||||
}
|
||||
|
||||
Statement* Expand::operator()(Import_Stub* i)
|
||||
{
|
||||
traces.push_back(Backtrace(i->pstate()));
|
||||
// get parent node from call stack
|
||||
AST_Node_Obj parent = call_stack.back();
|
||||
if (Cast<Block>(parent) == NULL) {
|
||||
error("Import directives may not be used within control directives or mixins.", i->pstate(), traces);
|
||||
}
|
||||
// we don't seem to need that actually afterall
|
||||
Sass_Import_Entry import = sass_make_import(
|
||||
i->imp_path().c_str(),
|
||||
i->abs_path().c_str(),
|
||||
0, 0
|
||||
);
|
||||
ctx.import_stack.push_back(import);
|
||||
|
||||
Block_Obj trace_block = SASS_MEMORY_NEW(Block, i->pstate());
|
||||
Trace_Obj trace = SASS_MEMORY_NEW(Trace, i->pstate(), i->imp_path(), trace_block, 'i');
|
||||
block_stack.back()->append(trace);
|
||||
block_stack.push_back(trace_block);
|
||||
|
||||
const sass::string& abs_path(i->resource().abs_path);
|
||||
append_block(ctx.sheets.at(abs_path).root);
|
||||
sass_delete_import(ctx.import_stack.back());
|
||||
ctx.import_stack.pop_back();
|
||||
block_stack.pop_back();
|
||||
traces.pop_back();
|
||||
return 0;
|
||||
}
|
||||
|
||||
Statement* Expand::operator()(WarningRule* w)
|
||||
{
|
||||
// eval handles this too, because warnings may occur in functions
|
||||
w->perform(&eval);
|
||||
return 0;
|
||||
}
|
||||
|
||||
Statement* Expand::operator()(ErrorRule* e)
|
||||
{
|
||||
// eval handles this too, because errors may occur in functions
|
||||
e->perform(&eval);
|
||||
return 0;
|
||||
}
|
||||
|
||||
Statement* Expand::operator()(DebugRule* d)
|
||||
{
|
||||
// eval handles this too, because warnings may occur in functions
|
||||
d->perform(&eval);
|
||||
return 0;
|
||||
}
|
||||
|
||||
Statement* Expand::operator()(Comment* c)
|
||||
{
|
||||
if (ctx.output_style() == COMPRESSED) {
|
||||
// comments should not be evaluated in compact
|
||||
// https://github.com/sass/libsass/issues/2359
|
||||
if (!c->is_important()) return NULL;
|
||||
}
|
||||
eval.is_in_comment = true;
|
||||
Comment* rv = SASS_MEMORY_NEW(Comment, c->pstate(), Cast<String>(c->text()->perform(&eval)), c->is_important());
|
||||
eval.is_in_comment = false;
|
||||
// TODO: eval the text, once we're parsing/storing it as a String_Schema
|
||||
return rv;
|
||||
}
|
||||
|
||||
Statement* Expand::operator()(If* i)
|
||||
{
|
||||
Env env(environment(), true);
|
||||
env_stack.push_back(&env);
|
||||
call_stack.push_back(i);
|
||||
ExpressionObj rv = i->predicate()->perform(&eval);
|
||||
if (*rv) {
|
||||
append_block(i->block());
|
||||
}
|
||||
else {
|
||||
Block* alt = i->alternative();
|
||||
if (alt) append_block(alt);
|
||||
}
|
||||
call_stack.pop_back();
|
||||
env_stack.pop_back();
|
||||
return 0;
|
||||
}
|
||||
|
||||
// For does not create a new env scope
|
||||
// But iteration vars are reset afterwards
|
||||
Statement* Expand::operator()(ForRule* f)
|
||||
{
|
||||
sass::string variable(f->variable());
|
||||
ExpressionObj low = f->lower_bound()->perform(&eval);
|
||||
if (low->concrete_type() != Expression::NUMBER) {
|
||||
traces.push_back(Backtrace(low->pstate()));
|
||||
throw Exception::TypeMismatch(traces, *low, "integer");
|
||||
}
|
||||
ExpressionObj high = f->upper_bound()->perform(&eval);
|
||||
if (high->concrete_type() != Expression::NUMBER) {
|
||||
traces.push_back(Backtrace(high->pstate()));
|
||||
throw Exception::TypeMismatch(traces, *high, "integer");
|
||||
}
|
||||
Number_Obj sass_start = Cast<Number>(low);
|
||||
Number_Obj sass_end = Cast<Number>(high);
|
||||
// check if units are valid for sequence
|
||||
if (sass_start->unit() != sass_end->unit()) {
|
||||
sass::ostream msg; msg << "Incompatible units: '"
|
||||
<< sass_start->unit() << "' and '"
|
||||
<< sass_end->unit() << "'.";
|
||||
error(msg.str(), low->pstate(), traces);
|
||||
}
|
||||
double start = sass_start->value();
|
||||
double end = sass_end->value();
|
||||
// only create iterator once in this environment
|
||||
Env env(environment(), true);
|
||||
env_stack.push_back(&env);
|
||||
call_stack.push_back(f);
|
||||
Block* body = f->block();
|
||||
if (start < end) {
|
||||
if (f->is_inclusive()) ++end;
|
||||
for (double i = start;
|
||||
i < end;
|
||||
++i) {
|
||||
Number_Obj it = SASS_MEMORY_NEW(Number, low->pstate(), i, sass_end->unit());
|
||||
env.set_local(variable, it);
|
||||
append_block(body);
|
||||
}
|
||||
} else {
|
||||
if (f->is_inclusive()) --end;
|
||||
for (double i = start;
|
||||
i > end;
|
||||
--i) {
|
||||
Number_Obj it = SASS_MEMORY_NEW(Number, low->pstate(), i, sass_end->unit());
|
||||
env.set_local(variable, it);
|
||||
append_block(body);
|
||||
}
|
||||
}
|
||||
call_stack.pop_back();
|
||||
env_stack.pop_back();
|
||||
return 0;
|
||||
}
|
||||
|
||||
// Eval does not create a new env scope
|
||||
// But iteration vars are reset afterwards
|
||||
Statement* Expand::operator()(EachRule* e)
|
||||
{
|
||||
sass::vector<sass::string> variables(e->variables());
|
||||
ExpressionObj expr = e->list()->perform(&eval);
|
||||
List_Obj list;
|
||||
Map_Obj map;
|
||||
if (expr->concrete_type() == Expression::MAP) {
|
||||
map = Cast<Map>(expr);
|
||||
}
|
||||
else if (SelectorList * ls = Cast<SelectorList>(expr)) {
|
||||
ExpressionObj rv = Listize::perform(ls);
|
||||
list = Cast<List>(rv);
|
||||
}
|
||||
else if (expr->concrete_type() != Expression::LIST) {
|
||||
list = SASS_MEMORY_NEW(List, expr->pstate(), 1, SASS_COMMA);
|
||||
list->append(expr);
|
||||
}
|
||||
else {
|
||||
list = Cast<List>(expr);
|
||||
}
|
||||
// remember variables and then reset them
|
||||
Env env(environment(), true);
|
||||
env_stack.push_back(&env);
|
||||
call_stack.push_back(e);
|
||||
Block* body = e->block();
|
||||
|
||||
if (map) {
|
||||
for (auto key : map->keys()) {
|
||||
ExpressionObj k = key->perform(&eval);
|
||||
ExpressionObj v = map->at(key)->perform(&eval);
|
||||
|
||||
if (variables.size() == 1) {
|
||||
List_Obj variable = SASS_MEMORY_NEW(List, map->pstate(), 2, SASS_SPACE);
|
||||
variable->append(k);
|
||||
variable->append(v);
|
||||
env.set_local(variables[0], variable);
|
||||
} else {
|
||||
env.set_local(variables[0], k);
|
||||
env.set_local(variables[1], v);
|
||||
}
|
||||
append_block(body);
|
||||
}
|
||||
}
|
||||
else {
|
||||
// bool arglist = list->is_arglist();
|
||||
if (list->length() == 1 && Cast<SelectorList>(list)) {
|
||||
list = Cast<List>(list);
|
||||
}
|
||||
for (size_t i = 0, L = list->length(); i < L; ++i) {
|
||||
ExpressionObj item = list->at(i);
|
||||
// unwrap value if the expression is an argument
|
||||
if (Argument_Obj arg = Cast<Argument>(item)) item = arg->value();
|
||||
// check if we got passed a list of args (investigate)
|
||||
if (List_Obj scalars = Cast<List>(item)) {
|
||||
if (variables.size() == 1) {
|
||||
List_Obj var = scalars;
|
||||
// if (arglist) var = (*scalars)[0];
|
||||
env.set_local(variables[0], var);
|
||||
} else {
|
||||
for (size_t j = 0, K = variables.size(); j < K; ++j) {
|
||||
env.set_local(variables[j], j >= scalars->length()
|
||||
? SASS_MEMORY_NEW(Null, expr->pstate())
|
||||
: (*scalars)[j]->perform(&eval));
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if (variables.size() > 0) {
|
||||
env.set_local(variables.at(0), item);
|
||||
for (size_t j = 1, K = variables.size(); j < K; ++j) {
|
||||
ExpressionObj res = SASS_MEMORY_NEW(Null, expr->pstate());
|
||||
env.set_local(variables[j], res);
|
||||
}
|
||||
}
|
||||
}
|
||||
append_block(body);
|
||||
}
|
||||
}
|
||||
call_stack.pop_back();
|
||||
env_stack.pop_back();
|
||||
return 0;
|
||||
}
|
||||
|
||||
Statement* Expand::operator()(WhileRule* w)
|
||||
{
|
||||
ExpressionObj pred = w->predicate();
|
||||
Block* body = w->block();
|
||||
Env env(environment(), true);
|
||||
env_stack.push_back(&env);
|
||||
call_stack.push_back(w);
|
||||
ExpressionObj cond = pred->perform(&eval);
|
||||
while (!cond->is_false()) {
|
||||
append_block(body);
|
||||
cond = pred->perform(&eval);
|
||||
}
|
||||
call_stack.pop_back();
|
||||
env_stack.pop_back();
|
||||
return 0;
|
||||
}
|
||||
|
||||
Statement* Expand::operator()(Return* r)
|
||||
{
|
||||
error("@return may only be used within a function", r->pstate(), traces);
|
||||
return 0;
|
||||
}
|
||||
|
||||
Statement* Expand::operator()(ExtendRule* e)
|
||||
{
|
||||
|
||||
// evaluate schema first
|
||||
if (e->schema()) {
|
||||
e->selector(eval(e->schema()));
|
||||
e->isOptional(e->selector()->is_optional());
|
||||
}
|
||||
// evaluate the selector
|
||||
e->selector(eval(e->selector()));
|
||||
|
||||
if (e->selector()) {
|
||||
|
||||
for (auto complex : e->selector()->elements()) {
|
||||
|
||||
if (complex->length() != 1) {
|
||||
error("complex selectors may not be extended.", complex->pstate(), traces);
|
||||
}
|
||||
|
||||
if (const CompoundSelector* compound = complex->first()->getCompound()) {
|
||||
|
||||
if (compound->length() != 1) {
|
||||
|
||||
sass::ostream sels; bool addComma = false;
|
||||
sels << "Compound selectors may no longer be extended.\n";
|
||||
sels << "Consider `@extend ";
|
||||
for (auto sel : compound->elements()) {
|
||||
if (addComma) sels << ", ";
|
||||
sels << sel->to_sass();
|
||||
addComma = true;
|
||||
}
|
||||
sels << "` instead.\n";
|
||||
sels << "See http://bit.ly/ExtendCompound for details.";
|
||||
|
||||
warning(sels.str(), compound->pstate());
|
||||
|
||||
// Make this an error once deprecation is over
|
||||
for (SimpleSelectorObj simple : compound->elements()) {
|
||||
// Pass every selector we ever see to extender (to make them findable for extend)
|
||||
ctx.extender.addExtension(selector(), simple, mediaStack.back(), e->isOptional());
|
||||
}
|
||||
|
||||
}
|
||||
else {
|
||||
// Pass every selector we ever see to extender (to make them findable for extend)
|
||||
ctx.extender.addExtension(selector(), compound->first(), mediaStack.back(), e->isOptional());
|
||||
}
|
||||
|
||||
}
|
||||
else {
|
||||
error("complex selectors may not be extended.", complex->pstate(), traces);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return nullptr;
|
||||
|
||||
}
|
||||
|
||||
Statement* Expand::operator()(Definition* d)
|
||||
{
|
||||
Env* env = environment();
|
||||
Definition_Obj dd = SASS_MEMORY_COPY(d);
|
||||
env->local_frame()[d->name() +
|
||||
(d->type() == Definition::MIXIN ? "[m]" : "[f]")] = dd;
|
||||
|
||||
if (d->type() == Definition::FUNCTION && (
|
||||
Prelexer::calc_fn_call(d->name().c_str()) ||
|
||||
d->name() == "element" ||
|
||||
d->name() == "expression" ||
|
||||
d->name() == "url"
|
||||
)) {
|
||||
deprecated(
|
||||
"Naming a function \"" + d->name() + "\" is disallowed and will be an error in future versions of Sass.",
|
||||
"This name conflicts with an existing CSS function with special parse rules.",
|
||||
false, d->pstate()
|
||||
);
|
||||
}
|
||||
|
||||
// set the static link so we can have lexical scoping
|
||||
dd->environment(env);
|
||||
return 0;
|
||||
}
|
||||
|
||||
Statement* Expand::operator()(Mixin_Call* c)
|
||||
{
|
||||
|
||||
if (recursions > maxRecursion) {
|
||||
throw Exception::StackError(traces, *c);
|
||||
}
|
||||
|
||||
recursions ++;
|
||||
|
||||
Env* env = environment();
|
||||
sass::string full_name(c->name() + "[m]");
|
||||
if (!env->has(full_name)) {
|
||||
error("no mixin named " + c->name(), c->pstate(), traces);
|
||||
}
|
||||
Definition_Obj def = Cast<Definition>((*env)[full_name]);
|
||||
Block_Obj body = def->block();
|
||||
Parameters_Obj params = def->parameters();
|
||||
|
||||
if (c->block() && c->name() != "@content" && !body->has_content()) {
|
||||
error("Mixin \"" + c->name() + "\" does not accept a content block.", c->pstate(), traces);
|
||||
}
|
||||
ExpressionObj rv = c->arguments()->perform(&eval);
|
||||
Arguments_Obj args = Cast<Arguments>(rv);
|
||||
sass::string msg(", in mixin `" + c->name() + "`");
|
||||
traces.push_back(Backtrace(c->pstate(), msg));
|
||||
ctx.callee_stack.push_back({
|
||||
c->name().c_str(),
|
||||
c->pstate().getPath(),
|
||||
c->pstate().getLine(),
|
||||
c->pstate().getColumn(),
|
||||
SASS_CALLEE_MIXIN,
|
||||
{ env }
|
||||
});
|
||||
|
||||
Env new_env(def->environment());
|
||||
env_stack.push_back(&new_env);
|
||||
if (c->block()) {
|
||||
Parameters_Obj params = c->block_parameters();
|
||||
if (!params) params = SASS_MEMORY_NEW(Parameters, c->pstate());
|
||||
// represent mixin content blocks as thunks/closures
|
||||
Definition_Obj thunk = SASS_MEMORY_NEW(Definition,
|
||||
c->pstate(),
|
||||
"@content",
|
||||
params,
|
||||
c->block(),
|
||||
Definition::MIXIN);
|
||||
thunk->environment(env);
|
||||
new_env.local_frame()["@content[m]"] = thunk;
|
||||
}
|
||||
|
||||
bind(sass::string("Mixin"), c->name(), params, args, &new_env, &eval, traces);
|
||||
|
||||
Block_Obj trace_block = SASS_MEMORY_NEW(Block, c->pstate());
|
||||
Trace_Obj trace = SASS_MEMORY_NEW(Trace, c->pstate(), c->name(), trace_block);
|
||||
|
||||
env->set_global("is_in_mixin", bool_true);
|
||||
if (Block* pr = block_stack.back()) {
|
||||
trace_block->is_root(pr->is_root());
|
||||
}
|
||||
block_stack.push_back(trace_block);
|
||||
for (auto bb : body->elements()) {
|
||||
if (StyleRule* r = Cast<StyleRule>(bb)) {
|
||||
r->is_root(trace_block->is_root());
|
||||
}
|
||||
Statement_Obj ith = bb->perform(this);
|
||||
if (ith) trace->block()->append(ith);
|
||||
}
|
||||
block_stack.pop_back();
|
||||
env->del_global("is_in_mixin");
|
||||
|
||||
ctx.callee_stack.pop_back();
|
||||
env_stack.pop_back();
|
||||
traces.pop_back();
|
||||
|
||||
recursions --;
|
||||
return trace.detach();
|
||||
}
|
||||
|
||||
Statement* Expand::operator()(Content* c)
|
||||
{
|
||||
Env* env = environment();
|
||||
// convert @content directives into mixin calls to the underlying thunk
|
||||
if (!env->has("@content[m]")) return 0;
|
||||
Arguments_Obj args = c->arguments();
|
||||
if (!args) args = SASS_MEMORY_NEW(Arguments, c->pstate());
|
||||
|
||||
Mixin_Call_Obj call = SASS_MEMORY_NEW(Mixin_Call,
|
||||
c->pstate(),
|
||||
"@content",
|
||||
args);
|
||||
|
||||
Trace_Obj trace = Cast<Trace>(call->perform(this));
|
||||
return trace.detach();
|
||||
}
|
||||
|
||||
// process and add to last block on stack
|
||||
inline void Expand::append_block(Block* b)
|
||||
{
|
||||
if (b->is_root()) call_stack.push_back(b);
|
||||
for (size_t i = 0, L = b->length(); i < L; ++i) {
|
||||
Statement* stm = b->at(i);
|
||||
Statement_Obj ith = stm->perform(this);
|
||||
if (ith) block_stack.back()->append(ith);
|
||||
}
|
||||
if (b->is_root()) call_stack.pop_back();
|
||||
}
|
||||
|
||||
}
|
||||
98
vendor/bundle/ruby/2.6.0/gems/sassc-2.4.0/ext/libsass/src/expand.hpp
vendored
Normal file
98
vendor/bundle/ruby/2.6.0/gems/sassc-2.4.0/ext/libsass/src/expand.hpp
vendored
Normal file
@@ -0,0 +1,98 @@
|
||||
#ifndef SASS_EXPAND_H
|
||||
#define SASS_EXPAND_H
|
||||
|
||||
#include <vector>
|
||||
|
||||
#include "ast.hpp"
|
||||
#include "eval.hpp"
|
||||
#include "operation.hpp"
|
||||
#include "environment.hpp"
|
||||
|
||||
namespace Sass {
|
||||
|
||||
class Listize;
|
||||
class Context;
|
||||
class Eval;
|
||||
struct Backtrace;
|
||||
|
||||
class Expand : public Operation_CRTP<Statement*, Expand> {
|
||||
public:
|
||||
|
||||
Env* environment();
|
||||
SelectorListObj& selector();
|
||||
SelectorListObj& original();
|
||||
SelectorListObj popFromSelectorStack();
|
||||
SelectorStack getOriginalStack();
|
||||
SelectorStack getSelectorStack();
|
||||
void pushNullSelector();
|
||||
void popNullSelector();
|
||||
void pushToSelectorStack(SelectorListObj selector);
|
||||
|
||||
SelectorListObj popFromOriginalStack();
|
||||
|
||||
void pushToOriginalStack(SelectorListObj selector);
|
||||
|
||||
Context& ctx;
|
||||
Backtraces& traces;
|
||||
Eval eval;
|
||||
size_t recursions;
|
||||
bool in_keyframes;
|
||||
bool at_root_without_rule;
|
||||
bool old_at_root_without_rule;
|
||||
|
||||
// it's easier to work with vectors
|
||||
EnvStack env_stack;
|
||||
BlockStack block_stack;
|
||||
CallStack call_stack;
|
||||
private:
|
||||
SelectorStack selector_stack;
|
||||
public:
|
||||
SelectorStack originalStack;
|
||||
MediaStack mediaStack;
|
||||
|
||||
Boolean_Obj bool_true;
|
||||
|
||||
private:
|
||||
|
||||
sass::vector<CssMediaQuery_Obj> mergeMediaQueries(const sass::vector<CssMediaQuery_Obj>& lhs, const sass::vector<CssMediaQuery_Obj>& rhs);
|
||||
|
||||
public:
|
||||
Expand(Context&, Env*, SelectorStack* stack = nullptr, SelectorStack* original = nullptr);
|
||||
~Expand() { }
|
||||
|
||||
Block* operator()(Block*);
|
||||
Statement* operator()(StyleRule*);
|
||||
|
||||
Statement* operator()(MediaRule*);
|
||||
|
||||
// Css StyleRule is already static
|
||||
// Statement* operator()(CssMediaRule*);
|
||||
|
||||
Statement* operator()(SupportsRule*);
|
||||
Statement* operator()(AtRootRule*);
|
||||
Statement* operator()(AtRule*);
|
||||
Statement* operator()(Declaration*);
|
||||
Statement* operator()(Assignment*);
|
||||
Statement* operator()(Import*);
|
||||
Statement* operator()(Import_Stub*);
|
||||
Statement* operator()(WarningRule*);
|
||||
Statement* operator()(ErrorRule*);
|
||||
Statement* operator()(DebugRule*);
|
||||
Statement* operator()(Comment*);
|
||||
Statement* operator()(If*);
|
||||
Statement* operator()(ForRule*);
|
||||
Statement* operator()(EachRule*);
|
||||
Statement* operator()(WhileRule*);
|
||||
Statement* operator()(Return*);
|
||||
Statement* operator()(ExtendRule*);
|
||||
Statement* operator()(Definition*);
|
||||
Statement* operator()(Mixin_Call*);
|
||||
Statement* operator()(Content*);
|
||||
|
||||
void append_block(Block*);
|
||||
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
1188
vendor/bundle/ruby/2.6.0/gems/sassc-2.4.0/ext/libsass/src/extender.cpp
vendored
Normal file
1188
vendor/bundle/ruby/2.6.0/gems/sassc-2.4.0/ext/libsass/src/extender.cpp
vendored
Normal file
File diff suppressed because it is too large
Load Diff
399
vendor/bundle/ruby/2.6.0/gems/sassc-2.4.0/ext/libsass/src/extender.hpp
vendored
Normal file
399
vendor/bundle/ruby/2.6.0/gems/sassc-2.4.0/ext/libsass/src/extender.hpp
vendored
Normal file
@@ -0,0 +1,399 @@
|
||||
#ifndef SASS_EXTENDER_H
|
||||
#define SASS_EXTENDER_H
|
||||
|
||||
#include <set>
|
||||
#include <map>
|
||||
#include <string>
|
||||
|
||||
#include "ast_helpers.hpp"
|
||||
#include "ast_fwd_decl.hpp"
|
||||
#include "operation.hpp"
|
||||
#include "extension.hpp"
|
||||
#include "backtrace.hpp"
|
||||
#include "ordered_map.hpp"
|
||||
|
||||
namespace Sass {
|
||||
|
||||
// ##########################################################################
|
||||
// Different hash map types used by extender
|
||||
// ##########################################################################
|
||||
|
||||
// This is special (ptrs!)
|
||||
typedef std::unordered_set<
|
||||
ComplexSelectorObj,
|
||||
ObjPtrHash,
|
||||
ObjPtrEquality
|
||||
> ExtCplxSelSet;
|
||||
|
||||
typedef std::unordered_set<
|
||||
SimpleSelectorObj,
|
||||
ObjHash,
|
||||
ObjEquality
|
||||
> ExtSmplSelSet;
|
||||
|
||||
typedef std::unordered_set<
|
||||
SelectorListObj,
|
||||
ObjPtrHash,
|
||||
ObjPtrEquality
|
||||
> ExtListSelSet;
|
||||
|
||||
typedef std::unordered_map<
|
||||
SimpleSelectorObj,
|
||||
ExtListSelSet,
|
||||
ObjHash,
|
||||
ObjEquality
|
||||
> ExtSelMap;
|
||||
|
||||
typedef ordered_map<
|
||||
ComplexSelectorObj,
|
||||
Extension,
|
||||
ObjHash,
|
||||
ObjEquality
|
||||
> ExtSelExtMapEntry;
|
||||
|
||||
typedef std::unordered_map<
|
||||
SimpleSelectorObj,
|
||||
ExtSelExtMapEntry,
|
||||
ObjHash,
|
||||
ObjEquality
|
||||
> ExtSelExtMap;
|
||||
|
||||
typedef std::unordered_map <
|
||||
SimpleSelectorObj,
|
||||
sass::vector<
|
||||
Extension
|
||||
>,
|
||||
ObjHash,
|
||||
ObjEquality
|
||||
> ExtByExtMap;
|
||||
|
||||
class Extender : public Operation_CRTP<void, Extender> {
|
||||
|
||||
public:
|
||||
|
||||
enum ExtendMode { TARGETS, REPLACE, NORMAL, };
|
||||
|
||||
private:
|
||||
|
||||
// ##########################################################################
|
||||
// The mode that controls this extender's behavior.
|
||||
// ##########################################################################
|
||||
ExtendMode mode;
|
||||
|
||||
// ##########################################################################
|
||||
// Shared backtraces with context and expander. Needed the throw
|
||||
// errors when e.g. extending across media query boundaries.
|
||||
// ##########################################################################
|
||||
Backtraces& traces;
|
||||
|
||||
// ##########################################################################
|
||||
// A map from all simple selectors in the stylesheet to the rules that
|
||||
// contain them.This is used to find which rules an `@extend` applies to.
|
||||
// ##########################################################################
|
||||
ExtSelMap selectors;
|
||||
|
||||
// ##########################################################################
|
||||
// A map from all extended simple selectors
|
||||
// to the sources of those extensions.
|
||||
// ##########################################################################
|
||||
ExtSelExtMap extensions;
|
||||
|
||||
// ##########################################################################
|
||||
// A map from all simple selectors in extenders to
|
||||
// the extensions that those extenders define.
|
||||
// ##########################################################################
|
||||
ExtByExtMap extensionsByExtender;
|
||||
|
||||
// ##########################################################################
|
||||
// A map from CSS rules to the media query contexts they're defined in.
|
||||
// This tracks the contexts in which each style rule is defined.
|
||||
// If a rule is defined at the top level, it doesn't have an entry.
|
||||
// ##########################################################################
|
||||
ordered_map<
|
||||
SelectorListObj,
|
||||
CssMediaRuleObj,
|
||||
ObjPtrHash,
|
||||
ObjPtrEquality
|
||||
> mediaContexts;
|
||||
|
||||
// ##########################################################################
|
||||
// A map from [SimpleSelector]s to the specificity of their source selectors.
|
||||
// This tracks the maximum specificity of the [ComplexSelector] that originally
|
||||
// contained each [SimpleSelector]. This allows us to ensure we don't trim any
|
||||
// selectors that need to exist to satisfy the [second law that of extend][].
|
||||
// [second law of extend]: https://github.com/sass/sass/issues/324#issuecomment-4607184
|
||||
// ##########################################################################
|
||||
std::unordered_map<
|
||||
SimpleSelectorObj,
|
||||
size_t,
|
||||
ObjPtrHash,
|
||||
ObjPtrEquality
|
||||
> sourceSpecificity;
|
||||
|
||||
// ##########################################################################
|
||||
// A set of [ComplexSelector]s that were originally part of their
|
||||
// component [SelectorList]s, as opposed to being added by `@extend`.
|
||||
// This allows us to ensure that we don't trim any selectors
|
||||
// that need to exist to satisfy the [first law of extend][].
|
||||
// ##########################################################################
|
||||
ExtCplxSelSet originals;
|
||||
|
||||
public:
|
||||
|
||||
// Constructor without default [mode].
|
||||
// [traces] are needed to throw errors.
|
||||
Extender(Backtraces& traces);
|
||||
|
||||
// ##########################################################################
|
||||
// Constructor with specific [mode].
|
||||
// [traces] are needed to throw errors.
|
||||
// ##########################################################################
|
||||
Extender(ExtendMode mode, Backtraces& traces);
|
||||
|
||||
// ##########################################################################
|
||||
// Empty desctructor
|
||||
// ##########################################################################
|
||||
~Extender() {};
|
||||
|
||||
// ##########################################################################
|
||||
// Extends [selector] with [source] extender and [targets] extendees.
|
||||
// This works as though `source {@extend target}` were written in the
|
||||
// stylesheet, with the exception that [target] can contain compound
|
||||
// selectors which must be extended as a unit.
|
||||
// ##########################################################################
|
||||
static SelectorListObj extend(
|
||||
SelectorListObj& selector,
|
||||
const SelectorListObj& source,
|
||||
const SelectorListObj& target,
|
||||
Backtraces& traces);
|
||||
|
||||
// ##########################################################################
|
||||
// Returns a copy of [selector] with [targets] replaced by [source].
|
||||
// ##########################################################################
|
||||
static SelectorListObj replace(
|
||||
SelectorListObj& selector,
|
||||
const SelectorListObj& source,
|
||||
const SelectorListObj& target,
|
||||
Backtraces& traces);
|
||||
|
||||
// ##########################################################################
|
||||
// Adds [selector] to this extender, with [selectorSpan] as the span covering
|
||||
// the selector and [ruleSpan] as the span covering the entire style rule.
|
||||
// Extends [selector] using any registered extensions, then returns an empty
|
||||
// [ModifiableCssStyleRule] with the resulting selector. If any more relevant
|
||||
// extensions are added, the returned rule is automatically updated.
|
||||
// The [mediaContext] is the media query context in which the selector was
|
||||
// defined, or `null` if it was defined at the top level of the document.
|
||||
// ##########################################################################
|
||||
void addSelector(
|
||||
const SelectorListObj& selector,
|
||||
const CssMediaRuleObj& mediaContext);
|
||||
|
||||
// ##########################################################################
|
||||
// Registers the [SimpleSelector]s in [list]
|
||||
// to point to [rule] in [selectors].
|
||||
// ##########################################################################
|
||||
void registerSelector(
|
||||
const SelectorListObj& list,
|
||||
const SelectorListObj& rule);
|
||||
|
||||
// ##########################################################################
|
||||
// Adds an extension to this extender. The [extender] is the selector for the
|
||||
// style rule in which the extension is defined, and [target] is the selector
|
||||
// passed to `@extend`. The [extend] provides the extend span and indicates
|
||||
// whether the extension is optional. The [mediaContext] defines the media query
|
||||
// context in which the extension is defined. It can only extend selectors
|
||||
// within the same context. A `null` context indicates no media queries.
|
||||
// ##########################################################################
|
||||
void addExtension(
|
||||
const SelectorListObj& extender,
|
||||
const SimpleSelectorObj& target,
|
||||
const CssMediaRuleObj& mediaQueryContext,
|
||||
bool is_optional = false);
|
||||
|
||||
// ##########################################################################
|
||||
// The set of all simple selectors in style rules handled
|
||||
// by this extender. This includes simple selectors that
|
||||
// were added because of downstream extensions.
|
||||
// ##########################################################################
|
||||
ExtSmplSelSet getSimpleSelectors() const;
|
||||
|
||||
// ##########################################################################
|
||||
// Check for extends that have not been satisfied.
|
||||
// Returns true if any non-optional extension did not
|
||||
// extend any selector. Updates the passed reference
|
||||
// to point to that Extension for further analysis.
|
||||
// ##########################################################################
|
||||
bool checkForUnsatisfiedExtends(
|
||||
Extension& unsatisfied) const;
|
||||
|
||||
private:
|
||||
|
||||
// ##########################################################################
|
||||
// A helper function for [extend] and [replace].
|
||||
// ##########################################################################
|
||||
static SelectorListObj extendOrReplace(
|
||||
SelectorListObj& selector,
|
||||
const SelectorListObj& source,
|
||||
const SelectorListObj& target,
|
||||
const ExtendMode mode,
|
||||
Backtraces& traces);
|
||||
|
||||
// ##########################################################################
|
||||
// Returns an extension that combines [left] and [right]. Throws
|
||||
// a [SassException] if [left] and [right] have incompatible
|
||||
// media contexts. Throws an [ArgumentError] if [left]
|
||||
// and [right] don't have the same extender and target.
|
||||
// ##########################################################################
|
||||
static Extension mergeExtension(
|
||||
const Extension& lhs,
|
||||
const Extension& rhs);
|
||||
|
||||
// ##########################################################################
|
||||
// Extend [extensions] using [newExtensions].
|
||||
// ##########################################################################
|
||||
// Note: dart-sass throws an error in here
|
||||
// ##########################################################################
|
||||
void extendExistingStyleRules(
|
||||
const ExtListSelSet& rules,
|
||||
const ExtSelExtMap& newExtensions);
|
||||
|
||||
// ##########################################################################
|
||||
// Extend [extensions] using [newExtensions]. Note that this does duplicate
|
||||
// some work done by [_extendExistingStyleRules], but it's necessary to
|
||||
// expand each extension's extender separately without reference to the full
|
||||
// selector list, so that relevant results don't get trimmed too early.
|
||||
// Returns `null` (Note: empty map) if there are no extensions to add.
|
||||
// ##########################################################################
|
||||
ExtSelExtMap extendExistingExtensions(
|
||||
// Taking in a reference here makes MSVC debug stuck!?
|
||||
const sass::vector<Extension>& extensions,
|
||||
const ExtSelExtMap& newExtensions);
|
||||
|
||||
// ##########################################################################
|
||||
// Extends [list] using [extensions].
|
||||
// ##########################################################################
|
||||
SelectorListObj extendList(
|
||||
const SelectorListObj& list,
|
||||
const ExtSelExtMap& extensions,
|
||||
const CssMediaRuleObj& mediaContext);
|
||||
|
||||
// ##########################################################################
|
||||
// Extends [complex] using [extensions], and
|
||||
// returns the contents of a [SelectorList].
|
||||
// ##########################################################################
|
||||
sass::vector<ComplexSelectorObj> extendComplex(
|
||||
// Taking in a reference here makes MSVC debug stuck!?
|
||||
const ComplexSelectorObj& list,
|
||||
const ExtSelExtMap& extensions,
|
||||
const CssMediaRuleObj& mediaQueryContext);
|
||||
|
||||
// ##########################################################################
|
||||
// Returns a one-off [Extension] whose
|
||||
// extender is composed solely of [simple].
|
||||
// ##########################################################################
|
||||
Extension extensionForSimple(
|
||||
const SimpleSelectorObj& simple) const;
|
||||
|
||||
// ##########################################################################
|
||||
// Returns a one-off [Extension] whose extender is composed
|
||||
// solely of a compound selector containing [simples].
|
||||
// ##########################################################################
|
||||
Extension extensionForCompound(
|
||||
// Taking in a reference here makes MSVC debug stuck!?
|
||||
const sass::vector<SimpleSelectorObj>& simples) const;
|
||||
|
||||
// ##########################################################################
|
||||
// Extends [compound] using [extensions], and returns the
|
||||
// contents of a [SelectorList]. The [inOriginal] parameter
|
||||
// indicates whether this is in an original complex selector,
|
||||
// meaning that [compound] should not be trimmed out.
|
||||
// ##########################################################################
|
||||
sass::vector<ComplexSelectorObj> extendCompound(
|
||||
const CompoundSelectorObj& compound,
|
||||
const ExtSelExtMap& extensions,
|
||||
const CssMediaRuleObj& mediaQueryContext,
|
||||
bool inOriginal = false);
|
||||
|
||||
// ##########################################################################
|
||||
// Extends [simple] without extending the
|
||||
// contents of any selector pseudos it contains.
|
||||
// ##########################################################################
|
||||
sass::vector<Extension> extendWithoutPseudo(
|
||||
const SimpleSelectorObj& simple,
|
||||
const ExtSelExtMap& extensions,
|
||||
ExtSmplSelSet* targetsUsed) const;
|
||||
|
||||
// ##########################################################################
|
||||
// Extends [simple] and also extending the
|
||||
// contents of any selector pseudos it contains.
|
||||
// ##########################################################################
|
||||
sass::vector<sass::vector<Extension>> extendSimple(
|
||||
const SimpleSelectorObj& simple,
|
||||
const ExtSelExtMap& extensions,
|
||||
const CssMediaRuleObj& mediaQueryContext,
|
||||
ExtSmplSelSet* targetsUsed);
|
||||
|
||||
// ##########################################################################
|
||||
// Inner loop helper for [extendPseudo] function
|
||||
// ##########################################################################
|
||||
static sass::vector<ComplexSelectorObj> extendPseudoComplex(
|
||||
const ComplexSelectorObj& complex,
|
||||
const PseudoSelectorObj& pseudo,
|
||||
const CssMediaRuleObj& mediaQueryContext);
|
||||
|
||||
// ##########################################################################
|
||||
// Extends [pseudo] using [extensions], and returns
|
||||
// a list of resulting pseudo selectors.
|
||||
// ##########################################################################
|
||||
sass::vector<PseudoSelectorObj> extendPseudo(
|
||||
const PseudoSelectorObj& pseudo,
|
||||
const ExtSelExtMap& extensions,
|
||||
const CssMediaRuleObj& mediaQueryContext);
|
||||
|
||||
// ##########################################################################
|
||||
// Rotates the element in list from [start] (inclusive) to [end] (exclusive)
|
||||
// one index higher, looping the final element back to [start].
|
||||
// ##########################################################################
|
||||
static void rotateSlice(
|
||||
sass::vector<ComplexSelectorObj>& list,
|
||||
size_t start, size_t end);
|
||||
|
||||
// ##########################################################################
|
||||
// Removes elements from [selectors] if they're subselectors of other
|
||||
// elements. The [isOriginal] callback indicates which selectors are
|
||||
// original to the document, and thus should never be trimmed.
|
||||
// ##########################################################################
|
||||
sass::vector<ComplexSelectorObj> trim(
|
||||
const sass::vector<ComplexSelectorObj>& selectors,
|
||||
const ExtCplxSelSet& set) const;
|
||||
|
||||
// ##########################################################################
|
||||
// Returns the maximum specificity of the given [simple] source selector.
|
||||
// ##########################################################################
|
||||
size_t maxSourceSpecificity(const SimpleSelectorObj& simple) const;
|
||||
|
||||
// ##########################################################################
|
||||
// Returns the maximum specificity for sources that went into producing [compound].
|
||||
// ##########################################################################
|
||||
size_t maxSourceSpecificity(const CompoundSelectorObj& compound) const;
|
||||
|
||||
// ##########################################################################
|
||||
// Helper function used as callbacks on lists
|
||||
// ##########################################################################
|
||||
static bool dontTrimComplex(
|
||||
const ComplexSelector* complex2,
|
||||
const ComplexSelector* complex1,
|
||||
const size_t maxSpecificity);
|
||||
|
||||
// ##########################################################################
|
||||
// Helper function used as callbacks on lists
|
||||
// ##########################################################################
|
||||
static bool hasExactlyOne(const ComplexSelectorObj& vec);
|
||||
static bool hasMoreThanOne(const ComplexSelectorObj& vec);
|
||||
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
43
vendor/bundle/ruby/2.6.0/gems/sassc-2.4.0/ext/libsass/src/extension.cpp
vendored
Normal file
43
vendor/bundle/ruby/2.6.0/gems/sassc-2.4.0/ext/libsass/src/extension.cpp
vendored
Normal file
@@ -0,0 +1,43 @@
|
||||
// sass.hpp must go before all system headers to get the
|
||||
// __EXTENSIONS__ fix on Solaris.
|
||||
#include "sass.hpp"
|
||||
|
||||
#include "ast_helpers.hpp"
|
||||
#include "extension.hpp"
|
||||
#include "ast.hpp"
|
||||
|
||||
namespace Sass {
|
||||
|
||||
// ##########################################################################
|
||||
// Static function to create a copy with a new extender
|
||||
// ##########################################################################
|
||||
Extension Extension::withExtender(const ComplexSelectorObj& newExtender) const
|
||||
{
|
||||
Extension extension(newExtender);
|
||||
extension.specificity = specificity;
|
||||
extension.isOptional = isOptional;
|
||||
extension.target = target;
|
||||
return extension;
|
||||
}
|
||||
|
||||
// ##########################################################################
|
||||
// Asserts that the [mediaContext] for a selector is
|
||||
// compatible with the query context for this extender.
|
||||
// ##########################################################################
|
||||
void Extension::assertCompatibleMediaContext(CssMediaRuleObj mediaQueryContext, Backtraces& traces) const
|
||||
{
|
||||
|
||||
if (this->mediaContext.isNull()) return;
|
||||
|
||||
if (mediaQueryContext && ObjPtrEqualityFn(mediaContext->block(), mediaQueryContext->block())) return;
|
||||
|
||||
if (ObjEqualityFn<CssMediaRuleObj>(mediaQueryContext, mediaContext)) return;
|
||||
|
||||
throw Exception::ExtendAcrossMedia(traces, *this);
|
||||
|
||||
}
|
||||
|
||||
// ##########################################################################
|
||||
// ##########################################################################
|
||||
|
||||
}
|
||||
89
vendor/bundle/ruby/2.6.0/gems/sassc-2.4.0/ext/libsass/src/extension.hpp
vendored
Normal file
89
vendor/bundle/ruby/2.6.0/gems/sassc-2.4.0/ext/libsass/src/extension.hpp
vendored
Normal file
@@ -0,0 +1,89 @@
|
||||
#ifndef SASS_EXTENSION_H
|
||||
#define SASS_EXTENSION_H
|
||||
|
||||
// sass.hpp must go before all system headers to get the
|
||||
// __EXTENSIONS__ fix on Solaris.
|
||||
#include "sass.hpp"
|
||||
|
||||
#include <unordered_map>
|
||||
#include <unordered_set>
|
||||
#include "ast_fwd_decl.hpp"
|
||||
#include "backtrace.hpp"
|
||||
|
||||
namespace Sass {
|
||||
|
||||
class Extension {
|
||||
|
||||
public:
|
||||
|
||||
// The selector in which the `@extend` appeared.
|
||||
ComplexSelectorObj extender;
|
||||
|
||||
// The selector that's being extended.
|
||||
// `null` for one-off extensions.
|
||||
SimpleSelectorObj target;
|
||||
|
||||
// The minimum specificity required for any
|
||||
// selector generated from this extender.
|
||||
size_t specificity;
|
||||
|
||||
// Whether this extension is optional.
|
||||
bool isOptional;
|
||||
|
||||
// Whether this is a one-off extender representing a selector that was
|
||||
// originally in the document, rather than one defined with `@extend`.
|
||||
bool isOriginal;
|
||||
|
||||
bool isSatisfied;
|
||||
|
||||
// The media query context to which this extend is restricted,
|
||||
// or `null` if it can apply within any context.
|
||||
CssMediaRuleObj mediaContext;
|
||||
|
||||
// Creates a one-off extension that's not intended to be modified over time.
|
||||
// If [specificity] isn't passed, it defaults to `extender.maxSpecificity`.
|
||||
Extension(ComplexSelectorObj extender) :
|
||||
extender(extender),
|
||||
target({}),
|
||||
specificity(0),
|
||||
isOptional(true),
|
||||
isOriginal(false),
|
||||
isSatisfied(false),
|
||||
mediaContext({}) {
|
||||
|
||||
}
|
||||
|
||||
// Copy constructor
|
||||
Extension(const Extension& extension) :
|
||||
extender(extension.extender),
|
||||
target(extension.target),
|
||||
specificity(extension.specificity),
|
||||
isOptional(extension.isOptional),
|
||||
isOriginal(extension.isOriginal),
|
||||
isSatisfied(extension.isSatisfied),
|
||||
mediaContext(extension.mediaContext) {
|
||||
|
||||
}
|
||||
|
||||
// Default constructor
|
||||
Extension() :
|
||||
extender({}),
|
||||
target({}),
|
||||
specificity(0),
|
||||
isOptional(false),
|
||||
isOriginal(false),
|
||||
isSatisfied(false),
|
||||
mediaContext({}) {
|
||||
}
|
||||
|
||||
// Asserts that the [mediaContext] for a selector is
|
||||
// compatible with the query context for this extender.
|
||||
void assertCompatibleMediaContext(CssMediaRuleObj mediaContext, Backtraces& traces) const;
|
||||
|
||||
Extension withExtender(const ComplexSelectorObj& newExtender) const;
|
||||
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
531
vendor/bundle/ruby/2.6.0/gems/sassc-2.4.0/ext/libsass/src/file.cpp
vendored
Normal file
531
vendor/bundle/ruby/2.6.0/gems/sassc-2.4.0/ext/libsass/src/file.cpp
vendored
Normal file
@@ -0,0 +1,531 @@
|
||||
// sass.hpp must go before all system headers to get the
|
||||
// __EXTENSIONS__ fix on Solaris.
|
||||
#include "sass.hpp"
|
||||
|
||||
#ifdef _WIN32
|
||||
# ifdef __MINGW32__
|
||||
# ifndef off64_t
|
||||
# define off64_t _off64_t /* Workaround for http://sourceforge.net/p/mingw/bugs/2024/ */
|
||||
# endif
|
||||
# endif
|
||||
# include <direct.h>
|
||||
# define S_ISDIR(mode) (((mode) & S_IFMT) == S_IFDIR)
|
||||
#else
|
||||
# include <unistd.h>
|
||||
#endif
|
||||
#include <cstdio>
|
||||
#include <vector>
|
||||
#include <algorithm>
|
||||
#include <sys/stat.h>
|
||||
#include "file.hpp"
|
||||
#include "context.hpp"
|
||||
#include "prelexer.hpp"
|
||||
#include "utf8_string.hpp"
|
||||
#include "sass_functions.hpp"
|
||||
#include "error_handling.hpp"
|
||||
#include "util.hpp"
|
||||
#include "util_string.hpp"
|
||||
#include "sass2scss.h"
|
||||
|
||||
#ifdef _WIN32
|
||||
# include <windows.h>
|
||||
|
||||
# ifdef _MSC_VER
|
||||
# include <codecvt>
|
||||
inline static Sass::sass::string wstring_to_string(const std::wstring& wstr)
|
||||
{
|
||||
std::wstring_convert<std::codecvt_utf8<wchar_t>, wchar_t> wchar_converter;
|
||||
return wchar_converter.to_bytes(wstr);
|
||||
}
|
||||
# else // mingw(/gcc) does not support C++11's codecvt yet.
|
||||
inline static Sass::sass::string wstring_to_string(const std::wstring &wstr)
|
||||
{
|
||||
int size_needed = WideCharToMultiByte(CP_UTF8, 0, &wstr[0], (int)wstr.size(), NULL, 0, NULL, NULL);
|
||||
Sass::sass::string strTo(size_needed, 0);
|
||||
WideCharToMultiByte(CP_UTF8, 0, &wstr[0], (int)wstr.size(), &strTo[0], size_needed, NULL, NULL);
|
||||
return strTo;
|
||||
}
|
||||
# endif
|
||||
#endif
|
||||
|
||||
namespace Sass {
|
||||
namespace File {
|
||||
|
||||
// return the current directory
|
||||
// always with forward slashes
|
||||
// always with trailing slash
|
||||
sass::string get_cwd()
|
||||
{
|
||||
const size_t wd_len = 4096;
|
||||
#ifndef _WIN32
|
||||
char wd[wd_len];
|
||||
char* pwd = getcwd(wd, wd_len);
|
||||
// we should check error for more detailed info (e.g. ENOENT)
|
||||
// http://man7.org/linux/man-pages/man2/getcwd.2.html#ERRORS
|
||||
if (pwd == NULL) throw Exception::OperationError("cwd gone missing");
|
||||
sass::string cwd = pwd;
|
||||
#else
|
||||
wchar_t wd[wd_len];
|
||||
wchar_t* pwd = _wgetcwd(wd, wd_len);
|
||||
if (pwd == NULL) throw Exception::OperationError("cwd gone missing");
|
||||
sass::string cwd = wstring_to_string(pwd);
|
||||
//convert backslashes to forward slashes
|
||||
replace(cwd.begin(), cwd.end(), '\\', '/');
|
||||
#endif
|
||||
if (cwd[cwd.length() - 1] != '/') cwd += '/';
|
||||
return cwd;
|
||||
}
|
||||
|
||||
// test if path exists and is a file
|
||||
bool file_exists(const sass::string& path)
|
||||
{
|
||||
#ifdef _WIN32
|
||||
wchar_t resolved[32768];
|
||||
// windows unicode filepaths are encoded in utf16
|
||||
sass::string abspath(join_paths(get_cwd(), path));
|
||||
if (!(abspath[0] == '/' && abspath[1] == '/')) {
|
||||
abspath = "//?/" + abspath;
|
||||
}
|
||||
std::wstring wpath(UTF_8::convert_to_utf16(abspath));
|
||||
std::replace(wpath.begin(), wpath.end(), '/', '\\');
|
||||
DWORD rv = GetFullPathNameW(wpath.c_str(), 32767, resolved, NULL);
|
||||
if (rv > 32767) throw Exception::OperationError("Path is too long");
|
||||
if (rv == 0) throw Exception::OperationError("Path could not be resolved");
|
||||
DWORD dwAttrib = GetFileAttributesW(resolved);
|
||||
return (dwAttrib != INVALID_FILE_ATTRIBUTES &&
|
||||
(!(dwAttrib & FILE_ATTRIBUTE_DIRECTORY)));
|
||||
#else
|
||||
struct stat st_buf;
|
||||
return (stat (path.c_str(), &st_buf) == 0) &&
|
||||
(!S_ISDIR (st_buf.st_mode));
|
||||
#endif
|
||||
}
|
||||
|
||||
// return if given path is absolute
|
||||
// works with *nix and windows paths
|
||||
bool is_absolute_path(const sass::string& path)
|
||||
{
|
||||
#ifdef _WIN32
|
||||
if (path.length() >= 2 && Util::ascii_isalpha(path[0]) && path[1] == ':') return true;
|
||||
#endif
|
||||
size_t i = 0;
|
||||
// check if we have a protocol
|
||||
if (path[i] && Util::ascii_isalpha(static_cast<unsigned char>(path[i]))) {
|
||||
// skip over all alphanumeric characters
|
||||
while (path[i] && Util::ascii_isalnum(static_cast<unsigned char>(path[i]))) ++i;
|
||||
i = i && path[i] == ':' ? i + 1 : 0;
|
||||
}
|
||||
return path[i] == '/';
|
||||
}
|
||||
|
||||
// helper function to find the last directory separator
|
||||
inline size_t find_last_folder_separator(const sass::string& path, size_t limit = sass::string::npos)
|
||||
{
|
||||
size_t pos;
|
||||
size_t pos_p = path.find_last_of('/', limit);
|
||||
#ifdef _WIN32
|
||||
size_t pos_w = path.find_last_of('\\', limit);
|
||||
#else
|
||||
size_t pos_w = sass::string::npos;
|
||||
#endif
|
||||
if (pos_p != sass::string::npos && pos_w != sass::string::npos) {
|
||||
pos = std::max(pos_p, pos_w);
|
||||
}
|
||||
else if (pos_p != sass::string::npos) {
|
||||
pos = pos_p;
|
||||
}
|
||||
else {
|
||||
pos = pos_w;
|
||||
}
|
||||
return pos;
|
||||
}
|
||||
|
||||
// return only the directory part of path
|
||||
sass::string dir_name(const sass::string& path)
|
||||
{
|
||||
size_t pos = find_last_folder_separator(path);
|
||||
if (pos == sass::string::npos) return "";
|
||||
else return path.substr(0, pos+1);
|
||||
}
|
||||
|
||||
// return only the filename part of path
|
||||
sass::string base_name(const sass::string& path)
|
||||
{
|
||||
size_t pos = find_last_folder_separator(path);
|
||||
if (pos == sass::string::npos) return path;
|
||||
else return path.substr(pos+1);
|
||||
}
|
||||
|
||||
// do a logical clean up of the path
|
||||
// no physical check on the filesystem
|
||||
sass::string make_canonical_path (sass::string path)
|
||||
{
|
||||
|
||||
// declarations
|
||||
size_t pos;
|
||||
|
||||
#ifdef _WIN32
|
||||
//convert backslashes to forward slashes
|
||||
replace(path.begin(), path.end(), '\\', '/');
|
||||
#endif
|
||||
|
||||
pos = 0; // remove all self references inside the path string
|
||||
while((pos = path.find("/./", pos)) != sass::string::npos) path.erase(pos, 2);
|
||||
|
||||
// remove all leading and trailing self references
|
||||
while(path.size() >= 2 && path[0] == '.' && path[1] == '/') path.erase(0, 2);
|
||||
while((pos = path.length()) > 1 && path[pos - 2] == '/' && path[pos - 1] == '.') path.erase(pos - 2);
|
||||
|
||||
|
||||
size_t proto = 0;
|
||||
// check if we have a protocol
|
||||
if (path[proto] && Util::ascii_isalpha(static_cast<unsigned char>(path[proto]))) {
|
||||
// skip over all alphanumeric characters
|
||||
while (path[proto] && Util::ascii_isalnum(static_cast<unsigned char>(path[proto++]))) {}
|
||||
// then skip over the mandatory colon
|
||||
if (proto && path[proto] == ':') ++ proto;
|
||||
}
|
||||
|
||||
// then skip over start slashes
|
||||
while (path[proto++] == '/') {}
|
||||
|
||||
pos = proto; // collapse multiple delimiters into a single one
|
||||
while((pos = path.find("//", pos)) != sass::string::npos) path.erase(pos, 1);
|
||||
|
||||
return path;
|
||||
|
||||
}
|
||||
|
||||
// join two path segments cleanly together
|
||||
// but only if right side is not absolute yet
|
||||
sass::string join_paths(sass::string l, sass::string r)
|
||||
{
|
||||
|
||||
#ifdef _WIN32
|
||||
// convert Windows backslashes to URL forward slashes
|
||||
replace(l.begin(), l.end(), '\\', '/');
|
||||
replace(r.begin(), r.end(), '\\', '/');
|
||||
#endif
|
||||
|
||||
if (l.empty()) return r;
|
||||
if (r.empty()) return l;
|
||||
|
||||
if (is_absolute_path(r)) return r;
|
||||
if (l[l.length()-1] != '/') l += '/';
|
||||
|
||||
// this does a logical cleanup of the right hand path
|
||||
// Note that this does collapse x/../y sections into y.
|
||||
// This is by design. If /foo on your system is a symlink
|
||||
// to /bar/baz, then /foo/../cd is actually /bar/cd,
|
||||
// not /cd as a naive ../ removal would give you.
|
||||
// will only work on leading double dot dirs on rhs
|
||||
// therefore it is safe if lhs is already resolved cwd
|
||||
while ((r.length() > 3) && ((r.substr(0, 3) == "../") || (r.substr(0, 3)) == "..\\")) {
|
||||
size_t L = l.length(), pos = find_last_folder_separator(l, L - 2);
|
||||
bool is_slash = pos + 2 == L && (l[pos+1] == '/' || l[pos+1] == '\\');
|
||||
bool is_self = pos + 3 == L && (l[pos+1] == '.');
|
||||
if (!is_self && !is_slash) r = r.substr(3);
|
||||
else if (pos == sass::string::npos) break;
|
||||
l = l.substr(0, pos == sass::string::npos ? pos : pos + 1);
|
||||
}
|
||||
|
||||
return l + r;
|
||||
}
|
||||
|
||||
sass::string path_for_console(const sass::string& rel_path, const sass::string& abs_path, const sass::string& orig_path)
|
||||
{
|
||||
// magic algorithm goes here!!
|
||||
|
||||
// if the file is outside this directory show the absolute path
|
||||
if (rel_path.substr(0, 3) == "../") {
|
||||
return orig_path;
|
||||
}
|
||||
// this seems to work most of the time
|
||||
return abs_path == orig_path ? abs_path : rel_path;
|
||||
}
|
||||
|
||||
// create an absolute path by resolving relative paths with cwd
|
||||
sass::string rel2abs(const sass::string& path, const sass::string& base, const sass::string& cwd)
|
||||
{
|
||||
sass::string rv = make_canonical_path(join_paths(join_paths(cwd + "/", base + "/"), path));
|
||||
#ifdef _WIN32
|
||||
// On windows we may get an absolute path without directory
|
||||
// In that case we should prepend the directory from the root
|
||||
if (rv[0] == '/' && rv[1] != '/') {
|
||||
rv.insert(0, cwd, 0, 2);
|
||||
}
|
||||
#endif
|
||||
return rv;
|
||||
}
|
||||
|
||||
// create a path that is relative to the given base directory
|
||||
// path and base will first be resolved against cwd to make them absolute
|
||||
sass::string abs2rel(const sass::string& path, const sass::string& base, const sass::string& cwd)
|
||||
{
|
||||
|
||||
sass::string abs_path = rel2abs(path, cwd);
|
||||
sass::string abs_base = rel2abs(base, cwd);
|
||||
|
||||
size_t proto = 0;
|
||||
// check if we have a protocol
|
||||
if (path[proto] && Util::ascii_isalpha(static_cast<unsigned char>(path[proto]))) {
|
||||
// skip over all alphanumeric characters
|
||||
while (path[proto] && Util::ascii_isalnum(static_cast<unsigned char>(path[proto++]))) {}
|
||||
// then skip over the mandatory colon
|
||||
if (proto && path[proto] == ':') ++ proto;
|
||||
}
|
||||
|
||||
// distinguish between windows absolute paths and valid protocols
|
||||
// we assume that protocols must at least have two chars to be valid
|
||||
if (proto && path[proto++] == '/' && proto > 3) return path;
|
||||
|
||||
#ifdef _WIN32
|
||||
// absolute link must have a drive letter, and we know that we
|
||||
// can only create relative links if both are on the same drive
|
||||
if (abs_base[0] != abs_path[0]) return abs_path;
|
||||
#endif
|
||||
|
||||
sass::string stripped_uri = "";
|
||||
sass::string stripped_base = "";
|
||||
|
||||
size_t index = 0;
|
||||
size_t minSize = std::min(abs_path.size(), abs_base.size());
|
||||
for (size_t i = 0; i < minSize; ++i) {
|
||||
#ifdef FS_CASE_SENSITIVE
|
||||
if (abs_path[i] != abs_base[i]) break;
|
||||
#else
|
||||
// compare the charactes in a case insensitive manner
|
||||
// windows fs is only case insensitive in ascii ranges
|
||||
if (Util::ascii_tolower(static_cast<unsigned char>(abs_path[i])) !=
|
||||
Util::ascii_tolower(static_cast<unsigned char>(abs_base[i]))) break;
|
||||
#endif
|
||||
if (abs_path[i] == '/') index = i + 1;
|
||||
}
|
||||
for (size_t i = index; i < abs_path.size(); ++i) {
|
||||
stripped_uri += abs_path[i];
|
||||
}
|
||||
for (size_t i = index; i < abs_base.size(); ++i) {
|
||||
stripped_base += abs_base[i];
|
||||
}
|
||||
|
||||
size_t left = 0;
|
||||
size_t directories = 0;
|
||||
for (size_t right = 0; right < stripped_base.size(); ++right) {
|
||||
if (stripped_base[right] == '/') {
|
||||
if (stripped_base.substr(left, 2) != "..") {
|
||||
++directories;
|
||||
}
|
||||
else if (directories > 1) {
|
||||
--directories;
|
||||
}
|
||||
else {
|
||||
directories = 0;
|
||||
}
|
||||
left = right + 1;
|
||||
}
|
||||
}
|
||||
|
||||
sass::string result = "";
|
||||
for (size_t i = 0; i < directories; ++i) {
|
||||
result += "../";
|
||||
}
|
||||
result += stripped_uri;
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
// Resolution order for ambiguous imports:
|
||||
// (1) filename as given
|
||||
// (2) underscore + given
|
||||
// (3) underscore + given + extension
|
||||
// (4) given + extension
|
||||
// (5) given + _index.scss
|
||||
// (6) given + _index.sass
|
||||
sass::vector<Include> resolve_includes(const sass::string& root, const sass::string& file, const sass::vector<sass::string>& exts)
|
||||
{
|
||||
sass::string filename = join_paths(root, file);
|
||||
// split the filename
|
||||
sass::string base(dir_name(file));
|
||||
sass::string name(base_name(file));
|
||||
sass::vector<Include> includes;
|
||||
// create full path (maybe relative)
|
||||
sass::string rel_path(join_paths(base, name));
|
||||
sass::string abs_path(join_paths(root, rel_path));
|
||||
if (file_exists(abs_path)) includes.push_back({{ rel_path, root }, abs_path });
|
||||
// next test variation with underscore
|
||||
rel_path = join_paths(base, "_" + name);
|
||||
abs_path = join_paths(root, rel_path);
|
||||
if (file_exists(abs_path)) includes.push_back({{ rel_path, root }, abs_path });
|
||||
// next test exts plus underscore
|
||||
for(auto ext : exts) {
|
||||
rel_path = join_paths(base, "_" + name + ext);
|
||||
abs_path = join_paths(root, rel_path);
|
||||
if (file_exists(abs_path)) includes.push_back({{ rel_path, root }, abs_path });
|
||||
}
|
||||
// next test plain name with exts
|
||||
for(auto ext : exts) {
|
||||
rel_path = join_paths(base, name + ext);
|
||||
abs_path = join_paths(root, rel_path);
|
||||
if (file_exists(abs_path)) includes.push_back({{ rel_path, root }, abs_path });
|
||||
}
|
||||
// index files
|
||||
if (includes.size() == 0) {
|
||||
// ignore directories that look like @import'able filename
|
||||
for(auto ext : exts) {
|
||||
if (ends_with(name, ext)) return includes;
|
||||
}
|
||||
// next test underscore index exts
|
||||
for(auto ext : exts) {
|
||||
rel_path = join_paths(base, join_paths(name, "_index" + ext));
|
||||
abs_path = join_paths(root, rel_path);
|
||||
if (file_exists(abs_path)) includes.push_back({{ rel_path, root }, abs_path });
|
||||
}
|
||||
// next test plain index exts
|
||||
for(auto ext : exts) {
|
||||
rel_path = join_paths(base, join_paths(name, "index" + ext));
|
||||
abs_path = join_paths(root, rel_path);
|
||||
if (file_exists(abs_path)) includes.push_back({{ rel_path, root }, abs_path });
|
||||
}
|
||||
}
|
||||
// nothing found
|
||||
return includes;
|
||||
}
|
||||
|
||||
sass::vector<sass::string> find_files(const sass::string& file, const sass::vector<sass::string> paths)
|
||||
{
|
||||
sass::vector<sass::string> includes;
|
||||
for (sass::string path : paths) {
|
||||
sass::string abs_path(join_paths(path, file));
|
||||
if (file_exists(abs_path)) includes.push_back(abs_path);
|
||||
}
|
||||
return includes;
|
||||
}
|
||||
|
||||
sass::vector<sass::string> find_files(const sass::string& file, struct Sass_Compiler* compiler)
|
||||
{
|
||||
// get the last import entry to get current base directory
|
||||
// struct Sass_Options* options = sass_compiler_get_options(compiler);
|
||||
Sass_Import_Entry import = sass_compiler_get_last_import(compiler);
|
||||
const sass::vector<sass::string>& incs = compiler->cpp_ctx->include_paths;
|
||||
// create the vector with paths to lookup
|
||||
sass::vector<sass::string> paths(1 + incs.size());
|
||||
paths.push_back(dir_name(import->abs_path));
|
||||
paths.insert(paths.end(), incs.begin(), incs.end());
|
||||
// dispatch to find files in paths
|
||||
return find_files(file, paths);
|
||||
}
|
||||
|
||||
// helper function to search one file in all include paths
|
||||
// this is normally not used internally by libsass (C-API sugar)
|
||||
sass::string find_file(const sass::string& file, const sass::vector<sass::string> paths)
|
||||
{
|
||||
if (file.empty()) return file;
|
||||
auto res = find_files(file, paths);
|
||||
return res.empty() ? "" : res.front();
|
||||
}
|
||||
|
||||
// helper function to resolve a filename
|
||||
sass::string find_include(const sass::string& file, const sass::vector<sass::string> paths)
|
||||
{
|
||||
// search in every include path for a match
|
||||
for (size_t i = 0, S = paths.size(); i < S; ++i)
|
||||
{
|
||||
sass::vector<Include> resolved(resolve_includes(paths[i], file));
|
||||
if (resolved.size()) return resolved[0].abs_path;
|
||||
}
|
||||
// nothing found
|
||||
return sass::string("");
|
||||
}
|
||||
|
||||
// try to load the given filename
|
||||
// returned memory must be freed
|
||||
// will auto convert .sass files
|
||||
char* read_file(const sass::string& path)
|
||||
{
|
||||
#ifdef _WIN32
|
||||
BYTE* pBuffer;
|
||||
DWORD dwBytes;
|
||||
wchar_t resolved[32768];
|
||||
// windows unicode filepaths are encoded in utf16
|
||||
sass::string abspath(join_paths(get_cwd(), path));
|
||||
if (!(abspath[0] == '/' && abspath[1] == '/')) {
|
||||
abspath = "//?/" + abspath;
|
||||
}
|
||||
std::wstring wpath(UTF_8::convert_to_utf16(abspath));
|
||||
std::replace(wpath.begin(), wpath.end(), '/', '\\');
|
||||
DWORD rv = GetFullPathNameW(wpath.c_str(), 32767, resolved, NULL);
|
||||
if (rv > 32767) throw Exception::OperationError("Path is too long");
|
||||
if (rv == 0) throw Exception::OperationError("Path could not be resolved");
|
||||
HANDLE hFile = CreateFileW(resolved, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, 0, NULL);
|
||||
if (hFile == INVALID_HANDLE_VALUE) return 0;
|
||||
DWORD dwFileLength = GetFileSize(hFile, NULL);
|
||||
if (dwFileLength == INVALID_FILE_SIZE) return 0;
|
||||
// allocate an extra byte for the null char
|
||||
// and another one for edge-cases in lexer
|
||||
pBuffer = (BYTE*)malloc((dwFileLength+2)*sizeof(BYTE));
|
||||
ReadFile(hFile, pBuffer, dwFileLength, &dwBytes, NULL);
|
||||
pBuffer[dwFileLength+0] = '\0';
|
||||
pBuffer[dwFileLength+1] = '\0';
|
||||
CloseHandle(hFile);
|
||||
// just convert from unsigned char*
|
||||
char* contents = (char*) pBuffer;
|
||||
#else
|
||||
// Read the file using `<cstdio>` instead of `<fstream>` for better portability.
|
||||
// The `<fstream>` header initializes `<locale>` and this buggy in GCC4/5 with static linking.
|
||||
// See:
|
||||
// https://www.spinics.net/lists/gcchelp/msg46851.html
|
||||
// https://github.com/sass/sassc-ruby/issues/128
|
||||
struct stat st;
|
||||
if (stat(path.c_str(), &st) == -1 || S_ISDIR(st.st_mode)) return 0;
|
||||
FILE* fd = std::fopen(path.c_str(), "rb");
|
||||
if (fd == nullptr) return nullptr;
|
||||
const std::size_t size = st.st_size;
|
||||
char* contents = static_cast<char*>(malloc(st.st_size + 2 * sizeof(char)));
|
||||
if (std::fread(static_cast<void*>(contents), 1, size, fd) != size) {
|
||||
free(contents);
|
||||
std::fclose(fd);
|
||||
return nullptr;
|
||||
}
|
||||
if (std::fclose(fd) != 0) {
|
||||
free(contents);
|
||||
return nullptr;
|
||||
}
|
||||
contents[size] = '\0';
|
||||
contents[size + 1] = '\0';
|
||||
#endif
|
||||
sass::string extension;
|
||||
if (path.length() > 5) {
|
||||
extension = path.substr(path.length() - 5, 5);
|
||||
}
|
||||
Util::ascii_str_tolower(&extension);
|
||||
if (extension == ".sass" && contents != 0) {
|
||||
char * converted = sass2scss(contents, SASS2SCSS_PRETTIFY_1 | SASS2SCSS_KEEP_COMMENT);
|
||||
free(contents); // free the indented contents
|
||||
return converted; // should be freed by caller
|
||||
} else {
|
||||
return contents;
|
||||
}
|
||||
}
|
||||
|
||||
// split a path string delimited by semicolons or colons (OS dependent)
|
||||
sass::vector<sass::string> split_path_list(const char* str)
|
||||
{
|
||||
sass::vector<sass::string> paths;
|
||||
if (str == NULL) return paths;
|
||||
// find delimiter via prelexer (return zero at end)
|
||||
const char* end = Prelexer::find_first<PATH_SEP>(str);
|
||||
// search until null delimiter
|
||||
while (end) {
|
||||
// add path from current position to delimiter
|
||||
paths.push_back(sass::string(str, end - str));
|
||||
str = end + 1; // skip delimiter
|
||||
end = Prelexer::find_first<PATH_SEP>(str);
|
||||
}
|
||||
// add path from current position to end
|
||||
paths.push_back(sass::string(str));
|
||||
// return back
|
||||
return paths;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
124
vendor/bundle/ruby/2.6.0/gems/sassc-2.4.0/ext/libsass/src/file.hpp
vendored
Normal file
124
vendor/bundle/ruby/2.6.0/gems/sassc-2.4.0/ext/libsass/src/file.hpp
vendored
Normal file
@@ -0,0 +1,124 @@
|
||||
#ifndef SASS_FILE_H
|
||||
#define SASS_FILE_H
|
||||
|
||||
// sass.hpp must go before all system headers to get the
|
||||
// __EXTENSIONS__ fix on Solaris.
|
||||
#include "sass.hpp"
|
||||
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
#include "sass/context.h"
|
||||
#include "ast_fwd_decl.hpp"
|
||||
|
||||
namespace Sass {
|
||||
|
||||
namespace File {
|
||||
|
||||
// return the current directory
|
||||
// always with forward slashes
|
||||
sass::string get_cwd();
|
||||
|
||||
// test if path exists and is a file
|
||||
bool file_exists(const sass::string& file);
|
||||
|
||||
// return if given path is absolute
|
||||
// works with *nix and windows paths
|
||||
bool is_absolute_path(const sass::string& path);
|
||||
|
||||
// return only the directory part of path
|
||||
sass::string dir_name(const sass::string& path);
|
||||
|
||||
// return only the filename part of path
|
||||
sass::string base_name(const sass::string&);
|
||||
|
||||
// do a locigal clean up of the path
|
||||
// no physical check on the filesystem
|
||||
sass::string make_canonical_path (sass::string path);
|
||||
|
||||
// join two path segments cleanly together
|
||||
// but only if right side is not absolute yet
|
||||
sass::string join_paths(sass::string root, sass::string name);
|
||||
|
||||
// if the relative path is outside of the cwd we want want to
|
||||
// show the absolute path in console messages
|
||||
sass::string path_for_console(const sass::string& rel_path, const sass::string& abs_path, const sass::string& orig_path);
|
||||
|
||||
// create an absolute path by resolving relative paths with cwd
|
||||
sass::string rel2abs(const sass::string& path, const sass::string& base = ".", const sass::string& cwd = get_cwd());
|
||||
|
||||
// create a path that is relative to the given base directory
|
||||
// path and base will first be resolved against cwd to make them absolute
|
||||
sass::string abs2rel(const sass::string& path, const sass::string& base = ".", const sass::string& cwd = get_cwd());
|
||||
|
||||
// helper function to resolve a filename
|
||||
// searching without variations in all paths
|
||||
sass::string find_file(const sass::string& file, struct Sass_Compiler* options);
|
||||
sass::string find_file(const sass::string& file, const sass::vector<sass::string> paths);
|
||||
|
||||
// helper function to resolve a include filename
|
||||
// this has the original resolve logic for sass include
|
||||
sass::string find_include(const sass::string& file, const sass::vector<sass::string> paths);
|
||||
|
||||
// split a path string delimited by semicolons or colons (OS dependent)
|
||||
sass::vector<sass::string> split_path_list(const char* paths);
|
||||
|
||||
// try to load the given filename
|
||||
// returned memory must be freed
|
||||
// will auto convert .sass files
|
||||
char* read_file(const sass::string& file);
|
||||
|
||||
}
|
||||
|
||||
// requested import
|
||||
class Importer {
|
||||
public:
|
||||
// requested import path
|
||||
sass::string imp_path;
|
||||
// parent context path
|
||||
sass::string ctx_path;
|
||||
// base derived from context path
|
||||
// this really just acts as a cache
|
||||
sass::string base_path;
|
||||
public:
|
||||
Importer(sass::string imp_path, sass::string ctx_path)
|
||||
: imp_path(File::make_canonical_path(imp_path)),
|
||||
ctx_path(File::make_canonical_path(ctx_path)),
|
||||
base_path(File::dir_name(ctx_path))
|
||||
{ }
|
||||
};
|
||||
|
||||
// a resolved include (final import)
|
||||
class Include : public Importer {
|
||||
public:
|
||||
// resolved absolute path
|
||||
sass::string abs_path;
|
||||
public:
|
||||
Include(const Importer& imp, sass::string abs_path)
|
||||
: Importer(imp), abs_path(abs_path)
|
||||
{ }
|
||||
};
|
||||
|
||||
// a loaded resource
|
||||
class Resource {
|
||||
public:
|
||||
// the file contents
|
||||
char* contents;
|
||||
// connected sourcemap
|
||||
char* srcmap;
|
||||
public:
|
||||
Resource(char* contents, char* srcmap)
|
||||
: contents(contents), srcmap(srcmap)
|
||||
{ }
|
||||
};
|
||||
|
||||
namespace File {
|
||||
|
||||
sass::vector<Include> resolve_includes(const sass::string& root, const sass::string& file,
|
||||
const sass::vector<sass::string>& exts = { ".scss", ".sass", ".css" });
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
596
vendor/bundle/ruby/2.6.0/gems/sassc-2.4.0/ext/libsass/src/fn_colors.cpp
vendored
Normal file
596
vendor/bundle/ruby/2.6.0/gems/sassc-2.4.0/ext/libsass/src/fn_colors.cpp
vendored
Normal file
@@ -0,0 +1,596 @@
|
||||
// sass.hpp must go before all system headers to get the
|
||||
// __EXTENSIONS__ fix on Solaris.
|
||||
#include "sass.hpp"
|
||||
|
||||
#include <iomanip>
|
||||
#include "ast.hpp"
|
||||
#include "fn_utils.hpp"
|
||||
#include "fn_colors.hpp"
|
||||
#include "util.hpp"
|
||||
#include "util_string.hpp"
|
||||
|
||||
namespace Sass {
|
||||
|
||||
namespace Functions {
|
||||
|
||||
bool string_argument(AST_Node_Obj obj) {
|
||||
String_Constant* s = Cast<String_Constant>(obj);
|
||||
if (s == nullptr) return false;
|
||||
const sass::string& str = s->value();
|
||||
return starts_with(str, "calc(") ||
|
||||
starts_with(str, "var(");
|
||||
}
|
||||
|
||||
void hsla_alpha_percent_deprecation(const SourceSpan& pstate, const sass::string val)
|
||||
{
|
||||
|
||||
sass::string msg("Passing a percentage as the alpha value to hsla() will be interpreted");
|
||||
sass::string tail("differently in future versions of Sass. For now, use " + val + " instead.");
|
||||
|
||||
deprecated(msg, tail, false, pstate);
|
||||
|
||||
}
|
||||
|
||||
Signature rgb_sig = "rgb($red, $green, $blue)";
|
||||
BUILT_IN(rgb)
|
||||
{
|
||||
if (
|
||||
string_argument(env["$red"]) ||
|
||||
string_argument(env["$green"]) ||
|
||||
string_argument(env["$blue"])
|
||||
) {
|
||||
return SASS_MEMORY_NEW(String_Constant, pstate, "rgb("
|
||||
+ env["$red"]->to_string()
|
||||
+ ", "
|
||||
+ env["$green"]->to_string()
|
||||
+ ", "
|
||||
+ env["$blue"]->to_string()
|
||||
+ ")"
|
||||
);
|
||||
}
|
||||
|
||||
return SASS_MEMORY_NEW(Color_RGBA,
|
||||
pstate,
|
||||
COLOR_NUM("$red"),
|
||||
COLOR_NUM("$green"),
|
||||
COLOR_NUM("$blue"));
|
||||
}
|
||||
|
||||
Signature rgba_4_sig = "rgba($red, $green, $blue, $alpha)";
|
||||
BUILT_IN(rgba_4)
|
||||
{
|
||||
if (
|
||||
string_argument(env["$red"]) ||
|
||||
string_argument(env["$green"]) ||
|
||||
string_argument(env["$blue"]) ||
|
||||
string_argument(env["$alpha"])
|
||||
) {
|
||||
return SASS_MEMORY_NEW(String_Constant, pstate, "rgba("
|
||||
+ env["$red"]->to_string()
|
||||
+ ", "
|
||||
+ env["$green"]->to_string()
|
||||
+ ", "
|
||||
+ env["$blue"]->to_string()
|
||||
+ ", "
|
||||
+ env["$alpha"]->to_string()
|
||||
+ ")"
|
||||
);
|
||||
}
|
||||
|
||||
return SASS_MEMORY_NEW(Color_RGBA,
|
||||
pstate,
|
||||
COLOR_NUM("$red"),
|
||||
COLOR_NUM("$green"),
|
||||
COLOR_NUM("$blue"),
|
||||
ALPHA_NUM("$alpha"));
|
||||
}
|
||||
|
||||
Signature rgba_2_sig = "rgba($color, $alpha)";
|
||||
BUILT_IN(rgba_2)
|
||||
{
|
||||
if (
|
||||
string_argument(env["$color"])
|
||||
) {
|
||||
return SASS_MEMORY_NEW(String_Constant, pstate, "rgba("
|
||||
+ env["$color"]->to_string()
|
||||
+ ", "
|
||||
+ env["$alpha"]->to_string()
|
||||
+ ")"
|
||||
);
|
||||
}
|
||||
|
||||
Color_RGBA_Obj c_arg = ARG("$color", Color)->toRGBA();
|
||||
|
||||
if (
|
||||
string_argument(env["$alpha"])
|
||||
) {
|
||||
sass::ostream strm;
|
||||
strm << "rgba("
|
||||
<< (int)c_arg->r() << ", "
|
||||
<< (int)c_arg->g() << ", "
|
||||
<< (int)c_arg->b() << ", "
|
||||
<< env["$alpha"]->to_string()
|
||||
<< ")";
|
||||
return SASS_MEMORY_NEW(String_Constant, pstate, strm.str());
|
||||
}
|
||||
|
||||
Color_RGBA_Obj new_c = SASS_MEMORY_COPY(c_arg);
|
||||
new_c->a(ALPHA_NUM("$alpha"));
|
||||
new_c->disp("");
|
||||
return new_c.detach();
|
||||
}
|
||||
|
||||
////////////////
|
||||
// RGB FUNCTIONS
|
||||
////////////////
|
||||
|
||||
Signature red_sig = "red($color)";
|
||||
BUILT_IN(red)
|
||||
{
|
||||
Color_RGBA_Obj color = ARG("$color", Color)->toRGBA();
|
||||
return SASS_MEMORY_NEW(Number, pstate, color->r());
|
||||
}
|
||||
|
||||
Signature green_sig = "green($color)";
|
||||
BUILT_IN(green)
|
||||
{
|
||||
Color_RGBA_Obj color = ARG("$color", Color)->toRGBA();
|
||||
return SASS_MEMORY_NEW(Number, pstate, color->g());
|
||||
}
|
||||
|
||||
Signature blue_sig = "blue($color)";
|
||||
BUILT_IN(blue)
|
||||
{
|
||||
Color_RGBA_Obj color = ARG("$color", Color)->toRGBA();
|
||||
return SASS_MEMORY_NEW(Number, pstate, color->b());
|
||||
}
|
||||
|
||||
Color_RGBA* colormix(Context& ctx, SourceSpan& pstate, Color* color1, Color* color2, double weight) {
|
||||
Color_RGBA_Obj c1 = color1->toRGBA();
|
||||
Color_RGBA_Obj c2 = color2->toRGBA();
|
||||
double p = weight/100;
|
||||
double w = 2*p - 1;
|
||||
double a = c1->a() - c2->a();
|
||||
|
||||
double w1 = (((w * a == -1) ? w : (w + a)/(1 + w*a)) + 1)/2.0;
|
||||
double w2 = 1 - w1;
|
||||
|
||||
return SASS_MEMORY_NEW(Color_RGBA,
|
||||
pstate,
|
||||
Sass::round(w1*c1->r() + w2*c2->r(), ctx.c_options.precision),
|
||||
Sass::round(w1*c1->g() + w2*c2->g(), ctx.c_options.precision),
|
||||
Sass::round(w1*c1->b() + w2*c2->b(), ctx.c_options.precision),
|
||||
c1->a()*p + c2->a()*(1-p));
|
||||
}
|
||||
|
||||
Signature mix_sig = "mix($color1, $color2, $weight: 50%)";
|
||||
BUILT_IN(mix)
|
||||
{
|
||||
Color_Obj color1 = ARG("$color1", Color);
|
||||
Color_Obj color2 = ARG("$color2", Color);
|
||||
double weight = DARG_U_PRCT("$weight");
|
||||
return colormix(ctx, pstate, color1, color2, weight);
|
||||
|
||||
}
|
||||
|
||||
////////////////
|
||||
// HSL FUNCTIONS
|
||||
////////////////
|
||||
|
||||
Signature hsl_sig = "hsl($hue, $saturation, $lightness)";
|
||||
BUILT_IN(hsl)
|
||||
{
|
||||
if (
|
||||
string_argument(env["$hue"]) ||
|
||||
string_argument(env["$saturation"]) ||
|
||||
string_argument(env["$lightness"])
|
||||
) {
|
||||
return SASS_MEMORY_NEW(String_Constant, pstate, "hsl("
|
||||
+ env["$hue"]->to_string()
|
||||
+ ", "
|
||||
+ env["$saturation"]->to_string()
|
||||
+ ", "
|
||||
+ env["$lightness"]->to_string()
|
||||
+ ")"
|
||||
);
|
||||
}
|
||||
|
||||
return SASS_MEMORY_NEW(Color_HSLA,
|
||||
pstate,
|
||||
ARGVAL("$hue"),
|
||||
ARGVAL("$saturation"),
|
||||
ARGVAL("$lightness"),
|
||||
1.0);
|
||||
|
||||
}
|
||||
|
||||
Signature hsla_sig = "hsla($hue, $saturation, $lightness, $alpha)";
|
||||
BUILT_IN(hsla)
|
||||
{
|
||||
if (
|
||||
string_argument(env["$hue"]) ||
|
||||
string_argument(env["$saturation"]) ||
|
||||
string_argument(env["$lightness"]) ||
|
||||
string_argument(env["$alpha"])
|
||||
) {
|
||||
return SASS_MEMORY_NEW(String_Constant, pstate, "hsla("
|
||||
+ env["$hue"]->to_string()
|
||||
+ ", "
|
||||
+ env["$saturation"]->to_string()
|
||||
+ ", "
|
||||
+ env["$lightness"]->to_string()
|
||||
+ ", "
|
||||
+ env["$alpha"]->to_string()
|
||||
+ ")"
|
||||
);
|
||||
}
|
||||
|
||||
Number* alpha = ARG("$alpha", Number);
|
||||
if (alpha && alpha->unit() == "%") {
|
||||
Number_Obj val = SASS_MEMORY_COPY(alpha);
|
||||
val->numerators.clear(); // convert
|
||||
val->value(val->value() / 100.0);
|
||||
sass::string nr(val->to_string(ctx.c_options));
|
||||
hsla_alpha_percent_deprecation(pstate, nr);
|
||||
}
|
||||
|
||||
return SASS_MEMORY_NEW(Color_HSLA,
|
||||
pstate,
|
||||
ARGVAL("$hue"),
|
||||
ARGVAL("$saturation"),
|
||||
ARGVAL("$lightness"),
|
||||
ARGVAL("$alpha"));
|
||||
|
||||
}
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////
|
||||
// Query functions
|
||||
/////////////////////////////////////////////////////////////////////////
|
||||
|
||||
Signature hue_sig = "hue($color)";
|
||||
BUILT_IN(hue)
|
||||
{
|
||||
Color_HSLA_Obj col = ARG("$color", Color)->toHSLA();
|
||||
return SASS_MEMORY_NEW(Number, pstate, col->h(), "deg");
|
||||
}
|
||||
|
||||
Signature saturation_sig = "saturation($color)";
|
||||
BUILT_IN(saturation)
|
||||
{
|
||||
Color_HSLA_Obj col = ARG("$color", Color)->toHSLA();
|
||||
return SASS_MEMORY_NEW(Number, pstate, col->s(), "%");
|
||||
}
|
||||
|
||||
Signature lightness_sig = "lightness($color)";
|
||||
BUILT_IN(lightness)
|
||||
{
|
||||
Color_HSLA_Obj col = ARG("$color", Color)->toHSLA();
|
||||
return SASS_MEMORY_NEW(Number, pstate, col->l(), "%");
|
||||
}
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////
|
||||
// HSL manipulation functions
|
||||
/////////////////////////////////////////////////////////////////////////
|
||||
|
||||
Signature adjust_hue_sig = "adjust-hue($color, $degrees)";
|
||||
BUILT_IN(adjust_hue)
|
||||
{
|
||||
Color* col = ARG("$color", Color);
|
||||
double degrees = ARGVAL("$degrees");
|
||||
Color_HSLA_Obj copy = col->copyAsHSLA();
|
||||
copy->h(absmod(copy->h() + degrees, 360.0));
|
||||
return copy.detach();
|
||||
}
|
||||
|
||||
Signature lighten_sig = "lighten($color, $amount)";
|
||||
BUILT_IN(lighten)
|
||||
{
|
||||
Color* col = ARG("$color", Color);
|
||||
double amount = DARG_U_PRCT("$amount");
|
||||
Color_HSLA_Obj copy = col->copyAsHSLA();
|
||||
copy->l(clip(copy->l() + amount, 0.0, 100.0));
|
||||
return copy.detach();
|
||||
|
||||
}
|
||||
|
||||
Signature darken_sig = "darken($color, $amount)";
|
||||
BUILT_IN(darken)
|
||||
{
|
||||
Color* col = ARG("$color", Color);
|
||||
double amount = DARG_U_PRCT("$amount");
|
||||
Color_HSLA_Obj copy = col->copyAsHSLA();
|
||||
copy->l(clip(copy->l() - amount, 0.0, 100.0));
|
||||
return copy.detach();
|
||||
}
|
||||
|
||||
Signature saturate_sig = "saturate($color, $amount: false)";
|
||||
BUILT_IN(saturate)
|
||||
{
|
||||
// CSS3 filter function overload: pass literal through directly
|
||||
if (!Cast<Number>(env["$amount"])) {
|
||||
return SASS_MEMORY_NEW(String_Quoted, pstate, "saturate(" + env["$color"]->to_string(ctx.c_options) + ")");
|
||||
}
|
||||
|
||||
Color* col = ARG("$color", Color);
|
||||
double amount = DARG_U_PRCT("$amount");
|
||||
Color_HSLA_Obj copy = col->copyAsHSLA();
|
||||
copy->s(clip(copy->s() + amount, 0.0, 100.0));
|
||||
return copy.detach();
|
||||
}
|
||||
|
||||
Signature desaturate_sig = "desaturate($color, $amount)";
|
||||
BUILT_IN(desaturate)
|
||||
{
|
||||
Color* col = ARG("$color", Color);
|
||||
double amount = DARG_U_PRCT("$amount");
|
||||
Color_HSLA_Obj copy = col->copyAsHSLA();
|
||||
copy->s(clip(copy->s() - amount, 0.0, 100.0));
|
||||
return copy.detach();
|
||||
}
|
||||
|
||||
Signature grayscale_sig = "grayscale($color)";
|
||||
BUILT_IN(grayscale)
|
||||
{
|
||||
// CSS3 filter function overload: pass literal through directly
|
||||
Number* amount = Cast<Number>(env["$color"]);
|
||||
if (amount) {
|
||||
return SASS_MEMORY_NEW(String_Quoted, pstate, "grayscale(" + amount->to_string(ctx.c_options) + ")");
|
||||
}
|
||||
|
||||
Color* col = ARG("$color", Color);
|
||||
Color_HSLA_Obj copy = col->copyAsHSLA();
|
||||
copy->s(0.0); // just reset saturation
|
||||
return copy.detach();
|
||||
}
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////
|
||||
// Misc manipulation functions
|
||||
/////////////////////////////////////////////////////////////////////////
|
||||
|
||||
Signature complement_sig = "complement($color)";
|
||||
BUILT_IN(complement)
|
||||
{
|
||||
Color* col = ARG("$color", Color);
|
||||
Color_HSLA_Obj copy = col->copyAsHSLA();
|
||||
copy->h(absmod(copy->h() - 180.0, 360.0));
|
||||
return copy.detach();
|
||||
}
|
||||
|
||||
Signature invert_sig = "invert($color, $weight: 100%)";
|
||||
BUILT_IN(invert)
|
||||
{
|
||||
// CSS3 filter function overload: pass literal through directly
|
||||
Number* amount = Cast<Number>(env["$color"]);
|
||||
double weight = DARG_U_PRCT("$weight");
|
||||
if (amount) {
|
||||
// TODO: does not throw on 100% manually passed as value
|
||||
if (weight < 100.0) {
|
||||
error("Only one argument may be passed to the plain-CSS invert() function.", pstate, traces);
|
||||
}
|
||||
return SASS_MEMORY_NEW(String_Quoted, pstate, "invert(" + amount->to_string(ctx.c_options) + ")");
|
||||
}
|
||||
|
||||
Color* col = ARG("$color", Color);
|
||||
Color_RGBA_Obj inv = col->copyAsRGBA();
|
||||
inv->r(clip(255.0 - inv->r(), 0.0, 255.0));
|
||||
inv->g(clip(255.0 - inv->g(), 0.0, 255.0));
|
||||
inv->b(clip(255.0 - inv->b(), 0.0, 255.0));
|
||||
return colormix(ctx, pstate, inv, col, weight);
|
||||
}
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////
|
||||
// Opacity functions
|
||||
/////////////////////////////////////////////////////////////////////////
|
||||
|
||||
Signature alpha_sig = "alpha($color)";
|
||||
Signature opacity_sig = "opacity($color)";
|
||||
BUILT_IN(alpha)
|
||||
{
|
||||
String_Constant* ie_kwd = Cast<String_Constant>(env["$color"]);
|
||||
if (ie_kwd) {
|
||||
return SASS_MEMORY_NEW(String_Quoted, pstate, "alpha(" + ie_kwd->value() + ")");
|
||||
}
|
||||
|
||||
// CSS3 filter function overload: pass literal through directly
|
||||
Number* amount = Cast<Number>(env["$color"]);
|
||||
if (amount) {
|
||||
return SASS_MEMORY_NEW(String_Quoted, pstate, "opacity(" + amount->to_string(ctx.c_options) + ")");
|
||||
}
|
||||
|
||||
return SASS_MEMORY_NEW(Number, pstate, ARG("$color", Color)->a());
|
||||
}
|
||||
|
||||
Signature opacify_sig = "opacify($color, $amount)";
|
||||
Signature fade_in_sig = "fade-in($color, $amount)";
|
||||
BUILT_IN(opacify)
|
||||
{
|
||||
Color* col = ARG("$color", Color);
|
||||
double amount = DARG_U_FACT("$amount");
|
||||
Color_Obj copy = SASS_MEMORY_COPY(col);
|
||||
copy->a(clip(col->a() + amount, 0.0, 1.0));
|
||||
return copy.detach();
|
||||
}
|
||||
|
||||
Signature transparentize_sig = "transparentize($color, $amount)";
|
||||
Signature fade_out_sig = "fade-out($color, $amount)";
|
||||
BUILT_IN(transparentize)
|
||||
{
|
||||
Color* col = ARG("$color", Color);
|
||||
double amount = DARG_U_FACT("$amount");
|
||||
Color_Obj copy = SASS_MEMORY_COPY(col);
|
||||
copy->a(std::max(col->a() - amount, 0.0));
|
||||
return copy.detach();
|
||||
}
|
||||
|
||||
////////////////////////
|
||||
// OTHER COLOR FUNCTIONS
|
||||
////////////////////////
|
||||
|
||||
Signature adjust_color_sig = "adjust-color($color, $red: false, $green: false, $blue: false, $hue: false, $saturation: false, $lightness: false, $alpha: false)";
|
||||
BUILT_IN(adjust_color)
|
||||
{
|
||||
Color* col = ARG("$color", Color);
|
||||
Number* r = Cast<Number>(env["$red"]);
|
||||
Number* g = Cast<Number>(env["$green"]);
|
||||
Number* b = Cast<Number>(env["$blue"]);
|
||||
Number* h = Cast<Number>(env["$hue"]);
|
||||
Number* s = Cast<Number>(env["$saturation"]);
|
||||
Number* l = Cast<Number>(env["$lightness"]);
|
||||
Number* a = Cast<Number>(env["$alpha"]);
|
||||
|
||||
bool rgb = r || g || b;
|
||||
bool hsl = h || s || l;
|
||||
|
||||
if (rgb && hsl) {
|
||||
error("Cannot specify HSL and RGB values for a color at the same time for `adjust-color'", pstate, traces);
|
||||
}
|
||||
else if (rgb) {
|
||||
Color_RGBA_Obj c = col->copyAsRGBA();
|
||||
if (r) c->r(c->r() + DARG_R_BYTE("$red"));
|
||||
if (g) c->g(c->g() + DARG_R_BYTE("$green"));
|
||||
if (b) c->b(c->b() + DARG_R_BYTE("$blue"));
|
||||
if (a) c->a(c->a() + DARG_R_FACT("$alpha"));
|
||||
return c.detach();
|
||||
}
|
||||
else if (hsl) {
|
||||
Color_HSLA_Obj c = col->copyAsHSLA();
|
||||
if (h) c->h(c->h() + absmod(h->value(), 360.0));
|
||||
if (s) c->s(c->s() + DARG_R_PRCT("$saturation"));
|
||||
if (l) c->l(c->l() + DARG_R_PRCT("$lightness"));
|
||||
if (a) c->a(c->a() + DARG_R_FACT("$alpha"));
|
||||
return c.detach();
|
||||
}
|
||||
else if (a) {
|
||||
Color_Obj c = SASS_MEMORY_COPY(col);
|
||||
c->a(c->a() + DARG_R_FACT("$alpha"));
|
||||
c->a(clip(c->a(), 0.0, 1.0));
|
||||
return c.detach();
|
||||
}
|
||||
error("not enough arguments for `adjust-color'", pstate, traces);
|
||||
// unreachable
|
||||
return col;
|
||||
}
|
||||
|
||||
Signature scale_color_sig = "scale-color($color, $red: false, $green: false, $blue: false, $hue: false, $saturation: false, $lightness: false, $alpha: false)";
|
||||
BUILT_IN(scale_color)
|
||||
{
|
||||
Color* col = ARG("$color", Color);
|
||||
Number* r = Cast<Number>(env["$red"]);
|
||||
Number* g = Cast<Number>(env["$green"]);
|
||||
Number* b = Cast<Number>(env["$blue"]);
|
||||
Number* h = Cast<Number>(env["$hue"]);
|
||||
Number* s = Cast<Number>(env["$saturation"]);
|
||||
Number* l = Cast<Number>(env["$lightness"]);
|
||||
Number* a = Cast<Number>(env["$alpha"]);
|
||||
|
||||
bool rgb = r || g || b;
|
||||
bool hsl = h || s || l;
|
||||
|
||||
if (rgb && hsl) {
|
||||
error("Cannot specify HSL and RGB values for a color at the same time for `scale-color'", pstate, traces);
|
||||
}
|
||||
else if (rgb) {
|
||||
Color_RGBA_Obj c = col->copyAsRGBA();
|
||||
double rscale = (r ? DARG_R_PRCT("$red") : 0.0) / 100.0;
|
||||
double gscale = (g ? DARG_R_PRCT("$green") : 0.0) / 100.0;
|
||||
double bscale = (b ? DARG_R_PRCT("$blue") : 0.0) / 100.0;
|
||||
double ascale = (a ? DARG_R_PRCT("$alpha") : 0.0) / 100.0;
|
||||
if (rscale) c->r(c->r() + rscale * (rscale > 0.0 ? 255.0 - c->r() : c->r()));
|
||||
if (gscale) c->g(c->g() + gscale * (gscale > 0.0 ? 255.0 - c->g() : c->g()));
|
||||
if (bscale) c->b(c->b() + bscale * (bscale > 0.0 ? 255.0 - c->b() : c->b()));
|
||||
if (ascale) c->a(c->a() + ascale * (ascale > 0.0 ? 1.0 - c->a() : c->a()));
|
||||
return c.detach();
|
||||
}
|
||||
else if (hsl) {
|
||||
Color_HSLA_Obj c = col->copyAsHSLA();
|
||||
double hscale = (h ? DARG_R_PRCT("$hue") : 0.0) / 100.0;
|
||||
double sscale = (s ? DARG_R_PRCT("$saturation") : 0.0) / 100.0;
|
||||
double lscale = (l ? DARG_R_PRCT("$lightness") : 0.0) / 100.0;
|
||||
double ascale = (a ? DARG_R_PRCT("$alpha") : 0.0) / 100.0;
|
||||
if (hscale) c->h(c->h() + hscale * (hscale > 0.0 ? 360.0 - c->h() : c->h()));
|
||||
if (sscale) c->s(c->s() + sscale * (sscale > 0.0 ? 100.0 - c->s() : c->s()));
|
||||
if (lscale) c->l(c->l() + lscale * (lscale > 0.0 ? 100.0 - c->l() : c->l()));
|
||||
if (ascale) c->a(c->a() + ascale * (ascale > 0.0 ? 1.0 - c->a() : c->a()));
|
||||
return c.detach();
|
||||
}
|
||||
else if (a) {
|
||||
Color_Obj c = SASS_MEMORY_COPY(col);
|
||||
double ascale = DARG_R_PRCT("$alpha") / 100.0;
|
||||
c->a(c->a() + ascale * (ascale > 0.0 ? 1.0 - c->a() : c->a()));
|
||||
c->a(clip(c->a(), 0.0, 1.0));
|
||||
return c.detach();
|
||||
}
|
||||
error("not enough arguments for `scale-color'", pstate, traces);
|
||||
// unreachable
|
||||
return col;
|
||||
}
|
||||
|
||||
Signature change_color_sig = "change-color($color, $red: false, $green: false, $blue: false, $hue: false, $saturation: false, $lightness: false, $alpha: false)";
|
||||
BUILT_IN(change_color)
|
||||
{
|
||||
Color* col = ARG("$color", Color);
|
||||
Number* r = Cast<Number>(env["$red"]);
|
||||
Number* g = Cast<Number>(env["$green"]);
|
||||
Number* b = Cast<Number>(env["$blue"]);
|
||||
Number* h = Cast<Number>(env["$hue"]);
|
||||
Number* s = Cast<Number>(env["$saturation"]);
|
||||
Number* l = Cast<Number>(env["$lightness"]);
|
||||
Number* a = Cast<Number>(env["$alpha"]);
|
||||
|
||||
bool rgb = r || g || b;
|
||||
bool hsl = h || s || l;
|
||||
|
||||
if (rgb && hsl) {
|
||||
error("Cannot specify HSL and RGB values for a color at the same time for `change-color'", pstate, traces);
|
||||
}
|
||||
else if (rgb) {
|
||||
Color_RGBA_Obj c = col->copyAsRGBA();
|
||||
if (r) c->r(DARG_U_BYTE("$red"));
|
||||
if (g) c->g(DARG_U_BYTE("$green"));
|
||||
if (b) c->b(DARG_U_BYTE("$blue"));
|
||||
if (a) c->a(DARG_U_FACT("$alpha"));
|
||||
return c.detach();
|
||||
}
|
||||
else if (hsl) {
|
||||
Color_HSLA_Obj c = col->copyAsHSLA();
|
||||
if (h) c->h(absmod(h->value(), 360.0));
|
||||
if (s) c->s(DARG_U_PRCT("$saturation"));
|
||||
if (l) c->l(DARG_U_PRCT("$lightness"));
|
||||
if (a) c->a(DARG_U_FACT("$alpha"));
|
||||
return c.detach();
|
||||
}
|
||||
else if (a) {
|
||||
Color_Obj c = SASS_MEMORY_COPY(col);
|
||||
c->a(clip(DARG_U_FACT("$alpha"), 0.0, 1.0));
|
||||
return c.detach();
|
||||
}
|
||||
error("not enough arguments for `change-color'", pstate, traces);
|
||||
// unreachable
|
||||
return col;
|
||||
}
|
||||
|
||||
Signature ie_hex_str_sig = "ie-hex-str($color)";
|
||||
BUILT_IN(ie_hex_str)
|
||||
{
|
||||
Color* col = ARG("$color", Color);
|
||||
Color_RGBA_Obj c = col->toRGBA();
|
||||
double r = clip(c->r(), 0.0, 255.0);
|
||||
double g = clip(c->g(), 0.0, 255.0);
|
||||
double b = clip(c->b(), 0.0, 255.0);
|
||||
double a = clip(c->a(), 0.0, 1.0) * 255.0;
|
||||
|
||||
sass::ostream ss;
|
||||
ss << '#' << std::setw(2) << std::setfill('0');
|
||||
ss << std::hex << std::setw(2) << static_cast<unsigned long>(Sass::round(a, ctx.c_options.precision));
|
||||
ss << std::hex << std::setw(2) << static_cast<unsigned long>(Sass::round(r, ctx.c_options.precision));
|
||||
ss << std::hex << std::setw(2) << static_cast<unsigned long>(Sass::round(g, ctx.c_options.precision));
|
||||
ss << std::hex << std::setw(2) << static_cast<unsigned long>(Sass::round(b, ctx.c_options.precision));
|
||||
|
||||
sass::string result = ss.str();
|
||||
Util::ascii_str_toupper(&result);
|
||||
return SASS_MEMORY_NEW(String_Quoted, pstate, result);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
85
vendor/bundle/ruby/2.6.0/gems/sassc-2.4.0/ext/libsass/src/fn_colors.hpp
vendored
Normal file
85
vendor/bundle/ruby/2.6.0/gems/sassc-2.4.0/ext/libsass/src/fn_colors.hpp
vendored
Normal file
@@ -0,0 +1,85 @@
|
||||
#ifndef SASS_FN_COLORS_H
|
||||
#define SASS_FN_COLORS_H
|
||||
|
||||
#include "fn_utils.hpp"
|
||||
|
||||
namespace Sass {
|
||||
|
||||
namespace Functions {
|
||||
|
||||
// macros for common ranges (u mean unsigned or upper, r for full range)
|
||||
#define DARG_U_FACT(argname) get_arg_r(argname, env, sig, pstate, traces, - 0.0, 1.0) // double
|
||||
#define DARG_R_FACT(argname) get_arg_r(argname, env, sig, pstate, traces, - 1.0, 1.0) // double
|
||||
#define DARG_U_BYTE(argname) get_arg_r(argname, env, sig, pstate, traces, - 0.0, 255.0) // double
|
||||
#define DARG_R_BYTE(argname) get_arg_r(argname, env, sig, pstate, traces, - 255.0, 255.0) // double
|
||||
#define DARG_U_PRCT(argname) get_arg_r(argname, env, sig, pstate, traces, - 0.0, 100.0) // double
|
||||
#define DARG_R_PRCT(argname) get_arg_r(argname, env, sig, pstate, traces, - 100.0, 100.0) // double
|
||||
|
||||
// macros for color related inputs (rbg and alpha/opacity values)
|
||||
#define COLOR_NUM(argname) color_num(argname, env, sig, pstate, traces) // double
|
||||
#define ALPHA_NUM(argname) alpha_num(argname, env, sig, pstate, traces) // double
|
||||
|
||||
extern Signature rgb_sig;
|
||||
extern Signature rgba_4_sig;
|
||||
extern Signature rgba_2_sig;
|
||||
extern Signature red_sig;
|
||||
extern Signature green_sig;
|
||||
extern Signature blue_sig;
|
||||
extern Signature mix_sig;
|
||||
extern Signature hsl_sig;
|
||||
extern Signature hsla_sig;
|
||||
extern Signature hue_sig;
|
||||
extern Signature saturation_sig;
|
||||
extern Signature lightness_sig;
|
||||
extern Signature adjust_hue_sig;
|
||||
extern Signature lighten_sig;
|
||||
extern Signature darken_sig;
|
||||
extern Signature saturate_sig;
|
||||
extern Signature desaturate_sig;
|
||||
extern Signature grayscale_sig;
|
||||
extern Signature complement_sig;
|
||||
extern Signature invert_sig;
|
||||
extern Signature alpha_sig;
|
||||
extern Signature opacity_sig;
|
||||
extern Signature opacify_sig;
|
||||
extern Signature fade_in_sig;
|
||||
extern Signature transparentize_sig;
|
||||
extern Signature fade_out_sig;
|
||||
extern Signature adjust_color_sig;
|
||||
extern Signature scale_color_sig;
|
||||
extern Signature change_color_sig;
|
||||
extern Signature ie_hex_str_sig;
|
||||
|
||||
BUILT_IN(rgb);
|
||||
BUILT_IN(rgba_4);
|
||||
BUILT_IN(rgba_2);
|
||||
BUILT_IN(red);
|
||||
BUILT_IN(green);
|
||||
BUILT_IN(blue);
|
||||
BUILT_IN(mix);
|
||||
BUILT_IN(hsl);
|
||||
BUILT_IN(hsla);
|
||||
BUILT_IN(hue);
|
||||
BUILT_IN(saturation);
|
||||
BUILT_IN(lightness);
|
||||
BUILT_IN(adjust_hue);
|
||||
BUILT_IN(lighten);
|
||||
BUILT_IN(darken);
|
||||
BUILT_IN(saturate);
|
||||
BUILT_IN(desaturate);
|
||||
BUILT_IN(grayscale);
|
||||
BUILT_IN(complement);
|
||||
BUILT_IN(invert);
|
||||
BUILT_IN(alpha);
|
||||
BUILT_IN(opacify);
|
||||
BUILT_IN(transparentize);
|
||||
BUILT_IN(adjust_color);
|
||||
BUILT_IN(scale_color);
|
||||
BUILT_IN(change_color);
|
||||
BUILT_IN(ie_hex_str);
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
285
vendor/bundle/ruby/2.6.0/gems/sassc-2.4.0/ext/libsass/src/fn_lists.cpp
vendored
Normal file
285
vendor/bundle/ruby/2.6.0/gems/sassc-2.4.0/ext/libsass/src/fn_lists.cpp
vendored
Normal file
@@ -0,0 +1,285 @@
|
||||
// sass.hpp must go before all system headers to get the
|
||||
// __EXTENSIONS__ fix on Solaris.
|
||||
#include "sass.hpp"
|
||||
|
||||
#include "listize.hpp"
|
||||
#include "operators.hpp"
|
||||
#include "fn_utils.hpp"
|
||||
#include "fn_lists.hpp"
|
||||
|
||||
namespace Sass {
|
||||
|
||||
namespace Functions {
|
||||
|
||||
/////////////////
|
||||
// LIST FUNCTIONS
|
||||
/////////////////
|
||||
|
||||
Signature keywords_sig = "keywords($args)";
|
||||
BUILT_IN(keywords)
|
||||
{
|
||||
List_Obj arglist = SASS_MEMORY_COPY(ARG("$args", List)); // copy
|
||||
Map_Obj result = SASS_MEMORY_NEW(Map, pstate, 1);
|
||||
for (size_t i = arglist->size(), L = arglist->length(); i < L; ++i) {
|
||||
ExpressionObj obj = arglist->at(i);
|
||||
Argument_Obj arg = (Argument*) obj.ptr(); // XXX
|
||||
sass::string name = sass::string(arg->name());
|
||||
name = name.erase(0, 1); // sanitize name (remove dollar sign)
|
||||
*result << std::make_pair(SASS_MEMORY_NEW(String_Quoted,
|
||||
pstate, name),
|
||||
arg->value());
|
||||
}
|
||||
return result.detach();
|
||||
}
|
||||
|
||||
Signature length_sig = "length($list)";
|
||||
BUILT_IN(length)
|
||||
{
|
||||
if (SelectorList * sl = Cast<SelectorList>(env["$list"])) {
|
||||
return SASS_MEMORY_NEW(Number, pstate, (double) sl->length());
|
||||
}
|
||||
Expression* v = ARG("$list", Expression);
|
||||
if (v->concrete_type() == Expression::MAP) {
|
||||
Map* map = Cast<Map>(env["$list"]);
|
||||
return SASS_MEMORY_NEW(Number, pstate, (double)(map ? map->length() : 1));
|
||||
}
|
||||
if (v->concrete_type() == Expression::SELECTOR) {
|
||||
if (CompoundSelector * h = Cast<CompoundSelector>(v)) {
|
||||
return SASS_MEMORY_NEW(Number, pstate, (double)h->length());
|
||||
} else if (SelectorList * ls = Cast<SelectorList>(v)) {
|
||||
return SASS_MEMORY_NEW(Number, pstate, (double)ls->length());
|
||||
} else {
|
||||
return SASS_MEMORY_NEW(Number, pstate, 1);
|
||||
}
|
||||
}
|
||||
|
||||
List* list = Cast<List>(env["$list"]);
|
||||
return SASS_MEMORY_NEW(Number,
|
||||
pstate,
|
||||
(double)(list ? list->size() : 1));
|
||||
}
|
||||
|
||||
Signature nth_sig = "nth($list, $n)";
|
||||
BUILT_IN(nth)
|
||||
{
|
||||
double nr = ARGVAL("$n");
|
||||
Map* m = Cast<Map>(env["$list"]);
|
||||
if (SelectorList * sl = Cast<SelectorList>(env["$list"])) {
|
||||
size_t len = m ? m->length() : sl->length();
|
||||
bool empty = m ? m->empty() : sl->empty();
|
||||
if (empty) error("argument `$list` of `" + sass::string(sig) + "` must not be empty", pstate, traces);
|
||||
double index = std::floor(nr < 0 ? len + nr : nr - 1);
|
||||
if (index < 0 || index > len - 1) error("index out of bounds for `" + sass::string(sig) + "`", pstate, traces);
|
||||
return Cast<Value>(Listize::perform(sl->get(static_cast<int>(index))));
|
||||
}
|
||||
List_Obj l = Cast<List>(env["$list"]);
|
||||
if (nr == 0) error("argument `$n` of `" + sass::string(sig) + "` must be non-zero", pstate, traces);
|
||||
// if the argument isn't a list, then wrap it in a singleton list
|
||||
if (!m && !l) {
|
||||
l = SASS_MEMORY_NEW(List, pstate, 1);
|
||||
l->append(ARG("$list", Expression));
|
||||
}
|
||||
size_t len = m ? m->length() : l->length();
|
||||
bool empty = m ? m->empty() : l->empty();
|
||||
if (empty) error("argument `$list` of `" + sass::string(sig) + "` must not be empty", pstate, traces);
|
||||
double index = std::floor(nr < 0 ? len + nr : nr - 1);
|
||||
if (index < 0 || index > len - 1) error("index out of bounds for `" + sass::string(sig) + "`", pstate, traces);
|
||||
|
||||
if (m) {
|
||||
l = SASS_MEMORY_NEW(List, pstate, 2);
|
||||
l->append(m->keys()[static_cast<unsigned int>(index)]);
|
||||
l->append(m->at(m->keys()[static_cast<unsigned int>(index)]));
|
||||
return l.detach();
|
||||
}
|
||||
else {
|
||||
ValueObj rv = l->value_at_index(static_cast<int>(index));
|
||||
rv->set_delayed(false);
|
||||
return rv.detach();
|
||||
}
|
||||
}
|
||||
|
||||
Signature set_nth_sig = "set-nth($list, $n, $value)";
|
||||
BUILT_IN(set_nth)
|
||||
{
|
||||
Map_Obj m = Cast<Map>(env["$list"]);
|
||||
List_Obj l = Cast<List>(env["$list"]);
|
||||
Number_Obj n = ARG("$n", Number);
|
||||
ExpressionObj v = ARG("$value", Expression);
|
||||
if (!l) {
|
||||
l = SASS_MEMORY_NEW(List, pstate, 1);
|
||||
l->append(ARG("$list", Expression));
|
||||
}
|
||||
if (m) {
|
||||
l = m->to_list(pstate);
|
||||
}
|
||||
if (l->empty()) error("argument `$list` of `" + sass::string(sig) + "` must not be empty", pstate, traces);
|
||||
double index = std::floor(n->value() < 0 ? l->length() + n->value() : n->value() - 1);
|
||||
if (index < 0 || index > l->length() - 1) error("index out of bounds for `" + sass::string(sig) + "`", pstate, traces);
|
||||
List* result = SASS_MEMORY_NEW(List, pstate, l->length(), l->separator(), false, l->is_bracketed());
|
||||
for (size_t i = 0, L = l->length(); i < L; ++i) {
|
||||
result->append(((i == index) ? v : (*l)[i]));
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
Signature index_sig = "index($list, $value)";
|
||||
BUILT_IN(index)
|
||||
{
|
||||
Map_Obj m = Cast<Map>(env["$list"]);
|
||||
List_Obj l = Cast<List>(env["$list"]);
|
||||
ExpressionObj v = ARG("$value", Expression);
|
||||
if (!l) {
|
||||
l = SASS_MEMORY_NEW(List, pstate, 1);
|
||||
l->append(ARG("$list", Expression));
|
||||
}
|
||||
if (m) {
|
||||
l = m->to_list(pstate);
|
||||
}
|
||||
for (size_t i = 0, L = l->length(); i < L; ++i) {
|
||||
if (Operators::eq(l->value_at_index(i), v)) return SASS_MEMORY_NEW(Number, pstate, (double)(i+1));
|
||||
}
|
||||
return SASS_MEMORY_NEW(Null, pstate);
|
||||
}
|
||||
|
||||
Signature join_sig = "join($list1, $list2, $separator: auto, $bracketed: auto)";
|
||||
BUILT_IN(join)
|
||||
{
|
||||
Map_Obj m1 = Cast<Map>(env["$list1"]);
|
||||
Map_Obj m2 = Cast<Map>(env["$list2"]);
|
||||
List_Obj l1 = Cast<List>(env["$list1"]);
|
||||
List_Obj l2 = Cast<List>(env["$list2"]);
|
||||
String_Constant_Obj sep = ARG("$separator", String_Constant);
|
||||
enum Sass_Separator sep_val = (l1 ? l1->separator() : SASS_SPACE);
|
||||
Value* bracketed = ARG("$bracketed", Value);
|
||||
bool is_bracketed = (l1 ? l1->is_bracketed() : false);
|
||||
if (!l1) {
|
||||
l1 = SASS_MEMORY_NEW(List, pstate, 1);
|
||||
l1->append(ARG("$list1", Expression));
|
||||
sep_val = (l2 ? l2->separator() : SASS_SPACE);
|
||||
is_bracketed = (l2 ? l2->is_bracketed() : false);
|
||||
}
|
||||
if (!l2) {
|
||||
l2 = SASS_MEMORY_NEW(List, pstate, 1);
|
||||
l2->append(ARG("$list2", Expression));
|
||||
}
|
||||
if (m1) {
|
||||
l1 = m1->to_list(pstate);
|
||||
sep_val = SASS_COMMA;
|
||||
}
|
||||
if (m2) {
|
||||
l2 = m2->to_list(pstate);
|
||||
}
|
||||
size_t len = l1->length() + l2->length();
|
||||
sass::string sep_str = unquote(sep->value());
|
||||
if (sep_str == "space") sep_val = SASS_SPACE;
|
||||
else if (sep_str == "comma") sep_val = SASS_COMMA;
|
||||
else if (sep_str != "auto") error("argument `$separator` of `" + sass::string(sig) + "` must be `space`, `comma`, or `auto`", pstate, traces);
|
||||
String_Constant_Obj bracketed_as_str = Cast<String_Constant>(bracketed);
|
||||
bool bracketed_is_auto = bracketed_as_str && unquote(bracketed_as_str->value()) == "auto";
|
||||
if (!bracketed_is_auto) {
|
||||
is_bracketed = !bracketed->is_false();
|
||||
}
|
||||
List_Obj result = SASS_MEMORY_NEW(List, pstate, len, sep_val, false, is_bracketed);
|
||||
result->concat(l1);
|
||||
result->concat(l2);
|
||||
return result.detach();
|
||||
}
|
||||
|
||||
Signature append_sig = "append($list, $val, $separator: auto)";
|
||||
BUILT_IN(append)
|
||||
{
|
||||
Map_Obj m = Cast<Map>(env["$list"]);
|
||||
List_Obj l = Cast<List>(env["$list"]);
|
||||
ExpressionObj v = ARG("$val", Expression);
|
||||
if (SelectorList * sl = Cast<SelectorList>(env["$list"])) {
|
||||
l = Cast<List>(Listize::perform(sl));
|
||||
}
|
||||
String_Constant_Obj sep = ARG("$separator", String_Constant);
|
||||
if (!l) {
|
||||
l = SASS_MEMORY_NEW(List, pstate, 1);
|
||||
l->append(ARG("$list", Expression));
|
||||
}
|
||||
if (m) {
|
||||
l = m->to_list(pstate);
|
||||
}
|
||||
List* result = SASS_MEMORY_COPY(l);
|
||||
sass::string sep_str(unquote(sep->value()));
|
||||
if (sep_str != "auto") { // check default first
|
||||
if (sep_str == "space") result->separator(SASS_SPACE);
|
||||
else if (sep_str == "comma") result->separator(SASS_COMMA);
|
||||
else error("argument `$separator` of `" + sass::string(sig) + "` must be `space`, `comma`, or `auto`", pstate, traces);
|
||||
}
|
||||
if (l->is_arglist()) {
|
||||
result->append(SASS_MEMORY_NEW(Argument,
|
||||
v->pstate(),
|
||||
v,
|
||||
"",
|
||||
false,
|
||||
false));
|
||||
|
||||
} else {
|
||||
result->append(v);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
Signature zip_sig = "zip($lists...)";
|
||||
BUILT_IN(zip)
|
||||
{
|
||||
List_Obj arglist = SASS_MEMORY_COPY(ARG("$lists", List));
|
||||
size_t shortest = 0;
|
||||
for (size_t i = 0, L = arglist->length(); i < L; ++i) {
|
||||
List_Obj ith = Cast<List>(arglist->value_at_index(i));
|
||||
Map_Obj mith = Cast<Map>(arglist->value_at_index(i));
|
||||
if (!ith) {
|
||||
if (mith) {
|
||||
ith = mith->to_list(pstate);
|
||||
} else {
|
||||
ith = SASS_MEMORY_NEW(List, pstate, 1);
|
||||
ith->append(arglist->value_at_index(i));
|
||||
}
|
||||
if (arglist->is_arglist()) {
|
||||
Argument_Obj arg = (Argument*)(arglist->at(i).ptr()); // XXX
|
||||
arg->value(ith);
|
||||
} else {
|
||||
(*arglist)[i] = ith;
|
||||
}
|
||||
}
|
||||
shortest = (i ? std::min(shortest, ith->length()) : ith->length());
|
||||
}
|
||||
List* zippers = SASS_MEMORY_NEW(List, pstate, shortest, SASS_COMMA);
|
||||
size_t L = arglist->length();
|
||||
for (size_t i = 0; i < shortest; ++i) {
|
||||
List* zipper = SASS_MEMORY_NEW(List, pstate, L);
|
||||
for (size_t j = 0; j < L; ++j) {
|
||||
zipper->append(Cast<List>(arglist->value_at_index(j))->at(i));
|
||||
}
|
||||
zippers->append(zipper);
|
||||
}
|
||||
return zippers;
|
||||
}
|
||||
|
||||
Signature list_separator_sig = "list_separator($list)";
|
||||
BUILT_IN(list_separator)
|
||||
{
|
||||
List_Obj l = Cast<List>(env["$list"]);
|
||||
if (!l) {
|
||||
l = SASS_MEMORY_NEW(List, pstate, 1);
|
||||
l->append(ARG("$list", Expression));
|
||||
}
|
||||
return SASS_MEMORY_NEW(String_Quoted,
|
||||
pstate,
|
||||
l->separator() == SASS_COMMA ? "comma" : "space");
|
||||
}
|
||||
|
||||
Signature is_bracketed_sig = "is-bracketed($list)";
|
||||
BUILT_IN(is_bracketed)
|
||||
{
|
||||
ValueObj value = ARG("$list", Value);
|
||||
List_Obj list = Cast<List>(value);
|
||||
return SASS_MEMORY_NEW(Boolean, pstate, list && list->is_bracketed());
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
34
vendor/bundle/ruby/2.6.0/gems/sassc-2.4.0/ext/libsass/src/fn_lists.hpp
vendored
Normal file
34
vendor/bundle/ruby/2.6.0/gems/sassc-2.4.0/ext/libsass/src/fn_lists.hpp
vendored
Normal file
@@ -0,0 +1,34 @@
|
||||
#ifndef SASS_FN_LISTS_H
|
||||
#define SASS_FN_LISTS_H
|
||||
|
||||
#include "fn_utils.hpp"
|
||||
|
||||
namespace Sass {
|
||||
|
||||
namespace Functions {
|
||||
|
||||
extern Signature length_sig;
|
||||
extern Signature nth_sig;
|
||||
extern Signature index_sig;
|
||||
extern Signature join_sig;
|
||||
extern Signature append_sig;
|
||||
extern Signature zip_sig;
|
||||
extern Signature list_separator_sig;
|
||||
extern Signature is_bracketed_sig;
|
||||
extern Signature keywords_sig;
|
||||
|
||||
BUILT_IN(length);
|
||||
BUILT_IN(nth);
|
||||
BUILT_IN(index);
|
||||
BUILT_IN(join);
|
||||
BUILT_IN(append);
|
||||
BUILT_IN(zip);
|
||||
BUILT_IN(list_separator);
|
||||
BUILT_IN(is_bracketed);
|
||||
BUILT_IN(keywords);
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
94
vendor/bundle/ruby/2.6.0/gems/sassc-2.4.0/ext/libsass/src/fn_maps.cpp
vendored
Normal file
94
vendor/bundle/ruby/2.6.0/gems/sassc-2.4.0/ext/libsass/src/fn_maps.cpp
vendored
Normal file
@@ -0,0 +1,94 @@
|
||||
#include "operators.hpp"
|
||||
#include "fn_utils.hpp"
|
||||
#include "fn_maps.hpp"
|
||||
|
||||
namespace Sass {
|
||||
|
||||
namespace Functions {
|
||||
|
||||
/////////////////
|
||||
// MAP FUNCTIONS
|
||||
/////////////////
|
||||
|
||||
Signature map_get_sig = "map-get($map, $key)";
|
||||
BUILT_IN(map_get)
|
||||
{
|
||||
// leaks for "map-get((), foo)" if not Obj
|
||||
// investigate why this is (unexpected)
|
||||
Map_Obj m = ARGM("$map", Map);
|
||||
ExpressionObj v = ARG("$key", Expression);
|
||||
try {
|
||||
ValueObj val = m->at(v);
|
||||
if (!val) return SASS_MEMORY_NEW(Null, pstate);
|
||||
val->set_delayed(false);
|
||||
return val.detach();
|
||||
} catch (const std::out_of_range&) {
|
||||
return SASS_MEMORY_NEW(Null, pstate);
|
||||
}
|
||||
catch (...) { throw; }
|
||||
}
|
||||
|
||||
Signature map_has_key_sig = "map-has-key($map, $key)";
|
||||
BUILT_IN(map_has_key)
|
||||
{
|
||||
Map_Obj m = ARGM("$map", Map);
|
||||
ExpressionObj v = ARG("$key", Expression);
|
||||
return SASS_MEMORY_NEW(Boolean, pstate, m->has(v));
|
||||
}
|
||||
|
||||
Signature map_keys_sig = "map-keys($map)";
|
||||
BUILT_IN(map_keys)
|
||||
{
|
||||
Map_Obj m = ARGM("$map", Map);
|
||||
List* result = SASS_MEMORY_NEW(List, pstate, m->length(), SASS_COMMA);
|
||||
for ( auto key : m->keys()) {
|
||||
result->append(key);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
Signature map_values_sig = "map-values($map)";
|
||||
BUILT_IN(map_values)
|
||||
{
|
||||
Map_Obj m = ARGM("$map", Map);
|
||||
List* result = SASS_MEMORY_NEW(List, pstate, m->length(), SASS_COMMA);
|
||||
for ( auto key : m->keys()) {
|
||||
result->append(m->at(key));
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
Signature map_merge_sig = "map-merge($map1, $map2)";
|
||||
BUILT_IN(map_merge)
|
||||
{
|
||||
Map_Obj m1 = ARGM("$map1", Map);
|
||||
Map_Obj m2 = ARGM("$map2", Map);
|
||||
|
||||
size_t len = m1->length() + m2->length();
|
||||
Map* result = SASS_MEMORY_NEW(Map, pstate, len);
|
||||
// concat not implemented for maps
|
||||
*result += m1;
|
||||
*result += m2;
|
||||
return result;
|
||||
}
|
||||
|
||||
Signature map_remove_sig = "map-remove($map, $keys...)";
|
||||
BUILT_IN(map_remove)
|
||||
{
|
||||
bool remove;
|
||||
Map_Obj m = ARGM("$map", Map);
|
||||
List_Obj arglist = ARG("$keys", List);
|
||||
Map* result = SASS_MEMORY_NEW(Map, pstate, 1);
|
||||
for (auto key : m->keys()) {
|
||||
remove = false;
|
||||
for (size_t j = 0, K = arglist->length(); j < K && !remove; ++j) {
|
||||
remove = Operators::eq(key, arglist->value_at_index(j));
|
||||
}
|
||||
if (!remove) *result << std::make_pair(key, m->at(key));
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
30
vendor/bundle/ruby/2.6.0/gems/sassc-2.4.0/ext/libsass/src/fn_maps.hpp
vendored
Normal file
30
vendor/bundle/ruby/2.6.0/gems/sassc-2.4.0/ext/libsass/src/fn_maps.hpp
vendored
Normal file
@@ -0,0 +1,30 @@
|
||||
#ifndef SASS_FN_MAPS_H
|
||||
#define SASS_FN_MAPS_H
|
||||
|
||||
#include "fn_utils.hpp"
|
||||
|
||||
namespace Sass {
|
||||
|
||||
namespace Functions {
|
||||
|
||||
#define ARGM(argname, argtype) get_arg_m(argname, env, sig, pstate, traces)
|
||||
|
||||
extern Signature map_get_sig;
|
||||
extern Signature map_merge_sig;
|
||||
extern Signature map_remove_sig;
|
||||
extern Signature map_keys_sig;
|
||||
extern Signature map_values_sig;
|
||||
extern Signature map_has_key_sig;
|
||||
|
||||
BUILT_IN(map_get);
|
||||
BUILT_IN(map_merge);
|
||||
BUILT_IN(map_remove);
|
||||
BUILT_IN(map_keys);
|
||||
BUILT_IN(map_values);
|
||||
BUILT_IN(map_has_key);
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
244
vendor/bundle/ruby/2.6.0/gems/sassc-2.4.0/ext/libsass/src/fn_miscs.cpp
vendored
Normal file
244
vendor/bundle/ruby/2.6.0/gems/sassc-2.4.0/ext/libsass/src/fn_miscs.cpp
vendored
Normal file
@@ -0,0 +1,244 @@
|
||||
#include "ast.hpp"
|
||||
#include "expand.hpp"
|
||||
#include "fn_utils.hpp"
|
||||
#include "fn_miscs.hpp"
|
||||
#include "util_string.hpp"
|
||||
|
||||
namespace Sass {
|
||||
|
||||
namespace Functions {
|
||||
|
||||
//////////////////////////
|
||||
// INTROSPECTION FUNCTIONS
|
||||
//////////////////////////
|
||||
|
||||
Signature type_of_sig = "type-of($value)";
|
||||
BUILT_IN(type_of)
|
||||
{
|
||||
Expression* v = ARG("$value", Expression);
|
||||
return SASS_MEMORY_NEW(String_Quoted, pstate, v->type());
|
||||
}
|
||||
|
||||
Signature variable_exists_sig = "variable-exists($name)";
|
||||
BUILT_IN(variable_exists)
|
||||
{
|
||||
sass::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)
|
||||
{
|
||||
sass::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* ss = Cast<String_Constant>(env["$name"]);
|
||||
if (!ss) {
|
||||
error("$name: " + (env["$name"]->to_string()) + " is not a string for `function-exists'", pstate, traces);
|
||||
}
|
||||
|
||||
sass::string name = Util::normalize_underscores(unquote(ss->value()));
|
||||
|
||||
if(d_env.has(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)
|
||||
{
|
||||
sass::string s = Util::normalize_underscores(unquote(ARG("$name", String_Constant)->value()));
|
||||
|
||||
if(d_env.has(s+"[m]")) {
|
||||
return SASS_MEMORY_NEW(Boolean, pstate, true);
|
||||
}
|
||||
else {
|
||||
return SASS_MEMORY_NEW(Boolean, pstate, false);
|
||||
}
|
||||
}
|
||||
|
||||
Signature feature_exists_sig = "feature-exists($feature)";
|
||||
BUILT_IN(feature_exists)
|
||||
{
|
||||
sass::string s = unquote(ARG("$feature", String_Constant)->value());
|
||||
|
||||
static const auto *const features = new std::unordered_set<sass::string> {
|
||||
"global-variable-shadowing",
|
||||
"extend-selector-pseudoclass",
|
||||
"at-error",
|
||||
"units-level-3",
|
||||
"custom-property"
|
||||
};
|
||||
return SASS_MEMORY_NEW(Boolean, pstate, features->find(s) != features->end());
|
||||
}
|
||||
|
||||
Signature call_sig = "call($function, $args...)";
|
||||
BUILT_IN(call)
|
||||
{
|
||||
sass::string function;
|
||||
Function* ff = Cast<Function>(env["$function"]);
|
||||
String_Constant* ss = Cast<String_Constant>(env["$function"]);
|
||||
|
||||
if (ss) {
|
||||
function = 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(function) + ")) instead." << std::endl;
|
||||
std::cerr << std::endl;
|
||||
} else if (ff) {
|
||||
function = ff->name();
|
||||
}
|
||||
|
||||
List_Obj arglist = SASS_MEMORY_COPY(ARG("$args", List));
|
||||
|
||||
Arguments_Obj args = SASS_MEMORY_NEW(Arguments, pstate);
|
||||
// sass::string full_name(name + "[f]");
|
||||
// Definition* def = d_env.has(full_name) ? Cast<Definition>((d_env)[full_name]) : 0;
|
||||
// Parameters* params = def ? def->parameters() : 0;
|
||||
// size_t param_size = params ? params->length() : 0;
|
||||
for (size_t i = 0, L = arglist->length(); i < L; ++i) {
|
||||
ExpressionObj expr = arglist->value_at_index(i);
|
||||
// if (params && params->has_rest_parameter()) {
|
||||
// Parameter_Obj p = param_size > i ? (*params)[i] : 0;
|
||||
// List* list = Cast<List>(expr);
|
||||
// if (list && p && !p->is_rest_parameter()) expr = (*list)[0];
|
||||
// }
|
||||
if (arglist->is_arglist()) {
|
||||
ExpressionObj obj = arglist->at(i);
|
||||
Argument_Obj arg = (Argument*) 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, function, args);
|
||||
|
||||
Expand expand(ctx, &d_env, &selector_stack, &original_stack);
|
||||
func->via_call(true); // calc invoke is allowed
|
||||
if (ff) func->func(ff);
|
||||
return Cast<PreValue>(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)
|
||||
{
|
||||
Expand expand(ctx, &d_env, &selector_stack, &original_stack);
|
||||
ExpressionObj cond = ARG("$condition", Expression)->perform(&expand.eval);
|
||||
bool is_true = !cond->is_false();
|
||||
ExpressionObj res = ARG(is_true ? "$if-true" : "$if-false", Expression);
|
||||
ValueObj qwe = Cast<Value>(res->perform(&expand.eval));
|
||||
// res = res->perform(&expand.eval.val_eval);
|
||||
qwe->set_delayed(false); // clone?
|
||||
return qwe.detach();
|
||||
}
|
||||
|
||||
//////////////////////////
|
||||
// MISCELLANEOUS FUNCTIONS
|
||||
//////////////////////////
|
||||
|
||||
Signature inspect_sig = "inspect($value)";
|
||||
BUILT_IN(inspect)
|
||||
{
|
||||
Expression* v = ARG("$value", Expression);
|
||||
if (v->concrete_type() == Expression::NULL_VAL) {
|
||||
return SASS_MEMORY_NEW(String_Constant, pstate, "null");
|
||||
} else if (v->concrete_type() == Expression::BOOLEAN && v->is_false()) {
|
||||
return SASS_MEMORY_NEW(String_Constant, pstate, "false");
|
||||
} else if (v->concrete_type() == Expression::STRING) {
|
||||
String_Constant *s = Cast<String_Constant>(v);
|
||||
if (s->quote_mark()) {
|
||||
return SASS_MEMORY_NEW(String_Constant, pstate, quote(s->value(), s->quote_mark()));
|
||||
} else {
|
||||
return s;
|
||||
}
|
||||
} 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());
|
||||
}
|
||||
}
|
||||
|
||||
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* ss = Cast<String_Constant>(env["$name"]);
|
||||
if (!ss) {
|
||||
error("$name: " + (env["$name"]->to_string()) + " is not a string for `get-function'", pstate, traces);
|
||||
}
|
||||
|
||||
sass::string name = Util::normalize_underscores(unquote(ss->value()));
|
||||
sass::string full_name = name + "[f]";
|
||||
|
||||
Boolean_Obj css = ARG("$css", Boolean);
|
||||
if (!css->is_false()) {
|
||||
Definition* 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* def = Cast<Definition>(d_env[full_name]);
|
||||
return SASS_MEMORY_NEW(Function, pstate, def, false);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
40
vendor/bundle/ruby/2.6.0/gems/sassc-2.4.0/ext/libsass/src/fn_miscs.hpp
vendored
Normal file
40
vendor/bundle/ruby/2.6.0/gems/sassc-2.4.0/ext/libsass/src/fn_miscs.hpp
vendored
Normal file
@@ -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
|
||||
227
vendor/bundle/ruby/2.6.0/gems/sassc-2.4.0/ext/libsass/src/fn_numbers.cpp
vendored
Normal file
227
vendor/bundle/ruby/2.6.0/gems/sassc-2.4.0/ext/libsass/src/fn_numbers.cpp
vendored
Normal file
@@ -0,0 +1,227 @@
|
||||
// sass.hpp must go before all system headers to get the
|
||||
// __EXTENSIONS__ fix on Solaris.
|
||||
#include "sass.hpp"
|
||||
|
||||
#include <cstdint>
|
||||
#include <cstdlib>
|
||||
#include <cmath>
|
||||
#include <random>
|
||||
#include <sstream>
|
||||
#include <iomanip>
|
||||
#include <algorithm>
|
||||
|
||||
#include "ast.hpp"
|
||||
#include "units.hpp"
|
||||
#include "fn_utils.hpp"
|
||||
#include "fn_numbers.hpp"
|
||||
|
||||
#ifdef __MINGW32__
|
||||
#include "windows.h"
|
||||
#include "wincrypt.h"
|
||||
#endif
|
||||
|
||||
namespace Sass {
|
||||
|
||||
namespace Functions {
|
||||
|
||||
#ifdef __MINGW32__
|
||||
uint64_t GetSeed()
|
||||
{
|
||||
HCRYPTPROV hp = 0;
|
||||
BYTE rb[8];
|
||||
CryptAcquireContext(&hp, 0, 0, PROV_RSA_FULL, CRYPT_VERIFYCONTEXT);
|
||||
CryptGenRandom(hp, sizeof(rb), rb);
|
||||
CryptReleaseContext(hp, 0);
|
||||
|
||||
uint64_t seed;
|
||||
memcpy(&seed, &rb[0], sizeof(seed));
|
||||
|
||||
return seed;
|
||||
}
|
||||
#else
|
||||
uint64_t GetSeed()
|
||||
{
|
||||
std::random_device rd;
|
||||
return rd();
|
||||
}
|
||||
#endif
|
||||
|
||||
// note: the performance of many implementations of
|
||||
// random_device degrades sharply once the entropy pool
|
||||
// is exhausted. For practical use, random_device is
|
||||
// generally only used to seed a PRNG such as mt19937.
|
||||
static std::mt19937 rand(static_cast<unsigned int>(GetSeed()));
|
||||
|
||||
///////////////////
|
||||
// NUMBER FUNCTIONS
|
||||
///////////////////
|
||||
|
||||
Signature percentage_sig = "percentage($number)";
|
||||
BUILT_IN(percentage)
|
||||
{
|
||||
Number_Obj n = ARGN("$number");
|
||||
if (!n->is_unitless()) error("argument $number of `" + sass::string(sig) + "` must be unitless", pstate, traces);
|
||||
return SASS_MEMORY_NEW(Number, pstate, n->value() * 100, "%");
|
||||
}
|
||||
|
||||
Signature round_sig = "round($number)";
|
||||
BUILT_IN(round)
|
||||
{
|
||||
Number_Obj r = ARGN("$number");
|
||||
r->value(Sass::round(r->value(), ctx.c_options.precision));
|
||||
r->pstate(pstate);
|
||||
return r.detach();
|
||||
}
|
||||
|
||||
Signature ceil_sig = "ceil($number)";
|
||||
BUILT_IN(ceil)
|
||||
{
|
||||
Number_Obj r = ARGN("$number");
|
||||
r->value(std::ceil(r->value()));
|
||||
r->pstate(pstate);
|
||||
return r.detach();
|
||||
}
|
||||
|
||||
Signature floor_sig = "floor($number)";
|
||||
BUILT_IN(floor)
|
||||
{
|
||||
Number_Obj r = ARGN("$number");
|
||||
r->value(std::floor(r->value()));
|
||||
r->pstate(pstate);
|
||||
return r.detach();
|
||||
}
|
||||
|
||||
Signature abs_sig = "abs($number)";
|
||||
BUILT_IN(abs)
|
||||
{
|
||||
Number_Obj r = ARGN("$number");
|
||||
r->value(std::abs(r->value()));
|
||||
r->pstate(pstate);
|
||||
return r.detach();
|
||||
}
|
||||
|
||||
Signature min_sig = "min($numbers...)";
|
||||
BUILT_IN(min)
|
||||
{
|
||||
List* arglist = ARG("$numbers", List);
|
||||
Number_Obj least;
|
||||
size_t L = arglist->length();
|
||||
if (L == 0) {
|
||||
error("At least one argument must be passed.", pstate, traces);
|
||||
}
|
||||
for (size_t i = 0; i < L; ++i) {
|
||||
ExpressionObj val = arglist->value_at_index(i);
|
||||
Number_Obj xi = Cast<Number>(val);
|
||||
if (!xi) {
|
||||
error("\"" + val->to_string(ctx.c_options) + "\" is not a number for `min'", pstate, traces);
|
||||
}
|
||||
if (least) {
|
||||
if (*xi < *least) least = xi;
|
||||
} else least = xi;
|
||||
}
|
||||
return least.detach();
|
||||
}
|
||||
|
||||
Signature max_sig = "max($numbers...)";
|
||||
BUILT_IN(max)
|
||||
{
|
||||
List* arglist = ARG("$numbers", List);
|
||||
Number_Obj greatest;
|
||||
size_t L = arglist->length();
|
||||
if (L == 0) {
|
||||
error("At least one argument must be passed.", pstate, traces);
|
||||
}
|
||||
for (size_t i = 0; i < L; ++i) {
|
||||
ExpressionObj val = arglist->value_at_index(i);
|
||||
Number_Obj xi = Cast<Number>(val);
|
||||
if (!xi) {
|
||||
error("\"" + val->to_string(ctx.c_options) + "\" is not a number for `max'", pstate, traces);
|
||||
}
|
||||
if (greatest) {
|
||||
if (*greatest < *xi) greatest = xi;
|
||||
} else greatest = xi;
|
||||
}
|
||||
return greatest.detach();
|
||||
}
|
||||
|
||||
Signature random_sig = "random($limit:false)";
|
||||
BUILT_IN(random)
|
||||
{
|
||||
AST_Node_Obj arg = env["$limit"];
|
||||
Value* v = Cast<Value>(arg);
|
||||
Number* l = Cast<Number>(arg);
|
||||
Boolean* b = Cast<Boolean>(arg);
|
||||
if (l) {
|
||||
double lv = l->value();
|
||||
if (lv < 1) {
|
||||
sass::ostream err;
|
||||
err << "$limit " << lv << " must be greater than or equal to 1 for `random'";
|
||||
error(err.str(), pstate, traces);
|
||||
}
|
||||
bool eq_int = std::fabs(trunc(lv) - lv) < NUMBER_EPSILON;
|
||||
if (!eq_int) {
|
||||
sass::ostream err;
|
||||
err << "Expected $limit to be an integer but got " << lv << " for `random'";
|
||||
error(err.str(), pstate, traces);
|
||||
}
|
||||
std::uniform_real_distribution<> distributor(1, lv + 1);
|
||||
uint_fast32_t distributed = static_cast<uint_fast32_t>(distributor(rand));
|
||||
return SASS_MEMORY_NEW(Number, pstate, (double)distributed);
|
||||
}
|
||||
else if (b) {
|
||||
std::uniform_real_distribution<> distributor(0, 1);
|
||||
double distributed = static_cast<double>(distributor(rand));
|
||||
return SASS_MEMORY_NEW(Number, pstate, distributed);
|
||||
} else if (v) {
|
||||
traces.push_back(Backtrace(pstate));
|
||||
throw Exception::InvalidArgumentType(pstate, traces, "random", "$limit", "number", v);
|
||||
} else {
|
||||
traces.push_back(Backtrace(pstate));
|
||||
throw Exception::InvalidArgumentType(pstate, traces, "random", "$limit", "number");
|
||||
}
|
||||
}
|
||||
|
||||
Signature unique_id_sig = "unique-id()";
|
||||
BUILT_IN(unique_id)
|
||||
{
|
||||
sass::ostream ss;
|
||||
std::uniform_real_distribution<> distributor(0, 4294967296); // 16^8
|
||||
uint_fast32_t distributed = static_cast<uint_fast32_t>(distributor(rand));
|
||||
ss << "u" << std::setfill('0') << std::setw(8) << std::hex << distributed;
|
||||
return SASS_MEMORY_NEW(String_Quoted, pstate, ss.str());
|
||||
}
|
||||
|
||||
Signature unit_sig = "unit($number)";
|
||||
BUILT_IN(unit)
|
||||
{
|
||||
Number_Obj arg = ARGN("$number");
|
||||
sass::string str(quote(arg->unit(), '"'));
|
||||
return SASS_MEMORY_NEW(String_Quoted, pstate, str);
|
||||
}
|
||||
|
||||
Signature unitless_sig = "unitless($number)";
|
||||
BUILT_IN(unitless)
|
||||
{
|
||||
Number_Obj arg = ARGN("$number");
|
||||
bool unitless = arg->is_unitless();
|
||||
return SASS_MEMORY_NEW(Boolean, pstate, unitless);
|
||||
}
|
||||
|
||||
Signature comparable_sig = "comparable($number1, $number2)";
|
||||
BUILT_IN(comparable)
|
||||
{
|
||||
Number_Obj n1 = ARGN("$number1");
|
||||
Number_Obj n2 = ARGN("$number2");
|
||||
if (n1->is_unitless() || n2->is_unitless()) {
|
||||
return SASS_MEMORY_NEW(Boolean, pstate, true);
|
||||
}
|
||||
// normalize into main units
|
||||
n1->normalize(); n2->normalize();
|
||||
Units &lhs_unit = *n1, &rhs_unit = *n2;
|
||||
bool is_comparable = (lhs_unit == rhs_unit);
|
||||
return SASS_MEMORY_NEW(Boolean, pstate, is_comparable);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
45
vendor/bundle/ruby/2.6.0/gems/sassc-2.4.0/ext/libsass/src/fn_numbers.hpp
vendored
Normal file
45
vendor/bundle/ruby/2.6.0/gems/sassc-2.4.0/ext/libsass/src/fn_numbers.hpp
vendored
Normal file
@@ -0,0 +1,45 @@
|
||||
#ifndef SASS_FN_NUMBERS_H
|
||||
#define SASS_FN_NUMBERS_H
|
||||
|
||||
#include "fn_utils.hpp"
|
||||
|
||||
namespace Sass {
|
||||
|
||||
namespace Functions {
|
||||
|
||||
// return a number object (copied since we want to have reduced units)
|
||||
#define ARGN(argname) get_arg_n(argname, env, sig, pstate, traces) // Number copy
|
||||
|
||||
extern Signature percentage_sig;
|
||||
extern Signature round_sig;
|
||||
extern Signature ceil_sig;
|
||||
extern Signature floor_sig;
|
||||
extern Signature abs_sig;
|
||||
extern Signature min_sig;
|
||||
extern Signature max_sig;
|
||||
extern Signature inspect_sig;
|
||||
extern Signature random_sig;
|
||||
extern Signature unique_id_sig;
|
||||
extern Signature unit_sig;
|
||||
extern Signature unitless_sig;
|
||||
extern Signature comparable_sig;
|
||||
|
||||
BUILT_IN(percentage);
|
||||
BUILT_IN(round);
|
||||
BUILT_IN(ceil);
|
||||
BUILT_IN(floor);
|
||||
BUILT_IN(abs);
|
||||
BUILT_IN(min);
|
||||
BUILT_IN(max);
|
||||
BUILT_IN(inspect);
|
||||
BUILT_IN(random);
|
||||
BUILT_IN(unique_id);
|
||||
BUILT_IN(unit);
|
||||
BUILT_IN(unitless);
|
||||
BUILT_IN(comparable);
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
205
vendor/bundle/ruby/2.6.0/gems/sassc-2.4.0/ext/libsass/src/fn_selectors.cpp
vendored
Normal file
205
vendor/bundle/ruby/2.6.0/gems/sassc-2.4.0/ext/libsass/src/fn_selectors.cpp
vendored
Normal file
@@ -0,0 +1,205 @@
|
||||
#include <numeric>
|
||||
|
||||
#include "parser.hpp"
|
||||
#include "extender.hpp"
|
||||
#include "listize.hpp"
|
||||
#include "fn_utils.hpp"
|
||||
#include "fn_selectors.hpp"
|
||||
|
||||
namespace Sass {
|
||||
|
||||
namespace Functions {
|
||||
|
||||
Signature selector_nest_sig = "selector-nest($selectors...)";
|
||||
BUILT_IN(selector_nest)
|
||||
{
|
||||
List* arglist = ARG("$selectors", List);
|
||||
|
||||
// Not enough parameters
|
||||
if (arglist->length() == 0) {
|
||||
error(
|
||||
"$selectors: At least one selector must be passed for `selector-nest'",
|
||||
pstate, traces);
|
||||
}
|
||||
|
||||
// Parse args into vector of selectors
|
||||
SelectorStack parsedSelectors;
|
||||
for (size_t i = 0, L = arglist->length(); i < L; ++i) {
|
||||
ExpressionObj exp = Cast<Expression>(arglist->value_at_index(i));
|
||||
if (exp->concrete_type() == Expression::NULL_VAL) {
|
||||
error(
|
||||
"$selectors: null is not a valid selector: it must be a string,\n"
|
||||
"a list of strings, or a list of lists of strings for 'selector-nest'",
|
||||
pstate, traces);
|
||||
}
|
||||
if (String_Constant_Obj str = Cast<String_Constant>(exp)) {
|
||||
str->quote_mark(0);
|
||||
}
|
||||
sass::string exp_src = exp->to_string(ctx.c_options);
|
||||
ItplFile* source = SASS_MEMORY_NEW(ItplFile, exp_src.c_str(), exp->pstate());
|
||||
SelectorListObj sel = Parser::parse_selector(source, ctx, traces);
|
||||
parsedSelectors.push_back(sel);
|
||||
}
|
||||
|
||||
// Nothing to do
|
||||
if( parsedSelectors.empty() ) {
|
||||
return SASS_MEMORY_NEW(Null, pstate);
|
||||
}
|
||||
|
||||
// Set the first element as the `result`, keep
|
||||
// appending to as we go down the parsedSelector vector.
|
||||
SelectorStack::iterator itr = parsedSelectors.begin();
|
||||
SelectorListObj& result = *itr;
|
||||
++itr;
|
||||
|
||||
for(;itr != parsedSelectors.end(); ++itr) {
|
||||
SelectorListObj& child = *itr;
|
||||
original_stack.push_back(result);
|
||||
SelectorListObj rv = child->resolve_parent_refs(original_stack, traces);
|
||||
result->elements(rv->elements());
|
||||
original_stack.pop_back();
|
||||
}
|
||||
|
||||
return Cast<Value>(Listize::perform(result));
|
||||
}
|
||||
|
||||
Signature selector_append_sig = "selector-append($selectors...)";
|
||||
BUILT_IN(selector_append)
|
||||
{
|
||||
List* arglist = ARG("$selectors", List);
|
||||
|
||||
// Not enough parameters
|
||||
if (arglist->empty()) {
|
||||
error(
|
||||
"$selectors: At least one selector must be "
|
||||
"passed for `selector-append'",
|
||||
pstate, traces);
|
||||
}
|
||||
|
||||
// Parse args into vector of selectors
|
||||
SelectorStack parsedSelectors;
|
||||
parsedSelectors.push_back({});
|
||||
for (size_t i = 0, L = arglist->length(); i < L; ++i) {
|
||||
Expression* exp = Cast<Expression>(arglist->value_at_index(i));
|
||||
if (exp->concrete_type() == Expression::NULL_VAL) {
|
||||
error(
|
||||
"$selectors: null is not a valid selector: it must be a string,\n"
|
||||
"a list of strings, or a list of lists of strings for 'selector-append'",
|
||||
pstate, traces);
|
||||
}
|
||||
if (String_Constant* str = Cast<String_Constant>(exp)) {
|
||||
str->quote_mark(0);
|
||||
}
|
||||
sass::string exp_src = exp->to_string();
|
||||
ItplFile* source = SASS_MEMORY_NEW(ItplFile, exp_src.c_str(), exp->pstate());
|
||||
SelectorListObj sel = Parser::parse_selector(source, ctx, traces, true);
|
||||
|
||||
for (auto& complex : sel->elements()) {
|
||||
if (complex->empty()) {
|
||||
complex->append(SASS_MEMORY_NEW(CompoundSelector, "[phony]"));
|
||||
}
|
||||
if (CompoundSelector* comp = Cast<CompoundSelector>(complex->first())) {
|
||||
comp->hasRealParent(true);
|
||||
complex->chroots(true);
|
||||
}
|
||||
}
|
||||
|
||||
if (parsedSelectors.size() > 1) {
|
||||
|
||||
if (!sel->has_real_parent_ref()) {
|
||||
auto parent = parsedSelectors.back();
|
||||
for (auto& complex : parent->elements()) {
|
||||
if (CompoundSelector* comp = Cast<CompoundSelector>(complex->first())) {
|
||||
comp->hasRealParent(false);
|
||||
}
|
||||
}
|
||||
error("Can't append \"" + sel->to_string() + "\" to \"" +
|
||||
parent->to_string() + "\" for `selector-append'",
|
||||
pstate, traces);
|
||||
}
|
||||
|
||||
// Build the resolved stack from the left. It's cheaper to directly
|
||||
// calculate and update each resolved selcted from the left, than to
|
||||
// recursively calculate them from the right side, as we would need
|
||||
// to go through the whole stack depth to build the final results.
|
||||
// E.g. 'a', 'b', 'x, y' => 'a' => 'a b' => 'a b x, a b y'
|
||||
// vs 'a', 'b', 'x, y' => 'x' => 'b x' => 'a b x', 'y' ...
|
||||
parsedSelectors.push_back(sel->resolve_parent_refs(parsedSelectors, traces, true));
|
||||
}
|
||||
else {
|
||||
parsedSelectors.push_back(sel);
|
||||
}
|
||||
}
|
||||
|
||||
// Nothing to do
|
||||
if( parsedSelectors.empty() ) {
|
||||
return SASS_MEMORY_NEW(Null, pstate);
|
||||
}
|
||||
|
||||
return Cast<Value>(Listize::perform(parsedSelectors.back()));
|
||||
}
|
||||
|
||||
Signature selector_unify_sig = "selector-unify($selector1, $selector2)";
|
||||
BUILT_IN(selector_unify)
|
||||
{
|
||||
SelectorListObj selector1 = ARGSELS("$selector1");
|
||||
SelectorListObj selector2 = ARGSELS("$selector2");
|
||||
SelectorListObj result = selector1->unifyWith(selector2);
|
||||
return Cast<Value>(Listize::perform(result));
|
||||
}
|
||||
|
||||
Signature simple_selectors_sig = "simple-selectors($selector)";
|
||||
BUILT_IN(simple_selectors)
|
||||
{
|
||||
CompoundSelectorObj sel = ARGSEL("$selector");
|
||||
|
||||
List* l = SASS_MEMORY_NEW(List, sel->pstate(), sel->length(), SASS_COMMA);
|
||||
|
||||
for (size_t i = 0, L = sel->length(); i < L; ++i) {
|
||||
const SimpleSelectorObj& ss = sel->get(i);
|
||||
sass::string ss_string = ss->to_string() ;
|
||||
l->append(SASS_MEMORY_NEW(String_Quoted, ss->pstate(), ss_string));
|
||||
}
|
||||
|
||||
return l;
|
||||
}
|
||||
|
||||
Signature selector_extend_sig = "selector-extend($selector, $extendee, $extender)";
|
||||
BUILT_IN(selector_extend)
|
||||
{
|
||||
SelectorListObj selector = ARGSELS("$selector");
|
||||
SelectorListObj target = ARGSELS("$extendee");
|
||||
SelectorListObj source = ARGSELS("$extender");
|
||||
SelectorListObj result = Extender::extend(selector, source, target, traces);
|
||||
return Cast<Value>(Listize::perform(result));
|
||||
}
|
||||
|
||||
Signature selector_replace_sig = "selector-replace($selector, $original, $replacement)";
|
||||
BUILT_IN(selector_replace)
|
||||
{
|
||||
SelectorListObj selector = ARGSELS("$selector");
|
||||
SelectorListObj target = ARGSELS("$original");
|
||||
SelectorListObj source = ARGSELS("$replacement");
|
||||
SelectorListObj result = Extender::replace(selector, source, target, traces);
|
||||
return Cast<Value>(Listize::perform(result));
|
||||
}
|
||||
|
||||
Signature selector_parse_sig = "selector-parse($selector)";
|
||||
BUILT_IN(selector_parse)
|
||||
{
|
||||
SelectorListObj selector = ARGSELS("$selector");
|
||||
return Cast<Value>(Listize::perform(selector));
|
||||
}
|
||||
|
||||
Signature is_superselector_sig = "is-superselector($super, $sub)";
|
||||
BUILT_IN(is_superselector)
|
||||
{
|
||||
SelectorListObj sel_sup = ARGSELS("$super");
|
||||
SelectorListObj sel_sub = ARGSELS("$sub");
|
||||
bool result = sel_sup->isSuperselectorOf(sel_sub);
|
||||
return SASS_MEMORY_NEW(Boolean, pstate, result);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
35
vendor/bundle/ruby/2.6.0/gems/sassc-2.4.0/ext/libsass/src/fn_selectors.hpp
vendored
Normal file
35
vendor/bundle/ruby/2.6.0/gems/sassc-2.4.0/ext/libsass/src/fn_selectors.hpp
vendored
Normal file
@@ -0,0 +1,35 @@
|
||||
#ifndef SASS_FN_SELECTORS_H
|
||||
#define SASS_FN_SELECTORS_H
|
||||
|
||||
#include "fn_utils.hpp"
|
||||
|
||||
namespace Sass {
|
||||
|
||||
namespace Functions {
|
||||
|
||||
#define ARGSEL(argname) get_arg_sel(argname, env, sig, pstate, traces, ctx)
|
||||
#define ARGSELS(argname) get_arg_sels(argname, env, sig, pstate, traces, ctx)
|
||||
|
||||
BUILT_IN(selector_nest);
|
||||
BUILT_IN(selector_append);
|
||||
BUILT_IN(selector_extend);
|
||||
BUILT_IN(selector_replace);
|
||||
BUILT_IN(selector_unify);
|
||||
BUILT_IN(is_superselector);
|
||||
BUILT_IN(simple_selectors);
|
||||
BUILT_IN(selector_parse);
|
||||
|
||||
extern Signature selector_nest_sig;
|
||||
extern Signature selector_append_sig;
|
||||
extern Signature selector_extend_sig;
|
||||
extern Signature selector_replace_sig;
|
||||
extern Signature selector_unify_sig;
|
||||
extern Signature is_superselector_sig;
|
||||
extern Signature simple_selectors_sig;
|
||||
extern Signature selector_parse_sig;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
268
vendor/bundle/ruby/2.6.0/gems/sassc-2.4.0/ext/libsass/src/fn_strings.cpp
vendored
Normal file
268
vendor/bundle/ruby/2.6.0/gems/sassc-2.4.0/ext/libsass/src/fn_strings.cpp
vendored
Normal file
@@ -0,0 +1,268 @@
|
||||
// sass.hpp must go before all system headers to get the
|
||||
// __EXTENSIONS__ fix on Solaris.
|
||||
#include "sass.hpp"
|
||||
|
||||
#include "utf8.h"
|
||||
#include "ast.hpp"
|
||||
#include "fn_utils.hpp"
|
||||
#include "fn_strings.hpp"
|
||||
#include "util_string.hpp"
|
||||
|
||||
namespace Sass {
|
||||
|
||||
namespace Functions {
|
||||
|
||||
void handle_utf8_error (const SourceSpan& pstate, Backtraces traces)
|
||||
{
|
||||
try {
|
||||
throw;
|
||||
}
|
||||
catch (utf8::invalid_code_point&) {
|
||||
sass::string msg("utf8::invalid_code_point");
|
||||
error(msg, pstate, traces);
|
||||
}
|
||||
catch (utf8::not_enough_room&) {
|
||||
sass::string msg("utf8::not_enough_room");
|
||||
error(msg, pstate, traces);
|
||||
}
|
||||
catch (utf8::invalid_utf8&) {
|
||||
sass::string msg("utf8::invalid_utf8");
|
||||
error(msg, pstate, traces);
|
||||
}
|
||||
catch (...) { throw; }
|
||||
}
|
||||
|
||||
///////////////////
|
||||
// STRING FUNCTIONS
|
||||
///////////////////
|
||||
|
||||
Signature unquote_sig = "unquote($string)";
|
||||
BUILT_IN(sass_unquote)
|
||||
{
|
||||
AST_Node_Obj arg = env["$string"];
|
||||
if (String_Quoted* string_quoted = Cast<String_Quoted>(arg)) {
|
||||
String_Constant* result = SASS_MEMORY_NEW(String_Constant, pstate, string_quoted->value());
|
||||
// remember if the string was quoted (color tokens)
|
||||
result->is_delayed(true); // delay colors
|
||||
return result;
|
||||
}
|
||||
else if (String_Constant* str = Cast<String_Constant>(arg)) {
|
||||
return str;
|
||||
}
|
||||
else if (Value* ex = Cast<Value>(arg)) {
|
||||
Sass_Output_Style oldstyle = ctx.c_options.output_style;
|
||||
ctx.c_options.output_style = SASS_STYLE_NESTED;
|
||||
sass::string val(arg->to_string(ctx.c_options));
|
||||
val = Cast<Null>(arg) ? "null" : val;
|
||||
ctx.c_options.output_style = oldstyle;
|
||||
|
||||
deprecated_function("Passing " + val + ", a non-string value, to unquote()", pstate);
|
||||
return ex;
|
||||
}
|
||||
throw std::runtime_error("Invalid Data Type for unquote");
|
||||
}
|
||||
|
||||
Signature quote_sig = "quote($string)";
|
||||
BUILT_IN(sass_quote)
|
||||
{
|
||||
const String_Constant* s = ARG("$string", String_Constant);
|
||||
String_Quoted *result = SASS_MEMORY_NEW(
|
||||
String_Quoted, pstate, s->value(),
|
||||
/*q=*/'\0', /*keep_utf8_escapes=*/false, /*skip_unquoting=*/true);
|
||||
result->quote_mark('*');
|
||||
return result;
|
||||
}
|
||||
|
||||
Signature str_length_sig = "str-length($string)";
|
||||
BUILT_IN(str_length)
|
||||
{
|
||||
size_t len = sass::string::npos;
|
||||
try {
|
||||
String_Constant* s = ARG("$string", String_Constant);
|
||||
len = UTF_8::code_point_count(s->value(), 0, s->value().size());
|
||||
|
||||
}
|
||||
// handle any invalid utf8 errors
|
||||
// other errors will be re-thrown
|
||||
catch (...) { handle_utf8_error(pstate, traces); }
|
||||
// return something even if we had an error (-1)
|
||||
return SASS_MEMORY_NEW(Number, pstate, (double)len);
|
||||
}
|
||||
|
||||
Signature str_insert_sig = "str-insert($string, $insert, $index)";
|
||||
BUILT_IN(str_insert)
|
||||
{
|
||||
sass::string str;
|
||||
try {
|
||||
String_Constant* s = ARG("$string", String_Constant);
|
||||
str = s->value();
|
||||
String_Constant* i = ARG("$insert", String_Constant);
|
||||
sass::string ins = i->value();
|
||||
double index = ARGVAL("$index");
|
||||
if (index != (int)index) {
|
||||
sass::ostream strm;
|
||||
strm << "$index: ";
|
||||
strm << std::to_string(index);
|
||||
strm << " is not an int";
|
||||
error(strm.str(), pstate, traces);
|
||||
}
|
||||
size_t len = UTF_8::code_point_count(str, 0, str.size());
|
||||
|
||||
if (index > 0 && index <= len) {
|
||||
// positive and within string length
|
||||
str.insert(UTF_8::offset_at_position(str, static_cast<size_t>(index) - 1), ins);
|
||||
}
|
||||
else if (index > len) {
|
||||
// positive and past string length
|
||||
str += ins;
|
||||
}
|
||||
else if (index == 0) {
|
||||
str = ins + str;
|
||||
}
|
||||
else if (std::abs(index) <= len) {
|
||||
// negative and within string length
|
||||
index += len + 1;
|
||||
str.insert(UTF_8::offset_at_position(str, static_cast<size_t>(index)), ins);
|
||||
}
|
||||
else {
|
||||
// negative and past string length
|
||||
str = ins + str;
|
||||
}
|
||||
|
||||
if (String_Quoted* ss = Cast<String_Quoted>(s)) {
|
||||
if (ss->quote_mark()) str = quote(str);
|
||||
}
|
||||
}
|
||||
// handle any invalid utf8 errors
|
||||
// other errors will be re-thrown
|
||||
catch (...) { handle_utf8_error(pstate, traces); }
|
||||
return SASS_MEMORY_NEW(String_Quoted, pstate, str);
|
||||
}
|
||||
|
||||
Signature str_index_sig = "str-index($string, $substring)";
|
||||
BUILT_IN(str_index)
|
||||
{
|
||||
size_t index = sass::string::npos;
|
||||
try {
|
||||
String_Constant* s = ARG("$string", String_Constant);
|
||||
String_Constant* t = ARG("$substring", String_Constant);
|
||||
sass::string str = s->value();
|
||||
sass::string substr = t->value();
|
||||
|
||||
size_t c_index = str.find(substr);
|
||||
if(c_index == sass::string::npos) {
|
||||
return SASS_MEMORY_NEW(Null, pstate);
|
||||
}
|
||||
index = UTF_8::code_point_count(str, 0, c_index) + 1;
|
||||
}
|
||||
// handle any invalid utf8 errors
|
||||
// other errors will be re-thrown
|
||||
catch (...) { handle_utf8_error(pstate, traces); }
|
||||
// return something even if we had an error (-1)
|
||||
return SASS_MEMORY_NEW(Number, pstate, (double)index);
|
||||
}
|
||||
|
||||
Signature str_slice_sig = "str-slice($string, $start-at, $end-at:-1)";
|
||||
BUILT_IN(str_slice)
|
||||
{
|
||||
sass::string newstr;
|
||||
try {
|
||||
String_Constant* s = ARG("$string", String_Constant);
|
||||
double start_at = ARGVAL("$start-at");
|
||||
double end_at = ARGVAL("$end-at");
|
||||
|
||||
if (start_at != (int)start_at) {
|
||||
sass::ostream strm;
|
||||
strm << "$start-at: ";
|
||||
strm << std::to_string(start_at);
|
||||
strm << " is not an int";
|
||||
error(strm.str(), pstate, traces);
|
||||
}
|
||||
|
||||
String_Quoted* ss = Cast<String_Quoted>(s);
|
||||
|
||||
sass::string str(s->value());
|
||||
|
||||
size_t size = utf8::distance(str.begin(), str.end());
|
||||
|
||||
if (!Cast<Number>(env["$end-at"])) {
|
||||
end_at = -1;
|
||||
}
|
||||
|
||||
if (end_at != (int)end_at) {
|
||||
sass::ostream strm;
|
||||
strm << "$end-at: ";
|
||||
strm << std::to_string(end_at);
|
||||
strm << " is not an int";
|
||||
error(strm.str(), pstate, traces);
|
||||
}
|
||||
|
||||
if (end_at == 0 || (end_at + size) < 0) {
|
||||
if (ss && ss->quote_mark()) newstr = quote("");
|
||||
return SASS_MEMORY_NEW(String_Quoted, pstate, newstr);
|
||||
}
|
||||
|
||||
if (end_at < 0) {
|
||||
end_at += size + 1;
|
||||
if (end_at == 0) end_at = 1;
|
||||
}
|
||||
if (end_at > size) { end_at = (double)size; }
|
||||
if (start_at < 0) {
|
||||
start_at += size + 1;
|
||||
if (start_at <= 0) start_at = 1;
|
||||
}
|
||||
else if (start_at == 0) { ++ start_at; }
|
||||
|
||||
if (start_at <= end_at)
|
||||
{
|
||||
sass::string::iterator start = str.begin();
|
||||
utf8::advance(start, start_at - 1, str.end());
|
||||
sass::string::iterator end = start;
|
||||
utf8::advance(end, end_at - start_at + 1, str.end());
|
||||
newstr = sass::string(start, end);
|
||||
}
|
||||
if (ss) {
|
||||
if(ss->quote_mark()) newstr = quote(newstr);
|
||||
}
|
||||
}
|
||||
// handle any invalid utf8 errors
|
||||
// other errors will be re-thrown
|
||||
catch (...) { handle_utf8_error(pstate, traces); }
|
||||
return SASS_MEMORY_NEW(String_Quoted, pstate, newstr);
|
||||
}
|
||||
|
||||
Signature to_upper_case_sig = "to-upper-case($string)";
|
||||
BUILT_IN(to_upper_case)
|
||||
{
|
||||
String_Constant* s = ARG("$string", String_Constant);
|
||||
sass::string str = s->value();
|
||||
Util::ascii_str_toupper(&str);
|
||||
|
||||
if (String_Quoted* ss = Cast<String_Quoted>(s)) {
|
||||
String_Quoted* cpy = SASS_MEMORY_COPY(ss);
|
||||
cpy->value(str);
|
||||
return cpy;
|
||||
} else {
|
||||
return SASS_MEMORY_NEW(String_Quoted, pstate, str);
|
||||
}
|
||||
}
|
||||
|
||||
Signature to_lower_case_sig = "to-lower-case($string)";
|
||||
BUILT_IN(to_lower_case)
|
||||
{
|
||||
String_Constant* s = ARG("$string", String_Constant);
|
||||
sass::string str = s->value();
|
||||
Util::ascii_str_tolower(&str);
|
||||
|
||||
if (String_Quoted* ss = Cast<String_Quoted>(s)) {
|
||||
String_Quoted* cpy = SASS_MEMORY_COPY(ss);
|
||||
cpy->value(str);
|
||||
return cpy;
|
||||
} else {
|
||||
return SASS_MEMORY_NEW(String_Quoted, pstate, str);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
34
vendor/bundle/ruby/2.6.0/gems/sassc-2.4.0/ext/libsass/src/fn_strings.hpp
vendored
Normal file
34
vendor/bundle/ruby/2.6.0/gems/sassc-2.4.0/ext/libsass/src/fn_strings.hpp
vendored
Normal file
@@ -0,0 +1,34 @@
|
||||
#ifndef SASS_FN_STRINGS_H
|
||||
#define SASS_FN_STRINGS_H
|
||||
|
||||
#include "fn_utils.hpp"
|
||||
|
||||
namespace Sass {
|
||||
|
||||
namespace Functions {
|
||||
|
||||
extern Signature unquote_sig;
|
||||
extern Signature quote_sig;
|
||||
extern Signature str_length_sig;
|
||||
extern Signature str_insert_sig;
|
||||
extern Signature str_index_sig;
|
||||
extern Signature str_slice_sig;
|
||||
extern Signature to_upper_case_sig;
|
||||
extern Signature to_lower_case_sig;
|
||||
extern Signature length_sig;
|
||||
|
||||
BUILT_IN(sass_unquote);
|
||||
BUILT_IN(sass_quote);
|
||||
BUILT_IN(str_length);
|
||||
BUILT_IN(str_insert);
|
||||
BUILT_IN(str_index);
|
||||
BUILT_IN(str_slice);
|
||||
BUILT_IN(to_upper_case);
|
||||
BUILT_IN(to_lower_case);
|
||||
BUILT_IN(length);
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
158
vendor/bundle/ruby/2.6.0/gems/sassc-2.4.0/ext/libsass/src/fn_utils.cpp
vendored
Normal file
158
vendor/bundle/ruby/2.6.0/gems/sassc-2.4.0/ext/libsass/src/fn_utils.cpp
vendored
Normal file
@@ -0,0 +1,158 @@
|
||||
// sass.hpp must go before all system headers to get the
|
||||
// __EXTENSIONS__ fix on Solaris.
|
||||
#include "sass.hpp"
|
||||
|
||||
#include "parser.hpp"
|
||||
#include "fn_utils.hpp"
|
||||
#include "util_string.hpp"
|
||||
|
||||
namespace Sass {
|
||||
|
||||
Definition* make_native_function(Signature sig, Native_Function func, Context& ctx)
|
||||
{
|
||||
SourceFile* source = SASS_MEMORY_NEW(SourceFile, "[built-in function]", sig, std::string::npos);
|
||||
Parser sig_parser(source, ctx, ctx.traces);
|
||||
sig_parser.lex<Prelexer::identifier>();
|
||||
sass::string name(Util::normalize_underscores(sig_parser.lexed));
|
||||
Parameters_Obj params = sig_parser.parse_parameters();
|
||||
return SASS_MEMORY_NEW(Definition,
|
||||
SourceSpan(source),
|
||||
sig,
|
||||
name,
|
||||
params,
|
||||
func,
|
||||
false);
|
||||
}
|
||||
|
||||
Definition* make_c_function(Sass_Function_Entry c_func, Context& ctx)
|
||||
{
|
||||
using namespace Prelexer;
|
||||
const char* sig = sass_function_get_signature(c_func);
|
||||
SourceFile* source = SASS_MEMORY_NEW(SourceFile, "[c function]", sig, std::string::npos);
|
||||
Parser sig_parser(source, ctx, ctx.traces);
|
||||
// allow to overload generic callback plus @warn, @error and @debug with custom functions
|
||||
sig_parser.lex < alternatives < identifier, exactly <'*'>,
|
||||
exactly < Constants::warn_kwd >,
|
||||
exactly < Constants::error_kwd >,
|
||||
exactly < Constants::debug_kwd >
|
||||
> >();
|
||||
sass::string name(Util::normalize_underscores(sig_parser.lexed));
|
||||
Parameters_Obj params = sig_parser.parse_parameters();
|
||||
return SASS_MEMORY_NEW(Definition,
|
||||
SourceSpan(source),
|
||||
sig,
|
||||
name,
|
||||
params,
|
||||
c_func);
|
||||
}
|
||||
|
||||
namespace Functions {
|
||||
|
||||
sass::string function_name(Signature sig)
|
||||
{
|
||||
sass::string str(sig);
|
||||
return str.substr(0, str.find('('));
|
||||
}
|
||||
|
||||
Map* get_arg_m(const sass::string& argname, Env& env, Signature sig, SourceSpan pstate, Backtraces traces)
|
||||
{
|
||||
AST_Node* value = env[argname];
|
||||
if (Map* map = Cast<Map>(value)) return map;
|
||||
List* list = Cast<List>(value);
|
||||
if (list && list->length() == 0) {
|
||||
return SASS_MEMORY_NEW(Map, pstate, 0);
|
||||
}
|
||||
return get_arg<Map>(argname, env, sig, pstate, traces);
|
||||
}
|
||||
|
||||
double get_arg_r(const sass::string& argname, Env& env, Signature sig, SourceSpan pstate, Backtraces traces, double lo, double hi)
|
||||
{
|
||||
Number* val = get_arg<Number>(argname, env, sig, pstate, traces);
|
||||
Number tmpnr(val);
|
||||
tmpnr.reduce();
|
||||
double v = tmpnr.value();
|
||||
if (!(lo <= v && v <= hi)) {
|
||||
sass::ostream msg;
|
||||
msg << "argument `" << argname << "` of `" << sig << "` must be between ";
|
||||
msg << lo << " and " << hi;
|
||||
error(msg.str(), pstate, traces);
|
||||
}
|
||||
return v;
|
||||
}
|
||||
|
||||
Number* get_arg_n(const sass::string& argname, Env& env, Signature sig, SourceSpan pstate, Backtraces traces)
|
||||
{
|
||||
Number* val = get_arg<Number>(argname, env, sig, pstate, traces);
|
||||
val = SASS_MEMORY_COPY(val);
|
||||
val->reduce();
|
||||
return val;
|
||||
}
|
||||
|
||||
double get_arg_val(const sass::string& argname, Env& env, Signature sig, SourceSpan pstate, Backtraces traces)
|
||||
{
|
||||
Number* val = get_arg<Number>(argname, env, sig, pstate, traces);
|
||||
Number tmpnr(val);
|
||||
tmpnr.reduce();
|
||||
return tmpnr.value();
|
||||
}
|
||||
|
||||
double color_num(const sass::string& argname, Env& env, Signature sig, SourceSpan pstate, Backtraces traces)
|
||||
{
|
||||
Number* val = get_arg<Number>(argname, env, sig, pstate, traces);
|
||||
Number tmpnr(val);
|
||||
tmpnr.reduce();
|
||||
if (tmpnr.unit() == "%") {
|
||||
return std::min(std::max(tmpnr.value() * 255 / 100.0, 0.0), 255.0);
|
||||
} else {
|
||||
return std::min(std::max(tmpnr.value(), 0.0), 255.0);
|
||||
}
|
||||
}
|
||||
|
||||
double alpha_num(const sass::string& argname, Env& env, Signature sig, SourceSpan pstate, Backtraces traces) {
|
||||
Number* val = get_arg<Number>(argname, env, sig, pstate, traces);
|
||||
Number tmpnr(val);
|
||||
tmpnr.reduce();
|
||||
if (tmpnr.unit() == "%") {
|
||||
return std::min(std::max(tmpnr.value(), 0.0), 100.0);
|
||||
} else {
|
||||
return std::min(std::max(tmpnr.value(), 0.0), 1.0);
|
||||
}
|
||||
}
|
||||
|
||||
SelectorListObj get_arg_sels(const sass::string& argname, Env& env, Signature sig, SourceSpan pstate, Backtraces traces, Context& ctx) {
|
||||
ExpressionObj exp = ARG(argname, Expression);
|
||||
if (exp->concrete_type() == Expression::NULL_VAL) {
|
||||
sass::ostream msg;
|
||||
msg << argname << ": null is not a valid selector: it must be a string,\n";
|
||||
msg << "a list of strings, or a list of lists of strings for `" << function_name(sig) << "'";
|
||||
error(msg.str(), exp->pstate(), traces);
|
||||
}
|
||||
if (String_Constant* str = Cast<String_Constant>(exp)) {
|
||||
str->quote_mark(0);
|
||||
}
|
||||
sass::string exp_src = exp->to_string(ctx.c_options);
|
||||
ItplFile* source = SASS_MEMORY_NEW(ItplFile, exp_src.c_str(), exp->pstate());
|
||||
return Parser::parse_selector(source, ctx, traces, false);
|
||||
}
|
||||
|
||||
CompoundSelectorObj get_arg_sel(const sass::string& argname, Env& env, Signature sig, SourceSpan pstate, Backtraces traces, Context& ctx) {
|
||||
ExpressionObj exp = ARG(argname, Expression);
|
||||
if (exp->concrete_type() == Expression::NULL_VAL) {
|
||||
sass::ostream msg;
|
||||
msg << argname << ": null is not a string for `" << function_name(sig) << "'";
|
||||
error(msg.str(), exp->pstate(), traces);
|
||||
}
|
||||
if (String_Constant* str = Cast<String_Constant>(exp)) {
|
||||
str->quote_mark(0);
|
||||
}
|
||||
sass::string exp_src = exp->to_string(ctx.c_options);
|
||||
ItplFile* source = SASS_MEMORY_NEW(ItplFile, exp_src.c_str(), exp->pstate());
|
||||
SelectorListObj sel_list = Parser::parse_selector(source, ctx, traces, false);
|
||||
if (sel_list->length() == 0) return {};
|
||||
return sel_list->first()->first();
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
62
vendor/bundle/ruby/2.6.0/gems/sassc-2.4.0/ext/libsass/src/fn_utils.hpp
vendored
Normal file
62
vendor/bundle/ruby/2.6.0/gems/sassc-2.4.0/ext/libsass/src/fn_utils.hpp
vendored
Normal file
@@ -0,0 +1,62 @@
|
||||
#ifndef SASS_FN_UTILS_H
|
||||
#define SASS_FN_UTILS_H
|
||||
|
||||
// sass.hpp must go before all system headers to get the
|
||||
// __EXTENSIONS__ fix on Solaris.
|
||||
#include "sass.hpp"
|
||||
|
||||
#include "units.hpp"
|
||||
#include "backtrace.hpp"
|
||||
#include "environment.hpp"
|
||||
#include "ast_fwd_decl.hpp"
|
||||
#include "error_handling.hpp"
|
||||
|
||||
namespace Sass {
|
||||
|
||||
#define FN_PROTOTYPE \
|
||||
Env& env, \
|
||||
Env& d_env, \
|
||||
Context& ctx, \
|
||||
Signature sig, \
|
||||
SourceSpan pstate, \
|
||||
Backtraces& traces, \
|
||||
SelectorStack selector_stack, \
|
||||
SelectorStack original_stack \
|
||||
|
||||
typedef const char* Signature;
|
||||
typedef PreValue* (*Native_Function)(FN_PROTOTYPE);
|
||||
#define BUILT_IN(name) PreValue* name(FN_PROTOTYPE)
|
||||
|
||||
#define ARG(argname, argtype) get_arg<argtype>(argname, env, sig, pstate, traces)
|
||||
// special function for weird hsla percent (10px == 10% == 10 != 0.1)
|
||||
#define ARGVAL(argname) get_arg_val(argname, env, sig, pstate, traces) // double
|
||||
|
||||
Definition* make_native_function(Signature, Native_Function, Context& ctx);
|
||||
Definition* make_c_function(Sass_Function_Entry c_func, Context& ctx);
|
||||
|
||||
namespace Functions {
|
||||
|
||||
template <typename T>
|
||||
T* get_arg(const sass::string& argname, Env& env, Signature sig, SourceSpan pstate, Backtraces traces)
|
||||
{
|
||||
T* val = Cast<T>(env[argname]);
|
||||
if (!val) {
|
||||
error("argument `" + argname + "` of `" + sig + "` must be a " + T::type_name(), pstate, traces);
|
||||
}
|
||||
return val;
|
||||
}
|
||||
|
||||
Map* get_arg_m(const sass::string& argname, Env& env, Signature sig, SourceSpan pstate, Backtraces traces); // maps only
|
||||
Number* get_arg_n(const sass::string& argname, Env& env, Signature sig, SourceSpan pstate, Backtraces traces); // numbers only
|
||||
double alpha_num(const sass::string& argname, Env& env, Signature sig, SourceSpan pstate, Backtraces traces); // colors only
|
||||
double color_num(const sass::string& argname, Env& env, Signature sig, SourceSpan pstate, Backtraces traces); // colors only
|
||||
double get_arg_r(const sass::string& argname, Env& env, Signature sig, SourceSpan pstate, Backtraces traces, double lo, double hi); // colors only
|
||||
double get_arg_val(const sass::string& argname, Env& env, Signature sig, SourceSpan pstate, Backtraces traces); // shared
|
||||
SelectorListObj get_arg_sels(const sass::string& argname, Env& env, Signature sig, SourceSpan pstate, Backtraces traces, Context& ctx); // selectors only
|
||||
CompoundSelectorObj get_arg_sel(const sass::string& argname, Env& env, Signature sig, SourceSpan pstate, Backtraces traces, Context& ctx); // selectors only
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
1125
vendor/bundle/ruby/2.6.0/gems/sassc-2.4.0/ext/libsass/src/inspect.cpp
vendored
Normal file
1125
vendor/bundle/ruby/2.6.0/gems/sassc-2.4.0/ext/libsass/src/inspect.cpp
vendored
Normal file
File diff suppressed because it is too large
Load Diff
101
vendor/bundle/ruby/2.6.0/gems/sassc-2.4.0/ext/libsass/src/inspect.hpp
vendored
Normal file
101
vendor/bundle/ruby/2.6.0/gems/sassc-2.4.0/ext/libsass/src/inspect.hpp
vendored
Normal file
@@ -0,0 +1,101 @@
|
||||
#ifndef SASS_INSPECT_H
|
||||
#define SASS_INSPECT_H
|
||||
|
||||
#include "position.hpp"
|
||||
#include "operation.hpp"
|
||||
#include "emitter.hpp"
|
||||
|
||||
namespace Sass {
|
||||
class Context;
|
||||
|
||||
class Inspect : public Operation_CRTP<void, Inspect>, public Emitter {
|
||||
protected:
|
||||
// import all the class-specific methods and override as desired
|
||||
using Operation_CRTP<void, Inspect>::operator();
|
||||
|
||||
public:
|
||||
|
||||
Inspect(const Emitter& emi);
|
||||
virtual ~Inspect();
|
||||
|
||||
// statements
|
||||
virtual void operator()(Block*);
|
||||
virtual void operator()(StyleRule*);
|
||||
virtual void operator()(Bubble*);
|
||||
virtual void operator()(SupportsRule*);
|
||||
virtual void operator()(AtRootRule*);
|
||||
virtual void operator()(AtRule*);
|
||||
virtual void operator()(Keyframe_Rule*);
|
||||
virtual void operator()(Declaration*);
|
||||
virtual void operator()(Assignment*);
|
||||
virtual void operator()(Import*);
|
||||
virtual void operator()(Import_Stub*);
|
||||
virtual void operator()(WarningRule*);
|
||||
virtual void operator()(ErrorRule*);
|
||||
virtual void operator()(DebugRule*);
|
||||
virtual void operator()(Comment*);
|
||||
virtual void operator()(If*);
|
||||
virtual void operator()(ForRule*);
|
||||
virtual void operator()(EachRule*);
|
||||
virtual void operator()(WhileRule*);
|
||||
virtual void operator()(Return*);
|
||||
virtual void operator()(ExtendRule*);
|
||||
virtual void operator()(Definition*);
|
||||
virtual void operator()(Mixin_Call*);
|
||||
virtual void operator()(Content*);
|
||||
// expressions
|
||||
virtual void operator()(Map*);
|
||||
virtual void operator()(Function*);
|
||||
virtual void operator()(List*);
|
||||
virtual void operator()(Binary_Expression*);
|
||||
virtual void operator()(Unary_Expression*);
|
||||
virtual void operator()(Function_Call*);
|
||||
// virtual void operator()(Custom_Warning*);
|
||||
// virtual void operator()(Custom_Error*);
|
||||
virtual void operator()(Variable*);
|
||||
virtual void operator()(Number*);
|
||||
virtual void operator()(Color_RGBA*);
|
||||
virtual void operator()(Color_HSLA*);
|
||||
virtual void operator()(Boolean*);
|
||||
virtual void operator()(String_Schema*);
|
||||
virtual void operator()(String_Constant*);
|
||||
virtual void operator()(String_Quoted*);
|
||||
virtual void operator()(Custom_Error*);
|
||||
virtual void operator()(Custom_Warning*);
|
||||
virtual void operator()(SupportsOperation*);
|
||||
virtual void operator()(SupportsNegation*);
|
||||
virtual void operator()(SupportsDeclaration*);
|
||||
virtual void operator()(Supports_Interpolation*);
|
||||
virtual void operator()(MediaRule*);
|
||||
virtual void operator()(CssMediaRule*);
|
||||
virtual void operator()(CssMediaQuery*);
|
||||
virtual void operator()(Media_Query*);
|
||||
virtual void operator()(Media_Query_Expression*);
|
||||
virtual void operator()(At_Root_Query*);
|
||||
virtual void operator()(Null*);
|
||||
virtual void operator()(Parent_Reference* p);
|
||||
// parameters and arguments
|
||||
virtual void operator()(Parameter*);
|
||||
virtual void operator()(Parameters*);
|
||||
virtual void operator()(Argument*);
|
||||
virtual void operator()(Arguments*);
|
||||
// selectors
|
||||
virtual void operator()(Selector_Schema*);
|
||||
virtual void operator()(PlaceholderSelector*);
|
||||
virtual void operator()(TypeSelector*);
|
||||
virtual void operator()(ClassSelector*);
|
||||
virtual void operator()(IDSelector*);
|
||||
virtual void operator()(AttributeSelector*);
|
||||
virtual void operator()(PseudoSelector*);
|
||||
virtual void operator()(SelectorComponent*);
|
||||
virtual void operator()(SelectorCombinator*);
|
||||
virtual void operator()(CompoundSelector*);
|
||||
virtual void operator()(ComplexSelector*);
|
||||
virtual void operator()(SelectorList*);
|
||||
virtual sass::string lbracket(List*);
|
||||
virtual sass::string rbracket(List*);
|
||||
|
||||
};
|
||||
|
||||
}
|
||||
#endif
|
||||
1436
vendor/bundle/ruby/2.6.0/gems/sassc-2.4.0/ext/libsass/src/json.cpp
vendored
Normal file
1436
vendor/bundle/ruby/2.6.0/gems/sassc-2.4.0/ext/libsass/src/json.cpp
vendored
Normal file
File diff suppressed because it is too large
Load Diff
117
vendor/bundle/ruby/2.6.0/gems/sassc-2.4.0/ext/libsass/src/json.hpp
vendored
Normal file
117
vendor/bundle/ruby/2.6.0/gems/sassc-2.4.0/ext/libsass/src/json.hpp
vendored
Normal file
@@ -0,0 +1,117 @@
|
||||
/*
|
||||
Copyright (C) 2011 Joseph A. Adams (joeyadams3.14159@gmail.com)
|
||||
All rights reserved.
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in
|
||||
all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#ifndef CCAN_JSON_H
|
||||
#define CCAN_JSON_H
|
||||
|
||||
#include <stdbool.h>
|
||||
#include <stddef.h>
|
||||
|
||||
typedef enum {
|
||||
JSON_NULL,
|
||||
JSON_BOOL,
|
||||
JSON_STRING,
|
||||
JSON_NUMBER,
|
||||
JSON_ARRAY,
|
||||
JSON_OBJECT,
|
||||
} JsonTag;
|
||||
|
||||
typedef struct JsonNode JsonNode;
|
||||
|
||||
struct JsonNode
|
||||
{
|
||||
/* only if parent is an object or array (NULL otherwise) */
|
||||
JsonNode *parent;
|
||||
JsonNode *prev, *next;
|
||||
|
||||
/* only if parent is an object (NULL otherwise) */
|
||||
char *key; /* Must be valid UTF-8. */
|
||||
|
||||
JsonTag tag;
|
||||
union {
|
||||
/* JSON_BOOL */
|
||||
bool bool_;
|
||||
|
||||
/* JSON_STRING */
|
||||
char *string_; /* Must be valid UTF-8. */
|
||||
|
||||
/* JSON_NUMBER */
|
||||
double number_;
|
||||
|
||||
/* JSON_ARRAY */
|
||||
/* JSON_OBJECT */
|
||||
struct {
|
||||
JsonNode *head, *tail;
|
||||
} children;
|
||||
};
|
||||
};
|
||||
|
||||
/*** Encoding, decoding, and validation ***/
|
||||
|
||||
JsonNode *json_decode (const char *json);
|
||||
char *json_encode (const JsonNode *node);
|
||||
char *json_encode_string (const char *str);
|
||||
char *json_stringify (const JsonNode *node, const char *space);
|
||||
void json_delete (JsonNode *node);
|
||||
|
||||
bool json_validate (const char *json);
|
||||
|
||||
/*** Lookup and traversal ***/
|
||||
|
||||
JsonNode *json_find_element (JsonNode *array, int index);
|
||||
JsonNode *json_find_member (JsonNode *object, const char *key);
|
||||
|
||||
JsonNode *json_first_child (const JsonNode *node);
|
||||
|
||||
#define json_foreach(i, object_or_array) \
|
||||
for ((i) = json_first_child(object_or_array); \
|
||||
(i) != NULL; \
|
||||
(i) = (i)->next)
|
||||
|
||||
/*** Construction and manipulation ***/
|
||||
|
||||
JsonNode *json_mknull(void);
|
||||
JsonNode *json_mkbool(bool b);
|
||||
JsonNode *json_mkstring(const char *s);
|
||||
JsonNode *json_mknumber(double n);
|
||||
JsonNode *json_mkarray(void);
|
||||
JsonNode *json_mkobject(void);
|
||||
|
||||
void json_append_element(JsonNode *array, JsonNode *element);
|
||||
void json_prepend_element(JsonNode *array, JsonNode *element);
|
||||
void json_append_member(JsonNode *object, const char *key, JsonNode *value);
|
||||
void json_prepend_member(JsonNode *object, const char *key, JsonNode *value);
|
||||
|
||||
void json_remove_from_parent(JsonNode *node);
|
||||
|
||||
/*** Debugging ***/
|
||||
|
||||
/*
|
||||
* Look for structure and encoding problems in a JsonNode or its descendents.
|
||||
*
|
||||
* If a problem is detected, return false, writing a description of the problem
|
||||
* to errmsg (unless errmsg is NULL).
|
||||
*/
|
||||
bool json_check(const JsonNode *node, char errmsg[256]);
|
||||
|
||||
#endif
|
||||
28
vendor/bundle/ruby/2.6.0/gems/sassc-2.4.0/ext/libsass/src/kwd_arg_macros.hpp
vendored
Normal file
28
vendor/bundle/ruby/2.6.0/gems/sassc-2.4.0/ext/libsass/src/kwd_arg_macros.hpp
vendored
Normal file
@@ -0,0 +1,28 @@
|
||||
#ifndef SASS_KWD_ARG_MACROS_H
|
||||
#define SASS_KWD_ARG_MACROS_H
|
||||
|
||||
// Example usage:
|
||||
// KWD_ARG_SET(Args) {
|
||||
// KWD_ARG(Args, string, foo);
|
||||
// KWD_ARG(Args, int, bar);
|
||||
// ...
|
||||
// };
|
||||
//
|
||||
// ... and later ...
|
||||
//
|
||||
// something(Args().foo("hey").bar(3));
|
||||
|
||||
#define KWD_ARG_SET(set_name) class set_name
|
||||
|
||||
#define KWD_ARG(set_name, type, name) \
|
||||
private: \
|
||||
type name##_; \
|
||||
public: \
|
||||
set_name& name(type name##__) { \
|
||||
name##_ = name##__; \
|
||||
return *this; \
|
||||
} \
|
||||
type name() { return name##_; } \
|
||||
private:
|
||||
|
||||
#endif
|
||||
122
vendor/bundle/ruby/2.6.0/gems/sassc-2.4.0/ext/libsass/src/lexer.cpp
vendored
Normal file
122
vendor/bundle/ruby/2.6.0/gems/sassc-2.4.0/ext/libsass/src/lexer.cpp
vendored
Normal file
@@ -0,0 +1,122 @@
|
||||
// sass.hpp must go before all system headers to get the
|
||||
// __EXTENSIONS__ fix on Solaris.
|
||||
#include "sass.hpp"
|
||||
|
||||
#include <iostream>
|
||||
#include <iomanip>
|
||||
#include "lexer.hpp"
|
||||
#include "constants.hpp"
|
||||
#include "util_string.hpp"
|
||||
|
||||
|
||||
namespace Sass {
|
||||
using namespace Constants;
|
||||
|
||||
namespace Prelexer {
|
||||
|
||||
//####################################
|
||||
// BASIC CHARACTER MATCHERS
|
||||
//####################################
|
||||
|
||||
// Match standard control chars
|
||||
const char* kwd_at(const char* src) { return exactly<'@'>(src); }
|
||||
const char* kwd_dot(const char* src) { return exactly<'.'>(src); }
|
||||
const char* kwd_comma(const char* src) { return exactly<','>(src); };
|
||||
const char* kwd_colon(const char* src) { return exactly<':'>(src); };
|
||||
const char* kwd_star(const char* src) { return exactly<'*'>(src); };
|
||||
const char* kwd_plus(const char* src) { return exactly<'+'>(src); };
|
||||
const char* kwd_minus(const char* src) { return exactly<'-'>(src); };
|
||||
const char* kwd_slash(const char* src) { return exactly<'/'>(src); };
|
||||
|
||||
bool is_number(char chr) {
|
||||
return Util::ascii_isdigit(static_cast<unsigned char>(chr)) ||
|
||||
chr == '-' || chr == '+';
|
||||
}
|
||||
|
||||
// check if char is within a reduced ascii range
|
||||
// valid in a uri (copied from Ruby Sass)
|
||||
bool is_uri_character(char chr)
|
||||
{
|
||||
unsigned int cmp = unsigned(chr);
|
||||
return (cmp > 41 && cmp < 127) ||
|
||||
cmp == ':' || cmp == '/';
|
||||
}
|
||||
|
||||
// check if char is within a reduced ascii range
|
||||
// valid for escaping (copied from Ruby Sass)
|
||||
bool is_escapable_character(char chr)
|
||||
{
|
||||
unsigned int cmp = unsigned(chr);
|
||||
return cmp > 31 && cmp < 127;
|
||||
}
|
||||
|
||||
// Match word character (look ahead)
|
||||
bool is_character(char chr)
|
||||
{
|
||||
// valid alpha, numeric or unicode char (plus hyphen)
|
||||
return Util::ascii_isalnum(static_cast<unsigned char>(chr)) ||
|
||||
!Util::ascii_isascii(static_cast<unsigned char>(chr)) ||
|
||||
chr == '-';
|
||||
}
|
||||
|
||||
//####################################
|
||||
// BASIC CLASS MATCHERS
|
||||
//####################################
|
||||
|
||||
// create matchers that advance the position
|
||||
const char* space(const char* src) { return Util::ascii_isspace(static_cast<unsigned char>(*src)) ? src + 1 : nullptr; }
|
||||
const char* alpha(const char* src) { return Util::ascii_isalpha(static_cast<unsigned char>(*src)) ? src + 1 : nullptr; }
|
||||
const char* nonascii(const char* src) { return Util::ascii_isascii(static_cast<unsigned char>(*src)) ? nullptr : src + 1; }
|
||||
const char* digit(const char* src) { return Util::ascii_isdigit(static_cast<unsigned char>(*src)) ? src + 1 : nullptr; }
|
||||
const char* xdigit(const char* src) { return Util::ascii_isxdigit(static_cast<unsigned char>(*src)) ? src + 1 : nullptr; }
|
||||
const char* alnum(const char* src) { return Util::ascii_isalnum(static_cast<unsigned char>(*src)) ? src + 1 : nullptr; }
|
||||
const char* hyphen(const char* src) { return *src == '-' ? src + 1 : 0; }
|
||||
const char* uri_character(const char* src) { return is_uri_character(*src) ? src + 1 : 0; }
|
||||
const char* escapable_character(const char* src) { return is_escapable_character(*src) ? src + 1 : 0; }
|
||||
|
||||
// Match multiple ctype characters.
|
||||
const char* spaces(const char* src) { return one_plus<space>(src); }
|
||||
const char* digits(const char* src) { return one_plus<digit>(src); }
|
||||
const char* hyphens(const char* src) { return one_plus<hyphen>(src); }
|
||||
|
||||
// Whitespace handling.
|
||||
const char* no_spaces(const char* src) { return negate< space >(src); }
|
||||
const char* optional_spaces(const char* src) { return zero_plus< space >(src); }
|
||||
|
||||
// Match any single character.
|
||||
const char* any_char(const char* src) { return *src ? src + 1 : src; }
|
||||
|
||||
// Match word boundary (zero-width lookahead).
|
||||
const char* word_boundary(const char* src) { return is_character(*src) || *src == '#' ? 0 : src; }
|
||||
|
||||
// Match linefeed /(?:\n|\r\n?|\f)/
|
||||
const char* re_linebreak(const char* src)
|
||||
{
|
||||
// end of file or unix linefeed return here
|
||||
if (*src == 0) return src;
|
||||
// end of file or unix linefeed return here
|
||||
if (*src == '\n' || *src == '\f') return src + 1;
|
||||
// a carriage return may optionally be followed by a linefeed
|
||||
if (*src == '\r') return *(src + 1) == '\n' ? src + 2 : src + 1;
|
||||
// no linefeed
|
||||
return 0;
|
||||
}
|
||||
|
||||
// Assert string boundaries (/\Z|\z|\A/)
|
||||
// This is a zero-width positive lookahead
|
||||
const char* end_of_line(const char* src)
|
||||
{
|
||||
// end of file or unix linefeed return here
|
||||
return *src == 0 || *src == '\n' || *src == '\r' || *src == '\f' ? src : 0;
|
||||
}
|
||||
|
||||
// Assert end_of_file boundary (/\z/)
|
||||
// This is a zero-width positive lookahead
|
||||
const char* end_of_file(const char* src)
|
||||
{
|
||||
// end of file or unix linefeed return here
|
||||
return *src == 0 ? src : 0;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
304
vendor/bundle/ruby/2.6.0/gems/sassc-2.4.0/ext/libsass/src/lexer.hpp
vendored
Normal file
304
vendor/bundle/ruby/2.6.0/gems/sassc-2.4.0/ext/libsass/src/lexer.hpp
vendored
Normal file
@@ -0,0 +1,304 @@
|
||||
#ifndef SASS_LEXER_H
|
||||
#define SASS_LEXER_H
|
||||
|
||||
#include <cstring>
|
||||
|
||||
namespace Sass {
|
||||
namespace Prelexer {
|
||||
|
||||
//####################################
|
||||
// BASIC CHARACTER MATCHERS
|
||||
//####################################
|
||||
|
||||
// Match standard control chars
|
||||
const char* kwd_at(const char* src);
|
||||
const char* kwd_dot(const char* src);
|
||||
const char* kwd_comma(const char* src);
|
||||
const char* kwd_colon(const char* src);
|
||||
const char* kwd_star(const char* src);
|
||||
const char* kwd_plus(const char* src);
|
||||
const char* kwd_minus(const char* src);
|
||||
const char* kwd_slash(const char* src);
|
||||
|
||||
//####################################
|
||||
// BASIC CLASS MATCHERS
|
||||
//####################################
|
||||
|
||||
// Matches ASCII digits, +, and -.
|
||||
bool is_number(char src);
|
||||
|
||||
bool is_uri_character(char src);
|
||||
bool escapable_character(char src);
|
||||
|
||||
// Match a single ctype predicate.
|
||||
const char* space(const char* src);
|
||||
const char* alpha(const char* src);
|
||||
const char* digit(const char* src);
|
||||
const char* xdigit(const char* src);
|
||||
const char* alnum(const char* src);
|
||||
const char* hyphen(const char* src);
|
||||
const char* nonascii(const char* src);
|
||||
const char* uri_character(const char* src);
|
||||
const char* escapable_character(const char* src);
|
||||
|
||||
// Match multiple ctype characters.
|
||||
const char* spaces(const char* src);
|
||||
const char* digits(const char* src);
|
||||
const char* hyphens(const char* src);
|
||||
|
||||
// Whitespace handling.
|
||||
const char* no_spaces(const char* src);
|
||||
const char* optional_spaces(const char* src);
|
||||
|
||||
// Match any single character (/./).
|
||||
const char* any_char(const char* src);
|
||||
|
||||
// Assert word boundary (/\b/)
|
||||
// Is a zero-width positive lookaheads
|
||||
const char* word_boundary(const char* src);
|
||||
|
||||
// Match a single linebreak (/(?:\n|\r\n?)/).
|
||||
const char* re_linebreak(const char* src);
|
||||
|
||||
// Assert string boundaries (/\Z|\z|\A/)
|
||||
// There are zero-width positive lookaheads
|
||||
const char* end_of_line(const char* src);
|
||||
|
||||
// Assert end_of_file boundary (/\z/)
|
||||
const char* end_of_file(const char* src);
|
||||
// const char* start_of_string(const char* src);
|
||||
|
||||
// Type definition for prelexer functions
|
||||
typedef const char* (*prelexer)(const char*);
|
||||
|
||||
//####################################
|
||||
// BASIC "REGEX" CONSTRUCTORS
|
||||
//####################################
|
||||
|
||||
// Match a single character literal.
|
||||
// Regex equivalent: /(?:x)/
|
||||
template <char chr>
|
||||
const char* exactly(const char* src) {
|
||||
return *src == chr ? src + 1 : 0;
|
||||
}
|
||||
|
||||
// Match the full string literal.
|
||||
// Regex equivalent: /(?:literal)/
|
||||
template <const char* str>
|
||||
const char* exactly(const char* src) {
|
||||
if (str == NULL) return 0;
|
||||
const char* pre = str;
|
||||
if (src == NULL) return 0;
|
||||
// there is a small chance that the search string
|
||||
// is longer than the rest of the string to look at
|
||||
while (*pre && *src == *pre) {
|
||||
++src, ++pre;
|
||||
}
|
||||
// did the matcher finish?
|
||||
return *pre == 0 ? src : 0;
|
||||
}
|
||||
|
||||
|
||||
// Match a single character literal.
|
||||
// Regex equivalent: /(?:x)/i
|
||||
// only define lower case alpha chars
|
||||
template <char chr>
|
||||
const char* insensitive(const char* src) {
|
||||
return *src == chr || *src+32 == chr ? src + 1 : 0;
|
||||
}
|
||||
|
||||
// Match the full string literal.
|
||||
// Regex equivalent: /(?:literal)/i
|
||||
// only define lower case alpha chars
|
||||
template <const char* str>
|
||||
const char* insensitive(const char* src) {
|
||||
if (str == NULL) return 0;
|
||||
const char* pre = str;
|
||||
if (src == NULL) return 0;
|
||||
// there is a small chance that the search string
|
||||
// is longer than the rest of the string to look at
|
||||
while (*pre && (*src == *pre || *src+32 == *pre)) {
|
||||
++src, ++pre;
|
||||
}
|
||||
// did the matcher finish?
|
||||
return *pre == 0 ? src : 0;
|
||||
}
|
||||
|
||||
// Match for members of char class.
|
||||
// Regex equivalent: /[axy]/
|
||||
template <const char* char_class>
|
||||
const char* class_char(const char* src) {
|
||||
const char* cc = char_class;
|
||||
while (*cc && *src != *cc) ++cc;
|
||||
return *cc ? src + 1 : 0;
|
||||
}
|
||||
|
||||
// Match for members of char class.
|
||||
// Regex equivalent: /[axy]+/
|
||||
template <const char* char_class>
|
||||
const char* class_chars(const char* src) {
|
||||
const char* p = src;
|
||||
while (class_char<char_class>(p)) ++p;
|
||||
return p == src ? 0 : p;
|
||||
}
|
||||
|
||||
// Match for members of char class.
|
||||
// Regex equivalent: /[^axy]/
|
||||
template <const char* neg_char_class>
|
||||
const char* neg_class_char(const char* src) {
|
||||
if (*src == 0) return 0;
|
||||
const char* cc = neg_char_class;
|
||||
while (*cc && *src != *cc) ++cc;
|
||||
return *cc ? 0 : src + 1;
|
||||
}
|
||||
|
||||
// Match for members of char class.
|
||||
// Regex equivalent: /[^axy]+/
|
||||
template <const char* neg_char_class>
|
||||
const char* neg_class_chars(const char* src) {
|
||||
const char* p = src;
|
||||
while (neg_class_char<neg_char_class>(p)) ++p;
|
||||
return p == src ? 0 : p;
|
||||
}
|
||||
|
||||
// Match all except the supplied one.
|
||||
// Regex equivalent: /[^x]/
|
||||
template <const char chr>
|
||||
const char* any_char_but(const char* src) {
|
||||
return (*src && *src != chr) ? src + 1 : 0;
|
||||
}
|
||||
|
||||
// Succeeds if the matcher fails.
|
||||
// Aka. zero-width negative lookahead.
|
||||
// Regex equivalent: /(?!literal)/
|
||||
template <prelexer mx>
|
||||
const char* negate(const char* src) {
|
||||
return mx(src) ? 0 : src;
|
||||
}
|
||||
|
||||
// Succeeds if the matcher succeeds.
|
||||
// Aka. zero-width positive lookahead.
|
||||
// Regex equivalent: /(?=literal)/
|
||||
// just hangs around until we need it
|
||||
template <prelexer mx>
|
||||
const char* lookahead(const char* src) {
|
||||
return mx(src) ? src : 0;
|
||||
}
|
||||
|
||||
// Tries supplied matchers in order.
|
||||
// Succeeds if one of them succeeds.
|
||||
// Regex equivalent: /(?:FOO|BAR)/
|
||||
template <const prelexer mx>
|
||||
const char* alternatives(const char* src) {
|
||||
const char* rslt;
|
||||
if ((rslt = mx(src))) return rslt;
|
||||
return 0;
|
||||
}
|
||||
template <const prelexer mx1, const prelexer mx2, const prelexer... mxs>
|
||||
const char* alternatives(const char* src) {
|
||||
const char* rslt;
|
||||
if ((rslt = mx1(src))) return rslt;
|
||||
return alternatives<mx2, mxs...>(src);
|
||||
}
|
||||
|
||||
// Tries supplied matchers in order.
|
||||
// Succeeds if all of them succeeds.
|
||||
// Regex equivalent: /(?:FOO)(?:BAR)/
|
||||
template <const prelexer mx1>
|
||||
const char* sequence(const char* src) {
|
||||
const char* rslt = src;
|
||||
if (!(rslt = mx1(rslt))) return 0;
|
||||
return rslt;
|
||||
}
|
||||
template <const prelexer mx1, const prelexer mx2, const prelexer... mxs>
|
||||
const char* sequence(const char* src) {
|
||||
const char* rslt = src;
|
||||
if (!(rslt = mx1(rslt))) return 0;
|
||||
return sequence<mx2, mxs...>(rslt);
|
||||
}
|
||||
|
||||
|
||||
// Match a pattern or not. Always succeeds.
|
||||
// Regex equivalent: /(?:literal)?/
|
||||
template <prelexer mx>
|
||||
const char* optional(const char* src) {
|
||||
const char* p = mx(src);
|
||||
return p ? p : src;
|
||||
}
|
||||
|
||||
// Match zero or more of the patterns.
|
||||
// Regex equivalent: /(?:literal)*/
|
||||
template <prelexer mx>
|
||||
const char* zero_plus(const char* src) {
|
||||
const char* p = mx(src);
|
||||
while (p) src = p, p = mx(src);
|
||||
return src;
|
||||
}
|
||||
|
||||
// Match one or more of the patterns.
|
||||
// Regex equivalent: /(?:literal)+/
|
||||
template <prelexer mx>
|
||||
const char* one_plus(const char* src) {
|
||||
const char* p = mx(src);
|
||||
if (!p) return 0;
|
||||
while (p) src = p, p = mx(src);
|
||||
return src;
|
||||
}
|
||||
|
||||
// Match mx non-greedy until delimiter.
|
||||
// Other prelexers are greedy by default.
|
||||
// Regex equivalent: /(?:$mx)*?(?=$delim)\b/
|
||||
template <prelexer mx, prelexer delim>
|
||||
const char* non_greedy(const char* src) {
|
||||
while (!delim(src)) {
|
||||
const char* p = mx(src);
|
||||
if (p == src) return 0;
|
||||
if (p == 0) return 0;
|
||||
src = p;
|
||||
}
|
||||
return src;
|
||||
}
|
||||
|
||||
//####################################
|
||||
// ADVANCED "REGEX" CONSTRUCTORS
|
||||
//####################################
|
||||
|
||||
// Match with word boundary rule.
|
||||
// Regex equivalent: /(?:$mx)\b/i
|
||||
template <const char* str>
|
||||
const char* keyword(const char* src) {
|
||||
return sequence <
|
||||
insensitive < str >,
|
||||
word_boundary
|
||||
>(src);
|
||||
}
|
||||
|
||||
// Match with word boundary rule.
|
||||
// Regex equivalent: /(?:$mx)\b/
|
||||
template <const char* str>
|
||||
const char* word(const char* src) {
|
||||
return sequence <
|
||||
exactly < str >,
|
||||
word_boundary
|
||||
>(src);
|
||||
}
|
||||
|
||||
template <char chr>
|
||||
const char* loosely(const char* src) {
|
||||
return sequence <
|
||||
optional_spaces,
|
||||
exactly < chr >
|
||||
>(src);
|
||||
}
|
||||
template <const char* str>
|
||||
const char* loosely(const char* src) {
|
||||
return sequence <
|
||||
optional_spaces,
|
||||
exactly < str >
|
||||
>(src);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
70
vendor/bundle/ruby/2.6.0/gems/sassc-2.4.0/ext/libsass/src/listize.cpp
vendored
Normal file
70
vendor/bundle/ruby/2.6.0/gems/sassc-2.4.0/ext/libsass/src/listize.cpp
vendored
Normal file
@@ -0,0 +1,70 @@
|
||||
// sass.hpp must go before all system headers to get the
|
||||
// __EXTENSIONS__ fix on Solaris.
|
||||
#include "sass.hpp"
|
||||
|
||||
#include <iostream>
|
||||
#include <typeinfo>
|
||||
#include <string>
|
||||
|
||||
#include "listize.hpp"
|
||||
#include "context.hpp"
|
||||
#include "backtrace.hpp"
|
||||
#include "error_handling.hpp"
|
||||
|
||||
namespace Sass {
|
||||
|
||||
Listize::Listize()
|
||||
{ }
|
||||
|
||||
Expression* Listize::perform(AST_Node* node)
|
||||
{
|
||||
Listize listize;
|
||||
return node->perform(&listize);
|
||||
}
|
||||
|
||||
Expression* Listize::operator()(SelectorList* sel)
|
||||
{
|
||||
List_Obj l = SASS_MEMORY_NEW(List, sel->pstate(), sel->length(), SASS_COMMA);
|
||||
l->from_selector(true);
|
||||
for (size_t i = 0, L = sel->length(); i < L; ++i) {
|
||||
if (!sel->at(i)) continue;
|
||||
l->append(sel->at(i)->perform(this));
|
||||
}
|
||||
if (l->length()) return l.detach();
|
||||
return SASS_MEMORY_NEW(Null, l->pstate());
|
||||
}
|
||||
|
||||
Expression* Listize::operator()(CompoundSelector* sel)
|
||||
{
|
||||
sass::string str;
|
||||
for (size_t i = 0, L = sel->length(); i < L; ++i) {
|
||||
Expression* e = (*sel)[i]->perform(this);
|
||||
if (e) str += e->to_string();
|
||||
}
|
||||
return SASS_MEMORY_NEW(String_Quoted, sel->pstate(), str);
|
||||
}
|
||||
|
||||
Expression* Listize::operator()(ComplexSelector* sel)
|
||||
{
|
||||
List_Obj l = SASS_MEMORY_NEW(List, sel->pstate());
|
||||
// ToDo: investigate what this does
|
||||
// Note: seems reated to parent ref
|
||||
l->from_selector(true);
|
||||
|
||||
for (auto component : sel->elements()) {
|
||||
if (CompoundSelectorObj compound = Cast<CompoundSelector>(component)) {
|
||||
if (!compound->empty()) {
|
||||
ExpressionObj hh = compound->perform(this);
|
||||
if (hh) l->append(hh);
|
||||
}
|
||||
}
|
||||
else if (component) {
|
||||
l->append(SASS_MEMORY_NEW(String_Quoted, component->pstate(), component->to_string()));
|
||||
}
|
||||
}
|
||||
|
||||
if (l->length() == 0) return 0;
|
||||
return l.detach();
|
||||
}
|
||||
|
||||
}
|
||||
37
vendor/bundle/ruby/2.6.0/gems/sassc-2.4.0/ext/libsass/src/listize.hpp
vendored
Normal file
37
vendor/bundle/ruby/2.6.0/gems/sassc-2.4.0/ext/libsass/src/listize.hpp
vendored
Normal file
@@ -0,0 +1,37 @@
|
||||
#ifndef SASS_LISTIZE_H
|
||||
#define SASS_LISTIZE_H
|
||||
|
||||
// sass.hpp must go before all system headers to get the
|
||||
// __EXTENSIONS__ fix on Solaris.
|
||||
#include "sass.hpp"
|
||||
|
||||
#include "ast_fwd_decl.hpp"
|
||||
#include "operation.hpp"
|
||||
|
||||
namespace Sass {
|
||||
|
||||
struct Backtrace;
|
||||
|
||||
class Listize : public Operation_CRTP<Expression*, Listize> {
|
||||
|
||||
public:
|
||||
|
||||
static Expression* perform(AST_Node* node);
|
||||
|
||||
public:
|
||||
Listize();
|
||||
~Listize() { }
|
||||
|
||||
Expression* operator()(SelectorList*);
|
||||
Expression* operator()(ComplexSelector*);
|
||||
Expression* operator()(CompoundSelector*);
|
||||
|
||||
// generic fallback
|
||||
template <typename U>
|
||||
Expression* fallback(U x)
|
||||
{ return Cast<Expression>(x); }
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
19
vendor/bundle/ruby/2.6.0/gems/sassc-2.4.0/ext/libsass/src/mapping.hpp
vendored
Normal file
19
vendor/bundle/ruby/2.6.0/gems/sassc-2.4.0/ext/libsass/src/mapping.hpp
vendored
Normal file
@@ -0,0 +1,19 @@
|
||||
#ifndef SASS_MAPPING_H
|
||||
#define SASS_MAPPING_H
|
||||
|
||||
#include "position.hpp"
|
||||
#include "backtrace.hpp"
|
||||
|
||||
namespace Sass {
|
||||
|
||||
struct Mapping {
|
||||
Position original_position;
|
||||
Position generated_position;
|
||||
|
||||
Mapping(const Position& original_position, const Position& generated_position)
|
||||
: original_position(original_position), generated_position(generated_position) { }
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
12
vendor/bundle/ruby/2.6.0/gems/sassc-2.4.0/ext/libsass/src/memory.hpp
vendored
Normal file
12
vendor/bundle/ruby/2.6.0/gems/sassc-2.4.0/ext/libsass/src/memory.hpp
vendored
Normal file
@@ -0,0 +1,12 @@
|
||||
#ifndef SASS_MEMORY_H
|
||||
#define SASS_MEMORY_H
|
||||
|
||||
#include "settings.hpp"
|
||||
|
||||
// Include memory headers
|
||||
#include "memory/config.hpp"
|
||||
#include "memory/allocator.hpp"
|
||||
#include "memory/shared_ptr.hpp"
|
||||
#include "memory/memory_pool.hpp"
|
||||
|
||||
#endif
|
||||
48
vendor/bundle/ruby/2.6.0/gems/sassc-2.4.0/ext/libsass/src/memory/allocator.cpp
vendored
Normal file
48
vendor/bundle/ruby/2.6.0/gems/sassc-2.4.0/ext/libsass/src/memory/allocator.cpp
vendored
Normal file
@@ -0,0 +1,48 @@
|
||||
#include "../sass.hpp"
|
||||
#include "allocator.hpp"
|
||||
#include "memory_pool.hpp"
|
||||
|
||||
#if defined (_MSC_VER) // Visual studio
|
||||
#define thread_local __declspec( thread )
|
||||
#elif defined (__GCC__) // GCC
|
||||
#define thread_local __thread
|
||||
#endif
|
||||
|
||||
namespace Sass {
|
||||
|
||||
#ifdef SASS_CUSTOM_ALLOCATOR
|
||||
|
||||
// Only use PODs for thread_local
|
||||
// Objects get unpredictable init order
|
||||
static thread_local MemoryPool* pool;
|
||||
static thread_local size_t allocations;
|
||||
|
||||
void* allocateMem(size_t size)
|
||||
{
|
||||
if (pool == nullptr) {
|
||||
pool = new MemoryPool();
|
||||
}
|
||||
allocations++;
|
||||
return pool->allocate(size);
|
||||
}
|
||||
|
||||
void deallocateMem(void* ptr, size_t size)
|
||||
{
|
||||
|
||||
// It seems thread_local variable might be discharged!?
|
||||
// But the destructors of e.g. static strings is still
|
||||
// called, although their memory was discharged too.
|
||||
// Fine with me as long as address sanitizer is happy.
|
||||
if (pool == nullptr || allocations == 0) { return; }
|
||||
|
||||
pool->deallocate(ptr);
|
||||
if (--allocations == 0) {
|
||||
delete pool;
|
||||
pool = nullptr;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
}
|
||||
138
vendor/bundle/ruby/2.6.0/gems/sassc-2.4.0/ext/libsass/src/memory/allocator.hpp
vendored
Normal file
138
vendor/bundle/ruby/2.6.0/gems/sassc-2.4.0/ext/libsass/src/memory/allocator.hpp
vendored
Normal file
@@ -0,0 +1,138 @@
|
||||
#ifndef SASS_ALLOCATOR_H
|
||||
#define SASS_ALLOCATOR_H
|
||||
|
||||
#include "config.hpp"
|
||||
#include "../settings.hpp"
|
||||
#include "../MurmurHash2.hpp"
|
||||
|
||||
#include <vector>
|
||||
#include <limits>
|
||||
#include <iostream>
|
||||
#include <algorithm>
|
||||
#include <functional>
|
||||
|
||||
namespace Sass {
|
||||
|
||||
#ifndef SASS_CUSTOM_ALLOCATOR
|
||||
|
||||
template <typename T> using Allocator = std::allocator<T>;
|
||||
|
||||
#else
|
||||
|
||||
void* allocateMem(size_t size);
|
||||
|
||||
void deallocateMem(void* ptr, size_t size = 1);
|
||||
|
||||
template<typename T>
|
||||
class Allocator
|
||||
{
|
||||
public:
|
||||
|
||||
// Allocator traits
|
||||
typedef T type;
|
||||
typedef type value_type;
|
||||
typedef value_type* pointer;
|
||||
typedef value_type const* const_pointer;
|
||||
typedef value_type& reference;
|
||||
typedef value_type const& const_reference;
|
||||
typedef std::size_t size_type;
|
||||
typedef std::ptrdiff_t difference_type;
|
||||
|
||||
template<typename U>
|
||||
struct rebind
|
||||
{
|
||||
typedef Allocator<U> other;
|
||||
};
|
||||
|
||||
// Constructor
|
||||
Allocator(void) {}
|
||||
|
||||
// Copy Constructor
|
||||
template<typename U>
|
||||
Allocator(Allocator<U> const&)
|
||||
{}
|
||||
|
||||
// allocate but don't initialize count of elements of type T
|
||||
pointer allocate(size_type count, const_pointer /* hint */ = 0)
|
||||
{
|
||||
return (pointer)(Sass::allocateMem(count * sizeof(T)));
|
||||
}
|
||||
|
||||
// deallocate storage ptr of deleted elements
|
||||
void deallocate(pointer ptr, size_type count)
|
||||
{
|
||||
Sass::deallocateMem(ptr, count);
|
||||
}
|
||||
|
||||
// return maximum number of elements that can be allocated
|
||||
size_type max_size() const throw()
|
||||
{
|
||||
return std::numeric_limits<size_type>::max() / sizeof(T);
|
||||
}
|
||||
|
||||
// Address of object
|
||||
type* address(type& obj) const { return &obj; }
|
||||
type const* address(type const& obj) const { return &obj; }
|
||||
|
||||
// Construct object
|
||||
void construct(type* ptr, type const& ref) const
|
||||
{
|
||||
// In-place copy construct
|
||||
new(ptr) type(ref);
|
||||
}
|
||||
|
||||
// Destroy object
|
||||
void destroy(type* ptr) const
|
||||
{
|
||||
// Call destructor
|
||||
ptr->~type();
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
template<typename T, typename U>
|
||||
bool operator==(Allocator<T> const& left,
|
||||
Allocator<U> const& right)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
template<typename T, typename U>
|
||||
bool operator!=(Allocator<T> const& left,
|
||||
Allocator<U> const& right)
|
||||
{
|
||||
return !(left == right);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
namespace sass {
|
||||
template <typename T> using vector = std::vector<T, Sass::Allocator<T>>;
|
||||
using string = std::basic_string<char, std::char_traits<char>, Sass::Allocator<char>>;
|
||||
using sstream = std::basic_stringstream<char, std::char_traits<char>, Sass::Allocator<char>>;
|
||||
using ostream = std::basic_ostringstream<char, std::char_traits<char>, Sass::Allocator<char>>;
|
||||
using istream = std::basic_istringstream<char, std::char_traits<char>, Sass::Allocator<char>>;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
#ifdef SASS_CUSTOM_ALLOCATOR
|
||||
|
||||
namespace std {
|
||||
// Only GCC seems to need this specialization!?
|
||||
template <> struct hash<Sass::sass::string> {
|
||||
public:
|
||||
inline size_t operator()(
|
||||
const Sass::sass::string& name) const
|
||||
{
|
||||
return MurmurHash2(
|
||||
(void*)name.c_str(),
|
||||
(int)name.size(),
|
||||
0x73617373);
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
#endif
|
||||
20
vendor/bundle/ruby/2.6.0/gems/sassc-2.4.0/ext/libsass/src/memory/config.hpp
vendored
Normal file
20
vendor/bundle/ruby/2.6.0/gems/sassc-2.4.0/ext/libsass/src/memory/config.hpp
vendored
Normal file
@@ -0,0 +1,20 @@
|
||||
#ifndef SASS_MEMORY_CONFIG_H
|
||||
#define SASS_MEMORY_CONFIG_H
|
||||
|
||||
// Define memory alignment requirements
|
||||
#define SASS_MEM_ALIGN sizeof(unsigned int)
|
||||
|
||||
// Minimal alignment for memory fragments. Must be a multiple
|
||||
// of `SASS_MEM_ALIGN` and should not be too big (maybe 1 or 2)
|
||||
#define SassAllocatorHeadSize sizeof(unsigned int)
|
||||
|
||||
// The number of bytes we use for our book-keeping before every
|
||||
// memory fragment. Needed to know to which bucket we belongs on
|
||||
// deallocations, or if it should go directly to the `free` call.
|
||||
#define SassAllocatorBookSize sizeof(unsigned int)
|
||||
|
||||
// Bytes reserve for book-keeping on the arenas
|
||||
// Currently unused and for later optimization
|
||||
#define SassAllocatorArenaHeadSize 0
|
||||
|
||||
#endif
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user