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