internal BinaryCSharpPattern(CSharpPatternInfo info, CSharpPatternType patternType, CSharpPattern left, CSharpPattern right)
     : base(info)
 {
     PatternType = patternType;
     Left        = left;
     Right       = right;
 }
 internal SwitchExpressionArm(ReadOnlyCollection <ParameterExpression> variables, CSharpPattern pattern, Expression whenClause, Expression value)
 {
     Variables  = variables;
     Pattern    = pattern;
     WhenClause = whenClause;
     Value      = value;
 }
Esempio n. 3
0
        internal static Expression MakeTest(CSharpPattern pattern, Expression @object, ExpressionType op, ConstantExpression value)
        {
            if (pattern.InputType == pattern.NarrowedType)
            {
                var obj = @object;

                if (obj.Type != pattern.InputType)
                {
                    obj = Expression.Convert(obj, pattern.InputType);
                }

                return
                    (Expression.MakeBinary(
                         op,
                         obj,
                         value
                         ));
            }
            else
            {
                return(PatternHelpers.Reduce(@object, obj =>
                {
                    return
                    Expression.AndAlso(
                        Expression.TypeIs(obj, pattern.NarrowedType),
                        Expression.MakeBinary(
                            op,
                            Expression.Convert(obj, pattern.NarrowedType),
                            value
                            )
                        );
                }));
            }
        }
Esempio n. 4
0
        /// <summary>
        /// Changes the input type to the specified type.
        /// </summary>
        /// <remarks>
        /// This functionality can be used when a pattern is pass to an expression or statement that applies the pattern.
        /// </remarks>
        /// <param name="inputType">The new input type.</param>
        /// <returns>The original pattern rewritten to use the specified input type.</returns>
        public override CSharpPattern ChangeType(Type inputType)
        {
            if (inputType == InputType)
            {
                return(this);
            }

            return(CSharpPattern.Recursive(ObjectPatternInfo(PatternInfo(inputType, NarrowedType), Variable), Type, DeconstructMethod, Deconstruction, Properties));
        }
Esempio n. 5
0
        /// <summary>
        /// Creates a new expression that is like this one, but using the supplied children. If all of the children are the same, it will return this expression.
        /// </summary>
        /// <param name="variable">The <see cref="Variable" /> property of the result.</param>
        /// <param name="deconstruction">The <see cref="Deconstruction" /> property of the result.</param>
        /// <param name="properties">The <see cref="Properties" /> property of the result.</param>
        /// <returns>This expression if no children changed, or an expression with the updated children.</returns>
        public RecursiveCSharpPattern Update(ParameterExpression variable, IEnumerable <PositionalCSharpSubpattern> deconstruction, IEnumerable <PropertyCSharpSubpattern> properties)
        {
            if (variable == Variable && SameElements(ref deconstruction, Deconstruction) && SameElements(ref properties, Properties))
            {
                return(this);
            }

            return(CSharpPattern.Recursive(ObjectPatternInfo(_info, variable), Type, DeconstructMethod, deconstruction, properties));
        }
        /// <summary>
        /// Creates a new expression that is like this one, but using the supplied children. If all of the children are the same, it will return this expression.
        /// </summary>
        /// <param name="left">The <see cref="Left" /> property of the result.</param>
        /// <param name="right">The <see cref="Right" /> property of the result.</param>
        /// <returns>This expression if no children changed, or an expression with the updated children.</returns>
        public BinaryCSharpPattern Update(CSharpPattern left, CSharpPattern right)
        {
            if (left == Left && right == Right)
            {
                return(this);
            }

            return(CSharpPattern.MakeBinary(_info, PatternType, left, right));
        }
Esempio n. 7
0
        /// <summary>
        /// Changes the input type to the specified type.
        /// </summary>
        /// <remarks>
        /// This functionality can be used when a pattern is pass to an expression or statement that applies the pattern.
        /// </remarks>
        /// <param name="inputType">The new input type.</param>
        /// <returns>The original pattern rewritten to use the specified input type.</returns>
        public override CSharpPattern ChangeType(Type inputType)
        {
            if (inputType == InputType)
            {
                return(this);
            }

            return(CSharpPattern.Type(PatternInfo(inputType, Type), Type));
        }
