예제 #1
0
def test_get_children():

    metamodel = metamodel_from_str(grammar)
    model = metamodel.model_from_str(model_str)

    seconds_thirds = get_children(
        lambda x: x.__class__.__name__ in ['Second', 'Third'], model)

    assert len(seconds_thirds) == 8  # 3 seconds and 5 thirds
    assert seconds_thirds[0].x == [23, 45, 56]
    assert seconds_thirds[1].x == 'one'
    assert seconds_thirds[-1].x == 'third'

    # Children first
    seconds_thirds = get_children(
        lambda x: x.__class__.__name__ in ['Second', 'Third'],
        model,
        children_first=True)

    assert len(seconds_thirds) == 8  # 3 seconds and 5 thirds
    assert seconds_thirds[0].x == 'one'
    assert seconds_thirds[1].x == [23, 45, 56]
    assert seconds_thirds[-1].x == 'third'

    # Do not traverse seconds
    seconds_thirds = get_children(
        lambda x: x.__class__.__name__ in ['Second', 'Third'],
        model,
        should_follow=lambda x: x.__class__.__name__ != 'Second')
    assert len(seconds_thirds) == 3  # Only 3 thirds at the top of the model
    assert seconds_thirds[0].x == 'first'
    assert seconds_thirds[-1].x == 'third'
예제 #2
0
def test_model_with_circular_imports():
    """
    Basic test for FQNImportURI + circular imports
    """
    #################################
    # META MODEL DEF
    #################################

    my_meta_model = metamodel_from_file(
        join(abspath(dirname(__file__)),
             'interface_model1', 'Interface.tx'))
    my_meta_model.register_scope_providers(
        {"*.*": scoping_providers.FQNImportURI()})

    #################################
    # MODEL PARSING
    #################################

    my_model = my_meta_model.model_from_file(
        join(abspath(dirname(__file__)),
             "interface_model1", "model_c", "A.if"))

    #################################
    # TEST MODEL
    #################################

    imports = get_children_of_type("Import", my_model)
    assert len(imports) > 0
    for i in imports:
        assert 1 == len(i._tx_loaded_models)  # one file / load import
        assert i.importURI in i._tx_loaded_models[0]._tx_filename

    check_unique_named_object_has_class(my_model, "A", "Interface")
    a = get_unique_named_object(my_model, "A")

    a_self = get_children(lambda x: hasattr(x, 'name') and x.name == "self", a)
    assert len(a_self) == 1
    a_self = a_self[0]

    a_other = get_children(
        lambda x: hasattr(x, 'name') and x.name == "other", a)
    assert len(a_other) == 1
    a_other = a_other[0]

    a_other_self = get_children(
        lambda x: hasattr(x, 'name') and x.name == "self", a_other.ref)
    assert len(a_other_self) == 1
    a_other_self = a_other_self[0]

    a_other_other = get_children(
        lambda x: hasattr(x, 'name') and x.name == "other", a_other.ref)
    assert len(a_other_other) == 1
    a_other_other = a_other_other[0]

    assert a_self.ref == a_other_other.ref
    assert a_self.ref != a_other.ref
    assert a_other.ref == a_other_self.ref
    assert a_other.ref != a_other_other.ref
예제 #3
0
def test_model_with_circular_imports():
    """
    Basic test for FQNImportURI + circular imports
    """
    #################################
    # META MODEL DEF
    #################################

    my_meta_model = metamodel_from_file(
        join(abspath(dirname(__file__)), 'interface_model1', 'Interface.tx'))
    my_meta_model.register_scope_providers(
        {"*.*": scoping_providers.FQNImportURI()})

    #################################
    # MODEL PARSING
    #################################

    my_model = my_meta_model.model_from_file(
        join(abspath(dirname(__file__)), "interface_model1", "model_c",
             "A.if"))

    #################################
    # TEST MODEL
    #################################

    imports = get_children_of_type("Import", my_model)
    assert len(imports) > 0
    for i in imports:
        assert 1 == len(i._tx_loaded_models)  # one file / load import
        assert i.importURI in i._tx_loaded_models[0]._tx_filename

    check_unique_named_object_has_class(my_model, "A", "Interface")
    a = get_unique_named_object(my_model, "A")

    a_self = get_children(lambda x: hasattr(x, 'name') and x.name == "self", a)
    assert len(a_self) == 1
    a_self = a_self[0]

    a_other = get_children(lambda x: hasattr(x, 'name') and x.name == "other",
                           a)
    assert len(a_other) == 1
    a_other = a_other[0]

    a_other_self = get_children(
        lambda x: hasattr(x, 'name') and x.name == "self", a_other.ref)
    assert len(a_other_self) == 1
    a_other_self = a_other_self[0]

    a_other_other = get_children(
        lambda x: hasattr(x, 'name') and x.name == "other", a_other.ref)
    assert len(a_other_other) == 1
    a_other_other = a_other_other[0]

    assert a_self.ref == a_other_other.ref
    assert a_self.ref != a_other.ref
    assert a_other.ref == a_other_self.ref
    assert a_other.ref != a_other_other.ref
