reorganization: Rename extensions -> language

I want all language elements to be defined in the same folder, rather
than having the "core" language split by parsing/AST/completions and the rest
split by language element.
This commit is contained in:
James Westman 2022-01-26 14:10:39 -06:00
parent 76f7befd68
commit 34f525beaa
14 changed files with 133 additions and 86 deletions

View file

@ -0,0 +1,101 @@
# gobject_signal.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 Signal(AstNode):
grammar = Statement(
UseIdent("name"),
Optional([
"::",
UseIdent("detail_name").expected("a signal detail name"),
]),
"=>",
UseIdent("handler").expected("the name of a function to handle the signal"),
Match("(").expected("argument list"),
Optional(UseIdent("object")).expected("object identifier"),
Match(")").expected(),
ZeroOrMore(AnyOf(
[Keyword("swapped"), UseLiteral("swapped", True)],
[Keyword("after"), UseLiteral("after", True)],
)),
)
@property
def gir_signal(self):
if self.gir_class is not None:
return self.gir_class.signals.get(self.tokens["name"])
@property
def gir_class(self):
return self.parent.parent.gir_class
@validate("name")
def signal_exists(self):
if self.gir_class is None:
# Objects that we have no gir data on should not be validated
# This happens for classes defined by the app itself
return
if isinstance(self.parent.parent, Template):
# If the signal is part of a template, it might be defined by
# the application and thus not in gir
return
if self.gir_signal is None:
raise CompileError(
f"Class {self.gir_class.full_name} does not contain a signal called {self.tokens['name']}",
did_you_mean=(self.tokens["name"], self.gir_class.signals.keys())
)
@validate("object")
def object_exists(self):
object_id = self.tokens["object"]
if object_id is None:
return
if self.root.objects_by_id.get(object_id) is None:
raise CompileError(
f"Could not find object with ID '{object_id}'"
)
@docs("name")
def signal_docs(self):
if self.gir_signal is not None:
return self.gir_signal.doc
def emit_xml(self, xml: XmlEmitter):
name = self.tokens["name"]
if self.tokens["detail_name"]:
name += "::" + self.tokens["detail_name"]
xml.put_self_closing(
"signal",
name=name,
handler=self.tokens["handler"],
swapped="true" if self.tokens["swapped"] else None,
object=self.tokens["object"]
)