Example #1
0
    def run(self, argv=None):
        parsed_args = self.args_parser.parse_args(argv)

        for trace in parsed_args.trace:
            print("Trace {} is activated".format(trace))
            Log.enable(trace)

        Diagnostics.set_style(parsed_args.diagnostic_style)

        if parsed_args.profile:
            import cProfile
            import pstats

            pr = cProfile.Profile()
            pr.enable()

        # Set the verbosity
        self.verbosity = parsed_args.verbosity

        self.no_ada_api = parsed_args.no_ada_api

        # If asked to, setup the exception hook as a last-chance handler to
        # invoke a debugger in case of uncaught exception.
        if parsed_args.debug:
            # Try to use IPython's debugger if it is available, otherwise
            # fallback to PDB.
            try:
                # noinspection PyPackageRequirements
                from IPython.core import ultratb
            except ImportError:
                ultratb = None  # To keep PyCharm happy...

                def excepthook(type, value, tb):
                    traceback.print_exception(type, value, tb)
                    pdb.post_mortem(tb)

                sys.excepthook = excepthook
            else:
                sys.excepthook = ultratb.FormattedTB(mode='Verbose',
                                                     color_scheme='Linux',
                                                     call_pdb=1)
            del ultratb

        self.dirs.set_build_dir(parsed_args.build_dir)
        install_dir = getattr(parsed_args, 'install-dir', None)
        if install_dir:
            self.dirs.set_install_dir(install_dir)

        if getattr(parsed_args, 'list_warnings', False):
            WarningSet.print_list()
            return

        # noinspection PyBroadException
        try:
            parsed_args.func(parsed_args)

        except DiagnosticError:
            if parsed_args.debug:
                raise
            if parsed_args.verbosity.debug or parsed_args.full_error_traces:
                traceback.print_exc()
            print(col('Errors, exiting', Colors.FAIL), file=sys.stderr)
            sys.exit(1)

        except Exception as e:
            if parsed_args.debug:
                raise
            ex_type, ex, tb = sys.exc_info()

            # If we have a syntax error, we know for sure the last stack frame
            # points to the code that must be fixed. Otherwise, point to the
            # top-most stack frame that does not belong to Langkit.
            if e.args and e.args[0] == 'invalid syntax':
                loc = Location(e.filename, e.lineno)
            else:
                loc = extract_library_location(traceback.extract_tb(tb))
            with Context("", loc, "recovery"):
                check_source_language(False, str(e), do_raise=False)

            # Keep Langkit bug "pretty" for users: display the Python stack
            # trace only when requested.
            if parsed_args.verbosity.debug or parsed_args.full_error_traces:
                traceback.print_exc()

            print(col('Internal error! Exiting', Colors.FAIL), file=sys.stderr)
            sys.exit(1)

        finally:
            if parsed_args.profile:
                pr.disable()
                ps = pstats.Stats(pr)
                ps.dump_stats('langkit.prof')
Example #2
0
class Example(FooNode):
    """
    Example node.
    """

    # This property is undocumented but it inherits a documented one, so it
    # should not have a warning.
    @langkit_property(public=True)
    def doc_prop():
        return True

    # This property is undocumented, so it should have a warning
    @langkit_property(public=True)
    def undoc_prop():
        return True

    # This property is documented, so it should not have a warning
    @langkit_property(public=True)
    def will_doc_prop():
        """
        This property is documented.
        """
        return True


grammar = Grammar('item')
grammar.add_rules(item=Example('example'))
emit_and_print_errors(grammar, warning_set=WarningSet())
print('Done')
Example #3
0
        pass


class Example(FooNode):
    """
    Example node.
    """

    # This property is undocumented but it inherits a documented one, so it
    # should not have a warning.
    @langkit_property(public=True)
    def doc_prop():
        return True

    # This property is undocumented, so it should have a warning
    @langkit_property(public=True)
    def undoc_prop():
        return True

    # This property is documented, so it should not have a warning
    @langkit_property(public=True)
    def will_doc_prop():
        """
        This property is documented.
        """
        return True


