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

Fix solution reload and config change issues #3025

Merged
merged 20 commits into from
May 16, 2017
Merged

Fix solution reload and config change issues #3025

merged 20 commits into from
May 16, 2017

Conversation

dsyme
Copy link
Contributor

@dsyme dsyme commented May 11, 2017

This fixes a bunch of bad regressions around solution reload and "change configuration" actions

The problems were:

  • we were caching the project options in LanguageService.fs but not invalidating the cache when a project was updated
  • we were caching colorization information but not making that conditional on the defines active for a colorization
  • we were not noticing "global" updates to project configuration affecting all projects, so getting situations where configurations were mixed between projects

Testing:

  • I've added a project under tests\projects\misc for manually checking behaviour when switching configs or making other changes to a project

  • I've checked the following load

    devenv tests\projects\stress\big\dense\Dense.sln
    devenv tests\projects\stress\huge\dense\Dense.sln
    devenv tests\projects\stress\big\shallow\Shallow.sln

Notes on testing:

  • The unit testing for much of this "the project is changed in Visual Studio" area has effectively been disabled since the Roslynization of the codebase, which we're certainly discovered by having lots of bugs in this area. We will somehow have to rewrite or rejig unit tests. For example, this unit test is in theory "active" but it still tests only the unit-testable slice of the old FSharp.LanguageService.dll instead of FSharp.Editor.dll. This means that it test how FSharp.LanguageService.dll is listening in and reacting to events from VS and FSharp.ProjectSystem.dll. It doesn't test any of the code in FSharpEditor...\LanguageService.fs
  • We should probably accept this PR and any other fixes to regressions before enabling the unit tests, but should activate the unit tests (somehow - it's really not easy!) before adding significant complexity to FSharp.Editor. It would be great if we could activate the unit tests before replacing the F# Project System but maybe that's just going to make them all obsolete in any case....

@saul @vasily-kirichenko and others - I'd be grateful if you could try this out and validate that it fixes the bugs I've marked. Also check for loss of performance - we get a lot of "Project has updated" signals so have to recompute a lot of flags.

@@ -13,7 +13,7 @@ type internal ValueStrength<'T when 'T : not struct> =
| Weak of WeakReference<'T>
#endif

type internal AgedLookup<'Token, 'Key, 'Value when 'Value : not struct>(keepStrongly:int, areSame, ?requiredToKeep, ?onStrongDiscard, ?keepMax: int) =
type internal AgedLookup<'Token, 'Key, 'Value when 'Value : not struct>(keepStrongly:int, areSimilar, ?requiredToKeep, ?onStrongDiscard, ?keepMax: int) =
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is just renaming arguments for consistency

@@ -2589,31 +2589,37 @@ type BackgroundCompiler(referenceResolver, projectCacheSize, keepAssemblyContent
})

member bc.InvalidateConfiguration(options : FSharpProjectOptions) =
// This operation can't currently be cancelled nor awaited
Copy link
Contributor Author

@dsyme dsyme May 11, 2017

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Invalidate configuration is adjusted to explicitly invalidate any similar background build, i.e. one with same project file. THis is used when switching configurations

@@ -401,7 +410,7 @@ type internal FSharpChecker =
/// can be used to marginally increase accuracy of intellisense results in some situations.
/// </param>
///
member CheckFileInProjectIfReady : parsed: FSharpParseFileResults * filename: string * fileversion: int * source: string * options: FSharpProjectOptions * ?textSnapshotInfo: obj -> Async<FSharpCheckFileAnswer option>
member CheckFileInProjectAllowingStaleCachedResults : parsed: FSharpParseFileResults * filename: string * fileversion: int * source: string * options: FSharpProjectOptions * ?textSnapshotInfo: obj -> Async<FSharpCheckFileAnswer option>
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

renaming

@@ -64,6 +64,8 @@ type internal FSharpCheckerProvider

member this.Checker = checker.Value

