Esempio n. 1
0
        protected override async Task <SemanticDocument> ExpandAsync(
            SelectionResult selection,
            CancellationToken cancellationToken
            )
        {
            var lastExpression = selection
                                 .GetFirstTokenInSelection()
                                 .GetCommonRoot(selection.GetLastTokenInSelection())
                                 .GetAncestors <ExpressionSyntax>()
                                 .LastOrDefault();

            if (lastExpression == null)
            {
                return(selection.SemanticDocument);
            }

            var newExpression = await Simplifier
                                .ExpandAsync(
                lastExpression,
                selection.SemanticDocument.Document,
                n => n != selection.GetContainingScope(),
                expandParameter : false,
                cancellationToken : cancellationToken
                )
                                .ConfigureAwait(false);

            return(await selection.SemanticDocument
                   .WithSyntaxRootAsync(
                       selection.SemanticDocument.Root.ReplaceNode(lastExpression, newExpression),
                       cancellationToken
                       )
                   .ConfigureAwait(false));
        }
            protected override ITypeSymbol GetSymbolType(
                SemanticModel semanticModel,
                ISymbol symbol
                )
            {
                var selectionOperation = semanticModel.GetOperation(
                    SelectionResult.GetContainingScope()
                    );

                switch (symbol)
                {
                case ILocalSymbol localSymbol
                    when localSymbol.NullableAnnotation == NullableAnnotation.Annotated:
                case IParameterSymbol parameterSymbol
                    when parameterSymbol.NullableAnnotation == NullableAnnotation.Annotated:

                    // For local symbols and parameters, we can check what the flow state
                    // for refences to the symbols are and determine if we can change
                    // the nullability to a less permissive state.
                    var references = selectionOperation
                                     .DescendantsAndSelf()
                                     .Where(IsSymbolReferencedByOperation);

                    if (AreAllReferencesNotNull(references))
                    {
                        return(base.GetSymbolType(semanticModel, symbol)
                               .WithNullableAnnotation(NullableAnnotation.NotAnnotated));
                    }

                    return(base.GetSymbolType(semanticModel, symbol));

                default:
                    return(base.GetSymbolType(semanticModel, symbol));
                }

                bool AreAllReferencesNotNull(IEnumerable <IOperation> references) =>
                references.All(
                    r =>
                    semanticModel.GetTypeInfo(r.Syntax).Nullability.FlowState
                    == NullableFlowState.NotNull
                    );

                bool IsSymbolReferencedByOperation(IOperation operation) =>
                operation switch
                {
                    ILocalReferenceOperation localReference
                    => localReference.Local.Equals(symbol),
                    IParameterReferenceOperation parameterReference
                    => parameterReference.Parameter.Equals(symbol),
                    IAssignmentOperation assignment
                    => IsSymbolReferencedByOperation(assignment.Target),
                    _ => false
                };
            }
        }
        protected override async Task<SemanticDocument> ExpandAsync(SelectionResult selection, CancellationToken cancellationToken)
        {
            var lastExpression = selection.GetFirstTokenInSelection().GetCommonRoot(selection.GetLastTokenInSelection()).GetAncestors<ExpressionSyntax>().LastOrDefault();
            if (lastExpression == null)
            {
                return selection.SemanticDocument;
            }

            var newExpression = await Simplifier.ExpandAsync(lastExpression, selection.SemanticDocument.Document, n => n != selection.GetContainingScope(), expandParameter: false, cancellationToken: cancellationToken).ConfigureAwait(false);
            return await selection.SemanticDocument.WithSyntaxRootAsync(selection.SemanticDocument.Root.ReplaceNode(lastExpression, newExpression), cancellationToken).ConfigureAwait(false);
        }
            protected override ITypeSymbol GetSymbolType(SemanticModel semanticModel, ISymbol symbol)
            {
                var selectionOperation = semanticModel.GetOperation(SelectionResult.GetContainingScope());

                // Check if null is possibly assigned to the symbol. If it is, leave nullable annotation as is, otherwise
                // we can modify the annotation to be NotAnnotated to code that more likely matches the user's intent.
                if (selectionOperation is not null &&
                    NullableHelpers.IsSymbolAssignedPossiblyNullValue(semanticModel, selectionOperation, symbol) == false)
                {
                    return(base.GetSymbolType(semanticModel, symbol).WithNullableAnnotation(NullableAnnotation.NotAnnotated));
                }

                return(base.GetSymbolType(semanticModel, symbol));
            }