sassc 1.11.4 → 1.12.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +5 -5
- data/.travis.yml +2 -2
- data/CODE_OF_CONDUCT.md +10 -0
- data/README.md +4 -1
- data/ext/libsass/.editorconfig +1 -1
- data/ext/libsass/.github/CONTRIBUTING.md +7 -7
- data/ext/libsass/.github/ISSUE_TEMPLATE.md +31 -6
- data/ext/libsass/.gitignore +3 -0
- data/ext/libsass/.travis.yml +37 -18
- data/ext/libsass/GNUmakefile.am +23 -37
- data/ext/libsass/Makefile +10 -6
- data/ext/libsass/Makefile.conf +3 -0
- data/ext/libsass/Readme.md +68 -63
- data/ext/libsass/appveyor.yml +7 -3
- data/ext/libsass/configure.ac +10 -14
- data/ext/libsass/docs/api-context-internal.md +29 -21
- data/ext/libsass/docs/api-context.md +26 -6
- data/ext/libsass/docs/api-doc.md +49 -16
- data/ext/libsass/docs/api-function-example.md +1 -1
- data/ext/libsass/docs/api-function.md +31 -7
- data/ext/libsass/docs/api-importer.md +19 -19
- data/ext/libsass/docs/api-value.md +4 -2
- data/ext/libsass/docs/build-on-windows.md +4 -4
- data/ext/libsass/docs/build-with-mingw.md +3 -3
- data/ext/libsass/docs/build.md +9 -9
- data/ext/libsass/docs/custom-functions-internal.md +10 -8
- data/ext/libsass/docs/implementations.md +20 -8
- data/ext/libsass/docs/unicode.md +16 -10
- data/ext/libsass/include/sass/base.h +0 -3
- data/ext/libsass/include/sass/context.h +20 -2
- data/ext/libsass/include/sass/functions.h +31 -0
- data/ext/libsass/include/sass/values.h +3 -1
- data/ext/libsass/include/sass/version.h +1 -1
- data/ext/libsass/include/sass/version.h.in +1 -1
- data/ext/libsass/include/sass2scss.h +1 -1
- data/ext/libsass/res/resource.rc +6 -6
- data/ext/libsass/script/ci-build-libsass +10 -5
- data/ext/libsass/script/ci-build-plugin +62 -0
- data/ext/libsass/script/ci-install-compiler +1 -1
- data/ext/libsass/script/ci-install-deps +4 -7
- data/ext/libsass/script/ci-report-coverage +13 -3
- data/ext/libsass/script/tap-driver +1 -1
- data/ext/libsass/script/tap-runner +1 -1
- data/ext/libsass/src/GNUmakefile.am +1 -1
- data/ext/libsass/src/ast.cpp +537 -762
- data/ext/libsass/src/ast.hpp +377 -419
- data/ext/libsass/src/ast_def_macros.hpp +26 -1
- data/ext/libsass/src/ast_fwd_decl.cpp +29 -0
- data/ext/libsass/src/ast_fwd_decl.hpp +94 -21
- data/ext/libsass/src/b64/encode.h +3 -1
- data/ext/libsass/src/backtrace.cpp +46 -0
- data/ext/libsass/src/backtrace.hpp +7 -54
- data/ext/libsass/src/bind.cpp +72 -50
- data/ext/libsass/src/bind.hpp +0 -1
- data/ext/libsass/src/cencode.c +6 -0
- data/ext/libsass/src/check_nesting.cpp +157 -135
- data/ext/libsass/src/check_nesting.hpp +11 -10
- data/ext/libsass/src/color_maps.cpp +10 -6
- data/ext/libsass/src/color_maps.hpp +6 -8
- data/ext/libsass/src/constants.cpp +4 -3
- data/ext/libsass/src/constants.hpp +4 -3
- data/ext/libsass/src/context.cpp +110 -47
- data/ext/libsass/src/context.hpp +11 -1
- data/ext/libsass/src/cssize.cpp +105 -94
- data/ext/libsass/src/cssize.hpp +4 -5
- data/ext/libsass/src/debugger.hpp +247 -244
- data/ext/libsass/src/emitter.cpp +30 -6
- data/ext/libsass/src/emitter.hpp +7 -0
- data/ext/libsass/src/environment.cpp +67 -16
- data/ext/libsass/src/environment.hpp +28 -7
- data/ext/libsass/src/error_handling.cpp +92 -64
- data/ext/libsass/src/error_handling.hpp +64 -43
- data/ext/libsass/src/eval.cpp +494 -544
- data/ext/libsass/src/eval.hpp +17 -23
- data/ext/libsass/src/expand.cpp +182 -154
- data/ext/libsass/src/expand.hpp +4 -5
- data/ext/libsass/src/extend.cpp +299 -291
- data/ext/libsass/src/extend.hpp +46 -11
- data/ext/libsass/src/file.cpp +103 -36
- data/ext/libsass/src/file.hpp +21 -4
- data/ext/libsass/src/functions.cpp +561 -312
- data/ext/libsass/src/functions.hpp +8 -5
- data/ext/libsass/src/inspect.cpp +108 -53
- data/ext/libsass/src/inspect.hpp +5 -2
- data/ext/libsass/src/lexer.cpp +15 -7
- data/ext/libsass/src/lexer.hpp +13 -4
- data/ext/libsass/src/listize.cpp +3 -2
- data/ext/libsass/src/listize.hpp +0 -1
- data/ext/libsass/src/memory/SharedPtr.cpp +16 -18
- data/ext/libsass/src/memory/SharedPtr.hpp +47 -43
- data/ext/libsass/src/node.cpp +34 -38
- data/ext/libsass/src/node.hpp +6 -8
- data/ext/libsass/src/operation.hpp +2 -2
- data/ext/libsass/src/operators.cpp +240 -0
- data/ext/libsass/src/operators.hpp +30 -0
- data/ext/libsass/src/output.cpp +22 -20
- data/ext/libsass/src/parser.cpp +719 -358
- data/ext/libsass/src/parser.hpp +57 -22
- data/ext/libsass/src/plugins.cpp +28 -10
- data/ext/libsass/src/position.cpp +21 -3
- data/ext/libsass/src/position.hpp +2 -1
- data/ext/libsass/src/prelexer.cpp +104 -19
- data/ext/libsass/src/prelexer.hpp +10 -3
- data/ext/libsass/src/remove_placeholders.cpp +9 -10
- data/ext/libsass/src/remove_placeholders.hpp +1 -5
- data/ext/libsass/src/sass.cpp +62 -4
- data/ext/libsass/src/sass.hpp +5 -2
- data/ext/libsass/src/sass_context.cpp +96 -58
- data/ext/libsass/src/sass_context.hpp +7 -5
- data/ext/libsass/src/sass_functions.cpp +63 -1
- data/ext/libsass/src/sass_functions.hpp +19 -1
- data/ext/libsass/src/sass_util.cpp +3 -3
- data/ext/libsass/src/sass_util.hpp +4 -4
- data/ext/libsass/src/sass_values.cpp +42 -39
- data/ext/libsass/src/sass_values.hpp +2 -1
- data/ext/libsass/src/source_map.cpp +16 -18
- data/ext/libsass/src/subset_map.cpp +6 -8
- data/ext/libsass/src/subset_map.hpp +6 -6
- data/ext/libsass/src/to_c.cpp +2 -2
- data/ext/libsass/src/to_value.cpp +8 -3
- data/ext/libsass/src/to_value.hpp +1 -0
- data/ext/libsass/src/units.cpp +349 -45
- data/ext/libsass/src/units.hpp +39 -22
- data/ext/libsass/src/utf8/checked.h +7 -0
- data/ext/libsass/src/utf8/unchecked.h +7 -0
- data/ext/libsass/src/utf8_string.cpp +1 -1
- data/ext/libsass/src/util.cpp +139 -45
- data/ext/libsass/src/util.hpp +4 -7
- data/ext/libsass/src/values.cpp +15 -23
- data/ext/libsass/win/libsass.sln +13 -2
- data/ext/libsass/win/libsass.sln.DotSettings +9 -0
- data/ext/libsass/win/libsass.targets +3 -0
- data/ext/libsass/win/libsass.vcxproj.filters +9 -0
- data/lib/sassc/version.rb +1 -1
- data/sassc.gemspec +1 -1
- data/test/native_test.rb +1 -1
- metadata +11 -4
@@ -19,12 +19,21 @@ class LocalOption {
|
|
19
19
|
this->orig = var;
|
20
20
|
*(this->var) = orig;
|
21
21
|
}
|
22
|
+
void reset()
|
23
|
+
{
|
24
|
+
*(this->var) = this->orig;
|
25
|
+
}
|
22
26
|
~LocalOption() {
|
23
27
|
*(this->var) = this->orig;
|
24
28
|
}
|
25
29
|
};
|
26
30
|
|
27
31
|
#define LOCAL_FLAG(name,opt) LocalOption<bool> flag_##name(name, opt)
|
32
|
+
#define LOCAL_COUNT(name,opt) LocalOption<size_t> cnt_##name(name, opt)
|
33
|
+
|
34
|
+
#define NESTING_GUARD(name) \
|
35
|
+
LocalOption<size_t> cnt_##name(name, name + 1); \
|
36
|
+
if (name > MAX_NESTING) throw Exception::NestingLimitError(pstate, traces); \
|
28
37
|
|
29
38
|
#define ATTACH_OPERATIONS()\
|
30
39
|
virtual void perform(Operation<void>* op) { (*op)(this); }\
|
@@ -44,7 +53,7 @@ public:\
|
|
44
53
|
type name(type name##__) { return name##_ = name##__; }\
|
45
54
|
private:
|
46
55
|
|
47
|
-
#define
|
56
|
+
#define HASH_PROPERTY(type, name)\
|
48
57
|
protected:\
|
49
58
|
type name##_;\
|
50
59
|
public:\
|
@@ -52,4 +61,20 @@ public:\
|
|
52
61
|
type name(type name##__) { hash_ = 0; return name##_ = name##__; }\
|
53
62
|
private:
|
54
63
|
|
64
|
+
#define ADD_CONSTREF(type, name) \
|
65
|
+
protected: \
|
66
|
+
type name##_; \
|
67
|
+
public: \
|
68
|
+
const type& name() const { return name##_; } \
|
69
|
+
void name(type name##__) { name##_ = name##__; } \
|
70
|
+
private:
|
71
|
+
|
72
|
+
#define HASH_CONSTREF(type, name) \
|
73
|
+
protected: \
|
74
|
+
type name##_; \
|
75
|
+
public: \
|
76
|
+
const type& name() const { return name##_; } \
|
77
|
+
void name(type name##__) { hash_ = 0; name##_ = name##__; } \
|
78
|
+
private:
|
79
|
+
|
55
80
|
#endif
|
@@ -0,0 +1,29 @@
|
|
1
|
+
#include "ast.hpp"
|
2
|
+
|
3
|
+
namespace Sass {
|
4
|
+
|
5
|
+
#define IMPLEMENT_BASE_CAST(T) \
|
6
|
+
template<> \
|
7
|
+
T* Cast(AST_Node* ptr) { \
|
8
|
+
return dynamic_cast<T*>(ptr); \
|
9
|
+
}; \
|
10
|
+
\
|
11
|
+
template<> \
|
12
|
+
const T* Cast(const AST_Node* ptr) { \
|
13
|
+
return dynamic_cast<const T*>(ptr); \
|
14
|
+
}; \
|
15
|
+
|
16
|
+
IMPLEMENT_BASE_CAST(AST_Node)
|
17
|
+
IMPLEMENT_BASE_CAST(Expression)
|
18
|
+
IMPLEMENT_BASE_CAST(Statement)
|
19
|
+
IMPLEMENT_BASE_CAST(Has_Block)
|
20
|
+
IMPLEMENT_BASE_CAST(PreValue)
|
21
|
+
IMPLEMENT_BASE_CAST(Value)
|
22
|
+
IMPLEMENT_BASE_CAST(List)
|
23
|
+
IMPLEMENT_BASE_CAST(String)
|
24
|
+
IMPLEMENT_BASE_CAST(String_Constant)
|
25
|
+
IMPLEMENT_BASE_CAST(Supports_Condition)
|
26
|
+
IMPLEMENT_BASE_CAST(Selector)
|
27
|
+
IMPLEMENT_BASE_CAST(Simple_Selector)
|
28
|
+
|
29
|
+
}
|
@@ -1,12 +1,17 @@
|
|
1
1
|
#ifndef SASS_AST_FWD_DECL_H
|
2
2
|
#define SASS_AST_FWD_DECL_H
|
3
3
|
|
4
|
+
#include <map>
|
5
|
+
#include <set>
|
6
|
+
#include <deque>
|
4
7
|
#include <vector>
|
8
|
+
#include <typeinfo>
|
5
9
|
#include <iostream>
|
6
10
|
#include <algorithm>
|
7
11
|
#include <unordered_map>
|
8
12
|
#include <unordered_set>
|
9
13
|
#include "memory/SharedPtr.hpp"
|
14
|
+
#include "sass/functions.h"
|
10
15
|
|
11
16
|
/////////////////////////////////////////////
|
12
17
|
// Forward declarations for the AST visitors.
|
@@ -128,6 +133,9 @@ namespace Sass {
|
|
128
133
|
class Map;
|
129
134
|
typedef Map* Map_Ptr;
|
130
135
|
typedef Map const* Map_Ptr_Const;
|
136
|
+
class Function;
|
137
|
+
typedef Function* Function_Ptr;
|
138
|
+
typedef Function const* Function_Ptr_Const;
|
131
139
|
|
132
140
|
class Mixin_Call;
|
133
141
|
typedef Mixin_Call* Mixin_Call_Ptr;
|
@@ -154,9 +162,6 @@ namespace Sass {
|
|
154
162
|
class Variable;
|
155
163
|
typedef Variable* Variable_Ptr;
|
156
164
|
typedef Variable const* Variable_Ptr_Const;
|
157
|
-
class Textual;
|
158
|
-
typedef Textual* Textual_Ptr;
|
159
|
-
typedef Textual const* Textual_Ptr_Const;
|
160
165
|
class Number;
|
161
166
|
typedef Number* Number_Ptr;
|
162
167
|
typedef Number const* Number_Ptr_Const;
|
@@ -310,6 +315,7 @@ namespace Sass {
|
|
310
315
|
IMPL_MEM_OBJ(Expression);
|
311
316
|
IMPL_MEM_OBJ(List);
|
312
317
|
IMPL_MEM_OBJ(Map);
|
318
|
+
IMPL_MEM_OBJ(Function);
|
313
319
|
IMPL_MEM_OBJ(Binary_Expression);
|
314
320
|
IMPL_MEM_OBJ(Unary_Expression);
|
315
321
|
IMPL_MEM_OBJ(Function_Call);
|
@@ -317,7 +323,6 @@ namespace Sass {
|
|
317
323
|
IMPL_MEM_OBJ(Custom_Warning);
|
318
324
|
IMPL_MEM_OBJ(Custom_Error);
|
319
325
|
IMPL_MEM_OBJ(Variable);
|
320
|
-
IMPL_MEM_OBJ(Textual);
|
321
326
|
IMPL_MEM_OBJ(Number);
|
322
327
|
IMPL_MEM_OBJ(Color);
|
323
328
|
IMPL_MEM_OBJ(Boolean);
|
@@ -353,37 +358,105 @@ namespace Sass {
|
|
353
358
|
IMPL_MEM_OBJ(Complex_Selector);
|
354
359
|
IMPL_MEM_OBJ(Selector_List);
|
355
360
|
|
361
|
+
// ###########################################################################
|
362
|
+
// Implement compare, order and hashing operations for AST Nodes
|
363
|
+
// ###########################################################################
|
356
364
|
|
357
|
-
struct
|
358
|
-
|
365
|
+
struct HashNodes {
|
366
|
+
template <class T>
|
367
|
+
size_t operator() (const T& ex) const {
|
368
|
+
return ex.isNull() ? 0 : ex->hash();
|
369
|
+
}
|
359
370
|
};
|
360
|
-
struct
|
361
|
-
|
371
|
+
struct OrderNodes {
|
372
|
+
template <class T>
|
373
|
+
bool operator() (const T& lhs, const T& rhs) const {
|
374
|
+
return !lhs.isNull() && !rhs.isNull() && *lhs < *rhs;
|
375
|
+
}
|
362
376
|
};
|
363
|
-
|
364
|
-
|
365
|
-
|
377
|
+
struct CompareNodes {
|
378
|
+
template <class T>
|
379
|
+
bool operator() (const T& lhs, const T& rhs) const {
|
380
|
+
// code around sass logic issue. 1px == 1 is true
|
381
|
+
// but both items are still different keys in maps
|
382
|
+
if (dynamic_cast<Number*>(lhs.ptr()))
|
383
|
+
if (dynamic_cast<Number*>(rhs.ptr()))
|
384
|
+
return lhs->hash() == rhs->hash();
|
385
|
+
return !lhs.isNull() && !rhs.isNull() && *lhs == *rhs;
|
386
|
+
}
|
366
387
|
};
|
367
388
|
|
368
|
-
|
369
|
-
|
370
|
-
|
389
|
+
// ###########################################################################
|
390
|
+
// some often used typedefs
|
391
|
+
// ###########################################################################
|
371
392
|
|
372
393
|
typedef std::unordered_map<
|
373
394
|
Expression_Obj, // key
|
374
395
|
Expression_Obj, // value
|
375
|
-
|
376
|
-
|
396
|
+
HashNodes, // hasher
|
397
|
+
CompareNodes // compare
|
377
398
|
> ExpressionMap;
|
378
399
|
typedef std::unordered_set<
|
379
400
|
Expression_Obj, // value
|
380
|
-
|
381
|
-
|
401
|
+
HashNodes, // hasher
|
402
|
+
CompareNodes // compare
|
382
403
|
> ExpressionSet;
|
383
404
|
|
384
|
-
typedef std::string
|
385
|
-
typedef std::vector<
|
386
|
-
|
405
|
+
typedef std::string SubSetMapKey;
|
406
|
+
typedef std::vector<std::string> SubSetMapKeys;
|
407
|
+
|
408
|
+
typedef std::pair<Complex_Selector_Obj, Compound_Selector_Obj> SubSetMapPair;
|
409
|
+
typedef std::pair<Compound_Selector_Obj, Complex_Selector_Obj> SubSetMapLookup;
|
410
|
+
typedef std::vector<SubSetMapPair> SubSetMapPairs;
|
411
|
+
typedef std::vector<SubSetMapLookup> SubSetMapLookups;
|
412
|
+
|
413
|
+
typedef std::pair<Complex_Selector_Obj, SubSetMapPairs> SubSetMapResult;
|
414
|
+
typedef std::vector<SubSetMapResult> SubSetMapResults;
|
415
|
+
|
416
|
+
typedef std::deque<Complex_Selector_Obj> ComplexSelectorDeque;
|
417
|
+
typedef std::set<Simple_Selector_Obj, OrderNodes> SimpleSelectorSet;
|
418
|
+
typedef std::set<Complex_Selector_Obj, OrderNodes> ComplexSelectorSet;
|
419
|
+
typedef std::set<Compound_Selector_Obj, OrderNodes> CompoundSelectorSet;
|
420
|
+
typedef std::unordered_set<Simple_Selector_Obj, HashNodes, CompareNodes> SimpleSelectorDict;
|
421
|
+
|
422
|
+
typedef std::vector<Sass_Import_Entry>* ImporterStack;
|
423
|
+
|
424
|
+
// only to switch implementations for testing
|
425
|
+
#define environment_map std::map
|
426
|
+
|
427
|
+
// ###########################################################################
|
428
|
+
// explicit type conversion functions
|
429
|
+
// ###########################################################################
|
430
|
+
|
431
|
+
template<class T>
|
432
|
+
T* Cast(AST_Node* ptr);
|
433
|
+
|
434
|
+
template<class T>
|
435
|
+
const T* Cast(const AST_Node* ptr);
|
436
|
+
|
437
|
+
// sometimes you know the class you want to cast to is final
|
438
|
+
// in this case a simple typeid check is faster and safe to use
|
439
|
+
|
440
|
+
#define DECLARE_BASE_CAST(T) \
|
441
|
+
template<> T* Cast(AST_Node* ptr); \
|
442
|
+
template<> const T* Cast(const AST_Node* ptr); \
|
443
|
+
|
444
|
+
// ###########################################################################
|
445
|
+
// implement specialization for final classes
|
446
|
+
// ###########################################################################
|
447
|
+
|
448
|
+
DECLARE_BASE_CAST(AST_Node)
|
449
|
+
DECLARE_BASE_CAST(Expression)
|
450
|
+
DECLARE_BASE_CAST(Statement)
|
451
|
+
DECLARE_BASE_CAST(Has_Block)
|
452
|
+
DECLARE_BASE_CAST(PreValue)
|
453
|
+
DECLARE_BASE_CAST(Value)
|
454
|
+
DECLARE_BASE_CAST(List)
|
455
|
+
DECLARE_BASE_CAST(String)
|
456
|
+
DECLARE_BASE_CAST(String_Constant)
|
457
|
+
DECLARE_BASE_CAST(Supports_Condition)
|
458
|
+
DECLARE_BASE_CAST(Selector)
|
459
|
+
DECLARE_BASE_CAST(Simple_Selector)
|
387
460
|
|
388
461
|
}
|
389
462
|
|
@@ -0,0 +1,46 @@
|
|
1
|
+
#include "backtrace.hpp"
|
2
|
+
|
3
|
+
namespace Sass {
|
4
|
+
|
5
|
+
const std::string traces_to_string(Backtraces traces, std::string indent) {
|
6
|
+
|
7
|
+
std::stringstream ss;
|
8
|
+
std::string cwd(File::get_cwd());
|
9
|
+
|
10
|
+
bool first = true;
|
11
|
+
size_t i_beg = traces.size() - 1;
|
12
|
+
size_t i_end = std::string::npos;
|
13
|
+
for (size_t i = i_beg; i != i_end; i --) {
|
14
|
+
|
15
|
+
const Backtrace& trace = traces[i];
|
16
|
+
|
17
|
+
// make path relative to the current directory
|
18
|
+
std::string rel_path(File::abs2rel(trace.pstate.path, cwd, cwd));
|
19
|
+
|
20
|
+
// skip functions on error cases (unsure why ruby sass does this)
|
21
|
+
// if (trace.caller.substr(0, 6) == ", in f") continue;
|
22
|
+
|
23
|
+
if (first) {
|
24
|
+
ss << indent;
|
25
|
+
ss << "on line ";
|
26
|
+
ss << trace.pstate.line + 1;
|
27
|
+
ss << " of " << rel_path;
|
28
|
+
// ss << trace.caller;
|
29
|
+
first = false;
|
30
|
+
} else {
|
31
|
+
ss << trace.caller;
|
32
|
+
ss << std::endl;
|
33
|
+
ss << indent;
|
34
|
+
ss << "from line ";
|
35
|
+
ss << trace.pstate.line + 1;
|
36
|
+
ss << " of " << rel_path;
|
37
|
+
}
|
38
|
+
|
39
|
+
}
|
40
|
+
|
41
|
+
ss << std::endl;
|
42
|
+
return ss.str();
|
43
|
+
|
44
|
+
}
|
45
|
+
|
46
|
+
};
|
@@ -1,75 +1,28 @@
|
|
1
1
|
#ifndef SASS_BACKTRACE_H
|
2
2
|
#define SASS_BACKTRACE_H
|
3
3
|
|
4
|
+
#include <vector>
|
4
5
|
#include <sstream>
|
5
|
-
|
6
6
|
#include "file.hpp"
|
7
7
|
#include "position.hpp"
|
8
8
|
|
9
9
|
namespace Sass {
|
10
10
|
|
11
|
-
|
12
11
|
struct Backtrace {
|
13
12
|
|
14
|
-
Backtrace* parent;
|
15
13
|
ParserState pstate;
|
16
|
-
std::string
|
14
|
+
std::string caller;
|
17
15
|
|
18
|
-
Backtrace(
|
19
|
-
:
|
20
|
-
pstate(pstate),
|
16
|
+
Backtrace(ParserState pstate, std::string c = "")
|
17
|
+
: pstate(pstate),
|
21
18
|
caller(c)
|
22
19
|
{ }
|
23
20
|
|
24
|
-
|
25
|
-
{
|
26
|
-
size_t i = -1;
|
27
|
-
std::stringstream ss;
|
28
|
-
std::string cwd(Sass::File::get_cwd());
|
29
|
-
Backtrace* this_point = this;
|
30
|
-
|
31
|
-
if (!warning) ss << std::endl << "Backtrace:";
|
32
|
-
// the first tracepoint (which is parent-less) is an empty placeholder
|
33
|
-
while (this_point->parent) {
|
34
|
-
|
35
|
-
// make path relative to the current directory
|
36
|
-
std::string rel_path(Sass::File::abs2rel(this_point->pstate.path, cwd, cwd));
|
37
|
-
|
38
|
-
if (warning) {
|
39
|
-
ss << std::endl
|
40
|
-
<< "\t"
|
41
|
-
<< (++i == 0 ? "on" : "from")
|
42
|
-
<< " line "
|
43
|
-
<< this_point->pstate.line + 1
|
44
|
-
<< " of "
|
45
|
-
<< rel_path;
|
46
|
-
} else {
|
47
|
-
ss << std::endl
|
48
|
-
<< "\t"
|
49
|
-
<< rel_path
|
50
|
-
<< ":"
|
51
|
-
<< this_point->pstate.line + 1
|
52
|
-
<< this_point->parent->caller;
|
53
|
-
}
|
54
|
-
|
55
|
-
this_point = this_point->parent;
|
56
|
-
}
|
57
|
-
|
58
|
-
return ss.str();
|
59
|
-
}
|
21
|
+
};
|
60
22
|
|
61
|
-
|
62
|
-
{
|
63
|
-
size_t d = 0;
|
64
|
-
Backtrace* p = parent;
|
65
|
-
while (p) {
|
66
|
-
++d;
|
67
|
-
p = p->parent;
|
68
|
-
}
|
69
|
-
return d-1;
|
70
|
-
}
|
23
|
+
typedef std::vector<Backtrace> Backtraces;
|
71
24
|
|
72
|
-
|
25
|
+
const std::string traces_to_string(Backtraces traces, std::string indent = "\t");
|
73
26
|
|
74
27
|
}
|
75
28
|
|
data/ext/libsass/src/bind.cpp
CHANGED
@@ -2,6 +2,7 @@
|
|
2
2
|
#include "bind.hpp"
|
3
3
|
#include "ast.hpp"
|
4
4
|
#include "context.hpp"
|
5
|
+
#include "expand.hpp"
|
5
6
|
#include "eval.hpp"
|
6
7
|
#include <map>
|
7
8
|
#include <iostream>
|
@@ -14,9 +15,11 @@ namespace Sass {
|
|
14
15
|
std::string callee(type + " " + name);
|
15
16
|
|
16
17
|
std::map<std::string, Parameter_Obj> param_map;
|
18
|
+
List_Obj varargs = SASS_MEMORY_NEW(List, as->pstate());
|
19
|
+
varargs->is_arglist(true); // enable keyword size handling
|
17
20
|
|
18
21
|
for (size_t i = 0, L = as->length(); i < L; ++i) {
|
19
|
-
if (auto str =
|
22
|
+
if (auto str = Cast<String_Quoted>((*as)[i]->value())) {
|
20
23
|
// force optional quotes (only if needed)
|
21
24
|
if (str->quote_mark()) {
|
22
25
|
str->quote_mark('*');
|
@@ -42,7 +45,7 @@ namespace Sass {
|
|
42
45
|
if (ip >= LP) {
|
43
46
|
// skip empty rest arguments
|
44
47
|
if (a->is_rest_argument()) {
|
45
|
-
if (List_Obj l =
|
48
|
+
if (List_Obj l = Cast<List>(a->value())) {
|
46
49
|
if (l->length() == 0) {
|
47
50
|
++ ia; continue;
|
48
51
|
}
|
@@ -51,7 +54,7 @@ namespace Sass {
|
|
51
54
|
std::stringstream msg;
|
52
55
|
msg << "wrong number of arguments (" << LA << " for " << LP << ")";
|
53
56
|
msg << " for `" << name << "'";
|
54
|
-
return error(msg.str(), as->pstate());
|
57
|
+
return error(msg.str(), as->pstate(), eval->exp.traces);
|
55
58
|
}
|
56
59
|
Parameter_Obj p = ps->at(ip);
|
57
60
|
|
@@ -61,7 +64,7 @@ namespace Sass {
|
|
61
64
|
if (a->is_rest_argument()) {
|
62
65
|
|
63
66
|
// We should always get a list for rest arguments
|
64
|
-
if (List_Obj rest =
|
67
|
+
if (List_Obj rest = Cast<List>(a->value())) {
|
65
68
|
// create a new list object for wrapped items
|
66
69
|
List_Ptr arglist = SASS_MEMORY_NEW(List,
|
67
70
|
p->pstate(),
|
@@ -70,12 +73,12 @@ namespace Sass {
|
|
70
73
|
true);
|
71
74
|
// wrap each item from list as an argument
|
72
75
|
for (Expression_Obj item : rest->elements()) {
|
73
|
-
if (Argument_Obj arg =
|
76
|
+
if (Argument_Obj arg = Cast<Argument>(item)) {
|
74
77
|
arglist->append(SASS_MEMORY_COPY(arg)); // copy
|
75
78
|
} else {
|
76
79
|
arglist->append(SASS_MEMORY_NEW(Argument,
|
77
80
|
item->pstate(),
|
78
|
-
|
81
|
+
item,
|
79
82
|
"",
|
80
83
|
false,
|
81
84
|
false));
|
@@ -93,15 +96,20 @@ namespace Sass {
|
|
93
96
|
// expand keyword arguments into their parameters
|
94
97
|
List_Ptr arglist = SASS_MEMORY_NEW(List, p->pstate(), 0, SASS_COMMA, true);
|
95
98
|
env->local_frame()[p->name()] = arglist;
|
96
|
-
Map_Obj argmap =
|
99
|
+
Map_Obj argmap = Cast<Map>(a->value());
|
97
100
|
for (auto key : argmap->keys()) {
|
98
|
-
|
99
|
-
|
100
|
-
|
101
|
-
|
102
|
-
|
103
|
-
|
104
|
-
|
101
|
+
if (String_Constant_Obj str = Cast<String_Constant>(key)) {
|
102
|
+
std::string param = unquote(str->value());
|
103
|
+
arglist->append(SASS_MEMORY_NEW(Argument,
|
104
|
+
key->pstate(),
|
105
|
+
argmap->at(key),
|
106
|
+
"$" + param,
|
107
|
+
false,
|
108
|
+
false));
|
109
|
+
} else {
|
110
|
+
eval->exp.traces.push_back(Backtrace(key->pstate()));
|
111
|
+
throw Exception::InvalidVarKwdType(key->pstate(), eval->exp.traces, key->inspect(), a);
|
112
|
+
}
|
105
113
|
}
|
106
114
|
|
107
115
|
} else {
|
@@ -117,25 +125,25 @@ namespace Sass {
|
|
117
125
|
// get and post inc
|
118
126
|
a = (*as)[ia++];
|
119
127
|
// maybe we have another list as argument
|
120
|
-
List_Obj ls =
|
128
|
+
List_Obj ls = Cast<List>(a->value());
|
121
129
|
// skip any list completely if empty
|
122
130
|
if (ls && ls->empty() && a->is_rest_argument()) continue;
|
123
131
|
|
124
132
|
Expression_Obj value = a->value();
|
125
|
-
if (Argument_Obj arg =
|
126
|
-
arglist->append(
|
133
|
+
if (Argument_Obj arg = Cast<Argument>(value)) {
|
134
|
+
arglist->append(arg);
|
127
135
|
}
|
128
136
|
// check if we have rest argument
|
129
137
|
else if (a->is_rest_argument()) {
|
130
138
|
// preserve the list separator from rest args
|
131
|
-
if (List_Obj rest =
|
139
|
+
if (List_Obj rest = Cast<List>(a->value())) {
|
132
140
|
arglist->separator(rest->separator());
|
133
141
|
|
134
|
-
for (size_t i = 0, L = rest->
|
135
|
-
Expression_Obj obj = rest->
|
142
|
+
for (size_t i = 0, L = rest->length(); i < L; ++i) {
|
143
|
+
Expression_Obj obj = rest->value_at_index(i);
|
136
144
|
arglist->append(SASS_MEMORY_NEW(Argument,
|
137
145
|
obj->pstate(),
|
138
|
-
|
146
|
+
obj,
|
139
147
|
"",
|
140
148
|
false,
|
141
149
|
false));
|
@@ -155,7 +163,7 @@ namespace Sass {
|
|
155
163
|
}
|
156
164
|
}
|
157
165
|
// assign new arglist to environment
|
158
|
-
env->local_frame()[p->name()] =
|
166
|
+
env->local_frame()[p->name()] = arglist;
|
159
167
|
}
|
160
168
|
// consumed parameter
|
161
169
|
++ip;
|
@@ -166,9 +174,16 @@ namespace Sass {
|
|
166
174
|
// If the current argument is the rest argument, extract a value for processing
|
167
175
|
else if (a->is_rest_argument()) {
|
168
176
|
// normal param and rest arg
|
169
|
-
List_Obj arglist =
|
177
|
+
List_Obj arglist = Cast<List>(a->value());
|
178
|
+
if (!arglist) {
|
179
|
+
if (Expression_Obj arg = Cast<Expression>(a->value())) {
|
180
|
+
arglist = SASS_MEMORY_NEW(List, a->pstate(), 1);
|
181
|
+
arglist->append(arg);
|
182
|
+
}
|
183
|
+
}
|
184
|
+
|
170
185
|
// empty rest arg - treat all args as default values
|
171
|
-
if (!arglist->length()) {
|
186
|
+
if (!arglist || !arglist->length()) {
|
172
187
|
break;
|
173
188
|
} else {
|
174
189
|
if (arglist->length() > LP - ip && !ps->has_rest_parameter()) {
|
@@ -187,8 +202,8 @@ namespace Sass {
|
|
187
202
|
}
|
188
203
|
// otherwise move one of the rest args into the param, converting to argument if necessary
|
189
204
|
Expression_Obj obj = arglist->at(0);
|
190
|
-
if (!(a =
|
191
|
-
Expression_Ptr a_to_convert =
|
205
|
+
if (!(a = Cast<Argument>(obj))) {
|
206
|
+
Expression_Ptr a_to_convert = obj;
|
192
207
|
a = SASS_MEMORY_NEW(Argument,
|
193
208
|
a_to_convert->pstate(),
|
194
209
|
a_to_convert,
|
@@ -202,17 +217,22 @@ namespace Sass {
|
|
202
217
|
}
|
203
218
|
|
204
219
|
} else if (a->is_keyword_argument()) {
|
205
|
-
Map_Obj argmap =
|
220
|
+
Map_Obj argmap = Cast<Map>(a->value());
|
206
221
|
|
207
222
|
for (auto key : argmap->keys()) {
|
208
|
-
|
223
|
+
String_Constant_Ptr val = Cast<String_Constant>(key);
|
224
|
+
if (val == NULL) {
|
225
|
+
eval->exp.traces.push_back(Backtrace(key->pstate()));
|
226
|
+
throw Exception::InvalidVarKwdType(key->pstate(), eval->exp.traces, key->inspect(), a);
|
227
|
+
}
|
228
|
+
std::string param = "$" + unquote(val->value());
|
209
229
|
|
210
|
-
if (!param_map.count(
|
230
|
+
if (!param_map.count(param)) {
|
211
231
|
std::stringstream msg;
|
212
|
-
msg << callee << " has no parameter named " <<
|
213
|
-
error(msg.str(), a->pstate());
|
232
|
+
msg << callee << " has no parameter named " << param;
|
233
|
+
error(msg.str(), a->pstate(), eval->exp.traces);
|
214
234
|
}
|
215
|
-
env->local_frame()[
|
235
|
+
env->local_frame()[param] = argmap->at(key);
|
216
236
|
}
|
217
237
|
++ia;
|
218
238
|
continue;
|
@@ -225,32 +245,38 @@ namespace Sass {
|
|
225
245
|
std::stringstream msg;
|
226
246
|
msg << "parameter " << p->name()
|
227
247
|
<< " provided more than once in call to " << callee;
|
228
|
-
error(msg.str(), a->pstate());
|
248
|
+
error(msg.str(), a->pstate(), eval->exp.traces);
|
229
249
|
}
|
230
250
|
// ordinal arg -- bind it to the next param
|
231
|
-
env->local_frame()[p->name()] =
|
251
|
+
env->local_frame()[p->name()] = a->value();
|
232
252
|
++ip;
|
233
253
|
}
|
234
254
|
else {
|
235
255
|
// named arg -- bind it to the appropriately named param
|
236
256
|
if (!param_map.count(a->name())) {
|
237
|
-
|
238
|
-
|
239
|
-
|
257
|
+
if (ps->has_rest_parameter()) {
|
258
|
+
varargs->append(a);
|
259
|
+
} else {
|
260
|
+
std::stringstream msg;
|
261
|
+
msg << callee << " has no parameter named " << a->name();
|
262
|
+
error(msg.str(), a->pstate(), eval->exp.traces);
|
263
|
+
}
|
240
264
|
}
|
241
|
-
if (param_map[a->name()]
|
242
|
-
|
243
|
-
|
244
|
-
|
245
|
-
|
265
|
+
if (param_map[a->name()]) {
|
266
|
+
if (param_map[a->name()]->is_rest_parameter()) {
|
267
|
+
std::stringstream msg;
|
268
|
+
msg << "argument " << a->name() << " of " << callee
|
269
|
+
<< "cannot be used as named argument";
|
270
|
+
error(msg.str(), a->pstate(), eval->exp.traces);
|
271
|
+
}
|
246
272
|
}
|
247
273
|
if (env->has_local(a->name())) {
|
248
274
|
std::stringstream msg;
|
249
275
|
msg << "parameter " << p->name()
|
250
276
|
<< "provided more than once in call to " << callee;
|
251
|
-
error(msg.str(), a->pstate());
|
277
|
+
error(msg.str(), a->pstate(), eval->exp.traces);
|
252
278
|
}
|
253
|
-
env->local_frame()[a->name()] =
|
279
|
+
env->local_frame()[a->name()] = a->value();
|
254
280
|
}
|
255
281
|
}
|
256
282
|
// EO while ia
|
@@ -265,11 +291,7 @@ namespace Sass {
|
|
265
291
|
// cerr << "********" << endl;
|
266
292
|
if (!env->has_local(leftover->name())) {
|
267
293
|
if (leftover->is_rest_parameter()) {
|
268
|
-
env->local_frame()[leftover->name()] =
|
269
|
-
leftover->pstate(),
|
270
|
-
0,
|
271
|
-
SASS_COMMA,
|
272
|
-
true);
|
294
|
+
env->local_frame()[leftover->name()] = varargs;
|
273
295
|
}
|
274
296
|
else if (leftover->default_value()) {
|
275
297
|
Expression_Ptr dv = leftover->default_value()->perform(eval);
|
@@ -277,7 +299,7 @@ namespace Sass {
|
|
277
299
|
}
|
278
300
|
else {
|
279
301
|
// param is unbound and has no default value -- error
|
280
|
-
throw Exception::MissingArgument(as->pstate(), name, leftover->name(), type);
|
302
|
+
throw Exception::MissingArgument(as->pstate(), eval->exp.traces, name, leftover->name(), type);
|
281
303
|
}
|
282
304
|
}
|
283
305
|
}
|