private async Task <ActionResult> TextSearchResults(string searchTerm) { var result = await storage.TextSearchAsync(this.GetSearchRepos(), searchTerm.TrimStart('`'), 500); if (result.Count == 0) { return(PartialView(null)); } SymbolReferenceResult referencesResult = FromTextEntries(result); referencesResult.SymbolName = searchTerm; return(PartialView("~/Views/References/References.cshtml", (object)ReferencesController.GenerateReferencesHtml(referencesResult))); }
public static string GenerateReferencesHtml(SymbolReferenceResult symbolReferenceResult) { var references = symbolReferenceResult.Entries; var definitionProjectId = symbolReferenceResult.ProjectId; var symbolId = symbolReferenceResult.SymbolId; var symbolName = symbolReferenceResult.SymbolName; int totalReferenceCount = 0; var referenceKindGroups = CreateReferences(references, out totalReferenceCount); using (var writer = new StringWriter()) { if ((symbolReferenceResult.RelatedDefinitions?.Count ?? 0) != 0) { var baseMember = symbolReferenceResult.RelatedDefinitions .Where(r => r.ReferenceKind == nameof(ReferenceKind.Override)) .FirstOrDefault(); if (baseMember != null) { WriteBaseMember(writer, baseMember); } var implementedMembers = symbolReferenceResult.RelatedDefinitions .Where(r => r.ReferenceKind == nameof(ReferenceKind.InterfaceMemberImplementation)) .ToList(); if (implementedMembers.Count != 0) { WriteImplementedInterfaceMembers(writer, implementedMembers); } } foreach (var referenceKind in referenceKindGroups.OrderBy(t => (int)t.Item1)) { string formatString = ""; switch (referenceKind.Item1) { case ReferenceKind.Reference: formatString = "{0} reference{1} to {2}"; break; case ReferenceKind.Definition: formatString = "{0} definition{1} of {2}"; break; case ReferenceKind.Constructor: formatString = "{0} constructor{1} of {2}"; break; case ReferenceKind.Instantiation: formatString = "{0} instantiation{1} of {2}"; break; case ReferenceKind.DerivedType: formatString = "{0} type{1} derived from {2}"; break; case ReferenceKind.InterfaceInheritance: formatString = "{0} interface{1} inheriting from {2}"; break; case ReferenceKind.InterfaceImplementation: formatString = "{0} implementation{1} of {2}"; break; case ReferenceKind.Override: formatString = "{0} override{1} of {2}"; break; case ReferenceKind.InterfaceMemberImplementation: formatString = "{0} implementation{1} of {2}"; break; case ReferenceKind.Write: formatString = "{0} write{1} to {2}"; break; case ReferenceKind.Read: formatString = "{0} read{1} of {2}"; break; case ReferenceKind.GuidUsage: formatString = "{0} usage{1} of Guid {2}"; break; case ReferenceKind.EmptyArrayAllocation: formatString = "{0} allocation{1} of empty arrays"; break; case ReferenceKind.MSBuildPropertyAssignment: formatString = "{0} assignment{1} to MSBuild property {2}"; break; case ReferenceKind.MSBuildPropertyUsage: formatString = "{0} usage{1} of MSBuild property {2}"; break; case ReferenceKind.MSBuildItemAssignment: formatString = "{0} assignment{1} to MSBuild item {2}"; break; case ReferenceKind.MSBuildItemUsage: formatString = "{0} usage{1} of MSBuild item {2}"; break; case ReferenceKind.MSBuildTargetDeclaration: formatString = "{0} declaration{1} of MSBuild target {2}"; break; case ReferenceKind.MSBuildTargetUsage: formatString = "{0} usage{1} of MSBuild target {2}"; break; case ReferenceKind.MSBuildTaskDeclaration: formatString = "{0} import{1} of MSBuild task {2}"; break; case ReferenceKind.MSBuildTaskUsage: formatString = "{0} call{1} to MSBuild task {2}"; break; case ReferenceKind.Text: formatString = "{0} text search hit{1} for '{2}'"; break; default: throw new NotImplementedException("Missing case for " + referenceKind.Item1); } var referencesOfSameKind = referenceKind.Item2.OrderBy(g => g.Item1, StringComparer.OrdinalIgnoreCase); totalReferenceCount = CountItems(referenceKind); string headerText = string.Format( formatString, totalReferenceCount, totalReferenceCount == 1 ? "" : "s", symbolName); Write(writer, string.Format(@"<div class=""rH"" onclick=""ToggleExpandCollapse(this); return false;"">{0}</div>", headerText)); Write(writer, @"<div class=""rK"">"); foreach (var sameAssemblyReferencesGroup in referencesOfSameKind) { string assemblyName = sameAssemblyReferencesGroup.Item1; Write(writer, "<div class=\"rA\" onclick=\"ToggleExpandCollapse(this); return false;\">{0} ({1})</div>", assemblyName, CountItems(sameAssemblyReferencesGroup)); Write(writer, "<div class=\"rG\" id=\"{0}\">", assemblyName); foreach (var sameFileReferencesGroup in sameAssemblyReferencesGroup.Item2.OrderBy(g => g.Item1)) { Write(writer, "<div class=\"rF\">"); var fileName = sameFileReferencesGroup.Item1; var glyph = "url('content/icons/" + GetGlyph(fileName) + ".png');"; WriteLine(writer, "<div class=\"rN\" style=\"background-image: {2}\">{0} ({1})</div>", fileName, CountItems(sameFileReferencesGroup), glyph); foreach (var sameLineReferencesGroup in sameFileReferencesGroup.Item2) { var first = sameLineReferencesGroup.First(); var lineNumber = first.ReferringSpan.LineNumber + 1; string onClick = $@"LoadSourceCode('{first.ReferringProjectId}', '{first.ReferringFilePath.AsJavaScriptStringEncoded()}', null, '{lineNumber}');return false;"; var url = $"/?leftProject={definitionProjectId}&leftSymbol={symbolId}&rightProject={first.ReferringProjectId}&file={HttpUtility.UrlEncode(first.ReferringFilePath)}&line={lineNumber}"; Write(writer, "<a class=\"rL\" onclick=\"{0}\" href=\"{1}\">", onClick, url); Write(writer, "<b>{0}</b>", sameLineReferencesGroup.Key); MergeOccurrences(writer, sameLineReferencesGroup); WriteLine(writer, "</a>"); } WriteLine(writer, "</div>"); } WriteLine(writer, "</div>"); } WriteLine(writer, "</div>"); } return(writer.ToString()); } }