diff --git a/src/CSharpLanguageServer/CSharpLanguageServer.fsproj b/src/CSharpLanguageServer/CSharpLanguageServer.fsproj
index 17671f98..4e6b6045 100644
--- a/src/CSharpLanguageServer/CSharpLanguageServer.fsproj
+++ b/src/CSharpLanguageServer/CSharpLanguageServer.fsproj
@@ -17,7 +17,6 @@
README.md
CHANGELOG.md
enable
- true
diff --git a/src/CSharpLanguageServer/Conversions.fs b/src/CSharpLanguageServer/Conversions.fs
index 7078593e..426366cc 100644
--- a/src/CSharpLanguageServer/Conversions.fs
+++ b/src/CSharpLanguageServer/Conversions.fs
@@ -88,6 +88,8 @@ module Location =
|> Option.bind (fun filePath -> if File.Exists filePath then Some filePath else None)
|> Option.map (fun filePath -> toLspLocation filePath (loc.GetLineSpan().Span))
+ //Console.Error.WriteLine("loc={0}; mapped={1}; source={2}", loc, mappedSourceLocation, sourceLocation)
+
mappedSourceLocation |> Option.orElse sourceLocation
| _ -> None
diff --git a/src/CSharpLanguageServer/Handlers/Completion.fs b/src/CSharpLanguageServer/Handlers/Completion.fs
index 6d16fb7e..fb3b3eff 100644
--- a/src/CSharpLanguageServer/Handlers/Completion.fs
+++ b/src/CSharpLanguageServer/Handlers/Completion.fs
@@ -3,19 +3,23 @@ namespace CSharpLanguageServer.Handlers
open System
open System.Reflection
+open Microsoft.CodeAnalysis
+open Microsoft.CodeAnalysis.Text
open Microsoft.Extensions.Caching.Memory
open Ionide.LanguageServerProtocol.Server
open Ionide.LanguageServerProtocol.Types
open Ionide.LanguageServerProtocol.JsonRpc
+open Microsoft.Extensions.Logging
open CSharpLanguageServer.State
open CSharpLanguageServer.Util
open CSharpLanguageServer.Conversions
open CSharpLanguageServer.Logging
+open CSharpLanguageServer.RoslynHelpers
[]
module Completion =
- let private _logger = Logging.getLoggerByName "Completion"
+ let private logger = Logging.getLoggerByName "Completion"
let private completionItemMemoryCache = new MemoryCache(new MemoryCacheOptions())
@@ -180,13 +184,99 @@ module Completion =
synopsis, documentationText
| _, _ -> None, None
- let handle
+ let getCompletionsForRazorDocument
+ (p: CompletionParams)
(context: ServerRequestContext)
+ : Async
diff --git a/tests/CSharpLanguageServer.Tests/CodeActionTests.fs b/tests/CSharpLanguageServer.Tests/CodeActionTests.fs
index 42de0f0c..fc2ed18c 100644
--- a/tests/CSharpLanguageServer.Tests/CodeActionTests.fs
+++ b/tests/CSharpLanguageServer.Tests/CodeActionTests.fs
@@ -124,5 +124,4 @@ let ``extract interface code action should extract an interface`` () =
Assert.AreEqual(expectedImplementInterfaceEdits, implementEdits |> TextEdit.normalizeNewText)
| _ -> failwith "Expected exactly one U2.C1 edit in both create/implement"
-
| _ -> failwith "Unexpected edit structure"
diff --git a/tests/CSharpLanguageServer.Tests/CompletionTests.fs b/tests/CSharpLanguageServer.Tests/CompletionTests.fs
index 24a65f77..1efc0ce9 100644
--- a/tests/CSharpLanguageServer.Tests/CompletionTests.fs
+++ b/tests/CSharpLanguageServer.Tests/CompletionTests.fs
@@ -136,3 +136,85 @@ let ``completion works for extension methods`` () =
Assert.IsFalse(itemResolved.Documentation.IsSome)
| _ -> failwith "Some U2.C1 was expected"
+
+
+[]
+let ``completion works in cshtml files`` () =
+ use client = activateFixture "aspnetProject"
+
+ use cshtmlFile = client.Open("Project/Views/Test/CompletionTests.cshtml")
+
+ let testCompletionResultContainsItem
+ line
+ character
+ expectedLabel
+ expectedCompletionItemKind
+ expectedDetail
+ documentationTestFn
+ =
+ let completionParams0: CompletionParams =
+ { TextDocument = { Uri = cshtmlFile.Uri }
+ Position = { Line = line; Character = character }
+ WorkDoneToken = None
+ PartialResultToken = None
+ Context = None }
+
+ let completion: U2 option =
+ client.Request("textDocument/completion", completionParams0)
+
+ match completion with
+ | Some(U2.C2 cl) ->
+ let expectedItem = cl.Items |> Seq.tryFind (fun i -> i.Label = expectedLabel)
+
+ match expectedItem with
+ | None -> failwithf "an item with Label '%s' was expected for completion at this position" expectedLabel
+ | Some item ->
+ Assert.AreEqual(expectedLabel, item.Label)
+ Assert.IsFalse(item.Detail.IsSome)
+ Assert.IsFalse(item.Documentation.IsSome)
+ Assert.AreEqual(Some expectedCompletionItemKind, item.Kind)
+
+ let itemResolved: CompletionItem = client.Request("completionItem/resolve", item)
+
+ Assert.AreEqual(Some expectedDetail, itemResolved.Detail)
+ Assert.IsTrue(documentationTestFn itemResolved.Documentation)
+
+ | _ -> failwith "Some U2.C1 was expected"
+
+ //
+ // 1st completion test: (@Model.|)
+ //
+ testCompletionResultContainsItem
+ 1u
+ 14u
+ "Output"
+ CompletionItemKind.Property
+ "string? Project.Models.Test.IndexViewModel.Output { get; set; }"
+ _.IsNone
+
+ //
+ // 2nd completion test: @Model.|
+ //
+ testCompletionResultContainsItem
+ 2u
+ 13u
+ "Output"
+ CompletionItemKind.Property
+ "string? Project.Models.Test.IndexViewModel.Output { get; set; }"
+ _.IsNone
+
+ //
+ // 3nd completion test: @Model.Output.|
+ //
+ testCompletionResultContainsItem 3u 13u "ToString" CompletionItemKind.Method "string? object.ToString()" _.IsSome
+
+ //
+ // 4nd completion test: x.
+ //
+ testCompletionResultContainsItem
+ 6u
+ 6u
+ "TryFormat"
+ CompletionItemKind.Method
+ "bool int.TryFormat(Span utf8Destination, out int bytesWritten, [ReadOnlySpan format = default], [IFormatProvider? provider = null])"
+ _.IsSome
diff --git a/tests/CSharpLanguageServer.Tests/DiagnosticTests.fs b/tests/CSharpLanguageServer.Tests/DiagnosticTests.fs
index 765ce983..39e13c0c 100644
--- a/tests/CSharpLanguageServer.Tests/DiagnosticTests.fs
+++ b/tests/CSharpLanguageServer.Tests/DiagnosticTests.fs
@@ -116,7 +116,37 @@ let testPullDiagnosticsWork () =
Assert.AreEqual(0, report.Items.Length)
| _ -> failwith "U2.C1 is expected"
- ()
+
+[]
+let testPullDiagnosticsWorkForRazorFiles () =
+ use client = activateFixture "aspnetProject"
+ use cshtmlFile = client.Open("Project/Views/Test/Index.cshtml")
+
+ let diagnosticParams: DocumentDiagnosticParams =
+ { WorkDoneToken = None
+ PartialResultToken = None
+ TextDocument = { Uri = cshtmlFile.Uri }
+ Identifier = None
+ PreviousResultId = None }
+
+ let report0: DocumentDiagnosticReport option =
+ client.Request("textDocument/diagnostic", diagnosticParams)
+
+ match report0 with
+ | Some(U2.C1 report) ->
+ Assert.AreEqual("full", report.Kind)
+ Assert.AreEqual(None, report.ResultId)
+ Assert.AreEqual(7, report.Items.Length)
+
+ let reportItems = report.Items |> Array.sortBy _.Range
+
+ let diagnostic0 = reportItems[0]
+ Assert.AreEqual(7, diagnostic0.Range.Start.Line)
+ Assert.AreEqual(4, diagnostic0.Range.Start.Character)
+ Assert.AreEqual(Some DiagnosticSeverity.Warning, diagnostic0.Severity)
+ Assert.AreEqual("Unnecessary using directive.", diagnostic0.Message)
+
+ | _ -> failwith "U2.C1 is expected"
[]
@@ -155,7 +185,7 @@ let testWorkspaceDiagnosticsWork () =
let testWorkspaceDiagnosticsWorkWithStreaming () =
use client = activateFixture "testDiagnosticsWork"
- Thread.Sleep(500)
+ Thread.Sleep(1000)
let partialResultToken: ProgressToken = System.Guid.NewGuid() |> string |> U2.C2
diff --git a/tests/CSharpLanguageServer.Tests/DocumentHighlightTests.fs b/tests/CSharpLanguageServer.Tests/DocumentHighlightTests.fs
new file mode 100644
index 00000000..259d30b6
--- /dev/null
+++ b/tests/CSharpLanguageServer.Tests/DocumentHighlightTests.fs
@@ -0,0 +1,59 @@
+module CSharpLanguageServer.Tests.DocumentHighlightTests
+
+open System
+
+open NUnit.Framework
+open Ionide.LanguageServerProtocol.Types
+open Ionide.LanguageServerProtocol.Server
+
+open CSharpLanguageServer.Tests.Tooling
+
+[]
+let ``test textDocument/documentHighlight works in .cs file`` () =
+ use client = activateFixture "genericProject"
+ use classFile = client.Open("Project/Class.cs")
+
+ let highlightParams: DocumentHighlightParams =
+ { TextDocument = { Uri = classFile.Uri }
+ Position = { Line = 9u; Character = 8u }
+ WorkDoneToken = None
+ PartialResultToken = None }
+
+ let highlights: DocumentHighlight[] option =
+ client.Request("textDocument/documentHighlight", highlightParams)
+
+ let expectedHighlights: DocumentHighlight list =
+ [ { Range =
+ { Start = { Line = 2u; Character = 16u }
+ End = { Line = 2u; Character = 23u } }
+ Kind = Some DocumentHighlightKind.Read }
+
+ { Range =
+ { Start = { Line = 9u; Character = 8u }
+ End = { Line = 9u; Character = 15u } }
+ Kind = Some DocumentHighlightKind.Read } ]
+
+ Assert.AreEqual(Some expectedHighlights, highlights |> Option.map List.ofArray)
+
+
+[]
+let ``test textDocument/documentHighlight works in .cshtml file`` () =
+ use client = activateFixture "aspnetProject"
+ use indexCshtmlFile = client.Open("Project/Views/Test/Index.cshtml")
+
+ let highlightParams: DocumentHighlightParams =
+ { TextDocument = { Uri = indexCshtmlFile.Uri }
+ Position = { Line = 1u; Character = 1u }
+ WorkDoneToken = None
+ PartialResultToken = None }
+
+ let highlights: DocumentHighlight[] option =
+ client.Request("textDocument/documentHighlight", highlightParams)
+
+ let expectedHighlights: DocumentHighlight list =
+ [ { Range =
+ { Start = { Line = 1u; Character = 1u }
+ End = { Line = 1u; Character = 6u } }
+ Kind = Some DocumentHighlightKind.Read } ]
+
+ Assert.AreEqual(Some expectedHighlights, highlights |> Option.map List.ofArray)
diff --git a/tests/CSharpLanguageServer.Tests/Fixtures/aspnetProject/Project/Views/Test/CompletionTests.cshtml b/tests/CSharpLanguageServer.Tests/Fixtures/aspnetProject/Project/Views/Test/CompletionTests.cshtml
new file mode 100644
index 00000000..3a22cf69
--- /dev/null
+++ b/tests/CSharpLanguageServer.Tests/Fixtures/aspnetProject/Project/Views/Test/CompletionTests.cshtml
@@ -0,0 +1,8 @@
+@model Project.Models.Test.IndexViewModel
+(@Model.)
+@Model.
+@Model.Output.
+@{
+ var x = 1;
+ x.
+}
diff --git a/tests/CSharpLanguageServer.Tests/Fixtures/genericProject/Project/ClassWithExtensionMethods.cs b/tests/CSharpLanguageServer.Tests/Fixtures/genericProject/Project/ClassWithExtensionMethods.cs
new file mode 100644
index 00000000..519314c2
--- /dev/null
+++ b/tests/CSharpLanguageServer.Tests/Fixtures/genericProject/Project/ClassWithExtensionMethods.cs
@@ -0,0 +1,23 @@
+<<<<<<<< HEAD:tests/CSharpLanguageServer.Tests/Fixtures/genericProject/Project/ClassForCompletionTestsWithExtensionMethods.cs
+class ClassForCompletionWithExtensionMethods
+========
+class ClassWithExtensionMethods
+>>>>>>>> 902dbd5 (squash):tests/CSharpLanguageServer.Tests/Fixtures/genericProject/Project/ClassWithExtensionMethods.cs
+{
+ public void MethodA(string arg)
+ {
+ this.
+ }
+}
+
+public static class ClassExtensions
+{
+<<<<<<<< HEAD:tests/CSharpLanguageServer.Tests/Fixtures/genericProject/Project/ClassForCompletionTestsWithExtensionMethods.cs
+ public static string MethodB(this ClassForCompletionWithExtensionMethods input)
+========
+ public static string MethodB(this ClassWithExtensionMethods input)
+>>>>>>>> 902dbd5 (squash):tests/CSharpLanguageServer.Tests/Fixtures/genericProject/Project/ClassWithExtensionMethods.cs
+ {
+ return "ok";
+ }
+}
diff --git a/tests/CSharpLanguageServer.Tests/Fixtures/genericProject/Project/Controllers/TestController.cs b/tests/CSharpLanguageServer.Tests/Fixtures/genericProject/Project/Controllers/TestController.cs
new file mode 100644
index 00000000..e4f76f59
--- /dev/null
+++ b/tests/CSharpLanguageServer.Tests/Fixtures/genericProject/Project/Controllers/TestController.cs
@@ -0,0 +1,17 @@
+using Microsoft.AspNetCore.Mvc;
+using Project.Models.Test;
+
+namespace Printlog.Web.ClientPart.Controllers;
+
+public class TestController : Controller
+{
+ public IActionResult Index()
+ {
+ var model = new IndexViewModel()
+ {
+ Output = "test"
+ };
+
+ return View(model);
+ }
+}
diff --git a/tests/CSharpLanguageServer.Tests/Fixtures/genericProject/Project/Models/Test/IndexViewModel.cs b/tests/CSharpLanguageServer.Tests/Fixtures/genericProject/Project/Models/Test/IndexViewModel.cs
new file mode 100644
index 00000000..02f6157a
--- /dev/null
+++ b/tests/CSharpLanguageServer.Tests/Fixtures/genericProject/Project/Models/Test/IndexViewModel.cs
@@ -0,0 +1,5 @@
+namespace Project.Models.Test;
+public class IndexViewModel
+{
+ public string? Output { get; set; }
+}
diff --git a/tests/CSharpLanguageServer.Tests/Fixtures/genericProject/Project/Program.cs b/tests/CSharpLanguageServer.Tests/Fixtures/genericProject/Project/Program.cs
new file mode 100644
index 00000000..698f461f
--- /dev/null
+++ b/tests/CSharpLanguageServer.Tests/Fixtures/genericProject/Project/Program.cs
@@ -0,0 +1,20 @@
+using Microsoft.AspNetCore;
+using System.Threading.Tasks;
+using Microsoft.AspNetCore.Hosting;
+
+namespace Project;
+
+public class Program
+{
+ public static async Task Main(string[] args)
+ {
+ await BuildWebHost(args).RunAsync();
+ }
+
+ public static IWebHost BuildWebHost(string[] args)
+ {
+ var builder = WebHost.CreateDefaultBuilder(args);
+ builder = builder.UseKestrel().UseStartup();
+ return builder.Build();
+ }
+}
diff --git a/tests/CSharpLanguageServer.Tests/Fixtures/genericProject/Project/Project.csproj b/tests/CSharpLanguageServer.Tests/Fixtures/genericProject/Project/Project.csproj
index 29aeae9e..9d715580 100644
--- a/tests/CSharpLanguageServer.Tests/Fixtures/genericProject/Project/Project.csproj
+++ b/tests/CSharpLanguageServer.Tests/Fixtures/genericProject/Project/Project.csproj
@@ -1,6 +1,10 @@
-
-
- Exe
- net9.0
-
+
+
+ net9.0
+ enable
+
+
+
+
+
diff --git a/tests/CSharpLanguageServer.Tests/Fixtures/genericProject/Project/Startup.cs b/tests/CSharpLanguageServer.Tests/Fixtures/genericProject/Project/Startup.cs
new file mode 100644
index 00000000..d089977c
--- /dev/null
+++ b/tests/CSharpLanguageServer.Tests/Fixtures/genericProject/Project/Startup.cs
@@ -0,0 +1,30 @@
+using Microsoft.AspNetCore.Builder;
+using Microsoft.AspNetCore.Hosting;
+using Microsoft.Extensions.Configuration;
+using Microsoft.Extensions.DependencyInjection;
+
+namespace Project;
+
+public class Startup
+{
+ public Startup(IConfiguration configuration, IWebHostEnvironment env)
+ {
+ }
+
+ public void ConfigureServices(IServiceCollection services)
+ {
+ services.AddOptions();
+ }
+
+ public void Configure(
+ IApplicationBuilder app,
+ IWebHostEnvironment env)
+ {
+ app.UseAuthentication();
+ app.UseAuthorization();
+
+ app.UseEndpoints(endpoints => {
+ endpoints.MapControllers();
+ });
+ }
+}
diff --git a/tests/CSharpLanguageServer.Tests/Fixtures/genericProject/Project/Views/Test/Index.cshtml b/tests/CSharpLanguageServer.Tests/Fixtures/genericProject/Project/Views/Test/Index.cshtml
new file mode 100644
index 00000000..5182deb0
--- /dev/null
+++ b/tests/CSharpLanguageServer.Tests/Fixtures/genericProject/Project/Views/Test/Index.cshtml
@@ -0,0 +1,8 @@
+@model Project.Models.Test.IndexViewModel
+@(Model.)
+@Model.
+@Model.Output.
+@{
+ int x = 1;
+ x.
+}
diff --git a/tests/CSharpLanguageServer.Tests/Fixtures/genericProject/Project/Views/_ViewImports.cshtml b/tests/CSharpLanguageServer.Tests/Fixtures/genericProject/Project/Views/_ViewImports.cshtml
new file mode 100644
index 00000000..a757b413
--- /dev/null
+++ b/tests/CSharpLanguageServer.Tests/Fixtures/genericProject/Project/Views/_ViewImports.cshtml
@@ -0,0 +1 @@
+@addTagHelper *, Microsoft.AspNetCore.Mvc.TagHelpers
diff --git a/tests/CSharpLanguageServer.Tests/Fixtures/genericProject/Project/Views/_ViewStart.cshtml b/tests/CSharpLanguageServer.Tests/Fixtures/genericProject/Project/Views/_ViewStart.cshtml
new file mode 100644
index 00000000..a5f10045
--- /dev/null
+++ b/tests/CSharpLanguageServer.Tests/Fixtures/genericProject/Project/Views/_ViewStart.cshtml
@@ -0,0 +1,3 @@
+@{
+ Layout = "_Layout";
+}
diff --git a/tests/CSharpLanguageServer.Tests/HoverTests.fs b/tests/CSharpLanguageServer.Tests/HoverTests.fs
index f1ce31eb..7ca585e3 100644
--- a/tests/CSharpLanguageServer.Tests/HoverTests.fs
+++ b/tests/CSharpLanguageServer.Tests/HoverTests.fs
@@ -47,19 +47,13 @@ let testHoverWorks () =
Assert.IsTrue(hover1.IsSome)
match hover1 with
- | Some hover ->
- match hover.Contents with
- | U3.C1 c ->
- Assert.AreEqual(MarkupKind.Markdown, c.Kind)
-
- Assert.AreEqual(
- "```csharp\nstring\n```\n\nRepresents text as a sequence of UTF-16 code units.",
- c.Value.ReplaceLineEndings("\n")
- )
- | _ -> failwith "C1 was expected"
-
- Assert.IsTrue(hover.Range.IsNone)
+ | Some { Contents = U3.C1 c } ->
+ Assert.AreEqual(MarkupKind.Markdown, c.Kind)
+ Assert.AreEqual(
+ "```csharp\nstring\n```\n\nRepresents text as a sequence of UTF-16 code units.",
+ c.Value.ReplaceLineEndings("\n")
+ )
| _ -> failwith "Some (U3.C1 c) was expected"
//
@@ -73,3 +67,25 @@ let testHoverWorks () =
let hover2: Hover option = client.Request("textDocument/hover", hover2Params)
Assert.IsTrue(hover2.IsNone)
+
+[]
+let testHoverWorksInRazorFile () =
+ use client = activateFixture "aspnetProject"
+
+ use indexCshtmlFile = client.Open("Project/Views/Test/Index.cshtml")
+
+ let hover0Params: HoverParams =
+ { TextDocument = { Uri = indexCshtmlFile.Uri }
+ Position = { Line = 1u; Character = 7u }
+ WorkDoneToken = None }
+
+ let hover0: Hover option = client.Request("textDocument/hover", hover0Params)
+
+ Assert.IsTrue(hover0.IsSome)
+
+ match hover0 with
+ | Some { Contents = U3.C1 c } ->
+ Assert.AreEqual(MarkupKind.Markdown, c.Kind)
+ Assert.AreEqual("```csharp\nstring? IndexViewModel.Output\n```", c.Value.ReplaceLineEndings("\n"))
+
+ | _ -> failwith "Some (U3.C1 c) was expected"
diff --git a/tests/CSharpLanguageServer.Tests/InitializationTests.fs b/tests/CSharpLanguageServer.Tests/InitializationTests.fs
index 604bb791..c64f707b 100644
--- a/tests/CSharpLanguageServer.Tests/InitializationTests.fs
+++ b/tests/CSharpLanguageServer.Tests/InitializationTests.fs
@@ -67,13 +67,18 @@ let testServerRegistersCapabilitiesWithTheClient () =
Assert.AreEqual(null, serverCaps.InlineValueProvider)
+ let expectedDocumentSelector =
+ [| U2.C1
+ { Language = Some "csharp"
+ Scheme = Some "file"
+ Pattern = Some "**/*.cs" }
+ U2.C1
+ { Language = Some "razor"
+ Scheme = Some "file"
+ Pattern = Some "**/*.cshtml" } |]
+
Assert.AreEqual(
- { DocumentSelector =
- Some
- [| U2.C1
- { Language = Some "csharp"
- Scheme = Some "file"
- Pattern = Some "**/*.cs" } |]
+ { DocumentSelector = Some expectedDocumentSelector
WorkDoneProgress = None
Identifier = None
InterFileDependencies = false
diff --git a/tests/CSharpLanguageServer.Tests/ReferenceTests.fs b/tests/CSharpLanguageServer.Tests/ReferenceTests.fs
index 7bab5060..a255b4c6 100644
--- a/tests/CSharpLanguageServer.Tests/ReferenceTests.fs
+++ b/tests/CSharpLanguageServer.Tests/ReferenceTests.fs
@@ -142,14 +142,16 @@ let testReferenceWorksDotnet8 () =
Assert.AreEqual(expectedLocations2, locations2.Value)
-
[]
-let testReferenceWorksToAspNetRazorPageReferencedValue () =
+let testReferenceWorksToRazorPageReferencedValue () =
use client = activateFixture "aspnetProject"
use testIndexViewModelCsFile = client.Open("Project/Models/Test/IndexViewModel.cs")
use testControllerCsFile = client.Open("Project/Controllers/TestController.cs")
- use viewsTestIndexCshtmlFile = client.Open("Project/Views/Test/Index.cshtml")
+ use indexCshtmlFile = client.Open("Project/Views/Test/Index.cshtml")
+
+ use completionTestsCshtmlFile =
+ client.Open("Project/Views/Test/CompletionTests.cshtml")
let referenceParams0: ReferenceParams =
{ TextDocument = { Uri = testIndexViewModelCsFile.Uri }
@@ -162,7 +164,7 @@ let testReferenceWorksToAspNetRazorPageReferencedValue () =
client.Request("textDocument/references", referenceParams0)
Assert.IsTrue(locations0.IsSome)
- Assert.AreEqual(2, locations0.Value.Length)
+ Assert.AreEqual(3, locations0.Value.Length)
let expectedLocations0: Location array =
[| { Uri = testControllerCsFile.Uri
@@ -170,12 +172,17 @@ let testReferenceWorksToAspNetRazorPageReferencedValue () =
{ Start = { Line = 11u; Character = 12u }
End = { Line = 11u; Character = 18u } } }
- { Uri = viewsTestIndexCshtmlFile.Uri
+ { Uri = completionTestsCshtmlFile.Uri
+ Range =
+ { Start = { Line = 3u; Character = 13u }
+ End = { Line = 3u; Character = 19u } } }
+
+ { Uri = indexCshtmlFile.Uri
Range =
{ Start = { Line = 1u; Character = 7u }
End = { Line = 1u; Character = 13u } } } |]
- Assert.AreEqual(expectedLocations0, locations0.Value)
+ Assert.AreEqual(expectedLocations0, locations0.Value |> Array.sortBy _.Uri)
//
// do same but with IncludeDeclaration=true
@@ -191,14 +198,19 @@ let testReferenceWorksToAspNetRazorPageReferencedValue () =
client.Request("textDocument/references", referenceParams1)
Assert.IsTrue(locations1.IsSome)
- Assert.AreEqual(5, locations1.Value.Length)
+ Assert.AreEqual(6, locations1.Value.Length)
let expectedLocations1: Location array =
- [| { Uri = viewsTestIndexCshtmlFile.Uri
+ [| { Uri = indexCshtmlFile.Uri
Range =
{ Start = { Line = 1u; Character = 7u }
End = { Line = 1u; Character = 13u } } }
+ { Uri = completionTestsCshtmlFile.Uri
+ Range =
+ { Start = { Line = 3u; Character = 13u }
+ End = { Line = 3u; Character = 19u } } }
+
{ Uri = testIndexViewModelCsFile.Uri
Range =
{ Start = { Line = 3u; Character = 19u }
@@ -224,3 +236,65 @@ let testReferenceWorksToAspNetRazorPageReferencedValue () =
|> Array.sortBy (fun f -> (f.Range.Start.Line, f.Range.Start.Character))
Assert.AreEqual(expectedLocations1, sortedLocations1)
+
+
+[]
+let testReferenceWorksFromRazorPageReferencedValue () =
+ use client = activateFixture "aspnetProject"
+
+ use testIndexViewModelCsFile = client.Open("Project/Models/Test/IndexViewModel.cs")
+ use testControllerCsFile = client.Open("Project/Controllers/TestController.cs")
+ use indexCshtmlFile = client.Open("Project/Views/Test/Index.cshtml")
+
+ use completionTestsCshtmlFile =
+ client.Open("Project/Views/Test/CompletionTests.cshtml")
+
+ let referenceParams0: ReferenceParams =
+ { TextDocument = { Uri = indexCshtmlFile.Uri }
+ Position = { Line = 1u; Character = 7u }
+ WorkDoneToken = None
+ PartialResultToken = None
+ Context = { IncludeDeclaration = true } }
+
+ let locations0: Location[] option =
+ client.Request("textDocument/references", referenceParams0)
+
+ Assert.IsTrue(locations0.IsSome)
+ Assert.AreEqual(6, locations0.Value.Length)
+
+ let expectedLocations0: Location array =
+ [| { Uri = indexCshtmlFile.Uri
+ Range =
+ { Start = { Line = 1u; Character = 7u }
+ End = { Line = 1u; Character = 13u } } }
+
+ { Uri = completionTestsCshtmlFile.Uri
+ Range =
+ { Start = { Line = 3u; Character = 13u }
+ End = { Line = 3u; Character = 19u } } }
+
+ { Uri = testIndexViewModelCsFile.Uri
+ Range =
+ { Start = { Line = 3u; Character = 19u }
+ End = { Line = 3u; Character = 25u } } }
+
+ { Uri = testIndexViewModelCsFile.Uri
+ Range =
+ { Start = { Line = 3u; Character = 28u }
+ End = { Line = 3u; Character = 31u } } }
+
+ { Uri = testIndexViewModelCsFile.Uri
+ Range =
+ { Start = { Line = 3u; Character = 33u }
+ End = { Line = 3u; Character = 36u } } }
+
+ { Uri = testControllerCsFile.Uri
+ Range =
+ { Start = { Line = 11u; Character = 12u }
+ End = { Line = 11u; Character = 18u } } } |]
+
+ let sortedLocations0 =
+ locations0.Value
+ |> Array.sortBy (fun f -> (f.Range.Start.Line, f.Range.Start.Character))
+
+ Assert.AreEqual(expectedLocations0, sortedLocations0)
diff --git a/tests/CSharpLanguageServer.Tests/TestData/testReferenceWorksFromRazorPageReferencedValue/Project/Controllers/TestController.cs b/tests/CSharpLanguageServer.Tests/TestData/testReferenceWorksFromRazorPageReferencedValue/Project/Controllers/TestController.cs
new file mode 100644
index 00000000..e4f76f59
--- /dev/null
+++ b/tests/CSharpLanguageServer.Tests/TestData/testReferenceWorksFromRazorPageReferencedValue/Project/Controllers/TestController.cs
@@ -0,0 +1,17 @@
+using Microsoft.AspNetCore.Mvc;
+using Project.Models.Test;
+
+namespace Printlog.Web.ClientPart.Controllers;
+
+public class TestController : Controller
+{
+ public IActionResult Index()
+ {
+ var model = new IndexViewModel()
+ {
+ Output = "test"
+ };
+
+ return View(model);
+ }
+}
diff --git a/tests/CSharpLanguageServer.Tests/TestData/testReferenceWorksFromRazorPageReferencedValue/Project/Models/Test/IndexViewModel.cs b/tests/CSharpLanguageServer.Tests/TestData/testReferenceWorksFromRazorPageReferencedValue/Project/Models/Test/IndexViewModel.cs
new file mode 100644
index 00000000..02f6157a
--- /dev/null
+++ b/tests/CSharpLanguageServer.Tests/TestData/testReferenceWorksFromRazorPageReferencedValue/Project/Models/Test/IndexViewModel.cs
@@ -0,0 +1,5 @@
+namespace Project.Models.Test;
+public class IndexViewModel
+{
+ public string? Output { get; set; }
+}
diff --git a/tests/CSharpLanguageServer.Tests/TestData/testReferenceWorksFromRazorPageReferencedValue/Project/Program.cs b/tests/CSharpLanguageServer.Tests/TestData/testReferenceWorksFromRazorPageReferencedValue/Project/Program.cs
new file mode 100644
index 00000000..698f461f
--- /dev/null
+++ b/tests/CSharpLanguageServer.Tests/TestData/testReferenceWorksFromRazorPageReferencedValue/Project/Program.cs
@@ -0,0 +1,20 @@
+using Microsoft.AspNetCore;
+using System.Threading.Tasks;
+using Microsoft.AspNetCore.Hosting;
+
+namespace Project;
+
+public class Program
+{
+ public static async Task Main(string[] args)
+ {
+ await BuildWebHost(args).RunAsync();
+ }
+
+ public static IWebHost BuildWebHost(string[] args)
+ {
+ var builder = WebHost.CreateDefaultBuilder(args);
+ builder = builder.UseKestrel().UseStartup();
+ return builder.Build();
+ }
+}
diff --git a/tests/CSharpLanguageServer.Tests/TestData/testReferenceWorksFromRazorPageReferencedValue/Project/Project.csproj b/tests/CSharpLanguageServer.Tests/TestData/testReferenceWorksFromRazorPageReferencedValue/Project/Project.csproj
new file mode 100644
index 00000000..9d715580
--- /dev/null
+++ b/tests/CSharpLanguageServer.Tests/TestData/testReferenceWorksFromRazorPageReferencedValue/Project/Project.csproj
@@ -0,0 +1,10 @@
+
+
+ net9.0
+ enable
+
+
+
+
+
+
diff --git a/tests/CSharpLanguageServer.Tests/TestData/testReferenceWorksFromRazorPageReferencedValue/Project/Startup.cs b/tests/CSharpLanguageServer.Tests/TestData/testReferenceWorksFromRazorPageReferencedValue/Project/Startup.cs
new file mode 100644
index 00000000..d089977c
--- /dev/null
+++ b/tests/CSharpLanguageServer.Tests/TestData/testReferenceWorksFromRazorPageReferencedValue/Project/Startup.cs
@@ -0,0 +1,30 @@
+using Microsoft.AspNetCore.Builder;
+using Microsoft.AspNetCore.Hosting;
+using Microsoft.Extensions.Configuration;
+using Microsoft.Extensions.DependencyInjection;
+
+namespace Project;
+
+public class Startup
+{
+ public Startup(IConfiguration configuration, IWebHostEnvironment env)
+ {
+ }
+
+ public void ConfigureServices(IServiceCollection services)
+ {
+ services.AddOptions();
+ }
+
+ public void Configure(
+ IApplicationBuilder app,
+ IWebHostEnvironment env)
+ {
+ app.UseAuthentication();
+ app.UseAuthorization();
+
+ app.UseEndpoints(endpoints => {
+ endpoints.MapControllers();
+ });
+ }
+}
diff --git a/tests/CSharpLanguageServer.Tests/TestData/testReferenceWorksFromRazorPageReferencedValue/Project/Views/Test/Index.cshtml b/tests/CSharpLanguageServer.Tests/TestData/testReferenceWorksFromRazorPageReferencedValue/Project/Views/Test/Index.cshtml
new file mode 100644
index 00000000..b094abcb
--- /dev/null
+++ b/tests/CSharpLanguageServer.Tests/TestData/testReferenceWorksFromRazorPageReferencedValue/Project/Views/Test/Index.cshtml
@@ -0,0 +1,2 @@
+@model Project.Models.Test.IndexViewModel
+@Model.Output
diff --git a/tests/CSharpLanguageServer.Tests/TestData/testReferenceWorksFromRazorPageReferencedValue/Project/Views/_ViewImports.cshtml b/tests/CSharpLanguageServer.Tests/TestData/testReferenceWorksFromRazorPageReferencedValue/Project/Views/_ViewImports.cshtml
new file mode 100644
index 00000000..a757b413
--- /dev/null
+++ b/tests/CSharpLanguageServer.Tests/TestData/testReferenceWorksFromRazorPageReferencedValue/Project/Views/_ViewImports.cshtml
@@ -0,0 +1 @@
+@addTagHelper *, Microsoft.AspNetCore.Mvc.TagHelpers
diff --git a/tests/CSharpLanguageServer.Tests/TestData/testReferenceWorksFromRazorPageReferencedValue/Project/Views/_ViewStart.cshtml b/tests/CSharpLanguageServer.Tests/TestData/testReferenceWorksFromRazorPageReferencedValue/Project/Views/_ViewStart.cshtml
new file mode 100644
index 00000000..a5f10045
--- /dev/null
+++ b/tests/CSharpLanguageServer.Tests/TestData/testReferenceWorksFromRazorPageReferencedValue/Project/Views/_ViewStart.cshtml
@@ -0,0 +1,3 @@
+@{
+ Layout = "_Layout";
+}
diff --git a/tests/CSharpLanguageServer.Tests/TestData/testReferenceWorksToRazorPageReferencedValue/Project/Controllers/TestController.cs b/tests/CSharpLanguageServer.Tests/TestData/testReferenceWorksToRazorPageReferencedValue/Project/Controllers/TestController.cs
new file mode 100644
index 00000000..e4f76f59
--- /dev/null
+++ b/tests/CSharpLanguageServer.Tests/TestData/testReferenceWorksToRazorPageReferencedValue/Project/Controllers/TestController.cs
@@ -0,0 +1,17 @@
+using Microsoft.AspNetCore.Mvc;
+using Project.Models.Test;
+
+namespace Printlog.Web.ClientPart.Controllers;
+
+public class TestController : Controller
+{
+ public IActionResult Index()
+ {
+ var model = new IndexViewModel()
+ {
+ Output = "test"
+ };
+
+ return View(model);
+ }
+}
diff --git a/tests/CSharpLanguageServer.Tests/TestData/testReferenceWorksToRazorPageReferencedValue/Project/Models/Test/IndexViewModel.cs b/tests/CSharpLanguageServer.Tests/TestData/testReferenceWorksToRazorPageReferencedValue/Project/Models/Test/IndexViewModel.cs
new file mode 100644
index 00000000..02f6157a
--- /dev/null
+++ b/tests/CSharpLanguageServer.Tests/TestData/testReferenceWorksToRazorPageReferencedValue/Project/Models/Test/IndexViewModel.cs
@@ -0,0 +1,5 @@
+namespace Project.Models.Test;
+public class IndexViewModel
+{
+ public string? Output { get; set; }
+}
diff --git a/tests/CSharpLanguageServer.Tests/TestData/testReferenceWorksToRazorPageReferencedValue/Project/Program.cs b/tests/CSharpLanguageServer.Tests/TestData/testReferenceWorksToRazorPageReferencedValue/Project/Program.cs
new file mode 100644
index 00000000..698f461f
--- /dev/null
+++ b/tests/CSharpLanguageServer.Tests/TestData/testReferenceWorksToRazorPageReferencedValue/Project/Program.cs
@@ -0,0 +1,20 @@
+using Microsoft.AspNetCore;
+using System.Threading.Tasks;
+using Microsoft.AspNetCore.Hosting;
+
+namespace Project;
+
+public class Program
+{
+ public static async Task Main(string[] args)
+ {
+ await BuildWebHost(args).RunAsync();
+ }
+
+ public static IWebHost BuildWebHost(string[] args)
+ {
+ var builder = WebHost.CreateDefaultBuilder(args);
+ builder = builder.UseKestrel().UseStartup();
+ return builder.Build();
+ }
+}
diff --git a/tests/CSharpLanguageServer.Tests/TestData/testReferenceWorksToRazorPageReferencedValue/Project/Project.csproj b/tests/CSharpLanguageServer.Tests/TestData/testReferenceWorksToRazorPageReferencedValue/Project/Project.csproj
new file mode 100644
index 00000000..9d715580
--- /dev/null
+++ b/tests/CSharpLanguageServer.Tests/TestData/testReferenceWorksToRazorPageReferencedValue/Project/Project.csproj
@@ -0,0 +1,10 @@
+
+
+ net9.0
+ enable
+
+
+
+
+
+
diff --git a/tests/CSharpLanguageServer.Tests/TestData/testReferenceWorksToRazorPageReferencedValue/Project/Startup.cs b/tests/CSharpLanguageServer.Tests/TestData/testReferenceWorksToRazorPageReferencedValue/Project/Startup.cs
new file mode 100644
index 00000000..d089977c
--- /dev/null
+++ b/tests/CSharpLanguageServer.Tests/TestData/testReferenceWorksToRazorPageReferencedValue/Project/Startup.cs
@@ -0,0 +1,30 @@
+using Microsoft.AspNetCore.Builder;
+using Microsoft.AspNetCore.Hosting;
+using Microsoft.Extensions.Configuration;
+using Microsoft.Extensions.DependencyInjection;
+
+namespace Project;
+
+public class Startup
+{
+ public Startup(IConfiguration configuration, IWebHostEnvironment env)
+ {
+ }
+
+ public void ConfigureServices(IServiceCollection services)
+ {
+ services.AddOptions();
+ }
+
+ public void Configure(
+ IApplicationBuilder app,
+ IWebHostEnvironment env)
+ {
+ app.UseAuthentication();
+ app.UseAuthorization();
+
+ app.UseEndpoints(endpoints => {
+ endpoints.MapControllers();
+ });
+ }
+}
diff --git a/tests/CSharpLanguageServer.Tests/TestData/testReferenceWorksToRazorPageReferencedValue/Project/Views/Test/Index.cshtml b/tests/CSharpLanguageServer.Tests/TestData/testReferenceWorksToRazorPageReferencedValue/Project/Views/Test/Index.cshtml
new file mode 100644
index 00000000..b094abcb
--- /dev/null
+++ b/tests/CSharpLanguageServer.Tests/TestData/testReferenceWorksToRazorPageReferencedValue/Project/Views/Test/Index.cshtml
@@ -0,0 +1,2 @@
+@model Project.Models.Test.IndexViewModel
+@Model.Output
diff --git a/tests/CSharpLanguageServer.Tests/TestData/testReferenceWorksToRazorPageReferencedValue/Project/Views/_ViewImports.cshtml b/tests/CSharpLanguageServer.Tests/TestData/testReferenceWorksToRazorPageReferencedValue/Project/Views/_ViewImports.cshtml
new file mode 100644
index 00000000..a757b413
--- /dev/null
+++ b/tests/CSharpLanguageServer.Tests/TestData/testReferenceWorksToRazorPageReferencedValue/Project/Views/_ViewImports.cshtml
@@ -0,0 +1 @@
+@addTagHelper *, Microsoft.AspNetCore.Mvc.TagHelpers
diff --git a/tests/CSharpLanguageServer.Tests/TestData/testReferenceWorksToRazorPageReferencedValue/Project/Views/_ViewStart.cshtml b/tests/CSharpLanguageServer.Tests/TestData/testReferenceWorksToRazorPageReferencedValue/Project/Views/_ViewStart.cshtml
new file mode 100644
index 00000000..a5f10045
--- /dev/null
+++ b/tests/CSharpLanguageServer.Tests/TestData/testReferenceWorksToRazorPageReferencedValue/Project/Views/_ViewStart.cshtml
@@ -0,0 +1,3 @@
+@{
+ Layout = "_Layout";
+}
diff --git a/tests/CSharpLanguageServer.Tests/WorkspaceSymbolTests.fs b/tests/CSharpLanguageServer.Tests/WorkspaceSymbolTests.fs
index 8e1c1700..5722a2f3 100644
--- a/tests/CSharpLanguageServer.Tests/WorkspaceSymbolTests.fs
+++ b/tests/CSharpLanguageServer.Tests/WorkspaceSymbolTests.fs
@@ -4,6 +4,7 @@ open NUnit.Framework
open Ionide.LanguageServerProtocol.Types
open CSharpLanguageServer.Tests.Tooling
+open System.Threading
[]
let testWorkspaceSymbolWorks () =
@@ -24,7 +25,7 @@ let testWorkspaceSymbolWorks () =
match symbols0 with
| Some(U2.C1 sis) ->
- Assert.AreEqual(4, sis.Length)
+ Assert.AreEqual(5, sis.Length)
let sym0 = sis[0]
Assert.AreEqual("Class", sym0.Name)