Skip to content

Commit d9262c2

Browse files
committed
Adding new roaming location to prevent syncing the new serialization format into an older version
1 parent 3f00166 commit d9262c2

3 files changed

Lines changed: 35 additions & 10 deletions

File tree

src/VisualStudio/Core/Def/Implementation/Options/RoamingVisualStudioProfileOptionPersister.cs

Lines changed: 29 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -80,6 +80,31 @@ private System.Threading.Tasks.Task OnSettingChangedAsync(object sender, Propert
8080
return SpecializedTasks.EmptyTask;
8181
}
8282

83+
private object GetFirstOrDefaultValue(OptionKey optionKey, IEnumerable<RoamingProfileStorageLocation> roamingSerializations)
84+
{
85+
// There can be more than 1 roaming location in the order of their priority.
86+
// When fetching a value, we iterate all of them until we find the first one that exists.
87+
// When persisting a value, we always use the first location.
88+
// This functionality exists for breaking changes to persistence of some options. In such a case, there
89+
// will be a new location added to the beginning with a new name. When fetching a value, we might find the old
90+
// location (and can upgrade the value accordingly) but we only write to the new location so that
91+
// we don't interfere with older versions. This will essentially "fork" the user's options at the time of upgrade.
92+
93+
foreach (var roamingSerialization in roamingSerializations)
94+
{
95+
var storageKey = roamingSerialization.GetKeyNameForLanguage(optionKey.Language);
96+
97+
RecordObservedValueToWatchForChanges(optionKey, storageKey);
98+
99+
if (_settingManager.TryGetValue(storageKey, out object value) == GetValueResult.Success)
100+
{
101+
return value;
102+
}
103+
}
104+
105+
return optionKey.Option.DefaultValue;
106+
}
107+
83108
public bool TryFetch(OptionKey optionKey, out object value)
84109
{
85110
if (_settingManager == null)
@@ -90,19 +115,15 @@ public bool TryFetch(OptionKey optionKey, out object value)
90115
}
91116

92117
// Do we roam this at all?
93-
var roamingSerialization = optionKey.Option.StorageLocations.OfType<RoamingProfileStorageLocation>().SingleOrDefault();
118+
var roamingSerializations = optionKey.Option.StorageLocations.OfType<RoamingProfileStorageLocation>();
94119

95-
if (roamingSerialization == null)
120+
if (!roamingSerializations.Any())
96121
{
97122
value = null;
98123
return false;
99124
}
100125

101-
var storageKey = roamingSerialization.GetKeyNameForLanguage(optionKey.Language);
102-
103-
RecordObservedValueToWatchForChanges(optionKey, storageKey);
104-
105-
value = _settingManager.GetValueOrDefault(storageKey, optionKey.Option.DefaultValue);
126+
value = GetFirstOrDefaultValue(optionKey, roamingSerializations);
106127

107128
// VS's ISettingsManager has some quirks around storing enums. Specifically,
108129
// it *can* persist and retrieve enums, but only if you properly call
@@ -222,7 +243,7 @@ public bool TryPersist(OptionKey optionKey, object value)
222243
}
223244

224245
// Do we roam this at all?
225-
var roamingSerialization = optionKey.Option.StorageLocations.OfType<RoamingProfileStorageLocation>().SingleOrDefault();
246+
var roamingSerialization = optionKey.Option.StorageLocations.OfType<RoamingProfileStorageLocation>().FirstOrDefault();
226247

227248
if (roamingSerialization == null)
228249
{

src/Workspaces/Core/Portable/NamingStyles/Serialization/NamingStylePreferences.cs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -349,6 +349,8 @@ private static XElement GetUpgradedSerializationIfNecessary(XElement rootElement
349349

350350
// Add future version checks here. If the version is off by more than 1, these upgrades will run in sequence.
351351
// The next one should check serializationVersion == 5 and update it to 6.
352+
// It is also important to create a new roaming location in SimplificationOptions.NamingPreferences
353+
// so that we never store the new format in an older version.
352354
Debug.Assert(s_serializationVersion == 5, "After increasing the serialization version, add an upgrade path here.");
353355

354356
return serializationVersion == s_serializationVersion

src/Workspaces/Core/Portable/Simplification/SimplificationOptions.cs

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -101,8 +101,10 @@ public static class SimplificationOptions
101101
/// and the level to which those rules should be enforced.
102102
/// </summary>
103103
internal static PerLanguageOption<NamingStylePreferences> NamingPreferences { get; } = new PerLanguageOption<NamingStylePreferences>(nameof(SimplificationOptions), nameof(NamingPreferences), defaultValue: NamingStylePreferences.Default,
104-
storageLocations: new OptionStorageLocation[]{
104+
storageLocations: new OptionStorageLocation[] {
105105
new NamingStylePreferenceEditorConfigStorageLocation(),
106-
new RoamingProfileStorageLocation("TextEditor.%LANGUAGE%.Specific.NamingPreferences")});
106+
new RoamingProfileStorageLocation("TextEditor.%LANGUAGE%.Specific.NamingPreferences[5]"),
107+
new RoamingProfileStorageLocation("TextEditor.%LANGUAGE%.Specific.NamingPreferences")
108+
});
107109
}
108110
}

0 commit comments

Comments
 (0)