Beispiel #1
0
        private static NamingStylePreferences AsyncFunctionNamesEndWithAsyncOption()
        {
            var symbolSpecification = new SymbolSpecification(
                null,
                "Name",
                ImmutableArray.Create(
                    new SymbolSpecification.SymbolKindOrTypeKind(MethodKind.Ordinary),
                    new SymbolSpecification.SymbolKindOrTypeKind(MethodKind.LocalFunction)),
                ImmutableArray <Accessibility> .Empty,
                ImmutableArray.Create(new SymbolSpecification.ModifierKind(SymbolSpecification.ModifierKindEnum.IsAsync)));

            var namingStyle = new NamingStyle(
                Guid.NewGuid(),
                capitalizationScheme: Capitalization.PascalCase,
                name: "Name",
                prefix: "",
                suffix: "Async",
                wordSeparator: "");

            var namingRule = new SerializableNamingRule()
            {
                SymbolSpecificationID = symbolSpecification.ID,
                NamingStyleID         = namingStyle.ID,
                EnforcementLevel      = DiagnosticSeverity.Error
            };

            var info = new NamingStylePreferences(
                ImmutableArray.Create(symbolSpecification),
                ImmutableArray.Create(namingStyle),
                ImmutableArray.Create(namingRule));

            return(info);
        }
Beispiel #2
0
        private static NamingStylePreferences ConstantsAreUpperCaseOption()
        {
            var symbolSpecification = new SymbolSpecification(
                null,
                "Name",
                ImmutableArray.Create(
                    new SymbolSpecification.SymbolKindOrTypeKind(SymbolKind.Field),
                    new SymbolSpecification.SymbolKindOrTypeKind(SymbolKind.Local)),
                ImmutableArray <Accessibility> .Empty,
                ImmutableArray.Create(new SymbolSpecification.ModifierKind(SymbolSpecification.ModifierKindEnum.IsConst)));

            var namingStyle = new NamingStyle(
                Guid.NewGuid(),
                capitalizationScheme: Capitalization.AllUpper,
                name: "Name",
                prefix: "",
                suffix: "",
                wordSeparator: "");

            var namingRule = new SerializableNamingRule()
            {
                SymbolSpecificationID = symbolSpecification.ID,
                NamingStyleID         = namingStyle.ID,
                EnforcementLevel      = DiagnosticSeverity.Error
            };

            var info = new NamingStylePreferences(
                ImmutableArray.Create(symbolSpecification),
                ImmutableArray.Create(namingStyle),
                ImmutableArray.Create(namingRule));

            return(info);
        }
        public NamingStyleOptionPageViewModel(NamingStylePreferences info)
        {
            var viewModels = new List <NamingRuleViewModel>();

            foreach (var namingRule in info.NamingRules)
            {
                var viewModel = new NamingRuleViewModel()
                {
                    NamingStyles            = new ObservableCollection <MutableNamingStyle>(info.NamingStyles.Select(n => new MutableNamingStyle(n))),
                    Specifications          = new ObservableCollection <SymbolSpecification>(info.SymbolSpecifications),
                    NotificationPreferences = new List <NotificationOptionViewModel>(_notifications)
                };

                viewModel.SelectedSpecification          = viewModel.Specifications.Single(s => s.ID == namingRule.SymbolSpecificationID);
                viewModel.SelectedStyle                  = viewModel.NamingStyles.Single(s => s.ID == namingRule.NamingStyleID);
                viewModel.SelectedNotificationPreference = viewModel.NotificationPreferences.Single(n => n.Notification.Value == namingRule.EnforcementLevel);

                viewModels.Add(viewModel);
            }

            CodeStyleItems = new ObservableCollection <NamingRuleViewModel>(viewModels);
            Specifications = new ObservableCollection <SymbolSpecification>(info.SymbolSpecifications);
            NamingStyles   = new ObservableCollection <MutableNamingStyle>(info.NamingStyles.Select(n => new MutableNamingStyle(n)));

            SetMoveArrowStatuses();
        }
