示例#1
0
                protected override ImmutableArray <StatementSyntax> GetInitialStatementsForMethodDefinitions()
                {
                    Contract.ThrowIfFalse(IsExtractMethodOnExpression(CSharpSelectionResult));

                    // special case for array initializer
                    var returnType      = AnalyzerResult.ReturnType;
                    var containingScope = CSharpSelectionResult.GetContainingScope();

                    ExpressionSyntax expression;

                    if (
                        returnType.TypeKind == TypeKind.Array &&
                        containingScope is InitializerExpressionSyntax
                        )
                    {
                        var typeSyntax = returnType.GenerateTypeSyntax();

                        expression = SyntaxFactory.ArrayCreationExpression(
                            typeSyntax as ArrayTypeSyntax,
                            containingScope as InitializerExpressionSyntax
                            );
                    }
                    else
                    {
                        expression = containingScope as ExpressionSyntax;
                    }

                    if (AnalyzerResult.HasReturnType)
                    {
                        return(ImmutableArray.Create <StatementSyntax>(
                                   SyntaxFactory.ReturnStatement(
                                       WrapInCheckedExpressionIfNeeded(expression)
                                       )
                                   ));
                    }
                    else
                    {
                        return(ImmutableArray.Create <StatementSyntax>(
                                   SyntaxFactory.ExpressionStatement(
                                       WrapInCheckedExpressionIfNeeded(expression)
                                       )
                                   ));
                    }
                }
                protected override SyntaxNode GetOutermostCallSiteContainerToProcess(
                    CancellationToken cancellationToken
                    )
                {
                    var callSiteContainer = GetCallSiteContainerFromOutermostMoveInVariable(
                        cancellationToken
                        );

                    if (callSiteContainer != null)
                    {
                        return(callSiteContainer);
                    }
                    else
                    {
                        var firstStatement =
                            CSharpSelectionResult.GetFirstStatementUnderContainer();
                        return(firstStatement.Parent);
                    }
                }
                protected override ImmutableArray <StatementSyntax> GetInitialStatementsForMethodDefinitions()
                {
                    var firstSeen = false;
                    var firstStatementUnderContainer =
                        CSharpSelectionResult.GetFirstStatementUnderContainer();
                    var lastStatementUnderContainer =
                        CSharpSelectionResult.GetLastStatementUnderContainer();

                    using var _ = ArrayBuilder <StatementSyntax> .GetInstance(out var list);

                    foreach (
                        var statement in GetStatementsFromContainer(
                            firstStatementUnderContainer.Parent
                            )
                        )
                    {
                        // reset first seen
                        if (!firstSeen)
                        {
                            firstSeen = statement == firstStatementUnderContainer;
                        }

                        // continue until we see the first statement
                        if (!firstSeen)
                        {
                            continue;
                        }

                        list.Add(statement);

                        // exit if we see last statement
                        if (statement == lastStatementUnderContainer)
                        {
                            break;
                        }
                    }

                    return(list.ToImmutable());
                }
                protected override SyntaxNode GetFirstStatementOrInitializerSelectedAtCallSite()
                {
                    var scope = (SyntaxNode)CSharpSelectionResult.GetContainingScopeOf <StatementSyntax>();

                    if (scope == null)
                    {
                        scope = CSharpSelectionResult.GetContainingScopeOf <FieldDeclarationSyntax>();
                    }

                    if (scope == null)
                    {
                        scope = CSharpSelectionResult.GetContainingScopeOf <ConstructorInitializerSyntax>();
                    }

                    if (scope == null)
                    {
                        // This is similar to FieldDeclaration case but we only want to do this
                        // if the member has an expression body.
                        scope = CSharpSelectionResult.GetContainingScopeOf <ArrowExpressionClauseSyntax>().Parent;
                    }

                    return(scope);
                }
示例#5
0
 public CSharpMethodExtractor(CSharpSelectionResult result) :
     base(result)
 {
 }
示例#6
0
 public CSharpMethodExtractor(CSharpSelectionResult result, bool localFunction)
     : base(result, localFunction)
 {
 }
示例#7
0
        public override async Task <SelectionResult> GetValidSelectionAsync(
            CancellationToken cancellationToken
            )
        {
            if (!ContainsValidSelection)
            {
                return(NullSelection);
            }

            var text  = SemanticDocument.Text;
            var root  = SemanticDocument.Root;
            var model = SemanticDocument.SemanticModel;
            var doc   = SemanticDocument;

            // go through pipe line and calculate information about the user selection
            var selectionInfo = GetInitialSelectionInfo(root, text);

            selectionInfo = AssignInitialFinalTokens(selectionInfo, root, cancellationToken);
            selectionInfo = AdjustFinalTokensBasedOnContext(
                selectionInfo,
                model,
                cancellationToken
                );
            selectionInfo = AssignFinalSpan(selectionInfo, text);
            selectionInfo = ApplySpecialCases(selectionInfo, text);
            selectionInfo = CheckErrorCasesAndAppendDescriptions(selectionInfo, root);

            // there was a fatal error that we couldn't even do negative preview, return error result
            if (selectionInfo.Status.FailedWithNoBestEffortSuggestion())
            {
                return(new ErrorSelectionResult(selectionInfo.Status));
            }

            var controlFlowSpan = GetControlFlowSpan(selectionInfo);

            if (!selectionInfo.SelectionInExpression)
            {
                var statementRange = GetStatementRangeContainedInSpan <StatementSyntax>(
                    root,
                    controlFlowSpan,
                    cancellationToken
                    );
                if (statementRange == null)
                {
                    selectionInfo = selectionInfo.WithStatus(
                        s =>
                        s.With(
                            OperationStatusFlag.None,
                            CSharpFeaturesResources.Can_t_determine_valid_range_of_statements_to_extract
                            )
                        );
                    return(new ErrorSelectionResult(selectionInfo.Status));
                }

                var isFinalSpanSemanticallyValid = IsFinalSpanSemanticallyValidSpan(
                    model,
                    controlFlowSpan,
                    statementRange,
                    cancellationToken
                    );
                if (!isFinalSpanSemanticallyValid)
                {
                    // check control flow only if we are extracting statement level, not expression
                    // level. you can not have goto that moves control out of scope in expression level
                    // (even in lambda)
                    selectionInfo = selectionInfo.WithStatus(
                        s =>
                        s.With(
                            OperationStatusFlag.BestEffort,
                            CSharpFeaturesResources.Not_all_code_paths_return
                            )
                        );
                }
            }

            return(await CSharpSelectionResult
                   .CreateAsync(
                       selectionInfo.Status,
                       selectionInfo.OriginalSpan,
                       selectionInfo.FinalSpan,
                       Options,
                       selectionInfo.SelectionInExpression,
                       doc,
                       selectionInfo.FirstTokenInFinalSpan,
                       selectionInfo.LastTokenInFinalSpan,
                       cancellationToken
                       )
                   .ConfigureAwait(false));
        }
示例#8
0
 protected override SyntaxNode GetLastStatementOrInitializerSelectedAtCallSite()
 {
     return(CSharpSelectionResult.GetLastStatementUnderContainer());
 }
示例#9
0
 public CSharpMethodExtractor(CSharpSelectionResult result) :
     base(result)
 {
 }
 protected override SyntaxNode GetFirstStatementOrInitializerSelectedAtCallSite()
 => CSharpSelectionResult.GetFirstStatementUnderContainer();
 protected override SyntaxNode GetLastStatementOrInitializerSelectedAtCallSite()
 {
     // it is a single statement case. either first statement is same as last statement or
     // last statement belongs (embedded statement) to the first statement.
     return(CSharpSelectionResult.GetFirstStatement());
 }
                protected override ImmutableArray <StatementSyntax> GetInitialStatementsForMethodDefinitions()
                {
                    Contract.ThrowIfFalse(IsExtractMethodOnSingleStatement(CSharpSelectionResult));

                    return(ImmutableArray.Create(CSharpSelectionResult.GetFirstStatement()));
                }
 public CSharpMethodExtractor(CSharpSelectionResult result, ExtractMethodGenerationOptions options, bool localFunction)
     : base(result, options, localFunction)
 {
 }
示例#14
0
        public override async Task <SelectionResult> GetValidSelectionAsync(CancellationToken cancellationToken)
        {
            if (!this.ContainsValidSelection)
            {
                return(NullSelection);
            }

            var text  = this.SemanticDocument.Text;
            var root  = this.SemanticDocument.Root;
            var model = this.SemanticDocument.SemanticModel;
            var doc   = this.SemanticDocument;

            // go through pipe line and calculate information about the user selection
            var selectionInfo = GetInitialSelectionInfo(root, text, cancellationToken);

            selectionInfo = AssignInitialFinalTokens(selectionInfo, root, cancellationToken);
            selectionInfo = AdjustFinalTokensBasedOnContext(selectionInfo, model, cancellationToken);
            selectionInfo = AssignFinalSpan(selectionInfo, text, cancellationToken);
            selectionInfo = ApplySpecialCases(selectionInfo, text, cancellationToken);
            selectionInfo = CheckErrorCasesAndAppendDescriptions(selectionInfo, root, model, cancellationToken);

            // there was a fatal error that we couldn't even do negative preview, return error result
            if (selectionInfo.Status.FailedWithNoBestEffortSuggestion())
            {
                return(new ErrorSelectionResult(selectionInfo.Status));
            }

            var controlFlowSpan = GetControlFlowSpan(selectionInfo);

            if (!selectionInfo.SelectionInExpression)
            {
                var statementRange = GetStatementRangeContainedInSpan <StatementSyntax>(root, controlFlowSpan, cancellationToken);
                if (statementRange == null)
                {
                    selectionInfo = selectionInfo.WithStatus(s => s.With(OperationStatusFlag.None, CSharpFeaturesResources.Can_t_determine_valid_range_of_statements_to_extract));
                    return(new ErrorSelectionResult(selectionInfo.Status));
                }

                var isFinalSpanSemanticallyValid = IsFinalSpanSemanticallyValidSpan(model, controlFlowSpan, statementRange, cancellationToken);
                if (!isFinalSpanSemanticallyValid)
                {
                    // check control flow only if we are extracting statement level, not expression
                    // level. you can not have goto that moves control out of scope in expression level
                    // (even in lambda)
                    selectionInfo = selectionInfo.WithStatus(s => s.With(OperationStatusFlag.BestEffort, CSharpFeaturesResources.Not_all_code_paths_return));
                }
            }

            // Warn if local functions are in selection since data flow analysis
            // cannot correctly analyze them
            // https://github.com/dotnet/roslyn/issues/14214
            if (SpanInvolvesLocalFunction(selectionInfo.FinalSpan, model, root))
            {
                selectionInfo = selectionInfo.WithStatus(s => s.With(
                                                             OperationStatusFlag.Succeeded | OperationStatusFlag.BestEffort,
                                                             CSharpFeaturesResources.Warning_Extracting_a_local_function_reference_may_produce_invalid_code));
                var commonRoot = selectionInfo.CommonRootFromOriginalSpan;
                var annotated  = commonRoot.WithAdditionalAnnotations(
                    WarningAnnotation.Create(CSharpFeaturesResources.Warning_Extracting_a_local_function_reference_may_produce_invalid_code));
                doc = await doc.WithSyntaxRootAsync(
                    root.ReplaceNode(commonRoot, annotated),
                    cancellationToken).ConfigureAwait(false);

                selectionInfo.FirstTokenInOriginalSpan = doc.Root.FindToken(selectionInfo.FirstTokenInOriginalSpan.SpanStart);
                selectionInfo.LastTokenInOriginalSpan  = doc.Root.FindToken(selectionInfo.LastTokenInOriginalSpan.SpanStart);
                selectionInfo.FirstTokenInFinalSpan    = doc.Root.FindToken(selectionInfo.FirstTokenInFinalSpan.SpanStart);
                selectionInfo.LastTokenInFinalSpan     = doc.Root.FindToken(selectionInfo.LastTokenInFinalSpan.SpanStart);
            }

            return(await CSharpSelectionResult.CreateAsync(
                       selectionInfo.Status,
                       selectionInfo.OriginalSpan,
                       selectionInfo.FinalSpan,
                       this.Options,
                       selectionInfo.SelectionInExpression,
                       doc,
                       selectionInfo.FirstTokenInFinalSpan,
                       selectionInfo.LastTokenInFinalSpan,
                       cancellationToken).ConfigureAwait(false));
        }
                protected override IEnumerable <StatementSyntax> GetInitialStatementsForMethodDefinitions()
                {
                    Contract.ThrowIfFalse(IsExtractMethodOnSingleStatement(CSharpSelectionResult));

                    return(SpecializedCollections.SingletonEnumerable <StatementSyntax>(CSharpSelectionResult.GetFirstStatement()));
                }
 protected override SyntaxNode GetFirstStatementOrInitializerSelectedAtCallSite()
 {
     return(CSharpSelectionResult.GetFirstStatement());
 }