Exemple #1
0
 public static FilterBoxViewModel NewBooleanLiteral(IValidationScope context, bool negate, bool value)
 {
     return(new FilterBoxViewModel(context, negate, new BooleanLiteralViewModel(value))
     {
         state = FilterBoxState.ReadyToUse
     });
 }
Exemple #2
0
        /// <summary>
        /// Validates THIS, which must have an indexer. If parameter count or type does
        /// not match, throws a <see cref="LocateableException"/>.
        /// </summary>
        /// <param name="context"></param>
        /// <returns></returns>
        public ArrayAccessExpression Validate(IValidationScope context)
        {
            var thisExpression = ThisExpression.Validate(context);
            var indices        = Indices.Select(i => i.Validate(context)).ToArray();
            var type           = context.TypeSystem.GetTypeByNative(thisExpression.SemanticType);

            indexer = type.Indexer;
            if (indexer == null)
            {
                throw new LocateableException(Location, "No indexer found!");
            }
            SemanticType = indexer.ReturnType;
            var formalParameters = indexer.FormalParameters;

            if (formalParameters.Length != indices.Length)
            {
                throw new LocateableException(Location, "Parameter count mismatch!");
            }
            for (var index = 0; index < formalParameters.Length; index++)
            {
                var formal = formalParameters[index];
                var actual = indices[index].SemanticType;
                if (formal != actual)
                {
                    var chain = context.TypeSystem.GetImplicitlyCastChain(actual, formal);
                    indices[index] = chain.ApplyCast(indices[index], context, () => new LocateableException(indices[index].Location, "Parameter type mismatch!"));
                }
            }
            return(this);
        }
Exemple #3
0
        /// <summary>
        /// Given to R-values, trys to unify both value's type by calling implicit type conversions.
        /// </summary>
        /// <param name="this"></param>
        /// <param name="lhs"></param>
        /// <param name="rhs"></param>
        /// <param name="generateError"></param>
        /// <returns></returns>
        public static Type AlignTypes(this IValidationScope @this, ref IExpression lhs, ref IExpression rhs, Func <Exception> generateError)
        {
            var chain   = @this.TypeSystem.GetImplicitlyCastChain(lhs.SemanticType, rhs.SemanticType);
            var newLeft = chain.ApplyCast(lhs, @this);

            if (newLeft != null)
            {
                lhs = newLeft;
                return(lhs.SemanticType);
            }
            else
            {
                chain = @this.TypeSystem.GetImplicitlyCastChain(rhs.SemanticType, lhs.SemanticType);
                var newRight = chain.ApplyCast(rhs, @this);
                if (newRight != null)
                {
                    rhs = newRight;
                    return(rhs.SemanticType);
                }
                else
                {
                    throw generateError();
                }
            }
        }
Exemple #4
0
 public static FilterBoxViewModel NewComparsion(IValidationScope context, bool negate, IVariable <Type> field, BinaryOperator op, ComparsionValueViewModel value)
 {
     return(new FilterBoxViewModel(context, negate, new FieldComparsionViewModel(context, field, op, value))
     {
         state = FilterBoxState.ReadyToUse
     });
 }
Exemple #5
0
 /// <summary>
 /// Validates the query. If the expression is not boolean, throws a <see cref="LocateableException"/>.
 /// </summary>
 /// <param name="context"></param>
 /// <returns></returns>
 public Query Validate(IValidationScope context)
 {
     Expression = Expression.Validate(context);
     if (Expression.SemanticType != typeof(bool))
     {
         throw new LocateableException(Expression.Location, "Query expression type must be boolean!");
     }
     return(this);
 }
Exemple #6
0
        /// <summary>
        /// Validation of expression: checks whether the variable is known and returns its type.
        /// </summary>
        /// <param name="context">The context.</param>
        /// <returns></returns>
        /// <exception cref="LocateableException">Unknown field!</exception>
        public VariableExpression Validate(IValidationScope context)
        {
            if (!context.TryGetVariable(Identifier, out IVariableDeclaration nameable))
            {
                throw new LocateableException(Location, "Unknown field!");
            }

            SemanticType = nameable.Value;
            return(this);
        }
