sass-embedded 1.74.1-x86-mingw-ucrt

Sign up to get free protection for your applications and to get access to all the features.
Files changed (52) hide show
  1. checksums.yaml +7 -0
  2. data/LICENSE +20 -0
  3. data/README.md +48 -0
  4. data/exe/sass +21 -0
  5. data/ext/sass/cli.rb +12 -0
  6. data/ext/sass/dart-sass/sass.bat +7 -0
  7. data/ext/sass/dart-sass/src/LICENSE +1687 -0
  8. data/ext/sass/dart-sass/src/dart.exe +0 -0
  9. data/ext/sass/dart-sass/src/sass.snapshot +0 -0
  10. data/ext/sass/embedded_sass_pb.rb +63 -0
  11. data/lib/sass/calculation_value/calculation_operation.rb +49 -0
  12. data/lib/sass/calculation_value.rb +22 -0
  13. data/lib/sass/canonicalize_context.rb +21 -0
  14. data/lib/sass/compile_result.rb +24 -0
  15. data/lib/sass/compiler/channel.rb +68 -0
  16. data/lib/sass/compiler/connection.rb +92 -0
  17. data/lib/sass/compiler/dispatcher.rb +115 -0
  18. data/lib/sass/compiler/host/function_registry.rb +87 -0
  19. data/lib/sass/compiler/host/importer_registry.rb +137 -0
  20. data/lib/sass/compiler/host/logger_registry.rb +55 -0
  21. data/lib/sass/compiler/host/protofier.rb +390 -0
  22. data/lib/sass/compiler/host/structifier.rb +37 -0
  23. data/lib/sass/compiler/host.rb +226 -0
  24. data/lib/sass/compiler/varint.rb +39 -0
  25. data/lib/sass/compiler.rb +212 -0
  26. data/lib/sass/elf.rb +276 -0
  27. data/lib/sass/embedded/version.rb +7 -0
  28. data/lib/sass/embedded.rb +107 -0
  29. data/lib/sass/embedded_protocol.rb +10 -0
  30. data/lib/sass/exception.rb +69 -0
  31. data/lib/sass/fork_tracker.rb +51 -0
  32. data/lib/sass/logger/silent.rb +28 -0
  33. data/lib/sass/logger/source_location.rb +22 -0
  34. data/lib/sass/logger/source_span.rb +28 -0
  35. data/lib/sass/node_package_importer.rb +17 -0
  36. data/lib/sass/serializer.rb +36 -0
  37. data/lib/sass/value/argument_list.rb +37 -0
  38. data/lib/sass/value/boolean.rb +52 -0
  39. data/lib/sass/value/calculation.rb +90 -0
  40. data/lib/sass/value/color.rb +253 -0
  41. data/lib/sass/value/function.rb +51 -0
  42. data/lib/sass/value/fuzzy_math.rb +80 -0
  43. data/lib/sass/value/list.rb +79 -0
  44. data/lib/sass/value/map.rb +71 -0
  45. data/lib/sass/value/mixin.rb +36 -0
  46. data/lib/sass/value/null.rb +48 -0
  47. data/lib/sass/value/number/unit.rb +186 -0
  48. data/lib/sass/value/number.rb +366 -0
  49. data/lib/sass/value/string.rb +61 -0
  50. data/lib/sass/value.rb +136 -0
  51. data/lib/sass-embedded.rb +4 -0
  52. metadata +120 -0
