Exemplo n.º 1
0
        /// <summary>
        /// Creates a <see cref="CdmTraitReference"/> based on a <see cref="CdmTraitDefinition"/> and adds it to the collection.
        /// </summary>
        /// <param name="traitDefinition">The trait definition used to create the trait reference.</param>
        /// <param name="simpleRef">Used to set trait.SimpleNamedReference in the constructor.</param>
        /// <returns>The created trait reference that was added to the collection.</returns>
        public CdmTraitReference Add(CdmTraitDefinition traitDefinition, bool simpleRef = false)
        {
            this.ClearCache();
            var traitReference = new CdmTraitReference(this.Ctx, traitDefinition, simpleRef, false);

            return(base.Add(traitReference));
        }
Exemplo n.º 2
0
        /// <inheritdoc />
        public override CdmObject Copy(ResolveOptions resOpt = null, CdmObject host = null)
        {
            if (resOpt == null)
            {
                resOpt = new ResolveOptions(this, this.Ctx.Corpus.DefaultResolutionDirectives);
            }

            CdmTraitDefinition copy;

            if (host == null)
            {
                copy = new CdmTraitDefinition(this.Ctx, this.TraitName, null);
            }
            else
            {
                copy           = host as CdmTraitDefinition;
                copy.Ctx       = this.Ctx;
                copy.TraitName = this.TraitName;
            }

            copy.ExtendsTrait         = (CdmTraitReference)this.ExtendsTrait?.Copy(resOpt);
            copy.AllParameters        = null;
            copy.Elevated             = this.Elevated;
            copy.Ugly                 = this.Ugly;
            copy.AssociatedProperties = this.AssociatedProperties;

            this.CopyDef(resOpt, copy);
            return(copy);
        }
Exemplo n.º 3
0
        /// <summary>
        /// Verifies if the trait argument data type matches what is specified on the trait definition.
        /// </summary>
        /// <param name="objects"></param>
        /// <param name="resOpt"></param>
        internal void ResolveTraitArguments(ResolveOptions resOpt)
        {
            ResolveContext ctx = this.Ctx as ResolveContext;

            foreach (var obj in this.InternalObjects)
            {
                if (obj is CdmTraitReference traitRef)
                {
                    CdmTraitDefinition traitDef = traitRef.FetchObjectDefinition <CdmTraitDefinition>(resOpt);
                    if (traitDef == null)
                    {
                        continue;
                    }

                    for (int argumentIndex = 0; argumentIndex < traitRef.Arguments.Count; ++argumentIndex)
                    {
                        CdmArgumentDefinition argument = traitRef.Arguments[argumentIndex];
                        try
                        {
                            ctx.RelativePath = argument.DeclaredPath;

                            ParameterCollection    paramCollection = traitDef.FetchAllParameters(resOpt);
                            CdmParameterDefinition paramFound      = paramCollection.ResolveParameter(argumentIndex, argument.Name);
                            argument.ResolvedParameter = paramFound;

                            // if parameter type is entity, then the value should be an entity or ref to one
                            // same is true of 'dataType' dataType
                            dynamic argumentValue = paramFound.ConstTypeCheck(resOpt, this, argument.Value);
                            if (argumentValue != null)
                            {
                                argument.Value = argumentValue;
                            }
                        }
                        catch (Exception e)
                        {
                            Logger.Error(ctx, Tag, nameof(ResolveTraitArguments), this.AtCorpusPath, CdmLogCode.ErrTraitResolutionFailure, traitDef.GetName(), e.ToString());
                        }
                    }

                    traitRef.ResolvedArguments = true;
                }
            }
        }
Exemplo n.º 4
0
        public override CdmObject Copy(ResolveOptions resOpt = null)
        {
            if (resOpt == null)
            {
                resOpt = new ResolveOptions(this);
            }

            CdmTraitDefinition copy = new CdmTraitDefinition(this.Ctx, this.TraitName, null)
            {
                ExtendsTrait         = (CdmTraitReference)this.ExtendsTrait?.Copy(resOpt),
                AllParameters        = null,
                Elevated             = this.Elevated,
                Ugly                 = this.Ugly,
                AssociatedProperties = this.AssociatedProperties
            };

            this.CopyDef(resOpt, copy);
            return(copy);
        }
