Пример #1
0
    def _fetch_resolved_traits(self, res_opt: 'ResolveOptions') -> 'ResolvedTraitSet':
        from cdm.resolvedmodel import ResolvedTrait, ResolvedTraitSet
        from cdm.utilities import SymbolSet

        from .cdm_corpus_def import CdmCorpusDefinition

        kind = 'rtsb'
        ctx = self.ctx
        # this may happen 0, 1 or 2 times. so make it fast
        base_trait = None  # type: CdmTraitDefinition
        base_values = None  # type: List[CdmArgumentValue]

        def get_base_info(base_trait, base_values):
            if self.extends_trait:
                base_trait = self.extends_trait.fetch_object_definition(res_opt)
                if base_trait:
                    base_rts = self.extends_trait._fetch_resolved_traits(res_opt)
                    if base_rts and base_rts.size == 1:
                        base_pv = base_rts.get(base_trait).parameter_values if base_rts.get(base_trait) else None
                        if base_pv:
                            base_values = base_pv.values

            return base_trait, base_values

        # see if one is already cached
        # if this trait has parameters, then the base trait found through the reference might be a different reference
        # because trait references are unique per argument value set. so use the base as a part of the cache tag
        # since it is expensive to figure out the extra tag, cache that too!
        if self._base_is_known_to_have_parameters is None:
            base_trait, base_values = get_base_info(base_trait, base_values)
            # is a cache tag needed? then make one
            self._base_is_known_to_have_parameters = False
            if base_values:
                self._base_is_known_to_have_parameters = True

        cache_tag_extra = ''
        if self._base_is_known_to_have_parameters:
            cache_tag_extra = str(self.extends_trait.id)

        cache_tag = ctx.corpus._fetch_definition_cache_tag(res_opt, self, kind, cache_tag_extra)
        rts_result = ctx._cache.get(cache_tag) if cache_tag else None

        # store the previous reference symbol set, we will need to add it with
        # children found from the _construct_resolved_traits call
        curr_sym_ref_set = res_opt._symbol_ref_set or SymbolSet()
        res_opt._symbol_ref_set = SymbolSet()

        # if not, then make one and save it
        if not rts_result:
            base_trait, base_values = get_base_info(base_trait, base_values)
            if base_trait:
                # get the resolution of the base class and use the values as a starting point for this trait's values
                if not self._has_set_flags:
                    # inherit these flags
                    if self.elevated is None:
                        self.elevated = base_trait.elevated
                    if self.ugly is None:
                        self.ugly = base_trait.ugly
                    if self.associated_properties is None:
                        self.associated_properties = base_trait.associated_properties

            self._has_set_flags = True
            pc = self._fetch_all_parameters(res_opt)
            av = []  # type: List[CdmArgumentValue]
            was_set = []  # type: List[bool]

            self._this_is_known_to_have_parameters = bool(pc.sequence)
            for i in range(len(pc.sequence)):
                # either use the default value or (higher precidence) the value taken from the base reference
                value = pc.sequence[i].default_value
                if base_values and i < len(base_values):
                    base_value = base_values[i]
                    if base_value:
                        value = base_value
                av.append(value)
                was_set.append(False)

            # save it
            res_trait = ResolvedTrait(self, pc, av, was_set)
            rts_result = ResolvedTraitSet(res_opt)
            rts_result.merge(res_trait, False)

            # register set of possible symbols
            ctx.corpus._register_definition_reference_symbols(self.fetch_object_definition(res_opt), kind, res_opt._symbol_ref_set)
            # get the new cache tag now that we have the list of docs
            cache_tag = ctx.corpus._fetch_definition_cache_tag(res_opt, self, kind, cache_tag_extra)
            if cache_tag:
                ctx._cache[cache_tag] = rts_result
        else:
            # cache found
            # get the SymbolSet for this cached object
            key = CdmCorpusDefinition._fetch_cache_key_from_object(self, kind)
            res_opt._symbol_ref_set = ctx.corpus._definition_reference_symbols.get(key)

        # merge child document set with current
        curr_sym_ref_set._merge(res_opt._symbol_ref_set)
        res_opt._symbol_ref_set = curr_sym_ref_set

        return rts_result
Пример #2
0
    def _fetch_resolved_traits(
            self, res_opt: 'ResolveOptions') -> 'ResolvedTraitSet':
        from cdm.resolvedmodel import ResolvedTraitSet, ResolvedTraitSetBuilder
        from cdm.utilities import SymbolSet

        was_previously_resolving = self.ctx.corpus._is_currently_resolving
        self.ctx.corpus._is_currently_resolving = True
        if not res_opt:
            res_opt = ResolveOptions(self)

        kind = 'rtsb'
        ctx = self.ctx
        cache_tag_a = ctx.corpus._fetch_definition_cache_tag(
            res_opt, self, kind)
        rtsb_all = None  # type: ResolvedTraitSetBuilder
        if self._trait_cache is None:
            self._trait_cache = {}
        elif cache_tag_a:
            rtsb_all = self._trait_cache.get(cache_tag_a)

        # store the previous document set, we will need to add it with
        # children found from the constructResolvedTraits call
        curr_doc_ref_set = res_opt._symbol_ref_set
        if curr_doc_ref_set is None:
            curr_doc_ref_set = SymbolSet()
        res_opt._symbol_ref_set = SymbolSet()

        if rtsb_all is None:
            rtsb_all = ResolvedTraitSetBuilder()

            if not self._resolving_traits:
                self._resolving_traits = True
                self._construct_resolved_traits(rtsb_all, res_opt)
                self._resolving_traits = False

            obj_def = self.fetch_object_definition(res_opt)
            if obj_def:
                # register set of possible docs
                ctx.corpus._register_definition_reference_symbols(
                    obj_def, kind, res_opt._symbol_ref_set)

                if rtsb_all.resolved_trait_set is None:
                    # nothing came back, but others will assume there is a set in this builder
                    rtsb_all.resolved_trait_set = ResolvedTraitSet(res_opt)

                # get the new cache tag now that we have the list of docs
                cache_tag_a = ctx.corpus._fetch_definition_cache_tag(
                    res_opt, self, kind)
                if cache_tag_a:
                    self._trait_cache[cache_tag_a] = rtsb_all
        else:
            # cache was found
            # get the SymbolSet for this cached object
            from .cdm_corpus_def import CdmCorpusDefinition
            key = CdmCorpusDefinition._fetch_cache_key_from_object(self, kind)
            temp_doc_ref_set = ctx.corpus._definition_reference_symbols.get(
                key)
            res_opt._symbol_ref_set = temp_doc_ref_set

        # merge child document set with current
        curr_doc_ref_set._merge(res_opt._symbol_ref_set)
        res_opt._symbol_ref_set = curr_doc_ref_set

        self.ctx.corpus._is_currently_resolving = was_previously_resolving
        return rtsb_all.resolved_trait_set