mirror of
https://gitlab.gnome.org/jwestman/blueprint-compiler.git
synced 2025-05-04 15:59:08 -04:00
Create an interactive porting tool
`blueprint-compiler port` interactively ports a project to blueprint. It will create the subproject wrap file, add it to .gitignore, decompile your GtkBuilder XML files, emit code to copy and paste into your meson.build file, and update POTFILES.in. It can't quite handle all of the features the forward compiler can, so it will skip those files.
This commit is contained in:
parent
84dfe74755
commit
8e4433a487
19 changed files with 921 additions and 61 deletions
|
@ -142,6 +142,10 @@ class GirNode:
|
|||
def name(self) -> str:
|
||||
return self.xml["name"]
|
||||
|
||||
@lazy_prop
|
||||
def cname(self) -> str:
|
||||
return self.xml["c:type"]
|
||||
|
||||
@lazy_prop
|
||||
def available_in(self) -> str:
|
||||
return self.xml.get("version")
|
||||
|
@ -176,10 +180,6 @@ class Property(GirNode):
|
|||
def __init__(self, klass, xml: xml_reader.Element):
|
||||
super().__init__(klass, xml)
|
||||
|
||||
@property
|
||||
def type_name(self):
|
||||
return self.xml.get_elements('type')[0]['name']
|
||||
|
||||
@property
|
||||
def signature(self):
|
||||
return f"{self.type_name} {self.container.name}.{self.name}"
|
||||
|
@ -295,12 +295,16 @@ class EnumMember(GirNode):
|
|||
def nick(self):
|
||||
return self.xml["glib:nick"]
|
||||
|
||||
@property
|
||||
def c_ident(self):
|
||||
return self.xml["c:identifier"]
|
||||
|
||||
@property
|
||||
def signature(self):
|
||||
return f"enum member {self.full_name} = {self.value}"
|
||||
|
||||
|
||||
class Enumeration(GirNode):
|
||||
class Enumeration(GirNode, GirType):
|
||||
def __init__(self, ns, xml: xml_reader.Element):
|
||||
super().__init__(ns, xml)
|
||||
self.members = { child["name"]: EnumMember(self, child) for child in xml.get_elements("member") }
|
||||
|
@ -309,6 +313,36 @@ class Enumeration(GirNode):
|
|||
def signature(self):
|
||||
return f"enum {self.full_name}"
|
||||
|
||||
def assignable_to(self, type):
|
||||
return type == self
|
||||
|
||||
|
||||
class BitfieldMember(GirNode):
|
||||
def __init__(self, ns, xml: xml_reader.Element):
|
||||
super().__init__(ns, xml)
|
||||
self._value = xml["value"]
|
||||
|
||||
@property
|
||||
def value(self):
|
||||
return self._value
|
||||
|
||||
@property
|
||||
def signature(self):
|
||||
return f"bitfield member {self.full_name} = {bin(self.value)}"
|
||||
|
||||
|
||||
class Bitfield(GirNode, GirType):
|
||||
def __init__(self, ns, xml: xml_reader.Element):
|
||||
super().__init__(ns, xml)
|
||||
self.members = { child["name"]: EnumMember(self, child) for child in xml.get_elements("member") }
|
||||
|
||||
@property
|
||||
def signature(self):
|
||||
return f"bitfield {self.full_name}"
|
||||
|
||||
def assignable_to(self, type):
|
||||
return type == self
|
||||
|
||||
|
||||
class Namespace(GirNode):
|
||||
def __init__(self, repo, xml: xml_reader.Element):
|
||||
|
@ -316,6 +350,7 @@ class Namespace(GirNode):
|
|||
self.classes = { child["name"]: Class(self, child) for child in xml.get_elements("class") }
|
||||
self.interfaces = { child["name"]: Interface(self, child) for child in xml.get_elements("interface") }
|
||||
self.enumerations = { child["name"]: Enumeration(self, child) for child in xml.get_elements("enumeration") }
|
||||
self.bitfields = { child["name"]: Bitfield(self, child) for child in xml.get_elements("bitfield") }
|
||||
self.version = xml["version"]
|
||||
|
||||
@property
|
||||
|
@ -325,7 +360,19 @@ class Namespace(GirNode):
|
|||
|
||||
def get_type(self, name):
|
||||
""" Gets a type (class, interface, enum, etc.) from this namespace. """
|
||||
return self.classes.get(name) or self.interfaces.get(name) or self.enumerations.get(name)
|
||||
return (
|
||||
self.classes.get(name)
|
||||
or self.interfaces.get(name)
|
||||
or self.enumerations.get(name)
|
||||
or self.bitfields.get(name)
|
||||
)
|
||||
|
||||
|
||||
def get_type_by_cname(self, cname: str):
|
||||
""" Gets a type from this namespace by its C name. """
|
||||
for item in [*self.classes.values(), *self.interfaces.values(), *self.enumerations.values()]:
|
||||
if item.cname == cname:
|
||||
return item
|
||||
|
||||
|
||||
def lookup_type(self, type_name: str):
|
||||
|
@ -359,6 +406,13 @@ class Repository(GirNode):
|
|||
return self.lookup_namespace(ns).get_type(name)
|
||||
|
||||
|
||||
def get_type_by_cname(self, name: str) -> T.Optional[GirNode]:
|
||||
for ns in self.namespaces.values():
|
||||
if type := ns.get_type_by_cname(name):
|
||||
return type
|
||||
return None
|
||||
|
||||
|
||||
def lookup_namespace(self, ns: str):
|
||||
""" Finds a namespace among this namespace's dependencies. """
|
||||
if namespace := self.namespaces.get(ns):
|
||||
|
@ -382,6 +436,13 @@ class GirContext:
|
|||
self.namespaces[namespace.name] = namespace
|
||||
|
||||
|
||||
def get_type_by_cname(self, name: str) -> T.Optional[GirNode]:
|
||||
for ns in self.namespaces.values():
|
||||
if type := ns.get_type_by_cname(name):
|
||||
return type
|
||||
return None
|
||||
|
||||
|
||||
def get_type(self, name: str, ns: str) -> T.Optional[GirNode]:
|
||||
ns = ns or "Gtk"
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue