{#     Copyright 2023, Kay Hayen, mailto:kay.hayen@gmail.com                    #}
{#                                                                              #}
{#     Part of "Nuitka", an optimizing Python compiler that is compatible and   #}
{#     integrates with CPython, but also works on its own.                      #}
{#                                                                              #}
{#     Licensed under the Apache License, Version 2.0 (the "License");          #}
{#     you may not use this file except in compliance with the License.         #}
{#     You may obtain a copy of the License at                                  #}
{#                                                                              #}
{#        http://www.apache.org/licenses/LICENSE-2.0                            #}
{#                                                                              #}
{#     Unless required by applicable law or agreed to in writing, software      #}
{#     distributed under the License is distributed on an "AS IS" BASIS,        #}
{#     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. #}
{#     See the License for the specific language governing permissions and      #}
{#     limitations under the License.                                           #}
{#                                                                              #}
{% macro apply_builtin_extraction(spec_name, call_suffix) %}
from nuitka.nodes.{{call_node_module_name}} import {{translateNodeClassName("Expression" + module_name_title + function_name_title + call_suffix + "Call")}}

result = extractBuiltinArgs(
    node=call_node,
    builtin_class={{translateNodeClassName("Expression" + module_name_title + function_name_title + call_suffix + "Call")}},
    builtin_spec={{spec_name}},
)

return (
    result,
    "new_expression",
    "Call to '{{module_name}}.{{function_name}}' recognized.",
)
{% endmacro %}

from nuitka.Options import shallMakeModule
from nuitka.PythonVersions import python_version
from nuitka.nodes.ImportHardNodes import ExpressionImportModuleNameHardExistsSpecificBase
from nuitka.specs.BuiltinParameterSpecs import extractBuiltinArgs
from nuitka.specs.HardImportSpecs import (
{% for spec in specs %}
    {{spec.spec_name}},
{% endfor %}
)
{% if module_name == "os.path" %}
import os
{% endif %}

class Expression{{module_name_title}}{{function_name_title}}Ref(
    ExpressionImportModuleNameHardExistsSpecificBase
):
    """Function reference {{module_name}}.{{function_name}}"""

    kind = "EXPRESSION_{{module_name_code.upper()}}_{{function_name_code.upper()}}_REF"

    def __init__(self, source_ref):
        ExpressionImportModuleNameHardExistsSpecificBase.__init__(
            self,
            module_name={%if module_name != 'os.path'%}"{{module_name}}" {% else %} os.path.__name__{% endif %},
            import_name="{{function_name}}",
            module_guaranteed={% if is_stdlib %}True{% else %}not shallMakeModule(){% endif %},
            source_ref=source_ref,
        )

    def computeExpressionCall(self, call_node, call_args, call_kw, trace_collection):
        # Anything may happen on call trace before this. On next pass, if
        # replaced, we might be better but not now.
        trace_collection.onExceptionRaiseExit(BaseException)

{% for spec in specs %}
{% if spec.python_criterion %}
        if python_version {{spec.python_criterion}}:
{{apply_builtin_extraction(spec.spec_name, spec.suffix)| indent(12, True)}}
{% else %}
{{apply_builtin_extraction(spec.spec_name, spec.suffix)| indent(8, True)}}
{% endif %}
{% endfor %}

hard_import_node_classes[Expression{{module_name_title}}{{function_name_title}}Ref] = {{specs[0].spec_name}}
