Coverage Report

Created: 2025-07-18 06:07

/src/libsass/src/ast_values.hpp
Line
Count
Source (jump to first uncovered line)
1
#ifndef SASS_AST_VALUES_H
2
#define SASS_AST_VALUES_H
3
4
// sass.hpp must go before all system headers to get the
5
// __EXTENSIONS__ fix on Solaris.
6
#include "sass.hpp"
7
#include "ast.hpp"
8
9
namespace Sass {
10
11
  //////////////////////////////////////////////////////////////////////
12
  // Still just an expression, but with a to_string method
13
  //////////////////////////////////////////////////////////////////////
14
  class PreValue : public Expression {
15
  public:
16
    PreValue(SourceSpan pstate, bool d = false, bool e = false, bool i = false, Type ct = NONE);
17
    ATTACH_VIRTUAL_AST_OPERATIONS(PreValue);
18
0
    virtual ~PreValue() { }
19
  };
20
21
  //////////////////////////////////////////////////////////////////////
22
  // base class for values that support operations
23
  //////////////////////////////////////////////////////////////////////
24
  class Value : public PreValue {
25
  public:
26
    Value(SourceSpan pstate, bool d = false, bool e = false, bool i = false, Type ct = NONE);
27
28
    // Some obects are not meant to be compared
29
    // ToDo: maybe fallback to pointer comparison?
30
    virtual bool operator< (const Expression& rhs) const override = 0;
31
    virtual bool operator== (const Expression& rhs) const override = 0;
32
33
    // We can give some reasonable implementations by using
34
    // inverst operators on the specialized implementations
35
0
    virtual bool operator> (const Expression& rhs) const {
36
0
      return rhs < *this;
37
0
    }
38
0
    virtual bool operator!= (const Expression& rhs) const {
39
0
      return !(*this == rhs);
40
0
    }
41
42
    ATTACH_VIRTUAL_AST_OPERATIONS(Value);
43
44
  };
45
46
  ///////////////////////////////////////////////////////////////////////
47
  // Lists of values, both comma- and space-separated (distinguished by a
48
  // type-tag.) Also used to represent variable-length argument lists.
49
  ///////////////////////////////////////////////////////////////////////
50
  class List : public Value, public Vectorized<ExpressionObj> {
51
28.0k
    void adjust_after_pushing(ExpressionObj e) override { is_expanded(false); }
52
  private:
53
    ADD_PROPERTY(enum Sass_Separator, separator)
54
    ADD_PROPERTY(bool, is_arglist)
55
    ADD_PROPERTY(bool, is_bracketed)
56
    ADD_PROPERTY(bool, from_selector)
57
  public:
58
    List(SourceSpan pstate, size_t size = 0, enum Sass_Separator sep = SASS_SPACE, bool argl = false, bool bracket = false);
59
0
    sass::string type() const override { return is_arglist_ ? "arglist" : "list"; }
60
0
    static sass::string type_name() { return "list"; }
61
0
    const char* sep_string(bool compressed = false) const {
62
0
      return separator() == SASS_SPACE ?
63
0
        " " : (compressed ? "," : ", ");
64
0
    }
65
0
    bool is_invisible() const override { return empty() && !is_bracketed(); }
66
    ExpressionObj value_at_index(size_t i);
67
68
    virtual size_t hash() const override;
69
    virtual size_t size() const;
70
    virtual void set_delayed(bool delayed) override;
71
72
    virtual bool operator< (const Expression& rhs) const override;
73
    virtual bool operator== (const Expression& rhs) const override;
74
75
    ATTACH_AST_OPERATIONS(List)
76
    ATTACH_CRTP_PERFORM_METHODS()
77
  };
78
79
  ///////////////////////////////////////////////////////////////////////
80
  // Key value paris.
81
  ///////////////////////////////////////////////////////////////////////
82
  class Map : public Value, public Hashed<ExpressionObj, ExpressionObj, Map_Obj> {
83
0
    void adjust_after_pushing(std::pair<ExpressionObj, ExpressionObj> p) override { is_expanded(false); }
84
  public:
85
    Map(SourceSpan pstate, size_t size = 0);
86
0
    sass::string type() const override { return "map"; }
87
0
    static sass::string type_name() { return "map"; }
88
0
    bool is_invisible() const override { return empty(); }
89
    List_Obj to_list(SourceSpan& pstate);
90
91
    virtual size_t hash() const override;
92
93
    virtual bool operator< (const Expression& rhs) const override;
94
    virtual bool operator== (const Expression& rhs) const override;
95
96
    ATTACH_AST_OPERATIONS(Map)
97
    ATTACH_CRTP_PERFORM_METHODS()
98
  };
99
100
101
  //////////////////////////////////////////////////////////////////////////
102
  // Binary expressions. Represents logical, relational, and arithmetic
103
  // operations. Templatized to avoid large switch statements and repetitive
104
  // subclassing.
105
  //////////////////////////////////////////////////////////////////////////
106
  class Binary_Expression : public PreValue {
107
  private:
108
    HASH_PROPERTY(Operand, op)
109
    HASH_PROPERTY(ExpressionObj, left)
110
    HASH_PROPERTY(ExpressionObj, right)
111
    mutable size_t hash_;
112
  public:
113
    Binary_Expression(SourceSpan pstate,
114
                      Operand op, ExpressionObj lhs, ExpressionObj rhs);
115
116
    const sass::string type_name();
117
    const sass::string separator();
118
    bool is_left_interpolant(void) const override;
119
    bool is_right_interpolant(void) const override;
120
    bool has_interpolant() const override;
121
122
    virtual void set_delayed(bool delayed) override;
123
124
    virtual bool operator< (const Expression& rhs) const override;
125
    virtual bool operator==(const Expression& rhs) const override;
126
127
    virtual size_t hash() const override;
128
698
    enum Sass_OP optype() const { return op_.operand; }
129
    ATTACH_AST_OPERATIONS(Binary_Expression)
130
    ATTACH_CRTP_PERFORM_METHODS()
131
  };
132
133
  ////////////////////////////////////////////////////
134
  // Function reference.
135
  ////////////////////////////////////////////////////
136
  class Function final : public Value {
137
  public:
138
    ADD_PROPERTY(Definition_Obj, definition)
139
    ADD_PROPERTY(bool, is_css)
140
  public:
141
    Function(SourceSpan pstate, Definition_Obj def, bool css);
142
143
0
    sass::string type() const override { return "function"; }
144
0
    static sass::string type_name() { return "function"; }
145
0
    bool is_invisible() const override { return true; }
146
147
    sass::string name();
148
149
    bool operator< (const Expression& rhs) const override;
150
    bool operator== (const Expression& rhs) const override;
151
152
    ATTACH_AST_OPERATIONS(Function)
153
    ATTACH_CRTP_PERFORM_METHODS()
154
  };
155
156
  //////////////////
157
  // Function calls.
158
  //////////////////
159
  class Function_Call final : public PreValue {
160
    HASH_CONSTREF(String_Obj, sname)
161
    HASH_PROPERTY(Arguments_Obj, arguments)
162
    HASH_PROPERTY(Function_Obj, func)
163
    ADD_PROPERTY(bool, via_call)
164
    ADD_PROPERTY(void*, cookie)
165
    mutable size_t hash_;
166
  public:
167
    Function_Call(SourceSpan pstate, sass::string n, Arguments_Obj args, void* cookie);
168
    Function_Call(SourceSpan pstate, sass::string n, Arguments_Obj args, Function_Obj func);
169
    Function_Call(SourceSpan pstate, sass::string n, Arguments_Obj args);
170
171
    Function_Call(SourceSpan pstate, String_Obj n, Arguments_Obj args, void* cookie);
172
    Function_Call(SourceSpan pstate, String_Obj n, Arguments_Obj args, Function_Obj func);
173
    Function_Call(SourceSpan pstate, String_Obj n, Arguments_Obj args);
174
175
    sass::string name() const;
176
    bool is_css();
177
178
    bool operator==(const Expression& rhs) const override;
179
180
    size_t hash() const override;
181
182
    ATTACH_AST_OPERATIONS(Function_Call)
183
    ATTACH_CRTP_PERFORM_METHODS()
184
  };
185
186
  ///////////////////////
187
  // Variable references.
188
  ///////////////////////
189
  class Variable final : public PreValue {
190
    ADD_CONSTREF(sass::string, name)
191
  public:
192
    Variable(SourceSpan pstate, sass::string n);
193
    virtual bool operator==(const Expression& rhs) const override;
194
    virtual size_t hash() const override;
195
    ATTACH_AST_OPERATIONS(Variable)
196
    ATTACH_CRTP_PERFORM_METHODS()
197
  };
198
199
  ////////////////////////////////////////////////
200
  // Numbers, percentages, dimensions, and colors.
201
  ////////////////////////////////////////////////
202
  class Number final : public Value, public Units {
203
    HASH_PROPERTY(double, value)
204
    ADD_PROPERTY(bool, zero)
205
    mutable size_t hash_;
206
  public:
207
    Number(SourceSpan pstate, double val, sass::string u = "", bool zero = true);
208
209
0
    bool zero() { return zero_; }
210
211
0
    sass::string type() const override { return "number"; }
212
0
    static sass::string type_name() { return "number"; }
213
214
    // cancel out unnecessary units
215
    // result will be in input units
216
    void reduce();
217
218
    // normalize units to defaults
219
    // needed to compare two numbers
220
    void normalize();
221
222
    size_t hash() const override;
223
224
    bool operator< (const Number& rhs) const;
225
    bool operator== (const Number& rhs) const;
226
    bool operator< (const Expression& rhs) const override;
227
    bool operator== (const Expression& rhs) const override;
228
    ATTACH_AST_OPERATIONS(Number)
229
    ATTACH_CRTP_PERFORM_METHODS()
230
  };
231
232
  //////////
233
  // Colors.
234
  //////////
235
  class Color : public Value {
236
    ADD_CONSTREF(sass::string, disp)
237
    HASH_PROPERTY(double, a)
238
  protected:
239
    mutable size_t hash_;
240
  public:
241
    Color(SourceSpan pstate, double a = 1, const sass::string disp = "");
242
243
0
    sass::string type() const override { return "color"; }
244
0
    static sass::string type_name() { return "color"; }
245
246
    virtual size_t hash() const override = 0;
247
248
    bool operator< (const Expression& rhs) const override;
249
    bool operator== (const Expression& rhs) const override;
250
251
    virtual Color_RGBA* copyAsRGBA() const = 0;
252
    virtual Color_RGBA* toRGBA() = 0;
253
254
    virtual Color_HSLA* copyAsHSLA() const = 0;
255
    virtual Color_HSLA* toHSLA() = 0;
256
257
    ATTACH_VIRTUAL_AST_OPERATIONS(Color)
258
  };
259
260
  //////////
261
  // Colors.
262
  //////////
263
  class Color_RGBA final : public Color {
264
    HASH_PROPERTY(double, r)
265
    HASH_PROPERTY(double, g)
266
    HASH_PROPERTY(double, b)
267
  public:
268
    Color_RGBA(SourceSpan pstate, double r, double g, double b, double a = 1, const sass::string disp = "");
269
270
0
    sass::string type() const override { return "color"; }
271
0
    static sass::string type_name() { return "color"; }
272
273
    size_t hash() const override;
274
275
    Color_RGBA* copyAsRGBA() const override;
276
0
    Color_RGBA* toRGBA() override { return this; }
277
278
    Color_HSLA* copyAsHSLA() const override;
279
0
    Color_HSLA* toHSLA() override { return copyAsHSLA(); }
280
281
    bool operator< (const Expression& rhs) const override;
282
    bool operator== (const Expression& rhs) const override;
283
284
    ATTACH_AST_OPERATIONS(Color_RGBA)
285
    ATTACH_CRTP_PERFORM_METHODS()
286
  };
287
288
289
  //////////
290
  // Colors.
291
  //////////
292
  class Color_HSLA final : public Color {
293
    HASH_PROPERTY(double, h)
294
    HASH_PROPERTY(double, s)
295
    HASH_PROPERTY(double, l)
296
  public:
297
    Color_HSLA(SourceSpan pstate, double h, double s, double l, double a = 1, const sass::string disp = "");
298
299
0
    sass::string type() const override { return "color"; }
300
0
    static sass::string type_name() { return "color"; }
301
302
    size_t hash() const override;
303
304
    Color_RGBA* copyAsRGBA() const override;
305
0
    Color_RGBA* toRGBA() override { return copyAsRGBA(); }
306
307
    Color_HSLA* copyAsHSLA() const override;
308
0
    Color_HSLA* toHSLA() override { return this; }
309
310
    bool operator< (const Expression& rhs) const override;
311
    bool operator== (const Expression& rhs) const override;
312
313
    ATTACH_AST_OPERATIONS(Color_HSLA)
314
    ATTACH_CRTP_PERFORM_METHODS()
315
  };
316
317
  //////////////////////////////
318
  // Errors from Sass_Values.
319
  //////////////////////////////
320
  class Custom_Error final : public Value {
321
    ADD_CONSTREF(sass::string, message)
322
  public:
323
    Custom_Error(SourceSpan pstate, sass::string msg);
324
    bool operator< (const Expression& rhs) const override;
325
    bool operator== (const Expression& rhs) const override;
326
    ATTACH_AST_OPERATIONS(Custom_Error)
327
    ATTACH_CRTP_PERFORM_METHODS()
328
  };
329
330
  //////////////////////////////
331
  // Warnings from Sass_Values.
332
  //////////////////////////////
333
  class Custom_Warning final : public Value {
334
    ADD_CONSTREF(sass::string, message)
335
  public:
336
    Custom_Warning(SourceSpan pstate, sass::string msg);
337
    bool operator< (const Expression& rhs) const override;
338
    bool operator== (const Expression& rhs) const override;
339
    ATTACH_AST_OPERATIONS(Custom_Warning)
340
    ATTACH_CRTP_PERFORM_METHODS()
341
  };
342
343
  ////////////
344
  // Booleans.
345
  ////////////
346
  class Boolean final : public Value {
347
    HASH_PROPERTY(bool, value)
348
    mutable size_t hash_;
349
  public:
350
    Boolean(SourceSpan pstate, bool val);
351
0
    operator bool() override { return value_; }
352
353
0
    sass::string type() const override { return "bool"; }
354
0
    static sass::string type_name() { return "bool"; }
355
356
    size_t hash() const override;
357
358
0
    bool is_false() override { return !value_; }
359
360
    bool operator< (const Expression& rhs) const override;
361
    bool operator== (const Expression& rhs) const override;
362
363
    ATTACH_AST_OPERATIONS(Boolean)
364
    ATTACH_CRTP_PERFORM_METHODS()
365
  };
366
367
  ////////////////////////////////////////////////////////////////////////
368
  // Abstract base class for Sass string values. Includes interpolated and
369
  // "flat" strings.
370
  ////////////////////////////////////////////////////////////////////////
371
  class String : public Value {
372
  public:
373
    String(SourceSpan pstate, bool delayed = false);
374
0
    static sass::string type_name() { return "string"; }
375
    virtual ~String() = 0;
376
    virtual void rtrim() = 0;
377
0
    virtual bool operator<(const Expression& rhs) const override {
378
0
      return this->to_string() < rhs.to_string();
379
0
    };
380
0
    virtual bool operator==(const Expression& rhs) const override {
381
0
      return this->to_string() == rhs.to_string();
382
0
    };
383
    ATTACH_VIRTUAL_AST_OPERATIONS(String);
384
    ATTACH_CRTP_PERFORM_METHODS()
385
  };
386
  inline String::~String() { };
387
388
  ///////////////////////////////////////////////////////////////////////
389
  // Interpolated strings. Meant to be reduced to flat strings during the
390
  // evaluation phase.
391
  ///////////////////////////////////////////////////////////////////////
392
  class String_Schema final : public String, public Vectorized<PreValueObj> {
393
    ADD_PROPERTY(bool, css)
394
    mutable size_t hash_;
395
  public:
396
    String_Schema(SourceSpan pstate, size_t size = 0, bool css = true);
397
398
0
    sass::string type() const override { return "string"; }
399
0
    static sass::string type_name() { return "string"; }
400
401
    bool is_left_interpolant(void) const override;
402
    bool is_right_interpolant(void) const override;
403
404
    bool has_interpolants();
405
    void rtrim() override;
406
    size_t hash() const override;
407
    virtual void set_delayed(bool delayed) override;
408
409
    bool operator< (const Expression& rhs) const override;
410
    bool operator==(const Expression& rhs) const override;
411
    ATTACH_AST_OPERATIONS(String_Schema)
412
    ATTACH_CRTP_PERFORM_METHODS()
413
  };
414
415
  ////////////////////////////////////////////////////////
416
  // Flat strings -- the lowest level of raw textual data.
417
  ////////////////////////////////////////////////////////
418
  class String_Constant : public String {
419
    ADD_PROPERTY(char, quote_mark)
420
    HASH_CONSTREF(sass::string, value)
421
  protected:
422
    mutable size_t hash_;
423
  public:
424
    String_Constant(SourceSpan pstate, sass::string val, bool css = true);
425
    String_Constant(SourceSpan pstate, const char* beg, bool css = true);
426
    String_Constant(SourceSpan pstate, const char* beg, const char* end, bool css = true);
427
    String_Constant(SourceSpan pstate, const Token& tok, bool css = true);
428
0
    sass::string type() const override { return "string"; }
429
0
    static sass::string type_name() { return "string"; }
430
    bool is_invisible() const override;
431
    virtual void rtrim() override;
432
    size_t hash() const override;
433
    bool operator< (const Expression& rhs) const override;
434
    bool operator==(const Expression& rhs) const override;
435
    // quotes are forced on inspection
436
    virtual sass::string inspect() const override;
437
    ATTACH_AST_OPERATIONS(String_Constant)
438
    ATTACH_CRTP_PERFORM_METHODS()
439
  };
440
441
  ////////////////////////////////////////////////////////
442
  // Possibly quoted string (unquote on instantiation)
443
  ////////////////////////////////////////////////////////
444
  class String_Quoted final : public String_Constant {
445
  public:
446
    String_Quoted(SourceSpan pstate, sass::string val, char q = 0,
447
      bool keep_utf8_escapes = false, bool skip_unquoting = false,
448
      bool strict_unquoting = true, bool css = true);
449
    bool operator< (const Expression& rhs) const override;
450
    bool operator==(const Expression& rhs) const override;
451
    // quotes are forced on inspection
452
    sass::string inspect() const override;
453
    ATTACH_AST_OPERATIONS(String_Quoted)
454
    ATTACH_CRTP_PERFORM_METHODS()
455
  };
456
457
  //////////////////
458
  // The null value.
459
  //////////////////
460
  class Null final : public Value {
461
  public:
462
    Null(SourceSpan pstate);
463
0
    sass::string type() const override { return "null"; }
464
0
    static sass::string type_name() { return "null"; }
465
0
    bool is_invisible() const override { return true; }
466
0
    operator bool() override { return false; }
467
0
    bool is_false() override { return true; }
468
469
    size_t hash() const override;
470
471
    bool operator< (const Expression& rhs) const override;
472
    bool operator== (const Expression& rhs) const override;
473
474
    ATTACH_AST_OPERATIONS(Null)
475
    ATTACH_CRTP_PERFORM_METHODS()
476
  };
477
478
  //////////////////////////////////
479
  // The Parent Reference Expression.
480
  //////////////////////////////////
481
  class Parent_Reference final : public Value {
482
  public:
483
    Parent_Reference(SourceSpan pstate);
484
0
    sass::string type() const override { return "parent"; }
485
0
    static sass::string type_name() { return "parent"; }
486
0
    bool operator< (const Expression& rhs) const override {
487
0
      return false; // they are always equal
488
0
    }
489
0
    bool operator==(const Expression& rhs) const override {
490
0
      return true; // they are always equal
491
0
    };
492
    ATTACH_AST_OPERATIONS(Parent_Reference)
493
    ATTACH_CRTP_PERFORM_METHODS()
494
  };
495
496
}
497
498
#endif