private IEdmValue Eval(IEdmExpression expression, IEdmStructuredValue context)
        {
            switch (expression.ExpressionKind)
            {
            case EdmExpressionKind.IntegerConstant:
                return((IEdmIntegerConstantExpression)expression);

            case EdmExpressionKind.StringConstant:
                return((IEdmStringConstantExpression)expression);

            case EdmExpressionKind.BinaryConstant:
                return((IEdmBinaryConstantExpression)expression);

            case EdmExpressionKind.BooleanConstant:
                return((IEdmBooleanConstantExpression)expression);

            case EdmExpressionKind.DateTimeConstant:
                return((IEdmDateTimeConstantExpression)expression);

            case EdmExpressionKind.DateTimeOffsetConstant:
                return((IEdmDateTimeOffsetConstantExpression)expression);

            case EdmExpressionKind.DecimalConstant:
                return((IEdmDecimalConstantExpression)expression);

            case EdmExpressionKind.FloatingConstant:
                return((IEdmFloatingConstantExpression)expression);

            case EdmExpressionKind.GuidConstant:
                return((IEdmGuidConstantExpression)expression);

            case EdmExpressionKind.TimeConstant:
                return((IEdmTimeConstantExpression)expression);

            case EdmExpressionKind.Null:
                return((IEdmNullExpression)expression);

            case EdmExpressionKind.Path:
            {
                EdmUtil.CheckArgumentNull(context, "context");

                IEdmPathExpression pathExpression = (IEdmPathExpression)expression;
                IEdmValue          result         = context;

                foreach (string hop in pathExpression.Path)
                {
                    result = this.FindProperty(hop, result);

                    if (result == null)
                    {
                        throw new InvalidOperationException(Edm.Strings.Edm_Evaluator_UnboundPath(hop));
                    }
                }

                return(result);
            }

            case EdmExpressionKind.FunctionApplication:
            {
                IEdmApplyExpression             apply                   = (IEdmApplyExpression)expression;
                IEdmExpression                  targetReference         = apply.AppliedFunction;
                IEdmFunctionReferenceExpression targetFunctionReference = targetReference as IEdmFunctionReferenceExpression;
                if (targetFunctionReference != null)
                {
                    IList <IEdmExpression> argumentExpressions = apply.Arguments.ToList();
                    IEdmValue[]            arguments           = new IEdmValue[argumentExpressions.Count()];

                    {
                        int argumentIndex = 0;
                        foreach (IEdmExpression argument in argumentExpressions)
                        {
                            arguments[argumentIndex++] = this.Eval(argument, context);
                        }
                    }

                    IEdmFunction target = targetFunctionReference.ReferencedFunction;
                    if (!target.IsBad())
                    {
                        //// Static validation will have checked that the number and types of arguments are correct,
                        //// so those checks are not performed dynamically.

                        Func <IEdmValue[], IEdmValue> functionEvaluator;
                        if (this.builtInFunctions.TryGetValue(target, out functionEvaluator))
                        {
                            return(functionEvaluator(arguments));
                        }
                    }

                    if (this.lastChanceFunctionApplier != null)
                    {
                        return(this.lastChanceFunctionApplier(target.FullName(), arguments));
                    }
                }

                throw new InvalidOperationException(Edm.Strings.Edm_Evaluator_UnboundFunction(targetFunctionReference != null ? targetFunctionReference.ReferencedFunction.ToTraceString() : string.Empty));
            }

            case EdmExpressionKind.If:
            {
                IEdmIfExpression ifExpression = (IEdmIfExpression)expression;

                if (((IEdmBooleanValue)this.Eval(ifExpression.TestExpression, context)).Value)
                {
                    return(this.Eval(ifExpression.TrueExpression, context));
                }

                return(this.Eval(ifExpression.FalseExpression, context));
            }

            case EdmExpressionKind.IsType:
            {
                IEdmIsTypeExpression isType = (IEdmIsTypeExpression)expression;

                IEdmValue         operand    = this.Eval(isType.Operand, context);
                IEdmTypeReference targetType = isType.Type;

                return(new EdmBooleanConstant(MatchesType(targetType, operand)));
            }

            case EdmExpressionKind.AssertType:
            {
                IEdmAssertTypeExpression assertType = (IEdmAssertTypeExpression)expression;

                IEdmValue         operand    = this.Eval(assertType.Operand, context);
                IEdmTypeReference targetType = assertType.Type;

                return(AssertType(targetType, operand));
            }

            case EdmExpressionKind.Record:
            {
                IEdmRecordExpression     record        = (IEdmRecordExpression)expression;
                DelayedExpressionContext recordContext = new DelayedExpressionContext(this, context);

                List <IEdmPropertyValue> propertyValues = new List <IEdmPropertyValue>();

                //// Static validation will have checked that the set of supplied properties are appropriate
                //// for the supplied type and have no duplicates, so those checks are not performed dynamically.

                foreach (IEdmPropertyConstructor propertyConstructor in record.Properties)
                {
                    propertyValues.Add(new DelayedRecordProperty(recordContext, propertyConstructor));
                }

                EdmStructuredValue result = new EdmStructuredValue(record.DeclaredType != null ? record.DeclaredType.AsStructured() : null, propertyValues);
                return(result);
            }

            case EdmExpressionKind.Collection:
            {
                IEdmCollectionExpression collection        = (IEdmCollectionExpression)expression;
                DelayedExpressionContext collectionContext = new DelayedExpressionContext(this, context);
                List <IEdmDelayedValue>  elementValues     = new List <IEdmDelayedValue>();

                //// Static validation will have checked that the result types of the element expressions are
                //// appropriate and so these checks are not performed dynamically.

                foreach (IEdmExpression element in collection.Elements)
                {
                    elementValues.Add(this.MapLabeledExpressionToDelayedValue(element, collectionContext, context));
                }

                EdmCollectionValue result = new EdmCollectionValue(collection.DeclaredType != null ? collection.DeclaredType.AsCollection() : null, elementValues);
                return(result);
            }

            case EdmExpressionKind.LabeledExpressionReference:
            {
                return(this.MapLabeledExpressionToDelayedValue(((IEdmLabeledExpressionReferenceExpression)expression).ReferencedLabeledExpression, null, context).Value);
            }

            case EdmExpressionKind.Labeled:
                return(this.MapLabeledExpressionToDelayedValue(expression, new DelayedExpressionContext(this, context), context).Value);

            case EdmExpressionKind.ParameterReference:
            case EdmExpressionKind.FunctionReference:
            case EdmExpressionKind.PropertyReference:
            case EdmExpressionKind.ValueTermReference:
            case EdmExpressionKind.EntitySetReference:
            case EdmExpressionKind.EnumMemberReference:
                throw new InvalidOperationException("Not yet implemented: evaluation of " + expression.ExpressionKind.ToString() + " expressions.");

            default:
                throw new InvalidOperationException(Edm.Strings.Edm_Evaluator_UnrecognizedExpressionKind(((int)expression.ExpressionKind).ToString(System.Globalization.CultureInfo.InvariantCulture)));
            }
        }
