lib/opal/nodes/def.rb
# 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 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) stmt_code = stmt(compiler.returns(stmts)) compile_block_arg add_temp 'self = this' compile_arity_check unshift "\n#{current_indent}", scope.to_vars line stmt_code if scope.catch_return unshift "try {\n" line '} catch ($returner) { if ($returner === Opal.returner) { return $returner.$v }' push ' throw $returner; }' end end # There are some special utf8 chars that can be used as valid JS # identifiers, some examples: # # utf8_pond = 'ⵌ' # utf8_question = 'ʔ̣' # utf8_exclamation 'ǃ' # # For now we're just using $$, to maintain compatibility with older IEs. function_name = valid_name?(mid) ? " $$#{mid}" : '' unshift ') {' unshift(inline_params) unshift "function#{function_name}(" if await_encountered unshift "async " end unshift "#{scope_name} = " if scope_name line '}' push ", #{scope_name}.$$arity = #{arity}" if compiler.arity_check? push ", #{scope_name}.$$parameters = #{parameters_code}" end if compiler.parse_comments? push ", #{scope_name}.$$comments = #{comments_code}" end if compiler.enable_source_location? push ", #{scope_name}.$$source_location = #{source_location}" end wrap_with_definition end def wrap_with_definition wrap "Opal.def(self, '$#{mid}', ", ')' if expr? wrap '(', ", nil) && '#{mid}'" else unshift "\n#{current_indent}" end end def comments_code '[' + comments.map { |comment| comment.text.inspect }.join(', ') + ']' end end end end