private ImmutableArray <SymbolDisplayPart> AppendAccessorAttributes( ImmutableArray <SymbolDisplayPart> parts, IMethodSymbol method, string keyword) { ImmutableArray <SymbolDisplayPart> attributeParts = SymbolDeclarationBuilder.GetAttributesParts( method.GetAttributes(), predicate: IsVisibleAttribute, splitAttributes: Options.SplitAttributes, includeAttributeArguments: Options.IncludeAttributeArguments, addNewLine: false); if (attributeParts.Any()) { SymbolDisplayPart part = parts.FirstOrDefault(f => f.IsKeyword(keyword)); Debug.Assert(part.Kind == SymbolDisplayPartKind.Keyword); if (part.Kind == SymbolDisplayPartKind.Keyword) { int index = parts.IndexOf(part); parts = parts.Insert(index, SymbolDisplayPartFactory.Space()); parts = parts.InsertRange(index, attributeParts); } } return(parts); }
private static void AddAccessorAttributes( ImmutableArray <SymbolDisplayPart> .Builder parts, IMethodSymbol methodSymbol, SymbolDisplayFormat format, SymbolDisplayAdditionalOptions additionalOptions, Func <ISymbol, AttributeData, bool> shouldDisplayAttribute) { ImmutableArray <SymbolDisplayPart> attributeParts = GetAttributesParts( methodSymbol, format: format, additionalOptions: additionalOptions, shouldDisplayAttribute: shouldDisplayAttribute, formatAttributes: false); if (attributeParts.Any()) { string keyword = GetKeyword(); SymbolDisplayPart part = parts.FirstOrDefault(f => f.IsKeyword(keyword)); Debug.Assert(part.Kind == SymbolDisplayPartKind.Keyword); if (part.Kind == SymbolDisplayPartKind.Keyword) { int index = parts.IndexOf(part); parts.Insert(index, SymbolDisplayPartFactory.Space()); parts.InsertRange(index, attributeParts); } } string GetKeyword() { switch (methodSymbol.MethodKind) { case MethodKind.EventAdd: return("add"); case MethodKind.EventRemove: return("remove"); case MethodKind.PropertyGet: return("get"); case MethodKind.PropertySet: return("set"); default: throw new InvalidOperationException(); } } }
public static ImmutableArray <SymbolDisplayPart> ToDisplayParts(this ISymbol symbol, SymbolDisplayFormat format, SymbolDisplayAdditionalMemberOptions additionalOptions) { if (additionalOptions == SymbolDisplayAdditionalMemberOptions.None) { return(symbol.ToDisplayParts(format)); } ImmutableArray <SymbolDisplayPart> parts = symbol.ToDisplayParts(format); int length = parts.Length; for (int i = 0; i < length; i++) { SymbolDisplayPart part = parts[i]; switch (part.Kind) { case SymbolDisplayPartKind.Keyword: { switch (part.ToString()) { case "this": { if ((additionalOptions & SymbolDisplayAdditionalMemberOptions.UseItemPropertyName) != 0 && (symbol as IPropertySymbol)?.IsIndexer == true) { parts = parts.Replace(part, SymbolDisplayPartFactory.PropertyName("Item", part.Symbol)); } break; } case "operator": { if ((additionalOptions & SymbolDisplayAdditionalMemberOptions.UseOperatorName) != 0 && symbol is IMethodSymbol methodSymbol && methodSymbol.MethodKind == MethodKind.UserDefinedOperator) { string name = methodSymbol.Name; Debug.Assert(name.StartsWith("op_", StringComparison.Ordinal), name); if (name.StartsWith("op_", StringComparison.Ordinal) && i < length - 2 && parts[i + 1].IsSpace() && parts[i + 2].Kind == SymbolDisplayPartKind.MethodName) { parts = parts.Replace(parts[i + 2], SymbolDisplayPartFactory.MethodName(name.Substring(3), parts[i + 2].Symbol)); parts = parts.RemoveRange(i, 2); length -= 2; } } break; } case "implicit": case "explicit": { if ((additionalOptions & SymbolDisplayAdditionalMemberOptions.UseOperatorName) != 0 && symbol is IMethodSymbol methodSymbol && methodSymbol.MethodKind == MethodKind.Conversion) { string name = methodSymbol.Name; Debug.Assert(name.StartsWith("op_", StringComparison.Ordinal), name); if (name.StartsWith("op_", StringComparison.Ordinal) && i < length - 2 && parts[i + 1].IsSpace() && parts[i + 2].IsKeyword("operator")) { List <SymbolDisplayPart> list = parts.ToList(); list[i + 2] = SymbolDisplayPartFactory.MethodName(name.Substring(3), list[i + 4].Symbol); list.RemoveRange(i, 2); length -= 2; if (i == length - 3 && list[i + 1].IsSpace() && list[i + 2].IsName()) { list.RemoveRange(i + 1, 2); length -= 2; } else if (i < length - 5 && list[i + 1].IsSpace() && list[i + 2].IsName() && list[i + 3].IsPunctuation() && list[i + 4].IsName() && list[i + 5].IsPunctuation()) { list.Insert(i + 5, list[i + 2]); list.Insert(i + 5, SymbolDisplayPartFactory.Text(" to ")); list.RemoveRange(i + 1, 2); length -= 5; } parts = list.ToImmutableArray(); } } break; } } break; } } } return(parts); }
private static void FormatParameters( ISymbol symbol, ImmutableArray <SymbolDisplayPart> .Builder parts, string indentChars) { int parenthesesDepth = 0; int bracesDepth = 0; int bracketsDepth = 0; int angleBracketsDepth = 0; int i = 0; int index = FindParameterListStart(symbol, parts); Debug.Assert(index != -1); if (index == -1) { return; } parts.Insert(index + 1, SymbolDisplayPartFactory.Indentation(indentChars)); parts.Insert(index + 1, SymbolDisplayPartFactory.LineBreak()); i++; while (i < parts.Count) { SymbolDisplayPart part = parts[i]; if (part.Kind == SymbolDisplayPartKind.Punctuation) { switch (part.ToString()) { case ",": { if (((angleBracketsDepth == 0 && parenthesesDepth == 1 && bracesDepth == 0 && bracketsDepth == 0) || (angleBracketsDepth == 0 && parenthesesDepth == 0 && bracesDepth == 0 && bracketsDepth == 1)) && i < parts.Count - 1) { SymbolDisplayPart nextPart = parts[i + 1]; if (nextPart.Kind == SymbolDisplayPartKind.Space) { parts[i + 1] = SymbolDisplayPartFactory.LineBreak(); parts.Insert(i + 2, SymbolDisplayPartFactory.Indentation(indentChars)); } } break; } case "(": { parenthesesDepth++; break; } case ")": { Debug.Assert(parenthesesDepth >= 0); parenthesesDepth--; if (parenthesesDepth == 0 && symbol.IsKind(SymbolKind.Method, SymbolKind.NamedType)) { return; } break; } case "[": { bracketsDepth++; break; } case "]": { Debug.Assert(bracketsDepth >= 0); bracketsDepth--; if (bracketsDepth == 0 && symbol.Kind == SymbolKind.Property) { return; } break; } case "{": { bracesDepth++; break; } case "}": { Debug.Assert(bracesDepth >= 0); bracesDepth--; break; } case "<": { angleBracketsDepth++; break; } case ">": { Debug.Assert(angleBracketsDepth >= 0); angleBracketsDepth--; break; } } } i++; } }
private static void AddParameterAttributes( ImmutableArray <SymbolDisplayPart> .Builder parts, ISymbol symbol, ImmutableArray <IParameterSymbol> parameters, SymbolDisplayFormat format, SymbolDisplayAdditionalOptions additionalOptions, Func <ISymbol, AttributeData, bool> shouldDisplayAttribute) { int i = FindParameterListStart(symbol, parts); if (i == -1) { return; } i++; int parameterIndex = 0; AddParameterAttributes(); int parenthesesDepth = 1; int bracesDepth = 0; int bracketsDepth = 0; int angleBracketsDepth = 0; while (i < parts.Count) { SymbolDisplayPart part = parts[i]; if (part.Kind == SymbolDisplayPartKind.Punctuation) { switch (part.ToString()) { case ",": { if (((angleBracketsDepth == 0 && parenthesesDepth == 1 && bracesDepth == 0 && bracketsDepth == 0) || (angleBracketsDepth == 0 && parenthesesDepth == 0 && bracesDepth == 0 && bracketsDepth == 1)) && i < parts.Count - 1) { SymbolDisplayPart nextPart = parts[i + 1]; if (nextPart.Kind == SymbolDisplayPartKind.Space) { i += 2; parameterIndex++; AddParameterAttributes(); continue; } } break; } case "(": { parenthesesDepth++; break; } case ")": { Debug.Assert(parenthesesDepth >= 0); parenthesesDepth--; if (parenthesesDepth == 0 && symbol.IsKind(SymbolKind.Method, SymbolKind.NamedType)) { return; } break; } case "[": { bracketsDepth++; break; } case "]": { Debug.Assert(bracketsDepth >= 0); bracketsDepth--; if (bracketsDepth == 0 && symbol.Kind == SymbolKind.Property) { return; } break; } case "{": { bracesDepth++; break; } case "}": { Debug.Assert(bracesDepth >= 0); bracesDepth--; break; } case "<": { angleBracketsDepth++; break; } case ">": { Debug.Assert(angleBracketsDepth >= 0); angleBracketsDepth--; break; } } } i++; } void AddParameterAttributes() { IParameterSymbol parameter = parameters[parameterIndex]; ImmutableArray <SymbolDisplayPart> attributeParts = GetAttributesParts( parameter, format, additionalOptions, shouldDisplayAttribute: shouldDisplayAttribute); if (attributeParts.Any()) { parts.Insert(i, SymbolDisplayPartFactory.Space()); parts.InsertRange(i, attributeParts); i += attributeParts.Length + 1; } } }
private static void AddKeyword(this ImmutableArray <SymbolDisplayPart> .Builder builder, string text) { builder.Add(SymbolDisplayPartFactory.Keyword(text)); }
private static void AddPunctuation(this ImmutableArray <SymbolDisplayPart> .Builder builder, string text) { builder.Add(SymbolDisplayPartFactory.Punctuation(text)); }
private static void AddLineBreak(this ImmutableArray <SymbolDisplayPart> .Builder builder) { builder.Add(SymbolDisplayPartFactory.LineBreak()); }
private static void AddIndentation(this ImmutableArray <SymbolDisplayPart> .Builder builder) { builder.Add(SymbolDisplayPartFactory.Indentation()); }
private static void AddSpace(this ImmutableArray <SymbolDisplayPart> .Builder builder) { builder.Add(SymbolDisplayPartFactory.Space()); }
private ImmutableArray <SymbolDisplayPart> AppendParameterAttributes( ImmutableArray <SymbolDisplayPart> parts, ISymbol symbol, ImmutableArray <IParameterSymbol> parameters) { int i = SymbolDeclarationBuilder.FindParameterListStart(symbol, parts); if (i == -1) { return(parts); } int parameterIndex = 0; IParameterSymbol parameter = parameters[parameterIndex]; ImmutableArray <SymbolDisplayPart> attributeParts = SymbolDeclarationBuilder.GetAttributesParts( parameter.GetAttributes(), predicate: IsVisibleAttribute, splitAttributes: Options.SplitAttributes, includeAttributeArguments: Options.IncludeAttributeArguments, addNewLine: false); if (attributeParts.Any()) { parts = parts.Insert(i + 1, SymbolDisplayPartFactory.Space()); parts = parts.InsertRange(i + 1, attributeParts); } int parenthesesDepth = 0; int bracesDepth = 0; int bracketsDepth = 0; int angleBracketsDepth = 0; ImmutableArray <SymbolDisplayPart> .Builder builder = null; int prevIndex = 0; AddParameterAttributes(); if (builder != null) { while (prevIndex < parts.Length) { builder.Add(parts[prevIndex]); prevIndex++; } return(builder.ToImmutableArray()); } return(parts); void AddParameterAttributes() { while (i < parts.Length) { SymbolDisplayPart part = parts[i]; if (part.Kind == SymbolDisplayPartKind.Punctuation) { switch (part.ToString()) { case ",": { if (((angleBracketsDepth == 0 && parenthesesDepth == 1 && bracesDepth == 0 && bracketsDepth == 0) || (angleBracketsDepth == 0 && parenthesesDepth == 0 && bracesDepth == 0 && bracketsDepth == 1)) && i < parts.Length - 1) { SymbolDisplayPart nextPart = parts[i + 1]; if (nextPart.Kind == SymbolDisplayPartKind.Space) { parameterIndex++; attributeParts = SymbolDeclarationBuilder.GetAttributesParts( parameters[parameterIndex].GetAttributes(), predicate: IsVisibleAttribute, splitAttributes: Options.SplitAttributes, includeAttributeArguments: Options.IncludeAttributeArguments, addNewLine: false); if (attributeParts.Any()) { if (builder == null) { builder = ImmutableArray.CreateBuilder <SymbolDisplayPart>(); builder.AddRange(parts, i + 1); } else { for (int j = prevIndex; j <= i; j++) { builder.Add(parts[j]); } } builder.Add(SymbolDisplayPartFactory.Space()); builder.AddRange(attributeParts); prevIndex = i + 1; } } } break; } case "(": { parenthesesDepth++; break; } case ")": { Debug.Assert(parenthesesDepth >= 0); parenthesesDepth--; if (parenthesesDepth == 0 && symbol.IsKind(SymbolKind.Method, SymbolKind.NamedType)) { return; } break; } case "[": { bracketsDepth++; break; } case "]": { Debug.Assert(bracketsDepth >= 0); bracketsDepth--; if (bracketsDepth == 0 && symbol.Kind == SymbolKind.Property) { return; } break; } case "{": { bracesDepth++; break; } case "}": { Debug.Assert(bracesDepth >= 0); bracesDepth--; break; } case "<": { angleBracketsDepth++; break; } case ">": { Debug.Assert(angleBracketsDepth >= 0); angleBracketsDepth--; break; } } } i++; } } }
public static ImmutableArray <SymbolDisplayPart> ToDisplayParts(this INamedTypeSymbol typeSymbol, SymbolDisplayFormat format, SymbolDisplayTypeDeclarationOptions typeDeclarationOptions) { if (typeDeclarationOptions == SymbolDisplayTypeDeclarationOptions.None) { return(typeSymbol.ToDisplayParts(format)); } ImmutableArray <SymbolDisplayPart> parts = typeSymbol.ToDisplayParts(format); ImmutableArray <SymbolDisplayPart> .Builder builder = ImmutableArray.CreateBuilder <SymbolDisplayPart>(parts.Length); if ((typeDeclarationOptions & SymbolDisplayTypeDeclarationOptions.IncludeAccessibility) != 0) { switch (typeSymbol.DeclaredAccessibility) { case Accessibility.Public: { AddKeyword(SyntaxKind.PublicKeyword); break; } case Accessibility.ProtectedOrInternal: { AddKeyword(SyntaxKind.ProtectedKeyword); AddKeyword(SyntaxKind.InternalKeyword); break; } case Accessibility.Internal: { AddKeyword(SyntaxKind.InternalKeyword); break; } case Accessibility.Protected: { AddKeyword(SyntaxKind.ProtectedKeyword); break; } case Accessibility.ProtectedAndInternal: { AddKeyword(SyntaxKind.PrivateKeyword); AddKeyword(SyntaxKind.ProtectedKeyword); break; } case Accessibility.Private: { AddKeyword(SyntaxKind.PrivateKeyword); break; } default: { throw new InvalidOperationException(); } } } if ((typeDeclarationOptions & SymbolDisplayTypeDeclarationOptions.IncludeModifiers) != 0) { if (typeSymbol.IsStatic) { AddKeyword(SyntaxKind.StaticKeyword); } if (typeSymbol.IsSealed && !typeSymbol.TypeKind.Is(TypeKind.Struct, TypeKind.Enum, TypeKind.Delegate)) { AddKeyword(SyntaxKind.SealedKeyword); } if (typeSymbol.IsAbstract && typeSymbol.TypeKind != TypeKind.Interface) { AddKeyword(SyntaxKind.AbstractKeyword); } } builder.AddRange(parts); return(builder.ToImmutableArray()); void AddKeyword(SyntaxKind kind) { builder.Add(SymbolDisplayPartFactory.Keyword(SyntaxFacts.GetText(kind))); AddSpace(); } void AddSpace() { builder.Add(SymbolDisplayPartFactory.Space()); } }