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); }
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); }