# frozen_string_literal: truerequire'opal/compiler'require'opal/erb'moduleOpalmoduleBuilderProcessorsclassProcessordefinitialize(source,filename,abs_path=nil,options={})options=abs_pathifabs_path.is_a?Hashsource+="\n"unlesssource.end_with?("\n")@source,@filename,@abs_path,@options=source,filename,abs_path,options.dup@cache=@options.delete(:cache){Opal.cache}@requires=[]@required_trees=[]@autoloads=[]endattr_reader:source,:filename,:options,:requires,:required_trees,:autoloads,:abs_pathdefto_ssource.to_sendclass<<selfattr_reader:extensionsdefhandles(*extensions)@extensions=extensionsmatches=extensions.join('|')matches="(#{matches})"unlessextensions.size==1@match_regexp=Regexp.new"\\.#{matches}#{REGEXP_END}"::Opal::Builder.register_processor(self,extensions)nilenddefmatch?(other)other.is_a?(String)&&other.match(match_regexp)enddefmatch_regexp@match_regexp||raise(NotImplementedError)endenddefmark_as_required(filename)"Opal.loaded([#{filename.to_s.inspect}]);"endendclassJsProcessor<Processorhandles:jsManualFragment=Struct.new(:line,:column,:code,:source_map_name)defsource_map@source_map||=beginmanual_fragments=source.each_line.with_index.mapdo|line_source,index|column=line_source.index(/\S/)line=index+1ManualFragment.new(line,column,line_source,nil)end::Opal::SourceMap::File.new(manual_fragments,filename,source)endenddefsource@source.to_s+mark_as_required(@filename)endendclassRubyProcessor<Processorhandles:rb,:opaldefsourcecompiled.resultenddefsource_mapcompiled.source_mapenddefcompiled@compiled||=Opal::Cache.fetch(@cache,cache_key)docompiler=compiler_for(@source,file: @filename)compiler.compilecompilerendenddefcache_key[self.class,@filename,@source,@options]enddefcompiler_for(source,options={})::Opal::Compiler.new(source,@options.merge(options))enddefrequirescompiled.requiresenddefrequired_treescompiled.required_treesenddefautoloadscompiled.autoloadsend# Also catch a files with missing extensions and nil.defself.match?(other)super||File.extname(other.to_s)==''endend# This handler is for files named ".opalerb", which ought to# first get compiled to Ruby code using ERB, then with Opal.# Unlike below processors, OpalERBProcessor can be used to# compile templates, which will in turn output HTML. Take# a look at docs/templates.md to understand this subsystem# better.classOpalERBProcessor<RubyProcessorhandles:opalerbdefinitialize(*args)super@source=prepare(@source,@filename)enddefrequires['erb']+superendprivatedefprepare(source,path)::Opal::ERB::Compiler.new(source,path).prepared_sourceendend# This handler is for files named ".rb.erb", which ought to# first get preprocessed via ERB, then via Opal.classRubyERBProcessor<RubyProcessorhandles:"rb.erb"defcompiled@compiled||=beginerb=::ERB.new(@source.to_s)erb.filename=@abs_path@source=erb.resultcompiler=compiler_for(@source,file: @filename)compiler.compilecompilerendendend# This handler is for files named ".js.erb", which ought to# first get preprocessed via ERB, then served verbatim as JS.classERBProcessor<Processorhandles:erbdefsourceerb=::ERB.new(@source.to_s)erb.filename=@abs_pathresult=erb.resultmodule_name=::Opal::Compiler.module_name(@filename)"Opal.modules[#{module_name.inspect}] = function() {#{result}};"endendendend