static void TestParseEditorConfigCodeStyleOption(string args, bool isEnabled, DiagnosticSeverity severity)
        {
            var notificationOption = NotificationOption.None;
            switch (severity)
            {
                case DiagnosticSeverity.Hidden:
                    notificationOption = NotificationOption.None;
                    break;
                case DiagnosticSeverity.Info:
                    notificationOption = NotificationOption.Suggestion;
                    break;
                case DiagnosticSeverity.Warning:
                    notificationOption = NotificationOption.Warning;
                    break;
                case DiagnosticSeverity.Error:
                    notificationOption = NotificationOption.Error;
                    break;
            }

            var codeStyleOption = new CodeStyleOption<bool>(value: isEnabled, notification: notificationOption);

            var result = CodeStyleHelpers.ParseEditorConfigCodeStyleOption(args);
            Assert.True(result.Value == isEnabled,
                        $"Expected {nameof(isEnabled)} to be {isEnabled}, was {result.Value}");
            Assert.True(result.Notification.Value == severity,
                        $"Expected {nameof(severity)} to be {severity}, was {result.Notification.Value}");
        }
        private static bool FetchStyleOption <T>(string typeStyleOptionValue, out object value)
        {
            if (string.IsNullOrEmpty(typeStyleOptionValue))
            {
                value = CodeStyleOption <T> .Default;
            }
            else
            {
                value = CodeStyleOption <T> .FromXElement(XElement.Parse(typeStyleOptionValue));
            }

            return(true);
        }
