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(CodeActionFactory.ChangeTypeToVar(context.Document, declarationExpression.Type, equivalenceKey: RefactoringIdentifiers.ChangeExplicitTypeToVar)); } } else if (analysis.SupportsExplicit && context.IsRefactoringEnabled(RefactoringIdentifiers.ChangeVarToExplicitType)) { TypeSyntax type = declarationExpression.Type; var localSymbol = (ILocalSymbol)semanticModel.GetDeclaredSymbol(declarationExpression.Designation, context.CancellationToken); ITypeSymbol typeSymbol = localSymbol.Type; context.RegisterRefactoring(CodeActionFactory.ChangeType(context.Document, type, typeSymbol, semanticModel, equivalenceKey: RefactoringIdentifiers.ChangeVarToExplicitType)); } } }
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 = CSharpTypeAnalysis.AnalyzeType(forEachStatement, semanticModel); if (analysis.IsExplicit) { if (analysis.SupportsImplicit && context.IsRefactoringEnabled(RefactoringDescriptors.UseImplicitType)) { context.RegisterRefactoring(CodeActionFactory.ChangeTypeToVar(context.Document, type, equivalenceKey: EquivalenceKey.Create(RefactoringDescriptors.UseImplicitType))); } if (!forEachStatement.ContainsDiagnostics && context.IsRefactoringEnabled(RefactoringDescriptors.ChangeTypeAccordingToExpression)) { ChangeTypeAccordingToExpression(context, forEachStatement, semanticModel); } } else if (analysis.SupportsExplicit && context.IsRefactoringEnabled(RefactoringDescriptors.UseExplicitType)) { context.RegisterRefactoring(CodeActionFactory.UseExplicitType(context.Document, type, analysis.Symbol, semanticModel, equivalenceKey: EquivalenceKey.Create(RefactoringDescriptors.UseExplicitType))); } }
private static async Task ChangeTypeAsync( RefactoringContext context, VariableDeclarationSyntax variableDeclaration) { SemanticModel semanticModel = await context.GetSemanticModelAsync().ConfigureAwait(false); TypeAnalysis analysis = CSharpTypeAnalysis.AnalyzeType(variableDeclaration, 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, variableDeclaration.Type, cancellationToken)); }, RefactoringIdentifiers.ChangeExplicitTypeToVar); } } else if (analysis.SupportsExplicit && context.IsRefactoringEnabled(RefactoringIdentifiers.ChangeVarToExplicitType)) { ITypeSymbol typeSymbol = semanticModel.GetTypeSymbol(variableDeclaration.Type, context.CancellationToken); ChangeType(context, variableDeclaration, typeSymbol, semanticModel, context.CancellationToken); } }
private static void AnalyzeVariableDeclaration(SyntaxNodeAnalysisContext context) { var variableDeclaration = (VariableDeclarationSyntax)context.Node; if (CSharpTypeAnalysis.IsExplicitThatCanBeImplicit(variableDeclaration, context.SemanticModel, TypeAppearance.Obvious, context.CancellationToken)) { ReportDiagnostic(context, variableDeclaration.Type); } }
private static void AnalyzeVariableDeclaration(SyntaxNodeAnalysisContext context) { var variableDeclaration = (VariableDeclarationSyntax)context.Node; if (CSharpTypeAnalysis.IsImplicitThatCanBeExplicit(variableDeclaration, context.SemanticModel, TypeAppearance.NotObvious, context.CancellationToken)) { DiagnosticHelpers.ReportDiagnostic(context, DiagnosticDescriptors.UseExplicitTypeInsteadOfVarWhenTypeIsNotObvious, variableDeclaration.Type); } }
private static void AnalyzeForEachStatement(SyntaxNodeAnalysisContext context) { var forEachStatement = (ForEachStatementSyntax)context.Node; if (CSharpTypeAnalysis.IsImplicitThatCanBeExplicit(forEachStatement, context.SemanticModel)) { DiagnosticHelpers.ReportDiagnostic(context, DiagnosticDescriptors.UseExplicitTypeInsteadOfVarInForEach, forEachStatement.Type); } }
private static void AnalyzeDeclarationExpression(SyntaxNodeAnalysisContext context) { var declarationExpression = (DeclarationExpressionSyntax)context.Node; if (CSharpTypeAnalysis.IsExplicitThatCanBeImplicit(declarationExpression, context.SemanticModel, context.CancellationToken)) { DiagnosticHelpers.ReportDiagnostic(context, DiagnosticDescriptors.UseVarInsteadOfExplicitTypeWhenTypeIsNotObvious, declarationExpression.Type); } }
private static void AnalyzeForEachStatement(SyntaxNodeAnalysisContext context) { var forEachStatement = (ForEachStatementSyntax)context.Node; TypeAnalysis analysis = CSharpTypeAnalysis.AnalyzeType(forEachStatement, context.SemanticModel); if (analysis.IsExplicit && analysis.SupportsImplicit) { DiagnosticHelpers.ReportDiagnostic(context, DiagnosticDescriptors.UseVarInsteadOfExplicitTypeInForEach, forEachStatement.Type); } }
private static void AnalyzeForEachVariableStatement(SyntaxNodeAnalysisContext context) { var forEachStatement = (ForEachVariableStatementSyntax)context.Node; TypeAnalysis analysis = CSharpTypeAnalysis.AnalyzeType(forEachStatement, context.SemanticModel); if (analysis.IsExplicit && analysis.SupportsImplicit) { ReportDiagnostic(context, forEachStatement.Variable); } }
private static void AnalyzeArrayCreationExpression(SyntaxNodeAnalysisContext context) { var arrayCreation = (ArrayCreationExpressionSyntax)context.Node; if (arrayCreation.ContainsDiagnostics) { return; } ArrayTypeSyntax arrayType = arrayCreation.Type; if (arrayType.ContainsDirectives) { return; } SeparatedSyntaxList <ExpressionSyntax> expressions = arrayCreation.Initializer?.Expressions ?? default; if (!expressions.Any()) { return; } if (AnalyzerOptions.UseImplicitlyTypedArrayWhenTypeIsObvious.IsEnabled(context)) { foreach (ExpressionSyntax expression in expressions) { if (!CSharpTypeAnalysis.IsTypeObvious(expression, null, context.SemanticModel, context.CancellationToken)) { return; } } } TypeSyntax elementType = arrayType.ElementType; SyntaxList <ArrayRankSpecifierSyntax> rankSpecifiers = arrayType.RankSpecifiers; TextSpan textSpan = TextSpan.FromBounds( elementType.SpanStart, ((rankSpecifiers.Count > 1) ? rankSpecifiers.LastButOne() : (SyntaxNode)elementType).Span.End); Location location = Location.Create(arrayCreation.SyntaxTree, textSpan); DiagnosticHelpers.ReportDiagnostic( context, DiagnosticRules.ReportOnly.UseImplicitlyTypedArray, location); DiagnosticHelpers.ReportObsolete(context, location, AnalyzerOptions.UseImplicitlyTypedArray); DiagnosticHelpers.ReportObsolete(context, location, AnalyzerOptions.UseImplicitlyTypedArrayWhenTypeIsObvious); }
private static void AnalyzeDeclarationExpression(SyntaxNodeAnalysisContext context) { var declarationExpression = (DeclarationExpressionSyntax)context.Node; if (declarationExpression.IsParentKind(SyntaxKind.ForEachVariableStatement)) { return; } if (CSharpTypeAnalysis.IsImplicitThatCanBeExplicit(declarationExpression, context.SemanticModel, context.CancellationToken)) { ReportDiagnostic(context, declarationExpression.Type); } }
private static void AnalyzeTupleExpression(SyntaxNodeAnalysisContext context) { var tupleExpression = (TupleExpressionSyntax)context.Node; if (tupleExpression.IsParentKind(SyntaxKind.ForEachVariableStatement)) { return; } if (CSharpTypeAnalysis.IsExplicitThatCanBeImplicit(tupleExpression, context.SemanticModel, TypeAppearance.Obvious, context.CancellationToken)) { ReportDiagnostic(context, tupleExpression); } }
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 AnalyzeForEachVariableStatement(SyntaxNodeAnalysisContext context) { var forEachStatement = (ForEachVariableStatementSyntax)context.Node; switch (forEachStatement.Variable) { case DeclarationExpressionSyntax declarationExpression: { if (CSharpTypeAnalysis.IsImplicitThatCanBeExplicit(forEachStatement, context.SemanticModel)) { ReportDiagnostic(context, declarationExpression.Type); } break; } case TupleExpressionSyntax tupleExpression: { foreach (ArgumentSyntax argument in tupleExpression.Arguments) { if (!(argument.Expression is DeclarationExpressionSyntax declarationExpression)) { continue; } if (CSharpTypeAnalysis.IsImplicitThatCanBeExplicit(declarationExpression, context.SemanticModel, context.CancellationToken)) { ReportDiagnostic(context, declarationExpression.Type); } } break; } default: { Debug.Assert(forEachStatement.ContainsDiagnostics, forEachStatement.Variable.Kind().ToString()); break; } } }
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 = CSharpTypeAnalysis.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), RefactoringIdentifiers.ChangeExplicitTypeToVar); } } 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), RefactoringIdentifiers.ChangeVarToExplicitType); } }
private static void AnalyzeImplicitArrayCreationExpression(SyntaxNodeAnalysisContext context, ArrayCreationTypeStyle kind) { var expression = (ImplicitArrayCreationExpressionSyntax)context.Node; if (expression.ContainsDiagnostics) { return; } if (expression.NewKeyword.ContainsDirectives) { return; } if (expression.OpenBracketToken.ContainsDirectives) { return; } if (expression.CloseBracketToken.ContainsDirectives) { return; } IArrayTypeSymbol arrayTypeSymbol = null; if (kind == ArrayCreationTypeStyle.ImplicitWhenTypeIsObvious) { InitializerExpressionSyntax initializer = expression.Initializer; if (initializer != null) { var isObvious = false; foreach (ExpressionSyntax expression2 in initializer.Expressions) { if (arrayTypeSymbol == null) { arrayTypeSymbol = context.SemanticModel.GetTypeSymbol(expression, context.CancellationToken) as IArrayTypeSymbol; if (arrayTypeSymbol?.ElementType.SupportsExplicitDeclaration() != true) { return; } } isObvious = CSharpTypeAnalysis.IsTypeObvious(expression2, arrayTypeSymbol.ElementType, includeNullability: true, context.SemanticModel, context.CancellationToken); if (!isObvious) { break; } } if (isObvious) { return; } } } if (arrayTypeSymbol == null) { arrayTypeSymbol = context.SemanticModel.GetTypeSymbol(expression, context.CancellationToken) as IArrayTypeSymbol; if (arrayTypeSymbol?.ElementType.SupportsExplicitDeclaration() != true) { return; } } Location location = Location.Create(expression.SyntaxTree, TextSpan.FromBounds(expression.NewKeyword.SpanStart, expression.CloseBracketToken.Span.End)); DiagnosticHelpers.ReportDiagnostic( context, DiagnosticRules.UseExplicitlyOrImplicitlyTypedArray, location, "explicitly"); }
private static void AnalyzeImplicitArrayCreationExpression(SyntaxNodeAnalysisContext context) { var expression = (ImplicitArrayCreationExpressionSyntax)context.Node; if (expression.ContainsDiagnostics) { return; } if (expression.NewKeyword.ContainsDirectives) { return; } if (expression.OpenBracketToken.ContainsDirectives) { return; } if (expression.CloseBracketToken.ContainsDirectives) { return; } if (AnalyzerOptions.UseImplicitlyTypedArrayWhenTypeIsObvious.IsEnabled(context)) { InitializerExpressionSyntax initializer = expression.Initializer; if (initializer != null) { var isObvious = false; foreach (ExpressionSyntax expression2 in initializer.Expressions) { isObvious = CSharpTypeAnalysis.IsTypeObvious(expression2, null, context.SemanticModel, context.CancellationToken); if (!isObvious) { break; } } if (isObvious) { return; } } } if (!(context.SemanticModel.GetTypeSymbol(expression, context.CancellationToken) is IArrayTypeSymbol arrayTypeSymbol)) { return; } if (!arrayTypeSymbol.ElementType.SupportsExplicitDeclaration()) { return; } DiagnosticHelpers.ReportDiagnostic( context, DiagnosticDescriptors.UseExplicitlyTypedArrayOrViceVersa, Location.Create(expression.SyntaxTree, TextSpan.FromBounds(expression.NewKeyword.SpanStart, expression.CloseBracketToken.Span.End))); }
public static async Task ComputeRefactoringsAsync(RefactoringContext context, VariableDeclarationSyntax variableDeclaration) { TypeSyntax type = variableDeclaration.Type; if (type?.Span.Contains(context.Span) == true && context.IsAnyRefactoringEnabled( RefactoringIdentifiers.ChangeExplicitTypeToVar, RefactoringIdentifiers.ChangeVarToExplicitType, RefactoringIdentifiers.ChangeTypeAccordingToExpression)) { SemanticModel semanticModel = await context.GetSemanticModelAsync().ConfigureAwait(false); TypeAnalysis analysis = CSharpTypeAnalysis.AnalyzeType(variableDeclaration, semanticModel, context.CancellationToken); if (analysis.IsExplicit) { if (analysis.SupportsImplicit && context.IsRefactoringEnabled(RefactoringIdentifiers.ChangeExplicitTypeToVar)) { context.RegisterRefactoring(CodeActionFactory.ChangeTypeToVar(context.Document, type, equivalenceKey: RefactoringIdentifiers.ChangeExplicitTypeToVar)); } if (!variableDeclaration.ContainsDiagnostics && context.IsRefactoringEnabled(RefactoringIdentifiers.ChangeTypeAccordingToExpression)) { ChangeTypeAccordingToExpression(context, variableDeclaration, analysis.Symbol, semanticModel); } } else if (analysis.SupportsExplicit && context.IsRefactoringEnabled(RefactoringIdentifiers.ChangeVarToExplicitType)) { ITypeSymbol typeSymbol = analysis.Symbol; VariableDeclaratorSyntax variableDeclarator = variableDeclaration.Variables.SingleOrDefault(shouldThrow: false); if (variableDeclarator?.Initializer?.Value != null) { if (typeSymbol.OriginalDefinition.EqualsOrInheritsFromTaskOfT()) { Func <CancellationToken, Task <Document> > createChangedDocument = DocumentRefactoringFactory.ChangeTypeAndAddAwait( context.Document, variableDeclaration, variableDeclarator, typeSymbol, semanticModel, context.CancellationToken); if (createChangedDocument != null) { ITypeSymbol typeArgument = ((INamedTypeSymbol)typeSymbol).TypeArguments[0]; context.RegisterRefactoring( $"Change type to '{SymbolDisplay.ToMinimalDisplayString(typeArgument, semanticModel, type.SpanStart)}' and add 'await'", createChangedDocument, EquivalenceKey.Join(RefactoringIdentifiers.ChangeVarToExplicitType, "AddAwait")); } } typeSymbol = semanticModel.GetTypeSymbol(variableDeclarator.Initializer.Value, context.CancellationToken); if (typeSymbol != null) { context.RegisterRefactoring(CodeActionFactory.ChangeType(context.Document, type, typeSymbol, semanticModel, equivalenceKey: RefactoringIdentifiers.ChangeVarToExplicitType)); } } } } }
private static void AnalyzeArrayCreationExpression(SyntaxNodeAnalysisContext context, ArrayCreationTypeStyle kind) { var arrayCreation = (ArrayCreationExpressionSyntax)context.Node; if (arrayCreation.ContainsDiagnostics) { return; } ArrayTypeSyntax arrayType = arrayCreation.Type; if (arrayType.ContainsDirectives) { return; } SeparatedSyntaxList <ExpressionSyntax> expressions = arrayCreation.Initializer?.Expressions ?? default; if (!expressions.Any()) { return; } ITypeSymbol typeSymbol = null; if (kind == ArrayCreationTypeStyle.ImplicitWhenTypeIsObvious) { foreach (ExpressionSyntax expression in expressions) { if (typeSymbol == null) { typeSymbol = context.SemanticModel.GetTypeSymbol(arrayCreation.Type.ElementType, context.CancellationToken); if (typeSymbol?.IsErrorType() != false) { return; } } if (!CSharpTypeAnalysis.IsTypeObvious(expression, typeSymbol, includeNullability: true, context.SemanticModel, context.CancellationToken)) { return; } } } TypeSyntax elementType = arrayType.ElementType; SyntaxList <ArrayRankSpecifierSyntax> rankSpecifiers = arrayType.RankSpecifiers; TextSpan textSpan = TextSpan.FromBounds( elementType.SpanStart, ((rankSpecifiers.Count > 1) ? rankSpecifiers.LastButOne() : (SyntaxNode)elementType).Span.End); Location location = Location.Create(arrayCreation.SyntaxTree, textSpan); DiagnosticHelpers.ReportDiagnostic( context, DiagnosticRules.UseExplicitlyOrImplicitlyTypedArray, location, "implicitly"); }