Beispiel #4
0
        private NamingStylePreferences MethodNamesArePascalCaseOption()
        {
            var symbolSpecification = new SymbolSpecification(
                "Name",
                SpecializedCollections.SingletonEnumerable(new SymbolSpecification.SymbolKindOrTypeKind(SymbolKind.Method)).ToList(),
                SpecializedCollections.EmptyList <Accessibility>(),
                SpecializedCollections.EmptyList <SymbolSpecification.ModifierKind>());

            var namingStyle = new NamingStyle()
            {
                CapitalizationScheme = Capitalization.PascalCase,
                Name          = "Name",
                Prefix        = "",
                Suffix        = "",
                WordSeparator = ""
            };
            var namingRule = new SerializableNamingRule()
            {
                SymbolSpecificationID = symbolSpecification.ID,
                NamingStyleID         = namingStyle.ID,
                EnforcementLevel      = DiagnosticSeverity.Error
            };
            var info = new NamingStylePreferences();

            info.SymbolSpecifications.Add(symbolSpecification);
            info.NamingStyles.Add(namingStyle);
            info.NamingRules.Add(namingRule);

            return(info);
        }
Beispiel #5
0
        private static ImmutableDictionary <Guid, string> AssignNamesToNamingStyleElements(
            NamingStylePreferences namingStylePreferences
            )
        {
            var symbolSpecificationNames = new HashSet <string>();
            var builder = ImmutableDictionary.CreateBuilder <Guid, string>();

            foreach (var symbolSpecification in namingStylePreferences.SymbolSpecifications)
            {
                var name = ToSnakeCaseName(symbolSpecification.Name);
                if (!symbolSpecificationNames.Add(name))
                {
                    name = symbolSpecification.ID.ToString("n");
                }

                builder.Add(symbolSpecification.ID, name);
            }

            var namingStyleNames = new HashSet <string>();

            foreach (var namingStyle in namingStylePreferences.NamingStyles)
            {
                var name = ToSnakeCaseName(namingStyle.Name);
                if (!namingStyleNames.Add(name))
                {
                    name = namingStyle.ID.ToString("n");
                }

                builder.Add(namingStyle.ID, name);
            }

            return(builder.ToImmutable());
Beispiel #6
0
        private NamingStylePreferences CreateCustomStaticFieldNamingStylePreference()
        {
            var symbolSpecification = new SymbolSpecification(
                null,
                "Name",
                ImmutableArray.Create(new SymbolKindOrTypeKind(SymbolKind.Field)),
                ImmutableArray <Accessibility> .Empty,
                ImmutableArray.Create(new ModifierKind(DeclarationModifiers.Static)));

            var namingStyle = new NamingStyle(
                Guid.NewGuid(),
                capitalizationScheme: Capitalization.PascalCase,
                name: "CustomStaticFieldTest",
                prefix: "staticfieldtest",
                suffix: "",
                wordSeparator: "");

            var namingRule = new SerializableNamingRule()
            {
                SymbolSpecificationID = symbolSpecification.ID,
                NamingStyleID         = namingStyle.ID,
                EnforcementLevel      = ReportDiagnostic.Error
            };

            var info = new NamingStylePreferences(
                ImmutableArray.Create(symbolSpecification),
                ImmutableArray.Create(namingStyle),
                ImmutableArray.Create(namingRule));

            return(info);
        }
Beispiel #7
0
        private NamingStylePreferences MethodNamesArePascalCaseOption()
        {
            var symbolSpecification = new SymbolSpecification(
                null,
                "Name",
                ImmutableArray.Create(new SymbolSpecification.SymbolKindOrTypeKind(SymbolKind.Method)),
                ImmutableArray <Accessibility> .Empty,
                ImmutableArray <SymbolSpecification.ModifierKind> .Empty);

            var namingStyle = new NamingStyle(
                Guid.NewGuid(),
                capitalizationScheme: Capitalization.PascalCase,
                name: "Name",
                prefix: "",
                suffix: "",
                wordSeparator: "");

            var namingRule = new SerializableNamingRule()
            {
                SymbolSpecificationID = symbolSpecification.ID,
                NamingStyleID         = namingStyle.ID,
                EnforcementLevel      = DiagnosticSeverity.Error
            };
            var info = new NamingStylePreferences(
                ImmutableArray.Create(symbolSpecification),
                ImmutableArray.Create(namingStyle),
                ImmutableArray.Create(namingRule));

            return(info);
        }
Beispiel #8
0
        private static string ReserializePreferences(string serializedPreferences)
        {
            var preferences = NamingStylePreferences.FromXElement(
                XElement.Parse(serializedPreferences)
                );

            return(preferences.CreateXElement().ToString());
        }
Beispiel #9
0
        public static NamingStylePreferences PrependNamingStylePreferences(this NamingStylePreferences original, NamingStylePreferences newPreferences)
        {
            var symbolSpecifications = original.SymbolSpecifications.InsertRange(0, newPreferences.SymbolSpecifications);
            var namingStyles         = original.NamingStyles.InsertRange(0, newPreferences.NamingStyles);
            var namingRules          = original.NamingRules.InsertRange(0, newPreferences.NamingRules);

            return(new NamingStylePreferences(symbolSpecifications, namingStyles, namingRules));
        }
 public static void AppendNamingStylePreferencesToEditorConfig(NamingStylePreferences namingStylePreferences, string language, StringBuilder editorconfig)
 {
     AppendNamingStylePreferencesToEditorConfig(
         namingStylePreferences.SymbolSpecifications,
         namingStylePreferences.NamingStyles,
         namingStylePreferences.NamingRules,
         language,
         editorconfig);
 }
Beispiel #11
0
        public static void AppendNamingStylePreferencesToEditorConfig(NamingStylePreferences namingStylePreferences, string language, StringBuilder editorconfig)
        {
            editorconfig.AppendLine($"#### {CompilerExtensionsResources.Naming_styles} ####");

            var serializedNameMap  = AssignNamesToNamingStyleElements(namingStylePreferences);
            var ruleNameMap        = AssignNamesToNamingStyleRules(namingStylePreferences, serializedNameMap);
            var referencedElements = new HashSet <Guid>();

            editorconfig.AppendLine();
            editorconfig.AppendLine($"# {CompilerExtensionsResources.Naming_rules}");

            foreach (var namingRule in namingStylePreferences.NamingRules)
            {
                referencedElements.Add(namingRule.SymbolSpecificationID);
                referencedElements.Add(namingRule.NamingStyleID);

                editorconfig.AppendLine();
                editorconfig.AppendLine($"dotnet_naming_rule.{ruleNameMap[namingRule]}.severity = {namingRule.EnforcementLevel.ToNotificationOption(defaultSeverity: DiagnosticSeverity.Hidden).ToEditorConfigString()}");
                editorconfig.AppendLine($"dotnet_naming_rule.{ruleNameMap[namingRule]}.symbols = {serializedNameMap[namingRule.SymbolSpecificationID]}");
                editorconfig.AppendLine($"dotnet_naming_rule.{ruleNameMap[namingRule]}.style = {serializedNameMap[namingRule.NamingStyleID]}");
            }

            editorconfig.AppendLine();
            editorconfig.AppendLine($"# {CompilerExtensionsResources.Symbol_specifications}");

            foreach (var symbolSpecification in namingStylePreferences.SymbolSpecifications)
            {
                if (!referencedElements.Contains(symbolSpecification.ID))
                {
                    continue;
                }

                editorconfig.AppendLine();
                editorconfig.AppendLine($"dotnet_naming_symbols.{serializedNameMap[symbolSpecification.ID]}.applicable_kinds = {symbolSpecification.ApplicableSymbolKindList.ToEditorConfigString()}");
                editorconfig.AppendLine($"dotnet_naming_symbols.{serializedNameMap[symbolSpecification.ID]}.applicable_accessibilities = {symbolSpecification.ApplicableAccessibilityList.ToEditorConfigString(language)}");
                editorconfig.AppendLine($"dotnet_naming_symbols.{serializedNameMap[symbolSpecification.ID]}.required_modifiers = {symbolSpecification.RequiredModifierList.ToEditorConfigString(language)}");
            }

            editorconfig.AppendLine();
            editorconfig.AppendLine($"# {CompilerExtensionsResources.Naming_styles}");

            foreach (var namingStyle in namingStylePreferences.NamingStyles)
            {
                if (!referencedElements.Contains(namingStyle.ID))
                {
                    continue;
                }

                editorconfig.AppendLine();
                editorconfig.AppendLine($"dotnet_naming_style.{serializedNameMap[namingStyle.ID]}.required_prefix = {namingStyle.Prefix}");
                editorconfig.AppendLine($"dotnet_naming_style.{serializedNameMap[namingStyle.ID]}.required_suffix = {namingStyle.Suffix}");
                editorconfig.AppendLine($"dotnet_naming_style.{serializedNameMap[namingStyle.ID]}.word_separator = {namingStyle.WordSeparator}");
                editorconfig.AppendLine($"dotnet_naming_style.{serializedNameMap[namingStyle.ID]}.capitalization = {namingStyle.CapitalizationScheme.ToEditorConfigString()}");
            }
        }
Beispiel #12
0
        private static NamingStylePreferences LocalsAreCamelCaseConstantsAreUpperCaseOption()
        {
            var localsSymbolSpecification = new SymbolSpecification(
                null,
                "Locals",
                ImmutableArray.Create(new SymbolSpecification.SymbolKindOrTypeKind(SymbolKind.Local)),
                ImmutableArray <Accessibility> .Empty,
                ImmutableArray <SymbolSpecification.ModifierKind> .Empty);

            var constLocalsSymbolSpecification = new SymbolSpecification(
                null,
                "Const Locals",
                ImmutableArray.Create(new SymbolSpecification.SymbolKindOrTypeKind(SymbolKind.Local)),
                ImmutableArray <Accessibility> .Empty,
                ImmutableArray.Create(new SymbolSpecification.ModifierKind(SymbolSpecification.ModifierKindEnum.IsConst)));

            var camelCaseNamingStyle = new NamingStyle(
                Guid.NewGuid(),
                capitalizationScheme: Capitalization.CamelCase,
                name: "Camel Case",
                prefix: "",
                suffix: "",
                wordSeparator: "");

            var allUpperNamingStyle = new NamingStyle(
                Guid.NewGuid(),
                capitalizationScheme: Capitalization.AllUpper,
                name: "All Upper",
                prefix: "",
                suffix: "",
                wordSeparator: "");

            var localsCamelCaseNamingRule = new SerializableNamingRule()
            {
                SymbolSpecificationID = localsSymbolSpecification.ID,
                NamingStyleID         = camelCaseNamingStyle.ID,
                EnforcementLevel      = DiagnosticSeverity.Error
            };

            var constLocalsUpperCaseNamingRule = new SerializableNamingRule()
            {
                SymbolSpecificationID = constLocalsSymbolSpecification.ID,
                NamingStyleID         = allUpperNamingStyle.ID,
                EnforcementLevel      = DiagnosticSeverity.Error
            };

            var info = new NamingStylePreferences(
                ImmutableArray.Create(localsSymbolSpecification, constLocalsSymbolSpecification),
                ImmutableArray.Create(camelCaseNamingStyle, allUpperNamingStyle),
                ImmutableArray.Create(constLocalsUpperCaseNamingRule, localsCamelCaseNamingRule));

            return(info);
        }
Beispiel #13
0
        public void TestFetchPersistNamingStyle(StorageLocationKind kind)
        {
            var defaultValue = NamingStylePreferences.Default;
            var value1       = new NamingStylePreferences(
                defaultValue.SymbolSpecifications,
                defaultValue.NamingStyles.WhereAsArray(x => x.Prefix == "I"),
                defaultValue.NamingRules
                );
            var value2 = new NamingStylePreferences(
                defaultValue.SymbolSpecifications,
                defaultValue.NamingStyles.WhereAsArray(x => x.Prefix != "I"),
                defaultValue.NamingRules
                );

            TestFetchPersist(kind, value1, value2, defaultValue);
        }
Beispiel #14
0
        private OptionSet ReadOptionFrom(OptionSet options, string language, PerLanguageOption <NamingStylePreferences> option, ObjectReader reader, CancellationToken cancellationToken)
        {
            cancellationToken.ThrowIfCancellationRequested();

            var xmlText = reader.ReadString();

            try
            {
                var value = NamingStylePreferences.FromXElement(XElement.Parse(xmlText));
                return(options.WithChangedOption(option, language, value));
            }
            catch (System.Exception)
            {
                return(options);
            }
        }
Beispiel #15
0
        public static void TestEmptyDictionaryDefaultNamingStylePreferencesObjectReturnsFalse()
        {
            var editorConfigStorageLocation    = new NamingStylePreferenceEditorConfigStorageLocation();
            var existingNamingStylePreferences = new NamingStylePreferences(
                ImmutableArray.Create <SymbolSpecification>(),
                ImmutableArray.Create <NamingStyle>(),
                ImmutableArray.Create <SerializableNamingRule>());

            var result = editorConfigStorageLocation.TryGetOption(
                existingNamingStylePreferences,
                new Dictionary <string, object>(),
                typeof(NamingStylePreferences),
                out var @object);

            Assert.False(result, "Expected TryParseReadonlyDictionary to return 'false' for empty dictionary");
        }
        internal override void SaveSettings()
        {
            var symbolSpecifications = ArrayBuilder <SymbolSpecification> .GetInstance();

            var namingRules = ArrayBuilder <SerializableNamingRule> .GetInstance();

            var namingStyles = ArrayBuilder <NamingStyle> .GetInstance();

            foreach (var item in _viewModel.CodeStyleItems)
            {
                if (!item.IsComplete())
                {
                    continue;
                }

                var rule = new SerializableNamingRule()
                {
                    EnforcementLevel      = item.SelectedNotificationPreference.Notification.Value,
                    NamingStyleID         = item.SelectedStyle.ID,
                    SymbolSpecificationID = item.SelectedSpecification.ID
                };

                namingRules.Add(rule);
            }

            foreach (var item in _viewModel.Specifications)
            {
                symbolSpecifications.Add(item);
            }

            foreach (var item in _viewModel.NamingStyles)
            {
                namingStyles.Add(item.NamingStyle);
            }

            var info = new NamingStylePreferences(
                symbolSpecifications.ToImmutableAndFree(),
                namingStyles.ToImmutableAndFree(),
                namingRules.ToImmutableAndFree());

            var oldOptions = OptionService.GetOptions();
            var newOptions = oldOptions.WithChangedOption(SimplificationOptions.NamingPreferences, _languageName, info);

            OptionService.SetOptions(newOptions);
            OptionLogger.Log(oldOptions, newOptions);
        }
        internal override void OnSave()
        {
            var symbolSpecifications = ArrayBuilder <SymbolSpecification> .GetInstance();

            var namingRules = ArrayBuilder <SerializableNamingRule> .GetInstance();

            var namingStyles = ArrayBuilder <NamingStyle> .GetInstance();

            foreach (var item in _viewModel.CodeStyleItems)
            {
                if (!item.IsComplete())
                {
                    continue;
                }

                var rule = new SerializableNamingRule()
                {
                    EnforcementLevel      = item.SelectedNotificationPreference.Notification.Severity,
                    NamingStyleID         = item.SelectedStyle.ID,
                    SymbolSpecificationID = item.SelectedSpecification.ID
                };

                namingRules.Add(rule);
            }

            foreach (var item in _viewModel.Specifications)
            {
                symbolSpecifications.Add(item);
            }

            foreach (var item in _viewModel.NamingStyles)
            {
                namingStyles.Add(item.NamingStyle);
            }

            var info = new NamingStylePreferences(
                symbolSpecifications.ToImmutableAndFree(),
                namingStyles.ToImmutableAndFree(),
                namingRules.ToImmutableAndFree()
                );

            OptionStore.SetOption(NamingStyleOptions.NamingPreferences, _languageName, info);
        }
        private void ValidateNamingStyles(Section section)
        {
            NamingStylePreferences namingStyle = EditorConfigNamingStyleParser.GetNamingStyles(section.Properties);

            IOrderedEnumerable <NamingRule> orderedRules = namingStyle.Rules.NamingRules
                                                           .OrderBy(rule => rule, NamingRuleModifierListComparer.Instance)
                                                           .ThenBy(rule => rule, NamingRuleAccessibilityListComparer.Instance)
                                                           .ThenBy(rule => rule, NamingRuleSymbolListComparer.Instance)
                                                           .ThenBy(rule => rule.Name, StringComparer.OrdinalIgnoreCase)
                                                           .ThenBy(rule => rule.Name, StringComparer.Ordinal);

            var orderedRulePreferences = new NamingStylePreferences(
                namingStyle.SymbolSpecifications,
                namingStyle.NamingStyles,
                orderedRules.Select(
                    rule => new SerializableNamingRule
            {
                Name = rule.Name,
                SymbolSpecificationID = rule.SymbolSpecification.ID,
                NamingStyleID         = rule.NamingStyle.ID,
                EnforcementLevel      = rule.EnforcementLevel,
            }).ToImmutableArray());

            var reorderedOverlappingRules = new List <(string firstRule, string secondRule)>();
            ImmutableArray <NamingRule> declaredNamingRules = namingStyle.Rules.NamingRules;
            ImmutableArray <NamingRule> orderedNamingRules  = orderedRulePreferences.Rules.NamingRules;

            for (int i = 0; i < declaredNamingRules.Length; i++)
            {
                for (int j = 0; j < i; j++)
                {
                    NamingRule firstRule  = declaredNamingRules[j];
                    NamingRule secondRule = declaredNamingRules[i];

                    // If the reordered rules are in the same relative order, no need to check the overlap
                    bool reordered = false;
                    foreach (NamingRule rule in orderedNamingRules)
                    {
                        if (rule.Name == firstRule.Name)
                        {
                            break;
                        }
                        else if (rule.Name == secondRule.Name)
                        {
                            reordered = true;
                            break;
                        }
                    }

                    if (!reordered)
                    {
                        continue;
                    }

                    // If the rules don't overlap, reordering is not a problem
                    if (!Overlaps(firstRule, secondRule))
                    {
                        continue;
                    }

                    reorderedOverlappingRules.Add((firstRule.Name, secondRule.Name));
                }
            }

            var reportedRules = new HashSet <string>();

            foreach (Property property in section.Properties)
            {
                string name = property.Keyword.Text.Trim();
                if (!name.StartsWith("dotnet_naming_rule."))
                {
                    continue;
                }

                string[] nameSplit = name.Split('.');
                if (nameSplit.Length != 3)
                {
                    continue;
                }

                string ruleName = nameSplit[1];
                if (!reportedRules.Add(ruleName))
                {
                    continue;
                }

                foreach ((string firstRule, string secondRule) in reorderedOverlappingRules)
                {
                    if (secondRule != ruleName)
                    {
                        continue;
                    }

                    ErrorCatalog.NamingRuleReordered.Run(property.Keyword, e =>
                    {
                        e.Register(secondRule, firstRule);
                    });
                }
            }
        }
        public bool TryFetch(OptionKey optionKey, out object value)
        {
            if (_settingManager == null)
            {
                Debug.Fail("Manager field is unexpectedly null.");
                value = null;
                return(false);
            }

            // Do we roam this at all?
            var roamingSerializations = optionKey.Option.StorageLocations.OfType <RoamingProfileStorageLocation>();

            if (!roamingSerializations.Any())
            {
                value = null;
                return(false);
            }

            value = GetFirstOrDefaultValue(optionKey, roamingSerializations);

            // VS's ISettingsManager has some quirks around storing enums.  Specifically,
            // it *can* persist and retrieve enums, but only if you properly call
            // GetValueOrDefault<EnumType>.  This is because it actually stores enums just
            // as ints and depends on the type parameter passed in to convert the integral
            // value back to an enum value.  Unfortunately, we call GetValueOrDefault<object>
            // and so we get the value back as boxed integer.
            //
            // Because of that, manually convert the integer to an enum here so we don't
            // crash later trying to cast a boxed integer to an enum value.
            if (optionKey.Option.Type.IsEnum)
            {
                if (value != null)
                {
                    value = Enum.ToObject(optionKey.Option.Type, value);
                }
            }
            else if (typeof(ICodeStyleOption).IsAssignableFrom(optionKey.Option.Type))
            {
                return(DeserializeCodeStyleOption(ref value, optionKey.Option.Type));
            }
            else if (optionKey.Option.Type == typeof(NamingStylePreferences))
            {
                // We store these as strings, so deserialize
                if (value is string serializedValue)
                {
                    try
                    {
                        value = NamingStylePreferences.FromXElement(XElement.Parse(serializedValue));
                    }
                    catch (Exception)
                    {
                        value = null;
                        return(false);
                    }
                }
                else
                {
                    value = null;
                    return(false);
                }
            }
            else if (optionKey.Option.Type == typeof(bool) && value is int intValue)
            {
                // TypeScript used to store some booleans as integers. We now handle them properly for legacy sync scenarios.
                value = intValue != 0;
                return(true);
            }
            else if (optionKey.Option.Type == typeof(bool) && value is long longValue)
            {
                // TypeScript used to store some booleans as integers. We now handle them properly for legacy sync scenarios.
                value = longValue != 0;
                return(true);
            }
            else if (optionKey.Option.Type == typeof(bool?))
            {
                // code uses object to hold onto any value which will use boxing on value types.
                // see boxing on nullable types - https://msdn.microsoft.com/en-us/library/ms228597.aspx
                return((value is bool) || (value == null));
            }
            else if (value != null && optionKey.Option.Type != value.GetType())
            {
                // We got something back different than we expected, so fail to deserialize
                value = null;
                return(false);
            }

            return(true);
        }
        public bool TryFetch(OptionKey optionKey, out object value)
        {
            if (_settingManager == null)
            {
                Debug.Fail("Manager field is unexpectedly null.");
                value = null;
                return(false);
            }

            // Do we roam this at all?
            var roamingSerialization = optionKey.Option.StorageLocations.OfType <RoamingProfileStorageLocation>().SingleOrDefault();

            if (roamingSerialization == null)
            {
                value = null;
                return(false);
            }

            var storageKey = roamingSerialization.GetKeyNameForLanguage(optionKey.Language);

            RecordObservedValueToWatchForChanges(optionKey, storageKey);

            value = _settingManager.GetValueOrDefault(storageKey, optionKey.Option.DefaultValue);

            // VS's ISettingsManager has some quirks around storing enums.  Specifically,
            // it *can* persist and retrieve enums, but only if you properly call
            // GetValueOrDefault<EnumType>.  This is because it actually stores enums just
            // as ints and depends on the type parameter passed in to convert the integral
            // value back to an enum value.  Unfortunately, we call GetValueOrDefault<object>
            // and so we get the value back as boxed integer.
            //
            // Because of that, manually convert the integer to an enum here so we don't
            // crash later trying to cast a boxed integer to an enum value.
            if (optionKey.Option.Type.IsEnum)
            {
                if (value != null)
                {
                    value = Enum.ToObject(optionKey.Option.Type, value);
                }
            }
            else if (optionKey.Option.Type == typeof(CodeStyleOption <bool>))
            {
                // We store these as strings, so deserialize
                if (value is string serializedValue)
                {
                    try
                    {
                        value = CodeStyleOption <bool> .FromXElement(XElement.Parse(serializedValue));
                    }
                    catch (Exception)
                    {
                        value = null;
                        return(false);
                    }
                }
                else
                {
                    value = null;
                    return(false);
                }
            }
            else if (optionKey.Option.Type == typeof(NamingStylePreferences))
            {
                // We store these as strings, so deserialize
                if (value is string serializedValue)
                {
                    try
                    {
                        value = NamingStylePreferences.FromXElement(XElement.Parse(serializedValue));
                    }
                    catch (Exception)
                    {
                        value = null;
                        return(false);
                    }
                }
                else
                {
                    value = null;
                    return(false);
                }
            }
            else if (optionKey.Option.Type == typeof(bool) && value is int intValue)
            {
                // TypeScript used to store some booleans as integers. We now handle them properly for legacy sync scenarios.
                value = intValue != 0;
                return(true);
            }
            else if (optionKey.Option.Type == typeof(bool) && value is long longValue)
            {
                // TypeScript used to store some booleans as integers. We now handle them properly for legacy sync scenarios.
                value = longValue != 0;
                return(true);
            }
            else if (value != null && optionKey.Option.Type != value.GetType())
            {
                // We got something back different than we expected, so fail to deserialize
                value = null;
                return(false);
            }

            return(true);
        }