private IEdmExpression ComputeAppliedOperation()
        {
            if (this.expression.Function == null)
            {
                return(CsdlSemanticsModel.WrapExpression(this.expression.Arguments.FirstOrDefault(null), this.bindingContext, this.schema));
            }
            else
            {
                IEdmOperation referenced;
                IEnumerable <IEdmOperation> candidateOperations = this.schema.FindOperations(this.expression.Function);
                int candidateCount = candidateOperations.Count();
                if (candidateCount == 0)
                {
                    referenced = new UnresolvedOperation(this.expression.Function, Edm.Strings.Bad_UnresolvedOperation(this.expression.Function), this.Location);
                }
                else
                {
                    candidateOperations = candidateOperations.Where(this.IsMatchingFunction);
                    candidateCount      = candidateOperations.Count();
                    if (candidateCount > 1)
                    {
                        candidateOperations = candidateOperations.Where(this.IsExactMatch);
                        candidateCount      = candidateOperations.Count();
                        if (candidateCount != 1)
                        {
                            referenced = new UnresolvedOperation(this.expression.Function, Edm.Strings.Bad_AmbiguousOperation(this.expression.Function), this.Location);
                        }
                        else
                        {
                            referenced = candidateOperations.Single();
                        }
                    }
                    else if (candidateCount == 0)
                    {
                        referenced = new UnresolvedOperation(this.expression.Function, Edm.Strings.Bad_OperationParametersDontMatch(this.expression.Function), this.Location);
                    }
                    else
                    {
                        referenced = candidateOperations.Single();
                    }
                }

                return(new Library.Expressions.EdmOperationReferenceExpression(referenced));
            }
        }
        private IEdmExpression ComputeAppliedOperation()
        {
            if (this.expression.Function == null)
            {
                return CsdlSemanticsModel.WrapExpression(this.expression.Arguments.FirstOrDefault(null), this.bindingContext, this.schema);
            }
            else
            {
                IEdmOperation referenced;
                IEnumerable<IEdmOperation> candidateOperations = this.schema.FindOperations(this.expression.Function);
                int candidateCount = candidateOperations.Count();
                if (candidateCount == 0)
                {
                    referenced = new UnresolvedOperation(this.expression.Function, Edm.Strings.Bad_UnresolvedOperation(this.expression.Function), this.Location);
                }
                else
                {
                    candidateOperations = candidateOperations.Where(this.IsMatchingFunction);
                    candidateCount = candidateOperations.Count();
                    if (candidateCount > 1)
                    {
                        candidateOperations = candidateOperations.Where(this.IsExactMatch);
                        candidateCount = candidateOperations.Count();
                        if (candidateCount != 1)
                        {
                            referenced = new UnresolvedOperation(this.expression.Function, Edm.Strings.Bad_AmbiguousOperation(this.expression.Function), this.Location);
                        }
                        else
                        {
                            referenced = candidateOperations.Single();
                        }
                    }
                    else if (candidateCount == 0)
                    {
                        referenced = new UnresolvedOperation(this.expression.Function, Edm.Strings.Bad_OperationParametersDontMatch(this.expression.Function), this.Location);
                    }
                    else
                    {
                        referenced = candidateOperations.Single();
                    }
                }

                return new Library.Expressions.EdmOperationReferenceExpression(referenced);
            }
        }
        private IEdmVocabularyAnnotatable ComputeTarget()
        {
            if (this.targetContext != null)
            {
                return(this.targetContext);
            }
            else
            {
                Debug.Assert(this.annotationsContext != null, "Annotation must either have a target context or annotations context");
                string              target              = this.annotationsContext.Annotations.Target;
                string[]            targetSegments      = target.Split('/');
                int                 targetSegmentsCount = targetSegments.Count();
                IEdmEntityContainer container;

                if (targetSegmentsCount == 1)
                {
                    string         elementName = targetSegments[0];
                    IEdmSchemaType type        = this.schema.FindType(elementName);
                    if (type != null)
                    {
                        return(type);
                    }

                    IEdmValueTerm term = this.schema.FindValueTerm(elementName);
                    if (term != null)
                    {
                        return(term);
                    }

                    IEdmOperation operation = this.FindParameterizedOperation(elementName, this.Schema.FindOperations, this.CreateAmbiguousOperation);
                    if (operation != null)
                    {
                        return(operation);
                    }

                    container = this.schema.FindEntityContainer(elementName);
                    if (container != null)
                    {
                        return(container);
                    }

                    return(new UnresolvedType(this.Schema.UnresolvedName(targetSegments[0]), this.Location));
                }

                if (targetSegmentsCount == 2)
                {
                    container = this.schema.FindEntityContainer(targetSegments[0]);
                    if (container != null)
                    {
                        IEdmEntityContainerElement containerElement = container.FindEntitySetExtended(targetSegments[1]);
                        if (containerElement != null)
                        {
                            return(containerElement);
                        }

                        IEdmOperationImport operationImport = this.FindParameterizedOperationImport(targetSegments[1], container.FindOperationImportsExtended, this.CreateAmbiguousOperationImport);
                        if (operationImport != null)
                        {
                            return(operationImport);
                        }

                        return(new UnresolvedEntitySet(targetSegments[1], container, this.Location));
                    }

                    IEdmStructuredType type = this.schema.FindType(targetSegments[0]) as IEdmStructuredType;
                    if (type != null)
                    {
                        IEdmProperty property = type.FindProperty(targetSegments[1]);
                        if (property != null)
                        {
                            return(property);
                        }

                        return(new UnresolvedProperty(type, targetSegments[1], this.Location));
                    }

                    IEdmOperation operation = this.FindParameterizedOperation(targetSegments[0], this.Schema.FindOperations, this.CreateAmbiguousOperation);
                    if (operation != null)
                    {
                        IEdmOperationParameter parameter = operation.FindParameter(targetSegments[1]);
                        if (parameter != null)
                        {
                            return(parameter);
                        }

                        return(new UnresolvedParameter(operation, targetSegments[1], this.Location));
                    }

                    return(new UnresolvedProperty(new UnresolvedEntityType(this.Schema.UnresolvedName(targetSegments[0]), this.Location), targetSegments[1], this.Location));
                }

                if (targetSegmentsCount == 3)
                {
                    // The only valid target with three segments is a function parameter.
                    string containerName = targetSegments[0];
                    string operationName = targetSegments[1];
                    string parameterName = targetSegments[2];

                    container = this.Model.FindEntityContainer(containerName);
                    if (container != null)
                    {
                        IEdmOperationImport operationImport = this.FindParameterizedOperationImport(operationName, container.FindOperationImportsExtended, this.CreateAmbiguousOperationImport);
                        if (operationImport != null)
                        {
                            IEdmOperationParameter parameter = operationImport.Operation.FindParameter(parameterName);
                            if (parameter != null)
                            {
                                return(parameter);
                            }

                            return(new UnresolvedParameter(operationImport.Operation, parameterName, this.Location));
                        }
                    }

                    string qualifiedOperationName           = containerName + "/" + operationName;
                    UnresolvedOperation unresolvedOperation = new UnresolvedOperation(qualifiedOperationName, Edm.Strings.Bad_UnresolvedOperation(qualifiedOperationName), this.Location);
                    return(new UnresolvedParameter(unresolvedOperation, parameterName, this.Location));
                }

                return(new BadElement(new EdmError[] { new EdmError(this.Location, EdmErrorCode.ImpossibleAnnotationsTarget, Edm.Strings.CsdlSemantics_ImpossibleAnnotationsTarget(target)) }));
            }
        }