예제 #4
0
파일: tools.py 프로젝트: nhamidn/textX
def get_unique_named_object_in_all_models(root, name):
    """
    retrieves a unique named object (no fully qualified name)

    Args:
        root: start of search (if root is a model all known models are searched
              as well)
        name: name of object

    Returns:
        the object (if not unique, raises an error)
    """
    if hasattr(root, '_tx_model_repository'):
        src = list(
            root._tx_model_repository.local_models.filename_to_model.values())
        if root not in src:
            src.append(root)
    else:
        src = [root]

    a = []
    for m in src:
        # print("analyzing {}".format(m._tx_filename))
        a = a + get_children(
            lambda x: hasattr(x, 'name') and x.name == name, m)

    assert len(a) == 1
    return a[0]
예제 #5
0
def test_children():
    """
    This test checks the get_children function
    """
    #################################
    # META MODEL DEF
    #################################

    my_metamodel = metamodel_from_str(metamodel_str)

    my_metamodel.register_scope_providers({"*.*": scoping_providers.FQN()})

    #################################
    # MODEL PARSING
    #################################

    my_model = my_metamodel.model_from_str('''
    package P1 {
        class Part1 {
        }
    }
    package P2 {
        class Part2 {
            attr C2 rec;
        }
        class C2 {
            attr P1.Part1 p1;
            attr Part2 p2a;
            attr P2.Part2 p2b;
        }
    }
    ''')

    #################################
    # TEST
    #################################

    res = get_children_of_type("Class", my_model)
    res.sort(key=lambda x: x.name)
    assert len(res) == 3
    assert all(map(eq, map(lambda x: x.name, res), ["C2", "Part1", "Part2"]))
    assert not all(map(eq, map(lambda x: x.name, res),
                       ["Part1", "Part2", "C2"]))
    for x in res:
        assert x.__class__.__name__ == "Class"

    res = get_children_of_type("Attribute", my_model)
    res.sort(key=lambda x: x.name)
    assert len(res) == 4
    assert all(map(eq, map(lambda x: x.name, res),
                   ["p1", "p2a", "p2b", "rec"]))
    for x in res:
        assert x.__class__.__name__ == "Attribute"

    res = get_children(lambda x: hasattr(x, "name") and re.match(
        ".*2.*", x.name), my_model)
    res.sort(key=lambda x: x.name)
    assert len(res) == 5
    assert all(map(eq, map(lambda x: x.name, res),
                   ["C2", "P2", "Part2", "p2a", "p2b"]))
예제 #6
0
def get_unique_named_object_in_all_models(root, name):
    """
    retrieves a unique named object (no fully qualified name)

    Args:
        root: start of search (if root is a model all known models are searched
              as well)
        name: name of object

    Returns:
        the object (if not unique, raises an error)
    """
    if hasattr(root, '_tx_model_repository'):
        src = list(
            root._tx_model_repository.local_models.filename_to_model.values())
        if root not in src:
            src.append(root)
    else:
        src = [root]

    a = []
    for m in src:
        print("analyzing {}".format(m._tx_filename))
        a = a + get_children(
            lambda x: hasattr(x, 'name') and x.name == name, m)

    assert len(a) == 1
    return a[0]
