private static void ChangeType( RefactoringContext context, VariableDeclarationSyntax variableDeclaration, ITypeSymbol typeSymbol, SemanticModel semanticModel, CancellationToken cancellationToken) { TypeSyntax type = variableDeclaration.Type; if (variableDeclaration.Variables.SingleOrDefault(shouldThrow: false)?.Initializer?.Value != null && typeSymbol.OriginalDefinition.EqualsOrInheritsFromTaskOfT(semanticModel)) { ISymbol enclosingSymbol = semanticModel.GetEnclosingSymbol(variableDeclaration.SpanStart, cancellationToken); if (enclosingSymbol.IsAsyncMethod()) { ITypeSymbol typeArgument = ((INamedTypeSymbol)typeSymbol).TypeArguments[0]; context.RegisterRefactoring( $"Change type to '{SymbolDisplay.ToMinimalDisplayString(typeArgument, semanticModel, type.SpanStart, SymbolDisplayFormats.Default)}' and insert 'await'", c => ChangeTypeAndAddAwaitAsync(context.Document, variableDeclaration, typeArgument, c), RefactoringIdentifiers.ChangeVarToExplicitType); } } context.RegisterRefactoring( $"Change type to '{SymbolDisplay.ToMinimalDisplayString(typeSymbol, semanticModel, type.SpanStart, SymbolDisplayFormats.Default)}'", c => ChangeTypeRefactoring.ChangeTypeAsync(context.Document, type, typeSymbol, c), RefactoringIdentifiers.ChangeVarToExplicitType); }
internal static async Task ChangeTypeAccordingToExpressionAsync( RefactoringContext context, ForEachStatementSyntax forEachStatement) { TypeSyntax type = forEachStatement.Type; if (type?.IsVar == false && type.Span.Contains(context.Span)) { SemanticModel semanticModel = await context.GetSemanticModelAsync().ConfigureAwait(false); ForEachStatementInfo info = semanticModel.GetForEachStatementInfo(forEachStatement); if (info.ElementType != null) { ITypeSymbol typeSymbol = semanticModel.GetTypeInfo(type).ConvertedType; if (!info.ElementType.Equals(typeSymbol)) { context.RegisterRefactoring( $"Change type to '{SymbolDisplay.GetMinimalString(info.ElementType, semanticModel, type.SpanStart)}'", cancellationToken => { return(ChangeTypeRefactoring.ChangeTypeAsync( context.Document, type, info.ElementType, cancellationToken)); }); } } } }
internal static async Task ChangeTypeAccordingToExpressionAsync( RefactoringContext context, ForEachStatementSyntax forEachStatement) { TypeSyntax type = forEachStatement.Type; if (type?.IsVar == false && type.Span.Contains(context.Span)) { SemanticModel semanticModel = await context.GetSemanticModelAsync().ConfigureAwait(false); ITypeSymbol elementType = semanticModel.GetForEachStatementInfo(forEachStatement).ElementType; if (elementType?.IsErrorType() == false) { ITypeSymbol typeSymbol = semanticModel.GetTypeInfo(type).ConvertedType; if (!elementType.Equals(typeSymbol)) { if (elementType.SupportsExplicitDeclaration()) { context.RegisterRefactoring( $"Change type to '{SymbolDisplay.GetMinimalString(elementType, semanticModel, type.SpanStart)}'", cancellationToken => ChangeTypeRefactoring.ChangeTypeAsync(context.Document, type, elementType, cancellationToken)); } else { context.RegisterRefactoring( "Change type to 'var'", cancellationToken => ChangeTypeRefactoring.ChangeTypeToVarAsync(context.Document, type, cancellationToken)); } } } } }
public static async Task ComputeRefactoringAsync(RefactoringContext context, MethodDeclarationSyntax methodDeclaration) { if (context.IsRefactoringEnabled(RefactoringIdentifiers.ChangeMethodReturnTypeToVoid) && methodDeclaration.ReturnType?.IsVoid() == false && methodDeclaration.Body?.Statements.Count > 0 && !methodDeclaration.IsIterator() && context.SupportsSemanticModel) { SemanticModel semanticModel = await context.GetSemanticModelAsync().ConfigureAwait(false); if (!IsAsyncMethodThatReturnsTask(methodDeclaration, semanticModel, context.CancellationToken)) { ControlFlowAnalysis analysis = semanticModel.AnalyzeControlFlow(methodDeclaration.Body); if (analysis.Succeeded && analysis.ReturnStatements.All(node => IsReturnStatementWithoutExpression(node))) { context.RegisterRefactoring( "Change return type to 'void'", cancellationToken => { return(ChangeTypeRefactoring.ChangeTypeAsync( context.Document, methodDeclaration.ReturnType, CSharpFactory.VoidType(), cancellationToken)); }); } } } }
internal static async Task ChangeTypeAsync( RefactoringContext context, ForEachStatementSyntax forEachStatement) { TypeSyntax type = forEachStatement.Type; if (type?.Span.Contains(context.Span) != true) { return; } SemanticModel semanticModel = await context.GetSemanticModelAsync().ConfigureAwait(false); TypeAnalysis analysis = TypeAnalysis.AnalyzeType(forEachStatement, semanticModel); if (analysis.IsExplicit) { if (analysis.SupportsImplicit && context.IsRefactoringEnabled(RefactoringIdentifiers.ChangeExplicitTypeToVar)) { context.RegisterRefactoring( "Change type to 'var'", cancellationToken => ChangeTypeRefactoring.ChangeTypeToVarAsync(context.Document, type, cancellationToken)); } } else if (analysis.SupportsExplicit && context.IsRefactoringEnabled(RefactoringIdentifiers.ChangeVarToExplicitType)) { ITypeSymbol typeSymbol = semanticModel.GetTypeSymbol(type, context.CancellationToken); context.RegisterRefactoring( $"Change type to '{SymbolDisplay.ToMinimalDisplayString(typeSymbol, semanticModel, type.SpanStart, SymbolDisplayFormats.Default)}'", cancellationToken => ChangeTypeRefactoring.ChangeTypeAsync(context.Document, type, typeSymbol, cancellationToken)); } }
private static void ChangeType( RefactoringContext context, VariableDeclarationSyntax variableDeclaration, ITypeSymbol typeSymbol, SemanticModel semanticModel, CancellationToken cancellationToken) { TypeSyntax type = variableDeclaration.Type; if (variableDeclaration.Variables.SingleOrDefault(shouldthrow: false)?.Initializer?.Value != null && typeSymbol.IsConstructedFromTaskOfT(semanticModel)) { ISymbol enclosingSymbol = semanticModel.GetEnclosingSymbol(variableDeclaration.SpanStart, cancellationToken); if (enclosingSymbol.IsAsyncMethod()) { ITypeSymbol typeArgument = ((INamedTypeSymbol)typeSymbol).TypeArguments[0]; context.RegisterRefactoring( $"Change type to '{SymbolDisplay.GetMinimalString(typeArgument, semanticModel, type.SpanStart)}' and insert 'await'", c => ChangeTypeAndAddAwaitAsync(context.Document, variableDeclaration, typeArgument, c)); } } context.RegisterRefactoring( $"Change type to '{SymbolDisplay.GetMinimalString(typeSymbol, semanticModel, type.Span.Start)}'", c => ChangeTypeRefactoring.ChangeTypeAsync(context.Document, type, typeSymbol, c)); }
private static async Task ChangeTypeAsync( RefactoringContext context, VariableDeclarationSyntax variableDeclaration) { SemanticModel semanticModel = await context.GetSemanticModelAsync().ConfigureAwait(false); TypeAnalysisFlags flags = CSharpAnalysis.AnalyzeType(variableDeclaration, semanticModel, context.CancellationToken); if (flags.IsExplicit()) { if (flags.SupportsImplicit() && flags.IsValidSymbol() && context.IsRefactoringEnabled(RefactoringIdentifiers.ChangeExplicitTypeToVar)) { context.RegisterRefactoring( "Change type to 'var'", cancellationToken => { return(ChangeTypeRefactoring.ChangeTypeToVarAsync( context.Document, variableDeclaration.Type, cancellationToken)); }); } } else if (flags.SupportsExplicit() && flags.IsValidSymbol() && context.IsRefactoringEnabled(RefactoringIdentifiers.ChangeVarToExplicitType)) { ITypeSymbol typeSymbol = semanticModel.GetTypeSymbol(variableDeclaration.Type, context.CancellationToken); ChangeType(context, variableDeclaration, typeSymbol, semanticModel, context.CancellationToken); } }
public static async Task ComputeRefactoringsAsync( RefactoringContext context, DeclarationExpressionSyntax declarationExpression) { if (declarationExpression.Type?.Span.Contains(context.Span) == true && context.IsAnyRefactoringEnabled( RefactoringIdentifiers.ChangeExplicitTypeToVar, RefactoringIdentifiers.ChangeVarToExplicitType)) { SemanticModel semanticModel = await context.GetSemanticModelAsync().ConfigureAwait(false); switch (CSharpAnalysis.AnalyzeType( declarationExpression, semanticModel, context.CancellationToken)) { case TypeAnalysisResult.Explicit: case TypeAnalysisResult.ExplicitButShouldBeImplicit: { if (context.IsRefactoringEnabled(RefactoringIdentifiers.ChangeExplicitTypeToVar)) { context.RegisterRefactoring( "Change type to 'var'", cancellationToken => { return(ChangeTypeRefactoring.ChangeTypeToVarAsync( context.Document, declarationExpression.Type, cancellationToken)); }); } break; } case TypeAnalysisResult.Implicit: case TypeAnalysisResult.ImplicitButShouldBeExplicit: { if (context.IsRefactoringEnabled(RefactoringIdentifiers.ChangeVarToExplicitType)) { TypeSyntax type = declarationExpression.Type; var localSymbol = semanticModel.GetDeclaredSymbol(declarationExpression.Designation, context.CancellationToken) as ILocalSymbol; ITypeSymbol typeSymbol = localSymbol.Type; context.RegisterRefactoring( $"Change type to '{SymbolDisplay.GetMinimalDisplayString(typeSymbol, type.Span.Start, semanticModel)}'", cancellationToken => ChangeTypeRefactoring.ChangeTypeAsync(context.Document, type, typeSymbol, cancellationToken)); } break; } } } }
private static void RegisterChangeType(RefactoringContext context, MemberDeclarationSyntax member, TypeSyntax type, ITypeSymbol newType) { context.RegisterRefactoring( $"Change {GetText(member)} type to '{newType.ToDisplayString(SyntaxUtility.DefaultSymbolDisplayFormat)}'", cancellationToken => { return(ChangeTypeRefactoring.ChangeTypeAsync( context.Document, type, newType, cancellationToken)); }); }
private static void RegisterChangeType(RefactoringContext context, MemberDeclarationSyntax member, TypeSyntax type, ITypeSymbol newType, SemanticModel semanticModel) { context.RegisterRefactoring( $"Change {GetText(member)} type to '{SymbolDisplay.GetMinimalString(newType, semanticModel, type.Span.Start)}'", cancellationToken => { return(ChangeTypeRefactoring.ChangeTypeAsync( context.Document, type, newType, cancellationToken)); }); }
public static async Task ComputeRefactoringAsync(RefactoringContext context, MethodDeclarationSyntax methodDeclaration) { if (context.IsRefactoringEnabled(RefactoringIdentifiers.ChangeMethodReturnTypeToVoid)) { TypeSyntax returnType = methodDeclaration.ReturnType; if (returnType?.IsVoid() == false) { BlockSyntax body = methodDeclaration.Body; if (body != null) { SyntaxList <StatementSyntax> statements = body.Statements; if (statements.Any() && !ContainsOnlyThrowStatement(statements) && !methodDeclaration.ContainsYield()) { SemanticModel semanticModel = await context.GetSemanticModelAsync().ConfigureAwait(false); IMethodSymbol methodSymbol = semanticModel.GetDeclaredSymbol(methodDeclaration, context.CancellationToken); if (methodSymbol?.IsOverride == false && !methodSymbol.ImplementsInterfaceMember() && !IsAsyncMethodThatReturnsTask(methodSymbol, semanticModel)) { ControlFlowAnalysis analysis = semanticModel.AnalyzeControlFlow(body); if (analysis.Succeeded && analysis.ReturnStatements.All(IsReturnStatementWithoutExpression)) { context.RegisterRefactoring( "Change return type to 'void'", cancellationToken => { return(ChangeTypeRefactoring.ChangeTypeAsync( context.Document, returnType, CSharpFactory.VoidType(), cancellationToken)); }); } } } } } } }
public static async Task ComputeRefactoringsAsync( RefactoringContext context, DeclarationExpressionSyntax declarationExpression) { if (declarationExpression.Type?.Span.Contains(context.Span) == true && context.IsAnyRefactoringEnabled( RefactoringIdentifiers.ChangeExplicitTypeToVar, RefactoringIdentifiers.ChangeVarToExplicitType)) { SemanticModel semanticModel = await context.GetSemanticModelAsync().ConfigureAwait(false); TypeAnalysis analysis = CSharpTypeAnalysis.AnalyzeType(declarationExpression, semanticModel, context.CancellationToken); if (analysis.IsExplicit) { if (analysis.SupportsImplicit && context.IsRefactoringEnabled(RefactoringIdentifiers.ChangeExplicitTypeToVar)) { context.RegisterRefactoring( "Change type to 'var'", cancellationToken => { return(ChangeTypeRefactoring.ChangeTypeToVarAsync( context.Document, declarationExpression.Type, cancellationToken)); }, RefactoringIdentifiers.ChangeExplicitTypeToVar); } } else if (analysis.SupportsExplicit && context.IsRefactoringEnabled(RefactoringIdentifiers.ChangeVarToExplicitType)) { TypeSyntax type = declarationExpression.Type; var localSymbol = semanticModel.GetDeclaredSymbol(declarationExpression.Designation, context.CancellationToken) as ILocalSymbol; ITypeSymbol typeSymbol = localSymbol.Type; context.RegisterRefactoring( $"Change type to '{SymbolDisplay.ToMinimalDisplayString(typeSymbol, semanticModel, type.SpanStart, SymbolDisplayFormats.Default)}'", cancellationToken => ChangeTypeRefactoring.ChangeTypeAsync(context.Document, type, typeSymbol, cancellationToken), RefactoringIdentifiers.ChangeVarToExplicitType); } } }
private static void ChangeType( RefactoringContext context, VariableDeclarationSyntax variableDeclaration, ITypeSymbol typeSymbol, SemanticModel semanticModel, CancellationToken cancellationToken) { TypeSyntax type = variableDeclaration.Type; if (variableDeclaration.Variables.Count == 1 && variableDeclaration.Variables[0].Initializer?.Value != null && typeSymbol.IsNamedType()) { INamedTypeSymbol taskOfT = semanticModel.Compilation.GetTypeByMetadataName("System.Threading.Tasks.Task`1"); if (((INamedTypeSymbol)typeSymbol).ConstructedFrom.Equals(taskOfT) && AsyncAnalysis.IsPartOfAsyncBlock(variableDeclaration, semanticModel, cancellationToken)) { ITypeSymbol typeArgumentType = ((INamedTypeSymbol)typeSymbol).TypeArguments[0]; context.RegisterRefactoring( $"Change type to '{typeArgumentType.ToDisplayString(SyntaxUtility.DefaultSymbolDisplayFormat)}' and insert 'await'", c => { return(ChangeTypeAndAddAwaitAsync( context.Document, variableDeclaration, typeArgumentType, c)); }); } } context.RegisterRefactoring( $"Change type to '{typeSymbol.ToDisplayString(SyntaxUtility.DefaultSymbolDisplayFormat)}'", c => { return(ChangeTypeRefactoring.ChangeTypeAsync( context.Document, type, typeSymbol, c)); }); }
private static void ComputeRefactoring( RefactoringContext context, IMethodSymbol methodSymbol, SemanticModel semanticModel, BlockSyntax body, TypeSyntax returnType) { if (methodSymbol?.IsOverride != false) { return; } if (methodSymbol.ImplementsInterfaceMember()) { return; } if (methodSymbol.IsAsync && methodSymbol.ReturnType.HasMetadataName(MetadataNames.System_Threading_Tasks_Task)) { return; } ControlFlowAnalysis analysis = semanticModel.AnalyzeControlFlow(body); if (!analysis.Succeeded) { return; } if (!analysis.ReturnStatements.All(f => (f as ReturnStatementSyntax)?.Expression == null)) { return; } context.RegisterRefactoring( "Change return type to 'void'", ct => ChangeTypeRefactoring.ChangeTypeAsync(context.Document, returnType, CSharpFactory.VoidType(), ct), RefactoringIdentifiers.ChangeMethodReturnTypeToVoid); }
internal static async Task ChangeTypeAsync( RefactoringContext context, ForEachStatementSyntax forEachStatement) { TypeSyntax type = forEachStatement.Type; if (type?.Span.Contains(context.Span) != true) { return; } SemanticModel semanticModel = await context.GetSemanticModelAsync().ConfigureAwait(false); TypeAnalysisResult result = ForEachStatementAnalysis.AnalyzeType( forEachStatement, semanticModel, context.CancellationToken); if (result == TypeAnalysisResult.Explicit) { if (context.IsRefactoringEnabled(RefactoringIdentifiers.ChangeExplicitTypeToVar)) { context.RegisterRefactoring( "Change type to 'var'", cancellationToken => ChangeTypeRefactoring.ChangeTypeToVarAsync(context.Document, type, cancellationToken)); } } else if (result == TypeAnalysisResult.ImplicitButShouldBeExplicit) { if (context.IsRefactoringEnabled(RefactoringIdentifiers.ChangeVarToExplicitType)) { ITypeSymbol typeSymbol = semanticModel.GetTypeInfo(type, context.CancellationToken).Type; context.RegisterRefactoring( $"Change type to '{typeSymbol.ToMinimalDisplayString(semanticModel, type.Span.Start, SyntaxUtility.DefaultSymbolDisplayFormat)}'", cancellationToken => ChangeTypeRefactoring.ChangeTypeAsync(context.Document, type, typeSymbol, cancellationToken)); } } }
private static async Task ChangeTypeAsync( RefactoringContext context, VariableDeclarationSyntax variableDeclaration) { SemanticModel semanticModel = await context.GetSemanticModelAsync().ConfigureAwait(false); TypeAnalysisResult result = VariableDeclarationAnalysis.AnalyzeType( variableDeclaration, semanticModel, context.CancellationToken); if (result == TypeAnalysisResult.Explicit || result == TypeAnalysisResult.ExplicitButShouldBeImplicit) { if (context.IsRefactoringEnabled(RefactoringIdentifiers.ChangeExplicitTypeToVar)) { context.RegisterRefactoring( "Change type to 'var'", cancellationToken => { return(ChangeTypeRefactoring.ChangeTypeToVarAsync( context.Document, variableDeclaration.Type, cancellationToken)); }); } } else if (result == TypeAnalysisResult.Implicit || result == TypeAnalysisResult.ImplicitButShouldBeExplicit) { if (context.IsRefactoringEnabled(RefactoringIdentifiers.ChangeVarToExplicitType)) { ITypeSymbol typeSymbol = semanticModel .GetTypeInfo(variableDeclaration.Type, context.CancellationToken) .Type; ChangeType(context, variableDeclaration, typeSymbol, semanticModel, context.CancellationToken); } } }
private static async Task ChangeTypeAccordingToExpressionAsync( RefactoringContext context, VariableDeclarationSyntax variableDeclaration) { TypeSyntax type = variableDeclaration.Type; if (type?.IsVar == false) { ExpressionSyntax initializerValue = variableDeclaration.Variables.SingleOrDefault(shouldthrow: false)?.Initializer?.Value; if (initializerValue != null) { SemanticModel semanticModel = await context.GetSemanticModelAsync().ConfigureAwait(false); ITypeSymbol initializerTypeSymbol = semanticModel.GetTypeSymbol(initializerValue); if (initializerTypeSymbol?.IsErrorType() == false) { ITypeSymbol typeSymbol = semanticModel.GetTypeInfo(type).ConvertedType; if (!initializerTypeSymbol.Equals(typeSymbol)) { if (initializerTypeSymbol.SupportsExplicitDeclaration()) { ChangeType(context, variableDeclaration, initializerTypeSymbol, semanticModel, context.CancellationToken); } else { context.RegisterRefactoring( "Change type to 'var'", cancellationToken => ChangeTypeRefactoring.ChangeTypeToVarAsync(context.Document, type, cancellationToken)); } } } } } }
public static async Task ComputeRefactoringsAsync(RefactoringContext context, YieldStatementSyntax yieldStatement) { if (context.IsAnyRefactoringEnabled( RefactoringIdentifiers.ChangeMemberTypeAccordingToYieldReturnExpression, RefactoringIdentifiers.AddCastExpression, RefactoringIdentifiers.CallToMethod) && yieldStatement.IsYieldReturn() && yieldStatement.Expression != null) { SemanticModel semanticModel = await context.GetSemanticModelAsync().ConfigureAwait(false); MemberDeclarationSyntax containingMember = await ReturnExpressionRefactoring.GetContainingMethodOrPropertyOrIndexerAsync(yieldStatement.Expression, semanticModel, context.CancellationToken).ConfigureAwait(false); if (containingMember != null) { TypeSyntax memberType = ReturnExpressionRefactoring.GetMemberType(containingMember); if (memberType != null) { ITypeSymbol memberTypeSymbol = semanticModel.GetTypeSymbol(memberType, context.CancellationToken); if (memberTypeSymbol?.SpecialType != SpecialType.System_Collections_IEnumerable) { ITypeSymbol typeSymbol = semanticModel.GetTypeSymbol(yieldStatement.Expression, context.CancellationToken); if (context.IsRefactoringEnabled(RefactoringIdentifiers.ChangeMemberTypeAccordingToYieldReturnExpression) && typeSymbol?.IsErrorType() == false && !typeSymbol.IsVoid() && (memberTypeSymbol == null || memberTypeSymbol.IsErrorType() || !memberTypeSymbol.IsConstructedFromIEnumerableOfT() || !((INamedTypeSymbol)memberTypeSymbol).TypeArguments[0].Equals(typeSymbol))) { INamedTypeSymbol newTypeSymbol = semanticModel .Compilation .GetSpecialType(SpecialType.System_Collections_Generic_IEnumerable_T) .Construct(typeSymbol); TypeSyntax newType = CSharpFactory.Type(newTypeSymbol, semanticModel, memberType.SpanStart); context.RegisterRefactoring( $"Change {ReturnExpressionRefactoring.GetText(containingMember)} type to '{SymbolDisplay.GetMinimalDisplayString(newTypeSymbol, memberType.SpanStart, semanticModel)}'", cancellationToken => { return(ChangeTypeRefactoring.ChangeTypeAsync( context.Document, memberType, newType, cancellationToken)); }); } if (context.IsAnyRefactoringEnabled(RefactoringIdentifiers.AddCastExpression, RefactoringIdentifiers.CallToMethod) && yieldStatement.Expression.Span.Contains(context.Span) && memberTypeSymbol?.IsNamedType() == true) { var namedTypeSymbol = (INamedTypeSymbol)memberTypeSymbol; if (namedTypeSymbol.IsConstructedFromIEnumerableOfT()) { ITypeSymbol argumentSymbol = namedTypeSymbol.TypeArguments[0]; if (argumentSymbol != typeSymbol) { ModifyExpressionRefactoring.ComputeRefactoring( context, yieldStatement.Expression, argumentSymbol, semanticModel); } } } } } } } if (context.IsRefactoringEnabled(RefactoringIdentifiers.ReplaceStatementWithIfStatement) && context.Span.IsBetweenSpans(yieldStatement)) { var refactoring = new ReplaceYieldStatementWithIfStatementRefactoring(); await refactoring.ComputeRefactoringAsync(context, yieldStatement).ConfigureAwait(false); } }
public static async Task ComputeRefactoringsAsync(RefactoringContext context, YieldStatementSyntax yieldStatement) { if (context.IsAnyRefactoringEnabled( RefactoringIdentifiers.ChangeMemberTypeAccordingToYieldReturnExpression, RefactoringIdentifiers.AddCastExpression, RefactoringIdentifiers.CallToMethod, RefactoringIdentifiers.CreateConditionFromBooleanExpression) && yieldStatement.IsYieldReturn() && yieldStatement.Expression != null && context.SupportsSemanticModel) { if (context.IsAnyRefactoringEnabled( RefactoringIdentifiers.ChangeMemberTypeAccordingToYieldReturnExpression, RefactoringIdentifiers.AddCastExpression, RefactoringIdentifiers.CallToMethod)) { MemberDeclarationSyntax containingMember = ReturnExpressionRefactoring.GetContainingMethodOrPropertyOrIndexer(yieldStatement.Expression); if (containingMember != null) { TypeSyntax memberType = ReturnExpressionRefactoring.GetMemberType(containingMember); if (memberType != null) { SemanticModel semanticModel = await context.GetSemanticModelAsync().ConfigureAwait(false); ITypeSymbol memberTypeSymbol = semanticModel .GetTypeInfo(memberType, context.CancellationToken) .Type; if (memberTypeSymbol?.SpecialType != SpecialType.System_Collections_IEnumerable) { ITypeSymbol typeSymbol = semanticModel .GetTypeInfo(yieldStatement.Expression, context.CancellationToken) .Type; if (context.IsRefactoringEnabled(RefactoringIdentifiers.ChangeMemberTypeAccordingToYieldReturnExpression) && typeSymbol?.IsErrorType() == false && (memberTypeSymbol == null || memberTypeSymbol.IsErrorType() || !SyntaxAnalyzer.IsGenericIEnumerable(memberTypeSymbol) || !((INamedTypeSymbol)memberTypeSymbol).TypeArguments[0].Equals(typeSymbol))) { TypeSyntax newType = QualifiedName( ParseName("System.Collections.Generic"), GenericName( Identifier("IEnumerable"), TypeArgumentList( SingletonSeparatedList( CSharpFactory.Type(typeSymbol))))); context.RegisterRefactoring( $"Change {ReturnExpressionRefactoring.GetText(containingMember)} type to 'IEnumerable<{typeSymbol.ToDisplayString(SyntaxUtility.DefaultSymbolDisplayFormat)}>'", cancellationToken => { return(ChangeTypeRefactoring.ChangeTypeAsync( context.Document, memberType, newType, cancellationToken)); }); } if (context.IsAnyRefactoringEnabled(RefactoringIdentifiers.AddCastExpression, RefactoringIdentifiers.CallToMethod) && yieldStatement.Expression.Span.Contains(context.Span) && memberTypeSymbol?.IsNamedType() == true) { var namedTypeSymbol = (INamedTypeSymbol)memberTypeSymbol; if (namedTypeSymbol.ConstructedFrom.SpecialType == SpecialType.System_Collections_Generic_IEnumerable_T) { ITypeSymbol argumentSymbol = namedTypeSymbol.TypeArguments[0]; if (argumentSymbol != typeSymbol) { ModifyExpressionRefactoring.ComputeRefactoring( context, yieldStatement.Expression, argumentSymbol, semanticModel); } } } } } } } if (context.IsRefactoringEnabled(RefactoringIdentifiers.CreateConditionFromBooleanExpression)) { await CreateConditionFromBooleanExpressionRefactoring.ComputeRefactoringAsync(context, yieldStatement.Expression).ConfigureAwait(false); } } }
public static async Task ComputeRefactoringsAsync(RefactoringContext context, YieldStatementSyntax yieldStatement) { if (context.IsAnyRefactoringEnabled( RefactoringIdentifiers.ChangeMemberTypeAccordingToYieldReturnExpression, RefactoringIdentifiers.AddCastExpression, RefactoringIdentifiers.CallToMethod) && yieldStatement.IsYieldReturn() && yieldStatement.Expression != null) { SemanticModel semanticModel = await context.GetSemanticModelAsync().ConfigureAwait(false); ISymbol memberSymbol = ReturnExpressionRefactoring.GetContainingMethodOrPropertySymbol(yieldStatement.Expression, semanticModel, context.CancellationToken); if (memberSymbol != null) { SyntaxNode node = await memberSymbol .DeclaringSyntaxReferences[0] .GetSyntaxAsync(context.CancellationToken) .ConfigureAwait(false); TypeSyntax type = ReturnExpressionRefactoring.GetTypeOrReturnType(node); if (type != null) { ITypeSymbol memberTypeSymbol = semanticModel.GetTypeSymbol(type, context.CancellationToken); if (memberTypeSymbol?.SpecialType != SpecialType.System_Collections_IEnumerable) { ITypeSymbol typeSymbol = semanticModel.GetTypeSymbol(yieldStatement.Expression, context.CancellationToken); if (context.IsRefactoringEnabled(RefactoringIdentifiers.ChangeMemberTypeAccordingToYieldReturnExpression) && typeSymbol?.IsErrorType() == false && !typeSymbol.IsVoid() && !memberSymbol.IsOverride && (memberTypeSymbol == null || memberTypeSymbol.IsErrorType() || !memberTypeSymbol.IsConstructedFromIEnumerableOfT() || !((INamedTypeSymbol)memberTypeSymbol).TypeArguments[0].Equals(typeSymbol))) { INamedTypeSymbol newTypeSymbol = semanticModel .Compilation .GetSpecialType(SpecialType.System_Collections_Generic_IEnumerable_T) .Construct(typeSymbol); TypeSyntax newType = newTypeSymbol.ToMinimalTypeSyntax(semanticModel, type.SpanStart); context.RegisterRefactoring( $"Change {ReturnExpressionRefactoring.GetText(node)} type to '{SymbolDisplay.GetMinimalString(newTypeSymbol, semanticModel, type.SpanStart)}'", cancellationToken => { return ChangeTypeRefactoring.ChangeTypeAsync( context.Document, type, newType, cancellationToken); }); } if (context.IsAnyRefactoringEnabled(RefactoringIdentifiers.AddCastExpression, RefactoringIdentifiers.CallToMethod) && yieldStatement.Expression.Span.Contains(context.Span) && memberTypeSymbol?.IsNamedType() == true) { var namedTypeSymbol = (INamedTypeSymbol)memberTypeSymbol; if (namedTypeSymbol.IsConstructedFromIEnumerableOfT()) { ITypeSymbol argumentSymbol = namedTypeSymbol.TypeArguments[0]; if (argumentSymbol != typeSymbol) { ModifyExpressionRefactoring.ComputeRefactoring( context, yieldStatement.Expression, argumentSymbol, semanticModel); } } } } } } } if (context.IsRefactoringEnabled(RefactoringIdentifiers.ReplaceStatementWithIfElse) && (context.Span.IsEmptyAndContainedInSpan(yieldStatement.YieldKeyword) || context.Span.IsEmptyAndContainedInSpan(yieldStatement.ReturnOrBreakKeyword) || context.Span.IsBetweenSpans(yieldStatement))) { await ReplaceStatementWithIfStatementRefactoring.ReplaceYieldReturnWithIfElse.ComputeRefactoringAsync(context, yieldStatement).ConfigureAwait(false); } }
public static async Task ComputeRefactoringAsync(RefactoringContext context, MethodDeclarationSyntax methodDeclaration) { TypeSyntax returnType = methodDeclaration.ReturnType; if (returnType?.IsVoid() != false) { return; } BlockSyntax body = methodDeclaration.Body; if (body == null) { return; } SyntaxList <StatementSyntax> statements = body.Statements; if (!statements.Any()) { return; } if (statements.SingleOrDefault(shouldThrow: false)?.Kind() == SyntaxKind.ThrowStatement) { return; } if (methodDeclaration.ContainsYield()) { return; } SemanticModel semanticModel = await context.GetSemanticModelAsync().ConfigureAwait(false); IMethodSymbol methodSymbol = semanticModel.GetDeclaredSymbol(methodDeclaration, context.CancellationToken); if (methodSymbol?.IsOverride != false) { return; } if (methodSymbol.ImplementsInterfaceMember()) { return; } if (IsAsyncMethodThatReturnsTask(methodSymbol, semanticModel)) { return; } ControlFlowAnalysis analysis = semanticModel.AnalyzeControlFlow(body); if (!analysis.Succeeded) { return; } if (!analysis.ReturnStatements.All(IsReturnStatementWithoutExpression)) { return; } context.RegisterRefactoring( "Change return type to 'void'", ct => ChangeTypeRefactoring.ChangeTypeAsync(context.Document, returnType, CSharpFactory.VoidType(), ct), RefactoringIdentifiers.ChangeMethodReturnTypeToVoid); }