public ExampleSyntax() { Dependencies.Add(nameof(ExampleCode)); DependencyOf.Add(nameof(Content)); ProcessModules = new ModuleList { new ConcatDocuments(nameof(Code)), new ConcatDocuments(nameof(ExampleCode)), new CacheDocuments( new AnalyzeCSharp() .WhereNamespaces(true) .WherePublic() .WithCssClasses("code", "cs") .WithDestinationPrefix("syntax") .WithAssemblySymbols() // we need to load Spectre.Console for compiling, but we don't need to process it in Statiq .WhereNamespaces(i => !i.StartsWith("Spectre.Console")) .WithImplicitInheritDoc(false), new ExecuteConfig(Config.FromDocument((doc, _) => { // Add metadata var metadataItems = new MetadataItems { // Calculate an xref that includes a "api-" prefix to avoid collisions { WebKeys.Xref, "syntax-" + doc.GetString(CodeAnalysisKeys.CommentId) }, }; var contentProvider = doc.ContentProvider; return(doc.Clone(metadataItems, contentProvider)); }))).WithoutSourceMapping() }; }
public Api() { Dependencies.Add(nameof(Code)); DependencyOf.Add(nameof(Content)); ProcessModules = new ModuleList { new ConcatDocuments(nameof(Code)), new CacheDocuments( new AnalyzeCSharp() .WhereNamespaces(ns => ns.StartsWith("Spectre.Console") && !ns.Contains("Analyzer") && !ns.Contains("Testing") && !ns.Contains("Examples")) .WherePublic(true) .WithCssClasses("code", "cs") .WithDestinationPrefix("api") .WithAssemblySymbols() .WithImplicitInheritDoc(false), new ExecuteConfig(Config.FromDocument((doc, ctx) => { // Calculate a type name to link lookup for auto linking string name = null; var kind = doc.GetString(CodeAnalysisKeys.Kind); switch (kind) { case "NamedType": name = doc.GetString(CodeAnalysisKeys.DisplayName); break; case "Method": var containingType = doc.GetDocument(CodeAnalysisKeys.ContainingType); if (containingType != null) { name = $"{containingType.GetString(CodeAnalysisKeys.DisplayName)}.{doc.GetString(CodeAnalysisKeys.DisplayName)}"; } break; } if (name != null) { var typeNameLinks = ctx.GetRequiredService <TypeNameLinks>(); typeNameLinks.Links.AddOrUpdate(WebUtility.HtmlEncode(name), ctx.GetLink(doc), (_, _) => string.Empty); } // Add metadata var metadataItems = new MetadataItems { { WebKeys.Xref, doc.GetString(CodeAnalysisKeys.CommentId) }, { WebKeys.Layout, "api/_layout.cshtml" }, { Constants.Hidden, true } }; var contentProvider = doc.ContentProvider.CloneWithMediaType(MediaTypes.Html); metadataItems.Add(WebKeys.ContentType, ContentType.Content); return(doc.Clone(metadataItems, contentProvider)); }))).WithoutSourceMapping() }; }
private void AddXmlDocumentation(ISymbol symbol, MetadataItems metadata) { string documentationCommentXml = symbol.GetDocumentationCommentXml(expandIncludes: true); XmlDocumentationParser xmlDocumentationParser = new XmlDocumentationParser(symbol, _commentIdToDocument, _cssClasses); IEnumerable <string> otherHtmlElementNames = xmlDocumentationParser.Parse(documentationCommentXml); // Add standard HTML elements metadata.AddRange(new [] { new MetadataItem(CodeAnalysisKeys.CommentXml, documentationCommentXml), new MetadataItem(CodeAnalysisKeys.Example, (k, m) => xmlDocumentationParser.Process().Example), new MetadataItem(CodeAnalysisKeys.Remarks, (k, m) => xmlDocumentationParser.Process().Remarks), new MetadataItem(CodeAnalysisKeys.Summary, (k, m) => xmlDocumentationParser.Process().Summary), new MetadataItem(CodeAnalysisKeys.Returns, (k, m) => xmlDocumentationParser.Process().Returns), new MetadataItem(CodeAnalysisKeys.Value, (k, m) => xmlDocumentationParser.Process().Value), new MetadataItem(CodeAnalysisKeys.Exceptions, (k, m) => xmlDocumentationParser.Process().Exceptions), new MetadataItem(CodeAnalysisKeys.Permissions, (k, m) => xmlDocumentationParser.Process().Permissions), new MetadataItem(CodeAnalysisKeys.Params, (k, m) => xmlDocumentationParser.Process().Params), new MetadataItem(CodeAnalysisKeys.TypeParams, (k, m) => xmlDocumentationParser.Process().TypeParams), new MetadataItem(CodeAnalysisKeys.SeeAlso, (k, m) => xmlDocumentationParser.Process().SeeAlso) }); // Add other HTML elements with keys of [ElementName]Html metadata.AddRange(otherHtmlElementNames.Select(x => new MetadataItem(FirstLetterToUpper(x) + "Comments", (k, m) => xmlDocumentationParser.Process().OtherComments[x]))); }
// We need to build the tree from the bottom up so that the children don't have to be lazy // This also sorts the children once they're created public void GenerateOutputDocuments(Tree tree, IExecutionContext context) { // Recursively build output documents for children foreach (TreeNode child in Children) { child.GenerateOutputDocuments(tree, context); } // We're done if we've already created the output document if (OutputDocument != null) { return; } // Sort the child documents since they're created now Children.Sort((x, y) => tree._sort(x.OutputDocument, y.OutputDocument)); // Create this output document MetadataItems metadata = new MetadataItems(); if (tree._childrenKey != null) { metadata.Add(tree._childrenKey, new ReadOnlyCollection <IDocument>(Children.Select(x => x.OutputDocument).ToArray())); } if (tree._parentKey != null) { metadata.Add(tree._parentKey, new CachedDelegateMetadataValue(_ => Parent?.OutputDocument)); } if (tree._previousSiblingKey != null) { metadata.Add(tree._previousSiblingKey, new CachedDelegateMetadataValue(_ => GetPreviousSibling()?.OutputDocument)); } if (tree._nextSiblingKey != null) { metadata.Add(tree._nextSiblingKey, new CachedDelegateMetadataValue(_ => GetNextSibling()?.OutputDocument)); } if (tree._previousKey != null) { metadata.Add(tree._previousKey, new CachedDelegateMetadataValue(_ => GetPrevious()?.OutputDocument)); } if (tree._nextKey != null) { metadata.Add(tree._nextKey, new CachedDelegateMetadataValue(_ => GetNext()?.OutputDocument)); } if (tree._treePathKey != null) { metadata.Add(tree._treePathKey, TreePath); } if (InputDocument == null) { // There's no input document for this node so we need to make a placeholder metadata.Add(Keys.TreePlaceholder, true); OutputDocument = tree._placeholderFactory(TreePath, metadata, context) ?? context.GetDocument(metadata); } else { OutputDocument = context.GetDocument(InputDocument, metadata); } }
internal void AddMetadataItem(MetadataItem item) { if (MetadataItems == null) { MetadataItems = new List <MetadataItem>(); } MetadataItems.Add(item); }
private static IDocument TreePlaceholderFactory(object[] path, MetadataItems items, IExecutionContext context) { FilePath indexPath = new FilePath(string.Join("/", path.Concat(new[] { "index.html" }))); items.Add(Keys.RelativeFilePath, indexPath); items.Add(Keys.Title, Title.GetTitle(indexPath)); return(context.GetDocument(context.GetContentStream("@Html.Partial(\"_ChildPages\")"), items)); }
private IDocument AddMemberDocument(ISymbol symbol, bool xmlDocumentation, MetadataItems items) { items.AddRange(new[] { new MetadataItem(CodeAnalysisKeys.ContainingType, DocumentFor(symbol.ContainingType)) }); return(AddDocument(symbol, xmlDocumentation, items)); }
private IDocument Write(IDocument input, IExecutionContext context, FilePath outputPath) { IFile output = context.FileSystem.GetOutputFile(outputPath); if (output != null) { using (Stream inputStream = input.GetStream()) { if (_ignoreEmptyContent && inputStream.Length == 0) { return(input); } if (!_onlyMetadata) { using (Stream outputStream = _append ? output.OpenAppend() : output.OpenWrite()) { inputStream.CopyTo(outputStream); if (!_append) { outputStream.SetLength(inputStream.Length); } } } } Trace.Verbose($"{(_onlyMetadata ? "Set metadata for" : "Wrote")} file {output.Path.FullPath} from {input.SourceString()}"); FilePath relativePath = context.FileSystem.GetOutputPath().GetRelativePath(output.Path) ?? output.Path.FileName; FilePath fileNameWithoutExtension = output.Path.FileNameWithoutExtension; MetadataItems metadata = new MetadataItems { { Keys.RelativeFilePath, relativePath }, { Keys.RelativeFilePathBase, fileNameWithoutExtension == null ? null : relativePath.Directory.CombineFile(output.Path.FileNameWithoutExtension) }, { Keys.RelativeFileDir, relativePath.Directory } }; if (_onlyMetadata) { metadata.Add(Keys.WritePath, outputPath); } else { metadata.AddRange(new MetadataItems { { Keys.DestinationFileBase, fileNameWithoutExtension }, { Keys.DestinationFileExt, output.Path.Extension }, { Keys.DestinationFileName, output.Path.FileName }, { Keys.DestinationFileDir, output.Path.Directory }, { Keys.DestinationFilePath, output.Path }, { Keys.DestinationFilePathBase, fileNameWithoutExtension == null ? null : output.Path.Directory.CombineFile(output.Path.FileNameWithoutExtension) }, }); } return(_onlyMetadata ? context.GetDocument(input, metadata) : context.GetDocument(input, output.OpenRead(), metadata)); } return(input); }
private void AddDocument(ISymbol symbol, bool xmlDocumentation, MetadataItems items) { // Get universal metadata items.AddRange(new [] { // In general, cache the values that need calculation and don't cache the ones that are just properties of ISymbol new MetadataItem(CodeAnalysisKeys.IsResult, !_finished), new MetadataItem(CodeAnalysisKeys.SymbolId, (k, m) => GetId(symbol), true), new MetadataItem(CodeAnalysisKeys.Symbol, symbol), new MetadataItem(CodeAnalysisKeys.Name, (k, m) => symbol.Name), new MetadataItem(CodeAnalysisKeys.FullName, (k, m) => GetFullName(symbol), true), new MetadataItem(CodeAnalysisKeys.DisplayName, (k, m) => GetDisplayName(symbol), true), new MetadataItem(CodeAnalysisKeys.QualifiedName, (k, m) => GetQualifiedName(symbol), true), new MetadataItem(CodeAnalysisKeys.Kind, (k, m) => symbol.Kind.ToString()), new MetadataItem(CodeAnalysisKeys.ContainingNamespace, DocumentFor(symbol.ContainingNamespace)), new MetadataItem(CodeAnalysisKeys.Syntax, (k, m) => GetSyntax(symbol), true) }); // Add metadata that's specific to initially-processed symbols if (!_finished) { items.AddRange(new[] { new MetadataItem(Keys.WritePath, (k, m) => _writePath(m), true), new MetadataItem(Keys.RelativeFilePath, (k, m) => m.FilePath(Keys.WritePath)), new MetadataItem(Keys.RelativeFilePathBase, (k, m) => { FilePath writePath = m.FilePath(Keys.WritePath); return(writePath.Directory.CombineFile(writePath.FileNameWithoutExtension)); }), new MetadataItem(Keys.RelativeFileDir, (k, m) => m.FilePath(Keys.WritePath).Directory) }); } // XML Documentation if (xmlDocumentation && (!_finished || _docsForImplicitSymbols)) { AddXmlDocumentation(symbol, items); } // Create the document and add it to the cache IDocument document = _context.GetDocument(new FilePath(NormalizedPath.AbstractProvider, symbol.ToDisplayString(), true), null, items); _symbolToDocument.GetOrAdd(symbol, _ => document); // Map the comment ID to the document if (!_finished) { string documentationCommentId = symbol.GetDocumentationCommentId(); if (documentationCommentId != null) { _commentIdToDocument.GetOrAdd(documentationCommentId, _ => document); } } }
private IDocument AddDocumentCommon(ISymbol symbol, bool xmlDocumentation, MetadataItems items) { // Get universal metadata string commentId = symbol.GetDocumentationCommentId(); items.AddRange(new[] { // In general, cache the values that need calculation and don't cache the ones that are just properties of ISymbol new MetadataItem(CodeAnalysisKeys.IsResult, !_finished), new MetadataItem(CodeAnalysisKeys.SymbolId, _ => GetId(symbol), true), new MetadataItem(CodeAnalysisKeys.CommentId, commentId), new MetadataItem(CodeAnalysisKeys.Name, metadata => string.IsNullOrEmpty(symbol.Name) ? metadata.String(CodeAnalysisKeys.FullName) : symbol.Name), new MetadataItem(CodeAnalysisKeys.FullName, _ => GetFullName(symbol), true), new MetadataItem(CodeAnalysisKeys.DisplayName, _ => GetDisplayName(symbol), true), new MetadataItem(CodeAnalysisKeys.QualifiedName, _ => GetQualifiedName(symbol), true), new MetadataItem(CodeAnalysisKeys.Kind, _ => symbol.Kind.ToString()), new MetadataItem(CodeAnalysisKeys.ContainingNamespace, DocumentFor(symbol.ContainingNamespace)), new MetadataItem(CodeAnalysisKeys.Syntax, _ => GetSyntax(symbol), true), new MetadataItem(CodeAnalysisKeys.IsStatic, _ => symbol.IsStatic), new MetadataItem(CodeAnalysisKeys.IsAbstract, _ => symbol.IsAbstract), new MetadataItem(CodeAnalysisKeys.IsVirtual, _ => symbol.IsVirtual), new MetadataItem(CodeAnalysisKeys.IsOverride, _ => symbol.IsOverride), new MetadataItem(CodeAnalysisKeys.OriginalDefinition, DocumentFor(GetOriginalSymbolDefinition(symbol))) }); // Add metadata that's specific to initially-processed symbols if (!_finished) { items.AddRange(new[] { new MetadataItem(Keys.WritePath, x => _writePath(x), true), new MetadataItem(Keys.RelativeFilePath, x => x.FilePath(Keys.WritePath)), new MetadataItem(Keys.RelativeFilePathBase, x => { FilePath writePath = x.FilePath(Keys.WritePath); return(writePath.Directory.CombineFile(writePath.FileNameWithoutExtension)); }), new MetadataItem(Keys.RelativeFileDir, x => x.FilePath(Keys.WritePath).Directory) }); } // XML Documentation if (xmlDocumentation && (!_finished || _docsForImplicitSymbols)) { AddXmlDocumentation(symbol, items); } // Create the document and add it to caches IDocument document = _symbolToDocument.GetOrAdd( symbol, _ => _context.GetDocument(new FilePath((Uri)null, symbol.ToDisplayString(), PathKind.Absolute), (Stream)null, items)); return(document); }
/// <inheritdoc /> protected override IEnumerable <IDocument> ExecuteContext(IExecutionContext context) { // Partition the pages and get a total before skip/take IDocument[][] pages = Partition(context.Inputs, _pageSize) .ToArray(); // Skip/take the pages pages = pages .Skip(_skipPages) .Take(_takePages) .ToArray(); // Special case for no pages, create an empty one if (pages.Length == 0) { pages = new[] { Array.Empty <IDocument>() }; } // Create the documents per page, setting previous and next values as we go Stack <(IDocument, LazyDocumentMetadataValue)> results = new Stack <(IDocument, LazyDocumentMetadataValue)>(); for (int c = 0; c < pages.Length; c++) { MetadataItems items = new MetadataItems { { Keys.Children, pages[c] }, { Keys.Index, c + 1 }, { Keys.TotalPages, pages.Length }, { Keys.TotalItems, context.Inputs.Length } }; if (results.Count > 0) { items.Add(Keys.Previous, new LazyDocumentMetadataValue(results.Peek().Item1)); } LazyDocumentMetadataValue next = null; if (c < pages.Length - 1) { next = new LazyDocumentMetadataValue(); items.Add(Keys.Next, next); } IDocument document = context.CreateDocument( _source, _source.IsNull ? _source : _source.GetRelativeInputPath(), items); if (results.Count > 0) { results.Peek().Item2.OriginalDocument = document; } results.Push((document, next)); } return(results.Select(x => x.Item1).Reverse()); }
public void ReturnsNullWhenKeyNotFound() { // Given MetadataItems initialMetadata = new MetadataItems(); IMetadata metadata = new Metadata(initialMetadata); // When IEnumerable <IDocument> result = metadata.GetDocuments("A"); // Then result.ShouldBeNull(); }
public void ReturnsEmptyListWhenKeyNotFound() { // Given MetadataItems initialMetadata = new MetadataItems(); IMetadata metadata = new Metadata(initialMetadata); // When DocumentList <IDocument> result = metadata.GetDocumentList("A"); // Then Assert.IsEmpty(result); }
public void CanCloneWithNewValues() { // Given MetadataItems initialMetadata = new MetadataItems(); Metadata metadata = new Metadata(initialMetadata); // When metadata = new Metadata(metadata, new[] { new KeyValuePair <string, object>("A", "a") }); // Then Assert.AreEqual("a", metadata["A"]); }
public override bool Execute() { StringBuilder builder = new StringBuilder(); // we always generate global configs builder.AppendLine("is_global = true"); // collect the properties into a global section foreach (var prop in PropertyItems) { builder .Append("build_property.") .Append(prop.ItemSpec) .Append(" = ") .AppendLine(prop.GetMetadata("Value")); } // group the metadata items by their full path var groupedItems = MetadataItems.GroupBy( i => NormalizeWithForwardSlash(i.GetMetadata("FullPath")) ); foreach (var group in groupedItems) { // write the section for this item builder.AppendLine().Append("["); EncodeString(builder, group.Key); builder.AppendLine("]"); foreach (var item in group) { string itemType = item.GetMetadata("ItemType"); string metadataName = item.GetMetadata("MetadataName"); if ( !string.IsNullOrWhiteSpace(itemType) && !string.IsNullOrWhiteSpace(metadataName) ) { builder .Append("build_metadata.") .Append(itemType) .Append(".") .Append(metadataName) .Append(" = ") .AppendLine(item.GetMetadata(metadataName)); } } } ConfigFileContents = builder.ToString(); return(true); }
private static void AddImage(MetadataItems metadata, IAsset?asset) { if (asset == null) { return; } var localPath = KontentAssetHelper.GetLocalFileName(asset.Url + "?w=800&h=800", "img"); var download = new KontentImageDownload(asset.Url, localPath); metadata.Add(FeedKeys.Image, localPath); metadata.Add("KONTENT-ASSET-DOWNLOADS", download); // TODO : an upcoming version of Kontent.Statiq will provide this key }
public void ReturnsCorrectDirectoryPathForDirectoryPath(string path, string expected) { // Given MetadataItems initialMetadata = new MetadataItems(); IMetadata metadata = new Metadata(initialMetadata); // When metadata = new Metadata(metadata, new[] { new KeyValuePair <string, object>("A", new NormalizedPath(path)) }); NormalizedPath result = metadata.GetPath("A"); // Then result.FullPath.ShouldBe(expected); }
public void ReturnsTrueForSameKeysWithDifferentCase() { // Given MetadataItems initialMetadata = new MetadataItems { { "A", "a" } }; Metadata metadata = new Metadata(initialMetadata); // When bool contains = metadata.ContainsKey("a"); // Then Assert.IsTrue(contains); }
private IDocument AddNamespaceDocument(INamespaceSymbol symbol, bool xmlDocumentation) { string displayName = GetDisplayName(symbol); MetadataItems items = new MetadataItems { { CodeAnalysisKeys.Symbol, _ => _namespaceDisplayNameToSymbols[displayName].ToImmutableList() }, { CodeAnalysisKeys.SpecificKind, _ => symbol.Kind.ToString() }, // We need to aggregate the results across all matching namespaces { CodeAnalysisKeys.MemberNamespaces, DocumentsFor(_namespaceDisplayNameToSymbols[displayName].SelectMany(x => x.GetNamespaceMembers())) }, { CodeAnalysisKeys.MemberTypes, DocumentsFor(_namespaceDisplayNameToSymbols[displayName].SelectMany(x => x.GetTypeMembers())) } }; return(AddDocumentCommon(symbol, xmlDocumentation, items)); }
public void ReturnsCorrectFilePathForFilePath(string path, string expected) { // Given MetadataItems initialMetadata = new MetadataItems(); IMetadata metadata = new Metadata(initialMetadata); // When metadata = new Metadata(metadata, new[] { new KeyValuePair <string, object>("A", new FilePath(path)) }); object result = metadata.GetFilePath("A"); // Then Assert.IsInstanceOf <FilePath>(result); Assert.AreEqual(expected, ((FilePath)result).FullPath); }
public override void VisitNamedType(INamedTypeSymbol symbol) { // Only visit the original definition until we're finished INamedTypeSymbol originalDefinition = GetOriginalSymbolDefinition(symbol); if (!_finished && !SymbolEqualityComparer.Default.Equals(originalDefinition, symbol)) { VisitNamedType(originalDefinition); return; } if (ShouldIncludeSymbol(symbol)) { MetadataItems metadata = new MetadataItems { { CodeAnalysisKeys.SpecificKind, _ => symbol.TypeKind.ToString() }, { CodeAnalysisKeys.ContainingType, DocumentFor(symbol.ContainingType) }, { CodeAnalysisKeys.MemberTypes, DocumentsFor(symbol.GetTypeMembers()) }, { CodeAnalysisKeys.BaseTypes, DocumentsFor(GetBaseTypes(symbol)) }, { CodeAnalysisKeys.AllInterfaces, DocumentsFor(symbol.AllInterfaces) }, { CodeAnalysisKeys.Members, DocumentsFor(GetAccessibleMembersInThisAndBaseTypes(symbol, symbol).Where(MemberPredicate)) }, { CodeAnalysisKeys.Operators, DocumentsFor(GetAccessibleMembersInThisAndBaseTypes(symbol, symbol).Where(OperatorPredicate)) }, { CodeAnalysisKeys.ExtensionMethods, _ => DocumentsFor(_extensionMethods.Where(x => x.ReduceExtensionMethod(symbol) != null)) }, { CodeAnalysisKeys.Constructors, DocumentsFor(symbol.Constructors.Where(x => !x.IsImplicitlyDeclared)) }, { CodeAnalysisKeys.TypeParameters, DocumentsFor(symbol.TypeParameters) }, { CodeAnalysisKeys.TypeArguments, DocumentsFor(symbol.TypeArguments) }, { CodeAnalysisKeys.Accessibility, _ => symbol.DeclaredAccessibility.ToString() }, { CodeAnalysisKeys.Attributes, GetAttributeDocuments(symbol) } }; if (!_finished) { metadata.AddRange(new[] { new MetadataItem(CodeAnalysisKeys.DerivedTypes, _ => GetDerivedTypes(symbol), true), new MetadataItem(CodeAnalysisKeys.ImplementingTypes, _ => GetImplementingTypes(symbol), true) }); } AddDocumentCommon(symbol, true, metadata); // Descend if not finished, and only if this type was included if (!_finished) { Parallel.ForEach( symbol.GetMembers() .Where(MemberPredicate) .Concat(symbol.Constructors.Where(x => !x.IsImplicitlyDeclared)), s => s.Accept(this)); } } }
public void ReturnsTrueForValidValue() { // Given MetadataItems initialMetadata = new MetadataItems { { "A", "a" } }; Metadata metadata = new Metadata(initialMetadata); // When bool contains = metadata.ContainsKey("A"); // Then Assert.IsTrue(contains); }
public void ReturnsCorrectStringForDirectoryPath(string path, string expected) { // Given MetadataItems initialMetadata = new MetadataItems(); IMetadata metadata = new Metadata(initialMetadata); // When metadata = new Metadata(metadata, new[] { new KeyValuePair <string, object>("A", new NormalizedPath(path)) }); object result = metadata.GetString("A"); // Then Assert.IsInstanceOf <string>(result); Assert.AreEqual(expected, result); }
public void GetWithMetadataValueReturnsCorrectResult() { // Given MetadataItems initialMetadata = new MetadataItems { { "A", "a" } }; IMetadata metadata = new Metadata(initialMetadata); // When object value = metadata.Get("A"); // Then Assert.AreEqual("a", value); }
// Used for everything but namespace documents private IDocument AddDocument(ISymbol symbol, bool xmlDocumentation, MetadataItems items) { items.AddRange(new[] { new MetadataItem(CodeAnalysisKeys.Symbol, symbol) }); // Add the containing assembly, but only if it's not the code analysis compilation if (symbol.ContainingAssembly?.Name != AnalyzeCSharp.CompilationAssemblyName && _assemblySymbols) { items.Add(new MetadataItem(CodeAnalysisKeys.ContainingAssembly, DocumentFor(symbol.ContainingAssembly))); } return(AddDocumentCommon(symbol, xmlDocumentation, items)); }
public void ReturnsEmptyListForSingleInt() { // Given MetadataItems initialMetadata = new MetadataItems { { "A", 1 } }; IMetadata metadata = new Metadata(initialMetadata); // When DocumentList <IDocument> result = metadata.GetDocumentList("A"); // Then Assert.IsNotNull(result); CollectionAssert.IsEmpty(result); }
public void MissingKeyThrowsKeyNotFoundException() { // Given MetadataItems initialMetadata = new MetadataItems(); Metadata metadata = new Metadata(initialMetadata); // When TestDelegate test = () => { object value = metadata["A"]; }; // Then Assert.Throws <KeyNotFoundException>(test); }
public void ReturnsCorrectResultForArray() { // Given MetadataItems initialMetadata = new MetadataItems { { "A", new[] { 1, 2, 3 } } }; IMetadata metadata = new Metadata(initialMetadata); // When IReadOnlyList <int> result = metadata.GetList <int>("A"); // Then Assert.IsNotNull(result); CollectionAssert.AreEqual(result, new[] { 1, 2, 3 }); }
public void NullKeyThrowsKeyNotFoundException() { // Given MetadataItems initialMetadata = new MetadataItems(); Metadata metadata = new Metadata(initialMetadata); // When TestDelegate test = () => { object value = metadata[null]; }; // Then Assert.Throws <ArgumentNullException>(test); }
public void ContainsNewValues() { // Given MetadataItems initialMetadata = new MetadataItems { { "A", "a" } }; Metadata metadata = new Metadata(initialMetadata); // When Metadata clone = new Metadata(metadata, new Dictionary <string, object> { { "B", "b" } }); // Then Assert.AreEqual("b", clone["B"]); }
private void AddDocument(ISymbol symbol, bool xmlDocumentation, MetadataItems items) { // Get universal metadata items.AddRange(new [] { // In general, cache the values that need calculation and don't cache the ones that are just properties of ISymbol new MetadataItem(CodeAnalysisKeys.IsResult, !_finished), new MetadataItem(CodeAnalysisKeys.SymbolId, (k, m) => GetId(symbol), true), new MetadataItem(CodeAnalysisKeys.Symbol, symbol), new MetadataItem(CodeAnalysisKeys.Name, (k, m) => symbol.Name), new MetadataItem(CodeAnalysisKeys.FullName, (k, m) => GetFullName(symbol), true), new MetadataItem(CodeAnalysisKeys.DisplayName, (k, m) => GetDisplayName(symbol), true), new MetadataItem(CodeAnalysisKeys.QualifiedName, (k, m) => GetQualifiedName(symbol), true), new MetadataItem(CodeAnalysisKeys.Kind, (k, m) => symbol.Kind.ToString()), new MetadataItem(CodeAnalysisKeys.ContainingNamespace, DocumentFor(symbol.ContainingNamespace)), new MetadataItem(CodeAnalysisKeys.Syntax, (k, m) => GetSyntax(symbol), true) }); // Add metadata that's specific to initially-processed symbols if (!_finished) { items.AddRange(new[] { new MetadataItem(Keys.WritePath, (k, m) => _writePath(m), true), new MetadataItem(Keys.RelativeFilePath, (k, m) => m.String(Keys.WritePath)), new MetadataItem(Keys.RelativeFilePathBase, (k, m) => PathHelper.RemoveExtension(m.String(Keys.WritePath))), new MetadataItem(Keys.RelativeFileDir, (k, m) => Path.GetDirectoryName(m.String(Keys.WritePath))) }); } // XML Documentation if (xmlDocumentation && (!_finished || _docsForImplicitSymbols)) { AddXmlDocumentation(symbol, items); } // Create the document and add it to the cache IDocument document = _context.GetNewDocument(symbol.ToDisplayString(), null, items); _symbolToDocument.GetOrAdd(symbol, _ => document); // Map the comment ID to the document if (!_finished) { string documentationCommentId = symbol.GetDocumentationCommentId(); if (documentationCommentId != null) { _commentIdToDocument.GetOrAdd(documentationCommentId, _ => document); } } }
private void AddDocumentForMember(ISymbol symbol, bool xmlDocumentation, MetadataItems items) { items.AddRange(new[] { new MetadataItem(CodeAnalysisKeys.ContainingType, DocumentFor(symbol.ContainingType)) }); AddDocument(symbol, xmlDocumentation, items); }
private void AddXmlDocumentation(ISymbol symbol, MetadataItems metadata) { string documentationCommentXml = symbol.GetDocumentationCommentXml(expandIncludes: true); XmlDocumentationParser xmlDocumentationParser = new XmlDocumentationParser(symbol, _commentIdToDocument, _cssClasses, _context.Trace); IEnumerable<string> otherHtmlElementNames = xmlDocumentationParser.Parse(documentationCommentXml); // Add standard HTML elements metadata.AddRange(new [] { new MetadataItem(CodeAnalysisKeys.CommentXml, documentationCommentXml), new MetadataItem(CodeAnalysisKeys.Example, (k, m) => xmlDocumentationParser.Process().Example), new MetadataItem(CodeAnalysisKeys.Remarks, (k, m) => xmlDocumentationParser.Process().Remarks), new MetadataItem(CodeAnalysisKeys.Summary, (k, m) => xmlDocumentationParser.Process().Summary), new MetadataItem(CodeAnalysisKeys.Returns, (k, m) => xmlDocumentationParser.Process().Returns), new MetadataItem(CodeAnalysisKeys.Value, (k, m) => xmlDocumentationParser.Process().Value), new MetadataItem(CodeAnalysisKeys.Exceptions, (k, m) => xmlDocumentationParser.Process().Exceptions), new MetadataItem(CodeAnalysisKeys.Permissions, (k, m) => xmlDocumentationParser.Process().Permissions), new MetadataItem(CodeAnalysisKeys.Params, (k, m) => xmlDocumentationParser.Process().Params), new MetadataItem(CodeAnalysisKeys.TypeParams, (k, m) => xmlDocumentationParser.Process().TypeParams), new MetadataItem(CodeAnalysisKeys.SeeAlso, (k, m) => xmlDocumentationParser.Process().SeeAlso) }); // Add other HTML elements with keys of [ElementName]Html metadata.AddRange(otherHtmlElementNames.Select(x => new MetadataItem(FirstLetterToUpper(x) + "Comments", (k, m) => xmlDocumentationParser.Process().OtherComments[x]))); }
public override void VisitNamedType(INamedTypeSymbol symbol) { if (_finished || _symbolPredicate == null || _symbolPredicate(symbol)) { MetadataItems metadata = new MetadataItems { { CodeAnalysisKeys.SpecificKind, (k, m) => symbol.TypeKind.ToString() }, { CodeAnalysisKeys.ContainingType, DocumentFor(symbol.ContainingType) }, { CodeAnalysisKeys.MemberTypes, DocumentsFor(symbol.GetTypeMembers()) }, { CodeAnalysisKeys.BaseType, DocumentFor(symbol.BaseType) }, { CodeAnalysisKeys.AllInterfaces, DocumentsFor(symbol.AllInterfaces) }, { CodeAnalysisKeys.Members, DocumentsFor(symbol.GetMembers().Where(MemberPredicate)) }, { CodeAnalysisKeys.Constructors, DocumentsFor(symbol.Constructors.Where(x => !x.IsImplicitlyDeclared)) }, { CodeAnalysisKeys.TypeParameters, DocumentsFor(symbol.TypeParameters) }, { CodeAnalysisKeys.Accessibility, (k, m) => symbol.DeclaredAccessibility.ToString() } }; if (!_finished) { metadata.AddRange(new [] { new MetadataItem(CodeAnalysisKeys.DerivedTypes, (k, m) => GetDerivedTypes(symbol), true), new MetadataItem(CodeAnalysisKeys.ImplementingTypes, (k, m) => GetImplementingTypes(symbol), true) }); } AddDocument(symbol, true, metadata); // Descend if not finished, and only if this type was included if (!_finished) { Parallel.ForEach(symbol.GetMembers() .Where(MemberPredicate) .Concat(symbol.Constructors.Where(x => !x.IsImplicitlyDeclared)), s => s.Accept(this)); } } }
private IDocument Write(IDocument input, IExecutionContext context, FilePath outputPath) { IFile output = context.FileSystem.GetOutputFile(outputPath); if (output != null) { using (Stream inputStream = input.GetStream()) { if (_ignoreEmptyContent && inputStream.Length == 0) { return input; } if (!_onlyMetadata) { using (Stream outputStream = _append ? output.OpenAppend() : output.OpenWrite()) { inputStream.CopyTo(outputStream); } } } Trace.Verbose($"{(_onlyMetadata ? "Set metadata for" : "Wrote")} file {output.Path.FullPath} from {input.SourceString()}"); FilePath relativePath = context.FileSystem.GetOutputPath().GetRelativePath(output.Path) ?? output.Path.FileName; FilePath fileNameWithoutExtension = output.Path.FileNameWithoutExtension; MetadataItems metadata = new MetadataItems { { Keys.RelativeFilePath, relativePath }, { Keys.RelativeFilePathBase, fileNameWithoutExtension == null ? null : relativePath.Directory.CombineFile(output.Path.FileNameWithoutExtension) }, { Keys.RelativeFileDir, relativePath.Directory } }; if (_onlyMetadata) { metadata.Add(Keys.WritePath, outputPath); } else { metadata.AddRange(new MetadataItems { { Keys.DestinationFileBase, fileNameWithoutExtension }, { Keys.DestinationFileExt, output.Path.Extension }, { Keys.DestinationFileName, output.Path.FileName }, { Keys.DestinationFileDir, output.Path.Directory }, { Keys.DestinationFilePath, output.Path }, { Keys.DestinationFilePathBase, fileNameWithoutExtension == null ? null : output.Path.Directory.CombineFile(output.Path.FileNameWithoutExtension) }, }); } return _onlyMetadata ? context.GetDocument(input, metadata) : context.GetDocument(input, output.OpenRead(), metadata); } return input; }