def test_resolve_model_path_simple_case_with_refs(): ################################# # META MODEL DEF ################################# grammar = r''' Model: name=ID b=B; B: 'B:' name=ID ('->' b=B | '-->' bref=[B] ); ''' mm = metamodel_from_str(grammar) ################################# # MODEL PARSING ################################# model = mm.model_from_str(r''' My_Model B: Level0_B -> B: Level1_B --> Level0_B ''') ################################# # TEST MODEL ################################# # test normal functionality (with refs) level0B = resolve_model_path(model, "b") assert level0B.name == "Level0_B" level1B = resolve_model_path(model, "b.b") assert level1B.name == "Level1_B" bref = resolve_model_path(model, "b.b.bref") assert bref.name == "Level0_B" assert bref == level0B
def test_resolve_model_path_simple_case(): ################################# # META MODEL DEF ################################# grammar = r''' Model: name=ID a=A b=B; A: 'A:' name=ID; B: 'B:' name=ID ('->' b=B| '=' a=A ); ''' mm = metamodel_from_str(grammar) ################################# # MODEL PARSING ################################# model = mm.model_from_str(r''' My_Model A: OuterA B: Level0_B -> B: Level1_B -> B: Level2_B = A: InnerA ''') ################################# # TEST MODEL ################################# # test normal functionality outerA = resolve_model_path(model, "a") assert outerA.name == "OuterA" level0B = resolve_model_path(model, "b") assert level0B.name == "Level0_B" level1B = resolve_model_path(model, "b.b") assert level1B.name == "Level1_B" level2B = resolve_model_path(model, "b.b.b") assert level2B.name == "Level2_B" innerA = resolve_model_path(model, "b.b.b.a") assert innerA.name == "InnerA" # test parent(TYPE) outerA2 = resolve_model_path(model, "b.b.b.parent(Model).a") assert outerA2 == outerA # test "normal" parent outerA3 = resolve_model_path(model, "b.b.parent.parent.a") assert outerA3 == outerA # test "None" level3B_none = resolve_model_path(model, "b.b.b.b") assert level3B_none is None innerA_none1 = resolve_model_path(model, "b.b.b.b.a") assert innerA_none1 is None innerA_none2 = resolve_model_path(model, "b.b.a") assert innerA_none2 is None
def ref_scope(refItem, myattr, attr_ref): # python3: nonlocal ref_scope_was_used ref_scope_was_used[0] = True if get_model(refItem).use == 'A': return resolve_model_path( refItem, "parent(Model).data.elementsA.{}".format( attr_ref.obj_name), True) else: return resolve_model_path( refItem, "parent(Model).data.elementsB.{}".format( attr_ref.obj_name), True)
def get_reference_propositions(self, obj, attr, name_part): """ retrieve a list of reference propositions. Args: obj: parent attr: attribute name_part: The name is used to build the list (e.g. using a substring-like logic). Returns: the list of objects representing the proposed references """ from textx.scoping.tools import resolve_model_path from textx import textx_isinstance obj_list = resolve_model_path(obj, self.path_to_container_object) if type(obj_list) is Postponed: self.postponed_counter += 1 return obj_list # the referenced element must be a list # (else it is a design error in the path passed to # the RelativeName object). if not isinstance(obj_list, list): from textx.exceptions import TextXError raise TextXError( "expected path to list in the model ({})".format( self.path_to_container_object)) obj_list = filter( lambda x: textx_isinstance(x, attr.cls) and x.name.find(name_part) >= 0, obj_list) return list(obj_list)
def get_reference_propositions(self, obj, attr, name_part): """ retrieve a list of reference propositions. Args: obj: parent attr: attribute name_part: The name is used to build the list (e.g. using a substring-like logic). Returns: the list of objects representing the proposed references """ from textx.scoping.tools import resolve_model_path from textx import textx_isinstance # find all all "connected" objects # (e.g. find all classes: the most derived # class, its base, the base of its base, etc.) from textx.scoping.tools import get_list_of_concatenated_objects def_obj = resolve_model_path(obj, self.path_to_definition_object) def_objs = get_list_of_concatenated_objects(def_obj, self.path_to_extension) # for all containing classes, collect all # objects to be looked up (e.g. methods) obj_list = [] for def_obj in def_objs: if type(def_obj) is Postponed: self.postponed_counter += 1 return def_obj tmp_list = resolve_model_path(def_obj, self.path_to_target) assert tmp_list is not None # expected to point to alist if not isinstance(tmp_list, list): from textx.exceptions import TextXError raise TextXError( "expected path to list in the model ({})".format( self.path_to_target)) tmp_list = list( filter( lambda x: textx_isinstance(x, attr.cls) and x.name.find( name_part) >= 0, tmp_list)) obj_list = obj_list + tmp_list return list(obj_list)
def get_reference_propositions(self, obj, attr, name_part): """ retrieve a list of reference propositions. Args: obj: parent attr: attribute name_part: The name is used to build the list (e.g. using a substring-like logic). Returns: the list of objects representing the proposed references """ from textx.scoping.tools import resolve_model_path from textx import textx_isinstance # find all all "connected" objects # (e.g. find all classes: the most derived # class, its base, the base of its base, etc.) from textx.scoping.tools import get_list_of_concatenated_objects def_obj = resolve_model_path(obj, self.path_to_definition_object) def_objs = get_list_of_concatenated_objects( def_obj, self.path_to_extension) # for all containing classes, collect all # objects to be looked up (e.g. methods) obj_list = [] for def_obj in def_objs: if type(def_obj) is Postponed: self.postponed_counter += 1 return def_obj tmp_list = resolve_model_path(def_obj, self.path_to_target) assert tmp_list is not None # expected to point to alist if not isinstance(tmp_list, list): from textx.exceptions import TextXError raise TextXError( "expected path to list in the model ({})".format( self.path_to_target)) tmp_list = list(filter( lambda x: textx_isinstance(x, attr.cls) and x.name.find(name_part) >= 0, tmp_list)) obj_list = obj_list + tmp_list return list(obj_list)
def test_resolve_model_path_with_lists(): ################################# # META MODEL DEF ################################# my_meta_model = metamodel_from_file( join(abspath(dirname(__file__)), 'components_model1', 'Components.tx')) my_meta_model.register_scope_providers({ "*.*": scoping_providers.FQN(), "Connection.from_port": scoping_providers.ExtRelativeName("from_inst.component", "slots", "extends"), "Connection.to_port": scoping_providers.ExtRelativeName("to_inst.component", "slots", "extends"), }) ################################# # MODEL PARSING ################################# my_model = my_meta_model.model_from_file( join(abspath(dirname(__file__)), "components_model1", "example_inherit2.components")) ################################# # TEST MODEL ################################# action2a = resolve_model_path(my_model, "packages.usage.instances.action2", True) action2b = get_unique_named_object(my_model, "action2") assert action2a is action2b middle_a = resolve_model_path(my_model, "packages.base.components.Middle", True) middle_b = get_unique_named_object(my_model, "Middle") assert middle_a is middle_b # test parent(...) with lists action2a_with_parent = resolve_model_path( action2a, "parent(Model).packages.usage.instances.action2", True) assert action2a_with_parent == action2a # test "normal" parent with lists action2a_with_parent2 = resolve_model_path( action2a, "parent.instances.action2", True) assert action2a_with_parent2 == action2a with raises(Exception, match=r'.*unexpected: got list in path for ' r'get_referenced_object.*'): resolve_model_path(my_model, "packages.usage.instances.action2", False)