diff --git a/benchmarks/CompilerServiceBenchmarks/Program.fs b/benchmarks/CompilerServiceBenchmarks/Program.fs index 386d8d95fb5..201856e3f98 100644 --- a/benchmarks/CompilerServiceBenchmarks/Program.fs +++ b/benchmarks/CompilerServiceBenchmarks/Program.fs @@ -7,7 +7,7 @@ open FSharp.Compiler.Text open FSharp.Compiler.AbstractIL open FSharp.Compiler.AbstractIL.IL open FSharp.Compiler.AbstractIL.ILBinaryReader -open CodeAnalysis.Text +open Microsoft.CodeAnalysis.Text open BenchmarkDotNet.Attributes open BenchmarkDotNet.Running @@ -80,6 +80,49 @@ type SourceText with member this.ToFSharpSourceText() = SourceText.weakTable.GetValue(this, Runtime.CompilerServices.ConditionalWeakTable<_,_>.CreateValueCallback(SourceText.create)) +[] +module Helpers = + + let createProject name referencedProjects = + let tmpPath = Path.GetTempPath() + let file = Path.Combine(tmpPath, Path.ChangeExtension(name, ".fs")) + { + ProjectFileName = Path.Combine(tmpPath, Path.ChangeExtension(name, ".dll")) + ProjectId = None + SourceFiles = [|file|] + OtherOptions = + Array.append [|"--optimize+"; "--target:library" |] (referencedProjects |> Array.ofList |> Array.map (fun x -> "-r:" + x.ProjectFileName)) + ReferencedProjects = + referencedProjects + |> List.map (fun x -> (x.ProjectFileName, x)) + |> Array.ofList + IsIncompleteTypeCheckEnvironment = false + UseScriptResolutionRules = false + LoadTime = DateTime() + UnresolvedReferences = None + OriginalLoadReferences = [] + ExtraProjectInfo = None + Stamp = Some 0L (* set the stamp to 0L on each run so we don't evaluate the whole project again *) + } + + let generateSourceCode moduleName = + sprintf """ +module Benchmark.%s + +type %s = + + val X : int + + val Y : int + + val Z : int + +let function%s (x: %s) = + let x = 1 + let y = 2 + let z = x + y + z""" moduleName moduleName moduleName moduleName + [] type CompilerService() = @@ -112,7 +155,7 @@ type CompilerService() = [] member __.Setup() = match checkerOpt with - | None -> checkerOpt <- Some(FSharpChecker.Create()) + | None -> checkerOpt <- Some(FSharpChecker.Create(projectCacheSize = 200)) | _ -> () match sourceOpt with @@ -127,18 +170,9 @@ type CompilerService() = |> Array.map (fun x -> (x.Location)) |> Some | _ -> () - - [] - member __.ParsingSetup() = - match checkerOpt with - | None -> failwith "no checker" - | Some(checker) -> - checker.InvalidateAll() - checker.ClearLanguageServiceRootCachesAndCollectAndFinalizeAllTransients() - checker.ParseFile("dummy.fs", SourceText.ofString "dummy", parsingOptions) |> Async.RunSynchronously |> ignore [] - member __.Parsing() = + member __.ParsingTypeCheckerFs() = match checkerOpt, sourceOpt with | None, _ -> failwith "no checker" | _, None -> failwith "no source" @@ -146,11 +180,15 @@ type CompilerService() = let results = checker.ParseFile("TypeChecker.fs", source.ToFSharpSourceText(), parsingOptions) |> Async.RunSynchronously if results.ParseHadErrors then failwithf "parse had errors: %A" results.Errors - [] - member __.ILReadingSetup() = - // With caching, performance increases an order of magnitude when re-reading an ILModuleReader. - // Clear it for benchmarking. - ClearAllILModuleReaderCache() + [] + member __.ParsingTypeCheckerFsSetup() = + match checkerOpt with + | None -> failwith "no checker" + | Some(checker) -> + checker.InvalidateAll() + checker.ClearLanguageServiceRootCachesAndCollectAndFinalizeAllTransients() + checker.ParseFile("dummy.fs", SourceText.ofString "dummy", parsingOptions) |> Async.RunSynchronously |> ignore + ClearAllILModuleReaderCache() [] member __.ILReading() = @@ -198,6 +236,85 @@ type CompilerService() = ) ) + [] + member __.ILReadingSetup() = + // With caching, performance increases an order of magnitude when re-reading an ILModuleReader. + // Clear it for benchmarking. + ClearAllILModuleReaderCache() + + member val TypeCheckFileWith100ReferencedProjectsOptions = + createProject "MainProject" + [ for i = 1 to 100 do + yield + createProject ("ReferencedProject" + string i) [] + ] + + member this.TypeCheckFileWith100ReferencedProjectsRun() = + let options = this.TypeCheckFileWith100ReferencedProjectsOptions + let file = options.SourceFiles.[0] + + match checkerOpt with + | None -> failwith "no checker" + | Some checker -> + let parseResult, checkResult = + checker.ParseAndCheckFileInProject(file, 0, SourceText.ofString (File.ReadAllText(file)), options) + |> Async.RunSynchronously + + if parseResult.Errors.Length > 0 then + failwithf "%A" parseResult.Errors + + match checkResult with + | FSharpCheckFileAnswer.Aborted -> failwith "aborted" + | FSharpCheckFileAnswer.Succeeded checkFileResult -> + + if checkFileResult.Errors.Length > 0 then + failwithf "%A" checkFileResult.Errors + + [] + member this.TypeCheckFileWith100ReferencedProjectsSetup() = + this.TypeCheckFileWith100ReferencedProjectsOptions.SourceFiles + |> Seq.iter (fun file -> + File.WriteAllText(file, generateSourceCode (Path.GetFileNameWithoutExtension(file))) + ) + + this.TypeCheckFileWith100ReferencedProjectsOptions.ReferencedProjects + |> Seq.iter (fun (_, referencedProjectOptions) -> + referencedProjectOptions.SourceFiles + |> Seq.iter (fun file -> + File.WriteAllText(file, generateSourceCode (Path.GetFileNameWithoutExtension(file))) + ) + ) + + this.TypeCheckFileWith100ReferencedProjectsRun() + + [] + member this.TypeCheckFileWith100ReferencedProjects() = + // Because the checker's projectcachesize is set to 200, this should be fast. + // If set to 3, it will be almost as slow as re-evaluating all project and it's projects references on setup; this could be a bug or not what we want. + this.TypeCheckFileWith100ReferencedProjectsRun() + + [] + member this.TypeCheckFileWith100ReferencedProjectsCleanup() = + this.TypeCheckFileWith100ReferencedProjectsOptions.SourceFiles + |> Seq.iter (fun file -> + try File.Delete(file) with | _ -> () + ) + + this.TypeCheckFileWith100ReferencedProjectsOptions.ReferencedProjects + |> Seq.iter (fun (_, referencedProjectOptions) -> + referencedProjectOptions.SourceFiles + |> Seq.iter (fun file -> + try File.Delete(file) with | _ -> () + ) + ) + + match checkerOpt with + | None -> failwith "no checker" + | Some(checker) -> + checker.InvalidateAll() + checker.ClearLanguageServiceRootCachesAndCollectAndFinalizeAllTransients() + ClearAllILModuleReaderCache() + [] let main argv = let _ = BenchmarkRunner.Run() diff --git a/benchmarks/Directory.Build.props b/benchmarks/Directory.Build.props deleted file mode 100644 index bb8eac309b1..00000000000 --- a/benchmarks/Directory.Build.props +++ /dev/null @@ -1,3 +0,0 @@ - - - diff --git a/benchmarks/Directory.Build.targets b/benchmarks/Directory.Build.targets deleted file mode 100644 index ccd47cc0a9a..00000000000 --- a/benchmarks/Directory.Build.targets +++ /dev/null @@ -1,3 +0,0 @@ - - - diff --git a/eng/Version.Details.xml b/eng/Version.Details.xml index f7bc5720dee..accc00e5562 100644 --- a/eng/Version.Details.xml +++ b/eng/Version.Details.xml @@ -3,9 +3,9 @@ - + https://github.com/dotnet/arcade - 4e21d52dabbb9f5705a90f097acb1465a0354c0d + 46718d98c0fd03690a6a8c83da692a4a85a17902 diff --git a/eng/common/CheckSymbols.ps1 b/eng/common/CheckSymbols.ps1 index 074b423245c..b8d84607b89 100644 --- a/eng/common/CheckSymbols.ps1 +++ b/eng/common/CheckSymbols.ps1 @@ -9,7 +9,8 @@ Add-Type -AssemblyName System.IO.Compression.FileSystem function FirstMatchingSymbolDescriptionOrDefault { param( [string] $FullPath, # Full path to the module that has to be checked - [string] $TargetServerParam # Parameter to pass to `Symbol Tool` indicating the server to lookup for symbols + [string] $TargetServerParam, # Parameter to pass to `Symbol Tool` indicating the server to lookup for symbols + [string] $SymbolsPath ) $FileName = [System.IO.Path]::GetFileName($FullPath) @@ -33,9 +34,9 @@ function FirstMatchingSymbolDescriptionOrDefault { # DWARF file for a .dylib $DylibDwarf = $SymbolPath.Replace($Extension, ".dylib.dwarf") - - .\dotnet-symbol.exe --symbols --modules $TargetServerParam $FullPath -o $SymbolsPath -d | Out-Null - + + .\dotnet-symbol.exe --symbols --modules --windows-pdbs $TargetServerParam $FullPath -o $SymbolsPath | Out-Null + if (Test-Path $PdbPath) { return "PDB" } @@ -73,8 +74,9 @@ function CountMissingSymbols { $MissingSymbols = 0 $PackageId = [System.IO.Path]::GetFileNameWithoutExtension($PackagePath) - $ExtractPath = $ExtractPath + $PackageId; - $SymbolsPath = $ExtractPath + $PackageId + ".Symbols"; + $PackageGuid = New-Guid + $ExtractPath = Join-Path -Path $ExtractPath -ChildPath $PackageGuid + $SymbolsPath = Join-Path -Path $ExtractPath -ChildPath "Symbols" [System.IO.Compression.ZipFile]::ExtractToDirectory($PackagePath, $ExtractPath) @@ -84,10 +86,15 @@ function CountMissingSymbols { Get-ChildItem -Recurse $ExtractPath | Where-Object {$RelevantExtensions -contains $_.Extension} | ForEach-Object { - Write-Host -NoNewLine "`t Checking file" $_.FullName "... " + if ($_.FullName -Match "\\ref\\") { + Write-Host "`t Ignoring reference assembly file" $_.FullName + return + } - $SymbolsOnMSDL = FirstMatchingSymbolDescriptionOrDefault $_.FullName "--microsoft-symbol-server" - $SymbolsOnSymWeb = FirstMatchingSymbolDescriptionOrDefault $_.FullName "--internal-server" + $SymbolsOnMSDL = FirstMatchingSymbolDescriptionOrDefault $_.FullName "--microsoft-symbol-server" $SymbolsPath + $SymbolsOnSymWeb = FirstMatchingSymbolDescriptionOrDefault $_.FullName "--internal-server" $SymbolsPath + + Write-Host -NoNewLine "`t Checking file" $_.FullName "... " if ($SymbolsOnMSDL -ne $null -and $SymbolsOnSymWeb -ne $null) { Write-Host "Symbols found on MSDL (" $SymbolsOnMSDL ") and SymWeb (" $SymbolsOnSymWeb ")" @@ -116,18 +123,35 @@ function CountMissingSymbols { function CheckSymbolsAvailable { if (Test-Path $ExtractPath) { - Remove-Item -recurse $ExtractPath + Remove-Item $ExtractPath -Force -Recurse -ErrorAction SilentlyContinue } Get-ChildItem "$InputPath\*.nupkg" | ForEach-Object { $FileName = $_.Name + + # These packages from Arcade-Services include some native libraries that + # our current symbol uploader can't handle. Below is a workaround until + # we get issue: https://github.com/dotnet/arcade/issues/2457 sorted. + if ($FileName -Match "Microsoft\.DotNet\.Darc\.") { + Write-Host "Ignoring Arcade-services file: $FileName" + Write-Host + return + } + elseif ($FileName -Match "Microsoft\.DotNet\.Maestro\.Tasks\.") { + Write-Host "Ignoring Arcade-services file: $FileName" + Write-Host + return + } + Write-Host "Validating $FileName " $Status = CountMissingSymbols "$InputPath\$FileName" if ($Status -ne 0) { Write-Error "Missing symbols for $Status modules in the package $FileName" } + + Write-Host } } diff --git a/fcs/Directory.Build.props b/fcs/Directory.Build.props index 4c8aac0a5b6..50e4c3e67b5 100644 --- a/fcs/Directory.Build.props +++ b/fcs/Directory.Build.props @@ -20,4 +20,19 @@ $(ArtifactsObjDir)\fcs true + + + + $(MSBuildThisFileDirectory)..\src + 22.0.3 + --version:$(VersionPrefix) + false + + + $(FSharpSourcesRoot)\..\packages\FSharp.Compiler.Tools.4.1.27\tools + fsi.exe + $(ArtifactsBinDir)\FSharp.Build\Proto\net472 + 4.6.2 + net461 + diff --git a/fcs/FSharp.Compiler.Service.MSBuild.v12/FSharp.Compiler.Service.MSBuild.v12.fsproj b/fcs/FSharp.Compiler.Service.MSBuild.v12/FSharp.Compiler.Service.MSBuild.v12.fsproj index 20e1f29af35..9f7b3d20b29 100644 --- a/fcs/FSharp.Compiler.Service.MSBuild.v12/FSharp.Compiler.Service.MSBuild.v12.fsproj +++ b/fcs/FSharp.Compiler.Service.MSBuild.v12/FSharp.Compiler.Service.MSBuild.v12.fsproj @@ -1,11 +1,7 @@  - - $(MSBuildProjectDirectory)\..\..\src - - - net461 + $(FcsTargetNetFxFramework) true $(DefineConstants);CROSS_PLATFORM_COMPILER $(DefineConstants);ENABLE_MONO_SUPPORT @@ -28,7 +24,7 @@ - + diff --git a/fcs/FSharp.Compiler.Service.ProjectCracker/FSharp.Compiler.Service.ProjectCracker.fsproj b/fcs/FSharp.Compiler.Service.ProjectCracker/FSharp.Compiler.Service.ProjectCracker.fsproj index 648f66924df..a9cb30ba0f7 100644 --- a/fcs/FSharp.Compiler.Service.ProjectCracker/FSharp.Compiler.Service.ProjectCracker.fsproj +++ b/fcs/FSharp.Compiler.Service.ProjectCracker/FSharp.Compiler.Service.ProjectCracker.fsproj @@ -1,8 +1,7 @@  - - net461 + $(FcsTargetNetFxFramework) true @@ -20,14 +19,14 @@ ProjectCrackerOptions.fs - - - + + + - + \ No newline at end of file diff --git a/fcs/FSharp.Compiler.Service.ProjectCrackerTool/FSharp.Compiler.Service.ProjectCracker.targets b/fcs/FSharp.Compiler.Service.ProjectCrackerTool/FSharp.Compiler.Service.ProjectCracker.targets index bd1c93e7979..ed01293adaf 100644 --- a/fcs/FSharp.Compiler.Service.ProjectCrackerTool/FSharp.Compiler.Service.ProjectCracker.targets +++ b/fcs/FSharp.Compiler.Service.ProjectCrackerTool/FSharp.Compiler.Service.ProjectCracker.targets @@ -1,7 +1,7 @@ - - + + diff --git a/fcs/FSharp.Compiler.Service.ProjectCrackerTool/FSharp.Compiler.Service.ProjectCrackerTool.fsproj b/fcs/FSharp.Compiler.Service.ProjectCrackerTool/FSharp.Compiler.Service.ProjectCrackerTool.fsproj index 3beb0e1f996..19789a96299 100644 --- a/fcs/FSharp.Compiler.Service.ProjectCrackerTool/FSharp.Compiler.Service.ProjectCrackerTool.fsproj +++ b/fcs/FSharp.Compiler.Service.ProjectCrackerTool/FSharp.Compiler.Service.ProjectCrackerTool.fsproj @@ -1,12 +1,8 @@  - - $(MSBuildProjectDirectory)\..\..\src - - Exe - net461 + $(FcsTargetNetFxFramework) true $(DefineConstants);CROSS_PLATFORM_COMPILER $(DefineConstants);ENABLE_MONO_SUPPORT @@ -23,7 +19,7 @@ - + diff --git a/fcs/FSharp.Compiler.Service.Tests/CSharp_Analysis/CSharp_Analysis.csproj b/fcs/FSharp.Compiler.Service.Tests/CSharp_Analysis/CSharp_Analysis.csproj index 30d3c96317f..534a1435415 100644 --- a/fcs/FSharp.Compiler.Service.Tests/CSharp_Analysis/CSharp_Analysis.csproj +++ b/fcs/FSharp.Compiler.Service.Tests/CSharp_Analysis/CSharp_Analysis.csproj @@ -1,7 +1,7 @@  - net461;netstandard2.0 + $(FcsTargetNetFxFramework);netstandard2.0 false $(NoWarn);0067;1591 diff --git a/fcs/FSharp.Compiler.Service.Tests/FSharp.Compiler.Service.Tests.fsproj b/fcs/FSharp.Compiler.Service.Tests/FSharp.Compiler.Service.Tests.fsproj index 1fe39896aa0..9019c4f017a 100644 --- a/fcs/FSharp.Compiler.Service.Tests/FSharp.Compiler.Service.Tests.fsproj +++ b/fcs/FSharp.Compiler.Service.Tests/FSharp.Compiler.Service.Tests.fsproj @@ -1,11 +1,7 @@ - - $(MSBuildProjectDirectory)\..\..\src - - - net461;netcoreapp2.0 + $(FcsTargetNetFxFramework);netcoreapp2.0 true 4.1.19 $(NoWarn);44;75; @@ -81,7 +77,7 @@ - + @@ -89,7 +85,7 @@ - + diff --git a/fcs/FSharp.Compiler.Service/FSharp.Compiler.Service.fsproj b/fcs/FSharp.Compiler.Service/FSharp.Compiler.Service.fsproj index c992397a72f..257344d1e18 100644 --- a/fcs/FSharp.Compiler.Service/FSharp.Compiler.Service.fsproj +++ b/fcs/FSharp.Compiler.Service/FSharp.Compiler.Service.fsproj @@ -1,12 +1,8 @@ - - $(MSBuildProjectDirectory)\..\..\src - - - - net461;netstandard2.0 + + $(FcsTargetNetFxFramework);netstandard2.0 true $(DefineConstants);COMPILER $(DefineConstants);BUILD_FROM_SOURCE @@ -638,7 +634,7 @@ - + @@ -650,7 +646,7 @@ - + diff --git a/fcs/README.md b/fcs/README.md index ac97222a3c6..f0126f369c8 100644 --- a/fcs/README.md +++ b/fcs/README.md @@ -28,7 +28,7 @@ There are subtle differences between FSharp.Compiler.Service and FSharp.Compiler FCS uses its own version number sequence for assemblies and packages, approximately following SemVer rules. To update the version number a global replace through fcs\... is currently needed, e.g. - fcs.props + Directory.Build.props nuget/FSharp.Compiler.Service.nuspec nuget/FSharp.Compiler.Service.MSBuild.v12.nuspec nuget/FSharp.Compiler.Service.ProjectCracker.nuspec diff --git a/fcs/fcs.props b/fcs/fcs.props deleted file mode 100644 index 207d1f8085b..00000000000 --- a/fcs/fcs.props +++ /dev/null @@ -1,14 +0,0 @@ - - - - - - 22.0.3 - --version:$(VersionPrefix) - false - - - $(FSharpSourcesRoot)\..\packages\FSharp.Compiler.Tools.4.1.27\tools - fsi.exe - - \ No newline at end of file diff --git a/fcs/samples/EditorService/EditorService.fsproj b/fcs/samples/EditorService/EditorService.fsproj index 25795d9299c..d71d6dc2913 100644 --- a/fcs/samples/EditorService/EditorService.fsproj +++ b/fcs/samples/EditorService/EditorService.fsproj @@ -1,8 +1,7 @@  - - net461;netcoreapp2.0 + $(FcsTargetNetFxFramework);netcoreapp2.0 true Exe false @@ -12,11 +11,11 @@ - + - + diff --git a/fcs/samples/FscExe/FscExe.fsproj b/fcs/samples/FscExe/FscExe.fsproj index a160f690d2f..97553e41249 100644 --- a/fcs/samples/FscExe/FscExe.fsproj +++ b/fcs/samples/FscExe/FscExe.fsproj @@ -1,8 +1,7 @@  - - net461 + $(FcsTargetNetFxFramework) true Exe false @@ -14,10 +13,10 @@ - + - + diff --git a/fcs/samples/FsiExe/FsiExe.fsproj b/fcs/samples/FsiExe/FsiExe.fsproj index 4ce18ab142c..94a2534c0e2 100644 --- a/fcs/samples/FsiExe/FsiExe.fsproj +++ b/fcs/samples/FsiExe/FsiExe.fsproj @@ -1,8 +1,7 @@  - - net461 + $(FcsTargetNetFxFramework) true Exe false @@ -16,10 +15,10 @@ - + - + diff --git a/fcs/samples/InteractiveService/InteractiveService.fsproj b/fcs/samples/InteractiveService/InteractiveService.fsproj index 75686578f21..bd834961496 100644 --- a/fcs/samples/InteractiveService/InteractiveService.fsproj +++ b/fcs/samples/InteractiveService/InteractiveService.fsproj @@ -1,8 +1,7 @@  - - net461 + $(FcsTargetNetFxFramework) true Exe false @@ -12,10 +11,10 @@ - + - + diff --git a/fcs/samples/Tokenizer/Tokenizer.fsproj b/fcs/samples/Tokenizer/Tokenizer.fsproj index 75686578f21..bd834961496 100644 --- a/fcs/samples/Tokenizer/Tokenizer.fsproj +++ b/fcs/samples/Tokenizer/Tokenizer.fsproj @@ -1,8 +1,7 @@  - - net461 + $(FcsTargetNetFxFramework) true Exe false @@ -12,10 +11,10 @@ - + - + diff --git a/fcs/samples/UntypedTree/UntypedTree.fsproj b/fcs/samples/UntypedTree/UntypedTree.fsproj index 75686578f21..bd834961496 100644 --- a/fcs/samples/UntypedTree/UntypedTree.fsproj +++ b/fcs/samples/UntypedTree/UntypedTree.fsproj @@ -1,8 +1,7 @@  - - net461 + $(FcsTargetNetFxFramework) true Exe false @@ -12,10 +11,10 @@ - + - + diff --git a/global.json b/global.json index fec974408a0..cd0f7712fcc 100644 --- a/global.json +++ b/global.json @@ -10,7 +10,7 @@ } }, "msbuild-sdks": { - "Microsoft.DotNet.Arcade.Sdk": "1.0.0-beta.19217.1", + "Microsoft.DotNet.Arcade.Sdk": "1.0.0-beta.19218.1", "Microsoft.DotNet.Helix.Sdk": "2.0.0-beta.19069.2" } }