diff options
author | Stephen Kelly <steveire@gmail.com> | 2017-01-14 22:13:49 +0000 |
---|---|---|
committer | Stephen Kelly <steveire@gmail.com> | 2017-01-15 11:18:50 +0000 |
commit | 636d6acc7adf8bf7169d38833340161dc42d3484 (patch) | |
tree | 2ff1bbefa5808aec21e902b10c9547e359067604 /find-modules/rules_engine.py | |
parent | 8c347c61abafa68e247ff4664ae658cfa15af932 (diff) | |
download | extra-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-x | find-modules/rules_engine.py | 77 |
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. |