defmodule Knigge.Code.Default do @moduledoc false alias Knigge.Code.Delegate alias Knigge.Implementation alias Knigge.Warnings, as: Warn def callback_to_defdefault( {name, arity}, from: module, default: {args, block}, delegate_at_runtime?: false ) do implementation = Implementation.fetch_for!(module) cond do Module.open?(implementation) -> Warn.defdefault_for_open_implementation(module, implementation: implementation, function: {name, arity} ) # The module is being compiled, we need to determine at runtime if delegation can happen callback_to_defdefault( {name, arity}, from: module, default: {args, block}, delegate_at_runtime?: true ) function_exported?(implementation, name, arity) -> # The module is compiled and the function exists, we can simply delegate Delegate.callback_to_defdelegate({name, arity}, from: module, to: implementation) true -> # The module is compiled and the function is missing, we can use the default quote do def unquote(name)(unquote_splicing(args)) do unquote(block) end end end end def callback_to_defdefault( {name, arity}, from: _module, default: {args, block}, delegate_at_runtime?: true ) do quote do def unquote(name)(unquote_splicing(args)) do implementation = __knigge__(:implementation) if function_exported?(implementation, unquote(name), unquote(arity)) do apply(implementation, unquote(name), unquote(args)) else unquote(block) end end end end end