Skip to content
Open
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
9 changes: 9 additions & 0 deletions ReSharper.FSharp/Directory.Build.props
Original file line number Diff line number Diff line change
Expand Up @@ -33,5 +33,14 @@
<PsiFeaturesTestSubplatform>$(Subplatform).Psi.Features_test_Framework.Props</PsiFeaturesTestSubplatform>
<RdBackendCommonSubplatform>$(Subplatform).Rider_RdBackend.Common.Props</RdBackendCommonSubplatform>
<RiderBackendSubplatform>$(Subplatform).Rider_Rider.Backend.Props</RiderBackendSubplatform>
<UseLocalFSharpCompilerService>true</UseLocalFSharpCompilerService>
<LocalFSharpRepository>$(MSBuildThisFileDirectory)../../fsharp</LocalFSharpRepository>
</PropertyGroup>

<ItemGroup>
<PackageReference Condition="'$(UseLocalFSharpCompilerService)' == 'false'" Include="JetBrains.FSharp.Compiler.Service" />
<ProjectReference Condition="'$(UseLocalFSharpCompilerService)' == 'true'" Include="$(LocalFSharpRepository)/src/Compiler/FSharp.Compiler.Service.fsproj" />
<ProjectReference Condition="'$(UseLocalFSharpCompilerService)' == 'true'" Include="$(LocalFSharpRepository)/src/FSharp.Compiler.Interactive.Settings/FSharp.Compiler.Interactive.Settings.fsproj" />
<ProjectReference Condition="'$(UseLocalFSharpCompilerService)' == 'true'" Include="$(LocalFSharpRepository)/src/FSharp.DependencyManager.Nuget/FSharp.DependencyManager.Nuget.fsproj" />
</ItemGroup>
</Project>
2 changes: 1 addition & 1 deletion ReSharper.FSharp/TypeProviders.Host.targets
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@

<ItemGroup>
<PackageReference Include="FSharp.Core" />
<PackageReference Include="JetBrains.FSharp.Compiler.Service" />
<PackageReference Condition="'$(UseLocalFSharpCompilerService)' == 'false'" Include="JetBrains.FSharp.Compiler.Service" />
</ItemGroup>

</Project>
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,6 @@
<ItemGroup>
<PackageReference Include="FSharp.Core" />
<PackageReference Include="JetBrains.Annotations" />
<PackageReference Include="JetBrains.FSharp.Compiler.Service" />
<PackageReference Include="JetBrains.Lifetimes" />
<PackageReference Include="JetBrains.RdFramework" />
<PackageReference Include="System.Diagnostics.Debug" />
Expand All @@ -46,4 +45,4 @@
<Import Project="ManagedProject.Generated.Targets" Condition="$(InternalBuild)" />
<Import Project="Sdk.targets" Sdk="JetBrains.Toolset.MainSolution.Sdk" Version="20200625.1.1.2" Condition="$(InternalBuild)" />
<Import Project="Sdk.targets" Sdk="Microsoft.NET.Sdk" Condition="!$(InternalBuild)" />
</Project>
</Project>
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,6 @@
<ItemGroup>
<PackageReference Include="FSharp.Core" />
<PackageReference Include="JetBrains.Annotations" />
<PackageReference Include="JetBrains.FSharp.Compiler.Service" />
<PackageReference Include="JetBrains.Lifetimes" />
<PackageReference Include="JetBrains.RdFramework" />
</ItemGroup>
Expand All @@ -39,4 +38,4 @@
<Import Project="ManagedProject.Generated.Targets" Condition="$(InternalBuild)" />
<Import Project="Sdk.targets" Sdk="JetBrains.Toolset.MainSolution.Sdk" Version="20200625.1.1.2" Condition="$(InternalBuild)" />
<Import Project="Sdk.targets" Sdk="Microsoft.NET.Sdk" Condition="!$(InternalBuild)" />
</Project>
</Project>
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
<DisableImplicitFSharpCoreReference>true</DisableImplicitFSharpCoreReference>
<RootNamespace>JetBrains.ReSharper.Plugins.FSharp</RootNamespace>
<AssemblyName>JetBrains.ReSharper.Plugins.FSharp.Common</AssemblyName>
<NoWarn>FS0057</NoWarn>
</PropertyGroup>