Exemple #7
0
        public static FilterBoxViewModel NewEditor(IValidationScope context, QueryPartSuggestion suggestion)
        {
            var result = new FilterBoxViewModel(context, false, suggestion.Part);

            result.FilterState = result.QueryPart.Validate(context);
            if (result.FilterState == FilterBoxState.HasErrors)
            {
                result.FilterState = FilterBoxState.Editing;
            }
            return(result);
        }
 /// <summary>
 /// Validation: Determine the actual operation and return type of this unary operator.
 /// </summary>
 /// <param name="context"></param>
 /// <returns></returns>
 public UnaryOperationExpression Validate(IValidationScope context)
 {
     Expression = Expression.Validate(context);
     operation  = context.TypeSystem.GetUnaryOperation(Operator, Expression.SemanticType);
     if (operation == null)
     {
         throw new LocateableException(Location, "Unary operation not supported for that type of operand!");
     }
     SemanticType = operation.ResultType;
     return(this);
 }
Exemple #9
0
 /// <summary>
 /// Validates this function call, by checking the signature, parameter count.
 /// Sets the semantic type to the return type of the found function.
 /// </summary>
 /// <param name="context"></param>
 /// <returns></returns>
 public FunctionCallExpression Validate(IValidationScope context)
 {
     ThisExpression = ThisExpression.Validate(context);
     if (ThisExpression.SemanticType.IfMemberFunctionClosureTryGetMethodSignature(out IMemberFunctionSignature methodSignature))
     {
         var parameterIndex = 0;
         if (methodSignature.ParameterTypes.Length != Parameters.Count())
         {
             throw new LocateableException(Location, "Parameter count mismatch!");
         }
         Parameters = Parameters.Select(p =>
         {
             p = p.Validate(context);
             var formalType = methodSignature.ParameterTypes[parameterIndex];
             parameterIndex++;
             if (p.SemanticType != formalType)
             {
                 var chain = context.TypeSystem.GetImplicitlyCastChain(p.SemanticType, formalType);
                 p         = chain.ApplyCast(p, context, () => new LocateableException(p.Location, "Parameter " + parameterIndex + " type mismatch: can not convert."));
             }
             return(p);
         }).ToArray();
         SemanticType = methodSignature.ReturnType;
         return(this);
     }
     else if (ThisExpression.SemanticType.IfFunctionClosureTryGetFunctionType(out GlobalFunctionSignature functionSignature))
     {
         var parameterIndex = 0;
         if (functionSignature.ParameterTypes.Length != Parameters.Count())
         {
             throw new InvalidOperationException("Parameter count mismatch!");
         }
         Parameters = Parameters.Select(p =>
         {
             p = p.Validate(context);
             var formalType = functionSignature.ParameterTypes[parameterIndex];
             parameterIndex++;
             if (p.SemanticType != formalType)
             {
                 var chain = context.TypeSystem.GetImplicitlyCastChain(p.SemanticType, formalType);
                 p         = chain.ApplyCast(p, context, () => new InvalidOperationException("Parameter " + parameterIndex + " type mismatch: can not convert."));
             }
             return(p);
         }).ToArray();
         SemanticType = functionSignature.ReturnType;
         return(this);
     }
     else
     {
         throw new LocateableException(Location, "Closure expected!");
     }
 }
Exemple #10
0
 private FilterBoxViewModel(IValidationScope context, bool negate, QueryPartViewModel queryPart)
 {
     this.Context                  = context;
     this.queryPart                = queryPart;
     queryPart.PropertyChanged    += (sender, args) => RaiseChanged();
     queryPart.ReadyModeRequested += (sender, args) => Validate();
     state         = FilterBoxState.Editing;
     this.negate   = negate;
     this.last     = false;
     AddCommand    = new RelayCommand <QueryPartSuggestion>(suggestion => Added?.Invoke(this, suggestion));
     DeleteCommand = new RelayCommand(() => Deleted?.Invoke(this, new EventArgs()));
     DoneCommand   = new RelayCommand(() => Validate());
 }
