aboutsummaryrefslogtreecommitdiff
path: root/find-modules/rules_engine.py
diff options
context:
space:
mode:
authorStephen Kelly <steveire@gmail.com>2017-01-14 22:13:49 +0000
committerStephen Kelly <steveire@gmail.com>2017-01-15 11:18:50 +0000
commit636d6acc7adf8bf7169d38833340161dc42d3484 (patch)
tree2ff1bbefa5808aec21e902b10c9547e359067604 /find-modules/rules_engine.py
parent8c347c61abafa68e247ff4664ae658cfa15af932 (diff)
downloadextra-cmake-modules-636d6acc7adf8bf7169d38833340161dc42d3484.tar.gz
extra-cmake-modules-636d6acc7adf8bf7169d38833340161dc42d3484.tar.bz2
Bindings: Fix handling of forward declarations
It is not appropriate to decorate each forward declaration with the SIP attribute /External/. That is only needed for forward declarations of types which are defined in a different module. Local forward declarations can be omitted from the sip code. In sip code, a forward declaration followed later by a full class definition is an error. Omit forward declarations unless they are decorated with the external attribute. Introduce a rules database for consumers to decorate them with the attribute as required.
Diffstat (limited to 'find-modules/rules_engine.py')
-rwxr-xr-xfind-modules/rules_engine.py77
1 files changed, 77 insertions, 0 deletions
diff --git a/find-modules/rules_engine.py b/find-modules/rules_engine.py
index 34bd15dc..897d0433 100755
--- a/find-modules/rules_engine.py
+++ b/find-modules/rules_engine.py
@@ -235,6 +235,71 @@ class ContainerRuleDb(AbstractCompiledRuleDb):
return None
+class ForwardDeclarationRuleDb(AbstractCompiledRuleDb):
+ """
+ THE RULES FOR FORWARD DECLARATIONS.
+
+ These are used to customise the behaviour of the SIP generator by allowing
+ the forward declaration for any container (class, struct, union) to be
+ customised, for example to add SIP compiler annotations.
+
+ Each entry in the raw rule database must be a list with members as follows:
+
+ 0. A regular expression which matches the fully-qualified name of the
+ "container" enclosing the container.
+
+ 1. A regular expression which matches the container name.
+
+ 2. A regular expression which matches any template parameters.
+
+ 3. A function.
+
+ In use, the database is walked in order from the first entry. If the regular
+ expressions are matched, the function is called, and no further entries are
+ walked. The function is called with the following contract:
+
+ def declaration_xxx(container, sip, matcher):
+ '''
+ Return a modified declaration for the given container.
+
+ :param container: The clang.cindex.Cursor for the container.
+ :param sip: A dict with the following keys:
+
+ name The name of the container.
+ template_parameters Any template parameters.
+ annotations Any SIP annotations.
+
+ :param matcher: The re.Match object. This contains named
+ groups corresponding to the key names above
+ EXCEPT body and annotations.
+
+ :return: An updated set of sip.xxx values. Setting sip.name to the
+ empty string will cause the container to be suppressed.
+ '''
+
+ :return: The compiled form of the rules.
+ """
+ def __init__(self, db):
+ super(ForwardDeclarationRuleDb, self).__init__(db, ["parents", "container", "template_parameters"])
+
+ def apply(self, container, sip):
+ """
+ Walk over the rules database for containers, applying the first matching transformation.
+
+ :param container: The clang.cindex.Cursor for the container.
+ :param sip: The SIP dict (may be modified on return).
+ :return: Modifying rule or None (even if a rule matched, it may not modify things).
+ """
+ parents = _parents(container)
+ matcher, rule = self._match(parents, sip["name"],
+ ", ".join(sip["template_parameters"]))
+ if matcher:
+ before = deepcopy(sip)
+ rule.fn(container, sip, matcher)
+ return rule.trace_result(parents, container, before, sip)
+ return None
+
+
class FunctionRuleDb(AbstractCompiledRuleDb):
"""
THE RULES FOR FUNCTIONS.
@@ -774,6 +839,15 @@ class RuleSet(object):
raise NotImplemented(_("Missing subclass implementation"))
@abstractmethod
+ def forward_declaration_rules(self):
+ """
+ Return a compiled list of rules for containers.
+
+ :return: A ForwardDeclarationRuleDb instance
+ """
+ raise NotImplemented(_("Missing subclass implementation"))
+
+ @abstractmethod
def function_rules(self):
"""
Return a compiled list of rules for functions.
@@ -888,6 +962,9 @@ def typedef_discard(container, typedef, sip, matcher):
def discard_QSharedData_base(container, sip, matcher):
sip["base_specifiers"].remove("QSharedData")
+def mark_forward_declaration_external(container, sip, matcher):
+ sip["annotations"].add("External")
+
def rules(project_rules):
"""
Constructor.