Skip to content
Snippets Groups Projects
generator.py 1.59 KiB
Newer Older
# TODO
# mypy strict_optional=False

import sys
import os
from os import path

from .configuration import (
    SfgConfiguration,
    config_from_commandline,
    merge_configurations,
)
from .context import SfgContext


class SourceFileGenerator:
    """Context manager that controls the code generation process in generator scripts."""
    def __init__(self, sfg_config: SfgConfiguration | None = None):
        if sfg_config and not isinstance(sfg_config, SfgConfiguration):
            raise TypeError("sfg_config is not an SfgConfiguration.")

        import __main__
        scriptpath = __main__.__file__
        scriptname = path.split(scriptpath)[1]
        basename = path.splitext(scriptname)[0]

        project_config, cmdline_config, script_args = config_from_commandline(sys.argv)

        config = merge_configurations(project_config, cmdline_config, sfg_config)

        assert config.codestyle is not None

        self._context = SfgContext(
            config.outer_namespace,
            config.codestyle,
            argv=script_args,
            project_info=config.project_info,
        )

        from .emission import HeaderImplPairEmitter
        self._emitter = HeaderImplPairEmitter(config.get_output_spec(basename))

    def clean_files(self):
        for file in self._emitter.output_files:
            if path.exists(file):
                os.remove(file)

    def __enter__(self) -> SfgContext:
        self.clean_files()
        return self._context

    def __exit__(self, exc_type, exc_value, traceback):
        if exc_type is None:
            self._emitter.write_files(self._context)