Class: Rjq::Compiler
- Inherits:
-
Object
- Object
- Rjq::Compiler
- Defined in:
- lib/rjq/compiler.rb
Constant Summary collapse
- OPTION_KEYS =
%i[allow_comments library_path max_filter_depth module_resolver source_path].freeze
Class Method Summary collapse
Instance Method Summary collapse
- #compile(filter_string) ⇒ Object
-
#initialize(opts = {}) ⇒ Compiler
constructor
A new instance of Compiler.
Constructor Details
#initialize(opts = {}) ⇒ Compiler
Returns a new instance of Compiler.
357 358 359 |
# File 'lib/rjq/compiler.rb', line 357 def initialize(opts = {}) @opts = self.class.(opts) end |
Class Method Details
.normalize_options(opts) ⇒ Object
313 314 315 316 317 318 |
# File 'lib/rjq/compiler.rb', line 313 def (opts) (opts) normalized = opts.dup normalized[:library_path] = normalized[:library_path].dup.freeze if normalized[:library_path] normalized.freeze end |
.options_from(opts) ⇒ Object
295 296 297 |
# File 'lib/rjq/compiler.rb', line 295 def (opts) opts.slice(*OPTION_KEYS) end |
.validate_options!(opts) ⇒ Object
299 300 301 302 303 304 305 306 307 308 309 310 311 |
# File 'lib/rjq/compiler.rb', line 299 def (opts) raise ArgumentError, 'options must be a Hash' unless opts.is_a?(Hash) unknown = opts.keys - OPTION_KEYS raise ArgumentError, "unknown compiler option: #{unknown.first.inspect}" unless unknown.empty? validate_boolean!(opts, :allow_comments) validate_optional_string!(opts, :source_path) validate_positive_integer!(opts, :max_filter_depth) validate_library_path!(opts[:library_path]) if opts.key?(:library_path) validate_module_resolver!(opts[:module_resolver]) if opts.key?(:module_resolver) opts end |
Instance Method Details
#compile(filter_string) ⇒ Object
361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 |
# File 'lib/rjq/compiler.rb', line 361 def compile(filter_string) max_filter_depth = @opts.fetch(:max_filter_depth, Parser::DEFAULT_MAX_FILTER_DEPTH) source_path = @opts[:source_path] || '<top-level>' parsed = Parser.new(filter_string, allow_comments: @opts.fetch(:allow_comments, true), source_name: source_path, max_filter_depth: max_filter_depth).parse resolver = @opts[:module_resolver] || default_module_resolver allow_comments = @opts.fetch(:allow_comments, true) loaded = ModuleLoader.new(resolver, allow_comments: allow_comments, max_filter_depth: max_filter_depth).load(parsed, source_path: @opts[:source_path]) ast = loaded.program program = BytecodeCompiler.new(allow_comments: allow_comments, max_filter_depth: max_filter_depth).compile( ast, module_metadata: loaded., module_variables: loaded.variables ) SemanticAnalyzer.new(program).validate! program.finalize! CompiledProgram.new(ast, program: program) rescue SystemStackError raise CompileError, "filter nesting exceeds safe parser/compiler depth in #{source_path}" end |