diff options
Diffstat (limited to 'vendor/bundle/ruby/3.4.0/gems/sass-embedded-1.89.2-arm64-darwin/lib/sass/compiler')
10 files changed, 1289 insertions, 0 deletions
diff --git a/vendor/bundle/ruby/3.4.0/gems/sass-embedded-1.89.2-arm64-darwin/lib/sass/compiler/channel.rb b/vendor/bundle/ruby/3.4.0/gems/sass-embedded-1.89.2-arm64-darwin/lib/sass/compiler/channel.rb new file mode 100644 index 0000000..254732b --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/sass-embedded-1.89.2-arm64-darwin/lib/sass/compiler/channel.rb @@ -0,0 +1,70 @@ +# frozen_string_literal: true + +module Sass + class Compiler + # The {Channel} class. + # + # It manages the lifecycle of {Dispatcher}. + class Channel + def initialize(*args, **kwargs, &block) + @args = args + @kwargs = kwargs + @block = block + @dispatcher = Dispatcher.new(*@args, **@kwargs, &@block) + @mutex = Mutex.new + end + + def close + @mutex.synchronize do + unless @dispatcher.nil? + @dispatcher.close + @dispatcher = nil + end + end + end + + def closed? + @mutex.synchronize do + @dispatcher.nil? + end + end + + def stream(host) + @mutex.synchronize do + raise IOError, 'closed compiler' if @dispatcher.nil? + + Stream.new(@dispatcher, host) + rescue Errno::EBUSY + @dispatcher = Dispatcher.new(*@args, **@kwargs, &@block) + Stream.new(@dispatcher, host) + end + end + + # The {Stream} between {Dispatcher} and {Host}. + class Stream + attr_reader :id + + def initialize(dispatcher, host) + @dispatcher = dispatcher + @id = @dispatcher.subscribe(host) + end + + def close + @dispatcher.unsubscribe(@id) + end + + def error(...) + @dispatcher.error(...) + end + + def send_proto(...) + @dispatcher.send_proto(...) + end + end + + private_constant :Stream + end + + private_constant :Channel + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/sass-embedded-1.89.2-arm64-darwin/lib/sass/compiler/connection.rb b/vendor/bundle/ruby/3.4.0/gems/sass-embedded-1.89.2-arm64-darwin/lib/sass/compiler/connection.rb new file mode 100644 index 0000000..d563103 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/sass-embedded-1.89.2-arm64-darwin/lib/sass/compiler/connection.rb @@ -0,0 +1,89 @@ +# frozen_string_literal: true + +require 'open3' + +require_relative '../../../ext/sass/cli' + +module Sass + class Compiler + # The stdio based {Connection} between the {Dispatcher} and the compiler. + # + # It runs the `sass --embedded` command. + class Connection + def initialize + @mutex = Mutex.new + @stdin, @stdout, @stderr, @wait_thread = Open3.popen3(*CLI::COMMAND, '--embedded', chdir: __dir__) + + @stdin.binmode + + # # https://dart.dev/tools/dart-devtools + # if 'dart' == File.basename(CLI::COMMAND.first, '.exe') && CLI::COMMAND.include?('--observe') + # Kernel.warn(@stdout.readline, uplevel: 0) + # Kernel.warn(@stdout.readline, uplevel: 0) + # end + + @stdout.binmode + + @wait_thread.name = "sass-embedded-process-waiter-#{id}" + end + + def id + @wait_thread.pid + end + + def listen(dispatcher) + Thread.new do + Thread.current.name = "sass-embedded-process-stdout-poller-#{id}" + loop do + length = Varint.read(@stdout) + id = Varint.read(@stdout) + proto = @stdout.read(length - Varint.length(id)) + dispatcher.receive_proto(id, proto) + end + rescue IOError, Errno::EBADF, Errno::EPROTO => e + dispatcher.error(e) + @mutex.synchronize do + @stdout.close + end + end + + Thread.new do + Thread.current.name = "sass-embedded-process-stderr-poller-#{id}" + loop do + Kernel.warn(@stderr.readline, uplevel: 0) + end + rescue IOError, Errno::EBADF + @mutex.synchronize do + @stderr.close + end + end + end + + def close + @mutex.synchronize do + @stdin.close + @wait_thread.join + @stdout.close + @stderr.close + end + end + + def closed? + @mutex.synchronize do + @stdin.closed? && !@wait_thread.alive? + end + end + + def write(id, proto) + buffer = [] + Varint.write(buffer, Varint.length(id) + proto.length) + Varint.write(buffer, id) + @mutex.synchronize do + @stdin.write(buffer.pack('C*'), proto) + end + end + end + + private_constant :Connection + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/sass-embedded-1.89.2-arm64-darwin/lib/sass/compiler/dispatcher.rb b/vendor/bundle/ruby/3.4.0/gems/sass-embedded-1.89.2-arm64-darwin/lib/sass/compiler/dispatcher.rb new file mode 100644 index 0000000..bf353d6 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/sass-embedded-1.89.2-arm64-darwin/lib/sass/compiler/dispatcher.rb @@ -0,0 +1,142 @@ +# frozen_string_literal: true + +module Sass + class Compiler + # The {Dispatcher} class. + # + # It dispatches messages between multiple instances of {Host} and a single {Connection} to the compiler. + class Dispatcher + def initialize(idle_timeout: 0) + @id = 1 + @observers = {}.compare_by_identity + @mutex = Mutex.new + @connection = Connection.new + @connection.listen(self) + ForkTracker.add(self) + + return unless idle_timeout.positive? + + @last_accessed_time = current_time + Thread.new do + Thread.current.name = "sass-embedded-connection-reaper-#{@connection.id}" + duration = idle_timeout + loop do + sleep(duration.negative? ? idle_timeout : duration) + break if @mutex.synchronize do + raise Errno::EBUSY if _closed? + + duration = idle_timeout - (current_time - @last_accessed_time) + duration.negative? && _idle? && _close + end + end + close + rescue Errno::EBUSY + # do nothing + end + end + + def subscribe(observer) + @mutex.synchronize do + raise Errno::EBUSY if _closed? + + id = @id + @id = id.next + @observers[id] = observer + id + end + end + + def unsubscribe(id) + @mutex.synchronize do + @observers.delete(id) + + return unless @observers.empty? + + if _closed? + Thread.new do + close + end + else + _idle + end + end + end + + def close + @mutex.synchronize do + _close + end + @connection.close + ForkTracker.delete(self) + end + + def closed? + @connection.closed? + end + + def error(error) + observers = @mutex.synchronize do + _close + @observers.values + end + + if observers.empty? + close + else + observers.each do |observer| + observer.error(error) + end + end + end + + def receive_proto(id, proto) + case id + when 1...0xffffffff + @mutex.synchronize { @observers[id] }&.receive_proto(proto) + when 0 + outbound_message = EmbeddedProtocol::OutboundMessage.decode(proto) + oneof = outbound_message.message + message = outbound_message.public_send(oneof) + @mutex.synchronize { @observers[message.id] }&.public_send(oneof, message) + when 0xffffffff + outbound_message = EmbeddedProtocol::OutboundMessage.decode(proto) + oneof = outbound_message.message + message = outbound_message.public_send(oneof) + raise Errno::EPROTO, message.message + else + raise Errno::EPROTO + end + end + + def send_proto(...) + @connection.write(...) + end + + private + + def current_time + Process.clock_gettime(Process::CLOCK_MONOTONIC) + end + + def _close + @id = 0xffffffff + end + + def _closed? + @id == 0xffffffff + end + + def _idle + @last_accessed_time = current_time if defined?(@last_accessed_time) + + @id = 1 + end + + def _idle? + @id == 1 + end + end + + private_constant :Dispatcher + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/sass-embedded-1.89.2-arm64-darwin/lib/sass/compiler/host.rb b/vendor/bundle/ruby/3.4.0/gems/sass-embedded-1.89.2-arm64-darwin/lib/sass/compiler/host.rb new file mode 100644 index 0000000..8381420 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/sass-embedded-1.89.2-arm64-darwin/lib/sass/compiler/host.rb @@ -0,0 +1,226 @@ +# frozen_string_literal: true + +require_relative 'host/function_registry' +require_relative 'host/importer_registry' +require_relative 'host/logger_registry' +require_relative 'host/protofier' +require_relative 'host/struct' + +module Sass + class Compiler + # The {Host} class. + # + # It communicates with {Dispatcher} and handles the host logic. + class Host + def initialize(channel) + @channel = channel + end + + def compile_request(path:, + source:, + importer:, + load_paths:, + syntax:, + url:, + charset:, + source_map:, + source_map_include_sources:, + style:, + functions:, + importers:, + alert_ascii:, + alert_color:, + fatal_deprecations:, + future_deprecations:, + logger:, + quiet_deps:, + silence_deprecations:, + verbose:) + alert_color = Exception.to_tty? if alert_color.nil? + + @function_registry = FunctionRegistry.new(functions, alert_color:) + @importer_registry = ImporterRegistry.new(importers, load_paths, alert_color:) + @logger_registry = LoggerRegistry.new(logger) + + compile_request = EmbeddedProtocol::InboundMessage::CompileRequest.new( + string: unless source.nil? + EmbeddedProtocol::InboundMessage::CompileRequest::StringInput.new( + source: source.to_str, + url: url&.to_s, + syntax: @importer_registry.syntax_to_proto(syntax), + importer: (@importer_registry.register(importer) unless importer.nil?) + ) + end, + path: (File.absolute_path(path) unless path.nil?), + style: case style&.to_sym + when :expanded + EmbeddedProtocol::OutputStyle::EXPANDED + when :compressed + EmbeddedProtocol::OutputStyle::COMPRESSED + else + raise ArgumentError, 'style must be one of :expanded, :compressed' + end, + charset:, + source_map:, + source_map_include_sources:, + importers: @importer_registry.importers, + global_functions: @function_registry.global_functions, + alert_ascii:, + alert_color:, + fatal_deprecation: fatal_deprecations.map(&:to_s), + future_deprecation: future_deprecations.map(&:to_s), + quiet_deps:, + silent: logger == Logger.silent, + silence_deprecation: silence_deprecations.map(&:to_s), + verbose: + ) + + compile_response = await do + send_message(compile_request:) + end + + oneof = compile_response.result + result = compile_response.public_send(oneof) + case oneof + when :failure + raise CompileError.new( + result.message, + result.formatted == '' ? nil : result.formatted, + result.stack_trace == '' ? nil : result.stack_trace, + result.span.nil? ? nil : Logger::SourceSpan.new(result.span), + compile_response.loaded_urls.to_a + ) + when :success + CompileResult.new( + result.css, + result.source_map == '' ? nil : result.source_map, + compile_response.loaded_urls.to_a + ) + else + raise ArgumentError, "Unknown CompileResponse.result #{result}" + end + end + + def version_request + version_response = await0 do + send_message0(version_request: EmbeddedProtocol::InboundMessage::VersionRequest.new( + id: + )) + end + + info = [ + version_response.implementation_name, + version_response.implementation_version, + '(Sass Compiler)' + ] + + case version_response.implementation_name + when 'dart-sass' + info << (CLI::COMMAND.first == 'node' ? '[JavaScript]' : '[Dart]') + end + + info + end + + def compile_response(message) + @result = message + @queue.close + end + + def version_response(message) + @result = message + @queue.close + end + + def error(message) + case message + when EmbeddedProtocol::ProtocolError + raise Errno::EPROTO, message.message + else + @error ||= message + @queue.close + end + end + + def log_event(message) + @logger_registry.log(message) + end + + def canonicalize_request(message) + send_message(canonicalize_response: @importer_registry.canonicalize(message)) + end + + def import_request(message) + send_message(import_response: @importer_registry.import(message)) + end + + def file_import_request(message) + send_message(file_import_response: @importer_registry.file_import(message)) + end + + def function_call_request(message) + send_message(function_call_response: @function_registry.function_call(message)) + end + + def receive_proto(proto) + @queue.push(proto) + end + + private + + def await0 + listen do + yield + + @queue.pop + end + end + + def await + listen do + yield + + while (proto = @queue.pop) + outbound_message = EmbeddedProtocol::OutboundMessage.decode(proto) + oneof = outbound_message.message + message = outbound_message.public_send(oneof) + public_send(oneof, message) + end + rescue Exception => e # rubocop:disable Lint/RescueException + @stream.error(e) + raise + end + end + + def listen + @queue = Queue.new + @stream = @channel.stream(self) + + yield + + raise @error if @error + + @result + ensure + @stream&.close + @queue&.close + end + + def id + @stream.id + end + + def send_message0(...) + inbound_message = EmbeddedProtocol::InboundMessage.new(...) + @stream.send_proto(0, EmbeddedProtocol::InboundMessage.encode(inbound_message)) + end + + def send_message(...) + inbound_message = EmbeddedProtocol::InboundMessage.new(...) + @stream.send_proto(id, EmbeddedProtocol::InboundMessage.encode(inbound_message)) + end + end + + private_constant :Host + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/sass-embedded-1.89.2-arm64-darwin/lib/sass/compiler/host/function_registry.rb b/vendor/bundle/ruby/3.4.0/gems/sass-embedded-1.89.2-arm64-darwin/lib/sass/compiler/host/function_registry.rb new file mode 100644 index 0000000..108451a --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/sass-embedded-1.89.2-arm64-darwin/lib/sass/compiler/host/function_registry.rb @@ -0,0 +1,87 @@ +# frozen_string_literal: true + +module Sass + class Compiler + class Host + # The {FunctionRegistry} class. + # + # It stores sass custom functions and handles function calls. + class FunctionRegistry + attr_reader :compile_context, :global_functions + + def initialize(functions, alert_color:) + @compile_context = Object.new + @global_functions = functions.keys.map!(&:to_s) + @functions_by_name = functions.transform_keys do |signature| + signature = signature.to_s + index = signature.index('(') + if index + signature.slice(0, index) + else + signature + end + end + + @id = 0 + @functions_by_id = {}.compare_by_identity + @ids_by_function = {}.compare_by_identity + + @highlight = alert_color + end + + def register(function) + @ids_by_function.fetch(function) do |fn| + id = @id + @id = id.next + + @functions_by_id[id] = fn + @ids_by_function[fn] = id + end + end + + def function_call(function_call_request) + oneof = function_call_request.identifier + identifier = function_call_request.public_send(oneof) + function = case oneof + when :name + @functions_by_name[identifier] + when :function_id + @functions_by_id[identifier] + else + raise ArgumentError, "Unknown FunctionCallRequest.identifier #{identifier}" + end + + arguments = function_call_request.arguments.map do |argument| + protofier.from_proto(argument) + end + + success = protofier.to_proto(function.call(arguments)) + accessed_argument_lists = arguments.filter_map do |argument| + if argument.is_a?(Sass::Value::ArgumentList) && argument.instance_variable_get(:@keywords_accessed) + argument.instance_variable_get(:@id) + end + end + + EmbeddedProtocol::InboundMessage::FunctionCallResponse.new( + id: function_call_request.id, + success:, + accessed_argument_lists: + ) + rescue StandardError => e + EmbeddedProtocol::InboundMessage::FunctionCallResponse.new( + id: function_call_request.id, + error: e.full_message(highlight: @highlight, order: :top) + ) + end + + private + + def protofier + @protofier ||= Protofier.new(self) + end + end + + private_constant :FunctionRegistry + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/sass-embedded-1.89.2-arm64-darwin/lib/sass/compiler/host/importer_registry.rb b/vendor/bundle/ruby/3.4.0/gems/sass-embedded-1.89.2-arm64-darwin/lib/sass/compiler/host/importer_registry.rb new file mode 100644 index 0000000..472ea4c --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/sass-embedded-1.89.2-arm64-darwin/lib/sass/compiler/host/importer_registry.rb @@ -0,0 +1,147 @@ +# frozen_string_literal: true + +module Sass + class Compiler + class Host + # The {ImporterRegistry} class. + # + # It stores importers and handles import requests. + class ImporterRegistry + attr_reader :importers + + def initialize(importers, load_paths, alert_color:) + @id = 0 + @importers_by_id = {}.compare_by_identity + @importers = importers + .map { |importer| register(importer) } + .concat( + load_paths.map do |load_path| + EmbeddedProtocol::InboundMessage::CompileRequest::Importer.new( + path: File.absolute_path(load_path) + ) + end + ) + + @highlight = alert_color + end + + IMPORTER_ATTRS = %i[non_canonical_scheme].freeze + + IMPORTER_METHODS = %i[canonicalize load find_file_url].freeze + + private_constant :IMPORTER_ATTRS, :IMPORTER_METHODS + + def register(importer) + if importer.is_a?(Sass::NodePackageImporter) + EmbeddedProtocol::InboundMessage::CompileRequest::Importer.new( + node_package_importer: EmbeddedProtocol::NodePackageImporter.new( + entry_point_directory: importer.instance_variable_get(:@entry_point_directory) + ) + ) + else + importer = Struct.new(importer, attrs: IMPORTER_ATTRS, methods: IMPORTER_METHODS) if importer.is_a?(::Hash) + + is_importer = importer.respond_to?(:canonicalize) && importer.respond_to?(:load) + is_file_importer = importer.respond_to?(:find_file_url) + + raise ArgumentError, 'importer must be an Importer or a FileImporter' if is_importer == is_file_importer + + id = @id + @id = id.next + + @importers_by_id[id] = importer + if is_importer + EmbeddedProtocol::InboundMessage::CompileRequest::Importer.new( + importer_id: id, + non_canonical_scheme: if importer.respond_to?(:non_canonical_scheme) + Array(importer.non_canonical_scheme) + else + [] + end + ) + else + EmbeddedProtocol::InboundMessage::CompileRequest::Importer.new( + file_importer_id: id + ) + end + end + end + + def canonicalize(canonicalize_request) + importer = @importers_by_id[canonicalize_request.importer_id] + canonicalize_context = CanonicalizeContext.new(canonicalize_request) + url = importer.canonicalize(canonicalize_request.url, + canonicalize_context)&.to_s + + EmbeddedProtocol::InboundMessage::CanonicalizeResponse.new( + id: canonicalize_request.id, + url:, + containing_url_unused: canonicalize_context.instance_variable_get(:@containing_url_unused) + ) + rescue StandardError => e + EmbeddedProtocol::InboundMessage::CanonicalizeResponse.new( + id: canonicalize_request.id, + error: e.full_message(highlight: @highlight, order: :top) + ) + end + + IMPORTER_RESULT_ATTRS = %i[contents syntax source_map_url].freeze + + private_constant :IMPORTER_RESULT_ATTRS + + def import(import_request) + importer = @importers_by_id[import_request.importer_id] + importer_result = importer.load(import_request.url) + importer_result = Struct.new(importer_result, attrs: IMPORTER_RESULT_ATTRS) if importer_result.is_a?(::Hash) + + EmbeddedProtocol::InboundMessage::ImportResponse.new( + id: import_request.id, + success: EmbeddedProtocol::InboundMessage::ImportResponse::ImportSuccess.new( + contents: importer_result.contents.to_str, + syntax: syntax_to_proto(importer_result.syntax), + source_map_url: (importer_result.source_map_url&.to_s if importer_result.respond_to?(:source_map_url)) + ) + ) + rescue StandardError => e + EmbeddedProtocol::InboundMessage::ImportResponse.new( + id: import_request.id, + error: e.full_message(highlight: @highlight, order: :top) + ) + end + + def file_import(file_import_request) + importer = @importers_by_id[file_import_request.importer_id] + canonicalize_context = CanonicalizeContext.new(file_import_request) + file_url = importer.find_file_url(file_import_request.url, + canonicalize_context)&.to_s + + EmbeddedProtocol::InboundMessage::FileImportResponse.new( + id: file_import_request.id, + file_url:, + containing_url_unused: canonicalize_context.instance_variable_get(:@containing_url_unused) + ) + rescue StandardError => e + EmbeddedProtocol::InboundMessage::FileImportResponse.new( + id: file_import_request.id, + error: e.full_message(highlight: @highlight, order: :top) + ) + end + + def syntax_to_proto(syntax) + case syntax&.to_sym + when :scss + EmbeddedProtocol::Syntax::SCSS + when :indented + EmbeddedProtocol::Syntax::INDENTED + when :css + EmbeddedProtocol::Syntax::CSS + else + raise ArgumentError, 'syntax must be one of :scss, :indented, :css' + end + end + end + + private_constant :ImporterRegistry + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/sass-embedded-1.89.2-arm64-darwin/lib/sass/compiler/host/logger_registry.rb b/vendor/bundle/ruby/3.4.0/gems/sass-embedded-1.89.2-arm64-darwin/lib/sass/compiler/host/logger_registry.rb new file mode 100644 index 0000000..0f79050 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/sass-embedded-1.89.2-arm64-darwin/lib/sass/compiler/host/logger_registry.rb @@ -0,0 +1,77 @@ +# frozen_string_literal: true + +module Sass + class Compiler + class Host + # The {LoggerRegistry} class. + # + # It stores logger and handles log events. + class LoggerRegistry + LOGGER_METHODS = %i[debug warn].freeze + + private_constant :LOGGER_METHODS + + def initialize(logger) + logger = Struct.new(logger, methods: LOGGER_METHODS) if logger.is_a?(::Hash) + @logger = logger + @logger_respond_to_debug = logger.respond_to?(:debug) + @logger_respond_to_warn = logger.respond_to?(:warn) + end + + def log(event) + case event.type + when :DEBUG + if @logger_respond_to_debug + @logger.debug(event.message, DebugContext.new(event)) + else + Kernel.warn(event.formatted) + end + when :DEPRECATION_WARNING, :WARNING + if @logger_respond_to_warn + @logger.warn(event.message, WarnContext.new(event)) + else + Kernel.warn(event.formatted) + end + else + raise ArgumentError, "Unknown LogEvent.type #{event.type}" + end + end + + # Contextual information passed to `debug`. + class DebugContext + # @return [Logger::SourceSpan, nil] + attr_reader :span + + def initialize(event) + @span = event.span.nil? ? nil : Logger::SourceSpan.new(event.span) + end + end + + private_constant :DebugContext + + # Contextual information passed to `warn`. + class WarnContext < DebugContext + # @return [Boolean] + attr_reader :deprecation + + # @return [String, nil] + attr_reader :deprecation_type + + # @return [String] + attr_reader :stack + + def initialize(event) + super + @deprecation = event.type == :DEPRECATION_WARNING + @deprecation_type = (event.deprecation_type if @deprecation) + @stack = event.stack_trace + end + end + + private_constant :WarnContext + end + + private_constant :LoggerRegistry + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/sass-embedded-1.89.2-arm64-darwin/lib/sass/compiler/host/protofier.rb b/vendor/bundle/ruby/3.4.0/gems/sass-embedded-1.89.2-arm64-darwin/lib/sass/compiler/host/protofier.rb new file mode 100644 index 0000000..3ab6519 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/sass-embedded-1.89.2-arm64-darwin/lib/sass/compiler/host/protofier.rb @@ -0,0 +1,376 @@ +# frozen_string_literal: true + +module Sass + class Compiler + class Host + # The {Protofier} class. + # + # It converts Pure Ruby types and Protobuf Ruby types. + class Protofier + def initialize(function_registry) + @function_registry = function_registry + end + + def to_proto(obj) + case obj + when Sass::Value::String + EmbeddedProtocol::Value.new( + string: EmbeddedProtocol::Value::String.new( + text: obj.text.to_str, + quoted: obj.quoted? + ) + ) + when Sass::Value::Number + EmbeddedProtocol::Value.new( + number: Number.to_proto(obj) + ) + when Sass::Value::Color + EmbeddedProtocol::Value.new( + color: EmbeddedProtocol::Value::Color.new( + channel1: obj.send(:channel0_or_nil), + channel2: obj.send(:channel1_or_nil), + channel3: obj.send(:channel2_or_nil), + alpha: obj.send(:alpha_or_nil), + space: obj.space + ) + ) + when Sass::Value::ArgumentList + if obj.instance_variable_get(:@compile_context) == @function_registry.compile_context + EmbeddedProtocol::Value.new( + argument_list: EmbeddedProtocol::Value::ArgumentList.new( + id: obj.instance_variable_get(:@id) + ) + ) + else + EmbeddedProtocol::Value.new( + argument_list: EmbeddedProtocol::Value::ArgumentList.new( + contents: obj.to_a.map { |element| to_proto(element) }, + keywords: obj.keywords.each_with_object({}) { |(key, value), hash| hash[key.to_s] = to_proto(value) }, + separator: ListSeparator.to_proto(obj.separator) + ) + ) + end + when Sass::Value::List + EmbeddedProtocol::Value.new( + list: EmbeddedProtocol::Value::List.new( + contents: obj.to_a.map { |element| to_proto(element) }, + separator: ListSeparator.to_proto(obj.separator), + has_brackets: obj.bracketed? + ) + ) + when Sass::Value::Map + EmbeddedProtocol::Value.new( + map: EmbeddedProtocol::Value::Map.new( + entries: obj.contents.map do |key, value| + EmbeddedProtocol::Value::Map::Entry.new( + key: to_proto(key), + value: to_proto(value) + ) + end + ) + ) + when Sass::Value::Function + if obj.instance_variable_defined?(:@id) + EmbeddedProtocol::Value.new( + compiler_function: EmbeddedProtocol::Value::CompilerFunction.new( + id: assert_compiler_value(obj).instance_variable_get(:@id) + ) + ) + else + EmbeddedProtocol::Value.new( + host_function: EmbeddedProtocol::Value::HostFunction.new( + id: @function_registry.register(obj.callback), + signature: obj.signature + ) + ) + end + when Sass::Value::Mixin + EmbeddedProtocol::Value.new( + compiler_mixin: EmbeddedProtocol::Value::CompilerMixin.new( + id: assert_compiler_value(obj).instance_variable_get(:@id) + ) + ) + when Sass::Value::Calculation + EmbeddedProtocol::Value.new( + calculation: Calculation.to_proto(obj) + ) + when Sass::Value::Boolean + EmbeddedProtocol::Value.new( + singleton: obj.value ? :TRUE : :FALSE + ) + when Sass::Value::Null + EmbeddedProtocol::Value.new( + singleton: :NULL + ) + else + raise Sass::ScriptError, "Unknown Sass::Value #{obj}" + end + end + + def from_proto(proto) + oneof = proto.value + obj = proto.public_send(oneof) + case oneof + when :string + Sass::Value::String.new( + obj.text, + quoted: obj.quoted + ) + when :number + Number.from_proto(obj) + when :color + Sass::Value::Color.send( + :for_space, + obj.space, + obj.has_channel1? ? obj.channel1 : nil, + obj.has_channel2? ? obj.channel2 : nil, + obj.has_channel3? ? obj.channel3 : nil, + obj.has_alpha? ? obj.alpha : nil + ) + when :argument_list + compiler_value( + Sass::Value::ArgumentList.new( + obj.contents.map do |element| + from_proto(element) + end, + obj.keywords.to_enum.with_object({}) do |(key, value), hash| + hash[key.to_sym] = from_proto(value) + end, + ListSeparator.from_proto(obj.separator) + ), + obj.id + ) + when :list + Sass::Value::List.new( + obj.contents.map do |element| + from_proto(element) + end, + separator: ListSeparator.from_proto(obj.separator), + bracketed: obj.has_brackets + ) + when :map + Sass::Value::Map.new( + obj.entries.to_enum.with_object({}) do |entry, hash| + hash[from_proto(entry.key)] = from_proto(entry.value) + end + ) + when :compiler_function + compiler_value(Sass::Value::Function.allocate, obj.id) + when :host_function + raise Sass::ScriptError, 'The compiler may not send Value.host_function to host' + when :compiler_mixin + compiler_value(Sass::Value::Mixin.allocate, obj.id) + when :calculation + Calculation.from_proto(obj) + when :singleton + case obj + when :TRUE + Sass::Value::Boolean::TRUE + when :FALSE + Sass::Value::Boolean::FALSE + when :NULL + Sass::Value::Null::NULL + else + raise Sass::ScriptError, "Unknown Value.singleton #{obj}" + end + else + raise Sass::ScriptError, "Unknown Value.value #{obj}" + end + end + + private + + def assert_compiler_value(value) + unless value.instance_variable_get(:@compile_context) == @function_registry.compile_context + raise Sass::ScriptError, "Value #{value} does not belong to this compilation" + end + + value + end + + def compiler_value(value, id) + value.instance_variable_set(:@compile_context, @function_registry.compile_context) + value.instance_variable_set(:@id, id) + value + end + + # The {Number} Protofier. + module Number + module_function + + def to_proto(obj) + EmbeddedProtocol::Value::Number.new( + value: obj.value.to_f, + numerators: obj.numerator_units, + denominators: obj.denominator_units + ) + end + + def from_proto(obj) + Sass::Value::Number.new( + obj.value, { + numerator_units: obj.numerators.to_a, + denominator_units: obj.denominators.to_a + } + ) + end + end + + private_constant :Number + + # The {Calculation} Protofier. + module Calculation + module_function + + def to_proto(obj) + EmbeddedProtocol::Value::Calculation.new( + name: obj.name, + arguments: obj.arguments.map { |argument| CalculationValue.to_proto(argument) } + ) + end + + def from_proto(obj) + Sass::Value::Calculation.send( + :new, + obj.name, + obj.arguments.map { |argument| CalculationValue.from_proto(argument) } + ) + end + end + + private_constant :Calculation + + # The {CalculationValue} Protofier. + module CalculationValue + module_function + + def to_proto(value) + case value + when Sass::Value::Number + EmbeddedProtocol::Value::Calculation::CalculationValue.new( + number: Number.to_proto(value) + ) + when Sass::Value::Calculation + EmbeddedProtocol::Value::Calculation::CalculationValue.new( + calculation: Calculation.to_proto(value) + ) + when Sass::Value::String + EmbeddedProtocol::Value::Calculation::CalculationValue.new( + string: value.text + ) + when Sass::CalculationValue::CalculationOperation + EmbeddedProtocol::Value::Calculation::CalculationValue.new( + operation: EmbeddedProtocol::Value::Calculation::CalculationOperation.new( + operator: CalculationOperator.to_proto(value.operator), + left: to_proto(value.left), + right: to_proto(value.right) + ) + ) + else + raise Sass::ScriptError, "Unknown CalculationValue #{value}" + end + end + + def from_proto(value) + oneof = value.value + obj = value.public_send(oneof) + case oneof + when :number + Number.from_proto(obj) + when :calculation + Calculation.from_proto(obj) + when :string + Sass::Value::String.new(obj, quoted: false) + when :operation + Sass::CalculationValue::CalculationOperation.new( + CalculationOperator.from_proto(obj.operator), + from_proto(obj.left), + from_proto(obj.right) + ) + else + raise Sass::ScriptError, "Unknown CalculationValue #{value}" + end + end + end + + private_constant :CalculationValue + + # The {CalculationOperator} Protofier. + module CalculationOperator + module_function + + def to_proto(operator) + case operator + when '+' + :PLUS + when '-' + :MINUS + when '*' + :TIMES + when '/' + :DIVIDE + else + raise Sass::ScriptError, "Unknown CalculationOperator #{separator}" + end + end + + def from_proto(operator) + case operator + when :PLUS + '+' + when :MINUS + '-' + when :TIMES + '*' + when :DIVIDE + '/' + else + raise Sass::ScriptError, "Unknown CalculationOperator #{separator}" + end + end + end + + private_constant :CalculationOperator + + # The {ListSeparator} Protofier. + module ListSeparator + module_function + + def to_proto(separator) + case separator + when ',' + :COMMA + when ' ' + :SPACE + when '/' + :SLASH + when nil + :UNDECIDED + else + raise Sass::ScriptError, "Unknown ListSeparator #{separator}" + end + end + + def from_proto(separator) + case separator + when :COMMA + ',' + when :SPACE + ' ' + when :SLASH + '/' + when :UNDECIDED + nil + else + raise Sass::ScriptError, "Unknown ListSeparator #{separator}" + end + end + end + + private_constant :ListSeparator + end + + private_constant :Protofier + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/sass-embedded-1.89.2-arm64-darwin/lib/sass/compiler/host/struct.rb b/vendor/bundle/ruby/3.4.0/gems/sass-embedded-1.89.2-arm64-darwin/lib/sass/compiler/host/struct.rb new file mode 100644 index 0000000..75a7399 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/sass-embedded-1.89.2-arm64-darwin/lib/sass/compiler/host/struct.rb @@ -0,0 +1,36 @@ +# frozen_string_literal: true + +module Sass + class Compiler + class Host + # The {Struct} class. + # + # It creates {::Struct}-like objects from {::Hash}. + class Struct + def initialize(hash, attrs: nil, methods: nil) + @hash = hash + @attrs = attrs + @methods = methods + end + + def method_missing(symbol, ...) + return super unless @hash.key?(symbol) + + if @attrs&.include?(symbol) + @hash.send(:[], symbol, ...) + elsif @methods&.include?(symbol) + @hash[symbol].call(...) + else + super + end + end + + def respond_to_missing?(symbol, _include_all) + @hash.key?(symbol) && (@attrs&.include?(symbol) || @methods&.include?(symbol)) + end + end + + private_constant :Struct + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/sass-embedded-1.89.2-arm64-darwin/lib/sass/compiler/varint.rb b/vendor/bundle/ruby/3.4.0/gems/sass-embedded-1.89.2-arm64-darwin/lib/sass/compiler/varint.rb new file mode 100644 index 0000000..7987779 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/sass-embedded-1.89.2-arm64-darwin/lib/sass/compiler/varint.rb @@ -0,0 +1,39 @@ +# frozen_string_literal: true + +module Sass + class Compiler + # The {Varint} module. + # + # It reads and writes varints. + module Varint + module_function + + def length(value) + return 1 if value < 128 + + (value.bit_length + 6) / 7 + end + + def read(readable) + value = bits = 0 + loop do + byte = readable.readbyte + value |= (byte & 0x7f) << bits + bits += 7 + break if byte < 0x80 + end + value + end + + def write(writeable, value) + until value < 0x80 + writeable << ((value & 0x7f) | 0x80) + value >>= 7 + end + writeable << value + end + end + + private_constant :Varint + end +end |
