diff --git a/ScipDotnet.Tests/SnapshotTests.cs b/ScipDotnet.Tests/SnapshotTests.cs index fc66e41..43f8630 100644 --- a/ScipDotnet.Tests/SnapshotTests.cs +++ b/ScipDotnet.Tests/SnapshotTests.cs @@ -47,7 +47,7 @@ public void Snapshot(string inputDirectory) RecursivelyListFiles(outputDirectory, absoluteOutputPaths); foreach (var absolutePath in absoluteOutputPaths) { - if (!absolutePath.EndsWith(".cs")) + if (!IsSnapshotFile(absolutePath)) { continue; } @@ -79,6 +79,13 @@ public void Snapshot(string inputDirectory) } } + /// + /// Razor views (.cshtml) and Blazor components (.razor) are never compiled from disk, the + /// Razor source generator feeds them to the compiler, so they have their own snapshots. + /// + private static bool IsSnapshotFile(string path) => + path.EndsWith(".cs") || path.EndsWith(".cshtml") || path.EndsWith(".razor"); + private static void RecursivelyListFiles(string path, List result) { if (!Directory.Exists(path)) return; diff --git a/ScipDotnet/ScipDocumentIndexer.cs b/ScipDotnet/ScipDocumentIndexer.cs index 57a6e6d..e1ee02d 100644 --- a/ScipDotnet/ScipDocumentIndexer.cs +++ b/ScipDotnet/ScipDocumentIndexer.cs @@ -16,6 +16,7 @@ public class ScipDocumentIndexer private readonly Dictionary _globals; private readonly Dictionary _locals = new(SymbolEqualityComparer.Default); private readonly string _markdownCodeFenceLanguage; + private readonly string? _originalFilePath; // Custom formatting options to render symbol documentation. Feel free to tweak these parameters. // The options were derived by multiple rounds of experimentation with the goal of striking a @@ -56,14 +57,22 @@ public class ScipDocumentIndexer SymbolDisplayMiscellaneousOptions.EscapeKeywordIdentifiers ); + /// + /// When non-null, only record the occurrences that #line directives attribute to + /// this file. Source generated documents such as the C# that the Razor generator emits for a + /// .cshtml file are a mixture of generated boilerplate and code the developer wrote, and only + /// the latter belongs in the index. + /// public ScipDocumentIndexer( Document doc, IndexCommandOptions options, - Dictionary globals) + Dictionary globals, + string? originalFilePath = null) { _doc = doc; _options = options; _globals = globals; + _originalFilePath = originalFilePath; _markdownCodeFenceLanguage = _doc.Language == "C#" ? "cs" : "vb"; } @@ -220,6 +229,12 @@ public void VisitOccurrence(ISymbol? symbol, Location location, bool isDefinitio return; } + if (_originalFilePath != null && + !string.Equals(location.GetMappedLineSpan().Path, _originalFilePath, StringComparison.Ordinal)) + { + return; + } + var symbolRole = 0; if (isDefinition) { diff --git a/ScipDotnet/ScipProjectIndexer.cs b/ScipDotnet/ScipProjectIndexer.cs index 1f1debf..fc6eff8 100644 --- a/ScipDotnet/ScipProjectIndexer.cs +++ b/ScipDotnet/ScipProjectIndexer.cs @@ -120,9 +120,106 @@ await host.Services.GetRequiredService() document.FilePath); } } + + foreach (var document in await IndexSourceGeneratedDocuments(project, options, globals)) + { + yield return document; + } + } + } + + /// + /// Indexes the documents that the compiler synthesizes instead of reading from disk. + /// Razor views (.cshtml) and Blazor components (.razor) enter the compilation this way, + /// through the Razor source generator, so project.Documents never sees them. + /// + /// The generated C# lives under obj/ and usually does not exist on disk at all, + /// so reporting its path would produce an index full of files nobody can open. Instead we + /// follow the #line directives that the generator emits, group the occurrences + /// by the original file each one came from and report that file. Occurrences that map to + /// generated code rather than to a file the developer wrote are dropped. + /// + private async Task> IndexSourceGeneratedDocuments( + Project project, + IndexCommandOptions options, + Dictionary globals) + { + var documentsByOriginalPath = new Dictionary(); + var generatedDocuments = await project.GetSourceGeneratedDocumentsAsync(); + options.Logger.LogDebug($"Found {generatedDocuments.Count()} source generated documents in {project.FilePath}"); + foreach (var document in generatedDocuments) + { + var tree = await document.GetSyntaxTreeAsync(); + if (tree == null) + { + continue; + } + + foreach (var originalPath in OriginalFilePaths(tree)) + { + if (!options.Matcher.Match(options.WorkingDirectory.FullName, originalPath).HasMatches) + { + options.Logger.LogDebug( + "Excluded file path '{FilePath}' because it did not match the provided --include and --exclude arguments", + originalPath); + continue; + } + + if (!documentsByOriginalPath.TryGetValue(originalPath, out var doc)) + { + doc = new Scip.Document + { + Language = project.Language, + RelativePath = Path.GetRelativePath(options.WorkingDirectory.FullName, originalPath) + }; + documentsByOriginalPath.Add(originalPath, doc); + } + + await WalkDocument(doc, document, options, globals, project.Language, originalPath); + } } + + foreach (var doc in documentsByOriginalPath.Values) + { + RemoveDuplicates(doc); + } + + return documentsByOriginalPath.Values; + } + + /// + /// Removes the occurrences and symbols that we recorded more than once because several + /// generated files attribute the same region of the same original file to themselves. + /// + private static void RemoveDuplicates(Scip.Document doc) + { + var seenOccurrences = new HashSet(); + var occurrences = doc.Occurrences.Where(occurrence => seenOccurrences.Add(OccurrenceKey(occurrence))).ToList(); + doc.Occurrences.Clear(); + doc.Occurrences.AddRange(occurrences); + + var seenSymbols = new HashSet(); + var symbols = doc.Symbols.Where(symbol => seenSymbols.Add(symbol.Symbol)).ToList(); + doc.Symbols.Clear(); + doc.Symbols.AddRange(symbols); } + private static string OccurrenceKey(Scip.Occurrence occurrence) => + $"{occurrence.Symbol} {occurrence.SymbolRoles} {string.Join(",", occurrence.Range)}"; + + /// + /// Returns the files that a generated syntax tree attributes its contents to via + /// #line directives. A single generated Razor file can point at more than one + /// original file because directives from _ViewImports.cshtml are copied into + /// every view that inherits them. + /// + private static IEnumerable OriginalFilePaths(SyntaxTree tree) => + tree.GetLineMappings() + .Where(mapping => !mapping.IsHidden && mapping.MappedSpan.HasMappedPath) + .Select(mapping => mapping.MappedSpan.Path) + .Where(path => !string.IsNullOrEmpty(path) && File.Exists(path)) + .Distinct(); + private async Task IndexDocument(Document document, IndexCommandOptions options, Dictionary globals, @@ -135,29 +232,42 @@ await host.Services.GetRequiredService() ? null : Path.GetRelativePath(options.WorkingDirectory.FullName, document.FilePath) }; + await WalkDocument(doc, document, options, globals, language, originalFilePath: null); + return doc; + } + + /// + /// Walks and adds what it finds to . When + /// is non-null only the occurrences that #line + /// directives attribute to that file are recorded. + /// + private async Task WalkDocument(Scip.Document doc, + Document document, + IndexCommandOptions options, + Dictionary globals, + string language, + string? originalFilePath) + { var semanticModel = await document.GetSemanticModelAsync(); if (semanticModel == null) { Logger.LogWarning( "Skipping document {DocumentFilePath} because document.GetSemanticModelAsync() returned null", document.FilePath); + return; } - else + + var symbolFormatter = new ScipDocumentIndexer(doc, options, globals, originalFilePath); + var root = await document.GetSyntaxRootAsync(); + if (language == "C#") { - var symbolFormatter = new ScipDocumentIndexer(doc, options, globals); - var root = await document.GetSyntaxRootAsync(); - if (language == "C#") - { - var walker = new ScipCSharpSyntaxWalker(symbolFormatter, semanticModel); - walker.Visit(root); - } - else if (language == "Visual Basic") - { - var walker = new ScipVisualBasicSyntaxWalker(symbolFormatter, semanticModel); - walker.Visit(root); - } + var walker = new ScipCSharpSyntaxWalker(symbolFormatter, semanticModel); + walker.Visit(root); + } + else if (language == "Visual Basic") + { + var walker = new ScipVisualBasicSyntaxWalker(symbolFormatter, semanticModel); + walker.Visit(root); } - - return doc; } } \ No newline at end of file diff --git a/snapshots/input/razor/RazorApp/Components/Counter.razor b/snapshots/input/razor/RazorApp/Components/Counter.razor new file mode 100644 index 0000000..dc7f2c3 --- /dev/null +++ b/snapshots/input/razor/RazorApp/Components/Counter.razor @@ -0,0 +1,12 @@ +

Current count: @CurrentCount

+ + + +@code { + private int CurrentCount { get; set; } + + private void Increment() + { + CurrentCount++; + } +} diff --git a/snapshots/input/razor/RazorApp/Components/_Imports.razor b/snapshots/input/razor/RazorApp/Components/_Imports.razor new file mode 100644 index 0000000..66ebfa5 --- /dev/null +++ b/snapshots/input/razor/RazorApp/Components/_Imports.razor @@ -0,0 +1 @@ +@using Microsoft.AspNetCore.Components.Web diff --git a/snapshots/input/razor/RazorApp/Pages/Index.cshtml b/snapshots/input/razor/RazorApp/Pages/Index.cshtml new file mode 100644 index 0000000..838740b --- /dev/null +++ b/snapshots/input/razor/RazorApp/Pages/Index.cshtml @@ -0,0 +1,14 @@ +@page +@model IndexModel +@{ + ViewData["Title"] = Model.Greeting; +} + +

@Model.Greeting

+

@Model.Shout("world")

+ +@functions { + private static string Loud(string text) => text.ToUpperInvariant(); +} + +

@Loud(Model.Greeting)

diff --git a/snapshots/input/razor/RazorApp/Pages/Index.cshtml.cs b/snapshots/input/razor/RazorApp/Pages/Index.cshtml.cs new file mode 100644 index 0000000..68c1d0b --- /dev/null +++ b/snapshots/input/razor/RazorApp/Pages/Index.cshtml.cs @@ -0,0 +1,15 @@ +using Microsoft.AspNetCore.Mvc.RazorPages; + +namespace RazorApp.Pages; + +public class IndexModel : PageModel +{ + public string Greeting { get; set; } = "Hello"; + + public string Shout(string name) => $"{Greeting}, {name}!"; + + public void OnGet() + { + Greeting = "Welcome"; + } +} diff --git a/snapshots/input/razor/RazorApp/Pages/_ViewImports.cshtml b/snapshots/input/razor/RazorApp/Pages/_ViewImports.cshtml new file mode 100644 index 0000000..818ab4a --- /dev/null +++ b/snapshots/input/razor/RazorApp/Pages/_ViewImports.cshtml @@ -0,0 +1,2 @@ +@using RazorApp.Pages +@addTagHelper *, Microsoft.AspNetCore.Mvc.TagHelpers diff --git a/snapshots/input/razor/RazorApp/Program.cs b/snapshots/input/razor/RazorApp/Program.cs new file mode 100644 index 0000000..a0c36ea --- /dev/null +++ b/snapshots/input/razor/RazorApp/Program.cs @@ -0,0 +1,5 @@ +var builder = WebApplication.CreateBuilder(args); +builder.Services.AddRazorPages(); +var app = builder.Build(); +app.MapRazorPages(); +app.Run(); diff --git a/snapshots/input/razor/RazorApp/RazorApp.csproj b/snapshots/input/razor/RazorApp/RazorApp.csproj new file mode 100644 index 0000000..834a1f1 --- /dev/null +++ b/snapshots/input/razor/RazorApp/RazorApp.csproj @@ -0,0 +1,9 @@ + + + + net10.0;net9.0;net8.0 + enable + enable + + + diff --git a/snapshots/input/razor/razor.sln b/snapshots/input/razor/razor.sln new file mode 100644 index 0000000..6473699 --- /dev/null +++ b/snapshots/input/razor/razor.sln @@ -0,0 +1,34 @@ + +Microsoft Visual Studio Solution File, Format Version 12.00 +# Visual Studio Version 17 +VisualStudioVersion = 17.0.31903.59 +MinimumVisualStudioVersion = 10.0.40219.1 +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "RazorApp", "RazorApp\RazorApp.csproj", "{2E0B95A8-D543-4F39-8618-4E1BE8AE024B}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Any CPU = Debug|Any CPU + Debug|x64 = Debug|x64 + Debug|x86 = Debug|x86 + Release|Any CPU = Release|Any CPU + Release|x64 = Release|x64 + Release|x86 = Release|x86 + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {2E0B95A8-D543-4F39-8618-4E1BE8AE024B}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {2E0B95A8-D543-4F39-8618-4E1BE8AE024B}.Debug|Any CPU.Build.0 = Debug|Any CPU + {2E0B95A8-D543-4F39-8618-4E1BE8AE024B}.Debug|x64.ActiveCfg = Debug|Any CPU + {2E0B95A8-D543-4F39-8618-4E1BE8AE024B}.Debug|x64.Build.0 = Debug|Any CPU + {2E0B95A8-D543-4F39-8618-4E1BE8AE024B}.Debug|x86.ActiveCfg = Debug|Any CPU + {2E0B95A8-D543-4F39-8618-4E1BE8AE024B}.Debug|x86.Build.0 = Debug|Any CPU + {2E0B95A8-D543-4F39-8618-4E1BE8AE024B}.Release|Any CPU.ActiveCfg = Release|Any CPU + {2E0B95A8-D543-4F39-8618-4E1BE8AE024B}.Release|Any CPU.Build.0 = Release|Any CPU + {2E0B95A8-D543-4F39-8618-4E1BE8AE024B}.Release|x64.ActiveCfg = Release|Any CPU + {2E0B95A8-D543-4F39-8618-4E1BE8AE024B}.Release|x64.Build.0 = Release|Any CPU + {2E0B95A8-D543-4F39-8618-4E1BE8AE024B}.Release|x86.ActiveCfg = Release|Any CPU + {2E0B95A8-D543-4F39-8618-4E1BE8AE024B}.Release|x86.Build.0 = Release|Any CPU + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection +EndGlobal diff --git a/snapshots/output-net10.0/razor/RazorApp/Components/Counter.razor b/snapshots/output-net10.0/razor/RazorApp/Components/Counter.razor new file mode 100644 index 0000000..a81f03a --- /dev/null +++ b/snapshots/output-net10.0/razor/RazorApp/Components/Counter.razor @@ -0,0 +1,21 @@ +

Current count: @CurrentCount

+// ^^^^^^^^^^^^ reference scip-dotnet nuget . . Components/Counter#CurrentCount. +// ^^^^^^^^^^^^^ reference scip-dotnet nuget . . Components/Counter#BuildRenderTree().(__builder) +// ^^^^^^^^^^^^^ reference scip-dotnet nuget Microsoft.AspNetCore.Components 10.0.0.0 Rendering/RenderTreeBuilder#AddContent(+5). + + +// ^^^^^^^^^ reference scip-dotnet nuget . . Components/Counter#Increment(). + + @code { + private int CurrentCount { get; set; } +// ^^^^^^^^^^^^ definition scip-dotnet nuget . . Components/Counter#CurrentCount. +// documentation ```cs\nprivate int Counter.CurrentCount { get; set; }\n``` + + private void Increment() +// ^^^^^^^^^ definition scip-dotnet nuget . . Components/Counter#Increment(). +// documentation ```cs\nprivate void Counter.Increment()\n``` + { + CurrentCount++; +// ^^^^^^^^^^^^ reference scip-dotnet nuget . . Components/Counter#CurrentCount. + } + } diff --git a/snapshots/output-net10.0/razor/RazorApp/Components/_Imports.razor b/snapshots/output-net10.0/razor/RazorApp/Components/_Imports.razor new file mode 100644 index 0000000..5f64de2 --- /dev/null +++ b/snapshots/output-net10.0/razor/RazorApp/Components/_Imports.razor @@ -0,0 +1,5 @@ + @using Microsoft.AspNetCore.Components.Web +// ^^^^^^^^^ reference scip-dotnet nuget . . Microsoft/ +// ^^^^^^^^^^ reference scip-dotnet nuget . . AspNetCore/ +// ^^^^^^^^^^ reference scip-dotnet nuget . . Components/ +// ^^^ reference scip-dotnet nuget . . Web/ diff --git a/snapshots/output-net10.0/razor/RazorApp/Pages/Index.cshtml b/snapshots/output-net10.0/razor/RazorApp/Pages/Index.cshtml new file mode 100644 index 0000000..094c74a --- /dev/null +++ b/snapshots/output-net10.0/razor/RazorApp/Pages/Index.cshtml @@ -0,0 +1,31 @@ + @page + @model IndexModel +// ^^^^^^^^^^ reference scip-dotnet nuget . . Pages/IndexModel# + @{ + ViewData["Title"] = Model.Greeting; +// ^^^^^^^^ reference scip-dotnet nuget . . AspNetCoreGeneratedDocument/Pages_Index#ViewData. +// ^^^^^ reference scip-dotnet nuget . . AspNetCoreGeneratedDocument/Pages_Index#Model. +// ^^^^^^^^ reference scip-dotnet nuget . . Pages/IndexModel#Greeting. + } + +

@Model.Greeting

+// ^^^^^ reference scip-dotnet nuget . . AspNetCoreGeneratedDocument/Pages_Index#Model. +// ^^^^^^^^ reference scip-dotnet nuget . . Pages/IndexModel#Greeting. +

@Model.Shout("world")

+// ^^^^^ reference scip-dotnet nuget . . AspNetCoreGeneratedDocument/Pages_Index#Model. +// ^^^^^ reference scip-dotnet nuget . . Pages/IndexModel#Shout(). + + @functions { + private static string Loud(string text) => text.ToUpperInvariant(); +// ^^^^ definition scip-dotnet nuget . . AspNetCoreGeneratedDocument/Pages_Index#Loud(). +// documentation ```cs\nprivate static string Pages_Index.Loud(string text)\n``` +// ^^^^ definition scip-dotnet nuget . . AspNetCoreGeneratedDocument/Pages_Index#Loud().(text) +// documentation ```cs\nstring text\n``` +// ^^^^ reference scip-dotnet nuget . . AspNetCoreGeneratedDocument/Pages_Index#Loud().(text) +// ^^^^^^^^^^^^^^^^ reference scip-dotnet nuget System.Runtime 10.0.0.0 System/String#ToUpperInvariant(). + } + +

@Loud(Model.Greeting)

+// ^^^^ reference scip-dotnet nuget . . AspNetCoreGeneratedDocument/Pages_Index#Loud(). +// ^^^^^ reference scip-dotnet nuget . . AspNetCoreGeneratedDocument/Pages_Index#Model. +// ^^^^^^^^ reference scip-dotnet nuget . . Pages/IndexModel#Greeting. diff --git a/snapshots/output-net10.0/razor/RazorApp/Pages/Index.cshtml.cs b/snapshots/output-net10.0/razor/RazorApp/Pages/Index.cshtml.cs new file mode 100644 index 0000000..a29d651 --- /dev/null +++ b/snapshots/output-net10.0/razor/RazorApp/Pages/Index.cshtml.cs @@ -0,0 +1,39 @@ + using Microsoft.AspNetCore.Mvc.RazorPages; +// ^^^^^^^^^ reference scip-dotnet nuget . . Microsoft/ +// ^^^^^^^^^^ reference scip-dotnet nuget . . AspNetCore/ +// ^^^ reference scip-dotnet nuget . . Mvc/ +// ^^^^^^^^^^ reference scip-dotnet nuget Microsoft.AspNetCore.Mvc.RazorPages 10.0.0.0 RazorPages/ + + namespace RazorApp.Pages; +// ^^^^^^^^ reference scip-dotnet nuget . . RazorApp/ +// ^^^^^ reference scip-dotnet nuget . . Pages/ + + public class IndexModel : PageModel +// ^^^^^^^^^^ definition scip-dotnet nuget . . Pages/IndexModel# +// documentation ```cs\nclass IndexModel\n``` +// relationship implementation scip-dotnet nuget Microsoft.AspNetCore.Mvc.RazorPages 10.0.0.0 RazorPages/PageModel# +// relationship implementation scip-dotnet nuget Microsoft.AspNetCore.Mvc.RazorPages 10.0.0.0 Filters/IAsyncPageFilter# +// relationship implementation scip-dotnet nuget Microsoft.AspNetCore.Mvc.RazorPages 10.0.0.0 Filters/IPageFilter# +// relationship implementation scip-dotnet nuget Microsoft.AspNetCore.Mvc.Abstractions 10.0.0.0 Filters/IFilterMetadata# +// ^^^^^^^^^ reference scip-dotnet nuget Microsoft.AspNetCore.Mvc.RazorPages 10.0.0.0 RazorPages/PageModel# + { + public string Greeting { get; set; } = "Hello"; +// ^^^^^^^^ definition scip-dotnet nuget . . Pages/IndexModel#Greeting. +// documentation ```cs\npublic string IndexModel.Greeting { get; set; }\n``` + + public string Shout(string name) => $"{Greeting}, {name}!"; +// ^^^^^ definition scip-dotnet nuget . . Pages/IndexModel#Shout(). +// documentation ```cs\npublic string IndexModel.Shout(string name)\n``` +// ^^^^ definition scip-dotnet nuget . . Pages/IndexModel#Shout().(name) +// documentation ```cs\nstring name\n``` +// ^^^^^^^^ reference scip-dotnet nuget . . Pages/IndexModel#Greeting. +// ^^^^ reference scip-dotnet nuget . . Pages/IndexModel#Shout().(name) + + public void OnGet() +// ^^^^^ definition scip-dotnet nuget . . Pages/IndexModel#OnGet(). +// documentation ```cs\npublic void IndexModel.OnGet()\n``` + { + Greeting = "Welcome"; +// ^^^^^^^^ reference scip-dotnet nuget . . Pages/IndexModel#Greeting. + } + } diff --git a/snapshots/output-net10.0/razor/RazorApp/Pages/_ViewImports.cshtml b/snapshots/output-net10.0/razor/RazorApp/Pages/_ViewImports.cshtml new file mode 100644 index 0000000..c93fb2f --- /dev/null +++ b/snapshots/output-net10.0/razor/RazorApp/Pages/_ViewImports.cshtml @@ -0,0 +1,4 @@ + @using RazorApp.Pages +// ^^^^^^^^ reference scip-dotnet nuget . . RazorApp/ +// ^^^^^ reference scip-dotnet nuget . . Pages/ + @addTagHelper *, Microsoft.AspNetCore.Mvc.TagHelpers diff --git a/snapshots/output-net10.0/razor/RazorApp/Program.cs b/snapshots/output-net10.0/razor/RazorApp/Program.cs new file mode 100644 index 0000000..5bed378 --- /dev/null +++ b/snapshots/output-net10.0/razor/RazorApp/Program.cs @@ -0,0 +1,21 @@ + var builder = WebApplication.CreateBuilder(args); +// ^^^^^^^ definition local 0 +// documentation ```cs\nWebApplicationBuilder? builder\n``` +// ^^^^^^^^^^^^^^ reference scip-dotnet nuget Microsoft.AspNetCore 10.0.0.0 Builder/WebApplication# +// ^^^^^^^^^^^^^ reference scip-dotnet nuget Microsoft.AspNetCore 10.0.0.0 Builder/WebApplication#CreateBuilder(+1). +// ^^^^ reference scip-dotnet nuget . . ``/Program#`
$`().(args) + builder.Services.AddRazorPages(); +//^^^^^^^ reference local 0 +// ^^^^^^^^ reference scip-dotnet nuget Microsoft.AspNetCore 10.0.0.0 Builder/WebApplicationBuilder#Services. +// ^^^^^^^^^^^^^ reference scip-dotnet nuget Microsoft.AspNetCore.Mvc 10.0.0.0 DependencyInjection/MvcServiceCollectionExtensions#AddRazorPages(). + var app = builder.Build(); +// ^^^ definition local 1 +// documentation ```cs\nWebApplication? app\n``` +// ^^^^^^^ reference local 0 +// ^^^^^ reference scip-dotnet nuget Microsoft.AspNetCore 10.0.0.0 Builder/WebApplicationBuilder#Build(). + app.MapRazorPages(); +//^^^ reference local 1 +// ^^^^^^^^^^^^^ reference scip-dotnet nuget Microsoft.AspNetCore.Mvc.RazorPages 10.0.0.0 Builder/RazorPagesEndpointRouteBuilderExtensions#MapRazorPages(). + app.Run(); +//^^^ reference local 1 +// ^^^ reference scip-dotnet nuget Microsoft.AspNetCore 10.0.0.0 Builder/WebApplication#Run(). diff --git a/snapshots/output-net8.0/razor/RazorApp/Components/Counter.razor b/snapshots/output-net8.0/razor/RazorApp/Components/Counter.razor new file mode 100644 index 0000000..8481e71 --- /dev/null +++ b/snapshots/output-net8.0/razor/RazorApp/Components/Counter.razor @@ -0,0 +1,21 @@ +

Current count: @CurrentCount

+// ^^^^^^^^^^^^ reference scip-dotnet nuget . . Components/Counter#CurrentCount. +// ^^^^^^^^^^^^^ reference scip-dotnet nuget . . Components/Counter#BuildRenderTree().(__builder) +// ^^^^^^^^^^^^^ reference scip-dotnet nuget Microsoft.AspNetCore.Components 8.0.0.0 Rendering/RenderTreeBuilder#AddContent(+5). + + +// ^^^^^^^^^ reference scip-dotnet nuget . . Components/Counter#Increment(). + + @code { + private int CurrentCount { get; set; } +// ^^^^^^^^^^^^ definition scip-dotnet nuget . . Components/Counter#CurrentCount. +// documentation ```cs\nprivate int Counter.CurrentCount { get; set; }\n``` + + private void Increment() +// ^^^^^^^^^ definition scip-dotnet nuget . . Components/Counter#Increment(). +// documentation ```cs\nprivate void Counter.Increment()\n``` + { + CurrentCount++; +// ^^^^^^^^^^^^ reference scip-dotnet nuget . . Components/Counter#CurrentCount. + } + } diff --git a/snapshots/output-net8.0/razor/RazorApp/Components/_Imports.razor b/snapshots/output-net8.0/razor/RazorApp/Components/_Imports.razor new file mode 100644 index 0000000..5f64de2 --- /dev/null +++ b/snapshots/output-net8.0/razor/RazorApp/Components/_Imports.razor @@ -0,0 +1,5 @@ + @using Microsoft.AspNetCore.Components.Web +// ^^^^^^^^^ reference scip-dotnet nuget . . Microsoft/ +// ^^^^^^^^^^ reference scip-dotnet nuget . . AspNetCore/ +// ^^^^^^^^^^ reference scip-dotnet nuget . . Components/ +// ^^^ reference scip-dotnet nuget . . Web/ diff --git a/snapshots/output-net8.0/razor/RazorApp/Pages/Index.cshtml b/snapshots/output-net8.0/razor/RazorApp/Pages/Index.cshtml new file mode 100644 index 0000000..bf955f8 --- /dev/null +++ b/snapshots/output-net8.0/razor/RazorApp/Pages/Index.cshtml @@ -0,0 +1,30 @@ + @page + @model IndexModel + @{ + ViewData["Title"] = Model.Greeting; +// ^^^^^^^^ reference scip-dotnet nuget . . AspNetCoreGeneratedDocument/Pages_Index#ViewData. +// ^^^^^ reference scip-dotnet nuget . . AspNetCoreGeneratedDocument/Pages_Index#Model. +// ^^^^^^^^ reference scip-dotnet nuget . . Pages/IndexModel#Greeting. + } + +

@Model.Greeting

+// ^^^^^ reference scip-dotnet nuget . . AspNetCoreGeneratedDocument/Pages_Index#Model. +// ^^^^^^^^ reference scip-dotnet nuget . . Pages/IndexModel#Greeting. +

@Model.Shout("world")

+// ^^^^^ reference scip-dotnet nuget . . AspNetCoreGeneratedDocument/Pages_Index#Model. +// ^^^^^ reference scip-dotnet nuget . . Pages/IndexModel#Shout(). + + @functions { + private static string Loud(string text) => text.ToUpperInvariant(); +// ^^^^ definition scip-dotnet nuget . . AspNetCoreGeneratedDocument/Pages_Index#Loud(). +// documentation ```cs\nprivate static string Pages_Index.Loud(string text)\n``` +// ^^^^ definition scip-dotnet nuget . . AspNetCoreGeneratedDocument/Pages_Index#Loud().(text) +// documentation ```cs\nstring text\n``` +// ^^^^ reference scip-dotnet nuget . . AspNetCoreGeneratedDocument/Pages_Index#Loud().(text) +// ^^^^^^^^^^^^^^^^ reference scip-dotnet nuget System.Runtime 8.0.0.0 System/String#ToUpperInvariant(). + } + +

@Loud(Model.Greeting)

+// ^^^^ reference scip-dotnet nuget . . AspNetCoreGeneratedDocument/Pages_Index#Loud(). +// ^^^^^ reference scip-dotnet nuget . . AspNetCoreGeneratedDocument/Pages_Index#Model. +// ^^^^^^^^ reference scip-dotnet nuget . . Pages/IndexModel#Greeting. diff --git a/snapshots/output-net8.0/razor/RazorApp/Pages/Index.cshtml.cs b/snapshots/output-net8.0/razor/RazorApp/Pages/Index.cshtml.cs new file mode 100644 index 0000000..efdcd55 --- /dev/null +++ b/snapshots/output-net8.0/razor/RazorApp/Pages/Index.cshtml.cs @@ -0,0 +1,39 @@ + using Microsoft.AspNetCore.Mvc.RazorPages; +// ^^^^^^^^^ reference scip-dotnet nuget . . Microsoft/ +// ^^^^^^^^^^ reference scip-dotnet nuget . . AspNetCore/ +// ^^^ reference scip-dotnet nuget . . Mvc/ +// ^^^^^^^^^^ reference scip-dotnet nuget Microsoft.AspNetCore.Mvc.RazorPages 8.0.0.0 RazorPages/ + + namespace RazorApp.Pages; +// ^^^^^^^^ reference scip-dotnet nuget . . RazorApp/ +// ^^^^^ reference scip-dotnet nuget . . Pages/ + + public class IndexModel : PageModel +// ^^^^^^^^^^ definition scip-dotnet nuget . . Pages/IndexModel# +// documentation ```cs\nclass IndexModel\n``` +// relationship implementation scip-dotnet nuget Microsoft.AspNetCore.Mvc.RazorPages 8.0.0.0 RazorPages/PageModel# +// relationship implementation scip-dotnet nuget Microsoft.AspNetCore.Mvc.RazorPages 8.0.0.0 Filters/IAsyncPageFilter# +// relationship implementation scip-dotnet nuget Microsoft.AspNetCore.Mvc.RazorPages 8.0.0.0 Filters/IPageFilter# +// relationship implementation scip-dotnet nuget Microsoft.AspNetCore.Mvc.Abstractions 8.0.0.0 Filters/IFilterMetadata# +// ^^^^^^^^^ reference scip-dotnet nuget Microsoft.AspNetCore.Mvc.RazorPages 8.0.0.0 RazorPages/PageModel# + { + public string Greeting { get; set; } = "Hello"; +// ^^^^^^^^ definition scip-dotnet nuget . . Pages/IndexModel#Greeting. +// documentation ```cs\npublic string IndexModel.Greeting { get; set; }\n``` + + public string Shout(string name) => $"{Greeting}, {name}!"; +// ^^^^^ definition scip-dotnet nuget . . Pages/IndexModel#Shout(). +// documentation ```cs\npublic string IndexModel.Shout(string name)\n``` +// ^^^^ definition scip-dotnet nuget . . Pages/IndexModel#Shout().(name) +// documentation ```cs\nstring name\n``` +// ^^^^^^^^ reference scip-dotnet nuget . . Pages/IndexModel#Greeting. +// ^^^^ reference scip-dotnet nuget . . Pages/IndexModel#Shout().(name) + + public void OnGet() +// ^^^^^ definition scip-dotnet nuget . . Pages/IndexModel#OnGet(). +// documentation ```cs\npublic void IndexModel.OnGet()\n``` + { + Greeting = "Welcome"; +// ^^^^^^^^ reference scip-dotnet nuget . . Pages/IndexModel#Greeting. + } + } diff --git a/snapshots/output-net8.0/razor/RazorApp/Pages/_ViewImports.cshtml b/snapshots/output-net8.0/razor/RazorApp/Pages/_ViewImports.cshtml new file mode 100644 index 0000000..c93fb2f --- /dev/null +++ b/snapshots/output-net8.0/razor/RazorApp/Pages/_ViewImports.cshtml @@ -0,0 +1,4 @@ + @using RazorApp.Pages +// ^^^^^^^^ reference scip-dotnet nuget . . RazorApp/ +// ^^^^^ reference scip-dotnet nuget . . Pages/ + @addTagHelper *, Microsoft.AspNetCore.Mvc.TagHelpers diff --git a/snapshots/output-net8.0/razor/RazorApp/Program.cs b/snapshots/output-net8.0/razor/RazorApp/Program.cs new file mode 100644 index 0000000..867e4ed --- /dev/null +++ b/snapshots/output-net8.0/razor/RazorApp/Program.cs @@ -0,0 +1,21 @@ + var builder = WebApplication.CreateBuilder(args); +// ^^^^^^^ definition local 0 +// documentation ```cs\nWebApplicationBuilder? builder\n``` +// ^^^^^^^^^^^^^^ reference scip-dotnet nuget Microsoft.AspNetCore 8.0.0.0 Builder/WebApplication# +// ^^^^^^^^^^^^^ reference scip-dotnet nuget Microsoft.AspNetCore 8.0.0.0 Builder/WebApplication#CreateBuilder(+1). +// ^^^^ reference scip-dotnet nuget . . ``/Program#`
$`().(args) + builder.Services.AddRazorPages(); +//^^^^^^^ reference local 0 +// ^^^^^^^^ reference scip-dotnet nuget Microsoft.AspNetCore 8.0.0.0 Builder/WebApplicationBuilder#Services. +// ^^^^^^^^^^^^^ reference scip-dotnet nuget Microsoft.AspNetCore.Mvc 8.0.0.0 DependencyInjection/MvcServiceCollectionExtensions#AddRazorPages(). + var app = builder.Build(); +// ^^^ definition local 1 +// documentation ```cs\nWebApplication? app\n``` +// ^^^^^^^ reference local 0 +// ^^^^^ reference scip-dotnet nuget Microsoft.AspNetCore 8.0.0.0 Builder/WebApplicationBuilder#Build(). + app.MapRazorPages(); +//^^^ reference local 1 +// ^^^^^^^^^^^^^ reference scip-dotnet nuget Microsoft.AspNetCore.Mvc.RazorPages 8.0.0.0 Builder/RazorPagesEndpointRouteBuilderExtensions#MapRazorPages(). + app.Run(); +//^^^ reference local 1 +// ^^^ reference scip-dotnet nuget Microsoft.AspNetCore 8.0.0.0 Builder/WebApplication#Run(). diff --git a/snapshots/output-net9.0/razor/RazorApp/Components/Counter.razor b/snapshots/output-net9.0/razor/RazorApp/Components/Counter.razor new file mode 100644 index 0000000..4eb35d6 --- /dev/null +++ b/snapshots/output-net9.0/razor/RazorApp/Components/Counter.razor @@ -0,0 +1,21 @@ +

Current count: @CurrentCount

+// ^^^^^^^^^^^^ reference scip-dotnet nuget . . Components/Counter#CurrentCount. +// ^^^^^^^^^^^^^ reference scip-dotnet nuget . . Components/Counter#BuildRenderTree().(__builder) +// ^^^^^^^^^^^^^ reference scip-dotnet nuget Microsoft.AspNetCore.Components 9.0.0.0 Rendering/RenderTreeBuilder#AddContent(+5). + + +// ^^^^^^^^^ reference scip-dotnet nuget . . Components/Counter#Increment(). + + @code { + private int CurrentCount { get; set; } +// ^^^^^^^^^^^^ definition scip-dotnet nuget . . Components/Counter#CurrentCount. +// documentation ```cs\nprivate int Counter.CurrentCount { get; set; }\n``` + + private void Increment() +// ^^^^^^^^^ definition scip-dotnet nuget . . Components/Counter#Increment(). +// documentation ```cs\nprivate void Counter.Increment()\n``` + { + CurrentCount++; +// ^^^^^^^^^^^^ reference scip-dotnet nuget . . Components/Counter#CurrentCount. + } + } diff --git a/snapshots/output-net9.0/razor/RazorApp/Components/_Imports.razor b/snapshots/output-net9.0/razor/RazorApp/Components/_Imports.razor new file mode 100644 index 0000000..5f64de2 --- /dev/null +++ b/snapshots/output-net9.0/razor/RazorApp/Components/_Imports.razor @@ -0,0 +1,5 @@ + @using Microsoft.AspNetCore.Components.Web +// ^^^^^^^^^ reference scip-dotnet nuget . . Microsoft/ +// ^^^^^^^^^^ reference scip-dotnet nuget . . AspNetCore/ +// ^^^^^^^^^^ reference scip-dotnet nuget . . Components/ +// ^^^ reference scip-dotnet nuget . . Web/ diff --git a/snapshots/output-net9.0/razor/RazorApp/Pages/Index.cshtml b/snapshots/output-net9.0/razor/RazorApp/Pages/Index.cshtml new file mode 100644 index 0000000..484583f --- /dev/null +++ b/snapshots/output-net9.0/razor/RazorApp/Pages/Index.cshtml @@ -0,0 +1,31 @@ + @page + @model IndexModel +// ^^^^^^^^^^ reference scip-dotnet nuget . . Pages/IndexModel# + @{ + ViewData["Title"] = Model.Greeting; +// ^^^^^^^^ reference scip-dotnet nuget . . AspNetCoreGeneratedDocument/Pages_Index#ViewData. +// ^^^^^ reference scip-dotnet nuget . . AspNetCoreGeneratedDocument/Pages_Index#Model. +// ^^^^^^^^ reference scip-dotnet nuget . . Pages/IndexModel#Greeting. + } + +

@Model.Greeting

+// ^^^^^ reference scip-dotnet nuget . . AspNetCoreGeneratedDocument/Pages_Index#Model. +// ^^^^^^^^ reference scip-dotnet nuget . . Pages/IndexModel#Greeting. +

@Model.Shout("world")

+// ^^^^^ reference scip-dotnet nuget . . AspNetCoreGeneratedDocument/Pages_Index#Model. +// ^^^^^ reference scip-dotnet nuget . . Pages/IndexModel#Shout(). + + @functions { + private static string Loud(string text) => text.ToUpperInvariant(); +// ^^^^ definition scip-dotnet nuget . . AspNetCoreGeneratedDocument/Pages_Index#Loud(). +// documentation ```cs\nprivate static string Pages_Index.Loud(string text)\n``` +// ^^^^ definition scip-dotnet nuget . . AspNetCoreGeneratedDocument/Pages_Index#Loud().(text) +// documentation ```cs\nstring text\n``` +// ^^^^ reference scip-dotnet nuget . . AspNetCoreGeneratedDocument/Pages_Index#Loud().(text) +// ^^^^^^^^^^^^^^^^ reference scip-dotnet nuget System.Runtime 9.0.0.0 System/String#ToUpperInvariant(). + } + +

@Loud(Model.Greeting)

+// ^^^^ reference scip-dotnet nuget . . AspNetCoreGeneratedDocument/Pages_Index#Loud(). +// ^^^^^ reference scip-dotnet nuget . . AspNetCoreGeneratedDocument/Pages_Index#Model. +// ^^^^^^^^ reference scip-dotnet nuget . . Pages/IndexModel#Greeting. diff --git a/snapshots/output-net9.0/razor/RazorApp/Pages/Index.cshtml.cs b/snapshots/output-net9.0/razor/RazorApp/Pages/Index.cshtml.cs new file mode 100644 index 0000000..8902214 --- /dev/null +++ b/snapshots/output-net9.0/razor/RazorApp/Pages/Index.cshtml.cs @@ -0,0 +1,39 @@ + using Microsoft.AspNetCore.Mvc.RazorPages; +// ^^^^^^^^^ reference scip-dotnet nuget . . Microsoft/ +// ^^^^^^^^^^ reference scip-dotnet nuget . . AspNetCore/ +// ^^^ reference scip-dotnet nuget . . Mvc/ +// ^^^^^^^^^^ reference scip-dotnet nuget Microsoft.AspNetCore.Mvc.RazorPages 9.0.0.0 RazorPages/ + + namespace RazorApp.Pages; +// ^^^^^^^^ reference scip-dotnet nuget . . RazorApp/ +// ^^^^^ reference scip-dotnet nuget . . Pages/ + + public class IndexModel : PageModel +// ^^^^^^^^^^ definition scip-dotnet nuget . . Pages/IndexModel# +// documentation ```cs\nclass IndexModel\n``` +// relationship implementation scip-dotnet nuget Microsoft.AspNetCore.Mvc.RazorPages 9.0.0.0 RazorPages/PageModel# +// relationship implementation scip-dotnet nuget Microsoft.AspNetCore.Mvc.RazorPages 9.0.0.0 Filters/IAsyncPageFilter# +// relationship implementation scip-dotnet nuget Microsoft.AspNetCore.Mvc.RazorPages 9.0.0.0 Filters/IPageFilter# +// relationship implementation scip-dotnet nuget Microsoft.AspNetCore.Mvc.Abstractions 9.0.0.0 Filters/IFilterMetadata# +// ^^^^^^^^^ reference scip-dotnet nuget Microsoft.AspNetCore.Mvc.RazorPages 9.0.0.0 RazorPages/PageModel# + { + public string Greeting { get; set; } = "Hello"; +// ^^^^^^^^ definition scip-dotnet nuget . . Pages/IndexModel#Greeting. +// documentation ```cs\npublic string IndexModel.Greeting { get; set; }\n``` + + public string Shout(string name) => $"{Greeting}, {name}!"; +// ^^^^^ definition scip-dotnet nuget . . Pages/IndexModel#Shout(). +// documentation ```cs\npublic string IndexModel.Shout(string name)\n``` +// ^^^^ definition scip-dotnet nuget . . Pages/IndexModel#Shout().(name) +// documentation ```cs\nstring name\n``` +// ^^^^^^^^ reference scip-dotnet nuget . . Pages/IndexModel#Greeting. +// ^^^^ reference scip-dotnet nuget . . Pages/IndexModel#Shout().(name) + + public void OnGet() +// ^^^^^ definition scip-dotnet nuget . . Pages/IndexModel#OnGet(). +// documentation ```cs\npublic void IndexModel.OnGet()\n``` + { + Greeting = "Welcome"; +// ^^^^^^^^ reference scip-dotnet nuget . . Pages/IndexModel#Greeting. + } + } diff --git a/snapshots/output-net9.0/razor/RazorApp/Pages/_ViewImports.cshtml b/snapshots/output-net9.0/razor/RazorApp/Pages/_ViewImports.cshtml new file mode 100644 index 0000000..c93fb2f --- /dev/null +++ b/snapshots/output-net9.0/razor/RazorApp/Pages/_ViewImports.cshtml @@ -0,0 +1,4 @@ + @using RazorApp.Pages +// ^^^^^^^^ reference scip-dotnet nuget . . RazorApp/ +// ^^^^^ reference scip-dotnet nuget . . Pages/ + @addTagHelper *, Microsoft.AspNetCore.Mvc.TagHelpers diff --git a/snapshots/output-net9.0/razor/RazorApp/Program.cs b/snapshots/output-net9.0/razor/RazorApp/Program.cs new file mode 100644 index 0000000..bb17ae8 --- /dev/null +++ b/snapshots/output-net9.0/razor/RazorApp/Program.cs @@ -0,0 +1,21 @@ + var builder = WebApplication.CreateBuilder(args); +// ^^^^^^^ definition local 0 +// documentation ```cs\nWebApplicationBuilder? builder\n``` +// ^^^^^^^^^^^^^^ reference scip-dotnet nuget Microsoft.AspNetCore 9.0.0.0 Builder/WebApplication# +// ^^^^^^^^^^^^^ reference scip-dotnet nuget Microsoft.AspNetCore 9.0.0.0 Builder/WebApplication#CreateBuilder(+1). +// ^^^^ reference scip-dotnet nuget . . ``/Program#`
$`().(args) + builder.Services.AddRazorPages(); +//^^^^^^^ reference local 0 +// ^^^^^^^^ reference scip-dotnet nuget Microsoft.AspNetCore 9.0.0.0 Builder/WebApplicationBuilder#Services. +// ^^^^^^^^^^^^^ reference scip-dotnet nuget Microsoft.AspNetCore.Mvc 9.0.0.0 DependencyInjection/MvcServiceCollectionExtensions#AddRazorPages(). + var app = builder.Build(); +// ^^^ definition local 1 +// documentation ```cs\nWebApplication? app\n``` +// ^^^^^^^ reference local 0 +// ^^^^^ reference scip-dotnet nuget Microsoft.AspNetCore 9.0.0.0 Builder/WebApplicationBuilder#Build(). + app.MapRazorPages(); +//^^^ reference local 1 +// ^^^^^^^^^^^^^ reference scip-dotnet nuget Microsoft.AspNetCore.Mvc.RazorPages 9.0.0.0 Builder/RazorPagesEndpointRouteBuilderExtensions#MapRazorPages(). + app.Run(); +//^^^ reference local 1 +// ^^^ reference scip-dotnet nuget Microsoft.AspNetCore 9.0.0.0 Builder/WebApplication#Run().