这是indexloc提供的服务,不要输入任何密码
Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 7 additions & 0 deletions DotNetTry.sln
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,8 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Microsoft.DotNet.Try.Projec
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Microsoft.DotNet.ProjectTemplate", "Microsoft.DotNet.Try.ProjectTemplate\Tutorial\Microsoft.DotNet.ProjectTemplate.csproj", "{E047D81A-7A18-4A1A-98E8-EDBB51EBB7DB}"
EndProject
Project("{6EC3EE1D-3C4E-46DD-8F32-0CC8E7565705}") = "FSharpWorkspaceShim", "FSharpWorkspaceShim\FSharpWorkspaceShim.fsproj", "{9128FCED-2A19-4502-BCEE-BE1BAB6882EB}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
Expand Down Expand Up @@ -151,6 +153,10 @@ Global
{E047D81A-7A18-4A1A-98E8-EDBB51EBB7DB}.Debug|Any CPU.Build.0 = Debug|Any CPU
{E047D81A-7A18-4A1A-98E8-EDBB51EBB7DB}.Release|Any CPU.ActiveCfg = Release|Any CPU
{E047D81A-7A18-4A1A-98E8-EDBB51EBB7DB}.Release|Any CPU.Build.0 = Release|Any CPU
{9128FCED-2A19-4502-BCEE-BE1BAB6882EB}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{9128FCED-2A19-4502-BCEE-BE1BAB6882EB}.Debug|Any CPU.Build.0 = Debug|Any CPU
{9128FCED-2A19-4502-BCEE-BE1BAB6882EB}.Release|Any CPU.ActiveCfg = Release|Any CPU
{9128FCED-2A19-4502-BCEE-BE1BAB6882EB}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
Expand Down Expand Up @@ -179,6 +185,7 @@ Global
{11FDD0E8-D07B-41C9-AF7E-E7F735D91ECF} = {8192FEAD-BCE6-4E62-97E5-2E9EA884BD71}
{1F1A7554-1E88-4514-8602-EC00899E0C49} = {8192FEAD-BCE6-4E62-97E5-2E9EA884BD71}
{E047D81A-7A18-4A1A-98E8-EDBB51EBB7DB} = {6EE8F484-DFA2-4F0F-939F-400CE78DFAC2}
{9128FCED-2A19-4502-BCEE-BE1BAB6882EB} = {6EE8F484-DFA2-4F0F-939F-400CE78DFAC2}
EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution
SolutionGuid = {D6CD99BA-B16B-4570-8910-225CBDFFA3AD}
Expand Down
23 changes: 23 additions & 0 deletions FSharpWorkspaceShim/FSharpWorkspaceShim.fsproj
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
<Project Sdk="Microsoft.NET.Sdk">

<PropertyGroup>
<TargetFramework>netstandard2.0</TargetFramework>
<NoWarn>$(NoWarn);2003</NoWarn><!-- AssemblyInformationalVersionAttribute contains a non-standard value -->
</PropertyGroup>

<PropertyGroup Condition="$(TargetFramework.StartsWith('netstandard')) AND '$(OS)' == 'Windows_NT'">
<!-- the 2.1.503 F# compiler can produce PDBs that can't properly be converted, see https://github.com/Microsoft/visualfsharp/issues/5976 -->
<PublishWindowsPdb>false</PublishWindowsPdb>
</PropertyGroup>

<ItemGroup>
<Compile Include="Library.fs" />
</ItemGroup>

<ItemGroup>
<PackageReference Update="FSharp.Core" Version="4.6.2" />
<PackageReference Include="FSharp.Compiler.Service" Version="28.0.0" />
<PackageReference Include="Microsoft.CodeAnalysis" Version="3.1.0-beta3-final" />
</ItemGroup>

</Project>
130 changes: 130 additions & 0 deletions FSharpWorkspaceShim/Library.fs
Original file line number Diff line number Diff line change
@@ -0,0 +1,130 @@
namespace FSharpWorkspaceShim