示例#4
0
        private IEdmVocabularyAnnotatable ComputeTarget()
        {
            if (this.targetContext != null)
            {
                return(this.targetContext);
            }
            else
            {
                Debug.Assert(this.annotationsContext != null, "Annotation must either have a target context or annotations context");
                string              target              = this.annotationsContext.Annotations.Target;
                string[]            targetSegments      = target.Split('/');
                int                 targetSegmentsCount = targetSegments.Length;
                IEdmEntityContainer container;

                if (targetSegmentsCount == 1)
                {
                    string         elementName = targetSegments[0];
                    IEdmSchemaType type        = this.schema.FindType(elementName);
                    if (type != null)
                    {
                        return(type);
                    }

                    IEdmTerm term = this.schema.FindTerm(elementName);
                    if (term != null)
                    {
                        return(term);
                    }

                    IEdmOperation operation = this.FindParameterizedOperation(elementName, this.Schema.FindOperations, this.CreateAmbiguousOperation);
                    if (operation != null)
                    {
                        return(operation);
                    }

                    container = this.schema.FindEntityContainer(elementName);
                    if (container != null)
                    {
                        return(container);
                    }

                    return(new UnresolvedType(this.Schema.UnresolvedName(targetSegments[0]), this.Location));
                }

                if (targetSegmentsCount == 2)
                {
                    container = this.schema.FindEntityContainer(targetSegments[0]);
                    if (container != null)
                    {
                        // Using the methods here results in a much faster lookup as it uses a dictionary instead of using the list of container elements.
                        IEdmEntityContainerElement containerElement = container.FindEntitySetExtended(targetSegments[1])
                                                                      ?? container.FindSingletonExtended(targetSegments[1]) as IEdmEntityContainerElement;
                        if (containerElement != null)
                        {
                            return(containerElement);
                        }

                        IEdmOperationImport operationImport = FindParameterizedOperationImport(targetSegments[1], container.FindOperationImportsExtended, this.CreateAmbiguousOperationImport);
                        if (operationImport != null)
                        {
                            return(operationImport);
                        }

                        return(new UnresolvedEntitySet(targetSegments[1], container, this.Location));
                    }

                    IEdmSchemaType type = this.schema.FindType(targetSegments[0]);
                    if (type != null)
                    {
                        IEdmStructuredType structuredType;
                        IEdmEnumType       enumType;
                        if ((structuredType = type as IEdmStructuredType) != null)
                        {
                            IEdmProperty property = structuredType.FindProperty(targetSegments[1]);
                            if (property != null)
                            {
                                return(property);
                            }

                            return(new UnresolvedProperty(structuredType, targetSegments[1], this.Location));
                        }
                        else if ((enumType = type as IEdmEnumType) != null)
                        {
                            foreach (IEdmEnumMember member in enumType.Members)
                            {
                                if (String.Equals(member.Name, targetSegments[1], StringComparison.OrdinalIgnoreCase))
                                {
                                    return(member);
                                }
                            }

                            return(new UnresolvedEnumMember(targetSegments[1], enumType, this.Location));
                        }
                    }

                    IEdmOperation operation = this.FindParameterizedOperation(targetSegments[0], this.Schema.FindOperations, this.CreateAmbiguousOperation);
                    if (operation != null)
                    {
                        // $ReturnType
                        if (targetSegments[1] == CsdlConstants.OperationReturnExternalTarget)
                        {
                            if (operation.ReturnType != null)
                            {
                                return(operation.GetReturn());
                            }

                            return(new UnresolvedReturn(operation, this.Location));
                        }

                        IEdmOperationParameter parameter = operation.FindParameter(targetSegments[1]);
                        if (parameter != null)
                        {
                            return(parameter);
                        }

                        return(new UnresolvedParameter(operation, targetSegments[1], this.Location));
                    }

                    return(new UnresolvedProperty(new UnresolvedEntityType(this.Schema.UnresolvedName(targetSegments[0]), this.Location), targetSegments[1], this.Location));
                }

                if (targetSegmentsCount == 3)
                {
                    // The only valid target with three segments is a function parameter, or an operation return.
                    string containerName = targetSegments[0];
                    string operationName = targetSegments[1];
                    string parameterName = targetSegments[2];

                    container = this.Model.FindEntityContainer(containerName);
                    if (container != null)
                    {
                        IEdmOperationImport operationImport = FindParameterizedOperationImport(operationName, container.FindOperationImportsExtended, this.CreateAmbiguousOperationImport);
                        if (operationImport != null)
                        {
                            // $ReturnType
                            if (parameterName == CsdlConstants.OperationReturnExternalTarget)
                            {
                                if (operationImport.Operation.ReturnType != null)
                                {
                                    return(operationImport.Operation.GetReturn());
                                }

                                return(new UnresolvedReturn(operationImport.Operation, this.Location));
                            }

                            IEdmOperationParameter parameter = operationImport.Operation.FindParameter(parameterName);
                            if (parameter != null)
                            {
                                return(parameter);
                            }

                            return(new UnresolvedParameter(operationImport.Operation, parameterName, this.Location));
                        }
                    }

                    string qualifiedOperationName           = containerName + "/" + operationName;
                    UnresolvedOperation unresolvedOperation = new UnresolvedOperation(qualifiedOperationName, Edm.Strings.Bad_UnresolvedOperation(qualifiedOperationName), this.Location);
                    if (parameterName == CsdlConstants.OperationReturnExternalTarget)
                    {
                        return(new UnresolvedReturn(unresolvedOperation, this.Location));
                    }
                    else
                    {
                        return(new UnresolvedParameter(unresolvedOperation, parameterName, this.Location));
                    }
                }

                return(new BadElement(new EdmError[] { new EdmError(this.Location, EdmErrorCode.ImpossibleAnnotationsTarget, Edm.Strings.CsdlSemantics_ImpossibleAnnotationsTarget(target)) }));
            }
        }
        private IEdmVocabularyAnnotatable ComputeTarget()
        {
            if (this.targetContext != null)
            {
                return this.targetContext;
            }
            else
            {
                Debug.Assert(this.annotationsContext != null, "Annotation must either have a target context or annotations context");
                string target = this.annotationsContext.Annotations.Target;
                string[] targetSegments = target.Split('/');
                int targetSegmentsCount = targetSegments.Count();
                IEdmEntityContainer container;

                if (targetSegmentsCount == 1)
                {
                    string elementName = targetSegments[0];
                    IEdmSchemaType type = this.schema.FindType(elementName);
                    if (type != null)
                    {
                        return type;
                    }

                    IEdmValueTerm term = this.schema.FindValueTerm(elementName);
                    if (term != null)
                    {
                        return term;
                    }

                    IEdmOperation operation = this.FindParameterizedOperation(elementName, this.Schema.FindOperations, this.CreateAmbiguousOperation);
                    if (operation != null)
                    {
                        return operation;
                    }

                    container = this.schema.FindEntityContainer(elementName);
                    if (container != null)
                    {
                        return container;
                    }

                    return new UnresolvedType(this.Schema.UnresolvedName(targetSegments[0]), this.Location);
                }

                if (targetSegmentsCount == 2)
                {
                    container = this.schema.FindEntityContainer(targetSegments[0]);
                    if (container != null)
                    {
                        IEdmEntityContainerElement containerElement = container.FindEntitySetExtended(targetSegments[1]);
                        if (containerElement != null)
                        {
                            return containerElement;
                        }

                        IEdmOperationImport operationImport = this.FindParameterizedOperationImport(targetSegments[1], container.FindOperationImportsExtended, this.CreateAmbiguousOperationImport);
                        if (operationImport != null)
                        {
                            return operationImport;
                        }

                        return new UnresolvedEntitySet(targetSegments[1], container, this.Location);
                    }

                    IEdmStructuredType type = this.schema.FindType(targetSegments[0]) as IEdmStructuredType;
                    if (type != null)
                    {
                        IEdmProperty property = type.FindProperty(targetSegments[1]);
                        if (property != null)
                        {
                            return property;
                        }

                        return new UnresolvedProperty(type, targetSegments[1], this.Location);
                    }

                    IEdmOperation operation = this.FindParameterizedOperation(targetSegments[0], this.Schema.FindOperations, this.CreateAmbiguousOperation);
                    if (operation != null)
                    {
                        IEdmOperationParameter parameter = operation.FindParameter(targetSegments[1]);
                        if (parameter != null)
                        {
                            return parameter;
                        }

                        return new UnresolvedParameter(operation, targetSegments[1], this.Location);
                    }

                    return new UnresolvedProperty(new UnresolvedEntityType(this.Schema.UnresolvedName(targetSegments[0]), this.Location), targetSegments[1], this.Location);
                }

                if (targetSegmentsCount == 3)
                {
                    // The only valid target with three segments is a function parameter.
                    string containerName = targetSegments[0];
                    string operationName = targetSegments[1];
                    string parameterName = targetSegments[2];

                    container = this.Model.FindEntityContainer(containerName);
                    if (container != null)
                    {
                        IEdmOperationImport operationImport = this.FindParameterizedOperationImport(operationName, container.FindOperationImportsExtended, this.CreateAmbiguousOperationImport);
                        if (operationImport != null)
                        {
                            IEdmOperationParameter parameter = operationImport.Operation.FindParameter(parameterName);
                            if (parameter != null)
                            {
                                return parameter;
                            }

                            return new UnresolvedParameter(operationImport.Operation, parameterName, this.Location);
                        }
                    }

                    string qualifiedOperationName = containerName + "/" + operationName;
                    UnresolvedOperation unresolvedOperation = new UnresolvedOperation(qualifiedOperationName, Edm.Strings.Bad_UnresolvedOperation(qualifiedOperationName), this.Location);
                    return new UnresolvedParameter(unresolvedOperation, parameterName, this.Location);
                }

                return new BadElement(new EdmError[] { new EdmError(this.Location, EdmErrorCode.ImpossibleAnnotationsTarget, Edm.Strings.CsdlSemantics_ImpossibleAnnotationsTarget(target)) });
            }
        }