diff --git a/src/VaVare.Tests/Statements/SelectionStatementTests.cs b/src/VaVare.Tests/Statements/SelectionStatementTests.cs
index e4bb632..3bb5c36 100644
--- a/src/VaVare.Tests/Statements/SelectionStatementTests.cs
+++ b/src/VaVare.Tests/Statements/SelectionStatementTests.cs
@@ -1,7 +1,10 @@
-using NUnit.Framework;
+using Microsoft.CodeAnalysis.CSharp;
+using Microsoft.CodeAnalysis.CSharp.Syntax;
+using NUnit.Framework;
using VaVare.Generators.Common;
using VaVare.Generators.Common.Arguments.ArgumentTypes;
using VaVare.Generators.Common.BinaryExpressions;
+using VaVare.Generators.Common.Patterns;
using VaVare.Models.References;
using VaVare.Statements;
using Assert = NUnit.Framework.Assert;
@@ -106,5 +109,91 @@ public void If_WhenCreatingAnIfWithBinaryExpressionAndExpressionStatement_Should
Assert.AreEqual("if(2==3)MyMethod();",
conditional.If(new ConditionalBinaryExpression(new ConstantReference(2), new ConstantReference(3), ConditionalStatements.Equal), Statement.Expression.Invoke("MyMethod").AsStatement()).ToString());
}
+
+ [Test]
+ public void If_ConditionalIsExpression()
+ {
+ var expected = "if(a is string){}".Replace(" ", "");
+ var sut = conditional.If(new ValueArgument("a", false), new ValueArgument("string", false), ConditionalStatements.Is, BodyGenerator.Create());
+
+ Assert.That(sut.ToFullString(), Is.EqualTo(expected));
+ }
+
+ [Test]
+ public void If_DeclarationPattern()
+ {
+ var expected = "if(a is string b){}".Replace(" ", "");
+
+ var declarationPattern = new DeclarationPattern(SyntaxFactory.ParseTypeName("string"), "b");
+ var sut = conditional.If(new ValueArgument("a", false), declarationPattern, BodyGenerator.Create());
+
+ Assert.That(sut.ToFullString(), Is.EqualTo(expected));
+ }
+
+ [Test]
+ public void If_NotTypePattern()
+ {
+ var expected = "if(a is not string){}".Replace(" ", "");
+
+ var typePattern = new TypePattern(SyntaxFactory.ParseTypeName("string"));
+ var pattern = new NotPattern(typePattern);
+ var sut = conditional.If(new ValueArgument("a", false), pattern, BodyGenerator.Create());
+
+ Assert.That(sut.ToFullString(), Is.EqualTo(expected));
+ }
+
+ [Test]
+ public void If_NotConstantPattern()
+ {
+ var expected = "if(a is not 12){}".Replace(" ", "");
+
+ var typePattern = new ConstantPattern(new ValueArgument(12));
+ var pattern = new NotPattern(typePattern);
+ var sut = conditional.If(new ValueArgument("a", false), pattern, BodyGenerator.Create());
+
+ Assert.That(sut.ToFullString(), Is.EqualTo(expected));
+ }
+
+ [Test]
+ public void If_NotAndRelationalPattern()
+ {
+ var expected = "if(a is not 12 and > 15){}".Replace(" ", "");
+
+ var typePattern = new ConstantPattern(new ValueArgument(12));
+ var relationPattern = new RelationalPattern(ConditionalStatements.GreaterThan, new ValueArgument(15));
+ var and = new AndPattern(typePattern, relationPattern);
+ var pattern = new NotPattern(and);
+ var sut = conditional.If(new ValueArgument("a", false), pattern, BodyGenerator.Create());
+
+ Assert.That(sut.ToFullString(), Is.EqualTo(expected));
+ }
+
+ [Test]
+ public void If_NotAndRelationalPatternGreaterEquals()
+ {
+ var expected = "if(a is not 12 and >= 15){}".Replace(" ", "");
+
+ var typePattern = new ConstantPattern(new ValueArgument(12));
+ var relationPattern = new RelationalPattern(ConditionalStatements.GreaterThanOrEqual, new ValueArgument(15));
+ var and = new AndPattern(typePattern, relationPattern);
+ var pattern = new NotPattern(and);
+ var sut = conditional.If(new ValueArgument("a", false), pattern, BodyGenerator.Create());
+
+ Assert.That(sut.ToFullString(), Is.EqualTo(expected));
+ }
+
+ [Test]
+ public void If_NotOrRelationalPatternGreaterEquals()
+ {
+ var expected = "if(a is not 12 or >= 15){}".Replace(" ", "");
+
+ var typePattern = new ConstantPattern(new ValueArgument(12));
+ var relationPattern = new RelationalPattern(ConditionalStatements.GreaterThanOrEqual, new ValueArgument(15));
+ var and = new OrPattern(typePattern, relationPattern);
+ var pattern = new NotPattern(and);
+ var sut = conditional.If(new ValueArgument("a", false), pattern, BodyGenerator.Create());
+
+ Assert.That(sut.ToFullString(), Is.EqualTo(expected));
+ }
}
}
diff --git a/src/VaVare/Enums.cs b/src/VaVare/Enums.cs
index 613802d..bf833de 100644
--- a/src/VaVare/Enums.cs
+++ b/src/VaVare/Enums.cs
@@ -36,6 +36,11 @@ public enum ConditionalStatements
/// Generate with a less than or equal conditional statement: "<=".
///
LessThanOrEqual,
+
+ ///
+ /// Generate with an is statement: "is".
+ ///
+ Is,
}
///
diff --git a/src/VaVare/Factories/ConditionalFactory.cs b/src/VaVare/Factories/ConditionalFactory.cs
index 9bd7f1a..ab970ff 100644
--- a/src/VaVare/Factories/ConditionalFactory.cs
+++ b/src/VaVare/Factories/ConditionalFactory.cs
@@ -21,6 +21,29 @@ public static SyntaxKind GetSyntaxKind(ConditionalStatements conditional)
return SyntaxKind.LessThanExpression;
case ConditionalStatements.LessThanOrEqual:
return SyntaxKind.LessThanOrEqualExpression;
+ case ConditionalStatements.Is:
+ return SyntaxKind.IsExpression;
+ default:
+ throw new ArgumentOutOfRangeException(nameof(conditional), conditional, null);
+ }
+ }
+
+ public static SyntaxKind GetSyntaxKindToken(ConditionalStatements conditional)
+ {
+ switch (conditional)
+ {
+ case ConditionalStatements.Equal:
+ return SyntaxKind.EqualsToken;
+ case ConditionalStatements.NotEqual:
+ return SyntaxKind.ExclamationEqualsToken;
+ case ConditionalStatements.GreaterThan:
+ return SyntaxKind.GreaterThanToken;
+ case ConditionalStatements.GreaterThanOrEqual:
+ return SyntaxKind.GreaterThanEqualsToken;
+ case ConditionalStatements.LessThan:
+ return SyntaxKind.LessThanToken;
+ case ConditionalStatements.LessThanOrEqual:
+ return SyntaxKind.LessThanEqualsToken;
default:
throw new ArgumentOutOfRangeException(nameof(conditional), conditional, null);
}
diff --git a/src/VaVare/Generators/Common/PatternExpressions/IPatternExpression.cs b/src/VaVare/Generators/Common/PatternExpressions/IPatternExpression.cs
new file mode 100644
index 0000000..79750f7
--- /dev/null
+++ b/src/VaVare/Generators/Common/PatternExpressions/IPatternExpression.cs
@@ -0,0 +1,13 @@
+using Microsoft.CodeAnalysis.CSharp.Syntax;
+
+namespace VaVare.Generators.Common.PatternExpressions
+{
+ public interface IPatternExpression
+ {
+ ///
+ /// Get the generated pattern expression.
+ ///
+ /// The generated pattern expression.
+ ExpressionSyntax GetPatternExpression();
+ }
+}
diff --git a/src/VaVare/Generators/Common/PatternExpressions/IsPatternExpression.cs b/src/VaVare/Generators/Common/PatternExpressions/IsPatternExpression.cs
new file mode 100644
index 0000000..82f9305
--- /dev/null
+++ b/src/VaVare/Generators/Common/PatternExpressions/IsPatternExpression.cs
@@ -0,0 +1,23 @@
+using Microsoft.CodeAnalysis.CSharp.Syntax;
+
+using static Microsoft.CodeAnalysis.CSharp.SyntaxFactory;
+
+namespace VaVare.Generators.Common.PatternExpressions
+{
+ public class IsPatternExpression : IPatternExpression
+ {
+ private readonly ExpressionSyntax _expressionSyntax;
+ private readonly PatternSyntax _patternSyntax;
+
+ public IsPatternExpression(ExpressionSyntax expressionSyntax, PatternSyntax patternSyntax)
+ {
+ _expressionSyntax = expressionSyntax;
+ _patternSyntax = patternSyntax;
+ }
+
+ public ExpressionSyntax GetPatternExpression()
+ {
+ return IsPatternExpression(_expressionSyntax, _patternSyntax);
+ }
+ }
+}
diff --git a/src/VaVare/Generators/Common/Patterns/AndPattern.cs b/src/VaVare/Generators/Common/Patterns/AndPattern.cs
new file mode 100644
index 0000000..01fb296
--- /dev/null
+++ b/src/VaVare/Generators/Common/Patterns/AndPattern.cs
@@ -0,0 +1,30 @@
+using Microsoft.CodeAnalysis.CSharp;
+using Microsoft.CodeAnalysis.CSharp.Syntax;
+
+using static Microsoft.CodeAnalysis.CSharp.SyntaxFactory;
+
+namespace VaVare.Generators.Common.Patterns
+{
+ public class AndPattern : Pattern
+ {
+ private readonly PatternSyntax _left;
+ private readonly PatternSyntax _right;
+
+ public AndPattern(PatternSyntax left, PatternSyntax right)
+ {
+ _left = left;
+ _right = right;
+ }
+
+ public AndPattern(Pattern left, Pattern right)
+ {
+ _left = left.GetPatternSyntax();
+ _right = right.GetPatternSyntax();
+ }
+
+ public override PatternSyntax GetPatternSyntax()
+ {
+ return BinaryPattern(SyntaxKind.AndPattern, _left, _right);
+ }
+ }
+}
diff --git a/src/VaVare/Generators/Common/Patterns/ConstantPattern.cs b/src/VaVare/Generators/Common/Patterns/ConstantPattern.cs
new file mode 100644
index 0000000..fbcadaa
--- /dev/null
+++ b/src/VaVare/Generators/Common/Patterns/ConstantPattern.cs
@@ -0,0 +1,26 @@
+using Microsoft.CodeAnalysis.CSharp.Syntax;
+using VaVare.Generators.Common.Arguments.ArgumentTypes;
+using static Microsoft.CodeAnalysis.CSharp.SyntaxFactory;
+
+namespace VaVare.Generators.Common.Patterns
+{
+ public class ConstantPattern : Pattern
+ {
+ private readonly ExpressionSyntax _expressionSyntax;
+
+ public ConstantPattern(ExpressionSyntax expression)
+ {
+ _expressionSyntax = expression;
+ }
+
+ public ConstantPattern(IArgument argument)
+ {
+ _expressionSyntax = argument.GetArgumentSyntax().Expression;
+ }
+
+ public override PatternSyntax GetPatternSyntax()
+ {
+ return ConstantPattern(_expressionSyntax);
+ }
+ }
+}
diff --git a/src/VaVare/Generators/Common/Patterns/DeclarationPattern.cs b/src/VaVare/Generators/Common/Patterns/DeclarationPattern.cs
new file mode 100644
index 0000000..8642fb5
--- /dev/null
+++ b/src/VaVare/Generators/Common/Patterns/DeclarationPattern.cs
@@ -0,0 +1,37 @@
+using Microsoft.CodeAnalysis;
+using Microsoft.CodeAnalysis.CSharp.Syntax;
+using VaVare.Factories;
+using VaVare.Generators.Common.Arguments.ArgumentTypes;
+using static Microsoft.CodeAnalysis.CSharp.SyntaxFactory;
+
+namespace VaVare.Generators.Common.Patterns
+{
+ public class DeclarationPattern : Pattern
+ {
+ private readonly TypeSyntax _typeSyntax;
+ private readonly VariableDesignationSyntax _variableDesignationSyntax;
+
+ public DeclarationPattern(TypeSyntax syntaxToken, VariableDesignationSyntax expressionSyntax)
+ {
+ _typeSyntax = syntaxToken;
+ _variableDesignationSyntax = expressionSyntax;
+ }
+
+ public DeclarationPattern(TypeSyntax syntaxToken, string identifier)
+ {
+ _typeSyntax = syntaxToken;
+ _variableDesignationSyntax = SingleVariableDesignation(Identifier(identifier));
+ }
+
+ public DeclarationPattern(TypeSyntax syntaxToken, SyntaxToken identifier)
+ {
+ _typeSyntax = syntaxToken;
+ _variableDesignationSyntax = SingleVariableDesignation(identifier);
+ }
+
+ public override PatternSyntax GetPatternSyntax()
+ {
+ return DeclarationPattern(_typeSyntax, _variableDesignationSyntax);
+ }
+ }
+}
diff --git a/src/VaVare/Generators/Common/Patterns/DiscardPattern.cs b/src/VaVare/Generators/Common/Patterns/DiscardPattern.cs
new file mode 100644
index 0000000..6420bd5
--- /dev/null
+++ b/src/VaVare/Generators/Common/Patterns/DiscardPattern.cs
@@ -0,0 +1,13 @@
+using Microsoft.CodeAnalysis.CSharp.Syntax;
+using static Microsoft.CodeAnalysis.CSharp.SyntaxFactory;
+
+namespace VaVare.Generators.Common.Patterns
+{
+ public class DiscardPattern : Pattern
+ {
+ public override PatternSyntax GetPatternSyntax()
+ {
+ return DiscardPattern();
+ }
+ }
+}
diff --git a/src/VaVare/Generators/Common/Patterns/IPattern.cs b/src/VaVare/Generators/Common/Patterns/IPattern.cs
new file mode 100644
index 0000000..4fbbc5d
--- /dev/null
+++ b/src/VaVare/Generators/Common/Patterns/IPattern.cs
@@ -0,0 +1,9 @@
+using Microsoft.CodeAnalysis.CSharp.Syntax;
+
+namespace VaVare.Generators.Common.Patterns
+{
+ public interface IPattern
+ {
+ PatternSyntax GetPatternSyntax();
+ }
+}
diff --git a/src/VaVare/Generators/Common/Patterns/NotPattern.cs b/src/VaVare/Generators/Common/Patterns/NotPattern.cs
new file mode 100644
index 0000000..e827d46
--- /dev/null
+++ b/src/VaVare/Generators/Common/Patterns/NotPattern.cs
@@ -0,0 +1,28 @@
+using Microsoft.CodeAnalysis;
+using Microsoft.CodeAnalysis.CSharp.Syntax;
+using VaVare.Factories;
+using VaVare.Generators.Common.Arguments.ArgumentTypes;
+using static Microsoft.CodeAnalysis.CSharp.SyntaxFactory;
+
+namespace VaVare.Generators.Common.Patterns
+{
+ public class NotPattern : Pattern
+ {
+ private readonly PatternSyntax _pattern;
+
+ public NotPattern(PatternSyntax pattern)
+ {
+ _pattern = pattern;
+ }
+
+ public NotPattern(Pattern pattern)
+ {
+ _pattern = pattern.GetPatternSyntax();
+ }
+
+ public override PatternSyntax GetPatternSyntax()
+ {
+ return UnaryPattern(_pattern);
+ }
+ }
+}
diff --git a/src/VaVare/Generators/Common/Patterns/OrPattern.cs b/src/VaVare/Generators/Common/Patterns/OrPattern.cs
new file mode 100644
index 0000000..798fb70
--- /dev/null
+++ b/src/VaVare/Generators/Common/Patterns/OrPattern.cs
@@ -0,0 +1,30 @@
+using Microsoft.CodeAnalysis.CSharp;
+using Microsoft.CodeAnalysis.CSharp.Syntax;
+
+using static Microsoft.CodeAnalysis.CSharp.SyntaxFactory;
+
+namespace VaVare.Generators.Common.Patterns
+{
+ public class OrPattern : Pattern
+ {
+ private readonly PatternSyntax _left;
+ private readonly PatternSyntax _right;
+
+ public OrPattern(PatternSyntax left, PatternSyntax right)
+ {
+ _left = left;
+ _right = right;
+ }
+
+ public OrPattern(Pattern left, Pattern right)
+ {
+ _left = left.GetPatternSyntax();
+ _right = right.GetPatternSyntax();
+ }
+
+ public override PatternSyntax GetPatternSyntax()
+ {
+ return BinaryPattern(SyntaxKind.OrPattern, _left, _right);
+ }
+ }
+}
diff --git a/src/VaVare/Generators/Common/Patterns/Pattern.cs b/src/VaVare/Generators/Common/Patterns/Pattern.cs
new file mode 100644
index 0000000..3ddbde5
--- /dev/null
+++ b/src/VaVare/Generators/Common/Patterns/Pattern.cs
@@ -0,0 +1,19 @@
+using Microsoft.CodeAnalysis.CSharp.Syntax;
+
+namespace VaVare.Generators.Common.Patterns
+{
+ ///
+ /// Provides the base class from which the classes that represent pattern derived.
+ ///
+ public abstract class Pattern : IPattern
+ {
+ ///
+ /// Initializes a new instance of the class.
+ ///
+ protected Pattern()
+ {
+ }
+
+ public abstract PatternSyntax GetPatternSyntax();
+ }
+}
diff --git a/src/VaVare/Generators/Common/Patterns/RelationalPattern.cs b/src/VaVare/Generators/Common/Patterns/RelationalPattern.cs
new file mode 100644
index 0000000..f0c2b9a
--- /dev/null
+++ b/src/VaVare/Generators/Common/Patterns/RelationalPattern.cs
@@ -0,0 +1,37 @@
+using Microsoft.CodeAnalysis;
+using Microsoft.CodeAnalysis.CSharp.Syntax;
+using VaVare.Factories;
+using VaVare.Generators.Common.Arguments.ArgumentTypes;
+using static Microsoft.CodeAnalysis.CSharp.SyntaxFactory;
+
+namespace VaVare.Generators.Common.Patterns
+{
+ public class RelationalPattern : Pattern
+ {
+ private readonly SyntaxToken _syntaxToken;
+ private readonly ExpressionSyntax _expressionSyntax;
+
+ public RelationalPattern(SyntaxToken syntaxToken, ExpressionSyntax expressionSyntax)
+ {
+ _syntaxToken = syntaxToken;
+ _expressionSyntax = expressionSyntax;
+ }
+
+ public RelationalPattern(ConditionalStatements conditionalStatement, ExpressionSyntax expressionSyntax)
+ {
+ _syntaxToken = Token(ConditionalFactory.GetSyntaxKindToken(conditionalStatement));
+ _expressionSyntax = expressionSyntax;
+ }
+
+ public RelationalPattern(ConditionalStatements conditionalStatement, IArgument argument)
+ {
+ _syntaxToken = Token(ConditionalFactory.GetSyntaxKindToken(conditionalStatement));
+ _expressionSyntax = argument.GetArgumentSyntax().Expression;
+ }
+
+ public override PatternSyntax GetPatternSyntax()
+ {
+ return RelationalPattern(_syntaxToken, _expressionSyntax);
+ }
+ }
+}
diff --git a/src/VaVare/Generators/Common/Patterns/TypePattern.cs b/src/VaVare/Generators/Common/Patterns/TypePattern.cs
new file mode 100644
index 0000000..59560cb
--- /dev/null
+++ b/src/VaVare/Generators/Common/Patterns/TypePattern.cs
@@ -0,0 +1,20 @@
+using Microsoft.CodeAnalysis.CSharp.Syntax;
+using static Microsoft.CodeAnalysis.CSharp.SyntaxFactory;
+
+namespace VaVare.Generators.Common.Patterns
+{
+ public class TypePattern : Pattern
+ {
+ private readonly TypeSyntax _typeSyntax;
+
+ public TypePattern(TypeSyntax typeSyntax)
+ {
+ _typeSyntax = typeSyntax;
+ }
+
+ public override PatternSyntax GetPatternSyntax()
+ {
+ return TypePattern(_typeSyntax);
+ }
+ }
+}
diff --git a/src/VaVare/Statements/SelectionStatement.cs b/src/VaVare/Statements/SelectionStatement.cs
index c0a9bc4..daed45e 100644
--- a/src/VaVare/Statements/SelectionStatement.cs
+++ b/src/VaVare/Statements/SelectionStatement.cs
@@ -3,6 +3,8 @@
using VaVare.Factories;
using VaVare.Generators.Common.Arguments.ArgumentTypes;
using VaVare.Generators.Common.BinaryExpressions;
+using VaVare.Generators.Common.PatternExpressions;
+using VaVare.Generators.Common.Patterns;
using static Microsoft.CodeAnalysis.CSharp.SyntaxFactory;
namespace VaVare.Statements
@@ -70,6 +72,60 @@ public StatementSyntax If(IArgument leftArgument, IArgument rightArgument, Condi
expressionStatement);
}
+ ///
+ /// Create the statement syntax for a if-conditional with a single statement.
+ ///
+ /// The left argument of the if-statement.
+ /// The right pattern of the if-statement.
+ /// Statement inside the if.
+ /// The declared statement syntax.
+ public StatementSyntax If(IArgument leftArgument, IPattern pattern, ExpressionStatementSyntax expressionStatement)
+ {
+ if (leftArgument == null)
+ {
+ throw new ArgumentNullException(nameof(leftArgument));
+ }
+
+ if (pattern == null)
+ {
+ throw new ArgumentNullException(nameof(pattern));
+ }
+
+ return
+ IfStatement(
+ IsPatternExpression(
+ leftArgument.GetArgumentSyntax().Expression,
+ pattern.GetPatternSyntax()),
+ expressionStatement);
+ }
+
+ ///
+ /// Create the statement syntax for a if-conditional with a single statement.
+ ///
+ /// The left argument of the if-statement.
+ /// The right pattern of the if-statement.
+ /// The block containing all statements.
+ /// The declared statement syntax.
+ public StatementSyntax If(IArgument leftArgument, IPattern pattern, BlockSyntax block)
+ {
+ if (leftArgument == null)
+ {
+ throw new ArgumentNullException(nameof(leftArgument));
+ }
+
+ if (pattern == null)
+ {
+ throw new ArgumentNullException(nameof(pattern));
+ }
+
+ return
+ IfStatement(
+ IsPatternExpression(
+ leftArgument.GetArgumentSyntax().Expression,
+ pattern.GetPatternSyntax()),
+ block);
+ }
+
///
/// Create the statement syntax for a if-conditional.
///
@@ -83,7 +139,23 @@ public StatementSyntax If(IBinaryExpression binaryExpression, BlockSyntax block)
throw new ArgumentNullException(nameof(binaryExpression));
}
- return IfStatement(binaryExpression.GetBinaryExpression(), block);
+ return IfStatement(binaryExpression.GetBinaryExpression(), block);
+ }
+
+ ///
+ /// Create the statement syntax for a if-conditional with pattern.
+ ///
+ /// The pattern expression to generate.
+ /// The block containing all statements.
+ /// The declared statement syntax.
+ public StatementSyntax If(IPatternExpression patternExpression, BlockSyntax block)
+ {
+ if (patternExpression == null)
+ {
+ throw new ArgumentNullException(nameof(patternExpression));
+ }
+
+ return IfStatement(patternExpression.GetPatternExpression(), block);
}
///
@@ -101,5 +173,21 @@ public StatementSyntax If(IBinaryExpression binaryExpression, ExpressionStatemen
return IfStatement(binaryExpression.GetBinaryExpression(), expressionStatement);
}
+
+ ///
+ /// Create the statement syntax for a if-conditional with a single statement and a pattern expression.
+ ///
+ /// The pattern expression to generate.
+ /// Statement inside the if.
+ /// The declared statement syntax.
+ public StatementSyntax If(IPatternExpression patternExpression, ExpressionStatementSyntax expressionStatement)
+ {
+ if (patternExpression == null)
+ {
+ throw new ArgumentNullException(nameof(patternExpression));
+ }
+
+ return IfStatement(patternExpression.GetPatternExpression(), expressionStatement);
+ }
}
}