sass-embedded 1.74.1-x86-mswin32

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
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