Skip to content
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

Use ProjInfo in tests #19

Draft
wants to merge 1 commit into
base: graph-tc
Choose a base branch
from
Draft
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
15 changes: 15 additions & 0 deletions FSharp.sln
Original file line number Diff line number Diff line change
Expand Up @@ -109,6 +109,8 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution
EndProject
Project("{F2A71F9B-5D33-465A-A702-920D77279786}") = "ParallelTypeCheckingTests", "tests\ParallelTypeCheckingTests\ParallelTypeCheckingTests.fsproj", "{59C31D40-97E0-4A69-ABD9-D316BD798ED8}"
EndProject
Project("{F2A71F9B-5D33-465A-A702-920D77279786}") = "ArgsGenerator", "tests\ArgsGenerator\ArgsGenerator.fsproj", "{90F850DD-52AD-40BC-A497-DE0382C1EE72}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
Expand Down Expand Up @@ -443,6 +445,18 @@ Global
{59C31D40-97E0-4A69-ABD9-D316BD798ED8}.Release|Any CPU.Build.0 = Release|Any CPU
{59C31D40-97E0-4A69-ABD9-D316BD798ED8}.Release|x86.ActiveCfg = Release|Any CPU
{59C31D40-97E0-4A69-ABD9-D316BD798ED8}.Release|x86.Build.0 = Release|Any CPU
{90F850DD-52AD-40BC-A497-DE0382C1EE72}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{90F850DD-52AD-40BC-A497-DE0382C1EE72}.Debug|Any CPU.Build.0 = Debug|Any CPU
{90F850DD-52AD-40BC-A497-DE0382C1EE72}.Debug|x86.ActiveCfg = Debug|Any CPU
{90F850DD-52AD-40BC-A497-DE0382C1EE72}.Debug|x86.Build.0 = Debug|Any CPU
{90F850DD-52AD-40BC-A497-DE0382C1EE72}.Proto|Any CPU.ActiveCfg = Debug|Any CPU
{90F850DD-52AD-40BC-A497-DE0382C1EE72}.Proto|Any CPU.Build.0 = Debug|Any CPU
{90F850DD-52AD-40BC-A497-DE0382C1EE72}.Proto|x86.ActiveCfg = Debug|Any CPU
{90F850DD-52AD-40BC-A497-DE0382C1EE72}.Proto|x86.Build.0 = Debug|Any CPU
{90F850DD-52AD-40BC-A497-DE0382C1EE72}.Release|Any CPU.ActiveCfg = Release|Any CPU
{90F850DD-52AD-40BC-A497-DE0382C1EE72}.Release|Any CPU.Build.0 = Release|Any CPU
{90F850DD-52AD-40BC-A497-DE0382C1EE72}.Release|x86.ActiveCfg = Release|Any CPU
{90F850DD-52AD-40BC-A497-DE0382C1EE72}.Release|x86.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
Expand Down Expand Up @@ -476,6 +490,7 @@ Global
{BEC6E796-7E53-4888-AAFC-B8FD55C425DF} = {CE70D631-C5DC-417E-9CDA-B16097BEF1AC}
{9C7523BA-7AB2-4604-A5FD-653E82C2BAD1} = {CE70D631-C5DC-417E-9CDA-B16097BEF1AC}
{59C31D40-97E0-4A69-ABD9-D316BD798ED8} = {CFE3259A-2D30-4EB0-80D5-E8B5F3D01449}
{90F850DD-52AD-40BC-A497-DE0382C1EE72} = {CFE3259A-2D30-4EB0-80D5-E8B5F3D01449}
EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution
SolutionGuid = {BD5177C7-1380-40E7-94D2-7768E1A8B1B8}
Expand Down
1 change: 1 addition & 0 deletions NuGet.config
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
<add key="dotnet-public" value="https://pkgs.dev.azure.com/dnceng/public/_packaging/dotnet-public/nuget/v3/index.json" />
<add key="vssdk" value="https://pkgs.dev.azure.com/azure-public/vside/_packaging/vssdk/nuget/v3/index.json" />
<add key="vs-impl" value="https://pkgs.dev.azure.com/azure-public/vside/_packaging/vs-impl/nuget/v3/index.json" />
<add key="NuGet official package source" value="https://api.nuget.org/v3/index.json" />
</packageSources>
<disabledPackageSources>
<clear />
Expand Down
2 changes: 0 additions & 2 deletions src/Compiler/Driver/ParseAndCheckInputs.fs
Original file line number Diff line number Diff line change
Expand Up @@ -1738,8 +1738,6 @@ let CheckMultipleInputsInParallel
let mutable CheckMultipleInputsUsingGraphMode: CheckArgs -> (PartialResult list * TcState) =
fun _ -> failwith $"Graph-based type-checking function not set - set CheckMultipleInputsUsingGraphMode before using this mode"

