private void DisplayName(CodeFileTokensBuilder builder, ISymbol symbol, ISymbol definedSymbol = null) { foreach (var symbolDisplayPart in symbol.ToDisplayParts(_defaultDisplayFormat)) { builder.Append(MapToken(definedSymbol, symbolDisplayPart)); } }
private void Build(CodeFileTokensBuilder builder, INamespaceSymbol namespaceSymbol, List <NavigationItem> navigationItems) { builder.Keyword(SyntaxKind.NamespaceKeyword); builder.Space(); BuildNamespaceName(builder, namespaceSymbol); builder.Space(); builder.Punctuation(SyntaxKind.OpenBraceToken); builder.IncrementIndent(); builder.NewLine(); List <NavigationItem> namespaceItems = new List <NavigationItem>(); foreach (var namedTypeSymbol in SymbolOrderProvider.OrderTypes(namespaceSymbol.GetTypeMembers())) { BuildType(builder, namedTypeSymbol, namespaceItems); } CloseBrace(builder); var namespaceItem = new NavigationItem() { NavigationId = namespaceSymbol.GetId(), Text = namespaceSymbol.ToDisplayString(), ChildItems = namespaceItems.ToArray(), Tags = { { "TypeKind", "namespace" } } }; navigationItems.Add(namespaceItem); }
private void BuildTypedConstant(CodeFileTokensBuilder builder, TypedConstant typedConstant) { if (typedConstant.IsNull) { builder.Keyword(SyntaxKind.NullKeyword); } else if (typedConstant.Kind == TypedConstantKind.Enum) { new CodeFileBuilderEnumFormatter(builder).Format(typedConstant.Type, typedConstant.Value); } else { if (typedConstant.Value is string s) { builder.Append( ObjectDisplay.FormatLiteral(s, ObjectDisplayOptions.UseQuotes | ObjectDisplayOptions.EscapeNonPrintableCharacters), CodeFileTokenKind.StringLiteral); } else { builder.Append( ObjectDisplay.FormatPrimitive(typedConstant.Value, ObjectDisplayOptions.None), CodeFileTokenKind.Literal); } } }
private void BuildMember(CodeFileTokensBuilder builder, ISymbol member) { BuildAttributes(builder, member.GetAttributes()); builder.WriteIndent(); NodeFromSymbol(builder, member); if (member.Kind == SymbolKind.Method && !member.IsAbstract && member.ContainingType.TypeKind != TypeKind.Interface) { builder.Space(); builder.Punctuation(SyntaxKind.OpenBraceToken); builder.Punctuation(SyntaxKind.CloseBraceToken); } else if (member.Kind == SymbolKind.Field && member.ContainingType.TypeKind == TypeKind.Enum) { builder.Punctuation(SyntaxKind.CommaToken); } else if (member.Kind != SymbolKind.Property) { builder.Punctuation(SyntaxKind.SemicolonToken); } builder.NewLine(); }
public CodeFile Build(IAssemblySymbol assemblySymbol) { var assemblyItems = new List <NavigationItem>(); var builder = new CodeFileTokensBuilder(); foreach (var namespaceSymbol in EnumerateNamespaces(assemblySymbol)) { if (namespaceSymbol.IsGlobalNamespace) { foreach (var namedTypeSymbol in SortTypes(namespaceSymbol.GetTypeMembers())) { BuildType(builder, namedTypeSymbol, assemblyItems); } } else { Build(builder, namespaceSymbol, assemblyItems); } } var node = new CodeFile() { Tokens = builder.Tokens.ToArray(), Version = CodeFile.CurrentVersion, Navigation = assemblyItems, }; return(node); }
private static void CloseBrace(CodeFileTokensBuilder builder) { builder.DecrementIndent(); builder.WriteIndent(); builder.Punctuation(SyntaxKind.CloseBraceToken); builder.NewLine(); }
private void BuildNamespaceName(CodeFileTokensBuilder builder, INamespaceSymbol namespaceSymbol) { if (!namespaceSymbol.ContainingNamespace.IsGlobalNamespace) { BuildNamespaceName(builder, namespaceSymbol.ContainingNamespace); builder.Punctuation(SyntaxKind.DotToken); } NodeFromSymbol(builder, namespaceSymbol); }
private void NodeFromSymbol(CodeFileTokensBuilder builder, ISymbol symbol) { builder.Append(new CodeFileToken() { DefinitionId = symbol.GetId(), Kind = CodeFileTokenKind.LineIdMarker }); DisplayName(builder, symbol, symbol); }
private void BuildType(CodeFileTokensBuilder builder, INamedTypeSymbol namedType, List <NavigationItem> navigationBuilder) { if (!IsAccessible(namedType)) { return; } var navigationItem = new NavigationItem() { NavigationId = GetId(namedType), Text = namedType.ToDisplayString(SymbolDisplayFormat.MinimallyQualifiedFormat), }; navigationBuilder.Add(navigationItem); navigationItem.Tags.Add("TypeKind", "type_" + namedType.TypeKind.ToString().ToLowerInvariant()); builder.WriteIndent(); NodeFromSymbol(builder, namedType, true); if (namedType.TypeKind == TypeKind.Delegate) { builder.Punctuation(SyntaxKind.SemicolonToken); builder.NewLine(); return; } builder.Space(); builder.Punctuation(SyntaxKind.OpenBraceToken); builder.IncrementIndent(); builder.NewLine(); foreach (var namedTypeSymbol in SortTypes(namedType.GetTypeMembers())) { BuildType(builder, namedTypeSymbol, navigationBuilder); } foreach (var member in SortMembers(namedType.GetMembers())) { if (member.Kind == SymbolKind.NamedType || member.IsImplicitlyDeclared || !IsAccessible(member)) { continue; } if (member is IMethodSymbol method) { if (method.MethodKind == MethodKind.PropertyGet || method.MethodKind == MethodKind.PropertySet || method.MethodKind == MethodKind.EventAdd || method.MethodKind == MethodKind.EventRemove || method.MethodKind == MethodKind.EventRaise) { continue; } } BuildMember(builder, member); } CloseBrace(builder); }
private void BuildTypedConstant(CodeFileTokensBuilder builder, TypedConstant typedConstant) { if (typedConstant.IsNull) { builder.Keyword(SyntaxKind.NullKeyword); } else if (typedConstant.Kind == TypedConstantKind.Enum) { new CodeFileBuilderEnumFormatter(builder).Format(typedConstant.Type, typedConstant.Value); } else if (typedConstant.Kind == TypedConstantKind.Type) { builder.Keyword(SyntaxKind.TypeOfKeyword); builder.Punctuation("("); DisplayName(builder, (ITypeSymbol)typedConstant.Value); builder.Punctuation(")"); } else if (typedConstant.Kind == TypedConstantKind.Array) { builder.Keyword(SyntaxKind.NewKeyword); builder.Punctuation("[] {"); bool first = true; foreach (var value in typedConstant.Values) { if (!first) { builder.Punctuation(SyntaxKind.CommaToken); builder.Space(); } else { first = false; } BuildTypedConstant(builder, value); } builder.Punctuation("}"); } else { if (typedConstant.Value is string s) { builder.Append( ObjectDisplay.FormatLiteral(s, ObjectDisplayOptions.UseQuotes | ObjectDisplayOptions.EscapeNonPrintableCharacters), CodeFileTokenKind.StringLiteral); } else { builder.Append( ObjectDisplay.FormatPrimitive(typedConstant.Value, ObjectDisplayOptions.None), CodeFileTokenKind.Literal); } } }
private void DisplayName(CodeFileTokensBuilder builder, ISymbol symbol, ISymbol definedSymbol = null) { if (NeedsAccessibility(symbol)) { builder.Keyword(SyntaxFacts.GetText(ToEffectiveAccessibility(symbol.DeclaredAccessibility))); builder.Space(); } foreach (var symbolDisplayPart in symbol.ToDisplayParts(_defaultDisplayFormat)) { builder.Append(MapToken(definedSymbol, symbolDisplayPart)); } }
public CodeFile Build(IAssemblySymbol assemblySymbol, bool runAnalysis, List <DependencyInfo> dependencies) { _assembly = assemblySymbol; var analyzer = new Analyzer(); if (runAnalysis) { analyzer.VisitAssembly(assemblySymbol); } var builder = new CodeFileTokensBuilder(); BuildDependencies(builder, dependencies); var navigationItems = new List <NavigationItem>(); foreach (var namespaceSymbol in SymbolOrderProvider.OrderNamespaces(EnumerateNamespaces(assemblySymbol))) { if (namespaceSymbol.IsGlobalNamespace) { foreach (var namedTypeSymbol in SymbolOrderProvider.OrderTypes(namespaceSymbol.GetTypeMembers())) { BuildType(builder, namedTypeSymbol, navigationItems); } } else { Build(builder, namespaceSymbol, navigationItems); } } NavigationItem assemblyNavigationItem = new NavigationItem() { Text = assemblySymbol.Name + ".dll", ChildItems = navigationItems.ToArray(), Tags = { { "TypeKind", "assembly" } } }; var node = new CodeFile() { Name = $"{assemblySymbol.Name} ({assemblySymbol.Identity.Version})", Language = "C#", Tokens = builder.Tokens.ToArray(), VersionString = CurrentVersion, Navigation = new[] { assemblyNavigationItem }, Diagnostics = analyzer.Results.ToArray(), PackageName = assemblySymbol.Name }; return(node); }
private void BuildDocumentation(CodeFileTokensBuilder builder, ISymbol symbol) { var lines = symbol.GetDocumentationCommentXml().Trim().Split(_newlineChars); if (lines.All(string.IsNullOrWhiteSpace)) { return; } builder.Append(null, CodeFileTokenKind.DocumentRangeStart); foreach (var line in lines) { builder.WriteIndent(); builder.Comment("// " + line.Trim()); builder.NewLine(); } builder.Append(null, CodeFileTokenKind.DocumentRangeEnd); }
private void NodeFromSymbol(CodeFileTokensBuilder builder, ISymbol symbol, bool prependVisibility = false) { builder.Append(new CodeFileToken() { DefinitionId = GetId(symbol), Kind = CodeFileTokenKind.LineIdMarker }); if (prependVisibility) { builder.Keyword(SyntaxFacts.GetText(ToEffectiveAccessibility(symbol.DeclaredAccessibility))); builder.Space(); } foreach (var symbolDisplayPart in symbol.ToDisplayParts(_defaultDisplayFormat)) { builder.Append(MapToken(symbol, symbolDisplayPart)); } }
private void BuildMember(CodeFileTokensBuilder builder, ISymbol member) { BuildDocumentation(builder, member); BuildAttributes(builder, member.GetAttributes()); builder.WriteIndent(); NodeFromSymbol(builder, member); if (member.Kind == SymbolKind.Field && member.ContainingType.TypeKind == TypeKind.Enum) { builder.Punctuation(SyntaxKind.CommaToken); } else if (member.Kind != SymbolKind.Property) { builder.Punctuation(SyntaxKind.SemicolonToken); } builder.NewLine(); }
private static void BuildClassModifiers(CodeFileTokensBuilder builder, INamedTypeSymbol namedType) { if (namedType.IsAbstract) { builder.Keyword(SyntaxKind.AbstractKeyword); builder.Space(); } if (namedType.IsStatic) { builder.Keyword(SyntaxKind.StaticKeyword); builder.Space(); } if (namedType.IsSealed) { builder.Keyword(SyntaxKind.SealedKeyword); builder.Space(); } }
private void BuildBaseType(CodeFileTokensBuilder builder, INamedTypeSymbol namedType) { bool first = true; if (namedType.BaseType != null && namedType.BaseType.SpecialType == SpecialType.None) { builder.Punctuation(SyntaxKind.ColonToken); builder.Space(); first = false; DisplayName(builder, namedType.BaseType); } foreach (var typeInterface in namedType.Interfaces) { if (!IsAccessible(typeInterface)) { continue; } if (!first) { builder.Punctuation(SyntaxKind.CommaToken); builder.Space(); } else { builder.Punctuation(SyntaxKind.ColonToken); builder.Space(); first = false; } DisplayName(builder, typeInterface); } if (!first) { builder.Space(); } }
public static void BuildDependencies(CodeFileTokensBuilder builder, List <DependencyInfo> dependencies) { if (dependencies != null && dependencies.Any()) { builder.NewLine(); builder.Append("Dependencies:", CodeFileTokenKind.Text); builder.NewLine(); foreach (DependencyInfo dependency in dependencies) { builder.Append(new CodeFileToken(dependency.Name, CodeFileTokenKind.Text) { // allow dependency to be commentable DefinitionId = dependency.Name }); // don't include the version in the API sign-off diffs builder.Append(null, CodeFileTokenKind.SkipDiffRangeStart); builder.Append($"-{dependency.Version}", CodeFileTokenKind.Text); builder.Append(null, CodeFileTokenKind.SkipDiffRangeEnd); builder.NewLine(); } builder.NewLine(); } }
public CodeFileBuilderEnumFormatter(CodeFileTokensBuilder builder) : base(null, SymbolDisplayFormat.FullyQualifiedFormat, false, null, 0, false) { _builder = builder; }
private void BuildVisibility(CodeFileTokensBuilder builder, ISymbol symbol) { builder.Keyword(SyntaxFacts.GetText(ToEffectiveAccessibility(symbol.DeclaredAccessibility))); }
private void BuildType(CodeFileTokensBuilder builder, INamedTypeSymbol namedType, List <NavigationItem> navigationBuilder) { if (!IsAccessible(namedType)) { return; } var navigationItem = new NavigationItem() { NavigationId = namedType.GetId(), Text = namedType.ToDisplayString(SymbolDisplayFormat.MinimallyQualifiedFormat), }; navigationBuilder.Add(navigationItem); navigationItem.Tags.Add("TypeKind", namedType.TypeKind.ToString().ToLowerInvariant()); BuildDocumentation(builder, namedType); BuildAttributes(builder, namedType.GetAttributes()); builder.WriteIndent(); BuildVisibility(builder, namedType); builder.Space(); switch (namedType.TypeKind) { case TypeKind.Class: BuildClassModifiers(builder, namedType); builder.Keyword(SyntaxKind.ClassKeyword); break; case TypeKind.Delegate: builder.Keyword(SyntaxKind.DelegateKeyword); break; case TypeKind.Enum: builder.Keyword(SyntaxKind.EnumKeyword); break; case TypeKind.Interface: builder.Keyword(SyntaxKind.InterfaceKeyword); break; case TypeKind.Struct: if (namedType.IsReadOnly) { builder.Keyword(SyntaxKind.ReadOnlyKeyword); builder.Space(); } builder.Keyword(SyntaxKind.StructKeyword); break; } builder.Space(); NodeFromSymbol(builder, namedType); if (namedType.TypeKind == TypeKind.Delegate) { builder.Punctuation(SyntaxKind.SemicolonToken); builder.NewLine(); return; } builder.Space(); BuildBaseType(builder, namedType); builder.Punctuation(SyntaxKind.OpenBraceToken); builder.IncrementIndent(); builder.NewLine(); foreach (var namedTypeSymbol in SymbolOrderProvider.OrderTypes(namedType.GetTypeMembers())) { BuildType(builder, namedTypeSymbol, navigationBuilder); } foreach (var member in SymbolOrderProvider.OrderMembers(namedType.GetMembers())) { if (member.Kind == SymbolKind.NamedType || member.IsImplicitlyDeclared || !IsAccessible(member)) { continue; } if (member is IMethodSymbol method) { if (method.MethodKind == MethodKind.PropertyGet || method.MethodKind == MethodKind.PropertySet || method.MethodKind == MethodKind.EventAdd || method.MethodKind == MethodKind.EventRemove || method.MethodKind == MethodKind.EventRaise) { continue; } } BuildMember(builder, member); } CloseBrace(builder); }
private void BuildAttributes(CodeFileTokensBuilder builder, ImmutableArray <AttributeData> attributes) { const string attributeSuffix = "Attribute"; foreach (var attribute in attributes) { if (!IsAccessible(attribute.AttributeClass) || IsSkippedAttribute(attribute.AttributeClass)) { continue; } builder.WriteIndent(); builder.Punctuation(SyntaxKind.OpenBracketToken); var name = attribute.AttributeClass.Name; if (name.EndsWith(attributeSuffix)) { name = name.Substring(0, name.Length - attributeSuffix.Length); } builder.Append(name, CodeFileTokenKind.TypeName); if (attribute.ConstructorArguments.Any()) { builder.Punctuation(SyntaxKind.OpenParenToken); bool first = true; foreach (var argument in attribute.ConstructorArguments) { if (!first) { builder.Punctuation(SyntaxKind.CommaToken); builder.Space(); } else { first = false; } BuildTypedConstant(builder, argument); } foreach (var argument in attribute.NamedArguments) { if (!first) { builder.Punctuation(SyntaxKind.CommaToken); builder.Space(); } else { first = false; } builder.Append(argument.Key, CodeFileTokenKind.Text); builder.Space(); builder.Punctuation(SyntaxKind.EqualsToken); builder.Space(); BuildTypedConstant(builder, argument.Value); } builder.Punctuation(SyntaxKind.CloseParenToken); } builder.Punctuation(SyntaxKind.CloseBracketToken); builder.NewLine(); } }