Compare commits

..

No commits in common. "main" and "v0.16.0" have entirely different histories.

28 changed files with 37 additions and 209 deletions

View file

@ -3,7 +3,7 @@ stages:
- pages - pages
build: build:
image: registry.gitlab.gnome.org/gnome/blueprint-compiler image: registry.gitlab.gnome.org/jwestman/blueprint-compiler
stage: build stage: build
script: script:
- black --check --diff ./ tests - black --check --diff ./ tests
@ -33,7 +33,7 @@ build:
path: coverage.xml path: coverage.xml
fuzz: fuzz:
image: registry.gitlab.gnome.org/gnome/blueprint-compiler image: registry.gitlab.gnome.org/jwestman/blueprint-compiler
stage: build stage: build
script: script:
- meson _build - meson _build

View file

@ -8,7 +8,7 @@ in the NEWS file.
3. Make a new commit with just these two changes. Use `Release v{version}` as the commit message. Tag the commit as `v{version}` and push the tag. 3. Make a new commit with just these two changes. Use `Release v{version}` as the commit message. Tag the commit as `v{version}` and push the tag.
4. Create a "Post-release version bump" commit. 4. Create a "Post-release version bump" commit.
5. Go to the Releases page in GitLab and create a new release from the tag. 5. Go to the Releases page in GitLab and create a new release from the tag.
6. Announce the release through relevant channels (Mastodon, TWIG, etc.) 6. Announce the release through relevant channels (Twitter, TWIG, etc.)
## Related projects ## Related projects

View file

@ -1,27 +0,0 @@
<Project xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns:rdfs="http://www.w3.org/2000/01/rdf-schema#"
xmlns:foaf="http://xmlns.com/foaf/0.1/"
xmlns:gnome="http://api.gnome.org/doap-extensions#"
xmlns="http://usefulinc.com/ns/doap#">
<name xml:lang="en">Blueprint</name>
<shortdesc xml:lang="en">A modern language for creating GTK interfaces</shortdesc>
<description xml:lang="en">Blueprint is a language and associated tooling for building user interfaces for GTK.</description>
<category rdf:resource="http://api.gnome.org/doap-extensions#apps" />
<programming-language>Python</programming-language>
<homepage
rdf:resource="https://gnome.gitlab.gnome.org/blueprint-compiler/" />
<download-page
rdf:resource="https://gitlab.gnome.org/GNOME/blueprint-compiler/-/releases" />
<bug-database
rdf:resource="https://gitlab.gnome.org/GNOME/blueprint-compiler/issues" />
<maintainer>
<foaf:Person>
<foaf:name>James Westman</foaf:name>
<foaf:mbox rdf:resource="mailto:james@jwestman.net" />
<gnome:userid>jwestman</gnome:userid>
</foaf:Person>
</maintainer>
</Project>

View file

@ -255,11 +255,7 @@ def decompile_element(
ctx._node_stack.append(xml) ctx._node_stack.append(xml)
ctx.start_block() ctx.start_block()
try:
gir = decompiler(*args, **kwargs) gir = decompiler(*args, **kwargs)
except TypeError as e:
raise UnsupportedError(tag=xml.tag)
if not decompiler._skip_children: if not decompiler._skip_children:
for child in xml.children: for child in xml.children:
@ -270,6 +266,8 @@ def decompile_element(
except UnsupportedError as e: except UnsupportedError as e:
raise e raise e
except TypeError as e:
raise UnsupportedError(tag=xml.tag)
def decompile(data: str) -> str: def decompile(data: str) -> str:

View file

@ -219,7 +219,7 @@ def report_bug(): # pragma: no cover
f"""{Colors.BOLD}{Colors.RED}***** COMPILER BUG ***** f"""{Colors.BOLD}{Colors.RED}***** COMPILER BUG *****
The blueprint-compiler program has crashed. Please report the above stacktrace, The blueprint-compiler program has crashed. Please report the above stacktrace,
along with the input file(s) if possible, on GitLab: along with the input file(s) if possible, on GitLab:
{Colors.BOLD}{Colors.BLUE}{Colors.UNDERLINE}https://gitlab.gnome.org/GNOME/blueprint-compiler/-/issues/new?issue {Colors.BOLD}{Colors.BLUE}{Colors.UNDERLINE}https://gitlab.gnome.org/jwestman/blueprint-compiler/-/issues/new?issue
{Colors.CLEAR}""" {Colors.CLEAR}"""
) )

