public override CdmObject Copy(ResolveOptions resOpt = null) { if (resOpt == null) { resOpt = new ResolveOptions(this); } CdmParameterDefinition copy = new CdmParameterDefinition(this.Ctx, this.Name); dynamic defVal = null; if (this.DefaultValue != null) { if (this.DefaultValue is string) { defVal = this.DefaultValue; } else { defVal = ((CdmObject)this.DefaultValue).Copy(resOpt); } } copy.Explanation = this.Explanation; copy.DefaultValue = defVal; copy.Required = this.Required; copy.DataTypeRef = (this.DataTypeRef != null ? this.DataTypeRef.Copy(resOpt) : null) as CdmDataTypeReference; return(copy); }
/// <summary> /// Fetches the corresponding object definition for every object reference. /// </summary> /// <param name="objects"></param> /// <param name="resOpt"></param> internal void ResolveObjectDefinitions(ResolveOptions resOpt) { ResolveContext ctx = this.Ctx as ResolveContext; resOpt.IndexingDoc = this; foreach (var obj in this.InternalObjects) { switch (obj.ObjectType) { case CdmObjectType.AttributeRef: case CdmObjectType.AttributeGroupRef: case CdmObjectType.AttributeContextRef: case CdmObjectType.DataTypeRef: case CdmObjectType.EntityRef: case CdmObjectType.PurposeRef: case CdmObjectType.TraitRef: ctx.RelativePath = obj.DeclaredPath; CdmObjectReferenceBase reff = obj as CdmObjectReferenceBase; if (CdmObjectReferenceBase.offsetAttributePromise(reff.NamedReference) < 0) { CdmObjectDefinition resNew = reff.FetchObjectDefinition <CdmObjectDefinition>(resOpt); if (resNew == null) { // It's okay if references can't be resolved when shallow validation is enabled. if (resOpt.ShallowValidation) { Logger.Warning(ctx, Tag, nameof(ResolveObjectDefinitions), this.AtCorpusPath, CdmLogCode.WarnResolveReferenceFailure, reff.NamedReference); } else { Logger.Error(ctx, Tag, nameof(ResolveObjectDefinitions), this.AtCorpusPath, CdmLogCode.ErrResolveReferenceFailure, reff.NamedReference); // don't check in this file without both of these comments. handy for debug of failed lookups // CdmObjectDefinitionBase resTest = ref.FetchObjectDefinition(resOpt); } } else { Logger.Info(ctx, Tag, nameof(ResolveObjectDefinitions), this.AtCorpusPath, $"resolved '{reff.NamedReference}'"); } } break; case CdmObjectType.ParameterDef: // when a parameter has a datatype that is a cdm object, validate that any default value is the // right kind object CdmParameterDefinition parameter = obj as CdmParameterDefinition; parameter.ConstTypeCheck(resOpt, this, null); break; } } resOpt.IndexingDoc = null; }
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.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); }
/// <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; } } }
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); }
/// <inheritdoc /> public override CdmObject Copy(ResolveOptions resOpt = null, CdmObject host = null) { if (resOpt == null) { resOpt = new ResolveOptions(this, this.Ctx.Corpus.DefaultResolutionDirectives); } CdmParameterDefinition copy; if (host == null) { copy = new CdmParameterDefinition(this.Ctx, this.Name); } else { copy = host as CdmParameterDefinition; copy.Ctx = this.Ctx; copy.Name = this.Name; } dynamic defVal = null; if (this.DefaultValue != null) { if (this.DefaultValue is string) { defVal = this.DefaultValue; } else { defVal = ((CdmObject)this.DefaultValue).Copy(resOpt); } } copy.Explanation = this.Explanation; copy.DefaultValue = defVal; copy.Required = this.Required; copy.DataTypeRef = this.DataTypeRef?.Copy(resOpt) as CdmDataTypeReference; return(copy); }
internal override ResolvedTraitSet FetchResolvedTraits(ResolveOptions resOpt = null) { if (resOpt == null) { resOpt = new ResolveOptions(this, this.Ctx.Corpus.DefaultResolutionDirectives); } const string kind = "rtsb"; var ctx = this.Ctx as ResolveContext; // get referenced trait var trait = this.FetchObjectDefinition <CdmTraitDefinition>(resOpt); ResolvedTraitSet rtsTrait = null; if (trait == null) { return(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 cacheByPath = true; if (trait.ThisIsKnownToHaveParameters != null) { cacheByPath = !((bool)trait.ThisIsKnownToHaveParameters); } string cacheTag = ctx.Corpus.CreateDefinitionCacheTag(resOpt, this, kind, "", cacheByPath, trait.AtCorpusPath); 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 argument in this.Arguments) { paramFound = param.ResolveParameter(iArg, argument.Name); argument.ResolvedParameter = paramFound; aValue = argument.Value; aValue = ctx.Corpus.ConstTypeCheck(resOpt, this.InDocument, paramFound, aValue); argument.Value = aValue; iArg++; } } } if (this.Arguments != null) { foreach (CdmArgumentDefinition a in this.Arguments) { rtsResult.SetParameterValueFromArgument(trait, a); } } } // register set of possible symbols ctx.Corpus.RegisterDefinitionReferenceSymbols(this.FetchObjectDefinition <CdmObjectDefinition>(resOpt), kind, resOpt.SymbolRefSet); // get the new cache tag now that we have the list of symbols cacheTag = ctx.Corpus.CreateDefinitionCacheTag(resOpt, this, kind, "", cacheByPath, trait.AtCorpusPath); 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); 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); }
internal override ResolvedTraitSet FetchResolvedTraits(ResolveOptions resOpt = null) { if (resOpt == null) { resOpt = new ResolveOptions(this, this.Ctx.Corpus.DefaultResolutionDirectives); } const string kind = "rtsb"; var ctx = this.Ctx as ResolveContext; // get referenced trait var trait = this.FetchObjectDefinition <CdmTraitDefinition>(resOpt); ResolvedTraitSet rtsTrait = null; if (trait == null) { return(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); } ResolvedTraitSet rtsResult = null; // store the previous reference symbol set, we will need to add it with // children found from the constructResolvedTraits call SymbolSet currSymRefSet = resOpt.SymbolRefSet ?? new SymbolSet(); resOpt.SymbolRefSet = new SymbolSet(); // 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); int argumentIndex = 0; foreach (CdmArgumentDefinition argument in this.Arguments) { CdmParameterDefinition paramFound = param.ResolveParameter(argumentIndex, argument.Name); argument.ResolvedParameter = paramFound; argument.Value = paramFound.ConstTypeCheck(resOpt, this.InDocument, argument.Value); argumentIndex++; } } foreach (CdmArgumentDefinition argument in this.Arguments) { rtsResult.SetParameterValueFromArgument(trait, argument); } } // register set of possible symbols ctx.Corpus.RegisterDefinitionReferenceSymbols(this.FetchObjectDefinition <CdmObjectDefinition>(resOpt), kind, resOpt.SymbolRefSet); // merge child document set with current currSymRefSet.Merge(resOpt.SymbolRefSet); resOpt.SymbolRefSet = currSymRefSet; return(rtsResult); }