<ItemGroup>
Expand Down Expand Up @@ -73,7 +74,6 @@
<ItemGroup>
<PackageReference Include="FSharp.Core" />
<PackageReference Include="JetBrains.Annotations" />
<PackageReference Include="JetBrains.FSharp.Compiler.Service" />
<PackageReference Include="JetBrains.HabitatDetector" />
<PackageReference Include="JetBrains.Lifetimes" />
<PackageReference Include="JetBrains.RdFramework" />
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ open JetBrains.ReSharper.Plugins.FSharp.Shim.AssemblyReader
open JetBrains.ReSharper.Plugins.FSharp.Util
open JetBrains.ReSharper.Psi
open JetBrains.ReSharper.Psi.CSharp
open JetBrains.ReSharper.Psi.Caches
open JetBrains.ReSharper.Psi.Modules
open JetBrains.ReSharper.Psi.Tree
open JetBrains.ReSharper.Psi.VB
Expand All @@ -36,6 +37,7 @@ module FcsCheckerService =
SourceText.ofString(document.GetText())


// add the project key?
type FcsProject =
{ OutputPath: VirtualFileSystemPath
ProjectOptions: FSharpProjectOptions
Expand Down Expand Up @@ -74,6 +76,59 @@ type FcsProject =
writer.WriteLine()


[<SolutionComponent>]
type FcsSnapshotCache(fcsProjectProvider: IFcsProjectProvider, locks: IShellLocks) =
let snapshots = Dictionary<FcsProjectKey, FSharpProjectSnapshot>()

let rec removeReferences (projectKey: FcsProjectKey) =
match fcsProjectProvider.GetReferencedModule(projectKey) with
| None -> ()
| Some referencedModule ->

for referencingProject in referencedModule.ReferencingProjects do
removeReferences referencingProject
snapshots.Remove(referencingProject) |> ignore

let remove (psiModule: IPsiModule) =
let projectKey = FcsProjectKey.Create(psiModule)
snapshots.Remove(projectKey) |> ignore
removeReferences projectKey

member this.GetProjectSnapshot(projectKey: FcsProjectKey, options: FSharpProjectOptions) =
// todo: use source files in file snapshots?
lock this (fun _ ->
snapshots.GetOrCreateValue(projectKey, fun (projectKey: FcsProjectKey) ->
FSharpProjectSnapshot.FromOptions(options).RunAsTask()
)
)

interface IPsiSourceFileCache with
member this.MarkAsDirty(sourceFile) =
locks.AssertWriteAccessAllowed()
remove sourceFile.PsiModule

member this.OnDocumentChange(sourceFile, _) =
locks.AssertWriteAccessAllowed()
remove sourceFile.PsiModule

member this.OnPsiChange(elementContainingChanges, _) =
if isNotNull elementContainingChanges then
locks.AssertWriteAccessAllowed()
remove (elementContainingChanges.GetPsiModule())

member this.HasDirtyFiles = false
member this.UpToDate _ = true
member this.SyncUpdate _ = ()

member this.Build(_, _) = null
member this.Drop _ = ()
member this.Dump(_, _) = ()
member this.Load(_, _) = null
member this.Merge(_, _) = ()
member this.MergeLoaded _ = ()
member this.Save(_, _) = ()


[<RequireQualifiedAccess>]
type FcsProjectInvalidationType =
/// Used when invalidation is needed for a project still known to FCS.
Expand All @@ -88,14 +143,17 @@ type FcsProjectInvalidationType =
type FcsCheckerService(lifetime: Lifetime, logger: ILogger, onSolutionCloseNotifier: OnSolutionCloseNotifier,
settingsStore: ISettingsStore, locks: IShellLocks, configurations: RunsProducts.ProductConfigurations) =

let checker =
Environment.SetEnvironmentVariable("FCS_CheckFileInProjectCacheSize", "20")
let settingsStoreLive = settingsStore.BindToContextLive(lifetime, ContextRange.ApplicationWide)

let settingsStoreLive = settingsStore.BindToContextLive(lifetime, ContextRange.ApplicationWide)
let getSettingProperty name =
let setting = SettingsUtil.getEntry<FSharpOptions> settingsStore name
settingsStoreLive.GetValueProperty(lifetime, setting, null)

let getSettingProperty name =
let setting = SettingsUtil.getEntry<FSharpOptions> settingsStore name
settingsStoreLive.GetValueProperty(lifetime, setting, null)
// TODO: double check setting
let useTransparentCompiler = true //(getSettingProperty "UseTransparentCompiler").Value

let checker =
Environment.SetEnvironmentVariable("FCS_CheckFileInProjectCacheSize", "20")

let skipImpl = getSettingProperty "SkipImplementationAnalysis"
let analyzerProjectReferencesInParallel = getSettingProperty "ParallelProjectReferencesAnalysis"
Expand All @@ -106,7 +164,8 @@ type FcsCheckerService(lifetime: Lifetime, logger: ILogger, onSolutionCloseNotif
keepAllBackgroundResolutions = false,
keepAllBackgroundSymbolUses = false,
enablePartialTypeChecking = skipImpl.Value,
parallelReferenceResolution = analyzerProjectReferencesInParallel.Value)
parallelReferenceResolution = analyzerProjectReferencesInParallel.Value,
useTransparentCompiler = useTransparentCompiler)

