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
							 |