reorganization: Move hooks to common.py

This allows them to be referenced before they are filled, helping avoid
circular dependencies.
This commit is contained in:
James Westman 2022-01-26 14:50:36 -06:00
parent 34f525beaa
commit 8f9de81e24
5 changed files with 89 additions and 6 deletions

View file

@ -11,9 +11,11 @@ from .gtk_size_group import Widgets
from .gtk_string_list import Strings from .gtk_string_list import Strings
from .gtk_styles import Styles from .gtk_styles import Styles
OBJECT_HOOKS = [menu] from .common import *
OBJECT_CONTENT_HOOKS = [ OBJECT_HOOKS.children = [menu]
OBJECT_CONTENT_HOOKS.children = [
Signal, A11y, Styles, Layout, mime_types, patterns, suffixes, Widgets, Items, Signal, A11y, Styles, Layout, mime_types, patterns, suffixes, Widgets, Items,
Strings, Strings,
] ]

View file

@ -26,3 +26,7 @@ from ..lsp_utils import Completion, CompletionItemKind
from ..parse_tree import * from ..parse_tree import *
from ..parser_utils import * from ..parser_utils import *
from ..xml_emitter import XmlEmitter from ..xml_emitter import XmlEmitter
OBJECT_HOOKS = AnyOf()
OBJECT_CONTENT_HOOKS = AnyOf()

View file

@ -0,0 +1,70 @@
# imports.py
#
# Copyright 2022 James Westman <james@jwestman.net>
#
# This file is free software; you can redistribute it and/or modify it
# under the terms of the GNU Lesser General Public License as
# published by the Free Software Foundation; either version 3 of the
# License, or (at your option) any later version.
#
# This file is distributed in the hope that it will be useful, but
# WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
# Lesser General Public License for more details.
#
# You should have received a copy of the GNU Lesser General Public
# License along with this program. If not, see <http://www.gnu.org/licenses/>.
#
# SPDX-License-Identifier: LGPL-3.0-or-later
from .common import *
class GtkDirective(AstNode):
grammar = Statement(
Match("using").err("File must start with a \"using Gtk\" directive (e.g. `using Gtk 4.0;`)"),
Match("Gtk").err("File must start with a \"using Gtk\" directive (e.g. `using Gtk 4.0;`)"),
UseNumberText("version").expected("a version number for GTK"),
)
@validate("version")
def gtk_version(self):
if self.tokens["version"] not in ["4.0"]:
err = CompileError("Only GTK 4 is supported")
if self.tokens["version"].startswith("4"):
err.hint("Expected the GIR version, not an exact version number. Use `using Gtk 4.0;`.")
else:
err.hint("Expected `using Gtk 4.0;`")
raise err
@property
def gir_namespace(self):
return gir.get_namespace("Gtk", self.tokens["version"])
def emit_xml(self, xml: XmlEmitter):
xml.put_self_closing("requires", lib="gtk", version=self.tokens["version"])
class Import(AstNode):
grammar = Statement(
"using",
UseIdent("namespace").expected("a GIR namespace"),
UseNumberText("version").expected("a version number"),
)
@validate("namespace", "version")
def namespace_exists(self):
gir.get_namespace(self.tokens["namespace"], self.tokens["version"])
@property
def gir_namespace(self):
try:
return gir.get_namespace(self.tokens["namespace"], self.tokens["version"])
except CompileError:
return None
def emit_xml(self, xml):
pass

View file

@ -324,7 +324,14 @@ class AnyOf(ParseNode):
""" ParseNode that attempts to match exactly one of its children. Child """ ParseNode that attempts to match exactly one of its children. Child
nodes are attempted in order. """ nodes are attempted in order. """
def __init__(self, *children): def __init__(self, *children):
self.children = [to_parse_node(child) for child in children] self.children = children
@property
def children(self):
return self._children
@children.setter
def children(self, children):
self._children = [to_parse_node(child) for child in children]
def _parse(self, ctx): def _parse(self, ctx):
for child in self.children: for child in self.children:

View file

@ -40,7 +40,7 @@ def parse(tokens) -> T.Tuple[ast.UI, T.Optional[MultipleErrors]]:
UseIdent("name"), UseIdent("name"),
":", ":",
AnyOf( AnyOf(
*OBJECT_HOOKS, OBJECT_HOOKS,
object, object,
value, value,
).expected("a value"), ).expected("a value"),
@ -82,7 +82,7 @@ def parse(tokens) -> T.Tuple[ast.UI, T.Optional[MultipleErrors]]:
[ [
"{", "{",
Until(AnyOf( Until(AnyOf(
*OBJECT_CONTENT_HOOKS, OBJECT_CONTENT_HOOKS,
binding, binding,
property, property,
child, child,
@ -116,7 +116,7 @@ def parse(tokens) -> T.Tuple[ast.UI, T.Optional[MultipleErrors]]:
ast.GtkDirective, ast.GtkDirective,
ZeroOrMore(ast.Import), ZeroOrMore(ast.Import),
Until(AnyOf( Until(AnyOf(
*OBJECT_HOOKS, OBJECT_HOOKS,
template, template,
object, object,
), Eof()), ), Eof()),