Esempio n. 8
0
        /// <summary>
        /// Changes the input type to the specified type.
        /// </summary>
        /// <remarks>
        /// This functionality can be used when a pattern is pass to an expression or statement that applies the pattern.
        /// </remarks>
        /// <param name="inputType">The new input type.</param>
        /// <returns>The original pattern rewritten to use the specified input type.</returns>
        public override CSharpPattern ChangeType(Type inputType)
        {
            if (inputType == InputType)
            {
                return(this);
            }

            return(CSharpPattern.Relational(PatternInfo(inputType, NarrowedType), PatternType, Value));
        }
        /// <summary>
        /// Changes the input type to the specified type.
        /// </summary>
        /// <remarks>
        /// This functionality can be used when a pattern is pass to an expression or statement that applies the pattern.
        /// </remarks>
        /// <param name="inputType">The new input type.</param>
        /// <returns>The original pattern rewritten to use the specified input type.</returns>
        public override CSharpPattern ChangeType(Type inputType)
        {
            if (inputType == InputType)
            {
                return(this);
            }

            return(CSharpPattern.ITuple(PatternInfo(inputType, NarrowedType), GetLengthMethod, GetItemMethod, Deconstruction));
        }
Esempio n. 10
0
        /// <summary>
        /// Changes the input type to the specified type.
        /// </summary>
        /// <remarks>
        /// This functionality can be used when a pattern is pass to an expression or statement that applies the pattern.
        /// </remarks>
        /// <param name="inputType">The new input type.</param>
        /// <returns>The original pattern rewritten to use the specified input type.</returns>
        public override CSharpPattern ChangeType(Type inputType)
        {
            if (inputType == InputType)
            {
                return(this);
            }

            return(CSharpPattern.Discard(inputType));
        }
        /// <summary>
        /// Creates a new expression that is like this one, but using the supplied children. If all of the children are the same, it will return this expression.
        /// </summary>
        /// <param name="deconstruction">The <see cref="Deconstruction" /> property of the result.</param>
        /// <returns>This expression if no children changed, or an expression with the updated children.</returns>
        public ITupleCSharpPattern Update(IEnumerable <PositionalCSharpSubpattern> deconstruction)
        {
            if (SameElements(ref deconstruction, Deconstruction))
            {
                return(this);
            }

            return(CSharpPattern.ITuple(_info, GetLengthMethod, GetItemMethod, deconstruction));
        }
        /// <summary>
        /// Changes the input type to the specified type.
        /// </summary>
        /// <remarks>
        /// This functionality can be used when a pattern is pass to an expression or statement that applies the pattern.
        /// </remarks>
        /// <param name="inputType">The new input type.</param>
        /// <returns>The original pattern rewritten to use the specified input type.</returns>
        public override CSharpPattern ChangeType(Type inputType)
        {
            if (inputType == InputType)
            {
                return(this);
            }

            return(CSharpPattern.Slice(PatternInfo(inputType, NarrowedType), IndexerAccess, Pattern));
        }
        /// <summary>
        /// Creates a new expression that is like this one, but using the supplied children. If all of the children are the same, it will return this expression.
        /// </summary>
        /// <param name="variable">The <see cref="Variable" /> property of the result.</param>
        /// <returns>This expression if no children changed, or an expression with the updated children.</returns>
        public VarCSharpPattern Update(ParameterExpression variable)
        {
            if (variable == Variable)
            {
                return(this);
            }

            return(CSharpPattern.Var(_info, variable));
        }
        /// <summary>
        /// Creates a new expression that is like this one, but using the supplied children. If all of the children are the same, it will return this expression.
        /// </summary>
        /// <param name="indexerAccess">The <see cref="IndexerAccess" /> property of the result.</param>
        /// <param name="pattern">The <see cref="Pattern" /> property of the result.</param>
        /// <returns>This expression if no children changed, or an expression with the updated children.</returns>
        public SliceCSharpPattern Update(LambdaExpression indexerAccess, CSharpPattern pattern)
        {
            if (indexerAccess == IndexerAccess && pattern == Pattern)
            {
                return(this);
            }

            return(CSharpPattern.Slice(_info, indexerAccess, pattern));
        }
        /// <summary>
        /// Creates a new expression that is like this one, but using the supplied children. If all of the children are the same, it will return this expression.
        /// </summary>
        /// <param name="variable">The <see cref="Variable" /> property of the result.</param>
        /// <param name="lengthAccess">The <see cref="LengthAccess" /> property of the result.</param>
        /// <param name="indexerAccess">The <see cref="IndexerAccess" /> property of the result.</param>
        /// <param name="patterns">The <see cref="Patterns" /> property of the result.</param>
        /// <returns>This expression if no children changed, or an expression with the updated children.</returns>
        public ListCSharpPattern Update(ParameterExpression variable, LambdaExpression lengthAccess, LambdaExpression indexerAccess, IEnumerable <CSharpPattern> patterns)
        {
            if (variable == Variable && lengthAccess == LengthAccess && indexerAccess == IndexerAccess && SameElements(ref patterns, Patterns))
            {
                return(this);
            }

            return(CSharpPattern.List(ObjectPatternInfo(_info, variable), lengthAccess, indexerAccess, patterns));
        }
        /// <summary>
        /// Creates a new expression that is like this one, but using the supplied children. If all of the children are the same, it will return this expression.
        /// </summary>
        /// <param name="variable">The <see cref="Variable" /> property of the result.</param>
        /// <returns>This expression if no children changed, or an expression with the updated children.</returns>
        public DeclarationCSharpPattern Update(ParameterExpression variable)
        {
            if (variable == Variable)
            {
                return(this);
            }

            return(CSharpPattern.Declaration(ObjectPatternInfo(_info, variable), Type));
        }
        /// <summary>
        /// Creates a new expression that is like this one, but using the supplied children. If all of the children are the same, it will return this expression.
        /// </summary>
        /// <param name="expression">The <see cref="Expression" /> property of the result.</param>
        /// <param name="pattern">The <see cref="Pattern" /> property of the result.</param>
        /// <returns>This expression if no children changed, or an expression with the updated children.</returns>
        public IsPatternCSharpExpression Update(Expression expression, CSharpPattern pattern)
        {
            if (expression == Expression && pattern == Pattern)
            {
                return(this);
            }

            return(CSharpExpression.IsPattern(expression, pattern));
        }
