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; }
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 ) ); })); } }
/// <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)); }
/// <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)); }
/// <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)); }
/// <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)); }
/// <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)); }
/// <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)); }
/// <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)); }
// 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)); }
/// <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)); }
/// <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))); }
/// <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)); }
/// <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); } }