예제 #1
0
파일: model.py 프로젝트: vlimmere/textX
 def wrapper(obj):
     try:
         return obj_processor(obj)
     except Exception as e:
         if isinstance(e, TextXError):
             raise
         else:
             if hasattr(obj, '_tx_position') and hasattr(obj, '_tx_filename'):
                 raise_from(TextXError(str(e), **get_location(obj)), e)
             else:
                 raise_from(TextXError(str(e)), e)
예제 #2
0
    def model_from_str(self,
                       model_str,
                       file_name=None,
                       debug=None,
                       pre_ref_resolution_callback=None,
                       encoding='utf-8'):
        """
        Instantiates model from the given string.
        :param pre_ref_resolution_callback: called before references are
               resolved. This can be useful to manage models distributed
               across files (scoping)
        """

        if type(model_str) is not text:
            raise TextXError("textX accepts only unicode strings.")

        if file_name is None:
            model = self._parser_blueprint.clone().get_model_from_str(
                model_str,
                debug=debug,
                pre_ref_resolution_callback=pre_ref_resolution_callback)

            for p in self._model_processors:
                p(model, self)
        else:
            model = self.internal_model_from_file(file_name,
                                                  encoding,
                                                  debug,
                                                  model_str=model_str)

        return model
예제 #3
0
    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)
예제 #4
0
def get_language(language_name):
    """
    Returns a callable that instantiates meta-model for the given language.
    """

    langs = list(pkg_resources.iter_entry_points(group=LANG_EP,
                                                 name=language_name))

    if not langs:
        raise TextXError('Language "{}" is not registered.'
                         .format(language_name))

    if len(langs) > 1:
        # Multiple languages defined with the same name
        raise TextXError('Language "{}" registered multiple times:\n{}'
                         .format(language_name,
                                 "\n".join([l.dist for l in langs])))

    return langs[0].load()()
예제 #5
0
def check_testcase(testcase):
    """
    checks that the config used by the testcase fulfills its needs
    """
    for need in testcase.needs:
        if need not in testcase.config.haves:
            raise (TextXError(
                "{}: {} not found in {}.{}".format(testcase.name, need.name,
                                                   testcase.scenario.name,
                                                   testcase.config.name),
                **get_location(testcase)  # unpack location info
            ))
예제 #6
0
    def model_from_str(self,
                       model_str,
                       file_name=None,
                       debug=None,
                       pre_ref_resolution_callback=None,
                       encoding='utf-8',
                       **kwargs):
        """
        Instantiates model from the given string.
        :param pre_ref_resolution_callback: called before references are
               resolved. This can be useful to manage models distributed
               across files (scoping)
        :param **kwargs additional arguments available through
                _tx_model_params after initiating the model. The attribute
                is set while executing pre_ref_resolution_callback (see
                scoping.md)
        """
        self._tx_model_param_definitions.check_params('from_str', **kwargs)

        if type(model_str) is not text:
            raise TextXError("textX accepts only unicode strings.")

        if file_name is None:

            def kwargs_callback(other_model):
                if hasattr(other_model, '_tx_metamodel'):
                    other_model._tx_model_params = ModelParams(kwargs)
                if pre_ref_resolution_callback:
                    pre_ref_resolution_callback(other_model)

            model = self._parser_blueprint.clone().get_model_from_str(
                model_str,
                debug=debug,
                pre_ref_resolution_callback=kwargs_callback)

            for p in self._model_processors:
                p(model, self)
        else:
            model = self.internal_model_from_file(
                file_name,
                encoding,
                debug,
                model_str=model_str,
                pre_ref_resolution_callback=pre_ref_resolution_callback,
                model_params=ModelParams(kwargs))

        return model
예제 #7
0
    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)
예제 #8
0
파일: tools.py 프로젝트: nhamidn/textX
def resolve_model_path(obj, dot_separated_name,
                       follow_named_element_in_lists=False):
    """
    Get a model object based on a model-path starting from some
    model object. It can be used in the same way you would
    navigate through a normal instance of a model object, except:
     - "parent(TYPE)" can be used to navigate to the parent of an
       element repeatedly, until a certain type is reached (see
       unittest).
     - lists of named objects (e.g. lists of named packages) can be
       traversed, as if the named objects were part of the model
       grammar (see unittest: Syntax,
       "name_of_model_list.name_of_named_obj_in_list").
     - None/Postponed values are intercepted and lead to an overall
       return value None/Postponed.
    A use case for this function is, when a model path needs to be
    stored and executed on a previously unknown object and/or the
    Postpone/None-logic is required.

    Args:
        obj: the current object
        dot_separated_name: the attribute name "a.b.c.d" starting from obj
           Note: the attribute "parent(TYPE)" is a shortcut to jump to the
           parent of type "TYPE" (exact match of type name).
        follow_named_element_in_lists: follow named elements in list if True
           override_unresolved_lists: try to follow unresolved lists, if True

    Returns:
        the object if found, or Postponed() if some postponed
        refs are found on the path / or obj is not found
    """
    from textx.scoping import Postponed
    names = dot_separated_name.split(".")
    match = re.match(r'parent\((\w+)\)', names[0])

    if obj is None or type(obj) is Postponed:
        return obj
    elif type(obj) is list:
        if follow_named_element_in_lists:
            next_obj = get_named_obj_in_list(obj, names[0])
        else:
            from textx.exceptions import TextXError
            raise TextXError(
                "unexpected: got list in path for get_referenced_object")
    elif match:
        next_obj = obj
        desired_parent_typename = match.group(1)
        next_obj = get_recursive_parent_with_typename(
            next_obj,
            desired_parent_typename)
        if type(next_obj) is Postponed:
            return next_obj
        elif next_obj is not None:
            return resolve_model_path(next_obj, ".".join(names[1:]),
                                      follow_named_element_in_lists)
        else:
            return None
    else:
        next_obj = getattr(obj, names[0])
        if needs_to_be_resolved(obj, names[0]):
            return Postponed()
        elif next_obj is None:
            return None
    if len(names) > 1:
        return resolve_model_path(next_obj, ".".join(
            names[1:]), follow_named_element_in_lists)
    return next_obj