Exemple #11
0
        /// <summary>
        /// Validation, checking whether the member is a valid property.
        /// </summary>
        /// <param name="context"></param>
        /// <returns></returns>
        public MemberExpression Validate(IValidationScope context)
        {
            var @this      = ThisExpression.Validate(context);
            var thisType   = @this.SemanticType;
            var csharpType = context.TypeSystem.GetTypeByNative(thisType);
            var symbol     = csharpType.GetByName(Delimiter, MemberName);

            if (!(symbol is IProperty))
            {
                throw new LocateableException(Location, "Expecting property!");
            }
            validatedProperty = symbol as IProperty;
            SemanticType      = validatedProperty.ReturnType;
            return(this);
        }
Exemple #12
0
        /// <summary>
        /// Validation: Checks whether the type really exists and whether the conversion is allowed.
        /// </summary>
        /// <param name="context"></param>
        /// <returns></returns>
        public CastExpression Validate(IValidationScope context)
        {
            var type = context.TypeSystem.GetTypeByName(CastTypeName)?.NativeType;

            if (type == null)
            {
                throw new LocateableException(Location, $"There is no type {CastTypeName}!");
            }
            Expression = Expression.Validate(context);
            rule       = context.TypeSystem.GetCoercionRule(Expression.SemanticType, type);
            if (rule == null)
            {
                throw new LocateableException(Location, $"Can not convert type into a '{CastTypeName}'.");
            }
            SemanticType = type;
            return(this);
        }
Exemple #13
0
        /// <summary>
        /// Validates expression. Trys to align types.
        /// </summary>
        /// <param name="context"></param>
        /// <returns></returns>
        public ArrayExpression Validate(IValidationScope context)
        {
            var elements = Elements.Select(e => e.Validate(context)).ToArray();
            //Attention! The array has at least one element.
            var elementType = Elements.First().SemanticType;

            for (var index = 1; index < elements.Length; index++)
            {
                if (elements[index].SemanticType != elementType)
                {
                    elementType = context.AlignTypes(ref elements[index - 1], ref elements[index], () => new LocateableException(Location, "Could not unify type of this array!"));
                }
            }
            Elements     = elements;
            elementType  = Elements.Select(e => e.SemanticType).GetCommonBaseClass();
            SemanticType = elementType.MakeArrayType();
            return(this);
        }
Exemple #14
0
 /// <summary>
 /// Validation.
 /// </summary>
 /// <param name="context"></param>
 /// <returns></returns>
 public ConditionalExpression Validate(IValidationScope context)
 {
     Condition = Condition.Validate(context);
     then      = then.Validate(context);
     @else     = @else.Validate(context);
     if (Condition.SemanticType != typeof(bool))
     {
         throw new LocateableException(Condition.Location, "Condition must be a boolean!");
     }
     if (Then.SemanticType != Else.SemanticType)
     {
         SemanticType = context.AlignTypes(ref then, ref @else,
                                           () => new LocateableException(Location, "In the end the Then and the Else part must have the same type (also using implicit type conversion)!"));
     }
     else
     {
         SemanticType = Then.SemanticType;
     }
     return(this);
 }
Exemple #15
0
 public FieldComparsionViewModel(IValidationScope context, IVariable <Type> field, BinaryOperator?op = null, ComparsionValueViewModel value = null)
 {
     this.KeyDownCommand = new RelayCommand <KeyEventArgs>(args =>
     {
         if (args.Key == Key.Return || args.Key == Key.Enter)
         {
             RequestReadyMode();
         }
     });
     this.context = context;
     this.field   = field;
     this.op      = op;
     this.value   = value;
     this.state   = field == null
         ? FieldComparsionState.Phase1_FieldMissing
         : op == null
             ? FieldComparsionState.Phase2_OperatorMissing
             : value == null
                 ? FieldComparsionState.Phase3_ValueMissing
                 : FieldComparsionState.ReadyToUse;
     ComputePossibleStates();
     UpdateField();
 }
 /// <summary>
 /// Validation: Nothing to do.
 /// </summary>
 /// <param name="context"></param>
 /// <returns></returns>
 public IntegerLiteralExpression Validate(IValidationScope context)
 {
     return(this);
 }