Exemplo n.º 5
0
        internal override ResolvedTraitSet FetchResolvedTraits(ResolveOptions resOpt = null)
        {
            if (resOpt == null)
            {
                resOpt = new ResolveOptions(this, this.Ctx.Corpus.DefaultResolutionDirectives);
            }

            const string   kind = "rtsb";
            ResolveContext ctx  = this.Ctx as ResolveContext;
            // this may happen 0, 1 or 2 times. so make it fast
            CdmTraitDefinition baseTrait  = null;
            ResolvedTraitSet   baseRts    = null;
            List <dynamic>     baseValues = null;

            System.Action GetBaseInfo = () =>
            {
                if (this.ExtendsTrait != null)
                {
                    baseTrait = this.ExtendsTrait.FetchObjectDefinition <CdmTraitDefinition>(resOpt);
                    if (baseTrait != null)
                    {
                        baseRts = this.ExtendsTrait.FetchResolvedTraits(resOpt);
                        if (baseRts?.Size == 1)
                        {
                            ParameterValueSet basePv = baseRts.Get(baseTrait)?.ParameterValues;
                            if (basePv != null)
                            {
                                baseValues = basePv.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 (this.BaseIsKnownToHaveParameters == null)
            {
                GetBaseInfo();
                // is a cache tag needed? then make one
                this.BaseIsKnownToHaveParameters = false;
                if (baseValues?.Count > 0)
                {
                    this.BaseIsKnownToHaveParameters = true;
                }
            }
            string cacheTagExtra = "";

            if (this.BaseIsKnownToHaveParameters == true)
            {
                cacheTagExtra = this.ExtendsTrait.Id.ToString();
            }

            string  cacheTag         = ctx.Corpus.CreateDefinitionCacheTag(resOpt, this, kind, cacheTagExtra);
            dynamic rtsResultDynamic = null;

            if (cacheTag != null)
            {
                ctx.Cache.TryGetValue(cacheTag, out rtsResultDynamic);
            }
            ResolvedTraitSet rtsResult = rtsResultDynamic as ResolvedTraitSet;

            // store the previous reference symbol set, we will need to add it with
            // children found from the constructResolvedTraits call
            SymbolSet currSymbolRefSet = resOpt.SymbolRefSet;

            if (currSymbolRefSet == null)
            {
                currSymbolRefSet = new SymbolSet();
            }
            resOpt.SymbolRefSet = new SymbolSet();

            // if not, then make one and save it
            if (rtsResult == null)
            {
                GetBaseInfo();
                if (baseTrait != null)
                {
                    // get the resolution of the base class and use the values as a starting point for this trait's values
                    if (!this.HasSetFlags)
                    {
                        // inherit these flags
                        if (this.Elevated == null)
                        {
                            this.Elevated = baseTrait.Elevated;
                        }
                        if (this.Ugly == null)
                        {
                            this.Ugly = baseTrait.Ugly;
                        }
                        if (this.AssociatedProperties == null)
                        {
                            this.AssociatedProperties = baseTrait.AssociatedProperties;
                        }
                    }
                }
                this.HasSetFlags = true;
                ParameterCollection pc     = this.FetchAllParameters(resOpt);
                List <dynamic>      av     = new List <dynamic>();
                List <bool>         wasSet = new List <bool>();
                this.ThisIsKnownToHaveParameters = pc.Sequence.Count > 0;
                for (int i = 0; i < pc.Sequence.Count; i++)
                {
                    // either use the default value or (higher precidence) the value taken from the base reference
                    dynamic value     = (pc.Sequence[i] as CdmParameterDefinition).DefaultValue;
                    dynamic baseValue = null;
                    if (baseValues != null && i < baseValues.Count)
                    {
                        baseValue = baseValues[i];
                        if (baseValue != null)
                        {
                            value = baseValue;
                        }
                    }
                    av.Add(value);
                    wasSet.Add(false);
                }

                // save it
                ResolvedTrait resTrait = new ResolvedTrait(this, pc, av, wasSet);
                rtsResult = new ResolvedTraitSet(resOpt);
                rtsResult.Merge(resTrait, false);

                // register set of possible symbols
                ctx.Corpus.RegisterDefinitionReferenceSymbols(this.FetchObjectDefinition <CdmObjectDefinitionBase>(resOpt), kind, resOpt.SymbolRefSet);
                // get the new cache tag now that we have the list of docs
                cacheTag = ctx.Corpus.CreateDefinitionCacheTag(resOpt, this, kind, cacheTagExtra);
                if (!string.IsNullOrWhiteSpace(cacheTag))
                {
                    ctx.Cache[cacheTag] = rtsResult;
                }
            }
            else
            {
                // cache found
                // get the SymbolSet for this cached object
                string key = CdmCorpusDefinition.CreateCacheKeyFromObject(this, kind);
                ((CdmCorpusDefinition)ctx.Corpus).DefinitionReferenceSymbols.TryGetValue(key, out SymbolSet tempSymbolRefSet);
                resOpt.SymbolRefSet = tempSymbolRefSet;
            }
            // merge child document set with current
            currSymbolRefSet.Merge(resOpt.SymbolRefSet);
            resOpt.SymbolRefSet = currSymbolRefSet;

            return(rtsResult);
        }
Exemplo n.º 6
0
        /// <summary>
        /// Removes the <see cref="CdmTraitReference"/> that has the same name as <see cref="CdmTraitDefinition"/>.
        /// If there are multiple matches, removes the first trait that is from a property. If there aren't any from properties and "onlyFromProperty" is false, removes the last trait that is not from a property.
        /// </summary>
        /// <param name="traitDefToRemove"><see cref="CdmTraitDefinition"/> whose reference to remove from the collection.</param>
        /// <param name="onlyFromProperty">Whether the function should only be applied for traits that originate from properties.</param>
        /// <returns>Whether the operation completed successfuly.</returns>
        public bool Remove(CdmTraitDefinition traitDefToRemove, bool onlyFromProperty = false)
        {
            var traitName = traitDefToRemove.TraitName;

            return(this.Remove(traitName, onlyFromProperty));
        }
Exemplo n.º 7
0
        /// <summary>
        /// Retrieves the index of a trait reference with the same name as the trait definition provided.
        /// If there are multiple matches, returns the index of the first trait that is from a property. If there aren't any from properties and "onlyFromProperty" is false, returns the index of the last trait that is not from a property.
        /// </summary>
        /// <param name="traitDefinition">The trait definition associated with the trait reference we want to retrieve the index of.</param>
        /// <param name="onlyFromProperty">Whether the function should only be applied for traits that originate from properties.</param>
        /// <returns>The index of the trait reference or -1 if no such trait exists in the collection.</returns>
        public int IndexOf(CdmTraitDefinition traitDefinition, bool onlyFromProperty = false)
        {
            var traitName = traitDefinition.TraitName;

            return(IndexOf(traitName, onlyFromProperty));
        }
Exemplo n.º 8
0
        internal override ResolvedTraitSet FetchResolvedTraits(ResolveOptions resOpt = null)
        {
            if (resOpt == null)
            {
                resOpt = new ResolveOptions(this);
            }

            const string   kind = "rtsb";
            ResolveContext ctx  = this.Ctx as ResolveContext;
            // get referenced trait
            CdmTraitDefinition trait    = this.FetchObjectDefinition <CdmTraitDefinition>(resOpt) as CdmTraitDefinition;
            ResolvedTraitSet   rtsTrait = null;

            if (trait == null)
            {
                return(((CdmCorpusDefinition)ctx.Corpus).CreateEmptyResolvedTraitSet(resOpt));
            }

            // see if one is already cached
            // cache by name unless there are parameter
            if (trait.ThisIsKnownToHaveParameters == null)
            {
                // never been resolved, it will happen soon, so why not now?
                rtsTrait = trait.FetchResolvedTraits(resOpt);
            }

            bool cacheByName = true;

            if (trait.ThisIsKnownToHaveParameters != null)
            {
                cacheByName = !((bool)trait.ThisIsKnownToHaveParameters);
            }

            string  cacheTag  = ((CdmCorpusDefinition)ctx.Corpus).CreateDefinitionCacheTag(resOpt, this, kind, "", cacheByName);
            dynamic rtsResult = null;

            if (cacheTag != null)
            {
                ctx.Cache.TryGetValue(cacheTag, out rtsResult);
            }

            // store the previous reference symbol set, we will need to add it with
            // children found from the constructResolvedTraits call
            SymbolSet currSymRefSet = resOpt.SymbolRefSet;

            if (currSymRefSet == null)
            {
                currSymRefSet = new SymbolSet();
            }
            resOpt.SymbolRefSet = new SymbolSet();

            // if not, then make one and save it
            if (rtsResult == null)
            {
                // get the set of resolutions, should just be this one trait
                if (rtsTrait == null)
                {
                    // store current symbol ref set
                    SymbolSet newSymbolRefSet = resOpt.SymbolRefSet;
                    resOpt.SymbolRefSet = new SymbolSet();

                    rtsTrait = trait.FetchResolvedTraits(resOpt);

                    // bubble up symbol reference set from children
                    if (newSymbolRefSet != null)
                    {
                        newSymbolRefSet.Merge(resOpt.SymbolRefSet);
                    }
                    resOpt.SymbolRefSet = newSymbolRefSet;
                }
                if (rtsTrait != null)
                {
                    rtsResult = rtsTrait.DeepCopy();
                }

                // now if there are argument for this application, set the values in the array
                if (this.Arguments != null && rtsResult != null)
                {
                    // if never tried to line up arguments with parameters, do that
                    if (!this.ResolvedArguments)
                    {
                        this.ResolvedArguments = true;
                        ParameterCollection    param      = trait.FetchAllParameters(resOpt);
                        CdmParameterDefinition paramFound = null;
                        dynamic aValue = null;

                        int iArg = 0;
                        if (this.Arguments != null)
                        {
                            foreach (CdmArgumentDefinition a in this.Arguments)
                            {
                                paramFound          = param.ResolveParameter(iArg, a.Name);
                                a.ResolvedParameter = paramFound;
                                aValue  = a.Value;
                                aValue  = ((CdmCorpusDefinition)ctx.Corpus).ConstTypeCheck(resOpt, this.InDocument, paramFound, aValue);
                                a.Value = aValue;
                                iArg++;
                            }
                        }
                    }
                    if (this.Arguments != null)
                    {
                        foreach (CdmArgumentDefinition a in this.Arguments)
                        {
                            rtsResult.SetParameterValueFromArgument(trait, a);
                        }
                    }
                }

                // register set of possible symbols
                ((CdmCorpusDefinition)ctx.Corpus).RegisterDefinitionReferenceSymbols(this.FetchObjectDefinition <CdmObjectDefinition>(resOpt), kind, resOpt.SymbolRefSet);

                // get the new cache tag now that we have the list of symbols
                cacheTag = ((CdmCorpusDefinition)ctx.Corpus).CreateDefinitionCacheTag(resOpt, this, kind, "", cacheByName);
                if (!string.IsNullOrWhiteSpace(cacheTag))
                {
                    ctx.Cache[cacheTag] = rtsResult;
                }
            }
            else
            {
                // cache was found
                // get the SymbolSet for this cached object
                string key = CdmCorpusDefinition.CreateCacheKeyFromObject(this, kind);
                ((CdmCorpusDefinition)ctx.Corpus).DefinitionReferenceSymbols.TryGetValue(key, out SymbolSet tempDocRefSet);
                resOpt.SymbolRefSet = tempDocRefSet;
            }

            // merge child document set with current
            currSymRefSet.Merge(resOpt.SymbolRefSet);
            resOpt.SymbolRefSet = currSymRefSet;

            return(rtsResult);
        }