예제 #7
0
파일: providers.py 프로젝트: fgro93/textX
    def _load_referenced_models(self, model, encoding='utf-8'):
        from textx.model import get_children
        visited = []
        for obj in get_children(
                lambda x: hasattr(x, "importURI") and x not in visited, model):
            visited.append(obj)
            if self.search_path is not None:
                # search_path based i/o:
                my_search_path = \
                    [dirname(model._tx_filename)] + self.search_path
                loaded_model = \
                    model._tx_model_repository.load_model_using_search_path(
                        obj.importURI, model=model,
                        search_path=my_search_path)
                obj._tx_loaded_models = [loaded_model]

            else:
                # globing based i/o:
                basedir = dirname(model._tx_filename)
                if len(basedir) > 0:
                    basedir += "/"
                filename_pattern = abspath(basedir + obj.importURI)
                obj._tx_loaded_models = \
                    model._tx_model_repository.load_models_using_filepattern(
                        filename_pattern, model=model,
                        glob_args=self.glob_args, encoding=encoding)
예제 #8
0
def test_model_with_circular_imports():
    #################################
    # META MODEL DEF
    #################################

    my_meta_model = metamodel_from_file(
        abspath(dirname(__file__)) + '/interface_model1/Interface.tx')
    my_meta_model.register_scope_providers(
        {"*.*": scoping_providers.FQNImportURI()})

    #################################
    # MODEL PARSING
    #################################

    my_model = my_meta_model.model_from_file(
        abspath(dirname(__file__)) + "/interface_model1/model_c/A.if")

    #################################
    # TEST MODEL
    #################################

    check_unique_named_object_has_class(my_model, "A", "Interface")
    a = get_unique_named_object(my_model, "A")

    a_self = get_children(lambda x: hasattr(x, 'name') and x.name == "self", a)
    assert len(a_self) == 1
    a_self = a_self[0]

    a_other = get_children(lambda x: hasattr(x, 'name') and x.name == "other",
                           a)
    assert len(a_other) == 1
    a_other = a_other[0]

    a_other_self = get_children(
        lambda x: hasattr(x, 'name') and x.name == "self", a_other.ref)
    assert len(a_other_self) == 1
    a_other_self = a_other_self[0]

    a_other_other = get_children(
        lambda x: hasattr(x, 'name') and x.name == "other", a_other.ref)
    assert len(a_other_other) == 1
    a_other_other = a_other_other[0]

    assert a_self.ref == a_other_other.ref
    assert a_self.ref != a_other.ref
    assert a_other.ref == a_other_self.ref
    assert a_other.ref != a_other_other.ref
예제 #9
0
def test_fully_qualified_name_ref():
    #################################
    # META MODEL DEF
    #################################

    my_metamodel = metamodel_from_str(metamodel_str)

    my_metamodel.register_scope_providers({"*.*": scoping_providers.FQN()})

    #################################
    # MODEL PARSING
    #################################

    my_model = my_metamodel.model_from_str('''
    package P1 {
        class Part1 {
        }
    }
    package P2 {
        class Part2 {
            attr C2 rec;
        }
        class C2 {
            attr P1.Part1 p1;
            attr Part2 p2a;
            attr P2.Part2 p2b;
        }
    }
    ''')

    #################################
    # TEST
    #################################

    res = get_children_of_type("Class", my_model)
    res.sort(key=lambda x: x.name)
    assert len(res) == 3
    assert all(map(eq, map(lambda x: x.name, res), ["C2", "Part1", "Part2"]))
    assert not all(
        map(eq, map(lambda x: x.name, res), ["Part1", "Part2", "C2"]))
    for x in res:
        assert x.__class__.__name__ == "Class"

    res = get_children_of_type("Attribute", my_model)
    res.sort(key=lambda x: x.name)
    assert len(res) == 4
    assert all(map(eq, map(lambda x: x.name, res),
                   ["p1", "p2a", "p2b", "rec"]))
    for x in res:
        assert x.__class__.__name__ == "Attribute"

    res = get_children(
        lambda x: hasattr(x, "name") and re.match(".*2.*", x.name), my_model)
    res.sort(key=lambda x: x.name)
    assert len(res) == 5
    assert all(
        map(eq, map(lambda x: x.name, res),
            ["C2", "P2", "Part2", "p2a", "p2b"]))