let mutable typeCheckingMode: TypeCheckingMode = TypeCheckingMode.Sequential

let CheckClosedInputSet (ctok, checkForErrors, tcConfig: TcConfig, tcImports, tcGlobals, prefixPathOpt, tcState, eagerFormat, inputs) =
// tcEnvAtEndOfLastFile is the environment required by fsi.exe when incrementally adding definitions
let results, tcState =
Expand Down
2 changes: 0 additions & 2 deletions src/Compiler/Driver/ParseAndCheckInputs.fsi
Original file line number Diff line number Diff line change
Expand Up @@ -202,8 +202,6 @@ val CheckMultipleInputsFinish:
/// Finish the checking of a closed set of inputs
val CheckClosedInputSetFinish: CheckedImplFile list * TcState -> TcState * CheckedImplFile list * ModuleOrNamespace

val mutable typeCheckingMode: TypeCheckingMode

/// Check a closed set of inputs
val CheckClosedInputSet:
ctok: CompilationThreadToken *
Expand Down
23 changes: 23 additions & 0 deletions tests/ArgsGenerator/ArgsGenerator.fsproj
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
<Project Sdk="Microsoft.NET.Sdk">

<PropertyGroup>
<TargetFramework>net7.0</TargetFramework>
<GenerateDocumentationFile>true</GenerateDocumentationFile>
<OutputType>exe</OutputType>
<DisableImplicitFSharpCoreReference>true</DisableImplicitFSharpCoreReference>
</PropertyGroup>

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

<ItemGroup>
<PackageReference Include="Ionide.ProjInfo.FCS" Version="0.61.0" />
<PackageReference Include="FSharp.Core" Version="6.0.5" />
<PackageReference Include="Microsoft.Build.Framework" Version="17.4.0" ExcludeAssets="runtime" />
<PackageReference Include="Microsoft.Build.Locator" Version="1.5.5" />
<PackageReference Include="Microsoft.Build.Tasks.Core" Version="17.4.0" ExcludeAssets="runtime" />
<PackageReference Include="Microsoft.Build.Utilities.Core" Version="17.4.0" ExcludeAssets="runtime" />
</ItemGroup>

</Project>
40 changes: 40 additions & 0 deletions tests/ArgsGenerator/Program.fs
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
module ArgsGenerator

open System.IO
open FSharp.Compiler.CodeAnalysis
open Ionide.ProjInfo

let optionsToArgs (opts: FSharpProjectOptions) : string[] =
Array.append opts.OtherOptions opts.SourceFiles

let loadProjectArgs (projectFile: string) =
let dir = Path.GetDirectoryName projectFile
let _ = Init.init (DirectoryInfo dir) None

let props =
[
"TargetFramework", "net7.0"
"Configuration", "Release"
]
let res =
ProjectLoader.getProjectInfo projectFile props (BinaryLogGeneration.Within(DirectoryInfo("c:/projekty/fsharp/cracking_logs")))

match res [] with
| Result.Ok _res ->
let fcs = FCS.mapToFSharpProjectOptions _res []
let args = optionsToArgs fcs
args
| Result.Error err -> failwith $"Failed to crack project: {err}"

/// Given a project file to analyse, generates fsc commandline arguments for compiling it, then saves them to a file.
[<EntryPoint>]
let main argv =
match argv with
| [| projectFile; outputFile |] ->
printfn $"Loading project args for project file: {projectFile}"
let args = loadProjectArgs projectFile
printfn $"Loaded {args.Length} args. Saving them to {outputFile}"
File.WriteAllLines(outputFile, args)
0
| _ ->
failwith "Invalid args. Usage: 'ArgsGenerator.exe %project_file% %output_file%'"
Original file line number Diff line number Diff line change
Expand Up @@ -72,8 +72,4 @@
<PackageReference Include="FSharp.Core" Version="$(FSharpCoreShippedPackageVersionValue)" />
</ItemGroup>

<ItemGroup>
<PackageReference Include="Buildalyzer" Version="4.1.2" />
</ItemGroup>

</Project>
31 changes: 12 additions & 19 deletions tests/ParallelTypeCheckingTests/Program.fs
Original file line number Diff line number Diff line change
@@ -1,35 +1,28 @@
module internal ParallelTypeCheckingTests.Program

