# frozen_string_literal: true require 'opal/nodes/node_with_args' module Opal module Nodes class DefNode < NodeWithArgs handle :def children :mid, :inline_args, :stmts def compile compile_body_or_shortcut blockopts = {} blockopts["$$arity"] = arity if arity < 0 if compiler.arity_check? blockopts["$$parameters"] = parameters_code end if compiler.parse_comments? blockopts["$$comments"] = comments_code end if compiler.enable_source_location? blockopts["$$source_location"] = source_location end if blockopts.keys == ["$$arity"] push ", #{arity}" elsif !blockopts.empty? push ', {', blockopts.map { |k, v| "#{k}: #{v}" }.join(', '), '}' end wrap_with_definition scope.nesting if @define_nesting scope.relative_access if @define_relative_access end def compile_body inline_params = nil scope_name = nil in_scope do scope.mid = mid scope.defs = true if @sexp.type == :defs scope.identify! scope_name = scope.identity # Setting a default block name (later can be overwritten by a blockarg) scope.block_name = '$yield' inline_params = process(inline_args) in_closure(Closure::DEF | Closure::JS_FUNCTION) do stmt_code = stmt(compiler.returns(stmts)) compile_block_arg add_temp 'self = this' if @define_self compile_arity_check unshift "\n#{current_indent}", scope.to_vars line stmt_code end end unshift ') {' unshift(inline_params) unshift "function #{scope_name}(" if await_encountered unshift "async " end line '}' end def wrap_with_definition helper :def wrap "$def(#{scope.self}, '$#{mid}', ", ')' unshift "\n#{current_indent}" unless expr? end def comments_code '[' + comments.map { |comment| comment.text.inspect }.join(', ') + ']' end end end end