def edit_connect(self, port_a, port_b, new_port_a=None, new_port_b=None): """edit_connect finds all connect clauses that match the pattern connect(<port_a>, <port_b>), in that order. If a port is an asterisk, '*', then it matches any identifier. :param port_a: string, identifier for first port; an asterisk matches all :param port_b: string, identifier for second port; an asterisk matches all :param new_port_a: string | None, replacement for port a; if None no changes are made :param new_port_b: string | None, replacement for port b; if None no changes are made """ # verify the paramaters are sensible if (port_a == '*' and new_port_a is not None) or (port_b == '*' and new_port_b is not None): raise Exception( 'Invalid to have a port match a wildcard and replace it (might result in duplicate clauses)' ) # make up to two transformations (one for each replacement) if new_port_a is not None: selector = (ConnectClauseSelector(port_a, port_b).chain( NthChildSelector(2))) self.add( SimpleTransformation(selector, Edit.make_replace(new_port_a))) if new_port_b is not None: selector = (ConnectClauseSelector(port_a, port_b).chain( NthChildSelector(4))) self.add( SimpleTransformation(selector, Edit.make_replace(new_port_b)))
def set_name(self, name): """sets the model's name :param name: string """ selector = ModelIdentifierSelector() self.add(SimpleTransformation(selector, Edit.make_replace(name)))
def remove_connect(self, port_a, port_b): """remove_connect finds and removes the connect clause that matches :param port_a: string, first port identifier; an asterisk matches all :param port_b: string, second port identifier; an asterisk matches all """ # select the parent of the component to also select the semicolon and comments selector = (ConnectClauseSelector(port_a, port_b).chain(ParentSelector())) self.add(SimpleTransformation(selector, Edit.make_delete()))
def set_within_statement(self, within_string): """changes 'within <string>;' at the beginning of the file :param within_string: string, new value """ selector = (WithinSelector().assert_count( 1, 'A single within statement must already exist')) self.add( SimpleTransformation( selector, Edit.make_replace(f'within {within_string};')))
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 remove_component_argument(self, type_, identifier, argument_name): """Remove the argument from a component :param type_: string, type of the component :param identifier: string, component identifier :param argument_name: string, name of the argument that will be removed """ if type_ is None and identifier is None: raise Exception('At least one of the parameters must not be None') selector = (ComponentDeclarationSelector(type_, identifier).chain( ComponentArgumentSelector(argument_name))) self.add(SimpleTransformation(selector, Edit.make_delete()))
def overwrite_component_redeclaration(self, type_, identifier, new_declaration): """ Overwrite the component redeclaration with a new string :param type_: string, type of the component :param identifier: string, component identifier :param new_declaration: string, new component redeclaration string. It is the entire string, i.e., argument=value """ selector = (ComponentDeclarationSelector(type_, identifier).chain( ComponentRedeclarationSelector())) self.add( SimpleTransformation(selector, Edit.make_replace(f'{new_declaration}')))
def rename_component_argument(self, type_, identifier, old_argument_name, new_argument_name): """Rename the argument name of a component :param type_: string, type of the component :param identifier: string, component identifier :param old_argument_name: string, name of the argument that will be replaced :param new_argument_name: string, name of the new argument name """ selector = (ComponentDeclarationSelector(type_, identifier).chain( ComponentModificationNameSelector(old_argument_name))) self.add( SimpleTransformation(selector, Edit.make_replace(f'{new_argument_name}')))
def remove_component(self, type_=None, identifier=None): """remove_component removes a component declaration. Note that if the component is part of a list of declarations, e.g. TypeName IdentifierA, IdentifierB, IdentifierC; then _all_ declarations are removed. :param type_: string, optional, type in the declaration :param identifier: string, optional, identifier in the declaration """ if type_ is None and identifier is None: raise Exception('At least one of the parameters must not be None') selector = ( ComponentDeclarationSelector(type_, identifier).chain( ParentSelector()) # component_list .chain(ParentSelector()) # component_clause .chain(ParentSelector())) # element self.add(SimpleTransformation(selector, Edit.make_delete()))
def update_component_modification(self, type_, identifier, modification_name, new_value, if_value=None): """update_component_modification changes the value of an _existing_ component modification value. ie this won't work if the argument isn't already used :param type_: string, component type :param identifier: string, component identifier :param modification_name: string, modification to update :param new_value: string, new modification value :param if_value: string, if provided it will only update the value if the existing value matches this """ selector = (ComponentDeclarationSelector(type_, identifier).chain( ComponentModificationValueSelector(modification_name, modification_value=if_value))) self.add(SimpleTransformation(selector, Edit.make_replace(new_value)))
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)