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 void AppendAssemblyAttributes(IAssemblySymbol assemblySymbol) { ImmutableArray <AttributeData> attributes = assemblySymbol.GetAttributes(); ImmutableArray <SymbolDisplayPart> attributeParts = SymbolDeclarationBuilder.GetAttributesParts( attributes, IsVisibleAttribute, splitAttributes: Options.SplitAttributes, includeAttributeArguments: Options.IncludeAttributeArguments, isAssemblyAttribute: true); if (attributeParts.Any()) { Append("// "); AppendLine(assemblySymbol.Identity.Name); Append(attributeParts); AppendLine(); } }
private void AppendMembers(INamedTypeSymbol typeModel) { bool isAny = false; using (IEnumerator <ISymbol> en = typeModel.GetMembers().Where(f => IsVisibleMember(f)) .OrderBy(f => f, MemberComparer) .GetEnumerator()) { if (en.MoveNext()) { MemberDeclarationKind kind = MemberDeclarationComparer.GetKind(en.Current); while (true) { ImmutableArray <SymbolDisplayPart> attributeParts = SymbolDeclarationBuilder.GetAttributesParts( en.Current.GetAttributes(), predicate: IsVisibleAttribute, splitAttributes: Options.SplitAttributes, includeAttributeArguments: Options.IncludeAttributeArguments); Append(attributeParts); ImmutableArray <SymbolDisplayPart> parts = en.Current.ToDisplayParts(_memberFormat); //XTODO: attribute on event accessor if (en.Current.Kind == SymbolKind.Property) { var propertySymbol = (IPropertySymbol)en.Current; IMethodSymbol getMethod = propertySymbol.GetMethod; if (getMethod != null) { parts = AppendAccessorAttributes(parts, getMethod, "get"); } IMethodSymbol setMethod = propertySymbol.SetMethod; if (setMethod != null) { parts = AppendAccessorAttributes(parts, setMethod, "set"); } } ImmutableArray <IParameterSymbol> parameters = en.Current.GetParameters(); if (parameters.Any()) { parts = AppendParameterAttributes(parts, en.Current, parameters); if (Options.FormatParameters && parameters.Length > 1) { ImmutableArray <SymbolDisplayPart> .Builder builder = parts.ToBuilder(); SymbolDeclarationBuilder.FormatParameters(en.Current, builder, Options.IndentChars); parts = builder.ToImmutableArray(); } } Append(parts); if (en.Current.Kind != SymbolKind.Property) { Append(";"); } AppendLine(); isAny = true; if (en.MoveNext()) { MemberDeclarationKind kind2 = MemberDeclarationComparer.GetKind(en.Current); if (kind != kind2 || Options.EmptyLineBetweenMembers) { AppendLine(); } kind = kind2; } else { break; } } } } AppendTypes(typeModel.GetTypeMembers().Where(f => IsVisibleType(f)), insertNewLineBeforeFirstType: isAny); }
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++; } } }
private void AppendTypes(IEnumerable <INamedTypeSymbol> types, bool insertNewLineBeforeFirstType = false) { using (IEnumerator <INamedTypeSymbol> en = types.OrderBy(f => f, TypeComparer).GetEnumerator()) { if (en.MoveNext()) { if (insertNewLineBeforeFirstType) { AppendLine(); } while (true) { TypeKind typeKind = en.Current.TypeKind; Append(SymbolDeclarationBuilder.GetDisplayParts( en.Current, _typeFormat, SymbolDisplayTypeDeclarationOptions.IncludeAccessibility | SymbolDisplayTypeDeclarationOptions.IncludeModifiers, isVisibleAttribute: IsVisibleAttribute, formatBaseList: Options.FormatBaseList, formatConstraints: Options.FormatConstraints, formatParameters: Options.FormatParameters, splitAttributes: Options.SplitAttributes, includeAttributeArguments: Options.IncludeAttributeArguments, omitIEnumerable: Options.OmitIEnumerable)); switch (typeKind) { case TypeKind.Class: { BeginTypeContent(); if (Options.Depth == DocumentationDepth.Member) { AppendMembers(en.Current); } EndTypeContent(); break; } case TypeKind.Delegate: { AppendLine(";"); break; } case TypeKind.Enum: { BeginTypeContent(); foreach (ISymbol member in en.Current.GetMembers()) { if (member.Kind == SymbolKind.Field && member.DeclaredAccessibility == Accessibility.Public) { Append(member, _enumFieldFormat); Append(","); AppendLine(); } } EndTypeContent(); break; } case TypeKind.Interface: { BeginTypeContent(); if (Options.Depth == DocumentationDepth.Member) { AppendMembers(en.Current); } EndTypeContent(); break; } case TypeKind.Struct: { BeginTypeContent(); if (Options.Depth == DocumentationDepth.Member) { AppendMembers(en.Current); } EndTypeContent(); break; } } if (en.MoveNext()) { AppendLine(); } else { break; } } } } }