checker

Expand All @@ -119,6 +178,7 @@ type FcsCheckerService(lifetime: Lifetime, logger: ILogger, onSolutionCloseNotif
member val AssemblyReaderShim = Unchecked.defaultof<IFcsAssemblyReaderShim> with get, set

member x.Checker = checker.Value
member val UseTransparentCompiler = useTransparentCompiler

member this.AssertFcsAccessThread() =
()
Expand Down Expand Up @@ -174,8 +234,19 @@ type FcsCheckerService(lifetime: Lifetime, logger: ILogger, onSolutionCloseNotif
let source = FcsCheckerService.getSourceText sourceFile.Document
logger.Trace("ParseAndCheckFile: start {0}, {1}", path, opName)

let getParseAndCheckResults () =
if useTransparentCompiler then
let projectKey = FcsProjectKey.Create(psiModule)
let fcsSnapshotCache = sourceFile.GetSolution().GetComponent<FcsSnapshotCache>()
let snapshot = fcsSnapshotCache.GetProjectSnapshot(projectKey, options)
match x.Checker.ParseAndCheckFileInProject(path, snapshot).RunAsTask() with
| _, FSharpCheckFileAnswer.Aborted -> None
| parseFileResults, FSharpCheckFileAnswer.Succeeded checkFileResults -> Some(parseFileResults, checkFileResults)
else
x.Checker.ParseAndCheckDocument(path, source, options, allowStaleResults, opName).RunAsTask()

// todo: don't cancel the computation when file didn't change
match x.Checker.ParseAndCheckDocument(path, source, options, allowStaleResults, opName).RunAsTask() with
match getParseAndCheckResults () with
| Some (parseResults, checkResults) ->
logger.Trace("ParseAndCheckFile: finish {0}, {1}", path, opName)
Some { ParseResults = parseResults; CheckResults = checkResults }
Expand All @@ -198,19 +269,34 @@ type FcsCheckerService(lifetime: Lifetime, logger: ILogger, onSolutionCloseNotif
let path = file.GetLocation().FullPath
logger.Trace("TryGetStaleCheckResults: start {0}, {1}", path, opName)

match x.Checker.TryGetRecentCheckResultsForFile(path, options) with
| Some (_, checkResults, _) ->
let recentCheckResults =
if not useTransparentCompiler then
x.Checker.TryGetRecentCheckResultsForFile(path, options)
|> Option.map (fun (_, checkResults, _) -> checkResults)
else
match x.FcsProjectProvider.GetFcsProject(file.PsiModule) with
| None -> None
| Some fcsProject ->

let projectKey = FcsProjectKey.Create(file.PsiModule)
let fcsSnapshotCache = file.GetSolution().GetComponent<FcsSnapshotCache>()
let snapshot = fcsSnapshotCache.GetProjectSnapshot(projectKey, fcsProject.ProjectOptions)
x.Checker.TryGetRecentCheckResultsForFile(path, snapshot)
|> Option.map snd

match recentCheckResults with
| Some checkResults ->
logger.Trace("TryGetStaleCheckResults: finish {0}, {1}", path, opName)
Some checkResults

| _ ->
logger.Trace("TryGetStaleCheckResults: fail {0}, {1}", path, opName)
None

member x.GetCachedScriptOptions(path) =
if checker.IsValueCreated then
checker.Value.GetCachedScriptOptions(path)
else None
else
None

member x.InvalidateFcsProject(projectOptions: FSharpProjectOptions, invalidationType: FcsProjectInvalidationType) =
if checker.IsValueCreated then
Expand All @@ -220,7 +306,13 @@ type FcsCheckerService(lifetime: Lifetime, logger: ILogger, onSolutionCloseNotif
checker.Value.ClearCache(Seq.singleton projectOptions)
| FcsProjectInvalidationType.Remove ->
logger.Trace("Invalidate FcsProject in FCS: {0}", projectOptions.ProjectFileName)
checker.Value.InvalidateConfiguration(projectOptions)
if useTransparentCompiler then
// InvalidateConfiguration isn't required for the transparent compiler as it works differently.
// InvalidateConfiguration in the BackgroundCompiler will recreate the createBuilderNode.
// This is not required in the TransparentCompiler and so Clearing the cache would be the proper equivalent.
checker.Value.ClearCache(Seq.singleton projectOptions)
else
checker.Value.InvalidateConfiguration(projectOptions)

/// Use with care: returns wrong symbol inside its non-recursive declaration, see dotnet/fsharp#7694.
member x.ResolveNameAtLocation(sourceFile: IPsiSourceFile, names, coords, resolveExpr: bool, opName) =
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -263,7 +263,13 @@ type FSharpScriptPsiModulesProvider(lifetime: Lifetime, solution: ISolution, cha
|> Option.iter (fun psiModule ->
match checkerService.GetCachedScriptOptions(path.FullPath) with
| Some options -> checkerService.InvalidateFcsProject(options, FcsProjectInvalidationType.Remove)
| None -> ()
| None ->
if checkerService.UseTransparentCompiler then
// The transparent compiler always returns GetCachedScriptOptions
// We can easily construct the project identifier (as it is done in GetProjectOptionsFromScript/GetProjectSnapshotFromScript)
// and clear the cache that way.
let projectIdentifier = ProjectSnapshot.FSharpProjectIdentifier($"%s{path.FullPath}.fsproj", "")
checkerService.Checker.ClearCache(Seq.singleton projectIdentifier)

scriptsFromProjectFiles.RemoveValue(path, psiModule) |> ignore
removePsiModule psiModule
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ module FSharpOptions =
let [<Literal>] nonFSharpProjectInMemoryReferences = "Analyze C# and VB.NET project references in-memory"
let [<Literal>] outOfScopeCompletion = "Enable out of scope items completion"
let [<Literal>] topLevelOpenCompletion = "Add 'open' declarations to top level module or namespace"
let [<Literal>] useTransparentCompilerDescription = "Use TransparentCompiler"


[<SettingsKey(typeof<FSharpSettings>, "FSharpOptions")>]
Expand All @@ -46,7 +47,10 @@ type FSharpOptions =
mutable EnableOutOfScopeCompletion: bool

[<SettingsEntry(true, topLevelOpenCompletion); DefaultValue>]
mutable TopLevelOpenCompletion: bool }
mutable TopLevelOpenCompletion: bool

[<SettingsEntry(false, useTransparentCompilerDescription)>]
mutable UseTransparentCompiler: bool }

type FantomasLocationSettings =
| AutoDetected = 0
Expand Down Expand Up @@ -155,6 +159,9 @@ type FSharpOptionsProvider(lifetime, solution, settings, settingsSchema) =
member val NonFSharpProjectInMemoryReferences =
base.GetValueProperty<bool>("NonFSharpProjectInMemoryReferences").Value with get, set

member val UseTransparentCompiler =
base.GetValueProperty<bool>("UseTransparentCompiler").Value

member this.UpdateAssemblyReaderSetting() =
this.NonFSharpProjectInMemoryReferences <-
base.GetValueProperty<bool>("NonFSharpProjectInMemoryReferences").Value
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,6 @@

<ItemGroup>
<PackageReference Include="FSharp.Core" />
<PackageReference Include="JetBrains.FSharp.Compiler.Service" />
<PackageReference Include="JetBrains.Annotations" />
<PackageReference Include="JetBrains.Lifetimes" />
</ItemGroup>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -83,7 +83,6 @@
<ItemGroup>
<PackageReference Include="FSharp.Core" />
<PackageReference Include="JetBrains.Annotations" />
<PackageReference Include="JetBrains.FSharp.Compiler.Service" />
<PackageReference Include="JetBrains.Lifetimes" />
<PackageReference Include="JetBrains.RdFramework" />
</ItemGroup>
Expand All @@ -92,4 +91,4 @@
<Import Project="ManagedProject.Generated.Targets" Condition="$(InternalBuild)" />
<Import Project="Sdk.targets" Sdk="JetBrains.NET.Sdk" Version="0.0.4" Condition="$(InternalBuild)" />
<Import Project="Sdk.targets" Sdk="Microsoft.NET.Sdk" Condition="!$(InternalBuild)" />
</Project>
</Project>
Original file line number Diff line number Diff line change
Expand Up @@ -124,7 +124,6 @@
<ItemGroup>
<PackageReference Include="FSharp.Core" />
<PackageReference Include="JetBrains.Annotations" />
<PackageReference Include="JetBrains.FSharp.Compiler.Service" />
<PackageReference Include="JetBrains.Lifetimes" />
<PackageReference Include="JetBrains.NuGet.Packaging" />
<PackageReference Include="JetBrains.NuGet.Versioning" />
Expand Down Expand Up @@ -165,4 +164,4 @@
<Import Project="ManagedProject.Generated.Targets" Condition="$(InternalBuild)" />
<Import Project="Sdk.targets" Sdk="JetBrains.NET.Sdk" Version="0.0.4" Condition="$(InternalBuild)" />
<Import Project="Sdk.targets" Sdk="Microsoft.NET.Sdk" Condition="!$(InternalBuild)" />
</Project>
</Project>
Original file line number Diff line number Diff line change
Expand Up @@ -142,7 +142,6 @@
</ItemGroup>
<ItemGroup>
<PackageReference Include="FSharp.Core" />
<PackageReference Include="JetBrains.FSharp.Compiler.Service" />
<PackageReference Include="JetBrains.Lifetimes" />
</ItemGroup>
<Import Project="$(RiderBackendSubplatform)" Condition="Exists('$(RiderBackendSubplatform)')" />
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -88,7 +88,6 @@
<ItemGroup>
<PackageReference Include="FSharp.Core" />
<PackageReference Include="JetBrains.Annotations" />
<PackageReference Include="JetBrains.FSharp.Compiler.Service" />
<PackageReference Include="JetBrains.Lifetimes" />
<PackageReference Include="JetBrains.RdFramework" />
</ItemGroup>
Expand All @@ -97,4 +96,4 @@
<Import Project="ManagedProject.Generated.Targets" Condition="$(InternalBuild)" />
<Import Project="Sdk.targets" Sdk="JetBrains.NET.Sdk" Version="0.0.4" Condition="$(InternalBuild)" />
<Import Project="Sdk.targets" Sdk="Microsoft.NET.Sdk" Condition="!$(InternalBuild)" />
</Project>
</Project>
3 changes: 1 addition & 2 deletions ReSharper.FSharp/src/FSharp/FSharp.Psi/FSharp.Psi.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,6 @@
<ItemGroup>
<PackageReference Include="FSharp.Core" />
<PackageReference Include="JetBrains.Annotations" />
<PackageReference Include="JetBrains.FSharp.Compiler.Service" />
<PackageReference Include="JetBrains.Lifetimes" />
<PackageReference Include="System.Collections.Immutable" />
<PackageReference Include="System.Runtime.CompilerServices.Unsafe" />
Expand All @@ -51,4 +50,4 @@
<Import Project="ManagedProject.Generated.Targets" Condition="$(InternalBuild)" />
<Import Project="Sdk.targets" Sdk="JetBrains.Toolset.MainSolution.Sdk" Version="20200625.1.1.2" Condition="$(InternalBuild)" />
<Import Project="Sdk.targets" Sdk="Microsoft.NET.Sdk" Condition="!$(InternalBuild)" />
</Project>
</Project>
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,6 @@

<ItemGroup>
<PackageReference Include="FSharp.Core" />
<PackageReference Include="JetBrains.FSharp.Compiler.Service" />
<PackageReference Include="JetBrains.Lifetimes" />
<PackageReference Include="JetBrains.RdFramework" />
</ItemGroup>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,6 @@
<ItemGroup>
<PackageReference Include="FSharp.Core" />
<PackageReference Include="JetBrains.Annotations" />
<PackageReference Include="JetBrains.FSharp.Compiler.Service" />
<PackageReference Include="JetBrains.Lifetimes" />
<PackageReference Include="JetBrains.NuGet.Versioning" />
<PackageReference Include="JetBrains.RdFramework" />
Expand Down
Loading