Example #1
0
        // https://docs.microsoft.com/en-us/dotnet/csharp/language-reference/keywords/default-values-table
        /// <summary>
        /// Creates a new <see cref="ExpressionSyntax"/> that represents default value of the specified type symbol.
        /// </summary>
        /// <param name="typeSymbol"></param>
        /// <param name="options"></param>
        /// <param name="type"></param>
        /// <param name="format"></param>
        public static ExpressionSyntax GetDefaultValueSyntax(
            this ITypeSymbol typeSymbol,
            DefaultSyntaxOptions options = DefaultSyntaxOptions.None,
            TypeSyntax type            = null,
            SymbolDisplayFormat format = null)
        {
            if (typeSymbol == null)
            {
                throw new ArgumentNullException(nameof(typeSymbol));
            }

            if ((options & DefaultSyntaxOptions.UseDefault) != 0)
            {
                return(CreateDefault());
            }

            if (typeSymbol.IsReferenceType ||
                typeSymbol.TypeKind == TypeKind.Pointer ||
                typeSymbol.IsNullableType())
            {
                return(NullLiteralExpression());
            }

            if (typeSymbol.TypeKind == TypeKind.Enum)
            {
                IFieldSymbol fieldSymbol = CSharpUtility.FindEnumDefaultField((INamedTypeSymbol)typeSymbol);

                if (fieldSymbol != null)
                {
                    return(SimpleMemberAccessExpression(GetTypeSyntax(), IdentifierName(fieldSymbol.Name)));
                }

                return(CastExpression(GetTypeSyntax(), NumericLiteralExpression(0)).WithSimplifierAnnotation());
            }

            switch (typeSymbol.SpecialType)
            {
            case SpecialType.System_Boolean:
                return(FalseLiteralExpression());

            case SpecialType.System_Char:
                return(CharacterLiteralExpression('\0'));

            case SpecialType.System_SByte:
            case SpecialType.System_Byte:
            case SpecialType.System_Int16:
            case SpecialType.System_UInt16:
            case SpecialType.System_Int32:
            case SpecialType.System_UInt32:
            case SpecialType.System_Int64:
            case SpecialType.System_UInt64:
            case SpecialType.System_Decimal:
            case SpecialType.System_Single:
            case SpecialType.System_Double:
                return(NumericLiteralExpression(0));
            }

            return(CreateDefault());

            TypeSyntax GetTypeSyntax()
            {
                return(type ?? typeSymbol.ToTypeSyntax(format).WithSimplifierAnnotation());
            }

            ExpressionSyntax CreateDefault()
            {
                if ((options & DefaultSyntaxOptions.AllowDefaultLiteral) != 0)
                {
                    return(DefaultLiteralExpression());
                }

                return(DefaultExpression(GetTypeSyntax()));
            }
        }
Example #2
0
        public static Task <Document> ToMultiLineAsync(
            Document document,
            ExpressionSyntax expression,
            SemanticModel semanticModel,
            CancellationToken cancellationToken = default(CancellationToken))
        {
            SyntaxTrivia trivia = expression.GetIndentation(cancellationToken);

            string indentation = Environment.NewLine + trivia.ToString() + SingleIndentation(trivia).ToString();

            TextChange?       textChange  = null;
            List <TextChange> textChanges = null;

            foreach (SyntaxNode node in CSharpUtility.EnumerateExpressionChain(expression))
            {
                switch (node.Kind())
                {
                case SyntaxKind.SimpleMemberAccessExpression:
                {
                    var memberAccess = (MemberAccessExpressionSyntax)node;

                    if (memberAccess.Expression.IsKind(SyntaxKind.ThisExpression))
                    {
                        break;
                    }

                    if (semanticModel
                        .GetSymbol(memberAccess.Expression, cancellationToken)?
                        .Kind == SymbolKind.Namespace)
                    {
                        break;
                    }

                    AddTextChange(memberAccess.OperatorToken);
                    break;
                }

                case SyntaxKind.MemberBindingExpression:
                {
                    var memberBinding = (MemberBindingExpressionSyntax)node;

                    AddTextChange(memberBinding.OperatorToken);
                    break;
                }
                }
            }

            if (textChanges != null)
            {
                TextChange[] arr = textChanges.ToArray();
                Array.Reverse(arr);
                return(document.WithTextChangesAsync(arr, cancellationToken));
            }
            else
            {
                return(document.WithTextChangeAsync(textChange.Value, cancellationToken));
            }

            void AddTextChange(SyntaxToken operatorToken)
            {
                var tc = new TextChange(new TextSpan(operatorToken.SpanStart, 0), indentation);

                if (textChange == null)
                {
                    textChange = tc;
                }
                else
                {
                    (textChanges ?? (textChanges = new List <TextChange>()
                    {
                        textChange.Value
                    })).Add(tc);
                }
            }
        }