Add lambda values

This commit is contained in:
James Westman 2022-07-09 19:20:15 -05:00
parent 30f0deea34
commit d7155981b1
No known key found for this signature in database
GPG key ID: CE2DBA0ADB654EA6
8 changed files with 119 additions and 4 deletions

View file

@ -16,6 +16,7 @@ from .gtk_string_list import Strings
from .gtk_styles import Styles
from .gtkbuilder_child import Child
from .gtkbuilder_template import Template
from .lambdas import Lambda
from .imports import GtkDirective, Import
from .ui import UI
from .values import IdentValue, TranslatedStringValue, FlagsValue, LiteralValue
@ -47,4 +48,5 @@ VALUE_HOOKS.children = [
FlagsValue,
IdentValue,
LiteralValue,
Lambda,
]

View file

@ -33,3 +33,24 @@ from ..xml_emitter import XmlEmitter
OBJECT_HOOKS = AnyOf()
OBJECT_CONTENT_HOOKS = AnyOf()
VALUE_HOOKS = AnyOf()
class Scope:
def get_variables(self) -> T.Iterator[str]:
yield from self.get_objects().keys()
def get_objects(self) -> T.Dict[str, T.Any]:
raise NotImplementedError()
@property
def this_name(self) -> T.Optional[str]:
return None
@property
def this_type(self) -> T.Optional[str]:
return None
@property
def this_type_glib_name(self) -> T.Optional[str]:
return None

View file

@ -41,7 +41,14 @@ class InfixExpr(AstNode):
class IdentExpr(AstNode):
grammar = UseIdent("ident")
@property
def is_this(self):
return self.parent_by_type(Scope).this_name == self.tokens["ident"]
def emit_xml(self, xml: XmlEmitter):
if self.is_this:
raise CompilerBugError()
xml.start_tag("constant")
xml.put_text(self.tokens["ident"])
xml.end_tag()
@ -51,6 +58,9 @@ class LookupOp(InfixExpr):
grammar = [".", UseIdent("property")]
def emit_xml(self, xml: XmlEmitter):
if isinstance(self.lhs, IdentExpr) and self.lhs.is_this:
xml.put_self_closing("lookup", name=self.tokens["property"], type=self.parent_by_type(Scope).this_type)
else:
xml.start_tag("lookup", name=self.tokens["property"])
self.lhs.emit_xml(xml)
xml.end_tag()

View file

@ -0,0 +1,54 @@
# lambdas.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 .types import TypeName
from .expression import Expr
from .values import Value
from .common import *
class Lambda(Value, Scope):
grammar = [
"(",
TypeName,
UseIdent("argument"),
")",
"=>",
Expr,
]
def emit_xml(self, xml: XmlEmitter):
for child in self.children:
child.emit_xml(xml)
def get_objects(self):
return {
**self.parent.parent_by_type(Scope).get_objects(),
self.tokens["argument"]: None,
}
@property
def this_name(self) -> str:
return self.tokens["argument"]
@property
def this_type(self) -> str:
return self.children[TypeName][0].gir_type

View file

@ -24,7 +24,7 @@ from .gtkbuilder_template import Template
from .common import *
class UI(AstNode):
class UI(AstNode, Scope):
""" The AST node for the entire file """
grammar = [
@ -62,6 +62,8 @@ class UI(AstNode):
def objects_by_id(self):
return { obj.tokens["id"]: obj for obj in self.iterate_children_recursive() if obj.tokens["id"] is not None }
def get_objects(self):
return self.objects_by_id
@validate()
def gir_errors(self):

9
tests/samples/lambda.blp Normal file
View file

@ -0,0 +1,9 @@
using Gtk 4.0;
Gtk.BoolFilter filter {
expression: (Gtk.Label object) => object.visible;
}
Gtk.BoolFilter {
expression: (Gtk.Label object) => filter.invert;
}

16
tests/samples/lambda.ui Normal file
View file

@ -0,0 +1,16 @@
<?xml version="1.0" encoding="UTF-8"?>
<interface>
<requires lib="gtk" version="4.0"/>
<object class="GtkBoolFilter" id="filter">
<property name="expression">
<lookup name="visible" type="GtkLabel"/>
</property>
</object>
<object class="GtkBoolFilter">
<property name="expression">
<lookup name="invert">
<constant>filter</constant>
</lookup>
</property>
</object>
</interface>

View file

@ -141,6 +141,7 @@ class TestSamples(unittest.TestCase):
self.assert_sample("flags")
self.assert_sample("id_prop")
self.assert_sample("inline_menu")
self.assert_sample("lambda")
self.assert_sample("layout")
self.assert_sample("menu")
self.assert_sample("numbers")