89 lines
3.9 KiB
Python
89 lines
3.9 KiB
Python
"""Instantiate a namespace."""
|
|
|
|
import itertools
|
|
|
|
import gtwrap.interface_parser as parser
|
|
from gtwrap.template_instantiator.classes import InstantiatedClass
|
|
from gtwrap.template_instantiator.declaration import InstantiatedDeclaration
|
|
from gtwrap.template_instantiator.function import InstantiatedGlobalFunction
|
|
|
|
|
|
def instantiate_namespace(namespace):
|
|
"""
|
|
Instantiate the classes and other elements in the `namespace` content and
|
|
assign it back to the namespace content attribute.
|
|
|
|
@param[in/out] namespace The namespace whose content will be replaced with
|
|
the instantiated content.
|
|
"""
|
|
instantiated_content = []
|
|
typedef_content = []
|
|
|
|
for element in namespace.content:
|
|
if isinstance(element, parser.Class):
|
|
original_class = element
|
|
if not original_class.template:
|
|
instantiated_content.append(
|
|
InstantiatedClass(original_class, []))
|
|
else:
|
|
# This case is for when the templates have enumerated instantiations.
|
|
|
|
# Use itertools to get all possible combinations of instantiations
|
|
# Works even if one template does not have an instantiation list
|
|
for instantiations in itertools.product(
|
|
*original_class.template.instantiations):
|
|
instantiated_content.append(
|
|
InstantiatedClass(original_class,
|
|
list(instantiations)))
|
|
|
|
elif isinstance(element, parser.GlobalFunction):
|
|
original_func = element
|
|
if not original_func.template:
|
|
instantiated_content.append(
|
|
InstantiatedGlobalFunction(original_func, []))
|
|
else:
|
|
# Use itertools to get all possible combinations of instantiations
|
|
# Works even if one template does not have an instantiation list
|
|
for instantiations in itertools.product(
|
|
*original_func.template.instantiations):
|
|
instantiated_content.append(
|
|
InstantiatedGlobalFunction(original_func,
|
|
list(instantiations)))
|
|
|
|
elif isinstance(element, parser.TypedefTemplateInstantiation):
|
|
# This is for the case where `typedef` statements are used
|
|
# to specify the template parameters.
|
|
typedef_inst = element
|
|
top_level = namespace.top_level()
|
|
original_element = top_level.find_class_or_function(
|
|
typedef_inst.typename)
|
|
|
|
# Check if element is a typedef'd class, function or
|
|
# forward declaration from another project.
|
|
if isinstance(original_element, parser.Class):
|
|
typedef_content.append(
|
|
InstantiatedClass(original_element,
|
|
typedef_inst.typename.instantiations,
|
|
typedef_inst.new_name))
|
|
elif isinstance(original_element, parser.GlobalFunction):
|
|
typedef_content.append(
|
|
InstantiatedGlobalFunction(
|
|
original_element, typedef_inst.typename.instantiations,
|
|
typedef_inst.new_name))
|
|
elif isinstance(original_element, parser.ForwardDeclaration):
|
|
typedef_content.append(
|
|
InstantiatedDeclaration(
|
|
original_element, typedef_inst.typename.instantiations,
|
|
typedef_inst.new_name))
|
|
|
|
elif isinstance(element, parser.Namespace):
|
|
element = instantiate_namespace(element)
|
|
instantiated_content.append(element)
|
|
else:
|
|
instantiated_content.append(element)
|
|
|
|
instantiated_content.extend(typedef_content)
|
|
namespace.content = instantiated_content
|
|
|
|
return namespace
|