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 |