private bool SwitchIsIncomplete(
            ISwitchStatement switchStatement,
            out bool missingCases, out bool missingDefaultCase)
        {
            var missingEnumMembers = PopulateSwitchHelpers.GetMissingEnumMembers(switchStatement);

            missingCases       = missingEnumMembers.Count > 0;
            missingDefaultCase = !PopulateSwitchHelpers.HasDefaultCase(switchStatement);

            // The switch is incomplete if we're missing any cases or we're missing a default case.
            return(missingDefaultCase || missingCases);
        }
        private async Task <Document> AddMissingSwitchCasesAsync(
            CodeFixContext context, bool includeMissingCases, bool includeDefaultCase)
        {
            var document          = context.Document;
            var span              = context.Span;
            var cancellationToken = context.CancellationToken;

            var root = await document.GetSyntaxRootAsync(cancellationToken).ConfigureAwait(false);

            var model = await document.GetSemanticModelAsync(cancellationToken).ConfigureAwait(false);

            var switchNode      = root.FindNode(span);
            var internalMethod  = typeof(SemanticModel).GetTypeInfo().GetDeclaredMethod("GetOperationInternal");
            var switchStatement = (ISwitchStatement)internalMethod.Invoke(model, new object[] { switchNode, cancellationToken });
            var enumType        = switchStatement.Value.Type;

            var generator = SyntaxGenerator.GetGenerator(document);

            var sectionStatements = new[] { generator.ExitSwitchStatement() };

            var newSections = new List <SyntaxNode>();

            if (includeMissingCases)
            {
                var missingEnumMembers = PopulateSwitchHelpers.GetMissingEnumMembers(switchStatement);
                var missingSections    =
                    from e in missingEnumMembers
                    let caseLabel = generator.MemberAccessExpression(generator.TypeExpression(enumType), e.Name).WithAdditionalAnnotations(Simplifier.Annotation)
                                    let section = generator.SwitchSection(caseLabel, sectionStatements)
                                                  select section;

                newSections.AddRange(missingSections);
            }

            if (includeDefaultCase)
            {
                // Always add the default clause at the end.
                newSections.Add(generator.DefaultSwitchSection(sectionStatements));
            }

            var insertLocation = InsertPosition(switchStatement);

            var newSwitchNode = generator.InsertSwitchSections(switchNode, insertLocation, newSections)
                                .WithAdditionalAnnotations(Formatter.Annotation);

            // Make sure we didn't cause any braces to be imbalanced when we added members
            // to the switch.
            AddMissingBraces(document, ref root, ref switchNode);

            var newRoot = root.ReplaceNode(switchNode, newSwitchNode);

            return(document.WithSyntaxRoot(newRoot));
        }
示例#3
0
        private void FixOneDiagnostic(
            Document document, SyntaxEditor editor,
            SemanticModel model, Diagnostic diagnostic,
            bool addCases, bool addDefaultCase,
            bool onlyOneDiagnostic,
            CancellationToken cancellationToken)
        {
            var hasMissingCases       = bool.Parse(diagnostic.Properties[PopulateSwitchHelpers.MissingCases]);
            var hasMissingDefaultCase = bool.Parse(diagnostic.Properties[PopulateSwitchHelpers.MissingDefaultCase]);

            var switchLocation  = diagnostic.AdditionalLocations[0];
            var switchNode      = switchLocation.FindNode(cancellationToken);
            var switchStatement = (ISwitchOperation)model.GetOperation(switchNode, cancellationToken);
            var enumType        = switchStatement.Value.Type;

            var generator = editor.Generator;

            var sectionStatements = new[] { generator.ExitSwitchStatement() };

            var newSections = new List <SyntaxNode>();

            if (hasMissingCases && addCases)
            {
                var missingEnumMembers = PopulateSwitchHelpers.GetMissingEnumMembers(switchStatement);
                var missingSections    =
                    from e in missingEnumMembers
                    let caseLabel = generator.MemberAccessExpression(generator.TypeExpression(enumType), e.Name).WithAdditionalAnnotations(Simplifier.Annotation)
                                    let section = generator.SwitchSection(caseLabel, sectionStatements)
                                                  select section;

                newSections.AddRange(missingSections);
            }

            if (hasMissingDefaultCase && addDefaultCase)
            {
                // Always add the default clause at the end.
                newSections.Add(generator.DefaultSwitchSection(sectionStatements));
            }

            var insertLocation = InsertPosition(switchStatement);

            var newSwitchNode = generator.InsertSwitchSections(switchNode, insertLocation, newSections)
                                .WithAdditionalAnnotations(Formatter.Annotation);

            if (onlyOneDiagnostic)
            {
                // If we're only fixing up one issue in this document, then also make sure we
                // didn't cause any braces to be imbalanced when we added members to the switch.
                // Note: i'm only doing this for the single case because it feels too complex
                // to try to support this during fix-all.
                var root = editor.OriginalRoot;
                AddMissingBraces(document, ref root, ref switchNode);

                var newRoot = root.ReplaceNode(switchNode, newSwitchNode);
                editor.ReplaceNode(editor.OriginalRoot, newRoot);
            }
            else
            {
                editor.ReplaceNode(switchNode, newSwitchNode);
            }
        }