/// Returns a map from parameter names to the final argument values for a trait reference. /// Values come (in this order) from base trait defaults, then default overrides on inheritence, /// then values supplied on this reference. public Dictionary <string, dynamic> FetchFinalArgumentValues(ResolveOptions resOpt) { Dictionary <string, dynamic> finalArgs = new Dictionary <string, dynamic>(); // get resolved traits does all the work, just clean up the answers ResolvedTraitSet rts = this.FetchResolvedTraits(resOpt); if (rts == null) { return(null); } // there is only one resolved trait ResolvedTrait rt = rts.First; if (rt.ParameterValues != null && rt.ParameterValues.Length > 0) { int l = rt.ParameterValues.Length; for (int i = 0; i < l; i++) { var p = rt.ParameterValues.FetchParameterAtIndex(i); dynamic v = rt.ParameterValues.FetchValue(i); string name = p.Name; if (name == null) { name = i.ToString(); } finalArgs.Add(name, v); } } return(finalArgs); }
private static ProjectionAttributeStateSet CreateNewProjectionAttributeStateSet( ProjectionContext projCtx, ProjectionAttributeStateSet projOutputSet, ResolvedAttribute newResAttrFK, string refAttrName) { List <ProjectionAttributeState> pasList = ProjectionResolutionCommonUtil.GetLeafList(projCtx, refAttrName); if (pasList != null) { // update the new foreign key resolved attribute with trait param with reference details ResolvedTrait reqdTrait = newResAttrFK.ResolvedTraits.Find(projCtx.ProjectionDirective.ResOpt, "is.linkedEntity.identifier"); if (reqdTrait != null) { CdmEntityReference traitParamEntRef = ProjectionResolutionCommonUtil.CreateForeignKeyLinkedEntityIdentifierTraitParameter(projCtx.ProjectionDirective, projOutputSet.Ctx.Corpus, pasList); reqdTrait.ParameterValues.SetParameterValue(projCtx.ProjectionDirective.ResOpt, "entityReferences", traitParamEntRef); } // Create new output projection attribute state set for FK and add prevPas as previous state set ProjectionAttributeState newProjAttrStateFK = new ProjectionAttributeState(projOutputSet.Ctx) { CurrentResolvedAttribute = newResAttrFK, PreviousStateList = pasList }; projOutputSet.Add(newProjAttrStateFK); } else { // Log error & return projOutputSet without any change Logger.Error(TAG, projOutputSet.Ctx, $"Unable to locate state for reference attribute \"{refAttrName}\".", nameof(CreateNewProjectionAttributeStateSet)); } return(projOutputSet); }
/// Returns a map from parameter names to the final argument values for a trait reference. /// Values come (in this order) from base trait defaults, then default overrides on inheritence, /// then values supplied on this reference. public Dictionary <string, dynamic> FetchFinalArgumentValues(ResolveOptions resOpt) { Dictionary <string, dynamic> finalArgs = new Dictionary <string, dynamic>(); // get resolved traits does all the work, just clean up the answers ResolvedTraitSet rts = this.FetchResolvedTraits(resOpt); if (rts == null || rts.Size != 1) { // well didn't get the traits. maybe imports are missing or maybe things are just not defined yet. // this function will try to fake up some answers then from the arguments that are set on this reference only if (this.Arguments != null && this.Arguments.Count > 0) { int unNamedCount = 0; foreach (var arg in this.Arguments) { // if no arg name given, use the position in the list. string argName = arg.Name; if (string.IsNullOrWhiteSpace(argName)) { argName = unNamedCount.ToString(); } finalArgs.Add(argName, arg.Value); unNamedCount++; } return(finalArgs); } return(null); } // there is only one resolved trait ResolvedTrait rt = rts.First; if (rt?.ParameterValues != null && rt.ParameterValues.Length > 0) { int l = rt.ParameterValues.Length; for (int i = 0; i < l; i++) { var p = rt.ParameterValues.FetchParameterAtIndex(i); dynamic v = rt.ParameterValues.FetchValue(i); string name = p.Name; if (name == null) { name = i.ToString(); } finalArgs.Add(name, v); } } return(finalArgs); }
private static ProjectionAttributeStateSet CreateNewProjectionAttributeStateSet( ProjectionContext projCtx, ProjectionAttributeStateSet projOutputSet, ResolvedAttribute newResAttrFK, string refAttrName) { List <ProjectionAttributeState> pasList = ProjectionResolutionCommonUtil.GetLeafList(projCtx, refAttrName); string sourceEntity = projCtx.ProjectionDirective.OriginalSourceAttributeName; if (sourceEntity == null) { Logger.Warning(projOutputSet.Ctx, Tag, nameof(CreateNewProjectionAttributeStateSet), null, CdmLogCode.WarnProjFKWithoutSourceEntity, refAttrName); } if (pasList != null) { // update the new foreign key resolved attribute with trait param with reference details ResolvedTrait reqdTrait = newResAttrFK.ResolvedTraits.Find(projCtx.ProjectionDirective.ResOpt, "is.linkedEntity.identifier"); if (reqdTrait != null && sourceEntity != null) { CdmEntityReference traitParamEntRef = ProjectionResolutionCommonUtil.CreateForeignKeyLinkedEntityIdentifierTraitParameter(projCtx.ProjectionDirective, projOutputSet.Ctx.Corpus, pasList); reqdTrait.ParameterValues.SetParameterValue(projCtx.ProjectionDirective.ResOpt, "entityReferences", traitParamEntRef); } // Create new output projection attribute state set for FK and add prevPas as previous state set ProjectionAttributeState newProjAttrStateFK = new ProjectionAttributeState(projOutputSet.Ctx) { CurrentResolvedAttribute = newResAttrFK, PreviousStateList = pasList }; projOutputSet.Add(newProjAttrStateFK); } else { // Log error & return projOutputSet without any change Logger.Error(projOutputSet.Ctx, Tag, nameof(CreateNewProjectionAttributeStateSet), null, CdmLogCode.ErrProjRefAttrStateFailure, refAttrName); } return(projOutputSet); }
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); }
internal static CdmTraitReference ResolvedTraitToTraitRef(ResolveOptions resOpt, ResolvedTrait rt) { CdmTraitReference traitRef = null; if (rt.ParameterValues != null && rt.ParameterValues.Length > 0) { traitRef = rt.Trait.Ctx.Corpus.MakeObject <CdmTraitReference>(CdmObjectType.TraitRef, rt.TraitName, false); int l = rt.ParameterValues.Length; if (l == 1) { // just one argument, use the shortcut syntax dynamic val = rt.ParameterValues.Values[0]; if (val != null) { traitRef.Arguments.Add(null, val); } } else { for (int i = 0; i < l; i++) { CdmParameterDefinition param = rt.ParameterValues.FetchParameterAtIndex(i); dynamic val = rt.ParameterValues.Values[i]; if (val != null) { traitRef.Arguments.Add(param.Name, val); } } } } else { traitRef = rt.Trait.Ctx.Corpus.MakeObject <CdmTraitReference>(CdmObjectType.TraitRef, rt.TraitName, true); } if (resOpt.SaveResolutionsOnCopy) { // used to localize references between documents traitRef.ExplicitReference = rt.Trait as CdmTraitDefinition; traitRef.InDocument = (rt.Trait as CdmTraitDefinition).InDocument; } // always make it a property when you can, however the dataFormat traits should be left alone if (rt.Trait.AssociatedProperties != null && !rt.Trait.IsDerivedFrom("is.dataFormat", resOpt)) { traitRef.IsFromProperty = true; } return(traitRef); }
// the only thing we need this code for is testing!!! public override ResolvedEntityReferenceSet FetchResolvedEntityReferences(ResolveOptions resOpt = null) { if (resOpt == null) { resOpt = new ResolveOptions(this); } ResolvedTraitSet rtsThisAtt = this.FetchResolvedTraits(resOpt); CdmAttributeResolutionGuidance resGuide = (CdmAttributeResolutionGuidance)this.ResolutionGuidance; // this context object holds all of the info about what needs to happen to resolve these attributes AttributeResolutionContext arc = new AttributeResolutionContext(resOpt, resGuide, rtsThisAtt); RelationshipInfo relInfo = this.GetRelationshipInfo(resOpt, arc); if (relInfo.IsByRef && !relInfo.IsArray) { { // only place this is used, so logic here instead of encapsulated. // make a set and the one ref it will hold ResolvedEntityReferenceSet rers = new ResolvedEntityReferenceSet(resOpt); ResolvedEntityReference rer = new ResolvedEntityReference(); // referencing attribute(s) come from this attribute rer.Referencing.ResolvedAttributeSetBuilder.MergeAttributes(this.FetchResolvedAttributes(resOpt, null)); Func<CdmEntityReference, ResolvedEntityReferenceSide> resolveSide = entRef => { ResolvedEntityReferenceSide sideOther = new ResolvedEntityReferenceSide(null, null); if (entRef != null) { // reference to the other entity, hard part is the attribue name. // by convention, this is held in a trait that identifies the key sideOther.Entity = entRef.FetchObjectDefinition<CdmEntityDefinition>(resOpt); if (sideOther.Entity != null) { CdmAttribute otherAttribute; ResolveOptions otherOpts = new ResolveOptions { WrtDoc = resOpt.WrtDoc, Directives = resOpt.Directives }; ResolvedTrait t = entRef.FetchResolvedTraits(otherOpts).Find(otherOpts, "is.identifiedBy"); if (t?.ParameterValues?.Length > 0) { dynamic otherRef = (t.ParameterValues.FetchParameterValueByName("attribute").Value); if (typeof(CdmObject).IsAssignableFrom(otherRef?.GetType())) { otherAttribute = (otherRef as CdmObject).FetchObjectDefinition<CdmObjectDefinition>(otherOpts) as CdmAttribute; if (otherAttribute != null) { sideOther.ResolvedAttributeSetBuilder.OwnOne(sideOther.Entity.FetchResolvedAttributes(otherOpts).Get(otherAttribute.GetName()).Copy()); } } } } } return sideOther; }; // either several or one entity // for now, a sub for the 'select one' idea if ((this.Entity as CdmEntityReference).ExplicitReference != null) { CdmEntityDefinition entPickFrom = (this.Entity as CdmEntityReference).FetchObjectDefinition<CdmEntityDefinition>(resOpt); CdmCollection<CdmAttributeItem> attsPick = entPickFrom.GetAttributeDefinitions(); if (attsPick != null && attsPick != null) { for (int i = 0; i < attsPick.Count; i++) { if (attsPick.AllItems[i].ObjectType == CdmObjectType.EntityAttributeDef) { CdmEntityReference er = (attsPick.AllItems[i] as CdmEntityAttributeDefinition).Entity; rer.Referenced.Add(resolveSide(er)); } } } } else { rer.Referenced.Add(resolveSide(this.Entity as CdmEntityReference)); } rers.Set.Add(rer); return rers; } } return null; }
internal override ResolvedAttributeSetBuilder ConstructResolvedAttributes(ResolveOptions resOpt, CdmAttributeContext under = null) { // find and cache the complete set of attributes // attributes definitions originate from and then get modified by subsequent re-defintions from (in this order): // the entity used as an attribute, traits applied to that entity, // the purpose of the attribute, any traits applied to the attribute. ResolvedAttributeSetBuilder rasb = new ResolvedAttributeSetBuilder(); CdmEntityReference ctxEnt = this.Entity as CdmEntityReference; CdmAttributeContext underAtt = (CdmAttributeContext)under; AttributeContextParameters acpEnt = null; if (underAtt != null) { // make a context for this attreibute that holds the attributes that come up from the entity acpEnt = new AttributeContextParameters { under = underAtt, type = CdmAttributeContextType.Entity, Name = ctxEnt.FetchObjectDefinitionName(), Regarding = ctxEnt, IncludeTraits = true }; } ResolvedTraitSet rtsThisAtt = this.FetchResolvedTraits(resOpt); // this context object holds all of the info about what needs to happen to resolve these attributes. // make a copy and add defaults if missing CdmAttributeResolutionGuidance resGuideWithDefault; if (this.ResolutionGuidance != null) resGuideWithDefault = (CdmAttributeResolutionGuidance)this.ResolutionGuidance.Copy(resOpt); else resGuideWithDefault = new CdmAttributeResolutionGuidance(this.Ctx); resGuideWithDefault.UpdateAttributeDefaults(this.Name); AttributeResolutionContext arc = new AttributeResolutionContext(resOpt, resGuideWithDefault, rtsThisAtt); // complete cheating but is faster. // this purpose will remove all of the attributes that get collected here, so dumb and slow to go get them RelationshipInfo relInfo = this.GetRelationshipInfo(arc.ResOpt, arc); if (relInfo.IsByRef) { // make the entity context that a real recursion would have give us if (under != null) under = rasb.ResolvedAttributeSet.CreateAttributeContext(resOpt, acpEnt); // if selecting from one of many attributes, then make a context for each one if (under != null && relInfo.SelectsOne) { // the right way to do this is to get a resolved entity from the embedded entity and then // look through the attribute context hierarchy for non-nested entityReferenceAsAttribute nodes // that seems like a disaster waiting to happen given endless looping, etc. // for now, just insist that only the top level entity attributes declared in the ref entity will work CdmEntityDefinition entPickFrom = (this.Entity as CdmEntityReference).FetchObjectDefinition<CdmEntityDefinition>(resOpt) as CdmEntityDefinition; CdmCollection<CdmAttributeItem> attsPick = entPickFrom?.GetAttributeDefinitions(); if (entPickFrom != null && attsPick != null) { for (int i = 0; i < attsPick.Count; i++) { if (attsPick.AllItems[i].ObjectType == CdmObjectType.EntityAttributeDef) { // a table within a table. as expected with a selectsOne attribute // since this is by ref, we won't get the atts from the table, but we do need the traits that hold the key // these are the same contexts that would get created if we recursed // first this attribute AttributeContextParameters acpEntAtt = new AttributeContextParameters { under = under, type = CdmAttributeContextType.AttributeDefinition, Name = attsPick.AllItems[i].FetchObjectDefinitionName(), Regarding = attsPick.AllItems[i], IncludeTraits = true }; CdmAttributeContext pickUnder = rasb.ResolvedAttributeSet.CreateAttributeContext(resOpt, acpEntAtt); CdmEntityReference pickEnt = (attsPick.AllItems[i] as CdmEntityAttributeDefinition).Entity as CdmEntityReference; AttributeContextParameters acpEntAttEnt = new AttributeContextParameters { under = pickUnder, type = CdmAttributeContextType.Entity, Name = pickEnt.FetchObjectDefinitionName(), Regarding = pickEnt, IncludeTraits = true }; rasb.ResolvedAttributeSet.CreateAttributeContext(resOpt, acpEntAttEnt); } } } } // if we got here because of the max depth, need to impose the directives to make the trait work as expected if (relInfo.MaxDepthExceeded) { if (arc.ResOpt.Directives == null) arc.ResOpt.Directives = new AttributeResolutionDirectiveSet(); arc.ResOpt.Directives.Add("referenceOnly"); } } else { ResolveOptions resLink = CopyResolveOptions(resOpt); resLink.SymbolRefSet = resOpt.SymbolRefSet; resLink.RelationshipDepth = relInfo.NextDepth; rasb.MergeAttributes((this.Entity as CdmEntityReference).FetchResolvedAttributes(resLink, acpEnt)); } // from the traits of purpose and applied here, see if new attributes get generated rasb.ResolvedAttributeSet.AttributeContext = underAtt; rasb.ApplyTraits(arc); rasb.GenerateApplierAttributes(arc, true); // true = apply the prepared traits to new atts // this may have added symbols to the dependencies, so merge them resOpt.SymbolRefSet.Merge(arc.ResOpt.SymbolRefSet); // use the traits for linked entity identifiers to record the actual foreign key links if (rasb.ResolvedAttributeSet?.Set != null && relInfo.IsByRef) { foreach (var att in rasb.ResolvedAttributeSet.Set) { var reqdTrait = att.ResolvedTraits.Find(resOpt, "is.linkedEntity.identifier"); if (reqdTrait == null) { continue; } if (reqdTrait.ParameterValues == null || reqdTrait.ParameterValues.Length == 0) { Logger.Warning(nameof(CdmEntityAttributeDefinition), this.Ctx as ResolveContext, "is.linkedEntity.identifier does not support arguments"); continue; } var entReferences = new List<string>(); var attReferences = new List<string>(); Action<CdmEntityReference, string> addEntityReference = (CdmEntityReference entRef, string nameSpace) => { var entDef = entRef.FetchObjectDefinition<CdmEntityDefinition>(resOpt); var identifyingTrait = entRef.FetchResolvedTraits(resOpt).Find(resOpt, "is.identifiedBy"); if (identifyingTrait != null && entDef != null) { var attRef = identifyingTrait.ParameterValues.FetchParameterValueByName("attribute").Value; string attNamePath = ((CdmObjectReferenceBase)attRef).NamedReference; string attName = attNamePath.Split('/').Last(); // path should be absolute and without a namespace string relativeEntPath = Ctx.Corpus.Storage.CreateAbsoluteCorpusPath(entDef.AtCorpusPath, entDef.InDocument); if (relativeEntPath.StartsWith($"{nameSpace}:")) { relativeEntPath = relativeEntPath.Substring(nameSpace.Length + 1); } entReferences.Add(relativeEntPath); attReferences.Add(attName); } }; if (relInfo.SelectsOne) { var entPickFrom = (this.Entity as CdmEntityReference).FetchObjectDefinition<CdmEntityDefinition>(resOpt) as CdmEntityDefinition; var attsPick = entPickFrom?.GetAttributeDefinitions()?.Cast<CdmObject>().ToList(); if (entPickFrom != null && attsPick != null) { for (int i = 0; i < attsPick.Count; i++) { if (attsPick[i].ObjectType == CdmObjectType.EntityAttributeDef) { var entAtt = attsPick[i] as CdmEntityAttributeDefinition; addEntityReference(entAtt.Entity, this.InDocument.Namespace); } } } } else { addEntityReference(this.Entity, this.InDocument.Namespace); } var constantEntity = this.Ctx.Corpus.MakeObject<CdmConstantEntityDefinition>(CdmObjectType.ConstantEntityDef); constantEntity.EntityShape = this.Ctx.Corpus.MakeRef<CdmEntityReference>(CdmObjectType.EntityRef, "entityGroupSet", true); constantEntity.ConstantValues = entReferences.Select((entRef, idx) => new List<string> { entRef, attReferences[idx] }).ToList(); var traitParam = this.Ctx.Corpus.MakeRef<CdmEntityReference>(CdmObjectType.EntityRef, constantEntity, false); reqdTrait.ParameterValues.SetParameterValue(resOpt, "entityReferences", traitParam); } } // a 'structured' directive wants to keep all entity attributes together in a group if (arc.ResOpt.Directives?.Has("structured") == true) { ResolvedAttribute raSub = new ResolvedAttribute(rtsThisAtt.ResOpt, rasb.ResolvedAttributeSet, this.Name, (CdmAttributeContext)rasb.ResolvedAttributeSet.AttributeContext); if (relInfo.IsArray) { // put a resolved trait on this att group, yuck, hope I never need to do this again and then need to make a function for this CdmTraitReference tr = this.Ctx.Corpus.MakeObject<CdmTraitReference>(CdmObjectType.TraitRef, "is.linkedEntity.array", true); var t = tr.FetchObjectDefinition<CdmTraitDefinition>(resOpt); ResolvedTrait rt = new ResolvedTrait(t, null, new List<dynamic>(), new List<bool>()); raSub.ResolvedTraits = raSub.ResolvedTraits.Merge(rt, true); } rasb = new ResolvedAttributeSetBuilder(); rasb.OwnOne(raSub); } return rasb; }
internal static CdmTraitReference ResolvedTraitToTraitRef(ResolveOptions resOpt, ResolvedTrait rt) { CdmTraitReference traitRef = null; if (rt.ParameterValues != null && rt.ParameterValues.Length > 0) { traitRef = rt.Trait.Ctx.Corpus.MakeObject <CdmTraitReference>(CdmObjectType.TraitRef, rt.TraitName, false); int l = rt.ParameterValues.Length; if (l == 1) { // just one argument, use the shortcut syntax dynamic val = ProtectParameterValues(resOpt, rt.ParameterValues.Values[0]); if (val != null) { traitRef.Arguments.Add(null, val); } } else { for (int i = 0; i < l; i++) { CdmParameterDefinition param = rt.ParameterValues.FetchParameterAtIndex(i); dynamic val = ProtectParameterValues(resOpt, rt.ParameterValues.Values[i]); if (val != null) { traitRef.Arguments.Add(param.Name, val); } } } } else { traitRef = rt.Trait.Ctx.Corpus.MakeObject <CdmTraitReference>(CdmObjectType.TraitRef, rt.TraitName, true); } if (resOpt.SaveResolutionsOnCopy) { // used to localize references between documents traitRef.ExplicitReference = rt.Trait; traitRef.InDocument = rt.Trait.InDocument; } // always make it a property when you can, however the dataFormat traits should be left alone // also the wellKnown is the first constrained list that uses the datatype to hold the table instead of the default value property. // so until we figure out how to move the enums away from default value, show that trait too if (rt.Trait.AssociatedProperties != null && !rt.Trait.IsDerivedFrom("is.dataFormat", resOpt) && !(rt.Trait.TraitName == "is.constrainedList.wellKnown")) { traitRef.IsFromProperty = true; } return(traitRef); }
internal static CdmTraitReference ResolvedTraitToTraitRef(ResolveOptions resOpt, ResolvedTrait rt) { CdmTraitReference traitRef = null; if (rt.ParameterValues != null && rt.ParameterValues.Length > 0) { traitRef = rt.Trait.Ctx.Corpus.MakeObject <CdmTraitReference>(CdmObjectType.TraitRef, rt.TraitName, false); int l = rt.ParameterValues.Length; if (l == 1) { // just one argument, use the shortcut syntax dynamic val = rt.ParameterValues.Values[0]; if (val != null) { traitRef.Arguments.Add(null, val); } } else { for (int i = 0; i < l; i++) { CdmParameterDefinition param = rt.ParameterValues.FetchParameterAtIndex(i); dynamic val = rt.ParameterValues.Values[i]; if (val != null) { traitRef.Arguments.Add(param.Name, val); } } } } else { traitRef = rt.Trait.Ctx.Corpus.MakeObject <CdmTraitReference>(CdmObjectType.TraitRef, rt.TraitName, true); } if (resOpt.SaveResolutionsOnCopy) { // used to localize references between documents traitRef.ExplicitReference = rt.Trait as CdmTraitDefinition; traitRef.DocCreatedIn = (rt.Trait as CdmTraitDefinition).DocCreatedIn; } return(traitRef); }