예제 #10
0
 def _export_subgraph(m):
     from textx import get_children
     f.write('subgraph "cluster_{}" {{\n'.format(m._tx_filename))
     f.write('''
     penwidth=2.0
     color=darkorange4;
     label = "{}";
                 '''.format(m._tx_filename))
     for obj in get_children(lambda _: True, m):
         f.write('{};\n'.format(id(obj)))
     f.write('\n}\n')
예제 #11
0
파일: export.py 프로젝트: stanislaw/textX
 def _export_subgraph(m):
     from textx import get_children
     f.write('subgraph "cluster_{}" {{\n'.format(m._tx_filename))
     f.write('''
     penwidth=2.0
     color=darkorange4;
     label = "{}";
                 '''.format(m._tx_filename))
     for obj in get_children(lambda _: True, m):
         f.write('{};\n'.format(id(obj)))
     f.write('\n}\n')
def test_fully_qualified_name_ref_with_splitstring():
    """
    This is a basic test for the FQN (positive and negative test).
    """
    #################################
    # META MODEL DEF
    #################################

    my_metamodel = metamodel_from_str(r'''
        Model: packages*=Package;
        Package: 'package' name=ID '{' classes*=Class '}';
        Class: 'class' name=ID '{'attributes*=Attribute'}';
        Attribute: 'attr' ref=[Class|FQN] name=ID ';';
        Comment: /#.*/;
        FQN[split='/']: ID('/'ID)*;
    ''')

    my_metamodel.register_scope_providers(
        {"Attribute.ref": "^packages*.classes"})

    #################################
    # MODEL PARSING
    #################################

    my_model = my_metamodel.model_from_str('''
    package P1 {
        class Part1 {
        }
    }
    package P2 {
        class Part2 {
            attr C2 rec;
        }
        class C2 {
            attr P1/Part1 p1;
            attr Part2 p2a;
            attr P2/Part2 p2b;
        }
    }
    ''')

    #################################
    # TEST MODEL
    #################################

    a = get_children(lambda x: hasattr(x, 'name') and x.name == "rec",
                     my_model)
    assert len(a) == 1
    assert a[0].name == "rec"
    assert a[0].ref.__class__.__name__ == "Class"
    assert a[0].ref.name == "C2"
예제 #13
0
파일: tools.py 프로젝트: nhamidn/textX
def get_unique_named_object(root, name):
    """
    retrieves a unique named object (no fully qualified name)

    Args:
        root: start of search
        name: name of object

    Returns:
        the object (if not unique, raises an error)
    """
    a = get_children(lambda x: hasattr(x, 'name') and x.name == name, root)
    assert len(a) == 1
    return a[0]
예제 #14
0
 def _load_referenced_models(self, model):
     from textx.model import get_children
     visited = []
     for obj in get_children(
             lambda x: hasattr(x, "importURI") and x not in visited, model):
         visited.append(obj)
         # TODO add multiple lookup rules for file search
         basedir = dirname(model._tx_filename)
         if len(basedir) > 0:
             basedir += "/"
         filename_pattern = abspath(basedir + obj.importURI)
         obj._tx_loaded_models = \
             model._tx_model_repository.load_models_using_filepattern(
                 filename_pattern, model=model, glob_args=self.glob_args)
예제 #15
0
def get_unique_named_object(root, name):
    """
    retrieves a unique named object (no fully qualified name)

    Args:
        root: start of search
        name: name of object

    Returns:
        the object (if not unique, raises an error)
    """
    a = get_children(lambda x: hasattr(x, 'name') and x.name == name, root)
    assert len(a) == 1
    return a[0]
예제 #16
0
    def _load_referenced_models(self, model, encoding):
        from textx.model import get_children
        visited = []
        for obj in get_children(
                lambda x: hasattr(x, "importURI") and x not in visited, model):
            add_to_local_models = True
            if self.importURI_to_scope_name is not None:
                obj.name = self.importURI_to_scope_name(obj)
                # print("setting name to {}".format(obj.name))
            if hasattr(obj, "name"):
                if obj.name is not None and obj.name != "":
                    add_to_local_models = not self.importAs

            visited.append(obj)
            if self.search_path is not None:
                # search_path based i/o:
                my_search_path = \
                    [dirname(model._tx_filename)] + self.search_path
                loaded_model = \
                    model._tx_model_repository.load_model_using_search_path(
                        self.importURI_converter(obj.importURI), model=model,
                        search_path=my_search_path, encoding=encoding,
                        add_to_local_models=add_to_local_models,
                        model_params=model._tx_model_params)
                obj._tx_loaded_models = [loaded_model]

            else:
                # globing based i/o:
                basedir = dirname(model._tx_filename)
                filename_pattern = abspath(
                    join(basedir, self.importURI_converter(obj.importURI)))

                obj._tx_loaded_models = \
                    model._tx_model_repository.load_models_using_filepattern(
                        filename_pattern, model=model,
                        glob_args=self.glob_args, encoding=encoding,
                        add_to_local_models=add_to_local_models,
                        model_params=model._tx_model_params)