Ejemplo n.º 2
0
 internal void WriteFunctionReferenceExpressionElement(IEdmFunctionReferenceExpression expression)
 {
     this.xmlWriter.WriteStartElement(CsdlConstants.Element_FunctionReference);
     this.WriteRequiredAttribute(CsdlConstants.Attribute_Name, expression.ReferencedFunction, this.FunctionAsXml);
     this.WriteEndElement();
 }
Ejemplo n.º 3
0
 protected override void ProcessFunctionReferenceExpression(IEdmFunctionReferenceExpression expression)
 {
     this.schemaWriter.WriteFunctionReferenceExpressionElement(expression);
 }
Ejemplo n.º 4
0
 protected virtual void ProcessFunctionReferenceExpression(IEdmFunctionReferenceExpression expression)
 {
     this.ProcessExpression(expression);
 }
Ejemplo n.º 5
0
 internal void WriteFunctionReferenceExpressionElement(IEdmFunctionReferenceExpression expression)
 {
     this.xmlWriter.WriteStartElement("FunctionReference");
     this.WriteRequiredAttribute <IEdmFunction>("Name", expression.ReferencedFunction, new Func <IEdmFunction, string>(this.FunctionAsXml));
     this.WriteEndElement();
 }
Ejemplo n.º 6
0
        private IEdmValue Eval(IEdmExpression expression, IEdmStructuredValue context)
        {
            Func <IEdmValue[], IEdmValue> func = null;
            IEdmStructuredTypeReference   edmStructuredTypeReference;
            IEdmCollectionTypeReference   edmCollectionTypeReference;
            object            traceString;
            EdmExpressionKind expressionKind = expression.ExpressionKind;

            switch (expressionKind)
            {
            case EdmExpressionKind.BinaryConstant:
            {
                return((IEdmBinaryConstantExpression)expression);
            }

            case EdmExpressionKind.BooleanConstant:
            {
                return((IEdmBooleanConstantExpression)expression);
            }

            case EdmExpressionKind.DateTimeConstant:
            {
                return((IEdmDateTimeConstantExpression)expression);
            }

            case EdmExpressionKind.DateTimeOffsetConstant:
            {
                return((IEdmDateTimeOffsetConstantExpression)expression);
            }

            case EdmExpressionKind.DecimalConstant:
            {
                return((IEdmDecimalConstantExpression)expression);
            }

            case EdmExpressionKind.FloatingConstant:
            {
                return((IEdmFloatingConstantExpression)expression);
            }

            case EdmExpressionKind.GuidConstant:
            {
                return((IEdmGuidConstantExpression)expression);
            }

            case EdmExpressionKind.IntegerConstant:
            {
                return((IEdmIntegerConstantExpression)expression);
            }

            case EdmExpressionKind.StringConstant:
            {
                return((IEdmStringConstantExpression)expression);
            }

            case EdmExpressionKind.TimeConstant:
            {
                return((IEdmTimeConstantExpression)expression);
            }

            case EdmExpressionKind.Null:
            {
                return((IEdmNullExpression)expression);
            }

            case EdmExpressionKind.Record:
            {
                IEdmRecordExpression edmRecordExpression = (IEdmRecordExpression)expression;
                EdmExpressionEvaluator.DelayedExpressionContext delayedExpressionContext = new EdmExpressionEvaluator.DelayedExpressionContext(this, context);
                List <IEdmPropertyValue> edmPropertyValues = new List <IEdmPropertyValue>();
                foreach (IEdmPropertyConstructor property in edmRecordExpression.Properties)
                {
                    edmPropertyValues.Add(new EdmExpressionEvaluator.DelayedRecordProperty(delayedExpressionContext, property));
                }
                if (edmRecordExpression.DeclaredType != null)
                {
                    edmStructuredTypeReference = edmRecordExpression.DeclaredType.AsStructured();
                }
                else
                {
                    edmStructuredTypeReference = null;
                }
                EdmStructuredValue edmStructuredValue = new EdmStructuredValue(edmStructuredTypeReference, edmPropertyValues);
                return(edmStructuredValue);
            }

            case EdmExpressionKind.Collection:
            {
                IEdmCollectionExpression edmCollectionExpression = (IEdmCollectionExpression)expression;
                EdmExpressionEvaluator.DelayedExpressionContext delayedExpressionContext1 = new EdmExpressionEvaluator.DelayedExpressionContext(this, context);
                List <IEdmDelayedValue> edmDelayedValues = new List <IEdmDelayedValue>();
                foreach (IEdmExpression element in edmCollectionExpression.Elements)
                {
                    edmDelayedValues.Add(this.MapLabeledExpressionToDelayedValue(element, delayedExpressionContext1, context));
                }
                if (edmCollectionExpression.DeclaredType != null)
                {
                    edmCollectionTypeReference = edmCollectionExpression.DeclaredType.AsCollection();
                }
                else
                {
                    edmCollectionTypeReference = null;
                }
                EdmCollectionValue edmCollectionValue = new EdmCollectionValue(edmCollectionTypeReference, edmDelayedValues);
                return(edmCollectionValue);
            }

            case EdmExpressionKind.Path:
            {
                EdmUtil.CheckArgumentNull <IEdmStructuredValue>(context, "context");
                IEdmPathExpression edmPathExpression = (IEdmPathExpression)expression;
                IEdmValue          edmValue          = context;
                foreach (string path in edmPathExpression.Path)
                {
                    edmValue = this.FindProperty(path, edmValue);
                    if (edmValue != null)
                    {
                        continue;
                    }
                    throw new InvalidOperationException(Strings.Edm_Evaluator_UnboundPath(path));
                }
                return(edmValue);
            }

            case EdmExpressionKind.ParameterReference:
            case EdmExpressionKind.FunctionReference:
            case EdmExpressionKind.PropertyReference:
            case EdmExpressionKind.ValueTermReference:
            case EdmExpressionKind.EntitySetReference:
            case EdmExpressionKind.EnumMemberReference:
            {
                throw new InvalidOperationException(string.Concat("Not yet implemented: evaluation of ", expression.ExpressionKind.ToString(), " expressions."));
            }

            case EdmExpressionKind.If:
            {
                IEdmIfExpression edmIfExpression = (IEdmIfExpression)expression;
                if (!((IEdmBooleanValue)this.Eval(edmIfExpression.TestExpression, context)).Value)
                {
                    return(this.Eval(edmIfExpression.FalseExpression, context));
                }
                else
                {
                    return(this.Eval(edmIfExpression.TrueExpression, context));
                }
            }

            case EdmExpressionKind.AssertType:
            {
                IEdmAssertTypeExpression edmAssertTypeExpression = (IEdmAssertTypeExpression)expression;
                IEdmValue         edmValue1 = this.Eval(edmAssertTypeExpression.Operand, context);
                IEdmTypeReference type      = edmAssertTypeExpression.Type;
                return(EdmExpressionEvaluator.AssertType(type, edmValue1));
            }

            case EdmExpressionKind.IsType:
            {
                IEdmIsTypeExpression edmIsTypeExpression = (IEdmIsTypeExpression)expression;
                IEdmValue            edmValue2           = this.Eval(edmIsTypeExpression.Operand, context);
                IEdmTypeReference    edmTypeReference    = edmIsTypeExpression.Type;
                return(new EdmBooleanConstant(EdmExpressionEvaluator.MatchesType(edmTypeReference, edmValue2)));
            }

            case EdmExpressionKind.FunctionApplication:
            {
                IEdmApplyExpression             edmApplyExpression             = (IEdmApplyExpression)expression;
                IEdmExpression                  appliedFunction                = edmApplyExpression.AppliedFunction;
                IEdmFunctionReferenceExpression edmFunctionReferenceExpression = appliedFunction as IEdmFunctionReferenceExpression;
                if (edmFunctionReferenceExpression != null)
                {
                    IList <IEdmExpression> list          = edmApplyExpression.Arguments.ToList <IEdmExpression>();
                    IEdmValue[]            edmValueArray = new IEdmValue[list.Count <IEdmExpression>()];
                    int num = 0;
                    foreach (IEdmExpression edmExpression in list)
                    {
                        int num1 = num;
                        num = num1 + 1;
                        edmValueArray[num1] = this.Eval(edmExpression, context);
                    }
                    IEdmFunction referencedFunction = edmFunctionReferenceExpression.ReferencedFunction;
                    if (referencedFunction.IsBad() || !this.builtInFunctions.TryGetValue(referencedFunction, out func))
                    {
                        if (this.lastChanceFunctionApplier != null)
                        {
                            return(this.lastChanceFunctionApplier(referencedFunction.FullName(), edmValueArray));
                        }
                    }
                    else
                    {
                        return(func(edmValueArray));
                    }
                }
                if (edmFunctionReferenceExpression != null)
                {
                    traceString = edmFunctionReferenceExpression.ReferencedFunction.ToTraceString();
                }
                else
                {
                    traceString = string.Empty;
                }
                throw new InvalidOperationException(Strings.Edm_Evaluator_UnboundFunction(traceString));
            }

            case EdmExpressionKind.LabeledExpressionReference:
            {
                return(this.MapLabeledExpressionToDelayedValue(((IEdmLabeledExpressionReferenceExpression)expression).ReferencedLabeledExpression, null, context).Value);
            }

            case EdmExpressionKind.Labeled:
            {
                return(this.MapLabeledExpressionToDelayedValue(expression, new EdmExpressionEvaluator.DelayedExpressionContext(this, context), context).Value);
            }
            }
            int expressionKind1 = (int)expression.ExpressionKind;

            throw new InvalidOperationException(Strings.Edm_Evaluator_UnrecognizedExpressionKind(expressionKind1.ToString(CultureInfo.InvariantCulture)));
        }