-
Notifications
You must be signed in to change notification settings - Fork 563
initial support for F# #237
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
810ce36 to
9747690
Compare
| { | ||
| internal class FSharpMethods | ||
| { | ||
| private const string FSharpRegionStart = "//#region"; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
"//#region" [](start = 49, length = 11)
Is this ideal? Any suggestions for making it more natural in F#?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Not really; F# doesn't have the equivalent of #region or any concept of a code block. The closest thing we have is computation expressions, but that would require the writer of the documentation/sample to define a new builder for each span of code. E.g., the backing code could look like this:
type DemoRegionBuilder() =
member __.Zero() = ()
// ... elsewhere
let demo_region_1 = new DemoRegionBuilder()
let demo_region_2 = new DemoRegionBuilder()
// .. repeat for every equivalent of `#region demo_region_X` that would be found in C#
[<EntryPoint>]
let main(args: string[]) =
let _ =
demo_region_1 {
printfn "hello, world" // this line appears in the web page
}
0With the markdown looking like this:
` ` ` fsharp --project ./MySampleProject.fsproj --source-file ./MySampleFile.fs --region demo_region_1
printfn "hello, world" // this line appears in the web page
` ` `Adding @KevinRansom to see if he has any additional insight, but I'm still leaning towards specially-formatted comments, because that's essentially what C#/VB #regions are anyways.
5fd1765 to
9a07403
Compare
| i <- i + delta | ||
| buf.ToString() | ||
|
|
||
| let private newlineifyErrorString (message:string) = message.Replace(newlineProxy, Environment.NewLine) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
"newlineify" 😆
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Slightly shorter than newlineificize.
| .Where(file => | ||
| { | ||
| return directoryAccessor.GetFullyQualifiedPath(file.Directory).FullName == rootDirectory.FullName && file.Extension == ".csproj"; | ||
| return directoryAccessor.GetFullyQualifiedPath(file.Directory).FullName == rootDirectory.FullName && (file.Extension == ".csproj" || file.Extension == ".fsproj"); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There's a potential inconsistency here in that I can do this and it will be valid:
```c# --project ./something.fsproj
```There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
My plan (hope?) was to merge as-is to feature/fsharp (where this PR is targeted) and then do a merge in from master to get @colombod's changes that add a language parameter to the workspace object and clean up the various hacks I added around detecting the language.
tl;dr - Editing/running F# snippets in Try .NET and displaying diagnostics.
Oh boy, is this a giant pile of hacks.
I'm creating this PR so early in the process to get feedback on how to better architect these changes, because right now I'm rather ashamed of what I've done.
List of sins and why I committed them (pun intended):
Workspace servers: Rather than try to factor out all the calls toI've mostly plumbed through aRoslynWorkspaceServerand properly abstract them, I createdWorkspaceServerMultiplexerwhich simply looks for the suffix.fsprojon the workspace type to redirect toFSharpWorkspaceServer; otherwise it defaults toRoslynWorkspaceServer. As I understand it, this will only work for on-disk workspaces which just happen to set their type to the project file path (see item 1 below).Languageproperty, and otherwise auto-detected it from the.fsprojsuffix for the workspace servers.In an attempt to reuse as much as possible (meaning less plumbing), I hijacked various functions to explicitly look for F#-specific file extensions and then bail in a different direction. SeeBufferInliningTransformer.cs,FileExtensions.cs, andSourceTextExtensions.cs. A method inBufferInliningTransformer.cshas been madevirtualto allow for F#-specific overriding.Markdig doesn't understand code fences of the typeTurns out it's not Markdig, but this repo; I found and updated the language parsing.fsharp, so to get it to appropriately classify F# blocks asAnnotatedCodeBlocks, I had to lie and say it was C#. The proper fix for this should be adding F# support to Markdig.RedirectedPackagewhich creates a directory under%TEMP%, copies everything from the parentPackage, and does the text substitution and all work there. (This also explains why I do source path mapping for F# diagnostics inLibrary.fs.) After compilation thebin/$(Configuration)directory is then copied back to the 'real' location to allow execution. See item 6.A below.Things that still need to be done:
Allow a workspace to properly state it's preferred server:RoslynWorkspaceServerorFSharpWorkspaceServer.Parameterize the hijacked methods and call sites to make the separation cleaner. See item 2 above.Cleaned up as much as possible for this PR. Will be cleaned up even more when enable language as property of workspaces #254 is integrated.FSharpWorkspaceServer.cs(future PR).FSharpWorkspaceServer.cs(future PR).and fix whatever other tests I most certainly broke.A. In the short term we could likely hijack the call to
dotnet buildand pass an additional property,/p:OutputPath=path\to\original\project\bin.Uninteresting note: The C# runner uses
#region/#endregiontags to designate which parts of the file to display in the editor. F# doesn't have the concept of regions but other tools cheat and use the specially-formatted comments,//#regionand//#endregion, so I also opted for that approach.