예제 #17
0
    def _load_referenced_models(self, model, encoding):
        from textx.model import get_children
        visited = []
        for obj in get_children(
                lambda x: hasattr(x, "importURI") and x not in visited, model):
            add_to_local_models = True
            if self.importURI_to_scope_name is not None:
                obj.name = self.importURI_to_scope_name(obj)
                print("setting name to {}".format(obj.name))
            if hasattr(obj, "name"):
                if obj.name is not None and obj.name != "":
                    add_to_local_models = not self.importAs

            visited.append(obj)
            if self.search_path is not None:
                # search_path based i/o:
                my_search_path = \
                    [dirname(model._tx_filename)] + self.search_path
                loaded_model = \
                    model._tx_model_repository.load_model_using_search_path(
                        self.importURI_converter(obj.importURI), model=model,
                        search_path=my_search_path, encoding=encoding,
                        add_to_local_models=add_to_local_models)
                obj._tx_loaded_models = [loaded_model]

            else:
                # globing based i/o:
                basedir = dirname(model._tx_filename)
                filename_pattern = abspath(
                    join(basedir, self.importURI_converter(obj.importURI)))

                obj._tx_loaded_models = \
                    model._tx_model_repository.load_models_using_filepattern(
                        filename_pattern, model=model,
                        glob_args=self.glob_args, encoding=encoding,
                        add_to_local_models=add_to_local_models)
예제 #18
0
def test_plain_name_ref():
    """
    Basic test for PlainName (good case and bad case)
    """
    #################################
    # META MODEL DEF
    #################################

    my_metamodel = metamodel_from_str(metamodel_str)

    my_metamodel.register_scope_providers(
        {"*.*": scoping_providers.PlainName(multi_metamodel_support=False)})

    #################################
    # MODEL PARSING
    #################################

    my_model = my_metamodel.model_from_str('''
    package P1 {
        class Part1 {
        }
    }
    package P2 {
        class Part2 {
            attr C2 rec;
        }
        class C2 {
            attr Part1 p1;
            attr Part2 p2a;
            attr Part2 p2b;
        }
    }
    ''')

    #################################
    # TEST MODEL
    #################################

    a = get_children(lambda x: hasattr(x, 'name') and x.name == "rec",
                     my_model)
    assert len(a) == 1
    assert a[0].name == "rec"
    assert a[0].ref.__class__.__name__ == "Class"
    assert a[0].ref.name == "C2"

    a = get_children(lambda x: hasattr(x, 'name') and x.name == "p1", my_model)
    assert len(a) == 1
    assert a[0].name == "p1"
    assert a[0].ref.__class__.__name__ == "Class"
    assert a[0].ref.name == "Part1"

    a = get_children(lambda x: hasattr(x, 'name') and x.name == "p2a",
                     my_model)
    assert len(a) == 1
    assert a[0].name == "p2a"
    assert a[0].ref.__class__.__name__ == "Class"
    assert a[0].ref.name == "Part2"

    a = get_children(lambda x: hasattr(x, 'name') and x.name == "p2b",
                     my_model)
    assert len(a) == 1
    assert a[0].name == "p2b"
    assert a[0].ref.__class__.__name__ == "Class"
    assert a[0].ref.name == "Part2"

    ###########################
    # MODEL WITH ERROR (no entry found)
    ############################
    with raises(textx.exceptions.TextXSemanticError,
                match=r'.*Unknown object.*Part0.*'):
        my_metamodel.model_from_str('''
        package P1 {
            class Part1 {
            }
        }
        package P2 {
            class C2 {
                attr Part0 p1;
            }
        }
        ''')

    ###########################
    # MODEL WITH NO ERROR (double entries not checked)
    ############################
    my_metamodel.model_from_str('''
    package P1 {
        class Part1 {
        }
    }
    package P2 {
        class Part1 {
        }
        class C2 {
            attr Part1 p1;
        }
    }
    ''')