open System
open System.IO
open FSharp.Compiler.SourceCodeServices
open Microsoft.CodeAnalysis
open Microsoft.CodeAnalysis.Text

module Shim =

let private checker = FSharpChecker.Create()

let private getIndex (text: string) (line: int) (column: int) =
let mutable index = -1
let mutable currentLine = 0
let mutable currentColumn = 0
text.ToCharArray()
|> Array.iteri (fun i c ->
if line = currentLine && column = currentColumn then index <- i
match c with
| '\n' ->
currentLine <- currentLine + 1
currentColumn <- 0
| _ -> currentColumn <- currentColumn + 1)
index

let private newlineProxy = System.String [|char 29|]

// adapted from https://github.com/dotnet/fsharp/blob/master/src/fsharp/ErrorLogger.fs
let private normalizeErrorString (text : string) =
if isNull text then nullArg "text"
let text = text.Trim()

let buf = System.Text.StringBuilder()
let mutable i = 0
while i < text.Length do
let delta =
match text.[i] with
| '\r' when i + 1 < text.Length && text.[i + 1] = '\n' ->
// handle \r\n sequence - replace it with one single space
buf.Append newlineProxy |> ignore
2
| '\n' | '\r' ->
buf.Append newlineProxy |> ignore
1
| c ->
// handle remaining chars: control - replace with space, others - keep unchanged
let c = if Char.IsControl c then ' ' else c
buf.Append c |> ignore
1
i <- i + delta
buf.ToString()

let private newlineifyErrorString (message:string) = message.Replace(newlineProxy, Environment.NewLine)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

"newlineify" 😆

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Slightly shorter than newlineificize.


// adapted from https://github.com/dotnet/fsharp/blob/master/vsintegration/src/FSharp.Editor/Common/RoslynHelpers.fs
let private convertError (error: FSharpErrorInfo) (location: Location) =
// Normalize the error message into the same format that we will receive it from the compiler.
// This ensures that IntelliSense and Compiler errors in the 'Error List' are de-duplicated.
// (i.e the same error does not appear twice, where the only difference is the line endings.)
let normalizedMessage = error.Message |> normalizeErrorString |> newlineifyErrorString

let id = "FS" + error.ErrorNumber.ToString("0000")
let emptyString = LocalizableString.op_Implicit("")
let description = LocalizableString.op_Implicit(normalizedMessage)
let severity = if error.Severity = FSharpErrorSeverity.Error then DiagnosticSeverity.Error else DiagnosticSeverity.Warning
let customTags =
match error.ErrorNumber with
| 1182 -> WellKnownDiagnosticTags.Unnecessary
| _ -> null
let descriptor = new DiagnosticDescriptor(id, emptyString, description, error.Subcategory, severity, true, emptyString, String.Empty, customTags)
Diagnostic.Create(descriptor, location)