emit_and_print_errors(lkt_file='foo.lkt', warning_set=WarningSet())
print('Done')
Example #4
0
    def add_generate_args(self, subparser):
        """
        Add arguments to tune code generation to "subparser".

        :type subparser: argparse.ArgumentParser
        """
        subparser.add_argument(
            '--no-pretty-print',
            '-P',
            action='store_true',
            help='Do not try to pretty-print generated source code.')
        subparser.add_argument(
            '--annotate-fields-types',
            action='store_true',
            help='Experimental feature. Modify the Python files where the'
            ' node types are defined, to annotate empty Field() '
            ' definitions.')
        subparser.add_argument(
            '--check-only',
            action='store_true',
            help="Only check the input for errors, don't generate the code.")
        subparser.add_argument(
            '--no-property-checks',
            action='store_true',
            help="Don't generate runtime checks for properties.")
        subparser.add_argument('--list-warnings',
                               action='store_true',
                               help='Display the list of available warnings.')
        subparser.add_argument(
            '--enable-warning',
            '-W',
            dest='enabled_warnings',
            default=WarningSet(),
            action=EnableWarningAction,
            choices=[w.name for w in WarningSet.available_warnings],
            help='Enable a warning.')
        subparser.add_argument(
            '--disable-warning',
            '-w',
            action=DisableWarningAction,
            choices=[w.name for w in WarningSet.available_warnings],
            help='Disable a warning.')
        subparser.add_argument(
            '--no-astdoc',
            '-D',
            dest='no_astdoc',
            action='store_true',
            help='Do not generate the HTML documentation for AST nodes, their'
            ' fields and their properties.')
        subparser.add_argument(
            '--generate-unparser',
            action='store_true',
            default=False,
            help='Generate an unparser along with the parser for the grammar.'
            ' Note that this machinery is intended only for languages'
            ' that have no significant whitespace, i.e. where whitespaces'
            ' can be abitrary inserted between two tokens without'
            ' affecting lexing.')
        subparser.add_argument(
            '--report-unused-doc-entries',
            action='store_true',
            default=False,
            help='Emit warnings for unused documentation entries .')
        subparser.add_argument(
            '--no-gdb-hook',
            action='store_true',
            help='Do not generate the ".debug_gdb_script" section. This'
            ' section is used to automatically run Langkit GDB helpers'
            ' when loading the generated library in a debugger.'
            ' Conventient for debugging, but bad for releases as this'
            ' hardcodes source paths in the sources.')
        subparser.add_argument(
            '--coverage',
            action='store_true',
            help='Instrument the generated library to compute its code'
            ' coverage. This requires GNATcoverage.')
        subparser.add_argument(
            '--relative-project',
            action='store_true',
            help='Use relative paths in generated project files. This is'
            ' useful in order to get portable generated sources, for'
            ' releases for instance.')

        # RA22-015: option to dump the results of the unparsing concrete syntax
        # to a file.
        subparser.add_argument(
            '--unparse-script',
            type=UnparseScript,
            default=None,
            help='If specified, sequence of actions to generate definition of'
            ' the source language using the concrete syntax DSL. Actions'
            ' are separated by commas. These can be:'
            ' to:FILE (write the next actions to the given file),'
            ' import:MODULE (write an import statement for the given'
            ' module name,'
            ' nodes (write definitions for nodes),'
            ' lexer (write the lexer definition),'
            ' grammar (write the grammar definition).')
Example #5
0
from __future__ import absolute_import, division, print_function

import os
import shutil
import subprocess
import sys

from langkit.compile_context import CompileCtx
from langkit.compiled_types import CompiledTypeMetaclass, create_builtin_types
from langkit.diagnostics import DiagnosticError, WarningSet
from langkit.dsl import _StructMetaclass, _ASTNodeMetaclass, _EnumNodeMetaclass
from langkit.expressions import Entity, Self
from langkit.libmanage import ManageScript
from langkit.utils import reset_memoized

default_warning_set = WarningSet()

# We don't want to be forced to provide dummy docs for public properties in
# testcases.
default_warning_set.disable(WarningSet.undocumented_public_properties)

pretty_print = bool(int(os.environ.get('LANGKIT_PRETTY_PRINT', '0')))

