/// <summary> /// Projections require a new resolved attribute to be created multiple times /// This function allows us to create new resolved attributes based on a input attribute /// </summary> /// <param name="projCtx"></param> /// <param name="attrCtxUnder"></param> /// <param name="targetAttr"></param> /// <param name="overrideDefaultName"></param> /// <param name="addedSimpleRefTraits"></param> /// <returns></returns> internal static ResolvedAttribute CreateNewResolvedAttribute( ProjectionContext projCtx, CdmAttributeContext attrCtxUnder, CdmAttribute targetAttr, string overrideDefaultName = null, List <string> addedSimpleRefTraits = null) { ResolvedAttribute newResAttr = new ResolvedAttribute( projCtx.ProjectionDirective.ResOpt, targetAttr, !string.IsNullOrWhiteSpace(overrideDefaultName) ? overrideDefaultName : targetAttr.GetName(), attrCtxUnder); if (addedSimpleRefTraits != null) { foreach (string trait in addedSimpleRefTraits) { if (targetAttr.AppliedTraits.Item(trait) == null) { targetAttr.AppliedTraits.Add(trait, true); } } } ResolvedTraitSet resTraitSet = targetAttr.FetchResolvedTraits(projCtx.ProjectionDirective.ResOpt); // Create deep a copy of traits to avoid conflicts in case of parameters if (resTraitSet != null) { newResAttr.ResolvedTraits = resTraitSet.DeepCopy(); } return(newResAttr); }
internal override void ConstructResolvedTraits(ResolvedTraitSetBuilder rtsb, ResolveOptions resOpt) { CdmObjectDefinition objDef = this.FetchObjectDefinition <CdmObjectDefinition>(resOpt); if (objDef != null) { ResolvedTraitSet rtsInh = (objDef as CdmObjectDefinitionBase).FetchResolvedTraits(resOpt); if (rtsInh != null) { rtsInh = rtsInh.DeepCopy(); } rtsb.TakeReference(rtsInh); } else { string defName = this.FetchObjectDefinitionName(); Logger.Warning(defName, this.Ctx, $"unable to resolve an object from the reference '{defName}'"); } if (this.AppliedTraits != null) { foreach (CdmTraitReference at in this.AppliedTraits) { rtsb.MergeTraits(at.FetchResolvedTraits(resOpt)); } } }
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); } if (this.NamedReference != null && this.AppliedTraits == null) { const string kind = "rts"; ResolveContext ctx = this.Ctx as ResolveContext; string objDefName = this.FetchObjectDefinitionName(); string cacheTag = ((CdmCorpusDefinition)ctx.Corpus).CreateDefinitionCacheTag(resOpt, this, kind, "", true); dynamic rtsResultDynamic = null; if (cacheTag != null) { ctx.Cache.TryGetValue(cacheTag, out rtsResultDynamic); } ResolvedTraitSet rtsResult = rtsResultDynamic as ResolvedTraitSet; // store the previous document 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 (rtsResult == null) { CdmObjectDefinition objDef = this.FetchObjectDefinition <CdmObjectDefinition>(resOpt); if (objDef != null) { rtsResult = (objDef as CdmObjectDefinitionBase).FetchResolvedTraits(resOpt); if (rtsResult != null) { rtsResult = rtsResult.DeepCopy(); } // register set of possible docs ((CdmCorpusDefinition)ctx.Corpus).RegisterDefinitionReferenceSymbols(objDef, kind, resOpt.SymbolRefSet); // get the new cache tag now that we have the list of docs cacheTag = ((CdmCorpusDefinition)ctx.Corpus).CreateDefinitionCacheTag(resOpt, this, kind, "", true); 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); } else { return(base.FetchResolvedTraits(resOpt)); } }
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); }