Example #3
0
        private static string GetExpressionBodyPreferenceEditorConfigString(CodeStyleOption <ExpressionBodyPreference> value)
        {
            Debug.Assert(value.Notification != null);

            var notificationString = value.Notification.ToEditorConfigString();

            return(value.Value switch
            {
                ExpressionBodyPreference.Never => $"false:{notificationString}",
                ExpressionBodyPreference.WhenPossible => $"true:{notificationString}",
                ExpressionBodyPreference.WhenOnSingleLine => $"when_on_single_line:{notificationString}",
                _ => throw new NotSupportedException(),
            });
Example #4
0
 private static void ReportDiagnostics(
     SyntaxNodeAnalysisContext context, DiagnosticDescriptor descriptor,
     IEnumerable <UsingDirectiveSyntax> usingDirectives, CodeStyleOption <AddImportPlacement> option)
 {
     foreach (var usingDirective in usingDirectives)
     {
         context.ReportDiagnostic(DiagnosticHelper.Create(
                                      descriptor,
                                      usingDirective.GetLocation(),
                                      option.Notification.Severity,
                                      additionalLocations: null,
                                      properties: null));
     }
 }
 public Result(
     ResultKind kind, CodeStyleOption <bool> option,
     IInvocationOperation invocationOperation, InvocationExpressionSyntax invocation,
     IMethodSymbol sliceLikeMethod, MemberInfo memberInfo,
     IOperation op1, IOperation op2)
 {
     Kind   = kind;
     Option = option;
     InvocationOperation = invocationOperation;
     Invocation          = invocation;
     SliceLikeMethod     = sliceLikeMethod;
     MemberInfo          = memberInfo;
     Op1 = op1;
     Op2 = op2;
 }
Example #6
0
        public static string GetUsingDirectivesPlacementEditorConfigString(CodeStyleOption <AddImportPlacement> value)
        {
            Debug.Assert(value.Notification != null);

            var notificationString = value.Notification.ToEditorConfigString();

            switch (value.Value)
            {
            case AddImportPlacement.InsideNamespace: return($"inside_namespace:{notificationString}");

            case AddImportPlacement.OutsideNamespace: return($"outside_namespace:{notificationString}");

            default:
                throw new NotSupportedException();
            }
        }
        private DiagnosticDescriptor GetFieldDescriptor(CodeStyleOption <bool> styleOption)
        {
            if (styleOption.Value)
            {
                switch (styleOption.Notification.Value)
                {
                case DiagnosticSeverity.Error: return(ErrorDescriptor);

                case DiagnosticSeverity.Warning: return(WarningDescriptor);

                case DiagnosticSeverity.Info: return(InfoDescriptor);
                }
            }

            return(UnnecessaryWithSuggestionDescriptor);
        }
Example #8
0
        private bool DeserializeCodeStyleOption <T>(ref object value)
        {
            if (value is string serializedValue)
            {
                try
                {
                    value = CodeStyleOption <T> .FromXElement(XElement.Parse(serializedValue));

                    return(true);
                }
                catch (Exception)
                {
                }
            }

            value = null;
            return(false);
        }
Example #9
0
        private static string GetExpressionBodyPreferenceEditorConfigString(CodeStyleOption <ExpressionBodyPreference> value)
        {
            Debug.Assert(value.Notification != null);

            var notificationString = value.Notification.ToEditorConfigString();

            switch (value.Value)
            {
            case ExpressionBodyPreference.Never: return($"false:{notificationString}");

            case ExpressionBodyPreference.WhenPossible: return($"true:{notificationString}");

            case ExpressionBodyPreference.WhenOnSingleLine: return($"when_on_single_line:{notificationString}");

            default:
                throw new NotSupportedException();
            }
        }
Example #10
0
        public static bool TryParseEditorConfigCodeStyleOption(string arg, out CodeStyleOption <bool> option)
        {
            var args      = arg.Split(':');
            var isEnabled = false;

            if (args.Length != 2)
            {
                if (args.Length == 1)
                {
                    if (bool.TryParse(args[0].Trim(), out isEnabled) && !isEnabled)
                    {
                        option = new CodeStyleOption <bool>(value: isEnabled, notification: NotificationOption.None);
                        return(true);
                    }
                    else
                    {
                        option = CodeStyleOption <bool> .Default;
                        return(false);
                    }
                }
                option = CodeStyleOption <bool> .Default;
                return(false);
            }

            if (!bool.TryParse(args[0].Trim(), out isEnabled))
            {
                option = CodeStyleOption <bool> .Default;
                return(false);
            }

            switch (args[1].Trim())
            {
            case EditorConfigSeverityStrings.Silent: option = new CodeStyleOption <bool>(value: isEnabled, notification: NotificationOption.None); return(true);

            case EditorConfigSeverityStrings.Suggestion: option = new CodeStyleOption <bool>(value: isEnabled, notification: NotificationOption.Suggestion); return(true);

            case EditorConfigSeverityStrings.Warning: option = new CodeStyleOption <bool>(value: isEnabled, notification: NotificationOption.Warning); return(true);

            case EditorConfigSeverityStrings.Error: option = new CodeStyleOption <bool>(value: isEnabled, notification: NotificationOption.Error); return(true);

            default: option = new CodeStyleOption <bool>(value: isEnabled, notification: NotificationOption.None); return(false);
            }
        }
Example #11
0
        public static PerLanguageOption <CodeStyleOption <T> > ToPublicOption <T>(
            this PerLanguageOption2 <CodeStyleOption2 <T> > option
            )
        {
            RoslynDebug.Assert(option != null);

            var codeStyleOption  = new CodeStyleOption <T>(option.DefaultValue);
            var optionDefinition = new OptionDefinition(
                option.Feature,
                option.Group,
                option.Name,
                defaultValue: codeStyleOption,
                type: typeof(CodeStyleOption <T>),
                isPerLanguage: true
                );

            return(new PerLanguageOption <CodeStyleOption <T> >(
                       optionDefinition,
                       option.StorageLocations.As <OptionStorageLocation>()
                       ));
        }
Example #12
0
        private static string GetPreferBracesPreferenceEditorConfigString(CodeStyleOption <PreferBracesPreference> value)
        {
            Debug.Assert(value.Notification != null);

            var notificationString = value.Notification.ToEditorConfigString();

            switch (value.Value)
            {
            case PreferBracesPreference.None:
                return($"false:{notificationString}");

            case PreferBracesPreference.WhenMultiline:
                return($"when_multiline:{notificationString}");

            case PreferBracesPreference.Always:
                return($"true:{notificationString}");

            default:
                throw ExceptionUtilities.Unreachable;
            }
        }
        private IFieldSymbol CreateField(
            CodeStyleOption <AccessibilityModifiersRequired> requireAccessibilityModifiers,
            IParameterSymbol parameter,
            ImmutableArray <NamingRule> rules,
            ImmutableArray <string> parameterNameParts)
        {
            foreach (var rule in rules)
            {
                if (rule.SymbolSpecification.AppliesTo(SymbolKind.Field, Accessibility.Private))
                {
                    var uniqueName = GenerateUniqueName(parameter, parameterNameParts, rule);

                    var accessibilityLevel = Accessibility.Private;
                    if (requireAccessibilityModifiers.Value == AccessibilityModifiersRequired.Never || requireAccessibilityModifiers.Value == AccessibilityModifiersRequired.OmitIfDefault)
                    {
                        var defaultAccessibility = DetermineDefaultFieldAccessibility(parameter.ContainingType);
                        if (defaultAccessibility == Accessibility.Private)
                        {
                            accessibilityLevel = Accessibility.NotApplicable;
                        }
                    }

                    return(CodeGenerationSymbolFactory.CreateFieldSymbol(
Example #14
0
        public async Task OptionSet_Serialization_CustomValue()
        {
            var workspace = new AdhocWorkspace();

            var newQualifyFieldAccessValue    = new CodeStyleOption <bool>(false, NotificationOption.Error);
            var newQualifyMethodAccessValue   = new CodeStyleOption <bool>(true, NotificationOption.Warning);
            var newVarWhenTypeIsApparentValue = new CodeStyleOption <bool>(false, NotificationOption.Suggestion);
            var newPreferIntrinsicPredefinedTypeKeywordInMemberAccessValue = new CodeStyleOption <bool>(true, NotificationOption.Silent);

            workspace.TryApplyChanges(workspace.CurrentSolution.WithOptions(workspace.Options
                                                                            .WithChangedOption(CodeStyleOptions.QualifyFieldAccess, LanguageNames.CSharp, newQualifyFieldAccessValue)
                                                                            .WithChangedOption(CodeStyleOptions.QualifyMethodAccess, LanguageNames.VisualBasic, newQualifyMethodAccessValue)
                                                                            .WithChangedOption(CSharpCodeStyleOptions.VarWhenTypeIsApparent, newVarWhenTypeIsApparentValue)
                                                                            .WithChangedOption(CodeStyleOptions.PreferIntrinsicPredefinedTypeKeywordInMemberAccess, LanguageNames.VisualBasic, newPreferIntrinsicPredefinedTypeKeywordInMemberAccessValue)));

            await VerifyOptionSetsAsync(workspace, VerifyOptions).ConfigureAwait(false);

            void VerifyOptions(OptionSet options)
            {
                var actualQualifyFieldAccessValue = options.GetOption(CodeStyleOptions.QualifyFieldAccess, LanguageNames.CSharp);

                Assert.Equal(newQualifyFieldAccessValue, actualQualifyFieldAccessValue);

                var actualQualifyMethodAccessValue = options.GetOption(CodeStyleOptions.QualifyMethodAccess, LanguageNames.VisualBasic);

                Assert.Equal(newQualifyMethodAccessValue, actualQualifyMethodAccessValue);

                var actualVarWhenTypeIsApparentValue = options.GetOption(CSharpCodeStyleOptions.VarWhenTypeIsApparent);

                Assert.Equal(newVarWhenTypeIsApparentValue, actualVarWhenTypeIsApparentValue);

                var actualPreferIntrinsicPredefinedTypeKeywordInMemberAccessValue = options.GetOption(CodeStyleOptions.PreferIntrinsicPredefinedTypeKeywordInMemberAccess, LanguageNames.VisualBasic);

                Assert.Equal(newPreferIntrinsicPredefinedTypeKeywordInMemberAccessValue, actualPreferIntrinsicPredefinedTypeKeywordInMemberAccessValue);
            }
        }
Example #15
0
 private static string GetBoolCodeStyleOptionEditorConfigStringForValue(CodeStyleOption <bool> value)
 => $"{(value.Value ? "true" : "false")}:{value.Notification.ToEditorConfigString()}";
 private static string GetStringCodeStyleOptionEditorConfigStringForValue(CodeStyleOption <string> value) => value.Value.ToLowerInvariant();
Example #17
0
 /// <summary>
 /// checks if style is preferred and the enforcement is not None.
 /// </summary>
 /// <remarks>if predefined type is not preferred, it implies the preference is framework type.</remarks>
 private static bool OptionSettingPrefersFrameworkType(CodeStyleOption <bool> optionValue, DiagnosticSeverity severity) =>
 !optionValue.Value && severity != DiagnosticSeverity.Hidden;
        public async Task CustomizableTagsForUnnecessaryCode()
        {
            var workspaceXml =
@"<Workspace>
    <Project Language=""C#"" CommonReferences=""true"">
        <Document FilePath = ""Test.cs"" >
// System is used - rest are unused.
using System.Collections;
using System;
using System.Diagnostics;
using System.Collections.Generic;

class Program
{
    void Test()
    {
        Int32 x = 2; // Int32 can be simplified.
        x += 1;
    }
}
        </Document>
    </Project>
</Workspace>";

            using (var workspace = await TestWorkspace.CreateAsync(workspaceXml))
            {
                var options = new Dictionary<OptionKey, object>();
                var language = workspace.Projects.Single().Language;
                var preferIntrinsicPredefinedTypeOption = new OptionKey(CodeStyleOptions.PreferIntrinsicPredefinedTypeKeywordInDeclaration, language);
                var preferIntrinsicPredefinedTypeOptionValue = new CodeStyleOption<bool>(value: true, notification: NotificationOption.Error);
                options.Add(preferIntrinsicPredefinedTypeOption, preferIntrinsicPredefinedTypeOptionValue);

                workspace.ApplyOptions(options);

                var analyzerMap = new Dictionary<string, DiagnosticAnalyzer[]>
                {
                    {
                        LanguageNames.CSharp,
                        new DiagnosticAnalyzer[]
                        {
                            new CSharpSimplifyTypeNamesDiagnosticAnalyzer(),
                            new CSharpRemoveUnnecessaryImportsDiagnosticAnalyzer()
                        }
                    }
                };

                var spans =
                    (await GetDiagnosticsAndErrorSpans(workspace, analyzerMap)).Item2
                        .OrderBy(s => s.Span.Span.Start).ToImmutableArray();

                Assert.Equal(3, spans.Length);
                var first = spans[0];
                var second = spans[1];
                var third = spans[2];

                Assert.Equal(PredefinedErrorTypeNames.Suggestion, first.Tag.ErrorType);
                Assert.Equal(CSharpFeaturesResources.Using_directive_is_unnecessary, first.Tag.ToolTipContent);
                Assert.Equal(40, first.Span.Start);
                Assert.Equal(25, first.Span.Length);

                Assert.Equal(PredefinedErrorTypeNames.Suggestion, second.Tag.ErrorType);
                Assert.Equal(CSharpFeaturesResources.Using_directive_is_unnecessary, second.Tag.ToolTipContent);
                Assert.Equal(82, second.Span.Start);
                Assert.Equal(60, second.Span.Length);

                Assert.Equal(PredefinedErrorTypeNames.SyntaxError, third.Tag.ErrorType);
                Assert.Equal(WorkspacesResources.Name_can_be_simplified, third.Tag.ToolTipContent);
                Assert.Equal(196, third.Span.Start);
                Assert.Equal(5, third.Span.Length);
            }
        }
Example #19
0
        public bool TryFetch(OptionKey optionKey, out object value)
        {
            if (this._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 = this._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
                var serializedValue = value as string;

                if (serializedValue != null)
                {
                    value = CodeStyleOption <bool> .FromXElement(XElement.Parse(serializedValue));
                }
                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);
        }
Example #20
0
        private void ProcessMemberDeclaration(
            SyntaxTreeAnalysisContext context, SyntaxGenerator generator,
            CodeStyleOption <AccessibilityModifiersRequired> option, MemberDeclarationSyntax member)
        {
            if (member.IsKind(SyntaxKind.NamespaceDeclaration, out NamespaceDeclarationSyntax namespaceDeclaration))
            {
                ProcessMembers(context, generator, option, namespaceDeclaration.Members);
            }

            // If we have a class or struct, recurse inwards.
            if (member.IsKind(SyntaxKind.ClassDeclaration, out TypeDeclarationSyntax typeDeclaration) ||
                member.IsKind(SyntaxKind.StructDeclaration, out typeDeclaration))
            {
                ProcessMembers(context, generator, option, typeDeclaration.Members);
            }

#if false
            // Add this once we have the language version for C# that supports accessibility
            // modifiers on interface methods.
            if (option.Value == AccessibilityModifiersRequired.Always &&
                member.IsKind(SyntaxKind.InterfaceDeclaration, out typeDeclaration))
            {
                // Only recurse into an interface if the user wants accessibility modifiers on
                ProcessTypeDeclaration(context, generator, option, typeDeclaration);
            }
#endif

            // Have to have a name to report the issue on.
            var name = member.GetNameToken();
            if (name.Kind() == SyntaxKind.None)
            {
                return;
            }

            // Certain members never have accessibility. Don't bother reporting on them.
            if (!generator.CanHaveAccessibility(member))
            {
                return;
            }

            // This analyzer bases all of its decisions on the accessibility
            var accessibility = generator.GetAccessibility(member);

            // Omit will flag any accessibility values that exist and are default
            // The other options will remove or ignore accessibility
            var isOmit = option.Value == AccessibilityModifiersRequired.OmitIfDefault;

            if (isOmit)
            {
                if (accessibility == Accessibility.NotApplicable)
                {
                    return;
                }

                var parentKind = member.Parent.Kind();
                switch (parentKind)
                {
                // Check for default modifiers in namespace and outside of namespace
                case SyntaxKind.CompilationUnit:
                case SyntaxKind.NamespaceDeclaration:
                {
                    // Default is internal
                    if (accessibility != Accessibility.Internal)
                    {
                        return;
                    }
                }
                break;

                case SyntaxKind.ClassDeclaration:
                case SyntaxKind.StructDeclaration:
                {
                    // Inside a type, default is private
                    if (accessibility != Accessibility.Private)
                    {
                        return;
                    }
                }
                break;

                default:
                    return;     // Unknown parent kind, don't do anything
                }
            }
            else
            {
                // Mode is always, so we have to flag missing modifiers
                if (accessibility != Accessibility.NotApplicable)
                {
                    return;
                }
            }

            // Have an issue to flag, either add or remove. Report issue to user.
            var additionalLocations = ImmutableArray.Create(member.GetLocation());
            context.ReportDiagnostic(DiagnosticHelper.Create(
                                         Descriptor,
                                         name.GetLocation(),
                                         option.Notification.Severity,
                                         additionalLocations: additionalLocations,
                                         properties: null));
        }
Example #21
0
 private static string GetStringCodeStyleOptionEditorConfigStringForValue(CodeStyleOption <string> value)
 => $"{value.Value.ToLowerInvariant()}:{value.Notification.ToEditorConfigString()}";
Example #22
0
        public async Task CustomizableTagsForUnnecessaryCode()
        {
            var workspaceXml =
                @"<Workspace>
    <Project Language=""C#"" CommonReferences=""true"">
        <Document FilePath = ""Test.cs"" >
// System is used - rest are unused.
using System.Collections;
using System;
using System.Diagnostics;
using System.Collections.Generic;

class Program
{
    void Test()
    {
        Int32 x = 2; // Int32 can be simplified.
        x += 1;
    }
}
        </Document>
    </Project>
</Workspace>";

            using var workspace = TestWorkspace.Create(workspaceXml);
            var options  = new Dictionary <OptionKey, object>();
            var language = workspace.Projects.Single().Language;
            var preferIntrinsicPredefinedTypeOption      = new OptionKey(CodeStyleOptions.PreferIntrinsicPredefinedTypeKeywordInDeclaration, language);
            var preferIntrinsicPredefinedTypeOptionValue = new CodeStyleOption <bool>(value: true, notification: NotificationOption.Error);

            options.Add(preferIntrinsicPredefinedTypeOption, preferIntrinsicPredefinedTypeOptionValue);

            workspace.ApplyOptions(options);

            var analyzerMap = new Dictionary <string, DiagnosticAnalyzer[]>
            {
                {
                    LanguageNames.CSharp,
                    new DiagnosticAnalyzer[]
                    {
                        new CSharpSimplifyTypeNamesDiagnosticAnalyzer(),
                        new CSharpRemoveUnnecessaryImportsDiagnosticAnalyzer()
                    }
                }
            };

            var spans =
                (await _producer.GetDiagnosticsAndErrorSpans(workspace, analyzerMap)).Item2
                .OrderBy(s => s.Span.Span.Start).ToImmutableArray();

            Assert.Equal(3, spans.Length);
            var first  = spans[0];
            var second = spans[1];
            var third  = spans[2];

            Assert.Equal(PredefinedErrorTypeNames.Suggestion, first.Tag.ErrorType);
            Assert.Equal(CSharpAnalyzersResources.Using_directive_is_unnecessary, first.Tag.ToolTipContent);
            Assert.Equal(40, first.Span.Start);
            Assert.Equal(25, first.Span.Length);

            Assert.Equal(PredefinedErrorTypeNames.Suggestion, second.Tag.ErrorType);
            Assert.Equal(CSharpAnalyzersResources.Using_directive_is_unnecessary, second.Tag.ToolTipContent);
            Assert.Equal(82, second.Span.Start);
            Assert.Equal(60, second.Span.Length);

            Assert.Equal(PredefinedErrorTypeNames.SyntaxError, third.Tag.ErrorType);
            Assert.Equal(WorkspacesResources.Name_can_be_simplified, third.Tag.ToolTipContent);
            Assert.Equal(196, third.Span.Start);
            Assert.Equal(5, third.Span.Length);
        }
        public static Result?AnalyzeInvocation(
            IInvocationOperation invocation, InfoCache infoCache,
            AnalyzerOptions analyzerOptionsOpt, CancellationToken cancellationToken)
        {
            // Validate we're on a piece of syntax we expect.  While not necessary for analysis, we
            // want to make sure we're on something the fixer will know how to actually fix.
            if (!(invocation.Syntax is InvocationExpressionSyntax invocationSyntax) ||
                invocationSyntax.ArgumentList is null)
            {
                return(null);
            }

            CodeStyleOption <bool> option = null;

            if (analyzerOptionsOpt != null)
            {
                // Check if we're at least on C# 8, and that the user wants these operators.
                var syntaxTree   = invocationSyntax.SyntaxTree;
                var parseOptions = (CSharpParseOptions)syntaxTree.Options;
                if (parseOptions.LanguageVersion < LanguageVersion.CSharp8)
                {
                    return(null);
                }

                option = analyzerOptionsOpt.GetOption(CSharpCodeStyleOptions.PreferRangeOperator, syntaxTree, cancellationToken);
                if (!option.Value)
                {
                    return(null);
                }
            }

            // look for `s.Slice(e1, end - e2)`
            if (invocation.Instance is null ||
                invocation.Arguments.Length != 2)
            {
                return(null);
            }

            // See if the call is to something slice-like.
            var targetMethod = invocation.TargetMethod;

            // Second arg needs to be a subtraction for: `end - e2`.  Once we've seen that we have
            // that, try to see if we're calling into some sort of Slice method with a matching
            // indexer or overload
            if (!IsSubtraction(invocation.Arguments[1].Value, out var subtraction) ||
                !infoCache.TryGetMemberInfo(targetMethod, out var memberInfo))
            {
                return(null);
            }

            // See if we have: (start, end - start).  Specifically where the start operation it the
            // same as the right side of the subtraction.
            var startOperation = invocation.Arguments[0].Value;

            if (CSharpSyntaxFacts.Instance.AreEquivalent(startOperation.Syntax, subtraction.RightOperand.Syntax))
            {
                return(new Result(
                           ResultKind.Computed, option,
                           invocation, invocationSyntax,
                           targetMethod, memberInfo,
                           startOperation, subtraction.LeftOperand));
            }

            // See if we have: (constant1, s.Length - constant2).  The constants don't have to be
            // the same value.  This will convert over to s[constant1..(constant - constant1)]
            if (IsConstantInt32(startOperation) &&
                IsConstantInt32(subtraction.RightOperand) &&
                IsInstanceLengthCheck(memberInfo.LengthLikeProperty, invocation.Instance, subtraction.LeftOperand))
            {
                return(new Result(
                           ResultKind.Constant, option,
                           invocation, invocationSyntax,
                           targetMethod, memberInfo,
                           startOperation, subtraction.RightOperand));
            }

            return(null);
        }
Example #24
0
        private void SetXmlOption <T>(Option <CodeStyleOption <T> > option, string value)
        {
            var convertedValue = CodeStyleOption <T> .FromXElement(XElement.Parse(value));

            _workspace.Options = _workspace.Options.WithChangedOption(option, convertedValue);
        }
Example #25
0
 protected IDictionary <OptionKey, object> Option(IOption option, CodeStyleOption <bool> notification)
 => Option(option, notification.Value, notification.Notification);
 protected IDictionary<OptionKey, object> Option(IOption option, CodeStyleOption<bool> notification)
     => Option(option, notification.Value, notification.Notification);
 /// <summary>
 /// checks if style is preferred and the enforcement is not None.
 /// </summary>
 /// <remarks>if predefined type is not preferred, it implies the preference is framework type.</remarks>
 private static bool OptionSettingPrefersFrameworkType(CodeStyleOption <bool> optionValue, ReportDiagnostic severity)
 => !optionValue.Value && severity.WithDefaultSeverity(DiagnosticSeverity.Hidden) < ReportDiagnostic.Hidden;
Example #28
0
 /// <summary>
 /// checks if style is preferred and the enforcement is not None.
 /// </summary>
 /// <remarks>if predefined type is not preferred, it implies the preference is framework type.</remarks>
 private static bool OptionSettingPrefersFrameworkType(CodeStyleOption <bool> optionValue, ReportDiagnostic severity)
 => !optionValue.Value && severity != ReportDiagnostic.Suppress;
 private static string GetBoolCodeStyleOptionEditorConfigStringForValue(CodeStyleOption <bool> value)
 => value.Value
        ? $"true:{value.Notification.ToEditorConfigString()}"
        : value.Notification != null ? $"false:{value.Notification.ToEditorConfigString()}" : "false";
 protected abstract void ProcessCompilationUnit(SyntaxTreeAnalysisContext context, SyntaxGenerator generator, CodeStyleOption <AccessibilityModifiersRequired> option, TCompilationUnitSyntax compilationUnitSyntax);
Example #31
0
 protected override void ProcessCompilationUnit(
     SyntaxTreeAnalysisContext context, SyntaxGenerator generator,
     CodeStyleOption <AccessibilityModifiersRequired> option, CompilationUnitSyntax compilationUnit)
 {
     ProcessMembers(context, generator, option, compilationUnit.Members);
 }
Example #32
0
        private void SetXmlOption(PerLanguageOption <CodeStyleOption <bool> > option, string value)
        {
            var convertedValue = CodeStyleOption <bool> .FromXElement(XElement.Parse(value));

            _workspace.Options = _workspace.Options.WithChangedOption(option, LanguageNames.CSharp, convertedValue);
        }
        private protected Task TestInRegularAndScriptAsync(string initialMarkup, string expectedMarkup, CodeStyleOption <AddImportPlacement> preferredPlacementOption, bool placeSystemNamespaceFirst)
        {
            var options = new Dictionary <OptionKey, object>
            {
                { CSharpCodeStyleOptions.PreferredUsingDirectivePlacement, preferredPlacementOption },
                { new OptionKey(GenerationOptions.PlaceSystemNamespaceFirst, LanguageNames.CSharp), placeSystemNamespaceFirst }
            };

            return(TestInRegularAndScriptAsync(initialMarkup, expectedMarkup, options: options));
        }