예제 #19
0
def test_plain_name_ref_with_muli_metamodel_support():
    """
    Basic test for PlainName with multi metamodel support.
    It is also checked that the referred objects must have a unique name.
    """
    #################################
    # META MODEL DEF
    #################################

    my_metamodel = metamodel_from_str(metamodel_str)

    my_metamodel.register_scope_providers(
        {"*.*": scoping_providers.PlainName(multi_metamodel_support=True)})

    #################################
    # MODEL PARSING
    #################################

    my_model = my_metamodel.model_from_str('''
    package P1 {
        class Part1 {
        }
    }
    package P2 {
        class Part2 {
            attr C2 rec;
        }
        class C2 {
            attr Part1 p1;
            attr Part2 p2a;
            attr Part2 p2b;
        }
    }
    ''')

    #################################
    # TEST MODEL
    #################################

    a = get_children(lambda x: hasattr(x, 'name') and x.name == "rec",
                     my_model)
    assert len(a) == 1
    assert a[0].name == "rec"
    assert a[0].ref.__class__.__name__ == "Class"
    assert a[0].ref.name == "C2"

    a = get_children(lambda x: hasattr(x, 'name') and x.name == "p1", my_model)
    assert len(a) == 1
    assert a[0].name == "p1"
    assert a[0].ref.__class__.__name__ == "Class"
    assert a[0].ref.name == "Part1"

    a = get_children(lambda x: hasattr(x, 'name') and x.name == "p2a",
                     my_model)
    assert len(a) == 1
    assert a[0].name == "p2a"
    assert a[0].ref.__class__.__name__ == "Class"
    assert a[0].ref.name == "Part2"

    a = get_children(lambda x: hasattr(x, 'name') and x.name == "p2b",
                     my_model)
    assert len(a) == 1
    assert a[0].name == "p2b"
    assert a[0].ref.__class__.__name__ == "Class"
    assert a[0].ref.name == "Part2"

    ###########################
    # MODEL WITH ERROR (no entry found)
    ############################
    with raises(textx.exceptions.TextXSemanticError,
                match=r'.*Unknown object.*Part0.*'):
        my_metamodel.model_from_str('''
        package P1 {
            class Part1 {
            }
        }
        package P2 {
            class C2 {
                attr Part0 p1;
            }
        }
        ''')

    ###########################
    # MODEL WITH ERROR (double entries)
    ############################
    with raises(textx.exceptions.TextXSemanticError,
                match=r'.*None:10:\d+: error: name Part1 is not unique.*'):
        my_metamodel.model_from_str('''
        package P1 {
            class Part1 {
            }
        }
        package P2 {
            class Part1 {
            }
            class C2 {
                attr Part1 p1;
            }
        }
        ''')