project_template = """
with "libfoolang";

project Gen is
    for Languages use ("Ada");
    for Source_Dirs use (".");
    for Object_Dir use "obj";
    for Main use ("{main_source}");
Example #6
0
    def add_generate_args(self, subparser):
        """
        Add arguments to tune code generation to "subparser".

        :type subparser: argparse.ArgumentParser
        """
        subparser.add_argument('--pretty-print',
                               '-p',
                               action='store_true',
                               help='Pretty-print generated source code.')
        subparser.add_argument(
            '--annotate-fields-types',
            action='store_true',
            help='Experimental feature. Modify the Python files where the'
            ' node types are defined, to annotate empty Field() '
            ' definitions.')
        subparser.add_argument('--no-compile-quex',
                               action='store_true',
                               help="Don't compile the Quex lexer.")
        subparser.add_argument(
            '--check-only',
            action='store_true',
            help="Only check the input for errors, don't generate the code.")
        subparser.add_argument(
            '--no-property-checks',
            action='store_true',
            help="Don't generate runtime checks for properties.")
        subparser.add_argument('--list-warnings',
                               action='store_true',
                               help='Display the list of available warnings.')
        subparser.add_argument(
            '--enable-warning',
            '-W',
            dest='enabled_warnings',
            default=WarningSet(),
            action=EnableWarningAction,
            choices=[w.name for w in WarningSet.available_warnings],
            help='Enable a warning.')
        subparser.add_argument(
            '--disable-warning',
            '-w',
            action=DisableWarningAction,
            choices=[w.name for w in WarningSet.available_warnings],
            help='Disable a warning.')
        subparser.add_argument(
            '--enable-properties-logging',
            dest='enabled_properties_logging',
            action='store_true',
            help='Instrument properties code to do logging.')
        subparser.add_argument(
            '--separate-properties',
            dest='separate_properties',
            action='store_true',
            help='Generate public properties in a separate package. This is a'
            ' development helper only, to make builds faster with GNAT.')
        subparser.add_argument(
            '--no-astdoc',
            '-D',
            dest='no_astdoc',
            action='store_true',
            help='Do not generate the HTML documentation for AST nodes, their'
            ' fields and their properties.')
Example #7
0
    def add_generate_args(self, subparser):
        """
        Add arguments to tune code generation to "subparser".

        :type subparser: argparse.ArgumentParser
        """
        subparser.add_argument(
            '--no-pretty-print',
            '-P',
            action='store_true',
            help='Do not try to pretty-print generated source code.')
        subparser.add_argument(
            '--annotate-fields-types',
            action='store_true',
            help='Experimental feature. Modify the Python files where the'
            ' node types are defined, to annotate empty Field() '
            ' definitions.')
        subparser.add_argument(
            '--check-only',
            action='store_true',
            help="Only check the input for errors, don't generate the code.")
        subparser.add_argument(
            '--no-property-checks',
            action='store_true',
            help="Don't generate runtime checks for properties.")
        subparser.add_argument('--list-warnings',
                               action='store_true',
                               help='Display the list of available warnings.')
        subparser.add_argument(
            '--enable-warning',
            '-W',
            dest='enabled_warnings',
            default=WarningSet(),
            action=EnableWarningAction,
            choices=[w.name for w in WarningSet.available_warnings],
            help='Enable a warning.')
        subparser.add_argument(
            '--disable-warning',
            '-w',
            action=DisableWarningAction,
            choices=[w.name for w in WarningSet.available_warnings],
            help='Disable a warning.')
        subparser.add_argument(
            '--no-astdoc',
            '-D',
            dest='no_astdoc',
            action='store_true',
            help='Do not generate the HTML documentation for AST nodes, their'
            ' fields and their properties.')
        subparser.add_argument(
            '--generate-unparser',
            action='store_true',
            default=False,
            help='Generate an unparser along with the parser for the grammar.'
            ' Note that this machinery is intended only for languages'
            ' that have no significant whitespace, i.e. where whitespaces'
            ' can be abitrary inserted between two tokens without'
            ' affecting lexing.')
        subparser.add_argument(
            '--no-gdb-hook',
            action='store_true',
            help='Do not generate the ".debug_gdb_script" section. This'
            ' section is used to automatically run Langkit GDB helpers'
            ' when loading the generated library in a debugger.'
            ' Conventient for debugging, but bad for releases as this'
            ' hardcodes source paths in the sources.')
Example #8
0
    def add_generate_args(self, subparser):
        """
        Add arguments to tune code generation to "subparser".

        :type subparser: argparse.ArgumentParser
        """
        subparser.add_argument('--pretty-print',
                               '-p',
                               action='store_true',
                               help='Pretty-print generated source code.')
        subparser.add_argument(
            '--annotate-fields-types',
            action='store_true',
            help='Experimental feature. Modify the Python files where the'
            ' node types are defined, to annotate empty Field() '
            ' definitions.')
        subparser.add_argument('--no-compile-quex',
                               action='store_true',
                               help="Don't compile the Quex lexer.")
        subparser.add_argument(
            '--check-only',
            action='store_true',
            help="Only check the input for errors, don't generate the code.")
        subparser.add_argument(
            '--no-property-checks',
            action='store_true',
            help="Don't generate runtime checks for properties.")
        subparser.add_argument('--list-warnings',
                               action='store_true',
                               help='Display the list of available warnings.')
        subparser.add_argument(
            '--enable-warning',
            '-W',
            dest='enabled_warnings',
            default=WarningSet(),
            action=EnableWarningAction,
            choices=[w.name for w in WarningSet.available_warnings],
            help='Enable a warning.')
        subparser.add_argument(
            '--disable-warning',
            '-w',
            action=DisableWarningAction,
            choices=[w.name for w in WarningSet.available_warnings],
            help='Disable a warning.')
        subparser.add_argument(
            '--enable-properties-logging',
            dest='enabled_properties_logging',
            action='store_true',
            help='Instrument properties code to do logging.')
        subparser.add_argument(
            '--separate-properties',
            dest='separate_properties',
            action='store_true',
            help='Generate public properties in a separate package. This is a'
            ' development helper only, to make builds faster with GNAT.')
        subparser.add_argument(
            '--no-astdoc',
            '-D',
            dest='no_astdoc',
            action='store_true',
            help='Do not generate the HTML documentation for AST nodes, their'
            ' fields and their properties.')
        subparser.add_argument(
            '--generate-unparser',
            action='store_true',
            default=False,
            help='Generate an unparser along with the parser for the grammar.'
            ' Note that this machinery is intended only for languages'
            ' that have no significant whitespace, i.e. where whitespaces'
            ' can be abitrary inserted between two tokens without'
            ' affecting lexing.')
Example #9
0
    def run_no_exit(self, argv: Opt[List[str]] = None) -> int:
        parsed_args, unknown_args = self.args_parser.parse_known_args(argv)

        for trace in parsed_args.trace:
            print("Trace {} is activated".format(trace))
            Log.enable(trace)

        Diagnostics.set_style(parsed_args.diagnostic_style)

        if parsed_args.profile:
            import cProfile
            import pstats

            pr = cProfile.Profile()
            pr.enable()

        # Set the verbosity
        self.verbosity = parsed_args.verbosity

        self.enable_build_warnings = getattr(parsed_args,
                                             "enable_build_warnings", False)

        # If there is no build_mode (ie. we're not running a command that
        # requires it), we still need one to call gnatpp, so set it to a dummy
        # build mode.
        self.build_mode = getattr(parsed_args, "build_mode",
                                  self.BUILD_MODES[0])

        self.no_ada_api = parsed_args.no_ada_api

        # If asked to, setup the exception hook as a last-chance handler to
        # invoke a debugger in case of uncaught exception.
        if parsed_args.debug:
            # Try to use IPython's debugger if it is available, otherwise
            # fallback to PDB.
            try:
                # noinspection PyPackageRequirements
                from IPython.core import ultratb
            except ImportError:

                def excepthook(typ: Type[BaseException], value: BaseException,
                               tb: TracebackType) -> Any:
                    traceback.print_exception(typ, value, tb)
                    pdb.post_mortem(tb)

                sys.excepthook = excepthook
            else:
                sys.excepthook = ultratb.FormattedTB(mode='Verbose',
                                                     color_scheme='Linux',
                                                     call_pdb=1)

        self.dirs.set_build_dir(parsed_args.build_dir)
        install_dir = getattr(parsed_args, 'install-dir', None)
        if install_dir:
            self.dirs.set_install_dir(install_dir)

        if getattr(parsed_args, 'list_warnings', False):
            WarningSet.print_list()
            return 0

        # noinspection PyBroadException
        try:
            parsed_args.func(parsed_args, unknown_args)
            return 0

        except DiagnosticError:
            if parsed_args.debug:
                raise
            if parsed_args.verbosity.debug or parsed_args.full_error_traces:
                traceback.print_exc()
            print(col('Errors, exiting', Colors.FAIL))
            return 1

        except Exception as e:
            if parsed_args.debug:
                raise
            ex_type, ex, tb = sys.exc_info()

            # If we have a syntax error, we know for sure the last stack frame
            # points to the code that must be fixed. Otherwise, point to the
            # top-most stack frame that does not belong to Langkit.
            if e.args and e.args[0] == 'invalid syntax':
                assert isinstance(e, SyntaxError)
                loc = Location(cast(str, e.filename), cast(int, e.lineno))
            else:
                loc = cast(Location,
                           extract_library_location(traceback.extract_tb(tb)))
            with diagnostic_context(loc):
                check_source_language(False, str(e), do_raise=False)

            # Keep Langkit bug "pretty" for users: display the Python stack
            # trace only when requested.
            if parsed_args.verbosity.debug or parsed_args.full_error_traces:
                traceback.print_exc()

            print(col('Internal error! Exiting', Colors.FAIL))
            return 1

        finally:
            if parsed_args.profile:
                pr.disable()
                ps = pstats.Stats(pr)
                ps.dump_stats('langkit.prof')