Exemplo n.º 1
0
        /// <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;
        }
Exemplo n.º 2
0
        /// <summary>
        /// Checks if the trait argumnet value matchs the data type defined on the trait parameter
        /// </summary>
        /// <param name="resOpt"></param>
        /// <param name="wrtDoc"></param>
        /// <param name="argumentValue"></param>
        /// <returns></returns>
        internal dynamic ConstTypeCheck(ResolveOptions resOpt, CdmDocumentDefinition wrtDoc, dynamic argumentValue)
        {
            ResolveContext ctx         = this.Ctx as ResolveContext;
            dynamic        replacement = argumentValue;

            // if parameter type is entity, then the value should be an entity or ref to one
            // same is true of 'dataType' dataType
            if (this.DataTypeRef == null)
            {
                return(replacement);
            }

            CdmDataTypeDefinition dt = this.DataTypeRef.FetchObjectDefinition <CdmDataTypeDefinition>(resOpt);

            if (dt == null)
            {
                Logger.Error(ctx, Tag, nameof(ConstTypeCheck), this.AtCorpusPath, CdmLogCode.ErrUnrecognizedDataType, this.Name);
                return(null);
            }

            // compare with passed in value or default for parameter
            dynamic pValue = argumentValue;

            if (pValue == null)
            {
                pValue      = this.DefaultValue;
                replacement = pValue;
            }
            if (pValue != null)
            {
                if (dt.IsDerivedFrom("cdmObject", resOpt))
                {
                    List <CdmObjectType> expectedTypes = new List <CdmObjectType>();
                    string expected = null;
                    if (dt.IsDerivedFrom("entity", resOpt))
                    {
                        expectedTypes.Add(CdmObjectType.ConstantEntityDef);
                        expectedTypes.Add(CdmObjectType.EntityRef);
                        expectedTypes.Add(CdmObjectType.EntityDef);
                        expectedTypes.Add(CdmObjectType.ProjectionDef);
                        expected = "entity";
                    }
                    else if (dt.IsDerivedFrom("attribute", resOpt))
                    {
                        expectedTypes.Add(CdmObjectType.AttributeRef);
                        expectedTypes.Add(CdmObjectType.TypeAttributeDef);
                        expectedTypes.Add(CdmObjectType.EntityAttributeDef);
                        expected = "attribute";
                    }
                    else if (dt.IsDerivedFrom("dataType", resOpt))
                    {
                        expectedTypes.Add(CdmObjectType.DataTypeRef);
                        expectedTypes.Add(CdmObjectType.DataTypeDef);
                        expected = "dataType";
                    }
                    else if (dt.IsDerivedFrom("purpose", resOpt))
                    {
                        expectedTypes.Add(CdmObjectType.PurposeRef);
                        expectedTypes.Add(CdmObjectType.PurposeDef);
                        expected = "purpose";
                    }
                    else if (dt.IsDerivedFrom("traitGroup", resOpt))
                    {
                        expectedTypes.Add(CdmObjectType.TraitGroupRef);
                        expectedTypes.Add(CdmObjectType.TraitGroupDef);
                        expected = "traitGroup";
                    }
                    else if (dt.IsDerivedFrom("trait", resOpt))
                    {
                        expectedTypes.Add(CdmObjectType.TraitRef);
                        expectedTypes.Add(CdmObjectType.TraitDef);
                        expected = "trait";
                    }
                    else if (dt.IsDerivedFrom("attributeGroup", resOpt))
                    {
                        expectedTypes.Add(CdmObjectType.AttributeGroupRef);
                        expectedTypes.Add(CdmObjectType.AttributeGroupDef);
                        expected = "attributeGroup";
                    }

                    if (expectedTypes.Count == 0)
                    {
                        Logger.Error(ctx, Tag, nameof(ConstTypeCheck), wrtDoc.FolderPath + wrtDoc.Name, CdmLogCode.ErrUnexpectedDataType, this.Name);
                    }

                    // if a string constant, resolve to an object ref.
                    CdmObjectType foundType  = CdmObjectType.Error;
                    Type          pValueType = pValue.GetType();

                    if (typeof(CdmObject).IsAssignableFrom(pValueType))
                    {
                        foundType = (pValue as CdmObject).ObjectType;
                    }
                    string foundDesc = ctx.RelativePath;
                    if (!(pValue is CdmObject))
                    {
                        // pValue is a string or JValue
                        pValue = (string)pValue;
                        if (pValue == "this.attribute" && expected == "attribute")
                        {
                            // will get sorted out later when resolving traits
                            foundType = CdmObjectType.AttributeRef;
                        }
                        else
                        {
                            foundDesc = pValue;
                            int seekResAtt = CdmObjectReferenceBase.offsetAttributePromise(pValue);
                            if (seekResAtt >= 0)
                            {
                                // get an object there that will get resolved later after resolved attributes
                                replacement = new CdmAttributeReference(ctx, pValue, true);
                                (replacement as CdmAttributeReference).Ctx        = ctx;
                                (replacement as CdmAttributeReference).InDocument = wrtDoc;
                                foundType = CdmObjectType.AttributeRef;
                            }
                            else
                            {
                                CdmObjectBase lu = ctx.Corpus.ResolveSymbolReference(resOpt, wrtDoc, pValue, CdmObjectType.Error, retry: true);
                                if (lu != null)
                                {
                                    if (expected == "attribute")
                                    {
                                        replacement = new CdmAttributeReference(ctx, pValue, true);
                                        (replacement as CdmAttributeReference).Ctx        = ctx;
                                        (replacement as CdmAttributeReference).InDocument = wrtDoc;
                                        foundType = CdmObjectType.AttributeRef;
                                    }
                                    else
                                    {
                                        replacement = lu;
                                        foundType   = (replacement as CdmObject).ObjectType;
                                    }
                                }
                            }
                        }
                    }
                    if (expectedTypes.IndexOf(foundType) == -1)
                    {
                        Logger.Error(ctx, Tag, nameof(ConstTypeCheck), wrtDoc.AtCorpusPath, CdmLogCode.ErrResolutionFailure, this.Name, expected, foundDesc, expected);
                    }
                    else
                    {
                        Logger.Info(ctx, Tag, nameof(ConstTypeCheck), wrtDoc.AtCorpusPath, $"resolved '{foundDesc}'");
                    }
                }
            }

            return(replacement);
        }