type Refreshable<'T> = 'T * (unit -> 'T)
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The idea here is that we have a function to recalc the options when we need to, But we also can deliver the latest copy of the options to other callers

@@ -267,7 +268,7 @@ module internal Tokenizer =
data.[i] <- None
i <- i + 1

let private dataCache = ConditionalWeakTable<DocumentId, SourceTextData>()
let private dataCache = ConditionalWeakTable<DocumentId, ConcurrentDictionary<string list, SourceTextData>>()
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is a fix to colorization - when switching configurations, colorization information was not updated, e.g. #if DEBUG sections.

@vasily-kirichenko
Copy link
Contributor

vasily-kirichenko commented May 11, 2017

  1. Load VFT solution
  2. Change the solution file outside VS
  3. Reload the solution
  4. Everything works, coloring reappear much quicker than the first time
  5. The following assertion raised (it seems to be unrelated to this PR though)
---------------------------
Assertion Failed: Abort=Quit, Retry=Debug, Ignore=Continue
---------------------------
IncrementalBuild object has already been disposed!

   at Microsoft.FSharp.Compiler.IncrementalBuilder.assertNotDisposed()
   at Microsoft.FSharp.Compiler.IncrementalBuilder.DecrementUsageCount()
   at <StartupCode$FSharp-LanguageService-Compiler>.$Service.-ctor@2157-123.Invoke(Tuple`3 tupledArg)
   at Internal.Utilities.Collections.AgedLookup`3.strongDiscard(Value x)
   at <StartupCode$FSharp-LanguageService-Compiler>.$InternalCollections.clo@110-9.Invoke(Value x)
   at Microsoft.FSharp.Primitives.Basics.List.iter[T](FSharpFunc`2 f, FSharpList`1 x)
   at Microsoft.FSharp.Collections.ListModule.Iterate[T](FSharpFunc`2 action, FSharpList`1 list)
   at Internal.Utilities.Collections.AgedLookup`3.AssignWithStrength[d,e](d tok, FSharpList`1 newdata, FSharpList`1 discard1)
   at <StartupCode$FSharp-LanguageService-Compiler>.$Service.clo@2166-424.Invoke(Tuple`3 _arg3)
   at Microsoft.FSharp.Compiler.AbstractIL.Internal.Library.CancellableModule.bind@744.Invoke(CancellationToken ct)
   at Microsoft.FS......
<truncated>
---------------------------
Abort   Retry   Ignore   
---------------------------

And this

image

And this

image

Again and again

1

@dsyme
Copy link
Contributor Author

dsyme commented May 11, 2017

This is ready (once green)

@dsyme
Copy link
Contributor Author

dsyme commented May 11, 2017

@vasily-kirichenko If you could give it another go that would be great.

@dsyme
Copy link
Contributor Author

dsyme commented May 13, 2017

@vasily-kirichenko @KevinRansom @brettfo @saul and others - could I request a code review on this please? Thanks

@@ -44,21 +44,30 @@ namespace Internal.Utilities.Collections
new : keepStrongly:int
* areSame:('Key * 'Key -> bool)
* ?isStillValid:('Key * 'Value -> bool)
* ?areSameForSubsumption:('Key * 'Key -> bool)
* ?areSimilar:('Key * 'Key -> bool)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

A XML Doc comment would be great here explaining what "similarity" means here and what it will be used for.

projectTable.TryRemove(projectId) |> ignore
member this.RefreshInfoForProjectsThatReferenceThisProject(projectId: ProjectId) =
// Search the projectTable for things to refresh
for KeyValue(otherProjectId, ((referencedProjectIds, _options), refresh)) in projectTable.ToArray() do
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm just curious, why ToArray here?

@vasily-kirichenko
Copy link
Contributor

@dsyme If you could give it another go that would be great.

Same endless assertions.

@majocha
Copy link
Contributor

majocha commented May 13, 2017

I can confirm the 3 issues fixed.
When switching branches in VisualFSharp I got lots of identical:
[Failure] Could not find file 'C:\Users\Kuba\AppData\Local\Temp\.NETFramework,Version=v4.5.AssemblyAttributes.cs'.
But I think I've seen those before.

fslibRoot (* , sprintf "v%d.%d" v1 v2 *)
with e ->
error(Error(FSComp.SR.buildErrorOpeningBinaryFile(filename, e.Message), rangeStartup))
if (* validate && *) fslibReference.ProjectReference.IsNone then
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why validate commented?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I've removed the commented out text now. It turns out this must be being called by fsc.exe with validate=false, so the error message sequence was being changed by checking this, but that is a separate issue

@@ -64,6 +65,8 @@ type internal FSharpCheckerProvider

member this.Checker = checker.Value

type Refreshable<'T> = 'T * (bool -> 'T)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

XML doc comment here?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

thanks

let ok,originalOptions = optionsAssociation.TryGetValue(projectContext)
let updatedOptions = site.CompilerFlags()
if not ok || originalOptions <> updatedOptions then
let updatedFiles = site.SourceFilesOnDisk() |> wellFormedFilePathSetIgnoreCase
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Shadowing the exact same above

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks, good catch, fixed

|> Seq.toArray
static let rec referencedProjectsOf (tryGetOptionsForReferencedProject, projectSite:IProjectSite, extraProjectInfo, serviceProvider:System.IServiceProvider, useUniqueStamp) =
[| for (p,ps) in referencedProvideProjectSites (projectSite, serviceProvider) do
match fullOutputAssemblyPath p with
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

is the indentation off by one here?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

thanks

// We wait until allproject configurations have been updated before updating our MSBuild state
projNode.UpdateMSBuildState()
projNode.SetProjectFileDirty(projNode.IsProjectFileDirty)
projNode.ComputeSourcesAndFlags()
Copy link
Contributor

@saul saul May 14, 2017

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

When is UpdateProjectCfg_Done called when OnAfterActiveSolutionCfgChange and OnActiveProjectCfgChangeBatchEnd isn't? Are we definitely only calling ComputeSourcesAndFlags once per project on configuration change? Also is the wait dialog still open when we call ComputeSourcesAndFlags here (is this method called before OnAfterActiveSolutionCfgChange)?

I'm worried we've just tripled configuration change/solution load time by calling ComputeSourcesAndFlags so many times.

Copy link
Contributor Author

@dsyme dsyme May 15, 2017

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Here's what I see for the set of events triggered when loading tests\projects\misc\TestProjectChanges.sln. Looking at this,

  • I believe you are right that we are doing ComputeSourcesAndFlags twice per project on solution load. But suspect we were doing that before, and it is because we are getting two complete sets of OnActiveProjectCfgChangeBatchBegin/ OnActiveProjectCfgChangeBatchEnd events sent through.

  • The cost of ComputeSourcesAndFlags has been much reduced since use graph of option objects - fix 2793 #3002 since it uses the stored computed options for referenced projects

  • It is important not to do any ComputeSourcesAndFlags until we have updated the configuration on all the projects. So I think we have to do this in OnActiveProjectCfgChangeBatchEnd.

Loading tests\projects\misc\TestProjectChanges.sln

  • OnActiveProjectCfgChangeBatchBegin x 3
  • IVsUpdateSolutionEvents.OnActiveProjectCfgChange(null) x 3
  • IVsUpdateSolutionEvents.OnActiveProjectCfgChange(not-null) x 6
  • OnActiveProjectCfgChangeBatchEnd x 3

Then we get a "duplicate" set of Batch events

  • OnActiveProjectCfgChangeBatchBegin x 3
  • OnActiveProjectCfgChangeBatchEnd x 3

Then something else forces ComputeSourcesAndFlags on each project

Switching to "Release"

  • OnBeforeActiveSolutionCfgChange x 3
  • OnActiveProjectCfgChangeBatchBegin x 3
  • IVsUpdateSolutionEvents.OnActiveProjectCfgChange(null) x 3
  • IVsUpdateSolutionEvents.OnActiveProjectCfgChange(not-null) x 6
  • OnActiveProjectCfgChangeBatchEnd x 3
  • OnAfterActiveSolutionCfgChange x 3 ComputeSourcesAndFlags

On prompted solution reload after a project file has been edited

  • OnActiveProjectCfgChangeBatchBegin x 3
  • IVsUpdateSolutionEvents.OnActiveProjectCfgChange(null) x 3
  • IVsUpdateSolutionEvents.OnActiveProjectCfgChange(not-null) x 6
  • OnActiveProjectCfgChangeBatchEnd x 3

Then we get a "duplicate" set of Batch events

  • OnActiveProjectCfgChangeBatchBegin x 3
  • OnActiveProjectCfgChangeBatchEnd x 3

Then something else forces ComputeSourcesAndFlags on each project

On individual project reload

  • OnActiveProjectCfgChange

Also I never see these being called in the scenarios I've tested - if you know a sequence that triggers them please let me know :)

  • IVsUpdateSolutionEvents2.OnActiveProjectCfgChange
  • IVsUpdateSolutionEvents2.UpdateProjectCfg_Begin
  • IVsUpdateSolutionEvents2.UpdateProjectCfg_Done

Copy link
Contributor

@saul saul left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I've just had a read through and I'm a bit concerned that we're now calling ComputeSourcesAndFlags 3 times when we change solution configuration and on solution load - that operational is painfully slow. Can you check that we're only calling it once in these scenarios?

@dsyme
Copy link
Contributor Author

dsyme commented May 15, 2017

@saul Thanks for the review! I'll go through the items now

@dsyme
Copy link
Contributor Author

dsyme commented May 15, 2017

@Saull Could you check the last two commits? I've updated to only call ComputeSourcesAndFlags in OnAfterActiveSolutionCfgChange and this seems to have the desired effect of only doing the operation once on load, reload and configuration update. On load and reload other operations end up forcing ComputeSourcesAndFlags

After this change I don't see any value in the batchState tracking.

I must say this logic is a right mess. I can't wait to ditch the whole project system and replace it with the Roslyn one

@dsyme
Copy link
Contributor Author

dsyme commented May 15, 2017

@saul OK, I think this is ready

@vasily-kirichenko I believe the assertion is a different problem - we've certainly seen it before - I've been able to repro it sometimes but not consistently.

@dsyme
Copy link
Contributor Author

dsyme commented May 15, 2017

When switching branches in VisualFSharp I got lots of identical: [Failure] Could not find file 'C:\Users\Kuba\AppData\Local\Temp.NETFramework,Version=v4.5.AssemblyAttributes.cs'.

I've not seen this before, I'm confident it's a separate problem but it would be good to address it

Copy link
Contributor

@saul saul left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm not entirely convinced by the ComputeSourcesAndFlags changes in the solution configuration event code in Project.fs - it looks like we're calling ComputeSourcesAndFlags the same number of times now in the same scenarios. What's actually been fixed here?

The batchState tracking ensured that for each batch, we only called ComputeSourcesAndFlags for each project once. Also out of interest why is UpdateMSBuildState necessary before we call ComputeSourcesAndFlags? It may be worth commenting the reason.

// By default, the F# project system keeps its own internal Configuration and Platform in sync with the current active
// Configuration and Platform by listening for OnActiveProjectCfgChange events. However there is one case where the
// active cfg changes without an event, and this is during 'Batch Build'. So we listen for the start and end of
// Batch Build, and manually update the project to the active cfg before/after to set/reset the config.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why has this comment been removed? Is this no longer the case? Your other comment didn't lead me to believe that you tried doing a batch build.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

See comment below.


VSConstants.S_OK

member x.OnAfterActiveSolutionCfgChange(_oldCfg, _newCfg) =

// We have updated the MSBuild state of each project. Now we can call ComputeSourcesAndFlags
projNode.ComputeSourcesAndFlags()
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why are we doing this here? This means that the progress dialog is going to close way before all of the ComputeSourcesAndFlags are complete.

We should reference count how many times waitDialog was (going to be) opened, and then only dispose of it when it reaches 0.

member x.OnActiveProjectCfgChangeBatchEnd() =
batchState <- NonBatch
projNode.UpdateMSBuildState()
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Any comments as to why this is now necessary? Why at this stage and not at OnActiveProjectCfgChange?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

All good questions. TBH I just fiddled around for about 3 days (yes really) until it seemed to work in every scenario I tried it in. Almost every other variation seemed to fail in some way or another.

I didn't however try a batch build. I had misunderstood what that actually was, sorry.

You are correct that the dialog goes away early though another "computing sources and flags for project" replaces it.

I'll see if I can find a less invasive set of changes. Perhaps there is just one fix needed in this code after all.

if GetCaption(pHierProj) = GetCaption(projNode.InteropSafeIVsHierarchy) then
// This code matches what ProjectNode.SetConfiguration would do; that method cannot be called during a build, but at this
// current moment in time, it is 'safe' to do this update.
let _,currentConfigName = Utilities.TryGetActiveConfigurationAndPlatform(projNode.Site, projNode.ProjectIDGuid)
MSBuildProject.SetGlobalProperty(projNode.BuildProject, ProjectFileConstants.Configuration, currentConfigName.ConfigName)
MSBuildProject.SetGlobalProperty(projNode.BuildProject, ProjectFileConstants.Platform, currentConfigName.MSBuildPlatform)
projNode.UpdateMSBuildState()
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why was this removed?

@dsyme
Copy link
Contributor Author

dsyme commented May 15, 2017

@KevinRansom This is not yet ready to go in (at least until @saul approves :))

@dsyme
Copy link
Contributor Author

dsyme commented May 15, 2017

A record of the events raised on various project actions:

Loading tests\projects\misc\TestProjectChanges.sln

  • OnActiveProjectCfgChangeBatchBegin x 3
  • IVsUpdateSolutionEvents.OnActiveProjectCfgChange(null) x 3
  • IVsUpdateSolutionEvents.OnActiveProjectCfgChange(not-null) x 6
  • OnActiveProjectCfgChangeBatchEnd x 3

Then we get a "duplicate" set of Batch events

  • OnActiveProjectCfgChangeBatchBegin x 3
  • OnActiveProjectCfgChangeBatchEnd x 3

Then something else forces ComputeSourcesAndFlags on each project

Switching to "Release"

  • OnBeforeActiveSolutionCfgChange x 3
  • OnActiveProjectCfgChangeBatchBegin x 3
  • IVsUpdateSolutionEvents.OnActiveProjectCfgChange(null) x 3
  • IVsUpdateSolutionEvents.OnActiveProjectCfgChange(not-null) x 6
  • OnActiveProjectCfgChangeBatchEnd x 3
  • OnAfterActiveSolutionCfgChange x 3 ComputeSourcesAndFlags

On prompted solution reload after a project file has been edited

  • OnActiveProjectCfgChangeBatchBegin x 3
  • IVsUpdateSolutionEvents.OnActiveProjectCfgChange(null) x 3
  • IVsUpdateSolutionEvents.OnActiveProjectCfgChange(not-null) x 6
  • OnActiveProjectCfgChangeBatchEnd x 3

Then we get a "duplicate" set of Batch events

  • OnActiveProjectCfgChangeBatchBegin x 3
  • OnActiveProjectCfgChangeBatchEnd x 3

Then something else forces ComputeSourcesAndFlags on each project

On individual project reload

  • OnActiveProjectCfgChange

On batch build:

  • UpdateProjectCfg_Begin x 6 (twice for each project!)
  • UpdateProjectCfg_Done x 6 (twice for each project!)

I never see this being called in the scenarios I've tested

  • IVsUpdateSolutionEvents2.OnActiveProjectCfgChange

@dsyme
Copy link
Contributor Author

dsyme commented May 15, 2017

@saul Here are my further investigations

  • First, I have adjusted the code to keep a count for the dialog

  • Second, I have tested "Batch Build". This functions correctly

  • Third, I've put the batchState value back in. This actually has nothing to do with batch builds - the OnActiveProjectCfgChangeBatchBegin doesn't get invoked for batch build and I really do think the old comments were just misled (a lot of this code is awful - we should never have copied the original C# VS sample from whence all this stems - and I can't wait to get rid of it with the new project system). I've added an assert that batchState is always NonBatch by the time we get to OnAfterActiveSolutionCfgChange

  • Fourth, I tried to move ComputeSourcesAndFlags back to OnActiveProjectCfgChangeBatchEnd. The problem with moving it there or any earlier is that it seems the MSBuild state of the project is out of sync, and we get invalid mixes of Debug and Release references in project options, This is the primary problem I've been fighting and which TestProjectChanges helps test (maually). I've tried hard to work out why this happens, and whether it is a regression or an existing bug, but it's just too hard for me. So I've kept ComputeSourcesAndFlags in OnAfterActiveSolutionCfgChange and made sure the dialog stays up.

So in short we should have the same number of ComputeSourcesAndFlags calls - 1 per project - but they just come later in the event sequence, when all projects have had their MSBuild state updated and the project options drop out correctly. Any other ordering just doesn't seem to work for me.

Manual testing:

tests\proejcts\misc\TestProjectChanges\TestProjectChanges.sln

  • Change to/from Debug/Release config and watch the intellisense/coloring update. No errors should appear
  • Build in each configuration
  • File --> Close Solution
  • File --> Open Solution
  • File --> Close Solution
  • Do a batch build over all configurations (except Lib2=Release which makes no sense for this)
  • Do a batch build "clean" over all configurations (except Lib2=Release which makes no sense for this)
  • Do a batch rebuild over all configurations (except Lib2=Release which makes no sense for this)

VisualFSharp.sln

  • Open in Debug, do a build, check #if DEBUG is active
  • Switch to Release do a build, check #if DEBUG is NOT active
  • File --> Close Solution
  • File --> Open Solution
  • File --> Close Solution

I think this is the best I can do. Though I'll try again if you ask me :)

Copy link
Contributor

@saul saul left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for investigating this @dsyme, just looked over your latest changes and my mind is at ease 😄 This looks a lot better.

@dsyme
Copy link
Contributor Author

dsyme commented May 15, 2017

@saul The thanks is to you for reviewing so carefully. It's about the most important thing we can do.

@dsyme
Copy link
Contributor Author

dsyme commented May 15, 2017

@KevinRansom this is ready to merge (unless you wish to add additional reviews)

@dsyme dsyme merged commit 722a64a into dotnet:master May 16, 2017
nosami pushed a commit to xamarin/visualfsharp that referenced this pull request Jan 26, 2022
* fix config change

* Fix configuration changes

* Fix colorization cache for changing defines

* fix config switching

* add manual test cases

* Fix test

* minor nit

* use correct reference count

* cleanup decrement logic

* fix build

* Update CompileOps.fs

* adjust unit tests mocks

* adjust unit tests mocks

* fix test

* add new misc project test

* do ComputeSourcesAndFlags later

* do ComputeSourcesAndFlags once

* variations

* keep dialog open
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

5 participants