#nowarn "1182"

open FSharp.Compiler.CompilerConfig
open ParallelTypeCheckingTests.TestUtils

let _parse (argv: string[]) : Args =
let parseMode (mode: string) =
match mode.ToLower() with
let parseArgs (argv: string[]) : Args =
let parseMode (method: string) =
match method.ToLower() with
| "sequential" -> Method.Sequential
| "parallelfs" -> Method.ParallelCheckingOfBackedImplFiles
| "graph" -> Method.Graph
| _ -> failwith $"Unrecognised mode: {mode}"
| _ -> failwith $"Unrecognised method: {method}"

let path, mode, workingDir =
let method, path =
match argv with
| [| path |] -> path, Method.Sequential, None
| [| path; method |] -> path, parseMode method, None
| [| path; method; workingDir |] -> path, parseMode method, Some workingDir
| _ -> failwith "Invalid args - use 'args_path [method [fs-parallel]]'"
| [| path |] -> Method.Graph, path
| [| method; path |] -> parseMode method, path
| _ -> failwith "Invalid args. Usage: '%method% %project_file%'"

{
Path = path
LineLimit = None
Method = mode
WorkingDir = workingDir
Method = method
ProjectFile = path
}

[<EntryPoint>]
let main _argv =
let args = _parse _argv
let args = { args with LineLimit = None }
let main argv =
let args = parseArgs argv
TestCompilationFromCmdlineArgs.TestCompilerFromArgs args
0
Original file line number Diff line number Diff line change
Expand Up @@ -10,55 +10,22 @@ open ParallelTypeCheckingTests.TestUtils

type Codebase =
{
WorkDir: string
Path: string
Limit: int option
ProjectFile : string
}

let codebases =
[|
{
WorkDir = $@"{__SOURCE_DIRECTORY__}\.fcs_test\src\compiler"
Path = $@"{__SOURCE_DIRECTORY__}\FCS.args.txt"
Limit = None
ProjectFile = $@"{__SOURCE_DIRECTORY__}\.fcs_test\src\compiler\FSharp.Compiler.Service.fsproj"
}
{
WorkDir = $@"{__SOURCE_DIRECTORY__}\.fcs_test\tests\FSharp.Compiler.ComponentTests"
Path = $@"{__SOURCE_DIRECTORY__}\ComponentTests.args.txt"
Limit = None
ProjectFile = $@"{__SOURCE_DIRECTORY__}\.fcs_test\tests\FSharp.Compiler.ComponentTests\FSharp.Compiler.ComponentTests.fsproj"
}
|]

let internal setupParsed config =
let {
Path = path
LineLimit = lineLimit
Method = method
WorkingDir = workingDir
} =
config

let args =
System.IO.File.ReadAllLines(path |> replacePaths)
|> fun lines ->
match lineLimit with
| Some limit -> Array.take (Math.Min(limit, lines.Length)) lines
| None -> lines
|> Array.map replacePaths

setupCompilationMethod method

printfn $"Method: {method}"
let args =
match method with
| Method.Sequential -> args
| Method.ParallelCheckingOfBackedImplFiles ->
Array.append args [|"--test:ParallelCheckingWithSignatureFilesOn"|]
| Method.Graph ->
Array.append args [|"--test:GraphBasedChecking"|]

printfn $"WorkingDir = {workingDir}"
workingDir |> Option.iter (fun dir -> Environment.CurrentDirectory <- dir)
let internal setupParsed {Method = method; ProjectFile = path} =
let args = getProjectArgs path
let args = Array.append args (TestCompilation.methodOptions method |> List.toArray)
args

let internal TestCompilerFromArgs (config: Args) : unit =
Expand All @@ -75,36 +42,33 @@ let internal TestCompilerFromArgs (config: Args) : unit =
}

try
printfn $"Type-checking method used: {config.Method}"
let args = setupParsed config
let exit: int = CommandLineMain.mainAux (args, true, Some exiter)
Assert.That(exit, Is.Zero)
finally
Environment.CurrentDirectory <- oldWorkDir

let internal codebaseToConfig code method =
let internal codebaseToConfig (code : Codebase) method =
{
Path = code.Path
LineLimit = code.Limit
ProjectFile = code.ProjectFile
Method = method
WorkingDir = Some code.WorkDir
}

