class Sass::Embedded::CompileContext
The {Observer} for {Embedded#compile}.
def canonicalize_response(canonicalize_request)
def canonicalize_response(canonicalize_request) importer = importer_with_id(canonicalize_request.importer_id) url = get_method(importer, :canonicalize).call canonicalize_request.url, from_import: canonicalize_request.from_import EmbeddedProtocol::InboundMessage::CanonicalizeResponse.new( id: canonicalize_request.id, url: url ) rescue StandardError => e EmbeddedProtocol::InboundMessage::CanonicalizeResponse.new( id: canonicalize_request.id, error: e.message ) end
def compile_request
def compile_request EmbeddedProtocol::InboundMessage::CompileRequest.new( id: id, string: unless @source.nil? EmbeddedProtocol::InboundMessage::CompileRequest::StringInput.new( source: @source, url: @url, syntax: to_proto_syntax(@syntax), importer: @importer.nil? ? nil : to_proto_importer(@importer, @importers.length) ) end, path: @path, style: to_proto_output_style(@style), source_map: @source_map, source_map_include_sources: @source_map_include_sources, importers: to_proto_importers(@importers, @load_paths), global_functions: @global_functions, alert_ascii: @alert_ascii, alert_color: @alert_color ) end
def file_import_response(file_import_request)
def file_import_response(file_import_request) file_importer = importer_with_id(file_import_request.importer_id) file_url = get_method(file_importer, :find_file_url).call file_import_request.url, from_import: file_import_request.from_import raise "file_url must be a file: URL, was \"#{file_url}\"" if !file_url.nil? && !file_url.start_with?('file:') EmbeddedProtocol::InboundMessage::FileImportResponse.new( id: file_import_request.id, file_url: file_url ) rescue StandardError => e EmbeddedProtocol::InboundMessage::FileImportResponse.new( id: file_import_request.id, error: e.message ) end
def function_call_response(function_call_request)
def function_call_response(function_call_request) EmbeddedProtocol::InboundMessage::FunctionCallResponse.new( id: function_call_request.id, success: @functions[function_call_request.name].call(*function_call_request.arguments), accessed_argument_lists: function_call_request.arguments .filter { |argument| argument.value == :argument_list } .map { |argument| argument.argument_list.id } ) rescue StandardError => e EmbeddedProtocol::InboundMessage::FunctionCallResponse.new( id: function_call_request.id, error: e.message ) end
def get_attr(obj, sym)
def get_attr(obj, sym) sym = sym.to_sym if obj.respond_to? sym obj.method(sym).call elsif obj.respond_to? :[] if obj[sym] obj[sym] elsif obj[sym.to_s] obj[sym.to_s] end end end
def get_method(obj, sym)
def get_method(obj, sym) sym = sym.to_sym if obj.respond_to? sym obj.method(sym) elsif obj.respond_to? :[] if obj[sym].respond_to? :call obj[sym] elsif obj[sym.to_s].respond_to? :call obj[sym.to_s] end end end
def import_response(import_request)
def import_response(import_request) importer = importer_with_id(import_request.importer_id) importer_result = get_method(importer, :load).call import_request.url EmbeddedProtocol::InboundMessage::ImportResponse.new( id: import_request.id, success: EmbeddedProtocol::InboundMessage::ImportResponse::ImportSuccess.new( contents: get_attr(importer_result, :contents), syntax: to_proto_syntax(get_attr(importer_result, :syntax)), source_map_url: get_attr(importer_result, :source_map_url) ) ) rescue StandardError => e EmbeddedProtocol::InboundMessage::ImportResponse.new( id: import_request.id, error: e.message ) end
def importer_with_id(id)
def importer_with_id(id) if id == @importers.length @importer else @importers[id] end end
def initialize(channel,
def initialize(channel, path:, source:, importer:, load_paths:, syntax:, url:, source_map:, source_map_include_sources:, style:, functions:, importers:, alert_ascii:, alert_color:, logger:, quiet_deps:, verbose:) @path = path @source = source @importer = importer @load_paths = load_paths @syntax = syntax @url = url @source_map = source_map @source_map_include_sources = source_map_include_sources @style = style @global_functions = functions.keys.map(&:to_s) @functions = functions.transform_keys do |key| key.to_s.split('(')[0].chomp end @importers = importers @alert_ascii = alert_ascii @alert_color = alert_color %i[debug warn].each do |sym| instance_variable_set("@#{sym}".to_sym, get_method(logger, sym)) end @quiet_deps = quiet_deps @verbose = verbose super(channel) send_message compile_request end
def log(event)
def log(event) case event.type when :DEBUG if @debug.nil? Kernel.warn(event.formatted) else @debug.call(event.message, span: Logger::SourceSpan.from_proto(event.span)) end when :DEPRECATION_WARNING if @warn.nil? Kernel.warn(event.formatted) else @warn.call(event.message, deprecation: true, span: Logger::SourceSpan.from_proto(event.span), stack: event.stack_trace) end when :WARNING if @warn.nil? Kernel.warn(event.formatted) else @warn.call(event.message, deprecation: false, span: Logger::SourceSpan.from_proto(event.span), stack: event.stack_trace) end end end
def to_proto_importer(importer, id)
def to_proto_importer(importer, id) is_importer = get_method(importer, :canonicalize) && get_method(importer, :load) is_file_importer = get_method(importer, :find_file_url) if is_importer && !is_file_importer EmbeddedProtocol::InboundMessage::CompileRequest::Importer.new( importer_id: id ) elsif is_file_importer && !is_importer EmbeddedProtocol::InboundMessage::CompileRequest::Importer.new( file_importer_id: id ) else raise ArgumentError, 'importer must be an Importer or a FileImporter' end end
def to_proto_importers(importers, load_paths)
def to_proto_importers(importers, load_paths) proto_importers = importers.map.with_index do |importer, id| to_proto_importer(importer, id) end load_paths.each do |load_path| proto_importers << EmbeddedProtocol::InboundMessage::CompileRequest::Importer.new( path: File.absolute_path(load_path) ) end proto_importers end
def to_proto_output_style(style)
def to_proto_output_style(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 end
def to_proto_syntax(syntax)
def to_proto_syntax(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
def update(error, message)
def update(error, message) raise error unless error.nil? case message when EmbeddedProtocol::OutboundMessage::CompileResponse return unless message.id == id Thread.new do super(nil, message) end when EmbeddedProtocol::OutboundMessage::LogEvent return unless message.compilation_id == id log message when EmbeddedProtocol::OutboundMessage::CanonicalizeRequest return unless message.compilation_id == id Thread.new do send_message canonicalize_response message end when EmbeddedProtocol::OutboundMessage::ImportRequest return unless message.compilation_id == id Thread.new do send_message import_response message end when EmbeddedProtocol::OutboundMessage::FileImportRequest return unless message.compilation_id == id Thread.new do send_message file_import_response message end when EmbeddedProtocol::OutboundMessage::FunctionCallRequest return unless message.compilation_id == id Thread.new do send_message function_call_response message end end rescue StandardError => e Thread.new do super(e, nil) end end