private async Task <bool> TryInitializeAsync(
                SemanticDocument document,
                TextSpan textSpan,
                CancellationToken cancellationToken)
            {
                if (cancellationToken.IsCancellationRequested)
                {
                    return(false);
                }

                Expression = await document.Document.TryGetRelevantNodeAsync <TExpressionSyntax>(textSpan, cancellationToken).ConfigureAwait(false);

                if (Expression == null || CodeRefactoringHelpers.IsNodeUnderselected(Expression, textSpan))
                {
                    return(false);
                }

                var expressionType = Document.SemanticModel.GetTypeInfo(Expression, cancellationToken).Type;

                if (expressionType is IErrorTypeSymbol)
                {
                    return(false);
                }

                var containingType = Expression.AncestorsAndSelf()
                                     .Select(n => Document.SemanticModel.GetDeclaredSymbol(n, cancellationToken))
                                     .OfType <INamedTypeSymbol>()
                                     .FirstOrDefault();

                containingType ??= Document.SemanticModel.Compilation.ScriptClass;

                if (containingType == null || containingType.TypeKind == TypeKind.Interface)
                {
                    return(false);
                }

                if (!CanIntroduceVariable(textSpan.IsEmpty, cancellationToken))
                {
                    return(false);
                }

                IsConstant = IsExpressionConstant(Document, Expression, _service, cancellationToken);

                // Note: the ordering of these clauses are important.  They go, generally, from
                // innermost to outermost order.
                if (IsInQueryContext(cancellationToken))
                {
                    if (CanGenerateInto <TQueryExpressionSyntax>(cancellationToken))
                    {
                        InQueryContext = true;
                        return(true);
                    }

                    return(false);
                }

                if (IsInConstructorInitializerContext(cancellationToken))
                {
                    if (CanGenerateInto <TTypeDeclarationSyntax>(cancellationToken))
                    {
                        InConstructorInitializerContext = true;
                        return(true);
                    }

                    return(false);
                }

                var enclosingBlocks = _service.GetContainingExecutableBlocks(Expression);

                if (enclosingBlocks.Any())
                {
                    // If we're inside a block, then don't even try the other options (like field,
                    // constructor initializer, etc.).  This is desirable behavior.  If we're in a
                    // block in a field, then we're in a lambda, and we want to offer to generate
                    // a local, and not a field.
                    if (IsInBlockContext(cancellationToken))
                    {
                        InBlockContext = true;
                        return(true);
                    }

                    return(false);
                }

                /* NOTE: All checks from this point forward are intentionally ordered to be AFTER the check for Block Context. */

                // If we are inside a block within an Expression bodied member we should generate inside the block,
                // instead of rewriting a concise expression bodied member to its equivalent that has a body with a block.
                if (_service.IsInExpressionBodiedMember(Expression))
                {
                    if (CanGenerateInto <TTypeDeclarationSyntax>(cancellationToken))
                    {
                        InExpressionBodiedMemberContext = true;
                        return(true);
                    }

                    return(false);
                }

                if (_service.IsInAutoPropertyInitializer(Expression))
                {
                    if (CanGenerateInto <TTypeDeclarationSyntax>(cancellationToken))
                    {
                        InAutoPropertyInitializerContext = true;
                        return(true);
                    }

                    return(false);
                }

                if (CanGenerateInto <TTypeDeclarationSyntax>(cancellationToken))
                {
                    if (IsInParameterContext(cancellationToken))
                    {
                        InParameterContext = true;
                        return(true);
                    }
                    else if (IsInFieldContext(cancellationToken))
                    {
                        InFieldContext = true;
                        return(true);
                    }
                    else if (IsInAttributeContext())
                    {
                        InAttributeContext = true;
                        return(true);
                    }
                }

                return(false);
            private bool TryInitialize(
                TextSpan textSpan,
                CancellationToken cancellationToken)
            {
                if (cancellationToken.IsCancellationRequested)
                {
                    return(false);
                }

                var tree        = this.Document.SyntaxTree;
                var syntaxFacts = this.Document.Project.LanguageServices.GetService <ISyntaxFactsService>();

                this.Expression = this.GetExpressionUnderSpan(tree, textSpan, cancellationToken);
                if (this.Expression == null)
                {
                    return(false);
                }

                var containingType = this.Expression.AncestorsAndSelf()
                                     .Select(n => this.Document.SemanticModel.GetDeclaredSymbol(n, cancellationToken))
                                     .OfType <INamedTypeSymbol>()
                                     .FirstOrDefault();

                containingType = containingType ?? this.Document.SemanticModel.Compilation.ScriptClass;

                if (containingType == null || containingType.TypeKind == TypeKind.Interface)
                {
                    return(false);
                }

                if (!CanIntroduceVariable(cancellationToken))
                {
                    return(false);
                }

                this.IsConstant = this.Document.SemanticModel.GetConstantValue(this.Expression).HasValue;

                // Note: the ordering of these clauses are important.  They go, generally, from
                // innermost to outermost order.
                if (IsInQueryContext(cancellationToken))
                {
                    if (CanGenerateInto <TQueryExpressionSyntax>(cancellationToken))
                    {
                        this.InQueryContext = true;
                        return(true);
                    }

                    return(false);
                }

                if (IsInConstructorInitializerContext(cancellationToken))
                {
                    if (CanGenerateInto <TTypeDeclarationSyntax>(cancellationToken))
                    {
                        this.InConstructorInitializerContext = true;
                        return(true);
                    }

                    return(false);
                }

                var enclosingBlocks = service.GetContainingExecutableBlocks(this.Expression);

                if (enclosingBlocks.Any())
                {
                    // If we're inside a block, then don't even try the other options (like field,
                    // constructor initializer, etc.).  This is desirable behavior.  If we're in a
                    // block in a field, then we're in a lambda, and we want to offer to generate
                    // a local, and not a field.
                    if (IsInBlockContext(cancellationToken))
                    {
                        this.InBlockContext = true;
                        return(true);
                    }

                    return(false);
                }

                if (CanGenerateInto <TTypeDeclarationSyntax>(cancellationToken))
                {
                    if (IsInParameterContext(cancellationToken))
                    {
                        this.InParameterContext = true;
                        return(true);
                    }
                    else if (IsInFieldContext(cancellationToken))
                    {
                        this.InFieldContext = true;
                        return(true);
                    }
                    else if (IsInAttributeContext(cancellationToken))
                    {
                        this.InAttributeContext = true;
                        return(true);
                    }
                }

                return(false);
            }
            private bool TryInitialize(
                TextSpan textSpan,
                CancellationToken cancellationToken)
            {
                if (cancellationToken.IsCancellationRequested)
                {
                    return(false);
                }

                var tree        = this.Document.SyntaxTree;
                var syntaxFacts = this.Document.Project.LanguageServices.GetService <ISyntaxFactsService>();

                this.Expression = this.GetExpressionUnderSpan(tree, textSpan, cancellationToken);
                if (this.Expression == null)
                {
                    return(false);
                }

                var expressionType = this.Document.SemanticModel.GetTypeInfo(this.Expression, cancellationToken).Type;

                if (expressionType is IErrorTypeSymbol)
                {
                    return(false);
                }

                var containingType = this.Expression.AncestorsAndSelf()
                                     .Select(n => this.Document.SemanticModel.GetDeclaredSymbol(n, cancellationToken))
                                     .OfType <INamedTypeSymbol>()
                                     .FirstOrDefault();

                containingType = containingType ?? this.Document.SemanticModel.Compilation.ScriptClass;

                if (containingType == null || containingType.TypeKind == TypeKind.Interface)
                {
                    return(false);
                }

                if (!CanIntroduceVariable(textSpan.IsEmpty, cancellationToken))
                {
                    return(false);
                }

                this.IsConstant = this.Document.SemanticModel.GetConstantValue(this.Expression, cancellationToken).HasValue;

                // Note: the ordering of these clauses are important.  They go, generally, from
                // innermost to outermost order.
                if (IsInQueryContext(cancellationToken))
                {
                    if (CanGenerateInto <TQueryExpressionSyntax>(cancellationToken))
                    {
                        this.InQueryContext = true;
                        return(true);
                    }

                    return(false);
                }

                if (IsInConstructorInitializerContext(cancellationToken))
                {
                    if (CanGenerateInto <TTypeDeclarationSyntax>(cancellationToken))
                    {
                        this.InConstructorInitializerContext = true;
                        return(true);
                    }

                    return(false);
                }

                var enclosingBlocks = _service.GetContainingExecutableBlocks(this.Expression);

                if (enclosingBlocks.Any())
                {
                    // If we're inside a block, then don't even try the other options (like field,
                    // constructor initializer, etc.).  This is desirable behavior.  If we're in a
                    // block in a field, then we're in a lambda, and we want to offer to generate
                    // a local, and not a field.
                    if (IsInBlockContext(cancellationToken))
                    {
                        this.InBlockContext = true;
                        return(true);
                    }

                    return(false);
                }

                /* NOTE: All checks from this point forward are intentionally ordered to be AFTER the check for Block Context. */

                // If we are inside a block within an Expression bodied member we should generate inside the block,
                // instead of rewriting a concise expression bodied member to its equivalent that has a body with a block.
                if (_service.IsInExpressionBodiedMember(this.Expression))
                {
                    if (CanGenerateInto <TTypeDeclarationSyntax>(cancellationToken))
                    {
                        this.InExpressionBodiedMemberContext = true;
                        return(true);
                    }

                    return(false);
                }

                if (_service.IsInAutoPropertyInitializer(this.Expression))
                {
                    if (CanGenerateInto <TTypeDeclarationSyntax>(cancellationToken))
                    {
                        this.InAutoPropertyInitializerContext = true;
                        return(true);
                    }

                    return(false);
                }

                if (CanGenerateInto <TTypeDeclarationSyntax>(cancellationToken))
                {
                    if (IsInParameterContext(cancellationToken))
                    {
                        this.InParameterContext = true;
                        return(true);
                    }
                    else if (IsInFieldContext(cancellationToken))
                    {
                        this.InFieldContext = true;
                        return(true);
                    }
                    else if (IsInAttributeContext(cancellationToken))
                    {
                        this.InAttributeContext = true;
                        return(true);
                    }
                }

                return(false);
            }
Esempio n. 4
0
            private bool TryInitialize(
                TextSpan textSpan,
                CancellationToken cancellationToken)
            {
                if (cancellationToken.IsCancellationRequested)
                {
                    return(false);
                }

                var tree = this.Document.SyntaxTree;

                this.Expression = this.GetExpressionUnderSpan(tree, textSpan, cancellationToken);
                if (this.Expression == null)
                {
                    return(false);
                }

                var containingType = this.Expression.AncestorsAndSelf()
                                     .Select(n => this.Document.SemanticModel.GetDeclaredSymbol(n, cancellationToken))
                                     .OfType <INamedTypeSymbol>()
                                     .FirstOrDefault();

                containingType = containingType ?? this.Document.SemanticModel.Compilation.ScriptClass;

                if (containingType == null || containingType.TypeKind == TypeKind.Interface)
                {
                    return(false);
                }

                if (!CanIntroduceVariable(cancellationToken))
                {
                    return(false);
                }

                this.IsConstant = this.Document.SemanticModel.GetConstantValue(this.Expression, cancellationToken).HasValue;

                // Note: the ordering of these clauses are important.  They go, generally, from
                // innermost to outermost order.
                if (IsInQueryContext(cancellationToken))
                {
                    if (CanGenerateInto <TQueryExpressionSyntax>(cancellationToken))
                    {
                        this.InQueryContext = true;
                        return(true);
                    }

                    return(false);
                }

                if (IsInConstructorInitializerContext(cancellationToken))
                {
                    if (CanGenerateInto <TTypeDeclarationSyntax>(cancellationToken))
                    {
                        this.InConstructorInitializerContext = true;
                        return(true);
                    }

                    return(false);
                }

                var enclosingBlocks = _service.GetContainingExecutableBlocks(this.Expression);

                if (enclosingBlocks.Any())
                {
                    // If we're inside a block, then don't even try the other options (like field,
                    // constructor initializer, etc.).  This is desirable behavior.  If we're in a
                    // block in a field, then we're in a lambda, and we want to offer to generate
                    // a local, and not a field.
                    if (IsInBlockContext(cancellationToken))
                    {
                        this.InBlockContext = true;
                        return(true);
                    }

                    return(false);
                }

                // The ordering of checks is important here. If we are inside a block within an Expression
                // bodied member, we should treat it as if we are in block context.
                // For example, in such a scenario we should generate inside the block, instead of rewriting
                // a concise expression bodied member to its equivalent that has a body with a block.
                // For this reason, block should precede expression bodied member check.
                if (_service.IsInExpressionBodiedMember(this.Expression))
                {
                    if (CanGenerateInto <TTypeDeclarationSyntax>(cancellationToken))
                    {
                        this.InExpressionBodiedMemberContext = true;
                        return(true);
                    }

                    return(false);
                }

                if (CanGenerateInto <TTypeDeclarationSyntax>(cancellationToken))
                {
                    if (IsInParameterContext(cancellationToken))
                    {
                        this.InParameterContext = true;
                        return(true);
                    }
                    else if (IsInFieldContext(cancellationToken))
                    {
                        this.InFieldContext = true;
                        return(true);
                    }
                    else if (IsInAttributeContext(cancellationToken))
                    {
                        this.InAttributeContext = true;
                        return(true);
                    }
                }

                return(false);
            }