Esempio n. 18
0
        /// <summary>
        /// Creates a new expression that is like this one, but using the supplied children. If all of the children are the same, it will return this expression.
        /// </summary>
        /// <param name="negated">The <see cref="Negated" /> property of the result.</param>
        /// <returns>This expression if no children changed, or an expression with the updated children.</returns>
        public NotCSharpPattern Update(CSharpPattern negated)
        {
            if (negated == Negated)
            {
                return(this);
            }

            return(CSharpPattern.Not(_info, negated));
        }
Esempio n. 19
0
        /// <summary>
        /// Creates a new expression that is like this one, but using the supplied children. If all of the children are the same, it will return this expression.
        /// </summary>
        /// <param name="pattern">The <see cref="Pattern" /> property of the result.</param>
        /// <returns>This expression if no children changed, or an expression with the updated children.</returns>
        public PropertyCSharpSubpattern Update(CSharpPattern pattern)
        {
            if (pattern == Pattern)
            {
                return(this);
            }

            return(CSharpPattern.PropertySubpattern(pattern, Member, IsLengthOrCount));
        }
Esempio n. 20
0
        // REVIEW: The parameter order is not left-to-right compared to the language grammar.

        /// <summary>
        /// Creates a property subpattern that matches a property or field on an object.
        /// </summary>
        /// <param name="pattern">The pattern to apply to the object in the corresponding position.</param>
        /// <param name="member">The property or field to match on.</param>
        /// <param name="isLengthOrCount">A value indicating whether the member is a length or count property.</param>
        /// <returns>A <see cref="PropertyCSharpSubpattern" /> representing a property subpattern.</returns>
        public static PropertyCSharpSubpattern PropertySubpattern(CSharpPattern pattern, PropertyCSharpSubpatternMember member, bool isLengthOrCount)
        {
            RequiresNotNull(pattern, nameof(pattern));
            RequiresNotNull(member, nameof(member));

            RequiresCompatiblePatternTypes(member.Type, ref pattern);

            return(new PropertyCSharpSubpattern(pattern, member, isLengthOrCount));
        }
        /// <summary>
        /// Changes the input type to the specified type.
        /// </summary>
        /// <remarks>
        /// This functionality can be used when a pattern is pass to an expression or statement that applies the pattern.
        /// </remarks>
        /// <param name="inputType">The new input type.</param>
        /// <returns>The original pattern rewritten to use the specified input type.</returns>
        public override CSharpPattern ChangeType(Type inputType)
        {
            if (inputType == InputType)
            {
                return(this);
            }

            return(CSharpPattern.List(ObjectPatternInfo(PatternInfo(inputType, NarrowedType), Variable), LengthAccess, IndexerAccess, Patterns));
        }
