Example #1
0
class Plugin(PluginBase):

    # ----------------------------------------------------------------------
    # |  Public Properties
    Name = DerivedProperty("Pickle")
    Description = DerivedProperty("Pickles each element to a file")
    Flags = DerivedProperty(ParseFlag.AllFlags)

    # ----------------------------------------------------------------------
    # |  Public Methods
    @staticmethod
    @override
    def IsValidEnvironment():
        return True

    # ----------------------------------------------------------------------
    @staticmethod
    @override
    def GenerateCustomSettingsAndDefaults():
        return []

    # ----------------------------------------------------------------------
    @staticmethod
    @override
    def GenerateOutputFilenames(context):
        # Return a single item (that will never be used), as an empty lists
        # aren't supported.
        return [
            "{}.{}".format(context["output_name"], ext)
            for ext in ["pickle", "path"]
        ]

    # ----------------------------------------------------------------------
    @staticmethod
    @override
    def Generate(simple_schema_generator, invoke_reason, input_filenames,
                 output_filenames, name, elements, include_indexes,
                 status_stream, verbose_stream, verbose, **custom_settings):
        assert len(output_filenames) == 2, output_filenames

        # Pickle
        status_stream.write("Creating '{}'...".format(output_filenames[0]))
        with status_stream.DoneManager() as status_dm:
            with open(output_filenames[0], "wb") as f:
                pickle.dump(elements, f)

        # Path
        status_stream.write("Creating '{}'...".format(output_filenames[1]))
        with status_stream.DoneManager() as status_dm:
            generator_path = os.path.dirname(
                simple_schema_generator.OriginalModuleFilename)
            assert os.path.isdir(generator_path), generator_path

            generator_path = os.path.dirname(generator_path)

            with open(output_filenames[1], "w") as f:
                f.write(generator_path)
    class _PlaceholderTypeInfo(TypeInfo):
        Desc                                = DerivedProperty("")
        ConstraintsDesc                     = DerivedProperty("")
        ExpectedType                        = bool

        @staticmethod
        @override
        def _ValidateItemNoThrowImpl(item):             # <Parameters differ from overridden...> pylint: disable = W0221
            pass
class Plugin(PluginBase):

    # ----------------------------------------------------------------------
    # |  Public Properties
    Name                                    = DerivedProperty("Debug")
    Description                             = DerivedProperty("Displays diagnostic information about each element")
    Flags                                   = DerivedProperty(ParseFlag.AllFlags)

    # ----------------------------------------------------------------------
    # |  Public Methods
    @staticmethod
    @override
    def IsValidEnvironment():
        return True

    # ----------------------------------------------------------------------
    @staticmethod
    @override
    def GenerateCustomSettingsAndDefaults():
        return []

    # ----------------------------------------------------------------------
    @staticmethod
    @override
    def GenerateOutputFilenames(context):
        # Return a single item (that will never be used), as an empty lists
        # aren't supported.
        return ["placeholder"]

    # ----------------------------------------------------------------------
    @staticmethod
    @override
    def Generate(
        simple_schema_generator,
        invoke_reason,
        input_filenames,
        output_filenames,
        name,
        elements,
        include_indexes,
        status_stream,
        verbose_stream,
        verbose,
        **custom_settings
    ):
        # ----------------------------------------------------------------------
        def Impl(element):
            status_stream.write(str(element))
            status_stream.write("\n\n")

        # ----------------------------------------------------------------------

        for include_index in include_indexes:
            Impl(elements[include_index])
