예제 #1
0
    def emit_gdb_helpers(self, ctx: CompileCtx) -> None:
        """
        Emit support files for GDB helpers.
        """
        lib_name = ctx.ada_api_settings.lib_name.lower()
        gdbinit_path = os.path.join(self.lib_root, 'gdbinit.py')
        gdb_c_path = os.path.join(self.src_dir, '{}-gdb.c'.format(lib_name))

        # Always emit the ".gdbinit.py" GDB script
        write_source_file(
            gdbinit_path,
            ctx.render_template(
                'gdb_py',
                langkit_path=os.path.dirname(os.path.dirname(__file__)),
                lib_name=lib_name,
                prefix=ctx.short_name_or_long,
            ), self.post_process_python)

        # Generate the C file to embed the absolute path to this script in the
        # generated library only if requested.
        if self.generate_gdb_hook:
            write_source_file(
                gdb_c_path,
                ctx.render_template('gdb_c',
                                    gdbinit_path=gdbinit_path,
                                    os_name=os.name), self.post_process_cpp)
            self.project_languages.add('C')
예제 #2
0
    def emit_ocaml_api(self, ctx: CompileCtx) -> None:
        """
        Generate binding for the external OCaml API.
        """
        if not ctx.ocaml_api_settings:
            return

        ctx.ocaml_api_settings.init_type_graph()

        if not os.path.isdir(self.ocaml_dir):
            os.mkdir(self.ocaml_dir)

        with names.camel:
            # Write an empty ocamlformat file so we can call ocamlformat
            write_source_file(os.path.join(self.ocaml_dir, '.ocamlformat'), '')

            ctx = get_context()
            code = ctx.render_template("ocaml_api/module_ocaml",
                                       c_api=ctx.c_api_settings,
                                       ocaml_api=ctx.ocaml_api_settings)

            ocaml_filename = '{}.ml'.format(ctx.c_api_settings.lib_name)
            write_ocaml_file(
                os.path.join(self.ocaml_dir, ocaml_filename),
                code,
                self.post_process_ocaml,
            )

            code = ctx.render_template("ocaml_api/module_sig_ocaml",
                                       c_api=ctx.c_api_settings,
                                       ocaml_api=ctx.ocaml_api_settings)

            ocaml_filename = '{}.mli'.format(ctx.c_api_settings.lib_name)
            write_ocaml_file(
                os.path.join(self.ocaml_dir, ocaml_filename),
                code,
                self.post_process_ocaml,
            )

            # Emit dune file to easily compile and install bindings
            code = ctx.render_template("ocaml_api/dune_ocaml",
                                       c_api=ctx.c_api_settings,
                                       ocaml_api=ctx.ocaml_api_settings)

            write_source_file(os.path.join(self.ocaml_dir, 'dune'), code)
            write_source_file(os.path.join(self.ocaml_dir, 'dune-project'),
                              '(lang dune 1.6)')

            # Write an empty opam file to install the lib with dune
            write_source_file(
                os.path.join(self.ocaml_dir,
                             '{}.opam'.format(ctx.c_api_settings.lib_name)),
                '')
예제 #3
0
    def emit_mains(self, ctx: CompileCtx) -> None:
        """
        Emit sources and the project file for mains.
        """
        with names.camel_with_underscores:
            write_ada_file(path.join(self.lib_root, 'src-mains'),
                           AdaSourceKind.body, ['Parse'],
                           ctx.render_template('main_parse_ada'),
                           self.post_process_ada)

        write_source_file(
            self.mains_project,
            ctx.render_template('mains_project_file',
                                lib_name=ctx.ada_api_settings.lib_name,
                                source_dirs=self.main_source_dirs,
                                main_programs=self.main_programs))
예제 #4
0
    def emit_python_api(self, ctx: CompileCtx) -> None:
        """
        Generate the Python binding module.
        """
        def render_python_template(file_path: str, *args: Any,
                                   **kwargs: Any) -> None:
            with names.camel:
                code = ctx.render_template(*args, **kwargs)
            self.write_python_file(file_path, code)

        # Emit the Python modules themselves
        render_python_template(os.path.join(self.python_pkg_dir,
                                            '__init__.py'),
                               'python_api/module_py',
                               c_api=ctx.c_api_settings,
                               pyapi=ctx.python_api_settings,
                               module_name=ctx.python_api_settings.module_name)

        # Emit the empty "py.type" file so that users can easily leverage type
        # annotations in the generated bindings.
        self.write_source_file(os.path.join(self.python_pkg_dir, "py.typed"),
                               "")

        # Emit the setup.py script to easily install the Python binding
        setup_py_file = os.path.join(self.lib_root, 'python', 'setup.py')
        self.write_python_file(setup_py_file,
                               ctx.render_template('python_api/setup_py'))
예제 #5
0
    def emit_python_api(self, ctx: CompileCtx) -> None:
        """
        Generate the Python binding module.
        """
        def pretty_print(code: str) -> str:
            if not self.pretty_print:
                return code

            try:
                from black import FileMode, format_file_contents
                return format_file_contents(code, fast=True, mode=FileMode())
            except ImportError:
                check_source_language(
                    False,
                    'Black not available, not pretty-printing Python code',
                    severity=Severity.warning,
                    ok_for_codegen=True)
                return code

        def render_python_template(file_path: str, *args: Any,
                                   **kwargs: Any) -> None:
            with names.camel:
                code = ctx.render_template(*args, **kwargs)

            # If pretty-printing failed, write the original code anyway in
            # order to ease debugging.
            exc = None
            try:
                pp_code = pretty_print(code)
            except SyntaxError:
                pp_code = code

            write_source_file(file_path, pp_code, self.post_process_python)
            if exc:
                raise exc

        # Emit the Python modules themselves
        render_python_template(os.path.join(self.python_pkg_dir,
                                            '__init__.py'),
                               'python_api/module_py',
                               c_api=ctx.c_api_settings,
                               pyapi=ctx.python_api_settings,
                               module_name=ctx.python_api_settings.module_name)

        # Emit the empty "py.type" file so that users can easily leverage type
        # annotations in the generated bindings.
        write_source_file(os.path.join(self.python_pkg_dir, "py.typed"), "")

        # Emit the setup.py script to easily install the Python binding
        setup_py_file = os.path.join(self.lib_root, 'python', 'setup.py')
        write_source_file(setup_py_file,
                          ctx.render_template('python_api/setup_py'),
                          self.post_process_python)
예제 #6
0
 def emit_python_playground(self, ctx: CompileCtx) -> None:
     """
     Emit sources for the Python playground script.
     """
     playground_file = os.path.join(
         self.scripts_dir, '{}_playground'.format(ctx.short_name_or_long))
     write_source_file(
         playground_file,
         ctx.render_template(
             'python_api/playground_py',
             module_name=ctx.python_api_settings.module_name),
         self.post_process_python)
     os.chmod(playground_file, 0o775)
예제 #7
0
 def emit_lib_project_file(self, ctx: CompileCtx) -> None:
     """
     Emit a project file for the generated library.
     """
     self._project_file_emitted = True
     write_source_file(
         self.main_project_file,
         ctx.render_template(
             'project_file',
             lib_name=ctx.ada_api_settings.lib_name,
             os_path=os.path,
             project_path=os.path.dirname(self.main_project_file),
         ))