Exemple #17
0
        /// <summary>
        /// Validation: determines the actual operation and its return type.
        /// </summary>
        /// <param name="context"></param>
        /// <returns></returns>
        public BinaryOperationExpression Validate(IValidationScope context)
        {
            this.leftExpression  = this.leftExpression.Validate(context);
            this.rightExpression = this.rightExpression.Validate(context);
            switch (this.Operator)
            {
            case BinaryOperator.In:
            case BinaryOperator.NotIn:
            {
                Type needleType = leftExpression.SemanticType;
                if (!rightExpression.IfArrayTryGetElementType(out Type elementType))
                {
                    throw new LocateableException(Location, "The 'in' operator requires an array expression for the right operand.");
                }
                if (needleType != elementType)
                {
                    var chain   = context.TypeSystem.GetImplicitlyCastChain(needleType, elementType);
                    var newLeft = chain.ApplyCast(leftExpression, context);
                    if (newLeft != null)
                    {
                        leftExpression = newLeft;
                        needleType     = elementType;
                    }
                    else
                    {
                        chain = context.TypeSystem.GetImplicitlyCastChain(elementType, needleType);
                        var array = rightExpression as ArrayExpression;
                        if (array == null)
                        {
                            throw new LocateableException(Location, "The 'in' operator requires that the right operand to be a list of the left operand's type.");
                        }
                        else
                        {
                            var newArray = new ArrayExpression(rightExpression.Location, array.Elements.Select(exp => chain.ApplyCast(exp, context)));
                            if (newArray.Elements.All(e => e != null))
                            {
                                rightExpression = newArray;
                                elementType     = needleType;
                            }
                            else
                            {
                                throw new LocateableException(Location, "The 'in' operator requires that the left operand has the same type like the elements of the right operand. At least these types must be convertible in each other.");
                            }
                        }
                    }
                }
                Type haystackType   = typeof(IEnumerable <>).MakeGenericType(elementType);
                var  equalsOperator = Operator == BinaryOperator.In ? BinaryOperator.Equals : BinaryOperator.NotEquals;
                var  equals         = context.TypeSystem.GetBinaryOperation(equalsOperator, needleType, elementType);
                if (equals == null)
                {
                    throw new LocateableException(Location, "The elements of the array are not comparable with the left operand.");
                }
                operation = new BinaryOperation(needleType, haystackType, typeof(bool), Operator, (needle, haystack) =>
                    {
                        foreach (object element in ((IEnumerable)haystack))
                        {
                            if ((bool)equals.Operation(needle, element) == true)
                            {
                                return(true);
                            }
                        }
                        return(false);
                    });
                SemanticType = typeof(bool);
            }
            break;

            case BinaryOperator.Is:
            {
                var negate = false;
                if (rightExpression is NullExpression)
                {
                    //almost everything could be null
                    SemanticType = typeof(bool);
                    operation    = new BinaryOperation(leftExpression.SemanticType, rightExpression.SemanticType, typeof(bool), Operator,
                                                       (lhs, _) => { return(negate ^ object.Equals(lhs, null)); });
                }
                else if (rightExpression is EmptyExpression)
                {
                    if (!leftExpression.IfArrayTryGetElementType(out Type elementType))
                    {
                        throw new LocateableException(leftExpression.Location, "Left operand must be of an array type.");
                    }
                    SemanticType = typeof(bool);
                    operation    = new BinaryOperation(leftExpression.SemanticType, rightExpression.SemanticType, typeof(bool), Operator,
                                                       (lhs, _) =>
                        {
                            foreach (object element in ((IEnumerable)lhs))
                            {
                                return(negate);
                            }
                            return(!negate);
                        });
                }
                else
                {
                    throw new LocateableException(rightExpression.Location, "Right operand must be NULL or EMPTY.");
                }
            }
            break;

            default:
                operation = context.TypeSystem.GetBinaryOperation(Operator, LeftExpression.SemanticType, RightExpression.SemanticType);
                if (operation == null)
                {
                    context.AlignTypes(ref leftExpression, ref rightExpression,
                                       () => new LocateableException(Location, "Binary operation not supported!"));
                }
                operation = context.TypeSystem.GetBinaryOperation(Operator, LeftExpression.SemanticType, RightExpression.SemanticType);
                if (operation == null)
                {
                    throw new LocateableException(Location, "Binary operation not supported!");
                }
                SemanticType = operation.ResultType;
                break;
            }
            return(this);
        }
 /// <summary>
 /// Validates literal.
 /// </summary>
 /// <param name="context"></param>
 /// <returns></returns>
 public BooleanLiteralExpression Validate(IValidationScope context)
 {
     return(this);
 }