Example #4
0
    class CodeGenerator(
            AtomicInputProcessingMixin,
            ConditionalInvocationQueryMixin,
            MultipleOutputMixin,
            CodeGeneratorMod.CodeGenerator,
    ):
        # ----------------------------------------------------------------------
        # |
        # |  Public Properties
        # |
        # ----------------------------------------------------------------------
        Name = DerivedProperty(name)
        Description = DerivedProperty(description)
        InputTypeInfo = DerivedProperty(
            FilenameTypeInfo(
                validation_expression=filename_validation_expression))

        OriginalModuleFilename = calling_mod_filename
        RequiresOutputName = requires_output_name

        # ----------------------------------------------------------------------
        # |
        # |  Public Methods
        # |
        # ----------------------------------------------------------------------
        @staticmethod
        @override
        def IsSupportedContent(filename):
            return is_supported_content_func is None or is_supported_content_func(
                filename)

        # ----------------------------------------------------------------------
        # |
        # |  Protected Methods
        # |
        # ----------------------------------------------------------------------
        @classmethod
        @override
        def _GetOptionalMetadata(cls):
            return get_optional_metadata_func() + \
                   [ ( "plugin_settings", {} ),
                   ] + \
                   super(CodeGenerator, cls)._GetOptionalMetadata()

        # ----------------------------------------------------------------------
        @classmethod
        @override
        def _GetRequiredMetadataNames(cls):
            names = [
                "plugin_name",
            ]

            if cls.RequiresOutputName:
                names += [
                    "output_name",
                ]

            names += super(CodeGenerator, cls)._GetRequiredMetadataNames()

            return names

        # ----------------------------------------------------------------------
        @classmethod
        @override
        def _CreateContext(cls, metadata, status_stream):
            if metadata["plugin_name"] not in plugin_map:
                raise CommandLine.UsageException(
                    "'{}' is not a valid plugin".format(
                        metadata["plugin_name"]))

            plugin = plugin_map[metadata["plugin_name"]].Plugin

            # Ensure that all plugin settings are present and that they
            # are the expected type.
            custom_settings = OrderedDict([
                (k, v) for k, v in plugin.GenerateCustomSettingsAndDefaults()
            ])

            plugin_settings = metadata["plugin_settings"]

            for k, v in six.iteritems(plugin_settings):
                if k not in custom_settings:
                    raise CommandLine.UsageException(
                        "'{}' is not a valid plugin setting".format(k))

                desired_type = type(custom_settings[k])

                if type(v) != desired_type:
                    assert isinstance(v,
                                      (str, UnicodeDecodeError)), (v, type(v))
                    plugin_settings[k] = StringSerialization.DeserializeItem(
                        CreateFromPythonType(desired_type), v)

            for k, v in six.iteritems(custom_settings):
                if k not in plugin_settings:
                    plugin_settings[k] = v

            metadata["plugin_settings"] = plugin.PreprocessMetadata(
                plugin_settings)

            # Invoke custom functionality
            context = create_context_func(metadata, plugin)
            context = plugin.PreprocessContext(context)

            context["output_filenames"] = [
                os.path.join(context["output_dir"], filename)
                for filename in plugin.GenerateOutputFilenames(context)
            ]

            context = plugin.PostprocessContext(context)

            if postprocess_context_func:
                context = postprocess_context_func(context, plugin)

            return super(CodeGenerator,
                         cls)._CreateContext(context, status_stream)

        # ----------------------------------------------------------------------
        @classmethod
        @override
        def _InvokeImpl(
            cls,
            invoke_reason,
            context,
            status_stream,
            verbose_stream,
            verbose,
        ):
            return invoke_func(
                cls,
                invoke_reason,
                context,
                status_stream,
                verbose_stream,
                verbose,
                plugin_map[context["plugin_name"]].Plugin,
            )

        # ----------------------------------------------------------------------
        @classmethod
        @override
        def _GetAdditionalGeneratorItems(cls, context):
            # ----------------------------------------------------------------------
            def ProcessorGeneratorItem(item):
                if isinstance(item, six.string_types) and item in plugin_map:
                    return plugin_map[item].Plugin

                return item

            # ----------------------------------------------------------------------

            plugin = plugin_map[context["plugin_name"]].Plugin

            return [ cls,
                     cls.OriginalModuleFilename,
                     plugin,
                   ] + \
                   list(plugin.GetAdditionalGeneratorItems(context)) + \
                   super(CodeGenerator, cls)._GetAdditionalGeneratorItems(context)
