def has_unresolved_crossrefs(self, obj, attr_name=None): """ Args: obj: has this object unresolved crossrefs in its fields (non recursively) Returns: True (has unresolved crossrefs) or False (else) """ if get_model(obj) != self.model: return get_model(obj). \ _tx_reference_resolver.has_unresolved_crossrefs(obj) else: for crossref_obj, attr, crossref in self.parser._crossrefs: if crossref_obj is obj: if (not attr_name) or attr_name == attr.name: return True return False
def get_location(model_obj): """ Args: model_obj: the model object of interest Returns: the line, col and filename of the model element. The filename may be None. This function may be used to fill exceptions """ from textx.model import get_model the_model = get_model(model_obj) line, col = the_model._tx_parser.pos_to_linecol(model_obj._tx_position) return {"line": line, "col": col, "filename": the_model._tx_filename}
def __call__(self, parser, obj, attr, obj_ref): from textx.model import ObjCrossRef, get_model assert type(obj_ref) is ObjCrossRef, type(obj_ref) # cls, obj_name = obj_ref.cls, obj_ref.obj_name # 1) lookup URIs... (first, before looking locally - to detect file # not founds and distant model errors...) # TODO: raise error if lookup is not unique model = get_model(obj) model_repository = model._tx_model_repository # 1) try to find object locally ret = self.scope_provider(parser, obj, attr, obj_ref) if ret: return ret # 2) do we have loaded models? for m in model_repository.local_models.filename_to_model.values(): ret = self.scope_provider(parser, m, attr, obj_ref) if ret: return ret return None
def get_metamodel(obj): """ Returns metamodel of the given object's model. """ return get_model(obj)._tx_metamodel
def resolve_one_step(self): """ Resolves model references. """ metamodel = self.parser.metamodel current_crossrefs = self.parser._crossrefs # print("DEBUG: Current crossrefs #: {}". # format(len(current_crossrefs))) new_crossrefs = [] self.delayed_crossrefs = [] resolved_crossref_count = 0 # ------------------------- # start of resolve-loop # ------------------------- default_scope = DefaultScopeProvider() for obj, attr, crossref in current_crossrefs: if (get_model(obj) == self.model): attr_value = getattr(obj, attr.name) attr_refs = [ obj.__class__.__name__ + "." + attr.name, "*." + attr.name, obj.__class__.__name__ + ".*", "*.*" ] if crossref.scope_provider is not None: resolved = crossref.scope_provider(obj, attr, crossref) else: for attr_ref in attr_refs: if attr_ref in metamodel.scope_providers: if self.parser.debug: self.parser.dprint( " FOUND {}".format(attr_ref)) resolved = metamodel.scope_providers[attr_ref]( obj, attr, crossref) break else: resolved = default_scope(obj, attr, crossref) # Collect cross-references for textx-tools if resolved is not None and not type(resolved) is Postponed: if metamodel.textx_tools_support: self.pos_crossref_list.append( RefRulePosition( name=crossref.obj_name, ref_pos_start=crossref.position, ref_pos_end=crossref.position + len(resolved.name), def_pos_start=resolved._tx_position, def_pos_end=resolved._tx_position_end)) if resolved is None: # As a fall-back search builtins if given if metamodel.builtins: if crossref.obj_name in metamodel.builtins: from textx import textx_isinstance if textx_isinstance( metamodel.builtins[crossref.obj_name], crossref.cls): resolved = metamodel.builtins[ crossref.obj_name] if resolved is None: line, col = self.parser.pos_to_linecol(crossref.position) raise TextXSemanticError( message='Unknown object "{}" of class "{}"'.format( crossref.obj_name, crossref.cls.__name__), line=line, col=col, err_type=UNKNOWN_OBJ_ERROR, expected_obj_cls=crossref.cls, filename=self.model._tx_filename) if type(resolved) is Postponed: self.delayed_crossrefs.append((obj, attr, crossref)) new_crossrefs.append((obj, attr, crossref)) else: resolved_crossref_count += 1 if attr.mult in [MULT_ONEORMORE, MULT_ZEROORMORE]: attr_value.append(resolved) else: setattr(obj, attr.name, resolved) else: # crossref not in model new_crossrefs.append((obj, attr, crossref)) # ------------------------- # end of resolve-loop # ------------------------- # store cross-refs from other models in the parser list (for later # processing) self.parser._crossrefs = new_crossrefs # print("DEBUG: Next crossrefs #: {}".format(len(new_crossrefs))) return (resolved_crossref_count, self.delayed_crossrefs)