Exemple #19
0
        /// <summary>
        /// Applies a set of type casts to an expression. This will insert several cast expressions.
        /// </summary>
        /// <param name="this"></param>
        /// <param name="expression"></param>
        /// <param name="context"></param>
        /// <param name="generateError"></param>
        /// <returns></returns>
        public static IExpression ApplyCast(this IEnumerable <CoercionRule> @this, IExpression expression, IValidationScope context, Func <Exception> generateError = null)
        {
            if ([email protected]())
            {
                if (generateError != null)
                {
                    throw generateError();
                }
                return(null);
            }
            var current = expression;

            foreach (var rule in @this)
            {
                current = new CastExpression(rule, current);
            }
            return(current);
        }
Exemple #20
0
 /// <summary>
 /// Validation, nothing important for strings.
 /// </summary>
 /// <param name="context"></param>
 /// <returns></returns>
 public StringLiteralExpression Validate(IValidationScope context)
 {
     SemanticType = typeof(string);
     return(this);
 }
Exemple #21
0
 /// <summary>
 /// Validation...
 /// </summary>
 /// <param name="context"></param>
 /// <returns></returns>
 public EmptyExpression Validate(IValidationScope context)
 {
     SemanticType = context.TypeSystem.EmptyType;
     return(this);
 }
Exemple #22
0
 /// <summary>
 /// Validation...
 /// </summary>
 /// <param name="context"></param>
 /// <returns></returns>
 public ParenthesisExpression Validate(IValidationScope context)
 {
     Expression   = Expression.Validate(context);
     SemanticType = Expression.SemanticType;
     return(this);
 }
Exemple #23
0
 public override FilterBoxState Validate(IValidationScope context)
 {
     return(FilterBoxState.ReadyToUse);
 }
Exemple #24
0
 /// <summary>
 /// Validation.
 /// </summary>
 /// <param name="context"></param>
 /// <returns></returns>
 public NullExpression Validate(IValidationScope context)
 {
     SemanticType = context.TypeSystem.NullType;
     return(this);
 }
Exemple #25
0
 /// <summary>
 /// Creates an empty validation scope.
 /// </summary>
 /// <param name="system"></param>
 /// <param name="parent"></param>
 public ValidationScope(ITypeSystem system, IValidationScope parent = null)
 {
     this.Parent     = parent;
     this.TypeSystem = system;
 }
 /// <summary>
 /// Validation... nothing to do here.
 /// </summary>
 /// <param name="context"></param>
 /// <returns></returns>
 public FloatingPointLiteralExpression Validate(IValidationScope context)
 {
     return(this);
 }
Exemple #27
0
 public abstract FilterBoxState Validate(IValidationScope context);
Exemple #28
0
 IExpression IExpression.Validate(IValidationScope context)
 {
     return(Validate(context));
 }
Exemple #29
0
 public override FilterBoxState Validate(IValidationScope context)
 {
     return(field == null || op == null || !op.HasValue || value == null ? FilterBoxState.HasErrors : FilterBoxState.ReadyToUse);
 }