class Plugin(PluginBase):

    # ----------------------------------------------------------------------
    # |  Public Properties
    Name = DerivedProperty("Dot")
    Description = DerivedProperty(
        "Generates a DOT file that contains all elements (https://en.wikipedia.org/wiki/DOT_(graph_description_language))"
    )
    Flags = DerivedProperty(ParseFlag.AllFlags)

    # ----------------------------------------------------------------------
    # |  Public Methods
    @staticmethod
    @override
    def IsValidEnvironment():
        return True

    # ----------------------------------------------------------------------
    @staticmethod
    @override
    def GenerateCustomSettingsAndDefaults():
        yield "no_attributes", False

    # ----------------------------------------------------------------------
    @staticmethod
    @override
    def GenerateOutputFilenames(context):
        return [
            os.path.join(context["output_dir"],
                         "{}.gv".format(context["output_name"]))
        ]

    # ----------------------------------------------------------------------
    @staticmethod
    @override
    def Generate(
        simple_schema_generator,
        invoke_reason,
        input_filenames,
        output_filenames,
        name,
        elements,
        include_indexes,
        status_stream,
        verbose_stream,
        verbose,
        no_attributes,
    ):
        assert len(output_filenames) == 1, output_filenames
        output_filename = output_filenames[0]

        common_input_prefix = FileSystem.GetCommonPath(*input_filenames)

        with open(output_filename, "w") as f:
            f.write(
                textwrap.dedent(
                    """\
                    digraph g {
                        graph [
                            rankdir = "LR"
                        ];
                    """, ), )

            indented_stream = StreamDecorator(
                f,
                line_prefix="    ",
            )

            # ----------------------------------------------------------------------
            def Impl(element):
                if element.IsDefinitionOnly:
                    element_type = "Definition"
                    style = "dashed"
                elif getattr(element, "IsAttribute", False):
                    element_type = "Attribute"
                    style = "rounded"
                else:
                    element_type = "Standard"
                    style = None

                type_info_type = element.TypeInfo.__class__.__name__

                indented_stream.write(
                    textwrap.dedent(
                        """\
                        "{dotted}" [
                            shape = rectangle
                            {style}
                            label = <
                              <table border="0">
                                <tr>
                                  <td align="left"><b>{name}</b></td>
                                  <td align="right">{element_type}<br align="right"/>{type_info}</td>
                                </tr>
                                <hr/>
                                <tr>
                                  <td colspan="2">{source} [{line}:{column}]</td>
                                </tr>
                                <hr/>
                                <tr>
                                  <td align="left">Arity:</td>
                                  <td align="right">{arity}</td>
                                </tr>
                        """, ).format(
                            dotted=element.DottedName,
                            name=element.Name,
                            style="style = {}".format(style) if style else "",
                            element_type=element_type,
                            type_info=type_info_type,
                            source=FileSystem.TrimPath(element.Source,
                                                       common_input_prefix),
                            line=element.Line,
                            column=element.Column,
                            arity=element.TypeInfo.Arity.ToString() or "1",
                        ), )

                if type_info_type != "ClassTypeInfo":
                    indented_stream.write(
                        StringHelpers.LeftJustify(
                            textwrap.dedent(
                                """\
                                <tr>
                                  <td align="left">Constraints:</td>
                                  <td align="right">{}</td>
                                </tr>
                                """, ).format(
                                    html.escape(
                                        element.TypeInfo.ConstraintsDesc), ),
                            8,
                            skip_first_line=False,
                        ), )

                if not no_attributes:
                    table_rows = []

                    for key, metadata_value in six.iteritems(
                            element.Metadata.Values):
                        table_rows.append(
                            textwrap.dedent(
                                """\
                                <tr>
                                  <td align="left">{}:</td>
                                  <td align="right">{}</td>
                                </tr>
                                """, ).format(
                                    html.escape(key),
                                    html.escape(metadata_value.Value),
                                ), )

                    if table_rows:
                        indented_stream.write(
                            StringHelpers.LeftJustify(
                                textwrap.dedent(
                                    """\
                                    <hr/>
                                    {}
                                    """, ).format("".join(table_rows)),
                                8,
                                skip_first_line=False,
                            ), )

                indented_stream.write(
                    textwrap.dedent(
                        """\
                              </table>
                            >
                        ];
                        """, ), )

                for child in getattr(element, "Children", []):
                    Impl(child)
                    indented_stream.write('"{}":f0 -> "{}":f0\n'.format(
                        element.DottedName, child.DottedName))

            # ----------------------------------------------------------------------

            for element in elements:
                Impl(element)

            f.write("}\n")