let GetDiagnostics (projectPath: string) (files: string[]) (pathMapSource: string) (pathMapDest: string) =
async {
let projectOptions = {
ProjectFileName = projectPath
ProjectId = None
SourceFiles = files
OtherOptions = [||]
ReferencedProjects = [||]
IsIncompleteTypeCheckEnvironment = false
UseScriptResolutionRules = false
LoadTime = DateTime.Now
UnresolvedReferences = None
OriginalLoadReferences = []
ExtraProjectInfo = None
Stamp = None
}
let ensureDirectorySeparator (path: string) =
if path.EndsWith(Path.DirectorySeparatorChar |> string) |> not then path + (string Path.DirectorySeparatorChar)
else path
let pathMapSource = ensureDirectorySeparator pathMapSource
let pathMapDest = ensureDirectorySeparator pathMapDest
let! results = checker.ParseAndCheckProject projectOptions
// adapted from from https://github.com/dotnet/fsharp/blob/master/vsintegration/src/FSharp.Editor/Diagnostics/DocumentDiagnosticAnalyzer.fs
let diagnostics =
results.Errors
|> Seq.choose (fun error ->
if error.StartLineAlternate = 0 || error.EndLineAlternate = 0 then
// F# error line numbers are one-based. Compiler returns 0 for global errors (reported by ProjectDiagnosticAnalyzer)
None
else
// Roslyn line numbers are zero-based
let linePositionSpan = LinePositionSpan(LinePosition(error.StartLineAlternate - 1, error.StartColumn), LinePosition(error.EndLineAlternate - 1, error.EndColumn))
let text = File.ReadAllText(error.FileName)
let textSpan =
TextSpan.FromBounds(
getIndex text (error.StartLineAlternate - 1) error.StartColumn,
getIndex text (error.EndLineAlternate - 1) error.EndColumn)

// F# compiler report errors at end of file if parsing fails. It should be corrected to match Roslyn boundaries
let correctedTextSpan =
if textSpan.End <= text.Length then
textSpan
else
let start =
min textSpan.Start (text.Length - 1)
|> max 0

TextSpan.FromBounds(start, text.Length)

let filePath =
if error.FileName.StartsWith(pathMapSource) then String.Concat(pathMapDest, error.FileName.Substring(pathMapSource.Length))
else error.FileName
let location = Location.Create(filePath, correctedTextSpan, linePositionSpan)
Some(convertError error location))
|> Seq.toArray
return diagnostics
} |> Async.StartAsTask
16 changes: 8 additions & 8 deletions MLS.Agent.Tests/ApiContracts/ApiInputContractChangeTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -28,14 +28,14 @@ public async Task Changing_the_completion_request_format_does_not_change_the_res
""files"": [],
""buffers"": [
{{
""id"": """",
""id"": ""file.cs"",
""content"": ""using System;\nusing System.Collections.Generic;\nusing System.Linq;\n\npublic class Program\n{{\n public static void Main()\n {{\n foreach (var i in Fibonacci().Take(20))\n {{\n Console.\n }}\n }}\n\n private static IEnumerable<int> Fibonacci()\n {{\n int current = 1, next = 1;\n\n while (true) \n {{\n yield return current;\n next = current + (current = next);\n }}\n }}\n}}\n"",
""position"": 0
}}
],
""usings"": []
}},
""activeBufferId"": """",
""activeBufferId"": ""file.cs"",
""position"": 187
}}";

Expand All @@ -46,14 +46,14 @@ public async Task Changing_the_completion_request_format_does_not_change_the_res
""files"": [],
""buffers"": [
{{
""id"": """",
""id"": ""file.cs"",
""content"": ""using System;\nusing System.Collections.Generic;\nusing System.Linq;\n\npublic class Program\n{{\n public static void Main()\n {{\n foreach (var i in Fibonacci().Take(20))\n {{\n Console.\n }}\n }}\n\n private static IEnumerable<int> Fibonacci()\n {{\n int current = 1, next = 1;\n\n while (true) \n {{\n yield return current;\n next = current + (current = next);\n }}\n }}\n}}\n"",
""position"": 187
}}
],
""usings"": []
}},
""activeBufferId"": """"
""activeBufferId"": ""file.cs""
}}";

var responseToOldFormatRequest = await CallCompletion(oldFormatRequest);
Expand Down Expand Up @@ -83,14 +83,14 @@ public async Task Changing_the_signature_help_request_format_does_not_change_the
""files"": [],
""buffers"": [
{{
""id"": """",
""id"": ""file.cs"",
""content"": ""using System;\nusing System.Collections.Generic;\nusing System.Linq;\n\npublic class Program\n{{\n public static void Main()\n {{\n foreach (var i in Fibonacci().Take(20))\n {{\n Console.WriteLine()\n }}\n }}\n\n private static IEnumerable<int> Fibonacci()\n {{\n int current = 1, next = 1;\n\n while (true) \n {{\n yield return current;\n next = current + (current = next);\n }}\n }}\n}}\n"",
""position"": 0
}}
],
""usings"": []
}},
""activeBufferId"": """",
""activeBufferId"": ""file.cs"",
""position"": 197
}}";

Expand All @@ -101,14 +101,14 @@ public async Task Changing_the_signature_help_request_format_does_not_change_the
""files"": [],
""buffers"": [
{{
""id"": """",
""id"": ""file.cs"",
""content"": ""using System;\nusing System.Collections.Generic;\nusing System.Linq;\n\npublic class Program\n{{\n public static void Main()\n {{\n foreach (var i in Fibonacci().Take(20))\n {{\n Console.WriteLine()\n }}\n }}\n\n private static IEnumerable<int> Fibonacci()\n {{\n int current = 1, next = 1;\n\n while (true) \n {{\n yield return current;\n next = current + (current = next);\n }}\n }}\n}}\n"",
""position"": 197
}}
],
""usings"": []
}},
""activeBufferId"": """"
""activeBufferId"": ""file.cs""
}}";

var responseToOldFormatRequest = await CallSignatureHelp(oldFormatRequest);
Expand Down
6 changes: 5 additions & 1 deletion MLS.Agent.Tests/ApiViaHttpTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -357,7 +357,8 @@ public static IEnumerable<int> Fibonacci()
new WorkspaceRequest(activeBufferId: "generators/FibonacciGenerator.cs",
requestId: "TestRun",
workspace: Workspace.FromSources(
"console",
workspaceType:"console",
language:"csharp",
("Program.cs", program, 0),
("generators/FibonacciGenerator.cs", processed, position)
)).ToJson();
Expand Down Expand Up @@ -434,6 +435,7 @@ public static IEnumerable<int> Fibonacci()
requestId: "TestRun",
workspace: Workspace.FromSources(
"console",
language: "csharp",
("Program.cs", program, 0),
("generators/FibonacciGenerator.cs", processed, position)
)).ToJson();
Expand Down Expand Up @@ -511,6 +513,7 @@ public static IEnumerable<int> Fibonacci()
requestId: "TestRun",
workspace: Workspace.FromSources(
package.Name,
language: "csharp",
("Program.cs", program, 0),
("generators/FibonacciGenerator.cs", processed, position)
)).ToJson();
Expand Down Expand Up @@ -588,6 +591,7 @@ public static IEnumerable<int> Fibonacci()
requestId: "TestRun",
workspace: Workspace.FromSources(
"console",
language: "csharp",
("Program.cs", program, 0),
("generators/FibonacciGenerator.cs", processed, position)
)).ToJson();
Expand Down
4 changes: 2 additions & 2 deletions MLS.Agent/CommandLine/VerifyCommand.cs
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@
using Microsoft.DotNet.Try.Protocol;
using MLS.Agent.Markdown;
using WorkspaceServer;
using WorkspaceServer.Servers.Roslyn;
using WorkspaceServer.Servers;
using Buffer = Microsoft.DotNet.Try.Protocol.Buffer;
using File = Microsoft.DotNet.Try.Protocol.File;

Expand All @@ -33,7 +33,7 @@ public static async Task<int> Do(
packageRegistry,
startupOptions);
var errorCount = 0;
var workspaceServer = new Lazy<RoslynWorkspaceServer>(() => new RoslynWorkspaceServer(packageRegistry));
var workspaceServer = new Lazy<IWorkspaceServer>(() => new WorkspaceServerMultiplexer(packageRegistry));

var markdownFiles = markdownProject.GetAllMarkdownFiles().ToArray();

Expand Down
6 changes: 3 additions & 3 deletions MLS.Agent/Controllers/CompileController.cs
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
using Microsoft.DotNet.Try.Protocol;
using MLS.Agent.Middleware;
using Pocket;
using WorkspaceServer.Servers.Roslyn;
using WorkspaceServer.Servers;
using static Pocket.Logger<MLS.Agent.Controllers.CompileController>;

namespace MLS.Agent.Controllers
Expand All @@ -19,11 +19,11 @@ public class CompileController : Controller
public static RequestDescriptor CompileApi => new RequestDescriptor(CompileRoute, timeoutMs: 600000);


private readonly RoslynWorkspaceServer _workspaceServer;
private readonly IWorkspaceServer _workspaceServer;
private readonly CompositeDisposable _disposables = new CompositeDisposable();

public CompileController(
RoslynWorkspaceServer workspaceServer)
IWorkspaceServer workspaceServer)
{
_workspaceServer = workspaceServer;
}
Expand Down
6 changes: 3 additions & 3 deletions MLS.Agent/Controllers/LanguageServicesController.cs
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@
using MLS.Agent.Middleware;
using Pocket;
using WorkspaceServer;
using WorkspaceServer.Servers.Roslyn;
using WorkspaceServer.Servers;
using static Pocket.Logger<MLS.Agent.Controllers.LanguageServicesController>;