[<TestCaseSource(nameof (codebases))>]
[<TestCaseSource(nameof codebases)>]
[<Explicit("Slow, only useful as a sanity check that the test codebase is sound and type-checks using the old method")>]
let ``1. Test sequential type-checking`` (code: Codebase) =
let config = codebaseToConfig code Method.Sequential
TestCompilerFromArgs config

/// Before running this test, you must prepare the codebase by running the script 'FCS.prepare.ps1'
[<TestCaseSource(nameof (codebases))>]
[<TestCaseSource(nameof codebases)>]
[<Explicit("Slow, only useful as a sanity check that the test codebase is sound and type-checks using the parallel-fs method")>]
let ``2. Test parallelfs type-checking`` (code: Codebase) =
let config = codebaseToConfig code Method.ParallelCheckingOfBackedImplFiles
TestCompilerFromArgs config

/// Before running this test, you must prepare the codebase by running the script 'FCS.prepare.ps1'
[<TestCaseSource(nameof (codebases))>]
[<TestCaseSource(nameof codebases)>]
let ``3. Test graph-based type-checking`` (code: Codebase) =
let config = codebaseToConfig code Method.Graph
printfn $"Args file generated: {config.ProjectFile}"
TestCompilerFromArgs config

33 changes: 4 additions & 29 deletions tests/ParallelTypeCheckingTests/Tests/TestDependencyResolution.fs
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@

open FSharp.Compiler.Service.Tests.Common
open System.IO
open Buildalyzer
open ParallelTypeCheckingTests
open ParallelTypeCheckingTests.Types
open ParallelTypeCheckingTests.Utils
Expand Down Expand Up @@ -337,53 +336,31 @@ let analyseResult (result: DepsResult) =
v |> Array.map (fun d -> result.Graph[d].Length) |> Array.max)

printfn $"TotalDeps: {totalDeps}, topFirstDeps: {topFirstDeps}"
//
// open GiGraph.Dot.Extensions
// open GiGraph.Dot.Output.Options
// let makeDotFile (path : string) (graph : Graph<File>) : unit =
// let g = DotGraph(directed=true)
// g.Layout.Direction <- DotLayoutDirection.LeftToRight
// let name (f : File) = $"{f.QualifiedName}.{Path.GetExtension(f.Name)}"
// graph
// |> Graph.collectEdges
// |> Array.iter (fun (a, b) -> g.Edges.Add(name a, name b) |> ignore)
// let _options = DotFormattingOptions()
// printfn $"{g.Build()}"
// g.SaveToFile(path)

[<Test>]
let ``Analyse hardcoded files`` () =
let deps = DependencyResolution.detectFileDependencies sampleFiles
printfn "Detected file dependencies:"
deps.Graph |> Graph.print
// makeDotFile "graph.dot" deps.Graph

let private parseProjectAndGetSourceFiles (projectFile: string) =
//let cacheDir = "."
//let getName projectFile = Path.Combine(Path.GetFileName(projectFile), ".fsharp"
let m = AnalyzerManager()
let analyzer = m.GetProject(projectFile)
let results = analyzer.Build()
// TODO Generalise for multiple TFMs
let res = results.Results |> Seq.head
let files = res.SourceFiles
log "built project using Buildalyzer"
files
projectFile
|> TestUtils.getProjectArgs
|> TestUtils.extractSourceFilesFromArgs

[<TestCase(__SOURCE_DIRECTORY__
+ @"\..\..\FSharp.Compiler.ComponentTests\FSharp.Compiler.ComponentTests.fsproj")>]
[<TestCase(__SOURCE_DIRECTORY__ + @"\..\..\..\src\Compiler\FSharp.Compiler.Service.fsproj")>]
[<Explicit("Slow as it uses Buildalyzer to analyse (build) projects first")>]
let ``Analyse whole projects and print statistics`` (projectFile: string) =
log $"Start finding file dependency graph for {projectFile}"
let files = parseProjectAndGetSourceFiles projectFile

log $"{files.Length} source files loaded using ProjInfo"
let files =
files
|> Array.Parallel.mapi (fun i f ->
let code = System.IO.File.ReadAllText(f)
let ast = parseSourceCode (f, code)

{
Idx = FileIdx.make i
//Code = code
Expand Down Expand Up @@ -420,5 +397,3 @@ let ``Analyse whole projects and print statistics`` (projectFile: string) =
v |> Array.map (fun d -> graph.Graph[d].Length) |> Array.max)

printfn $"TotalDeps: {totalDeps}, topFirstDeps: {topFirstDeps}, diff: {totalDeps - topFirstDeps}"

// makeDotFile "FCS.deps.dot" graph.Graph
Loading