class Plugin(PluginBase):

    # ----------------------------------------------------------------------
    # |  Public Properties
    Name = DerivedProperty("PyDictionary")
    Description = DerivedProperty(
        "Generates python source code that contains a dictionary with top-level enum schema elements that have corresponding friendly names"
    )
    Flags = DerivedProperty(ParseFlag.AllFlags)

    # ----------------------------------------------------------------------
    # |  Public Methods
    @staticmethod
    @override
    def IsValidEnvironment():
        return True

    # ----------------------------------------------------------------------
    @staticmethod
    @override
    def GenerateCustomSettingsAndDefaults():
        return []

    # ----------------------------------------------------------------------
    @staticmethod
    @override
    def GenerateOutputFilenames(context):
        return ["{}_dict.py".format(context["output_name"])]

    # ----------------------------------------------------------------------
    @classmethod
    @override
    def Generate(cls, simple_schema_generator, invoke_reason, input_filenames,
                 output_filenames, name, elements, include_indexes,
                 status_stream, verbose_stream, verbose, **custom_settings):
        assert len(output_filenames) == 1, output_filenames
        output_filename = output_filenames[0]
        del output_filenames

        status_stream.write("Creating '{}'...".format(output_filename))
        with status_stream.DoneManager() as this_dm:
            with open(output_filename, "w") as f:
                f.write(
                    textwrap.dedent(
                        """\
                        {}
                        from collections import OrderedDict

                        """, ).format(
                            cls._GenerateFileHeader(
                                prefix="# ",
                                filename_prefix="<SimpleSchemaGenerator>/",
                            ), ), )

                nonlocals = CommonEnvironment.Nonlocals(wrote_value=False, )

                # ----------------------------------------------------------------------
                def OnCompoundVisitingChildren(
                        element, *args,
                        **kwargs):  # <Unused argument> pylint: disable = W0613
                    # Don't visit children
                    return False

                # ----------------------------------------------------------------------
                def OnSimpleVisitingChildren(
                        element, *args,
                        **kwargs):  # <Unused argument> pylint: disable = W0613
                    # Don't visit children
                    return False

                # ----------------------------------------------------------------------
                def OnFundamental(
                        element, *args,
                        **kwargs):  # <Unused argument> pylint: disable = W0613
                    if not isinstance(element.TypeInfo, EnumTypeInfo):
                        return

                    if not element.TypeInfo.FriendlyValues:
                        return

                    name = element.Name
                    reversed_name = "{}_reversed".format(name)

                    prefix = "{} = OrderedDict".format(name)
                    reversed_prefix = "{} = OrderedDict".format(reversed_name)

                    f.write(
                        textwrap.dedent(
                            """\
                            {prefix}{assignments}

                            {name}_max_key_length = len(max({name}.keys(), len))
                            {name}_max_value_length = len(max({name}.values(), len))

                            {reversed_prefix}{reversed_assignments}

                            {reversed_name}_max_key_length = len(max({reversed_name}.keys(), len))
                            {reversed_name}_max_value_length = len(max({reversed_name}.values(), len))

                            """,
                        ).format(
                            prefix=prefix,
                            assignments=StringHelpers.LeftJustify(
                                "([ {}\n ])".format(
                                    "\n   ".join([
                                        '( "{}", "{}" ),'.format(v, fv)
                                        for v, fv in six.moves.zip(
                                            element.TypeInfo.Values,
                                            element.TypeInfo.FriendlyValues)
                                    ]), ),
                                len(prefix),
                            ),
                            name=name,
                            reversed_prefix=reversed_prefix,
                            reversed_assignments=StringHelpers.LeftJustify(
                                "([ {}\n ])".format(
                                    "\n   ".join([
                                        '( "{}", "{}" ),'.format(fv, v)
                                        for v, fv in six.moves.zip(
                                            element.TypeInfo.Values,
                                            element.TypeInfo.FriendlyValues)
                                    ]), ),
                                len(reversed_prefix),
                            ),
                            reversed_name=reversed_name,
                        ), )

                    nonlocals.wrote_value = True

                # ----------------------------------------------------------------------

                simple_element_visitor = Elements.CreateElementVisitor(
                    on_fundamental_func=OnFundamental,
                    on_compound_visiting_children_func=
                    OnCompoundVisitingChildren,
                    on_simple_visiting_children_func=OnSimpleVisitingChildren,
                )

                for include_index in include_indexes:
                    element = elements[include_index]

                    simple_element_visitor.Accept(element)

                if not nonlocals.wrote_value:
                    f.write(
                        "# No enum values with friendly names were found.\n")