View file

@ -71,7 +71,7 @@ def decompile_file(in_file, out_file) -> T.Union[str, CouldNotPort]:
print( print(
f"""{Colors.FAINT}Either the original XML file had an error, or there is a bug in the f"""{Colors.FAINT}Either the original XML file had an error, or there is a bug in the
porting tool. If you think it's a bug (which is likely), please file an issue on GitLab: porting tool. If you think it's a bug (which is likely), please file an issue on GitLab:
{Colors.BLUE}{Colors.UNDERLINE}https://gitlab.gnome.org/GNOME/blueprint-compiler/-/issues/new?issue{Colors.CLEAR}\n""" {Colors.BLUE}{Colors.UNDERLINE}https://gitlab.gnome.org/jwestman/blueprint-compiler/-/issues/new?issue{Colors.CLEAR}\n"""
) )
return CouldNotPort("does not compile") return CouldNotPort("does not compile")
@ -136,7 +136,7 @@ def step1():
wrap.write( wrap.write(
f"""[wrap-git] f"""[wrap-git]
directory = blueprint-compiler directory = blueprint-compiler
url = https://gitlab.gnome.org/GNOME/blueprint-compiler.git url = https://gitlab.gnome.org/jwestman/blueprint-compiler.git
revision = {VERSION} revision = {VERSION}
depth = 1 depth = 1

View file

@ -81,8 +81,8 @@ class AdwBreakpointSetter(AstNode):
return self.tokens["property"] return self.tokens["property"]
@property @property
def value(self) -> T.Optional[Value]: def value(self) -> Value:
return self.children[Value][0] if len(self.children[Value]) > 0 else None return self.children[Value][0]
@property @property
def gir_class(self) -> T.Optional[GirType]: def gir_class(self) -> T.Optional[GirType]:
@ -106,10 +106,7 @@ class AdwBreakpointSetter(AstNode):
return None return None
@property @property
def document_symbol(self) -> T.Optional[DocumentSymbol]: def document_symbol(self) -> DocumentSymbol:
if self.value is None:
return None
return DocumentSymbol( return DocumentSymbol(
f"{self.object_id}.{self.property_name}", f"{self.object_id}.{self.property_name}",
SymbolKind.Property, SymbolKind.Property,

View file

@ -302,18 +302,12 @@ expr.children = [
@decompiler("lookup", skip_children=True, cdata=True) @decompiler("lookup", skip_children=True, cdata=True)
def decompile_lookup( def decompile_lookup(
ctx: DecompileCtx, ctx: DecompileCtx, gir: gir.GirContext, cdata: str, name: str, type: str
gir: gir.GirContext,
cdata: str,
name: str,
type: T.Optional[str] = None,
): ):
if ctx.parent_node is not None and ctx.parent_node.tag == "property": if ctx.parent_node is not None and ctx.parent_node.tag == "property":
ctx.print("expr ") ctx.print("expr ")
if type is None: if t := ctx.type_by_cname(type):
type = ""
elif t := ctx.type_by_cname(type):
type = decompile.full_name(t) type = decompile.full_name(t)
else: else:
type = "$" + type type = "$" + type
@ -333,7 +327,7 @@ def decompile_lookup(
if constant == ctx.template_class: if constant == ctx.template_class:
ctx.print("template." + name) ctx.print("template." + name)
elif constant == "": elif constant == "":
ctx.print(f"item as <{type}>.{name}") ctx.print("item as <" + type + ">." + name)
else: else:
ctx.print(constant + "." + name) ctx.print(constant + "." + name)
return return

View file

@ -225,14 +225,8 @@ class Signal(AstNode):
@decompiler("signal") @decompiler("signal")
def decompile_signal( def decompile_signal(ctx, gir, name, handler, swapped=None, after="false", object=None):
ctx: DecompileCtx, gir, name, handler, swapped=None, after="false", object=None
):
object_name = object or "" object_name = object or ""
if object_name == ctx.template_class:
object_name = "template"
name = name.replace("_", "-") name = name.replace("_", "-")
line = f"{name} => ${handler}({object_name})" line = f"{name} => ${handler}({object_name})"

View file

@ -225,12 +225,12 @@ class Flag(AstNode):
return self.tokens["value"] return self.tokens["value"]
@property @property
def value(self) -> T.Optional[str]: def value(self) -> T.Optional[int]:
type = self.context[ValueTypeCtx].value_type type = self.context[ValueTypeCtx].value_type
if not isinstance(type, Enumeration): if not isinstance(type, Enumeration):
return None return None
elif member := type.members.get(self.name): elif member := type.members.get(self.name):
return member.nick return member.value
else: else:
return None return None

View file

@ -308,9 +308,6 @@ class XmlOutput(OutputFormat):
elif isinstance(extension, AdwBreakpointSetters): elif isinstance(extension, AdwBreakpointSetters):
for setter in extension.setters: for setter in extension.setters:
if setter.value is None:
continue
attrs = {} attrs = {}
if isinstance(setter.value.child, Translated): if isinstance(setter.value.child, Translated):

View file

@ -73,7 +73,6 @@ class XmlEmitter:
self._needs_newline = False self._needs_newline = False
def put_cdata(self, text: str): def put_cdata(self, text: str):
text = text.replace("]]>", "]]]]><![CDATA[>")
self.result += f"<![CDATA[{text}]]>" self.result += f"<![CDATA[{text}]]>"
self._needs_newline = False self._needs_newline = False

View file

@ -17,7 +17,7 @@
# #
# SPDX-License-Identifier: LGPL-3.0-or-later # SPDX-License-Identifier: LGPL-3.0-or-later
"""Utilities for parsing an AST from a token stream.""" """ Utilities for parsing an AST from a token stream. """
import typing as T import typing as T
from enum import Enum from enum import Enum

View file

@ -9,7 +9,7 @@ from pathlib import Path
__all__ = ["get_docs_section"] __all__ = ["get_docs_section"]
DOCS_ROOT = "https://gnome.pages.gitlab.gnome.org/blueprint-compiler" DOCS_ROOT = "https://jwestman.pages.gitlab.gnome.org/blueprint-compiler"
sections: dict[str, "Section"] = {} sections: dict[str, "Section"] = {}
@ -132,8 +132,5 @@ if __name__ == "__main__":
# print the sections to a json file # print the sections to a json file
with open(outfile, "w") as f: with open(outfile, "w") as f:
json.dump( json.dump(
{name: section.to_json() for name, section in sections.items()}, {name: section.to_json() for name, section in sections.items()}, f, indent=2
f,
indent=2,
sort_keys=True,
) )

View file

@ -16,7 +16,7 @@ a module in your flatpak manifest:
"sources": [ "sources": [
{ {
"type": "git", "type": "git",
"url": "https://gitlab.gnome.org/GNOME/blueprint-compiler", "url": "https://gitlab.gnome.org/jwestman/blueprint-compiler",
"tag": "v0.16.0" "tag": "v0.16.0"
} }
] ]

View file

@ -26,7 +26,7 @@ Blueprint is a markup language and compiler for GTK 4 user interfaces.
using Gtk 4.0; using Gtk 4.0;
template $MyAppWindow: ApplicationWindow { template MyAppWindow : ApplicationWindow {
default-width: 600; default-width: 600;
default-height: 300; default-height: 300;
title: _("Hello, Blueprint!"); title: _("Hello, Blueprint!");
@ -35,7 +35,7 @@ Blueprint is a markup language and compiler for GTK 4 user interfaces.
HeaderBar {} HeaderBar {}
Label { Label {
label: bind template.main_text; label: bind MyAppWindow.main_text;
} }
} }
@ -59,7 +59,7 @@ Features
Links Links
----- -----
- `Source code <https://gitlab.gnome.org/GNOME/blueprint-compiler>`_ - `Source code <https://gitlab.gnome.org/jwestman/blueprint-compiler>`_
- `Workbench <https://github.com/sonnyp/Workbench>`_ lets you try, preview and export Blueprint - `Workbench <https://github.com/sonnyp/Workbench>`_ lets you try, preview and export Blueprint
- `GNOME Builder <https://developer.gnome.org/documentation/introduction/builder.html>`_ provides builtin support - `GNOME Builder <https://developer.gnome.org/documentation/introduction/builder.html>`_ provides builtin support
- `Vim syntax highlighting plugin by thetek42 <https://github.com/thetek42/vim-blueprint-syntax>`_ - `Vim syntax highlighting plugin by thetek42 <https://github.com/thetek42/vim-blueprint-syntax>`_

View file

@ -10,7 +10,7 @@ Properties are the main way to set values on objects, but they are limited by th
Extensions are a feature of ``Gtk.Buildable``--see `Gtk.Buildable.custom_tag_start() <https://docs.gtk.org/gtk4/vfunc.Buildable.custom_tag_start.html>`_ for internal details. Extensions are a feature of ``Gtk.Buildable``--see `Gtk.Buildable.custom_tag_start() <https://docs.gtk.org/gtk4/vfunc.Buildable.custom_tag_start.html>`_ for internal details.
Because they aren't part of the type system, they aren't present in typelib files like properties and signals are. Therefore, if a library adds a new extension, syntax for it must be added to Blueprint manually. If there's a commonly used extension that isn't supported by Blueprint, please `file an issue <https://gitlab.gnome.org/GNOME/blueprint-compiler/-/issues>`_. Because they aren't part of the type system, they aren't present in typelib files like properties and signals are. Therefore, if a library adds a new extension, syntax for it must be added to Blueprint manually. If there's a commonly used extension that isn't supported by Blueprint, please `file an issue <https://gitlab.gnome.org/jwestman/blueprint-compiler/-/issues>`_.
.. rst-class:: grammar-block .. rst-class:: grammar-block

View file

@ -8,7 +8,7 @@ Setting up Blueprint on a new or existing project
Using the porting tool Using the porting tool
~~~~~~~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~~~~~~~
Clone `blueprint-compiler <https://gitlab.gnome.org/GNOME/blueprint-compiler>`_ Clone `blueprint-compiler <https://gitlab.gnome.org/jwestman/blueprint-compiler>`_
from source. You can install it using ``meson _build`` and ``ninja -C _build install``, from source. You can install it using ``meson _build`` and ``ninja -C _build install``,
or you can leave it uninstalled. or you can leave it uninstalled.
@ -29,7 +29,7 @@ blueprint-compiler works as a meson subproject.
[wrap-git] [wrap-git]
directory = blueprint-compiler directory = blueprint-compiler
url = https://gitlab.gnome.org/GNOME/blueprint-compiler.git url = https://gitlab.gnome.org/jwestman/blueprint-compiler.git
revision = main revision = main
depth = 1 depth = 1

View file

@ -7,7 +7,7 @@ corresponding .blp file and regenerate this file with blueprint-compiler.
<interface> <interface>
<requires lib="gtk" version="4.0"/> <requires lib="gtk" version="4.0"/>
<object class="GApplication"> <object class="GApplication">
<property name="flags">is-service|handles-open</property> <property name="flags">1|4</property>
</object> </object>
<object class="GtkEventControllerScroll"> <object class="GtkEventControllerScroll">
<property name="flags">1</property> <property name="flags">1</property>

View file

@ -1,15 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<interface>
<requires lib="gtk" version="4.0"/>
<template class="GtkListItem">
<property name="child">
<object class="GtkLabel">
<binding name="label">
<lookup type="RecentObject" name="filename">
<lookup name="item">GtkListItem</lookup>
</lookup>
</binding>
</object>
</property>
</template>
</interface>

View file

@ -1,7 +0,0 @@
using Gtk 4.0;
template ListItem {
child: Label {
label: bind template.item as <$RecentObject>.filename;
};
}

View file

@ -1,17 +0,0 @@
using Gtk 4.0;
Gtk.ListView {
factory: Gtk.BuilderListItemFactory list_item_factory {
template ListItem {
child: Gtk.ListView {
factory: Gtk.BuilderListItemFactory list_item_factory {
template ListItem {
child: Gtk.Label {
label: bind template.item as <$MyObject>.name;
};
}
};
};
}
};
}

View file

@ -1,44 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<!--
DO NOT EDIT!
This file was @generated by blueprint-compiler. Instead, edit the
corresponding .blp file and regenerate this file with blueprint-compiler.
-->
<interface>
<requires lib="gtk" version="4.0"/>
<object class="GtkListView">
<property name="factory">
<object class="GtkBuilderListItemFactory" id="list_item_factory">
<property name="bytes"><![CDATA[<?xml version="1.0" encoding="UTF-8"?>
<interface>
<template class="GtkListItem">
<property name="child">
<object class="GtkListView">
<property name="factory">
<object class="GtkBuilderListItemFactory" id="list_item_factory">
<property name="bytes"><![CDATA[<?xml version="1.0" encoding="UTF-8"?>
<interface>
<template class="GtkListItem">
<property name="child">
<object class="GtkLabel">
<binding name="label">
<lookup name="name" type="MyObject">
<lookup name="item" type="GtkListItem">
<constant>GtkListItem</constant>
</lookup>
</lookup>
</binding>
</object>
</property>
</template>
</interface>]]]]><![CDATA[></property>
</object>
</property>
</object>
</property>
</template>
</interface>]]></property>
</object>
</property>
</object>
</interface>

View file

@ -1,18 +0,0 @@
using Gtk 4.0;
ListView {
factory: BuilderListItemFactory list_item_factory {
template ListItem {
child: ListView {
factory: BuilderListItemFactory list_item_factory {
template ListItem {
child: Label {
label: bind template.item as <$MyObject>.name;
};
}
};
};
}
};
}

View file

@ -1,7 +0,0 @@
using Gtk 4.0;
template $MyTemplate {
Button {
clicked => $my_signal_handler(template);
}
}

View file

@ -1,16 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<!--
DO NOT EDIT!
This file was @generated by blueprint-compiler. Instead, edit the
corresponding .blp file and regenerate this file with blueprint-compiler.
-->
<interface>
<requires lib="gtk" version="4.0"/>
<template class="MyTemplate">
<child>
<object class="GtkButton">
<signal name="clicked" handler="my_signal_handler" object="MyTemplate"/>
</object>
</child>
</template>
</interface>

View file

@ -181,7 +181,11 @@ class TestSamples(unittest.TestCase):
def test_samples(self): def test_samples(self):
# list the samples directory # list the samples directory
samples = [f.stem for f in Path(__file__).parent.glob("samples/*.blp")] samples = [
f.stem
for f in Path(__file__).parent.glob("samples/*.blp")
if not f.stem.endswith("_dec")
]
samples.sort() samples.sort()
for sample in samples: for sample in samples:
REQUIRE_ADW_1_4 = ["adw_breakpoint"] REQUIRE_ADW_1_4 = ["adw_breakpoint"]
@ -198,7 +202,6 @@ class TestSamples(unittest.TestCase):
"parseable", "parseable",
"signal", "signal",
"signal_not_swapped", "signal_not_swapped",
"signal_template_object",
"template", "template",
"template_binding", "template_binding",
"template_binding_extern", "template_binding_extern",
@ -212,7 +215,7 @@ class TestSamples(unittest.TestCase):
] ]
# Decompiler-only tests # Decompiler-only tests
SKIP_COMPILE = ["issue_177", "issue_187", "translator_comments"] SKIP_COMPILE = ["issue_177", "translator_comments"]
SKIP_DECOMPILE = [ SKIP_DECOMPILE = [
# Comments are not preserved in either direction # Comments are not preserved in either direction
@ -225,7 +228,7 @@ class TestSamples(unittest.TestCase):
continue continue
with self.subTest(sample): with self.subTest(sample):
if sample not in SKIP_COMPILE and not sample.endswith("_dec"): if sample not in SKIP_COMPILE:
self.assert_sample(sample, skip_run=sample in SKIP_RUN) self.assert_sample(sample, skip_run=sample in SKIP_RUN)
with self.subTest("decompile/" + sample): with self.subTest("decompile/" + sample):

View file

@ -25,7 +25,7 @@ from blueprintcompiler.tokenizer import Token, TokenType, tokenize
class TestTokenizer(unittest.TestCase): class TestTokenizer(unittest.TestCase):
def assert_tokenize(self, string: str, expect: list[Token]): def assert_tokenize(self, string: str, expect: [Token]):
try: try:
tokens = tokenize(string) tokens = tokenize(string)
self.assertEqual(len(tokens), len(expect)) self.assertEqual(len(tokens), len(expect))