-
Notifications
You must be signed in to change notification settings - Fork 789
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
Using ProjectTracker
instead of CurrentSolution
#5391
Conversation
…oesn't open a F# document by default
@Pilchie does this look good to you? |
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.
Presumably this regressed as part of #5284? Why didn't we catch it as part of validation of that change, or in the 3 weeks since with our own dogfooding?
@@ -118,7 +119,8 @@ type internal FSharpProjectOptionsManager | |||
( | |||
checkerProvider: FSharpCheckerProvider, | |||
[<Import(typeof<VisualStudioWorkspace>)>] workspace: VisualStudioWorkspaceImpl, | |||
[<Import(typeof<SVsServiceProvider>)>] serviceProvider: System.IServiceProvider | |||
[<Import(typeof<SVsServiceProvider>)>] serviceProvider: System.IServiceProvider, | |||
[<Import(typeof<ISettings>)>] _settings: ISettings // This is necessary so that the Settings global doesn't explode. |
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.
It's not clear how this is related to the rest of the change.
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.
It's a bit complicated. We have a Settings
type that relies on the implementation of ISettings
s' constructor to be called. We import it here to force the constructor to be called at this point. Unfortunately we do a similar thing already in the FSharpPackage
's Initialize
method, but since Initialize
hasn't been called yet until a document has been opened, we have to do this in order for it to work.
This is absolutely not ideal and a horrific pattern. We need to re-design how all of this flows through our language service.
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.
If FSharpPackage
hasn't been initialized, I expect lots of horrible things to happen. I would look into fixing that first.
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.
@Pilchie, the updateprojectinfo relies on access to the F# VS Settings. This causes them to be initialized when the CommandLineOptionsEvent arrived. The CommandLine options event may fire before the package is fully initialized.
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.
The CommandLine options event may fire before the package is fully initialized.
We should fix that.
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.
That's unlikely to be feasible any time soon, since the commandline arguments types are strongly connected to the C#/VB types, and include compiler concepts that don't apply to F#.
Regardless, it wouldn't help this initialization piece. In the short term though, I'm not sure why we couldn't call IVsShell::LoadPackage
(or QueryService
for a service profferred from the language service) from the project system to ensure the language service is initialized before we start using it.
It's historically been very hard to reason about VS packages that might get loaded by MEF but not have Initialize
called on them. If that's happening in F#, my guess is that this is far from the only bug that happens as a result, and it would be better to fix the underlying issue.
Can you look at how the C# Language Service package gets initialized in a similar codepath and explain why that doesn't happen for 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.
For a long-term solution, I really think we should explore what could possibly be done for the commandline arguments. @jasonmalinowski thinks we might be able to do this. We should all talk about this together.
The ISettings
initialization is perfectly fine to happen here; we just have a bad pattern where a global structure relies on its initialization. In a separate PR, we can remove the global structure and just use the ISettings
instance when we need it.
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.
Regardless if we use LoadPackage
or not, we should take this PR as using CurrentSolution
is not correct here anyways.
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.
After checking with @jasonmalinowski , calling IVsShell::LoadPackage
seems reasonable to do.
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.
I think I found where to do it: https://github.com/dotnet/roslyn/blob/0959f9d826116a47a6da267cd1420fc803568b28/src/VisualStudio/Core/Impl/ProjectSystem/CPS/CPSProjectFactory.cs#L122
Seems F# is not in that list. :)
Note for any OSS folks - this may also address a slough of issues related to the F# editor not getting the language service initialized. We'll have to go back and hunt down some of these bugs in the repo and verify if they are fixed/not fixed, but at the very least, this fixes the bug listed in the PR text. |
@Pilchie This didn't regress as part of this: #5284 , because the issue was reported using VS 15.7.3. I believe I know where this regressed. It regressed when we made the performance improvement for .net sdk projects, and we put it in 15.7.3. We did not have this issue in 15.6 for sure. Why it regressed and why we missed it is complicated. I will explain: Why it regressedBefore the perf fix, every time we opened a document, we would update project information. With the perf fix, we stopped doing that as it was a perf problem. This seemed perfectly reasonable to do because However, there was something that slipped through the cracks. The reason it worked before is because we would update project information when a document opened and calling Why we missed itThere are a few reasons why we didn't encounter this earlier:
ConclusionThis is a specific case for this issue to occur: A solution has to already exist with a F# project and no F# documents are opened automatically when you load the solution from a newly instanced VS. The fix here is to not use |
Even after the fix in 15.7.3, until the PR I mentioned above, we used |
Are you referring to this line? https://github.com/Microsoft/visualfsharp/pull/5284/files#diff-588c38c5c54419143876d9c7ce941753L231 If you look below it it still uses I removed the |
@dotnet-bot test Ubuntu16.04 Release_default Build please |
@TIHan - I was referring to that line, missed the |
Seems the PR here: dotnet/roslyn#28901 will also resolve the issue of editor features not working. I still think we should merge this PR, only because we should be using |
ProjectTracker
instead of CurrentSolution
Closing this as per discussion with @jasonmalinowski , we should not be using |
This ensures the F# package is loaded for CPS only projects in a solution. Seems this was an oversight. Independent of dotnet/fsharp#5391, ensuring the F# package load fixes this issue: dotnet/fsharp#5395 - and it probably fixes other issues that we haven't discovered as a result of not loading the package.
Fixes the issue reported here: #5395
The fix is to use the
AbstractProject
type instead of the VSProject
type when creating aIProjectSite
. The reason why is because we can't rely onCurrentSolution
to give us aProject
by itsProjectId
. However, we can rely on theProjectTracker
to give us anAbstractProject
.