File: IncrementalParsing\UnaryExpression.cs
Web Access
Project: src\src\Compilers\CSharp\Test\Syntax\Microsoft.CodeAnalysis.CSharp.Syntax.UnitTests.csproj (Microsoft.CodeAnalysis.CSharp.Syntax.UnitTests)
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
 
#nullable disable
 
using System;
using Microsoft.CodeAnalysis.CSharp.Symbols;
using Microsoft.CodeAnalysis.CSharp.Syntax;
using Microsoft.CodeAnalysis.CSharp.Test.Utilities;
using Microsoft.CodeAnalysis.Text;
using Xunit;
 
namespace Microsoft.CodeAnalysis.CSharp.UnitTests.IncrementalParsing
{
    // These tests handle changing between different unary expressions 
    public class UnaryExpression
    {
        [Fact]
        public void PlusToNegate()
        {
            MakeUnaryChange(SyntaxKind.UnaryPlusExpression, SyntaxKind.UnaryMinusExpression);
        }
 
        [Fact]
        public void PlusToAddressOf()
        {
            MakeUnaryChange(SyntaxKind.UnaryPlusExpression, SyntaxKind.AddressOfExpression);
        }
 
        [Fact]
        public void PlusToBitwiseNot()
        {
            MakeUnaryChange(SyntaxKind.UnaryPlusExpression, SyntaxKind.BitwiseNotExpression);
        }
 
        [Fact]
        public void PlusToLogicalNot()
        {
            MakeUnaryChange(SyntaxKind.UnaryPlusExpression, SyntaxKind.LogicalNotExpression);
        }
 
        [Fact]
        public void PlusToPointerIndirect()
        {
            MakeUnaryChange(SyntaxKind.UnaryPlusExpression, SyntaxKind.PointerIndirectionExpression);
        }
 
        [Fact]
        public void PlusToPreDecrement()
        {
            MakeUnaryChange(SyntaxKind.UnaryPlusExpression, SyntaxKind.PreDecrementExpression);
        }
 
        [Fact]
        public void PlusToPreIncrement()
        {
            MakeUnaryChange(SyntaxKind.UnaryPlusExpression, SyntaxKind.PreIncrementExpression);
        }
 
        #region Helpers
        private static void MakeUnaryChange(SyntaxKind oldStyle, SyntaxKind newStyle)
        {
            MakeUnaryChanges(oldStyle, newStyle);
            MakeUnaryChanges(oldStyle, newStyle, options: TestOptions.Script);
            MakeUnaryChanges(oldStyle, newStyle, topLevel: true, options: TestOptions.Script);
        }
 
        private static void MakeUnaryChanges(SyntaxKind oldSyntaxKind, SyntaxKind newSyntaxKind, bool topLevel = false, CSharpParseOptions options = null)
        {
            string oldName = GetExpressionString(oldSyntaxKind);
            string newName = GetExpressionString(newSyntaxKind);
 
            string topLevelStatement = oldName + " y";
            // Be warned when changing the fields here
            var code = @"class C { void m() {
                 " + topLevelStatement + @";
                }}";
            var oldTree = SyntaxFactory.ParseSyntaxTree(topLevel ? topLevelStatement : code, options: options);
 
            // Make the change to the node
            var newTree = oldTree.WithReplaceFirst(oldName, newName);
            var treeNode = topLevel ? GetGlobalExpressionNode(newTree) : GetExpressionNode(newTree);
            Assert.Equal(treeNode.Kind(), newSyntaxKind);
        }
 
        private static PrefixUnaryExpressionSyntax GetExpressionNode(SyntaxTree newTree)
        {
            var classType = newTree.GetCompilationUnitRoot().Members[0] as TypeDeclarationSyntax;
            var method = classType.Members[0] as MethodDeclarationSyntax;
            var block = method.Body;
            var statement = block.Statements[0] as ExpressionStatementSyntax;
            var expression = statement.Expression as PrefixUnaryExpressionSyntax;
            return expression;
        }
 
        private static PrefixUnaryExpressionSyntax GetGlobalExpressionNode(SyntaxTree newTree)
        {
            var statementType = newTree.GetCompilationUnitRoot().Members[0] as GlobalStatementSyntax;
            Assert.True(statementType.AttributeLists.Count == 0);
            Assert.True(statementType.Modifiers.Count == 0);
            var statement = statementType.Statement as ExpressionStatementSyntax;
            var expression = statement.Expression as PrefixUnaryExpressionSyntax;
            return expression;
        }
 
        private static string GetExpressionString(SyntaxKind oldStyle)
        {
            switch (oldStyle)
            {
                case SyntaxKind.UnaryPlusExpression:
                    return "+";
                case SyntaxKind.UnaryMinusExpression:
                    return "-";
                case SyntaxKind.BitwiseNotExpression:
                    return "~";
                case SyntaxKind.LogicalNotExpression:
                    return "!";
                case SyntaxKind.PreIncrementExpression:
                    return "++";
                case SyntaxKind.PreDecrementExpression:
                    return "--";
                case SyntaxKind.PointerIndirectionExpression:
                    return "*";
                case SyntaxKind.AddressOfExpression:
                    return "&";
                default:
                    throw new Exception("Unexpected case");
            }
        }
        #endregion
    }
}