namespace MLS.Agent.Controllers
Expand All @@ -33,9 +33,9 @@ public class LanguageServicesController : Controller
public static RequestDescriptor SignatureHelpApi => new RequestDescriptor(SignatureHelpRoute, timeoutMs: 60000);

private readonly CompositeDisposable _disposables = new CompositeDisposable();
private readonly RoslynWorkspaceServer _workspaceServer;
private readonly IWorkspaceServer _workspaceServer;

public LanguageServicesController(RoslynWorkspaceServer workspaceServer)
public LanguageServicesController(IWorkspaceServer workspaceServer)
{
_workspaceServer = workspaceServer ?? throw new ArgumentNullException(nameof(workspaceServer));
}
Expand Down
3 changes: 2 additions & 1 deletion MLS.Agent/Controllers/ProjectController.cs
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,8 @@ public IActionResult GenerateRegionsFromFiles([FromBody] CreateRegionsFromFilesR
private static IEnumerable<SourceFileRegion> ExtractRegions(SourceFile sourceFile)
{
var sc = SourceText.From(sourceFile.Content);
var regions = sc.ExtractRegions(sourceFile.Name).Select(region => new SourceFileRegion(region.id, region.content)).ToArray();
var regions = sc.ExtractRegions(sourceFile.Name).Select(
region => new SourceFileRegion(region.bufferId.ToString(), sc.ToString(region.span).FormatSourceCode(sourceFile.Name))).ToArray();
return regions;
}

Expand Down
7 changes: 3 additions & 4 deletions MLS.Agent/Controllers/RunController.cs
Original file line number Diff line number Diff line change
Expand Up @@ -8,13 +8,12 @@
using Microsoft.DotNet.Try.Protocol;
using MLS.Agent.Middleware;
using Pocket;
using WorkspaceServer;
using WorkspaceServer.Models.Execution;
using WorkspaceServer.Servers.Roslyn;
using WorkspaceServer.Servers.Scripting;
using WorkspaceServer.Features;
using static Pocket.Logger<MLS.Agent.Controllers.RunController>;
using MLS.Agent.CommandLine;
using WorkspaceServer.Servers;

namespace MLS.Agent.Controllers
{
Expand All @@ -24,12 +23,12 @@ public class RunController : Controller
public static RequestDescriptor RunApi => new RequestDescriptor(RunRoute, timeoutMs:600000);

private readonly StartupOptions _options;
private readonly RoslynWorkspaceServer _workspaceServer;
private readonly IWorkspaceServer _workspaceServer;
private readonly CompositeDisposable _disposables = new CompositeDisposable();

public RunController(
StartupOptions options,
RoslynWorkspaceServer workspaceServer)
IWorkspaceServer workspaceServer)
{
_options = options ?? throw new ArgumentNullException(nameof(options));
_workspaceServer = workspaceServer;
Expand Down
Loading