예제 #20
0
def test_fully_qualified_name_ref():
    """
    This is a basic test for the FQN (positive and negative test).
    """
    #################################
    # META MODEL DEF
    #################################

    my_metamodel = metamodel_from_str(metamodel_str)

    my_metamodel.register_scope_providers({"*.*": scoping_providers.FQN()})

    #################################
    # MODEL PARSING
    #################################

    my_model = my_metamodel.model_from_str('''
    package P1 {
        class Part1 {
        }
    }
    package P2 {
        class Part2 {
            attr C2 rec;
        }
        class C2 {
            attr P1.Part1 p1;
            attr Part2 p2a;
            attr P2.Part2 p2b;
        }
    }
    ''')

    #################################
    # TEST MODEL
    #################################

    a = get_children(lambda x: hasattr(x, 'name') and x.name == "rec",
                     my_model)
    assert len(a) == 1
    assert a[0].name == "rec"
    assert a[0].ref.__class__.__name__ == "Class"
    assert a[0].ref.name == "C2"

    a = get_children(lambda x: hasattr(x, 'name') and x.name == "p1", my_model)
    assert len(a) == 1
    assert a[0].name == "p1"
    assert a[0].ref.__class__.__name__ == "Class"
    assert a[0].ref.name == "Part1"

    a = get_children(lambda x: hasattr(x, 'name') and x.name == "p2a",
                     my_model)
    assert len(a) == 1
    assert a[0].name == "p2a"
    assert a[0].ref.__class__.__name__ == "Class"
    assert a[0].ref.name == "Part2"

    a = get_children(lambda x: hasattr(x, 'name') and x.name == "p2b",
                     my_model)
    assert len(a) == 1
    assert a[0].name == "p2b"
    assert a[0].ref.__class__.__name__ == "Class"
    assert a[0].ref.name == "Part2"

    ###########################
    # MODEL WITH ERROR
    ############################
    with raises(textx.exceptions.TextXSemanticError,
                match=r'None:8:.*: Unknown object.*Part1.*'):
        my_metamodel.model_from_str(''' #1
        package P1 { #2
            class Part1 { #3
            } #4
        } #5
        package P2 { #6
            class C2 { #7
                attr Part1 p1; #8
            }
        }
        ''')

    with raises(textx.exceptions.TextXSemanticError,
                match=r'.*test_fully_qualified_name_test_error.model:8:\d+:'
                ' Unknown object.*Part1.*'):
        my_metamodel.model_from_file(
            join(dirname(__file__), "misc",
                 "test_fully_qualified_name_test_error.model"))
예제 #21
0
    def __call__(self, obj, attr, obj_ref):
        """
        the default scope provider

        Args:
            obj: unused (used for multi_metamodel_support)
            attr: unused
            obj_ref: the cross reference to be resolved

        Returns:
            the resolved reference or None
        """
        from textx.const import RULE_COMMON, RULE_ABSTRACT
        from textx.model import ObjCrossRef
        from textx.scoping.tools import get_parser

        if obj_ref is None:
            return None  # an error! (see model.py: resolve_refs (TODO check)

        assert type(obj_ref) is ObjCrossRef, type(obj_ref)

        if get_parser(obj).debug:
            get_parser(obj).dprint("Resolving obj crossref: {}:{}"
                                   .format(obj_ref.cls, obj_ref.obj_name))

        def _inner_resolve_link_rule_ref(cls, obj_name):
            """
            Depth-first resolving of link rule reference.
            """
            if cls._tx_type is RULE_ABSTRACT:
                for inherited in cls._tx_inh_by:
                    result = _inner_resolve_link_rule_ref(inherited,
                                                          obj_name)
                    if result:
                        return result
            elif cls._tx_type == RULE_COMMON:
                # TODO make this code exchangable
                # allow to know the current attribute (model location for
                # namespace) and to navigate through the whole model...
                # OR (with another scope provider) to make custom lookups in
                # the model
                #
                # Scopeprovider
                # - needs: .current reference (in the model)
                #          .the model (?)
                # - provides: the resolved object or None
                if id(cls) in get_parser(obj)._instances:
                    objs = get_parser(obj)._instances[id(cls)]
                    return objs.get(obj_name)

        if self.multi_metamodel_support:
            from textx import get_model, get_children
            from textx import textx_isinstance
            result_lst = get_children(
                lambda x:
                _hasattr(x, "name") and _getattr(x, "name") == obj_ref.obj_name
                and textx_isinstance(x, obj_ref.cls), get_model(obj))
            if len(result_lst) == 1:
                result = result_lst[0]
            elif len(result_lst) > 1:
                line, col = get_parser(obj).pos_to_linecol(obj_ref.position)
                raise TextXSemanticError(
                    "name {} is not unique.".format(obj_ref.obj_name),
                    line=line, col=col, filename=get_model(obj)._tx_filename)
            else:
                result = None
        else:
            result = _inner_resolve_link_rule_ref(obj_ref.cls,
                                                  obj_ref.obj_name)
        if result:
            return result

        return None  # error handled outside
