def build_edits(self, tree, parser): # try to find the model annotation model_annotation_xpath = 'stored_definition/class_definition/class_specifier/long_class_specifier/composition/model_annotation' model_annotation_node = XPath.XPath.findAll(tree, model_annotation_xpath, parser) if not model_annotation_node: # insert the model annotation along with the modifications selector = (EquationSectionSelector().chain( NthChildSelector(-1)).assert_count( 1, 'Failed to find end of the equation section')) edit = Edit.make_insert( f'\n{config.INDENTATION}annotation({build_modifications(self.modifications, indented=False)});' ) return SimpleTransformation(selector, edit).build_edits(tree, parser) # model annotation exists, recursively update or insert the modifications model_annotation_node = model_annotation_node[0] return make_edits_for_modifications( model_annotation_node.annotation().class_modification(), self.modifications, parser, indented=config.INDENT_INSERTED_ANNOTATION_ARGS, )
def test_make_insert_before(self): # Setup insert = Edit.make_insert('Dog', insert_after=False) # Act edit = insert({'start': 0, 'stop': 2}) result = Edit.apply_edits([edit], self.data) # Assert self.assertEqual('DogCatBat123', result)
def transformation(self): """transformation creates the transformation required for inserting the built for loop :return: Transformation """ # select the last child of the equation section and insert after it selector = (EquationSectionSelector().chain( NthChildSelector(-1)).assert_count( 1, 'Failed to find end of the equation section')) edit = Edit.make_insert(self.build(), insert_after=True) return SimpleTransformation(selector, edit)
def transformation(self): """transformation creates the transformation required for inserting the built component :return: Transformation """ if self._insert_index == 0: selector = (ElementListSelector().chain(NthChildSelector(0))) insert_after = False elif self._insert_index < 0: # insert after the last child selector = (ElementListSelector().chain(NthChildSelector(-1))) insert_after = True else: selector = (ElementListSelector().chain( NthChildSelector(self._insert_index))) insert_after = True edit = Edit.make_insert(self.build(), insert_after=insert_after) return SimpleTransformation(selector, edit)
def make_edits_for_modifications(class_modification_node, modifications, parser, depth=1, indented=False): """Constructs a list of edits required to update the node with the provided modifications. :param class_modification_node: modelicaParser.Class_modificationContext :param modifications: dict :param parser: antlr4.Parser :param depth: int, current modification depth, used for determining code indentation :param indent: bool, if true each inserted modification will be indented on new line """ requested_modifications = deepcopy(modifications) overwrite_modifications = requested_modifications.pop( 'OVERWRITE_MODIFICATIONS', False) if overwrite_modifications: # don't care about selectively updating existing values # just overwrite any existing modifications new_modifications_string = build_modifications(requested_modifications, depth=depth, indented=indented) edit = Edit.make_replace(new_modifications_string) # replace the entire argument_list with our new modifications return [edit(class_modification_node.argument_list())] all_edits = [] element_modification_xpath = 'class_modification/argument_list/argument/element_modification_or_replaceable/element_modification' element_modification_nodes = XPath.XPath.findAll( class_modification_node, element_modification_xpath, parser) # iterate through the existing element modifications for element_modification_node in element_modification_nodes: # check if there's a request to update this modification element_modification_name = element_modification_node.name().getText() if element_modification_name in requested_modifications: # found a modification to update requested_modification_value = requested_modifications.pop( element_modification_name) if isinstance(requested_modification_value, dict): # recursively make edits for this modification next_class_modification_node = element_modification_node.modification( ).class_modification() all_edits += make_edits_for_modifications( next_class_modification_node, requested_modification_value, parser, depth=depth + 1, indented=indented) else: edit = Edit.make_replace(f'={requested_modification_value}') # replace the modification node with our value all_edits.append(edit( element_modification_node.modification())) # remaining modifications will need to be inserted (matched modification were removed from the dict) if requested_modifications: new_modifications_string = build_modifications(requested_modifications, depth=depth, indented=indented) edit = Edit.make_insert(', ' + new_modifications_string, insert_after=True) all_edits.append(edit(class_modification_node.argument_list())) return all_edits