@@ -0,0 +1,48 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Sass
4
+ module Value
5
+ # Sass's null type.
6
+ #
7
+ # @see https://sass-lang.com/documentation/js-api/variables/sassnull/
8
+ class Null
9
+ include Value
10
+
11
+ def initialize
12
+ @value = nil
13
+ end
14
+
15
+ # @return [nil]
16
+ attr_reader :value
17
+
18
+ # @return [Boolean]
19
+ def !
20
+ Boolean::TRUE
21
+ end
22
+
23
+ # @return [::Boolean]
24
+ def ==(other)
25
+ other.is_a?(Sass::Value::Null)
26
+ end
27
+
28
+ # @return [Integer]
29
+ def hash
30
+ @hash ||= value.hash
31
+ end
32
+
33
+ # @return [::Boolean]
34
+ def to_bool
35
+ false
36
+ end
37
+
38
+ alias to_nil value
39
+
40
+ # Sass's null value.
41
+ NULL = Null.new
42
+
43
+ def self.new
44
+ NULL
45
+ end
46
+ end
47
+ end
48
+ end
@@ -0,0 +1,186 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Sass
4
+ module Value
5
+ class Number
6
+ # The {Unit} module.
7
+ module Unit
8
+ CONVERSIONS = {
9
+ # Length
10
+ 'in' => {
11
+ 'in' => Rational(1),
12
+ 'cm' => Rational(1, 2.54),
13
+ 'pc' => Rational(1, 6),
14
+ 'mm' => Rational(1, 25.4),
15
+ 'q' => Rational(1, 101.6),
16
+ 'pt' => Rational(1, 72),
17
+ 'px' => Rational(1, 96)
18
+ },
19
+ 'cm' => {
20
+ 'in' => Rational(2.54),
21
+ 'cm' => Rational(1),
22
+ 'pc' => Rational(2.54, 6),
23
+ 'mm' => Rational(1, 10),
24
+ 'q' => Rational(1, 40),
25
+ 'pt' => Rational(2.54, 72),
26
+ 'px' => Rational(2.54, 96)
27
+ },
28
+ 'pc' => {
29
+ 'in' => Rational(6),
30
+ 'cm' => Rational(6, 2.54),
31
+ 'pc' => Rational(1),
32
+ 'mm' => Rational(6, 25.4),
33
+ 'q' => Rational(6, 101.6),
34
+ 'pt' => Rational(1, 12),
35
+ 'px' => Rational(1, 16)
36
+ },
37
+ 'mm' => {
38
+ 'in' => Rational(25.4),
39
+ 'cm' => Rational(10),
40
+ 'pc' => Rational(25.4, 6),
41
+ 'mm' => Rational(1),
42
+ 'q' => Rational(1, 4),
43
+ 'pt' => Rational(25.4, 72),
44
+ 'px' => Rational(25.4, 96)
45
+ },
46
+ 'q' => {
47
+ 'in' => Rational(101.6),
48
+ 'cm' => Rational(40),
49
+ 'pc' => Rational(101.6, 6),
50
+ 'mm' => Rational(4),
51
+ 'q' => Rational(1),
52
+ 'pt' => Rational(101.6, 72),
53
+ 'px' => Rational(101.6, 96)
54
+ },
55
+ 'pt' => {
56
+ 'in' => Rational(72),
57
+ 'cm' => Rational(72, 2.54),
58
+ 'pc' => Rational(12),
59
+ 'mm' => Rational(72, 25.4),
60
+ 'q' => Rational(72, 101.6),
61
+ 'pt' => Rational(1),
62
+ 'px' => Rational(3, 4)
63
+ },
64
+ 'px' => {
65
+ 'in' => Rational(96),
66
+ 'cm' => Rational(96, 2.54),
67
+ 'pc' => Rational(16),
68
+ 'mm' => Rational(96, 25.4),
69
+ 'q' => Rational(96, 101.6),
70
+ 'pt' => Rational(4, 3),
71
+ 'px' => Rational(1)
72
+ },
73
+
74
+ # Rotation
75
+ 'deg' => {
76
+ 'deg' => Rational(1),
77
+ 'grad' => Rational(9, 10),
78
+ 'rad' => Rational(180, Math::PI),
79
+ 'turn' => Rational(360)
80
+ },
81
+ 'grad' => {
82
+ 'deg' => Rational(10, 9),
83
+ 'grad' => Rational(1),
84
+ 'rad' => Rational(200, Math::PI),
85
+ 'turn' => Rational(400)
86
+ },
87
+ 'rad' => {
88
+ 'deg' => Rational(Math::PI, 180),
89
+ 'grad' => Rational(Math::PI, 200),
90
+ 'rad' => Rational(1),
91
+ 'turn' => Rational(Math::PI * 2)
92
+ },
93
+ 'turn' => {
94
+ 'deg' => Rational(1, 360),
95
+ 'grad' => Rational(1, 400),
96
+ 'rad' => Rational(1, Math::PI * 2),
97
+ 'turn' => Rational(1)
98
+ },
99
+
100
+ # Time
101
+ 's' => {
102
+ 's' => Rational(1),
103
+ 'ms' => Rational(1, 1000)
104
+ },
105
+ 'ms' => {
106
+ 's' => Rational(1000),
107
+ 'ms' => Rational(1)
108
+ },
109
+
110
+ # Frequency
111
+ 'Hz' => {
112
+ 'Hz' => Rational(1),
113
+ 'kHz' => Rational(1000)
114
+ },
115
+ 'kHz' => {
116
+ 'Hz' => Rational(1, 1000),
117
+ 'kHz' => Rational(1)
118
+ },
119
+
120
+ # Pixel density
121
+ 'dpi' => {
122
+ 'dpi' => Rational(1),
123
+ 'dpcm' => Rational(2.54),
124
+ 'dppx' => Rational(96)
125
+ },
126
+ 'dpcm' => {
127
+ 'dpi' => Rational(1, 2.54),
128
+ 'dpcm' => Rational(1),
129
+ 'dppx' => Rational(96, 2.54)
130
+ },
131
+ 'dppx' => {
132
+ 'dpi' => Rational(1, 96),
133
+ 'dpcm' => Rational(2.54, 96),
134
+ 'dppx' => Rational(1)
135
+ }
136
+ }.freeze
137
+
138
+ UNITS_BY_TYPE = {
139
+ time: %w[s ms],
140
+ frequency: %w[Hz kHz],
141
+ 'pixel density': %w[dpi dpcm dppx]
142
+ }.freeze
143
+
144
+ TYPES_BY_UNIT = UNITS_BY_TYPE.invert
145
+ .to_a
146
+ .flat_map { |pair| pair[0].map { |key| [key, pair[1]] } }
147
+ .to_h
148
+
149
+ module_function
150
+
151
+ def conversion_factor(unit1, unit2)
152
+ return 1 if unit1 == unit2
153
+
154
+ CONVERSIONS.dig(unit1, unit2)
155
+ end
156
+
157
+ def canonicalize_units(units)
158
+ return units if units.empty?
159
+
160
+ if units.length == 1
161
+ type = TYPES_BY_UNIT[units.first]
162
+ return type.nil? ? units : [UNITS_BY_TYPE[type].first]
163
+ end
164
+
165
+ units.map do |unit|
166
+ type = TYPES_BY_UNIT[unit]
167
+ type.nil? ? units : [UNITS_BY_TYPE[type].first]
168
+ end.sort
169
+ end
170
+
171
+ def canonical_multiplier(units)
172
+ units.reduce(1) do |multiplier, unit|
173
+ multiplier * canonical_multiplier_for_unit(unit)
174
+ end
175
+ end
176
+
177
+ def canonical_multiplier_for_unit(unit)
178
+ inner_map = CONVERSIONS[unit]
179
+ inner_map.nil? ? 1 : 1 / inner_map.values.first
180
+ end
181
+ end
182
+
183
+ private_constant :Unit
184
+ end
185
+ end
186
+ end
@@ -0,0 +1,366 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative 'number/unit'
4
+
5
+ module Sass
6
+ module Value
7
+ # Sass's number type.
8
+ #
9
+ # @see https://sass-lang.com/documentation/js-api/classes/sassnumber/
10
+ class Number
11
+ include Value
12
+ include CalculationValue
13
+
14
+ # @param value [Numeric]
15
+ # @param unit [::String, Hash]
16
+ # @option unit [Array<::String>] :numerator_units
17
+ # @option unit [Array<::String>] :denominator_units
18
+ def initialize(value, unit = nil)
19
+ case unit
20
+ when nil
21
+ numerator_units = []
22
+ denominator_units = []
23
+ when ::String
24
+ numerator_units = [unit]
25
+ denominator_units = []
26
+ when ::Hash
27
+ numerator_units = unit.fetch(:numerator_units, [])
28
+ unless numerator_units.is_a?(Array)
29
+ raise Sass::ScriptError, "invalid numerator_units #{numerator_units.inspect}"
30
+ end
31
+
32
+ denominator_units = unit.fetch(:denominator_units, [])
33
+ unless denominator_units.is_a?(Array)
34
+ raise Sass::ScriptError, "invalid denominator_units #{denominator_units.inspect}"
35
+ end
36
+ else
37
+ raise Sass::ScriptError, "invalid unit #{unit.inspect}"
38
+ end
39
+
40
+ unless denominator_units.empty? && numerator_units.empty?
41
+ value = value.dup
42
+ numerator_units = numerator_units.dup
43
+ new_denominator_units = []
44
+
45
+ denominator_units.each do |denominator_unit|
46
+ index = numerator_units.find_index do |numerator_unit|
47
+ factor = Unit.conversion_factor(denominator_unit, numerator_unit)
48
+ if factor.nil?
49
+ false
50
+ else
51
+ value *= factor
52
+ true
53
+ end
54
+ end
55
+ if index.nil?
56
+ new_denominator_units.push(denominator_unit)
57
+ else
58
+ numerator_units.delete_at(index)
59
+ end
60
+ end
61
+
62
+ denominator_units = new_denominator_units
63
+ end
64
+
65
+ @value = value.freeze
66
+ @numerator_units = numerator_units.each(&:freeze).freeze
67
+ @denominator_units = denominator_units.each(&:freeze).freeze
68
+ end
69
+
70
+ # @return [Numeric]
71
+ attr_reader :value
72
+
73
+ # @return [Array<::String>]
74
+ attr_reader :numerator_units, :denominator_units
75
+
76
+ # @return [::Boolean]
77
+ def ==(other)
78
+ return false unless other.is_a?(Sass::Value::Number)
79
+
80
+ return false if numerator_units.length != other.numerator_units.length ||
81
+ denominator_units.length != other.denominator_units.length
82
+
83
+ return FuzzyMath.equals(value, other.value) if unitless?
84
+
85
+ if Unit.canonicalize_units(numerator_units) != Unit.canonicalize_units(other.numerator_units) &&
86
+ Unit.canonicalize_units(denominator_units) != Unit.canonicalize_units(other.denominator_units)
87
+ return false
88
+ end
89
+
90
+ FuzzyMath.equals(
91
+ (value *
92
+ Unit.canonical_multiplier(numerator_units) /
93
+ Unit.canonical_multiplier(denominator_units)),
94
+ (other.value *
95
+ Unit.canonical_multiplier(other.numerator_units) /
96
+ Unit.canonical_multiplier(other.denominator_units))
97
+ )
98
+ end
99
+
100
+ # @return [Integer]
101
+ def hash
102
+ @hash ||= FuzzyMath.hash(canonical_units_value)
103
+ end
104
+
105
+ # @return [::Boolean]
106
+ def unitless?
107
+ numerator_units.empty? && denominator_units.empty?
108
+ end
109
+
110
+ # @return [Number]
111
+ # @raise [ScriptError]
112
+ def assert_unitless(name = nil)
113
+ raise Sass::ScriptError.new("Expected #{self} to have no units", name) unless unitless?
114
+
115
+ self
116
+ end
117
+
118
+ # @return [::Boolean]
119
+ def units?
120
+ !unitless?
121
+ end
122
+
123
+ # @param unit [::String]
124
+ # @return [::Boolean]
125
+ def unit?(unit)
126
+ single_unit? && numerator_units.first == unit
127
+ end
128
+
129
+ # @param unit [::String]
130
+ # @return [Number]
131
+ # @raise [ScriptError]
132
+ def assert_unit(unit, name = nil)
133
+ raise Sass::ScriptError.new("Expected #{self} to have unit #{unit.inspect}", name) unless unit?(unit)
134
+
135
+ self
136
+ end
137
+
138
+ # @return [::Boolean]
139
+ def integer?
140
+ FuzzyMath.integer?(value)
141
+ end
142
+
143
+ # @return [Integer]
144
+ # @raise [ScriptError]
145
+ def assert_integer(name = nil)
146
+ raise Sass::ScriptError.new("#{self} is not an integer", name) unless integer?
147
+
148
+ to_i
149
+ end
150
+
151
+ # @return [Integer]
152
+ def to_i
153
+ FuzzyMath.to_i(value)
154
+ end
155
+
156
+ # @param min [Numeric]
157
+ # @param max [Numeric]
158
+ # @return [Numeric]
159
+ # @raise [ScriptError]
160
+ def assert_between(min, max, name = nil)
161
+ FuzzyMath.assert_between(value, min, max, name)
162
+ end
163
+
164
+ # @param unit [::String]
165
+ # @return [::Boolean]
166
+ def compatible_with_unit?(unit)
167
+ single_unit? && !Unit.conversion_factor(numerator_units.first, unit).nil?
168
+ end
169
+
170
+ # @param new_numerator_units [Array<::String>]
171
+ # @param new_denominator_units [Array<::String>]
172
+ # @return [Number]
173
+ def convert(new_numerator_units, new_denominator_units, name = nil)
174
+ Number.new(convert_value(new_numerator_units, new_denominator_units, name), {
175
+ numerator_units: new_numerator_units,
176
+ denominator_units: new_denominator_units
177
+ })
178
+ end
179
+
180
+ # @param new_numerator_units [Array<::String>]
181
+ # @param new_denominator_units [Array<::String>]
182
+ # @return [Numeric]
183
+ def convert_value(new_numerator_units, new_denominator_units, name = nil)
184
+ coerce_or_convert_value(new_numerator_units, new_denominator_units,
185
+ coerce_unitless: false,
186
+ name:)
187
+ end
188
+
189
+ # @param other [Number]
190
+ # @return [Number]
191
+ def convert_to_match(other, name = nil, other_name = nil)
192
+ Number.new(convert_value_to_match(other, name, other_name), {
193
+ numerator_units: other.numerator_units,
194
+ denominator_units: other.denominator_units
195
+ })
196
+ end
197
+
198
+ # @param other [Number]
199
+ # @return [Numeric]
200
+ def convert_value_to_match(other, name = nil, other_name = nil)
201
+ coerce_or_convert_value(other.numerator_units, other.denominator_units,
202
+ coerce_unitless: false,
203
+ name:,
204
+ other:,
205
+ other_name:)
206
+ end
207
+
208
+ # @param new_numerator_units [Array<::String>]
209
+ # @param new_denominator_units [Array<::String>]
210
+ # @return [Number]
211
+ def coerce(new_numerator_units, new_denominator_units, name = nil)
212
+ Number.new(coerce_value(new_numerator_units, new_denominator_units, name), {
213
+ numerator_units: new_numerator_units,
214
+ denominator_units: new_denominator_units
215
+ })
216
+ end
217
+
218
+ # @param new_numerator_units [Array<::String>]
219
+ # @param new_denominator_units [Array<::String>]
220
+ # @return [Numeric]
221
+ def coerce_value(new_numerator_units, new_denominator_units, name = nil)
222
+ coerce_or_convert_value(new_numerator_units, new_denominator_units,
223
+ coerce_unitless: true,
224
+ name:)
225
+ end
226
+
227
+ # @param unit [::String]
228
+ # @return [Numeric]
229
+ def coerce_value_to_unit(unit, name = nil)
230
+ coerce_value([unit], [], name)
231
+ end
232
+
233
+ # @param other [Number]
234
+ # @return [Number]
235
+ def coerce_to_match(other, name = nil, other_name = nil)
236
+ Number.new(coerce_value_to_match(other, name, other_name), {
237
+ numerator_units: other.numerator_units,
238
+ denominator_units: other.denominator_units
239
+ })
240
+ end
241
+
242
+ # @param other [Number]
243
+ # @return [Numeric]
244
+ def coerce_value_to_match(other, name = nil, other_name = nil)
245
+ coerce_or_convert_value(other.numerator_units, other.denominator_units,
246
+ coerce_unitless: true,
247
+ name:,
248
+ other:,
249
+ other_name:)
250
+ end
251
+
252
+ # @return [Number]
253
+ def assert_number(_name = nil)
254
+ self
255
+ end
256
+
257
+ private
258
+
259
+ def single_unit?
260
+ numerator_units.length == 1 && denominator_units.empty?
261
+ end
262
+
263
+ def canonical_units_value
264
+ if unitless?
265
+ value
266
+ elsif single_unit?
267
+ value * Unit.canonical_multiplier_for_unit(numerator_units.first)
268
+ else
269
+ value * Unit.canonical_multiplier(numerator_units) / Unit.canonical_multiplier(denominator_units)
270
+ end
271
+ end
272
+
273
+ def coerce_or_convert_value(new_numerator_units, new_denominator_units,
274
+ coerce_unitless:,
275
+ name: nil,
276
+ other: nil,
277
+ other_name: nil)
278
+ if other && (other.numerator_units != new_denominator_units && other.denominator_units != new_denominator_units)
279
+ raise Sass::ScriptError, "Expect #{other} to have units #{unit_string(new_numerator_units,
280
+ new_denominator_units).inspect}"
281
+ end
282
+
283
+ return value if numerator_units == new_numerator_units && denominator_units == new_denominator_units
284
+
285
+ return value if numerator_units == new_numerator_units && denominator_units == new_denominator_units
286
+
287
+ other_unitless = new_numerator_units.empty? && new_denominator_units.empty?
288
+
289
+ return value if coerce_unitless && (unitless? || other_unitless)
290
+
291
+ compatibility_error = lambda {
292
+ unless other.nil?
293
+ message = +"#{self} and"
294
+ message << " $#{other_name}:" unless other_name.nil?
295
+ message << " #{other} have incompatible units"
296
+ message << " (one has units and the other doesn't)" if unitless? || other_unitless
297
+ return Sass::ScriptError.new(message, name)
298
+ end
299
+
300
+ return Sass::ScriptError.new("Expected #{self} to have no units", name) unless other_unitless
301
+
302
+ if new_numerator_units.length == 1 && new_denominator_units.empty?
303
+ type = Unit::TYPES_BY_UNIT[new_numerator_units.first]
304
+ return Sass::ScriptError.new(
305
+ "Expected #{self} to have a #{type} unit (#{Unit::UNITS_BY_TYPE[type].join(', ')})", name
306
+ )
307
+ end
308
+
309
+ unit_length = new_numerator_units.length + new_denominator_units.length
310
+ units = unit_string(new_numerator_units, new_denominator_units)
311
+ Sass::ScriptError.new("Expected #{self} to have unit#{unit_length > 1 ? 's' : ''} #{units}", name)
312
+ }
313
+
314
+ result = value
315
+
316
+ old_numerator_units = numerator_units.dup
317
+ new_numerator_units.each do |new_numerator_unit|
318
+ index = old_numerator_units.find_index do |old_numerator_unit|
319
+ factor = Unit.conversion_factor(new_numerator_unit, old_numerator_unit)
320
+ if factor.nil?
321
+ false
322
+ else
323
+ result *= factor
324
+ true
325
+ end
326
+ end
327
+ raise compatibility_error.call if index.nil?
328
+
329
+ old_numerator_units.delete_at(index)
330
+ end
331
+
332
+ old_denominator_units = denominator_units.dup
333
+ new_denominator_units.each do |new_denominator_unit|
334
+ index = old_denominator_units.find_index do |old_denominator_unit|
335
+ factor = Unit.conversion_factor(new_denominator_unit, old_denominator_unit)
336
+ if factor.nil?
337
+ false
338
+ else
339
+ result /= factor
340
+ true
341
+ end
342
+ end
343
+ raise compatibility_error.call if index.nil?
344
+
345
+ old_denominator_units.delete_at(index)
346
+ end
347
+
348
+ raise compatibility_error.call unless old_numerator_units.empty? && old_denominator_units.empty?
349
+
350
+ result
351
+ end
352
+
353
+ def unit_string(numerator_units, denominator_units)
354
+ if numerator_units.empty?
355
+ return 'no units' if denominator_units.empty?
356
+
357
+ return denominator_units.length == 1 ? "#{denominator_units.first}^-1" : "(#{denominator_units.join('*')})^-1"
358
+ end
359
+
360
+ return numerator_units.join('*') if denominator_units.empty?
361
+
362
+ "#{numerator_units.join('*')}/#{denominator_units.join('*')}"
363
+ end
364
+ end
365
+ end
366
+ end
@@ -0,0 +1,61 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Sass
4
+ module Value
5
+ # Sass's string type.
6
+ #
7
+ # @see https://sass-lang.com/documentation/js-api/classes/sassstring/
8
+ class String
9
+ include Value
10
+ include CalculationValue
11
+
12
+ # @param text [::String]
13
+ # @param quoted [::Boolean]
14
+ def initialize(text = '', quoted: true)
15
+ @text = text.freeze
16
+ @quoted = quoted
17
+ end
18
+
19
+ # @return [::String]
20
+ attr_reader :text
21
+
22
+ # @return [::Boolean]
23
+ def quoted?
24
+ @quoted
25
+ end
26
+
27
+ # @return [::Boolean]
28
+ def ==(other)
29
+ other.is_a?(Sass::Value::String) && other.text == text
30
+ end
31
+
32
+ # @return [Integer]
33
+ def hash
34
+ @hash ||= text.hash
35
+ end
36
+
37
+ # @return [String]
38
+ def assert_string(_name = nil)
39
+ self
40
+ end
41
+
42
+ # @param sass_index [Number]
43
+ # @return [Integer]
44
+ def sass_index_to_string_index(sass_index, name = nil)
45
+ index = sass_index.assert_number(name).assert_integer(name)
46
+ raise Sass::ScriptError.new('String index may not be 0', name) if index.zero?
47
+
48
+ if index.abs > text.length
49
+ raise Sass::ScriptError.new("Invalid index #{sass_index} for a string with #{text.length} characters", name)
50
+ end
51
+
52
+ index.negative? ? text.length + index : index - 1
53
+ end
54
+
55
+ # @return [String]
56
+ def to_s
57
+ @quoted ? Serializer.serialize_quoted_string(@text) : Serializer.serialize_unquoted_string(@text)
58
+ end
59
+ end
60
+ end
61
+ end