def expand_attributes(self, attributes): for i in range(0, len(attributes)): [attrib_name, had_hyphen] = strFunctions.remove_hyphens(attributes[i]['name']) capname = strFunctions.upper_first(attrib_name) if had_hyphen: orig_name = attributes[i]['name'] attributes[i]['name'] = strFunctions.lower_first(orig_name) else: attributes[i]['name'] = strFunctions.lower_first(capname) attributes[i]['capAttName'] = capname attributes[i]['memberName'] = 'm' + capname attributes[i]['pluralName'] = \ strFunctions.plural(attrib_name) attributes[i]['isEnum'] = False attributes[i]['isArray'] = False attributes[i]['isVector'] = False attributes[i]['children_overwrite'] = False att_type = attributes[i]['type'] if att_type == 'SId' or att_type == 'SIdRef' or att_type == 'IDREF' or att_type == 'ID': attributes[i]['attType'] = 'string' attributes[i]['attTypeCode'] = 'std::string&' attributes[i]['CType'] = 'const char *' attributes[i]['isNumber'] = False attributes[i]['default'] = '""' elif att_type == 'UnitSId' or att_type == 'UnitSIdRef': attributes[i]['attType'] = 'string' attributes[i]['attTypeCode'] = 'std::string&' attributes[i]['CType'] = 'const char *' attributes[i]['isNumber'] = False attributes[i]['default'] = '""' elif att_type == 'string': attributes[i]['attType'] = 'string' attributes[i]['attTypeCode'] = 'std::string&' attributes[i]['CType'] = 'const char *' attributes[i]['isNumber'] = False attributes[i]['default'] = '""' elif att_type == 'double': attributes[i]['attType'] = 'double' attributes[i]['attTypeCode'] = 'double' attributes[i]['CType'] = 'double' attributes[i]['isNumber'] = True attributes[i]['default'] = 'util_NaN()' elif att_type == 'int': attributes[i]['attType'] = 'integer' attributes[i]['attTypeCode'] = 'int' attributes[i]['CType'] = 'int' attributes[i]['isNumber'] = True attributes[i]['default'] = '{0}_INT_' \ 'MAX'.format(self.cap_language) elif att_type == 'uint': attributes[i]['attType'] = 'unsigned integer' attributes[i]['attTypeCode'] = 'unsigned int' attributes[i]['CType'] = 'unsigned int' attributes[i]['isNumber'] = True attributes[i]['default'] = '{0}_INT_' \ 'MAX'.format(self.cap_language) elif att_type == 'bool' or att_type == 'boolean': attributes[i]['attType'] = 'boolean' attributes[i]['attTypeCode'] = 'bool' attributes[i]['CType'] = 'int' attributes[i]['isNumber'] = False attributes[i]['default'] = 'false' elif att_type == 'enum': attributes[i]['isEnum'] = True attributes[i]['attType'] = 'enum' attributes[i]['attTypeCode'] = attributes[i]['element'] + '_t' attributes[i]['CType'] = attributes[i]['element'] + '_t' attributes[i]['isNumber'] = False attributes[i]['default'] = \ query.get_default_enum_value(attributes[i]) elif att_type == 'element': el_name = attributes[i]['element'] at_name = attrib_name attributes[i]['attType'] = 'element' if attrib_name == 'math': if global_variables.is_package: attributes[i]['attTypeCode'] = 'ASTNode*' attributes[i]['CType'] = 'ASTNode_t*' else: attributes[i][ 'attTypeCode'] = 'LIBSBML_CPP_NAMESPACE_QUALIFIER ASTNode*' attributes[i][ 'CType'] = 'LIBSBML_CPP_NAMESPACE_QUALIFIER ASTNode_t*' else: attributes[i][ 'attTypeCode'] = attributes[i]['element'] + '*' attributes[i]['CType'] = attributes[i]['element'] + '_t*' if attributes[i][ 'attTypeCode'] == 'XMLNode*' and not global_variables.is_package: attributes[i][ 'attTypeCode'] = 'LIBSBML_CPP_NAMESPACE_QUALIFIER {0}*'.format( attributes[i]['element']) attributes[i][ 'CType'] = 'LIBSBML_CPP_NAMESPACE_QUALIFIER {0}_t*'.format( attributes[i]['element']) attributes[i]['isNumber'] = False attributes[i]['default'] = 'NULL' if strFunctions.compare_no_case( strFunctions.remove_prefix(el_name), at_name): attributes[i]['children_overwrite'] = False else: attributes[i]['children_overwrite'] = True elif att_type == 'lo_element' or att_type == 'inline_lo_element': childclass = query.get_class(attributes[i]['element'], attributes[i]['root']) if 'lo_class_name' in childclass and childclass[ 'lo_class_name'] != '': name = childclass['lo_class_name'] else: name = strFunctions.list_of_name(attributes[i]['element']) plural = strFunctions.plural_no_prefix( attributes[i]['element']) attributes[i]['attType'] = 'lo_element' attributes[i]['attTypeCode'] = name attributes[i]['CType'] = 'ListOf_t' attributes[i]['memberName'] = 'm' + plural attributes[i]['isNumber'] = False attributes[i]['default'] = 'NULL' if 'xml_name' in attributes[ i] and attributes[i]['xml_name'] != '': attributes[i]['used_child_name'] = strFunctions.singular( attributes[i]['xml_name']) elif att_type == 'array': attributes[i]['isArray'] = True if attributes[i]['element'] == 'Integer' or attributes[i][ 'element'] == 'integer': attributes[i]['element'] = 'int' else: attributes[i]['element'] = \ strFunctions.lower_first(attributes[i]['element']) attributes[i]['attType'] = 'array' attributes[i]['attTypeCode'] = attributes[i]['element'] + '*' attributes[i]['CType'] = attributes[i]['attTypeCode'] attributes[i]['isNumber'] = False attributes[i]['default'] = 'NULL' elif att_type == 'vector': attributes[i]['isVector'] = True if attributes[i]['element'] == 'Integer' or attributes[i][ 'element'] == 'integer': attributes[i]['element'] = 'int' else: attributes[i]['element'] = \ strFunctions.lower_first(attributes[i]['element']) attributes[i]['attType'] = 'vector' attributes[i]['attTypeCode'] = 'std::vector<{0}>'.format( attributes[i]['element']) attributes[i]['CType'] = attributes[i]['attTypeCode'] attributes[i]['isNumber'] = False attributes[i]['default'] = 'NULL' else: global_variables.code_returned \ = global_variables.return_codes['unknown type used'] attributes[i]['attType'] = 'FIXME_{0}'.format(att_type) attributes[i]['attTypeCode'] = 'FIXME_{0}'.format(att_type) attributes[i]['CType'] = 'FIXME_{0}'.format(att_type) attributes[i]['isNumber'] = False attributes[i]['default'] = 'FIXME_{0}'.format(att_type) return attributes
def write_attribute_type_rule(self, attribute, lo=None): if lo: formatted_name = lo['formatted_name'] refname = lo['name'] abbrev = strFunctions.abbrev_lo_name(refname) else: formatted_name = self.formatted_name refname = self.name abbrev = self.name att_type = attribute['type'] [att_name_no_hyphen, unused] = strFunctions.remove_hyphens(attribute['name']) att_name = strFunctions.upper_first(att_name_no_hyphen) name = strFunctions.wrap_token(attribute['texname'], self.package) rule_type = 'String' if att_type == 'SId': return elif att_type == 'SIdRef': [ref_name, ref_type] = \ strFunctions.get_sid_refs(attribute['element']) # hack for render if ref_name == 'StartHead' or ref_name == 'EndHead': ref_name = 'LineEnding' if ref_name == 'SBase': text = 'The value of the attribute {0} of {1} {2} object must be ' \ 'the identifier of an existing object derived from the \SBase class and defined in the ' \ 'enclosing \Model object.'\ .format(name, self.indef, formatted_name, ref_name) else: text = 'The value of the attribute {0} of {1} {2} object must be ' \ 'the identifier of an existing \{3} object defined in the ' \ 'enclosing \Model object.'\ .format(name, self.indef, formatted_name, ref_name) rule_type = ref_type elif att_type == 'string': text = 'The attribute {0} on {1} {2} must have a value of data ' \ 'type {3}.'\ .format(name, self.indef, formatted_name, strFunctions.wrap_token('string')) elif att_type == 'ID': text = 'The attribute {0} on {1} {2} must have a value of XML data ' \ 'type {3}.'\ .format(name, self.indef, formatted_name, strFunctions.wrap_token('ID')) elif att_type == 'IDREF': text = 'The value of the attribute {0} of {1} {2} object must be ' \ 'the \'metaid\' of an existing \SBase object defined in the ' \ 'enclosing \Model object.'\ .format(name, self.indef, formatted_name) rule_type = 'SBase' elif att_type == 'int' or att_type == 'uint': text = 'The attribute {0} on {1} {2} must have a value of data ' \ 'type {3}{4}'\ .format(name, self.indef, formatted_name, strFunctions.wrap_token('integer'), '.' if att_type == 'int' else ', and must be non negative.') rule_type = 'Integer' if att_type == 'int' else 'NonNegativeInteger' elif att_type == 'double': text = 'The attribute {0} on {1} {2} must have a value of data ' \ 'type {3}.'\ .format(name, self.indef, formatted_name, strFunctions.wrap_token('double')) rule_type = 'Double' elif att_type == 'boolean' or att_type == 'bool': text = 'The attribute {0} on {1} {2} must have a value of data ' \ 'type {3}.'\ .format(name, self.indef, formatted_name, strFunctions.wrap_token('boolean')) rule_type = 'Boolean' elif att_type == 'UnitSId' or att_type == 'UnitSIdRef': text = 'The value of the attribute {0} on {1} {2} must have a ' \ 'taken from the following: the identifier of a ' \ '\\UnitDefinition object in the enclosing \Model, or one ' \ 'of the base units in SBML.'.format(name, self.indef, formatted_name) rule_type = 'UnitSId' elif att_type == 'enum': enum_name = strFunctions.texify(attribute['element']) enums = attribute['parent']['root']['enums'] enum_values = self.parse_enum_values(attribute['element'], enums) text = 'The value of the attribute {0} of {1} {2} object must ' \ 'conform to the syntax of SBML data type {3} and ' \ 'may only take on the allowed values of {3} defined ' \ 'in SBML; that is, the value must be one of the ' \ 'following: {4}.'.format(name, self.indef, formatted_name, strFunctions.wrap_enum(enum_name), enum_values) rule_type = '{0}Enum'.format(attribute['element']) elif att_type == 'array': array_type = strFunctions.lower_first(attribute['element']) text = 'The value of the attribute {0} of {1} {2} object must ' \ 'be an array of values of type {3}.'\ .format(name, self.indef, formatted_name, strFunctions.wrap_token(array_type)) elif att_type == 'vector': array_type = strFunctions.lower_first(attribute['element']) text = 'The value of the attribute {0} of {1} {2} object must ' \ 'be an vector of values of type {3}.'\ .format(name, self.indef, formatted_name, strFunctions.wrap_token(array_type)) elif att_type == 'element' and attribute['element'] == 'RelAbsVector': text = 'The value of the attribute {0} of {1} {2} object must ' \ 'conform to the syntax of SBML data type \\RelAbsVector, ' \ 'i.e., a string encoding optionally an absolute number ' \ 'followed by an optional relative number followed ' \ 'by a \\% sign. Adding spaces between the ' \ 'coordinates is encouraged, but not required.'\ .format(name, self.indef, formatted_name) else: text = 'FIXME: Encountered an unknown attribute type {0} in ' \ 'ValidationRulesForClass'\ .format(att_type) # global_variables.code_returned = \ # global_variables.return_codes['unknown type used'] ref = '{0}, {1}.'\ .format(self.pkg_ref, strFunctions.wrap_section(refname)) sev = 'ERROR' lib_sev = '{0}_SEV_ERROR'.format(global_variables.up_full_lib) if att_type == 'SIdRef' or att_type == 'IDREF': short = 'The attribute \'{0}\' must point to {1} object.'.format( strFunctions.lower_first(att_name), rule_type) else: short = 'The \'{0}\' attribute must be {1}.'.format( strFunctions.lower_first(att_name), rule_type) lib_ref = 'L3V1 {0} V1 Section'.format(self.up_package) tc = '{0}{1}{2}MustBe{3}'.format(self.up_package, abbrev, att_name, rule_type) return dict({ 'number': self.number, 'text': text, 'reference': ref, 'severity': sev, 'typecode': tc, 'lib_sev': lib_sev, 'short': short, 'lib_ref': lib_ref, 'object': refname, 'attrib': att_name, 'attrib_type': att_type })
def write_get_object(self): if not self.is_cpp_api: return elif self.is_list_of: return if len(self.elements) == 0: return # create comment parts params = [] return_lines = [] additional = [] title_line = 'Returns the nth object of \"objectName" in this {0}.' \ .format(self.class_name) params.append( '@param elementName, the name of the element to get number of.') params.append( '@param index, unsigned int the index of the object to retrieve.') return_lines.append('@return pointer to the object.') # create the function declaration function = 'getObject' return_type = '{0}*'.format(global_variables.baseClass) arguments = ['const std::string& elementName', 'unsigned int index'] code = [] if not self.has_elements_with_same_xml_name(): # create the function implementation first_line = ['{0}* obj = NULL'.format(global_variables.baseClass)] last_line = ['return obj'] first = True block = [] if_block = [] for elem in self.elements: if not first: block.append('else if') else: first = False block.append('elementName == \"{0}\"'.format(elem['name'])) [elem_name, unused] = strFunctions.remove_hyphens(elem['name']) if elem in self.single_elements: block.append('return get{0}()'.format( strFunctions.upper_first(elem_name))) else: block.append('return get{0}(index)'.format( strFunctions.upper_first(elem_name))) if len(block) > 2: if_block = self.create_code_block('else_if', block) else: if_block = self.create_code_block('if', block) code = [ self.create_code_block('line', first_line), if_block, self.create_code_block('line', last_line) ] else: code = [ self.create_code_block('comment', ['TO DO']), self.create_code_block('line', ['return NULL']) ] # return the parts return dict({ 'title_line': title_line, 'params': params, 'return_lines': return_lines, 'additional': additional, 'function': function, 'return_type': return_type, 'arguments': arguments, 'constant': False, 'virtual': True, 'object_name': self.struct_name, 'implementation': code })
def write_get_num_objects(self): if not self.is_cpp_api: return elif self.is_list_of: return if len(self.elements) == 0: return # create comment parts params = [] return_lines = [] additional = [] title_line = 'Returns the number of \"elementName" in this {0}.' \ .format(self.class_name) params.append( '@param elementName, the name of the element to get number of.') return_lines.append('@return unsigned int number of elements.') # create the function declaration function = 'getNumObjects' return_type = 'unsigned int' arguments = ['const std::string& elementName'] code = [] if not self.has_elements_with_same_xml_name(): # create the function implementation first_line = ['unsigned int n = 0'] last_line = ['return n'] first = True block = [] if_block = [] for elem in self.elements: if not first: block.append('else if') else: first = False block.append('elementName == \"{0}\"'.format(elem['name'])) if elem in self.lo_elements: name = strFunctions.plural( strFunctions.upper_first(elem['name'])) block.append('return getNum{0}()'.format(name)) else: [elem_name, unused] = strFunctions.remove_hyphens(elem['name']) nested_if = [ 'isSet{0}()'.format( strFunctions.upper_first(elem_name)), 'return 1' ] nested_if_block = self.create_code_block('if', nested_if) block.append(nested_if_block) if len(block) > 2: if_block = self.create_code_block('else_if', block) else: if_block = self.create_code_block('if', block) code = [ self.create_code_block('line', first_line), if_block, self.create_code_block('line', last_line) ] else: code = [ self.create_code_block('comment', ['TO DO']), self.create_code_block('line', ['return 0']) ] # return the parts return dict({ 'title_line': title_line, 'params': params, 'return_lines': return_lines, 'additional': additional, 'function': function, 'return_type': return_type, 'arguments': arguments, 'constant': False, 'virtual': True, 'object_name': self.struct_name, 'implementation': code })
def write_remove_object(self): if not self.is_cpp_api: return elif self.is_list_of: return if len(self.elements) == 0: return # create comment parts params = [] return_lines = [] additional = [] title_line = 'Removes and returns the new "elementName" object with the given id in this {0}.' \ .format(self.class_name) params.append('@param elementName, the name of the element to remove.') params.append('@param id, the id of the element to remove.') return_lines.append('@return pointer to the element removed.') # create the function declaration function = 'removeChildObject' return_type = '{0}*'.format(global_variables.baseClass) arguments = ['const std::string& elementName', 'const std::string& id'] code = [] if not self.has_elements_with_same_xml_name(): # create the function implementation last_line = ['return NULL'] first = True block = [] if_block = [] for elem in self.elements: if elem['concrete']: for conc in elem['concrete']: if not first: block.append('else if') else: first = False elemName = elem['name'] if not elem['element'] or elem['element'] == elemName: elemElem = elemName else: elemElem = elem['element'] block.append('elementName == \"{0}\"'.format( conc['name'])) single = True if elem not in self.single_elements: thisClass = query.get_class( elemElem, self.classroot) single = False hasid = False for att in thisClass['attribs']: if att['name'] == 'id': hasid = True if hasid: block.append('return remove{0}(id)'.format( strFunctions.upper_first(elemName))) else: nested_if = self.create_code_block( 'if', [ 'get{0}(i)->getId() == id'.format( strFunctions.upper_first(elemName) ), 'return remove{0}(i)'.format( strFunctions.upper_first(elemName)) ]) nested_for = self.create_code_block( 'for', [ 'unsigned int i = 0; i < getNum{0}(); i++' ''.format( strFunctions.plural( strFunctions.upper_first( elemName))), nested_if ]) block.append(nested_for) else: [elem_name, unused] = strFunctions.remove_hyphens(elemName) block.append('{0} * obj = get{1}()'.format( elemElem, strFunctions.upper_first(elem_name))) block.append( 'if (unset{0}() == LIBSBML_OPERATION_SUCCESS) return obj' .format(strFunctions.upper_first(elem_name))) else: if not first: block.append('else if') else: first = False elemName = elem['name'] if not elem['element'] or elem['element'] == elemName: elemElem = elemName else: elemElem = elem['element'] block.append('elementName == \"{0}\"'.format(elem['name'])) single = True if elem not in self.single_elements: thisClass = query.get_class(elemElem, self.classroot) single = False hasid = False for att in thisClass['attribs']: if att['name'] == 'id': hasid = True if hasid: block.append('return remove{0}(id)'.format( strFunctions.upper_first(elemName))) else: nested_if = self.create_code_block( 'if', [ 'get{0}(i)->getId() == id'.format( strFunctions.upper_first(elemName)), 'return remove{0}(i)'.format( strFunctions.upper_first(elemName)) ]) nested_for = self.create_code_block( 'for', [ 'unsigned int i = 0; i < getNum{0}(); i++' ''.format( strFunctions.plural( strFunctions.upper_first( elemName))), nested_if ]) block.append(nested_for) else: [elem_name, unused] = strFunctions.remove_hyphens(elemName) block.append('{0} * obj = get{1}()'.format( elemElem, strFunctions.upper_first(elem_name))) block.append( 'if (unset{0}() == LIBSBML_OPERATION_SUCCESS) return obj' .format(strFunctions.upper_first(elem_name))) if single: if len(block) > 3: if_block = self.create_code_block('else_if', block) else: if_block = self.create_code_block('if', block) else: if len(block) > 2: if_block = self.create_code_block('else_if', block) else: if_block = self.create_code_block('if', block) code = [if_block, self.create_code_block('line', last_line)] else: code = [ self.create_code_block('comment', ['TO DO']), self.create_code_block('line', ['return NULL']) ] # return the parts return dict({ 'title_line': title_line, 'params': params, 'return_lines': return_lines, 'additional': additional, 'function': function, 'return_type': return_type, 'arguments': arguments, 'constant': False, 'virtual': True, 'object_name': self.struct_name, 'implementation': code })
def write_add_object(self): if not self.is_cpp_api: return elif self.is_list_of: return if len(self.elements) == 0: return # create comment parts params = [] return_lines = [] additional = [] title_line = 'Adds a new "elementName" object to this {0}.' \ .format(self.class_name) params.append('@param elementName, the name of the element to create.') params.append('@param element, pointer to the element to be added.') return_lines.append('@copydetails doc_returns_success_code') return_lines.append('@li @{0}constant{1}{2}, ' ' OperationReturnValues_' 't{3}'.format(self.language, self.open_br, self.success, self.close_br)) return_lines.append('@li @{0}constant{1}{2},' ' OperationReturnValues_' 't{3}'.format(self.language, self.open_br, self.failed, self.close_br)) # create the function declaration function = 'addChildObject' return_type = 'int' arguments = [ 'const std::string& elementName', 'const {0}* element'.format(global_variables.baseClass) ] code = [] if not self.has_elements_with_same_xml_name(): # create the function implementation last_line = ['return LIBSBML_OPERATION_FAILED'] first = True block = [] if_block = [] for elem in self.elements: if elem['concrete']: for conc in elem['concrete']: if not first: block.append('else if') else: first = False elemName = elem['name'] if not elem['element'] or elem['element'] == elemName: elemElem = elemName else: elemElem = elem['element'] block.append( 'elementName == \"{0}\" && element->getTypeCode() == {1}' .format(conc['name'], conc['typecode'])) if elem not in self.single_elements: block.append( 'return add{0}((const {1}*)(element))'.format( strFunctions.upper_first(elemName), elemElem)) else: block.append( 'return set{0}((const {1}*)(element))'.format( strFunctions.upper_first(elemName), elemElem)) else: if not first: block.append('else if') else: first = False elemName = elem['name'] if not elem['element'] or elem['element'] == elemName: elemElem = elemName else: elemElem = elem['element'] [elem_name, unused] = strFunctions.remove_hyphens(elemName) block.append( 'elementName == \"{0}\" && element->getTypeCode() == {1}' .format(elemName, elem['typecode'])) if elem not in self.single_elements: block.append( 'return add{0}((const {1}*)(element))'.format( strFunctions.upper_first(elem_name), elemElem)) else: block.append( 'return set{0}((const {1}*)(element))'.format( strFunctions.upper_first(elem_name), elemElem)) if len(block) > 2: if_block = self.create_code_block('else_if', block) else: if_block = self.create_code_block('if', block) code = [if_block, self.create_code_block('line', last_line)] else: code = [ self.create_code_block('comment', ['TO DO']), self.create_code_block('line', ['return -1']) ] # return the parts return dict({ 'title_line': title_line, 'params': params, 'return_lines': return_lines, 'additional': additional, 'function': function, 'return_type': return_type, 'arguments': arguments, 'constant': False, 'virtual': True, 'object_name': self.struct_name, 'implementation': code })
def write_create_object(self): if not self.is_cpp_api: return elif self.is_list_of: return if len(self.elements) == 0: return # create comment parts params = [] return_lines = [] additional = [] title_line = 'Creates and returns an new "elementName" object in this {0}.' \ .format(self.class_name) params.append('@param elementName, the name of the element to create.') return_lines.append('@return pointer to the element created.') # create the function declaration function = 'createChildObject' # if self.is_plugin: return_type = '{0}*'.format(global_variables.baseClass) arguments = ['const std::string& elementName'] code = [] # create the function implementation if self.is_plugin: first_line = ['{0}* obj = NULL'.format(global_variables.baseClass)] else: first_line = ['{0}* obj = NULL'.format(self.base_class)] last_line = ['return obj'] if not self.has_elements_with_same_xml_name(): first = True block = [] if_block = [] for elem in self.elements: if elem['concrete']: for conc in elem['concrete']: if not first: block.append('else if') else: first = False concname = conc['name'] concelem = conc['name'] if conc['name'].lower() != conc['element'].lower(): concelem = strFunctions.lower_first( strFunctions.remove_prefix(conc['element'])) # hack for render if self.package == 'Render' or self.package == 'render': remove_prefix = True prefix_to_remove = strFunctions.upper_first( self.package) concelem = strFunctions.remove_prefix( conc['element'], False, remove_prefix, prefix_to_remove) block.append('elementName == \"{0}\"'.format(concname)) block.append('return create{0}()'.format( strFunctions.upper_first(concelem))) if len(block) > 2: if_block = self.create_code_block('else_if', block) else: if_block = self.create_code_block('if', block) else: if not first: block.append('else if') else: first = False block.append('elementName == \"{0}\"'.format(elem['name'])) [elem_name, unused] = strFunctions.remove_hyphens(elem['name']) block.append('return create{0}()'.format( strFunctions.upper_first(elem_name))) if len(block) > 2: if_block = self.create_code_block('else_if', block) else: if_block = self.create_code_block('if', block) code = [ self.create_code_block('line', first_line), if_block, self.create_code_block('line', last_line) ] else: code = [ self.create_code_block('line', first_line), self.create_code_block('comment', ['TO DO']), self.create_code_block('line', last_line) ] # return the parts return dict({ 'title_line': title_line, 'params': params, 'return_lines': return_lines, 'additional': additional, 'function': function, 'return_type': return_type, 'arguments': arguments, 'constant': False, 'virtual': True, 'object_name': self.struct_name, 'implementation': code })