public override void VisitAttributeEntry(AttributeEntry attributeEntry) { if (attributeEntry.Name != "xml-docs") { return; } //true when running from the IDE, build/output might have not been created string configuration = null; if (Program.BuildOutputPath.Contains("src")) { //bin/Debug|Release/netcoreapp2.1 configuration = new DirectoryInfo(Path.GetDirectoryName(Assembly.GetEntryAssembly().Location)).Parent?.Name; return; } string XmlFile(string project) { if (configuration == null) { return(Path.Combine(Program.BuildOutputPath, project, "netstandard2.0", $"{project}.XML")); } return(Path.Combine(Program.BuildOutputPath, project, "bin", configuration, "netstandard2.0", $"{project}.XML")); } var value = attributeEntry.Value; if (string.IsNullOrEmpty(value)) { base.VisitAttributeEntry(attributeEntry); return; } var parts = value.Split(':'); var assemblyName = parts[0]; var typeName = parts[1]; string xmlDocsFile; Assembly assembly; string assemblyNamespace; //TODO: tidy this up switch (assemblyName.ToLowerInvariant()) { case "elasticsearch.net": xmlDocsFile = Path.GetFullPath(XmlFile("Elasticsearch.Net")); assembly = typeof(ElasticLowLevelClient).Assembly; assemblyNamespace = typeof(ElasticLowLevelClient).Namespace; break; default: xmlDocsFile = Path.GetFullPath(XmlFile("Nest")); assembly = typeof(ElasticClient).Assembly; assemblyNamespace = typeof(ElasticClient).Namespace; break; } // build xml documentation file on the fly if it doesn't exist if (!File.Exists(xmlDocsFile)) { var project = _projects[assemblyName]; var compilation = project.GetCompilationAsync().Result; using (var peStream = new MemoryStream()) using (var commentStream = File.Create(xmlDocsFile)) { var emitResult = compilation.Emit(peStream, null, commentStream); if (!emitResult.Success) { var failures = emitResult.Diagnostics.Where(diagnostic => diagnostic.IsWarningAsError || diagnostic.Severity == DiagnosticSeverity.Error); var builder = new StringBuilder($"Unable to emit compilation for: {assemblyName}"); foreach (var diagnostic in failures) { builder.AppendLine($"{diagnostic.Id}: {diagnostic.GetMessage()}"); } builder.AppendLine(new string('-', 30)); throw new Exception(builder.ToString()); } } } var assemblyMembers = DocReader.Read(assembly, xmlDocsFile); var type = assembly.GetType(assemblyNamespace + "." + typeName); var visitor = new XmlDocsVisitor(type); visitor.VisitAssembly(assemblyMembers); if (visitor.LabeledListItems.Any()) { var labeledList = new LabeledList(); foreach (var item in visitor.LabeledListItems.OrderBy(l => l.Label)) { labeledList.Items.Add(item); } _newDocument.Insert(_newDocument.IndexOf(attributeEntry), labeledList); } }
public override void VisitAttributeEntry(AttributeEntry attributeEntry) { if (attributeEntry.Name != "xml-docs") { return; } var configuration = new DirectoryInfo(Path.GetDirectoryName(Assembly.GetEntryAssembly().Location)).Parent?.Name; string XmlFile(string xmlName) { //Elastic.Transport xml lives in Elasticsearch.Net var project = xmlName == "Elastic.Transport" ? "Elasticsearch.Net" : xmlName; if (configuration == null) { return(Path.Combine(Program.InputDirPath, project, "netstandard2.0", $"{xmlName}.xml")); } return(Path.Combine(Program.InputDirPath, project, "bin", configuration, "netstandard2.0", $"{xmlName}.xml")); } var value = attributeEntry.Value; if (string.IsNullOrEmpty(value)) { base.VisitAttributeEntry(attributeEntry); return; } var parts = value.Split(':'); var assemblyName = parts[0]; var typeName = parts[1]; string xmlDocsFile; Assembly assembly; string assemblyNamespace; //TODO: tidy this up switch (assemblyName.ToLowerInvariant()) { case "elasticsearch.net": xmlDocsFile = Path.GetFullPath(XmlFile("Elasticsearch.Net")); assembly = typeof(ElasticLowLevelClient).Assembly; assemblyNamespace = typeof(ElasticLowLevelClient).Namespace; break; case "elastic.transport": xmlDocsFile = Path.GetFullPath(XmlFile("Elastic.Transport")); assembly = typeof(CloudConnectionPool).Assembly; assemblyNamespace = typeof(CloudConnectionPool).Namespace; break; default: xmlDocsFile = Path.GetFullPath(XmlFile("Nest")); assembly = typeof(ElasticClient).Assembly; assemblyNamespace = typeof(ElasticClient).Namespace; break; } // build xml documentation file on the fly if it doesn't exist if (!File.Exists(xmlDocsFile) && _projects.ContainsKey(assemblyName)) { Console.WriteLine($"Can not find {xmlDocsFile} attempting to build"); var project = _projects[assemblyName]; var compilation = project.GetCompilationAsync().Result; using (var peStream = new MemoryStream()) using (var commentStream = File.Create(xmlDocsFile)) { var emitResult = compilation.Emit(peStream, null, commentStream); if (!emitResult.Success) { var failures = emitResult.Diagnostics.Where(diagnostic => diagnostic.IsWarningAsError || diagnostic.Severity == DiagnosticSeverity.Error); var builder = new StringBuilder($"Unable to emit compilation for: {assemblyName}"); foreach (var diagnostic in failures.Take(50)) { builder.AppendLine($"{diagnostic.Id}: {diagnostic.GetMessage()}"); } builder.AppendLine(new string('-', 30)); throw new Exception(builder.ToString()); } } } if (!File.Exists(xmlDocsFile)) { throw new Exception($"Can not find xml docs: '{xmlDocsFile}'"); } var assemblyMembers = DocReader.Read(assembly, xmlDocsFile); var type = assembly.GetType(assemblyNamespace + "." + typeName); var visitor = new XmlDocsVisitor(type); visitor.VisitAssembly(assemblyMembers); if (visitor.LabeledListItems.Any()) { var labeledList = new LabeledList(); foreach (var item in visitor.LabeledListItems .OrderBy(l => l.Label) .GroupBy(l => l.Label) .Select(x => x.First())) { labeledList.Items.Add(item); } _newDocument.Insert(_newDocument.IndexOf(attributeEntry), labeledList); } }