예제 #22
0
def test_fully_qualified_name_ref():
    #################################
    # META MODEL DEF
    #################################

    my_metamodel = metamodel_from_str(metamodel_str)

    my_metamodel.register_scope_providers({"*.*": scoping_providers.FQN()})

    #################################
    # MODEL PARSING
    #################################

    my_model = my_metamodel.model_from_str('''
    package P1 {
        class Part1 {
        }
    }
    package P2 {
        class Part2 {
            attr C2 rec;
        }
        class C2 {
            attr P1.Part1 p1;
            attr Part2 p2a;
            attr P2.Part2 p2b;
        }
    }
    ''')

    #################################
    # TEST MODEL
    #################################

    a = get_children(lambda x: hasattr(x, 'name') and x.name == "rec",
                     my_model)
    assert len(a) == 1
    assert a[0].name == "rec"
    assert a[0].ref.__class__.__name__ == "Class"
    assert a[0].ref.name == "C2"

    a = get_children(lambda x: hasattr(x, 'name') and x.name == "p1", my_model)
    assert len(a) == 1
    assert a[0].name == "p1"
    assert a[0].ref.__class__.__name__ == "Class"
    assert a[0].ref.name == "Part1"

    a = get_children(lambda x: hasattr(x, 'name') and x.name == "p2a",
                     my_model)
    assert len(a) == 1
    assert a[0].name == "p2a"
    assert a[0].ref.__class__.__name__ == "Class"
    assert a[0].ref.name == "Part2"

    a = get_children(lambda x: hasattr(x, 'name') and x.name == "p2b",
                     my_model)
    assert len(a) == 1
    assert a[0].name == "p2b"
    assert a[0].ref.__class__.__name__ == "Class"
    assert a[0].ref.name == "Part2"

    ###########################
    # MODEL WITH ERROR
    ############################
    with raises(textx.exceptions.TextXSemanticError,
                match=r'.*Unknown object.*Part1.*'):
        my_model2 = my_metamodel.model_from_str('''
        package P1 {
            class Part1 {
            }
        }
        package P2 {
            class C2 {
                attr Part1 p1;
            }
        }
        ''')
예제 #23
0
    def __call__(self, obj, attr, obj_ref):
        """
        the default scope provider

        Args:
            obj: unused (used for multi_metamodel_support)
            attr: unused
            obj_ref: the cross reference to be resolved

        Returns:
            the resolved reference or None
        """
        from textx.const import RULE_COMMON, RULE_ABSTRACT
        from textx.model import ObjCrossRef
        from textx.scoping.tools import get_parser

        if obj_ref is None:
            return None  # an error! (see model.py: resolve_refs (TODO check)

        assert type(obj_ref) is ObjCrossRef, type(obj_ref)

        if get_parser(obj).debug:
            get_parser(obj).dprint("Resolving obj crossref: {}:{}"
                                   .format(obj_ref.cls, obj_ref.obj_name))

        def _inner_resolve_link_rule_ref(cls, obj_name):
            """
            Depth-first resolving of link rule reference.
            """
            if cls._tx_type is RULE_ABSTRACT:
                for inherited in cls._tx_inh_by:
                    result = _inner_resolve_link_rule_ref(inherited,
                                                          obj_name)
                    if result:
                        return result
            elif cls._tx_type == RULE_COMMON:
                # TODO make this code exchangable
                # allow to know the current attribute (model location for
                # namespace) and to navigate through the whole model...
                # OR (with another scope provider) to make custom lookups in
                # the model
                #
                # Scopeprovider
                # - needs: .current reference (in the model)
                #          .the model (?)
                # - provides: the resolved object or None
                if id(cls) in get_parser(obj)._instances:
                    objs = get_parser(obj)._instances[id(cls)]
                    return objs.get(obj_name)

        if self.multi_metamodel_support:
            from textx import get_model, get_children
            from textx import textx_isinstance
            result_lst = get_children(
                lambda x:
                hasattr(x, "name") and x.name == obj_ref.obj_name
                and textx_isinstance(x, obj_ref.cls), get_model(obj))
            if len(result_lst) == 1:
                result = result_lst[0]
            elif len(result_lst) > 1:
                line, col = get_parser(obj).pos_to_linecol(obj_ref.position)
                raise TextXSemanticError(
                    "name {} is not unique.".format(obj_ref.obj_name),
                    line=line, col=col, filename=get_model(obj)._tx_filename)
            else:
                result = None
        else:
            result = _inner_resolve_link_rule_ref(obj_ref.cls,
                                                  obj_ref.obj_name)
        if result:
            return result

        return None  # error handled outside