Esempio n. 22
0
        /// <summary>
        /// Creates a new expression that is like this one, but using the supplied children. If all of the children are the same, it will return this expression.
        /// </summary>
        /// <param name="label">The <see cref="Label" /> property of the result.</param>
        /// <param name="pattern">The <see cref="Pattern" /> property of the result.</param>
        /// <param name="whenClause">The <see cref="WhenClause" /> property of the result.</param>
        /// <returns>This expression if no children changed, or an expression with the updated children.</returns>
        public SwitchLabel Update(LabelTarget label, CSharpPattern pattern, Expression whenClause)
        {
            if (label == Label && pattern == Pattern && whenClause == WhenClause)
            {
                return(this);
            }

            return(CSharpExpression.SwitchLabel(label, pattern, whenClause));
        }
        /// <summary>
        /// Changes the input type to the specified type.
        /// </summary>
        /// <remarks>
        /// This functionality can be used when a pattern is pass to an expression or statement that applies the pattern.
        /// </remarks>
        /// <param name="inputType">The new input type.</param>
        /// <returns>The original pattern rewritten to use the specified input type.</returns>
        public override CSharpPattern ChangeType(Type inputType)
        {
            if (inputType == InputType)
            {
                return(this);
            }

            return(CSharpPattern.Constant(PatternInfo(inputType, NarrowedType), Value));
        }
        /// <summary>
        /// Creates a new expression that is like this one, but using the supplied children. If all of the children are the same, it will return this expression.
        /// </summary>
        /// <param name="value">The <see cref="Value" /> property of the result.</param>
        /// <returns>This expression if no children changed, or an expression with the updated children.</returns>
        public ConstantCSharpPattern Update(ConstantExpression value)
        {
            if (value == Value)
            {
                return(this);
            }

            return(CSharpPattern.Constant(_info, value));
        }
Esempio n. 25
0
        /// <summary>
        /// Creates a new expression that is like this one, but using the supplied children. If all of the children are the same, it will return this expression.
        /// </summary>
        /// <param name="pattern">The <see cref="Pattern" /> property of the result.</param>
        /// <returns>This expression if no children changed, or an expression with the updated children.</returns>
        public PositionalCSharpSubpattern Update(CSharpPattern pattern)
        {
            if (pattern == Pattern)
            {
                return(this);
            }

            return(Rewrite(pattern));
        }
        /// <summary>
        /// Creates an <see cref="IsPatternCSharpExpression"/> that represents an is expression using a pattern.
        /// </summary>
        /// <param name="expression">The expression to check using the pattern.</param>
        /// <param name="pattern">The pattern to check.</param>
        /// <returns>The created <see cref="IsPatternCSharpExpression"/>.</returns>
        public static IsPatternCSharpExpression IsPattern(Expression expression, CSharpPattern pattern)
        {
            RequiresCanRead(expression, nameof(expression));

            RequiresNotNull(pattern, nameof(pattern));

            ValidateType(expression.Type);

            return(new IsPatternCSharpExpression(expression, pattern));
        }
        /// <summary>
        /// Changes the input type to the specified type.
        /// </summary>
        /// <remarks>
        /// This functionality can be used when a pattern is pass to an expression or statement that applies the pattern.
        /// </remarks>
        /// <param name="inputType">The new input type.</param>
        /// <returns>The original pattern rewritten to use the specified input type.</returns>
        public override CSharpPattern ChangeType(Type inputType)
        {
            if (inputType == InputType)
            {
                return(this);
            }

            // NB: This can fail if there's a variable and the input type is not compatible. See Var factory.

            return(CSharpPattern.Var(ObjectPatternInfo(PatternInfo(inputType, inputType), Variable)));
        }
Esempio n. 28
0
        /// <summary>
        /// Changes the input type to the specified type.
        /// </summary>
        /// <remarks>
        /// This functionality can be used when a pattern is pass to an expression or statement that applies the pattern.
        /// </remarks>
        /// <param name="inputType">The new input type.</param>
        /// <returns>The original pattern rewritten to use the specified input type.</returns>
        public override CSharpPattern ChangeType(Type inputType)
        {
            if (inputType == InputType)
            {
                return(this);
            }

            var negated = Negated.ChangeType(inputType);

            return(CSharpPattern.Not(info: null, negated));
        }
Esempio n. 29
0
        /// <summary>
        /// Creates a positional subpattern that matches a component of a tuple.
        /// </summary>
        /// <param name="pattern">The pattern to apply to the object in the corresponding position.</param>
        /// <param name="field">The field in the tuple to match.</param>
        /// <returns>A <see cref="PositionalCSharpSubpattern" /> representing a positional subpattern.</returns>
        public static PositionalCSharpSubpattern PositionalSubpattern(CSharpPattern pattern, TupleFieldInfo field)
        {
            RequiresNotNull(pattern, nameof(pattern));
            RequiresNotNull(field, nameof(field));

            if (field.Index < 0)
            {
                throw Error.TupleFieldIndexMustBePositive();
            }

            return(new PositionalCSharpSubpattern.WithField(pattern, field));
        }
 private static void ParenthesizedVisit(this ICSharpPrintingVisitor visitor, CSharpPattern parent, CSharpPattern nodeToVisit)
 {
     if (nodeToVisit.GetPrecedence() < parent.GetPrecedence())
     {
         visitor.Out("(");
         visitor.Visit(nodeToVisit);
         visitor.Out(")");
     }
     else
     {
         visitor.Visit(nodeToVisit);
     }
 }