Skip to content

Commit

Permalink
Reference C# projects
Browse files Browse the repository at this point in the history
  • Loading branch information
georgewfraser committed Jun 15, 2018
1 parent a679f00 commit ba671fa
Show file tree
Hide file tree
Showing 10 changed files with 74 additions and 5 deletions.
1 change: 1 addition & 0 deletions TODO.md
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@
- Don't autocomplete things with spaces
- Crack FCS
- Reload options when .fsx is saved
- Invalidate check results when referenced .dlls are modified

# Optimizations
- Cancel redundant analyze-.fsproj sequences when .fsproj files get modified repeatedly
Expand Down
2 changes: 1 addition & 1 deletion package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -94,4 +94,4 @@
"typescript": "^2.6.1",
"vscode": "^1.1.18"
}
}
}
7 changes: 7 additions & 0 deletions sample/CSharpProject/CSharpProject.csproj
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
<Project Sdk="Microsoft.NET.Sdk">

<PropertyGroup>
<TargetFramework>netcoreapp2.1</TargetFramework>
</PropertyGroup>

</Project>
11 changes: 11 additions & 0 deletions sample/CSharpProject/Class1.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
using System;

namespace CSharpProject
{
public class Class1
{
public static String name() {
return "CSharp";
}
}
}
6 changes: 6 additions & 0 deletions sample/ReferenceCSharp/Library.fs
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
namespace ReferenceCSharp

module Say =
let hello () =
let csharp = CSharpProject.Class1.name()
printfn "Hello %s" csharp
15 changes: 15 additions & 0 deletions sample/ReferenceCSharp/ReferenceCSharp.fsproj
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
<Project Sdk="Microsoft.NET.Sdk">

<PropertyGroup>
<TargetFramework>netcoreapp2.1</TargetFramework>
</PropertyGroup>

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

<ItemGroup>
<ProjectReference Include="..\CSharpProject\CSharpProject.csproj" />
</ItemGroup>

</Project>
3 changes: 3 additions & 0 deletions src/FSharpLanguageServer/ProjectManager.fs
Original file line number Diff line number Diff line change
Expand Up @@ -293,6 +293,9 @@ type ProjectManager(client: ILanguageClient, checker: FSharpChecker) =
match analyzedByProjectFile.[r.FullName] with
| FsprojOptions(cracked, _) -> yield "-r:" + cracked.target.FullName
| _ -> ()
// Reference target .dll for .csproj proejcts
for r in cracked.otherProjectReferences do
yield "-r:" + r.FullName
// Reference packages
for r in cracked.packageReferences do
yield "-r:" + r.FullName
Expand Down
24 changes: 22 additions & 2 deletions src/ProjectCracker/ProjectCracker.fs
Original file line number Diff line number Diff line change
Expand Up @@ -31,8 +31,10 @@ type CrackedProject = {
/// List of source files.
/// These are fsc args, but presented separately because that's how FSharpProjectOptions wants them.
sources: FileInfo list
/// .fsproj files on references projects
/// .fsproj files
projectReferences: FileInfo list
/// .dlls corresponding to non-F# projects
otherProjectReferences: FileInfo list
/// .dlls
packageReferences: FileInfo list
/// An error was encountered while cracking the project
Expand Down Expand Up @@ -302,6 +304,18 @@ let private project(fsproj: FileInfo): ProjectAnalyzer =
let manager = AnalyzerManager(options)
manager.GetProject(fsproj.FullName)

let private projectTarget(csproj: FileInfo) =
let baseName = Path.GetFileNameWithoutExtension(csproj.Name)
let dllName = baseName + ".dll"
let placeholderTarget = FileInfo(Path.Combine [|csproj.DirectoryName; "bin"; "Debug"; "placeholder"; dllName|])
let projectAssetsJson = FileInfo(Path.Combine [|csproj.DirectoryName; "obj"; "project.assets.json"|])
if projectAssetsJson.Exists then
let assets = parseProjectAssets(projectAssetsJson)
// TODO this seems fragile
FileInfo(Path.Combine [|csproj.DirectoryName; "bin"; "Debug"; assets.framework; dllName|])
else
placeholderTarget

/// Crack an .fsproj file by:
/// - Running the "Restore" target and reading
/// - Reading .fsproj using the MSBuild API
Expand All @@ -328,6 +342,7 @@ let crack(fsproj: FileInfo): CrackedProject =
target=placeholderTarget
sources=sources
projectReferences=[]
otherProjectReferences=[]
packageReferences=[]
error=Some(sprintf "%s does not exist; maybe you need to build your project?" projectAssetsJson.FullName)
}
Expand All @@ -336,11 +351,15 @@ let crack(fsproj: FileInfo): CrackedProject =
// msbuild produces paths like src/LSP/bin/Debug/netcoreapp2.0/LSP.dll
// TODO this seems fragile
let target = FileInfo(Path.Combine [|fsproj.DirectoryName; "bin"; "Debug"; assets.framework; dllName|])
let isFsproj(f: FileInfo) = f.Name.EndsWith(".fsproj")
let fsProjects, csProjects = List.partition isFsproj assets.projects

{
fsproj=fsproj
target=target
sources=sources
projectReferences=assets.projects
projectReferences=fsProjects
otherProjectReferences=[for csproj in csProjects do yield projectTarget(csproj)]
packageReferences=assets.packages
error=None
}
Expand All @@ -350,6 +369,7 @@ let crack(fsproj: FileInfo): CrackedProject =
target=placeholderTarget
sources=[]
projectReferences=[]
otherProjectReferences=[]
packageReferences=[]
error=Some(e.Message)
}
8 changes: 7 additions & 1 deletion tests/FSharpLanguageServer.Tests/ServerTests.fs
Original file line number Diff line number Diff line change
Expand Up @@ -342,4 +342,10 @@ let ``create Run Test code lens``() =
let client, server = createServerAndReadFile("HasTests", "MyTests.fs")
let lenses = server.CodeLens({ textDocument = textDocument("HasTests", "MyTests.fs") }) |> Async.RunSynchronously
let lines = [for l in lenses do yield l.range.start.line]
CollectionAssert.Contains(lines, 5, sprintf "No line 5 in %A" lenses)
CollectionAssert.Contains(lines, 5, sprintf "No line 5 in %A" lenses)

[<Test>]
let ``report no type errors in CSharp reference``() =
let client, server = createServerAndReadFile("ReferenceCSharp", "Library.fs")
let messages = diagnosticMessages(client)
CollectionAssert.IsEmpty(messages)

0 comments on commit ba671fa

Please sign in to comment.