public override DocumentationUrlInfo CreateUrl(ImmutableArray <string> folders) { switch (folders[0]) { case "System": case "Microsoft": { const string baseUrl = "https://docs.microsoft.com/en-us/dotnet/api/"; int capacity = baseUrl.Length; foreach (string name in folders) { capacity += name.Length; } capacity += folders.Length - 1; StringBuilder sb = StringBuilderCache.GetInstance(capacity); sb.Append(baseUrl); sb.Append(folders[0].ToLowerInvariant()); for (int i = 1; i < folders.Length; i++) { sb.Append("."); sb.Append(folders[i].ToLowerInvariant()); } return(new DocumentationUrlInfo(StringBuilderCache.GetStringAndFree(sb), DocumentationUrlKind.External)); } } return(default);
public override DocumentationUrlInfo GetLocalUrl(ImmutableArray <string> folders, ImmutableArray <string> containingFolders = default, string fragment = null) { string url = CreateLocalUrl(); return(new DocumentationUrlInfo(url, DocumentationUrlKind.Local)); string CreateLocalUrl() { if (containingFolders.IsDefault) { return(GetUrl(ReadMeFileName, folders, '/') + fragment); } if (FoldersEqual(containingFolders, folders)) { return((string.IsNullOrEmpty(fragment)) ? LinkToSelf : fragment); } int count = 0; int i = 0; int j = 0; while (i < folders.Length && j < containingFolders.Length && string.Equals(folders[i], containingFolders[j], StringComparison.Ordinal)) { count++; i++; j++; } int diff = containingFolders.Length - count; StringBuilder sb = StringBuilderCache.GetInstance(); if (diff > 0) { sb.Append(".."); diff--; while (diff > 0) { sb.Append("/.."); diff--; } } i = count; if (i < folders.Length) { if (sb.Length > 0) { sb.Append("/"); } sb.Append(folders[i]); i++; while (i < folders.Length) { sb.Append("/"); sb.Append(folders[i]); i++; } } sb.Append("/"); sb.Append(ReadMeFileName); return(StringBuilderCache.GetStringAndFree(sb) + fragment); } bool FoldersEqual(ImmutableArray <string> folders1, ImmutableArray <string> folders2) { int length = folders1.Length; if (length != folders2.Length) { return(false); } for (int i = 0; i < length; i++) { if (folders1[i] != folders2[i]) { return(false); } } return(true); } }
public static async Task <string> GenerateAsync( DocumentationModel documentationModel, DeclarationListOptions options = null, IComparer <INamespaceSymbol> namespaceComparer = null, IComparer <INamedTypeSymbol> typeComparer = null, IComparer <ISymbol> memberComparer = null, CancellationToken cancellationToken = default) { cancellationToken.ThrowIfCancellationRequested(); options = options ?? DeclarationListOptions.Default; var builder = new DeclarationListBuilder( options: options, namespaceComparer: namespaceComparer, typeComparer: typeComparer, memberComparer: memberComparer); builder.Append(documentationModel); StringBuilder sb = StringBuilderCache.GetInstance(); if ((options.IgnoredParts & DeclarationListParts.AutoGeneratedComment) == 0) { AppendAutoGeneratedComment(documentationModel, sb); } foreach (INamespaceSymbol namespaceSymbol in builder.Namespaces.OrderBy(f => f, builder.NamespaceComparer)) { cancellationToken.ThrowIfCancellationRequested(); sb.Append("using "); sb.Append(namespaceSymbol.ToDisplayString(SymbolDisplayFormats.TypeNameAndContainingTypesAndNamespaces)); sb.AppendLine(";"); } if (builder.Namespaces.Count > 0) { sb.AppendLine(); } sb.Append(builder); string content = sb.ToString(); Project project = new AdhocWorkspace() .CurrentSolution .AddProject("AdHocProject", "AdHocProject", documentationModel.Language) .WithMetadataReferences(documentationModel.Compilation.References); if (project.ParseOptions is CSharpParseOptions csharpParseOptions) { project = project.WithParseOptions(csharpParseOptions.WithLanguageVersion(LanguageVersion.Latest)); } else { Debug.Fail(project.ParseOptions.GetType().FullName); } Document document = project.AddDocument("AdHocFile.cs", SourceText.From(content)); SemanticModel semanticModel = await document.GetSemanticModelAsync(cancellationToken).ConfigureAwait(false); SyntaxNode root = await document.GetSyntaxRootAsync(cancellationToken).ConfigureAwait(false); var rewriter = new Rewriter(options, semanticModel, cancellationToken); root = rewriter.Visit(root); document = document.WithSyntaxRoot(root); document = await Simplifier.ReduceAsync(document, cancellationToken : cancellationToken).ConfigureAwait(false); root = await document.GetSyntaxRootAsync(cancellationToken).ConfigureAwait(false); return(root.ToFullString()); }
public static string CreateLocalLink(ISymbol symbol, string prefix = null) { StringBuilder sb = StringBuilderCache.GetInstance(); if (prefix != null) { sb.Append(prefix); } int count = 0; INamespaceSymbol n = symbol.ContainingNamespace; while (n?.IsGlobalNamespace == false) { n = n.ContainingNamespace; count++; } while (count > 0) { int c = count; n = symbol.ContainingNamespace; while (c > 1) { n = n.ContainingNamespace; c--; } sb.Append(n.Name); sb.Append("_"); count--; } count = 0; INamedTypeSymbol t = symbol.ContainingType; while (t != null) { t = t.ContainingType; count++; } while (count > 0) { t = symbol.ContainingType; while (count > 1) { t = t.ContainingType; count--; } AppendType(t); sb.Append("_"); count--; } if (symbol.IsKind(SymbolKind.NamedType)) { AppendType((INamedTypeSymbol)symbol); } else { sb.Append(symbol.Name); } return(StringBuilderCache.GetStringAndFree(sb)); void AppendType(INamedTypeSymbol typeSymbol) { sb.Append(typeSymbol.Name); int arity = typeSymbol.Arity; if (arity > 0) { sb.Append("_"); sb.Append(arity.ToString()); } } }