private static GenericInfo ToMultiLine(GenericInfo info) { SyntaxNode declaration = info.Node; SyntaxList <TypeParameterConstraintClauseSyntax> constraintClauses = info.ConstraintClauses; TypeParameterConstraintClauseSyntax first = constraintClauses.First(); SyntaxToken previousToken = declaration.FindToken(first.FullSpan.Start - 1); declaration = declaration.ReplaceToken(previousToken, previousToken.WithTrailingTrivia(TriviaList(NewLine()))); SyntaxTriviaList leadingTrivia = declaration .FindToken(declaration.SpanStart) .LeadingTrivia; SyntaxTriviaList trivia = IncreaseIndentation(leadingTrivia.LastOrDefault()); int count = constraintClauses.Count; for (int i = 0; i < count; i++) { TypeParameterConstraintClauseSyntax newNode = constraintClauses[i].WithLeadingTrivia(trivia); if (i < count - 1) { newNode = newNode.WithTrailingTrivia(NewLine()); } constraintClauses = constraintClauses.ReplaceAt(i, newNode); } return(SyntaxInfo.GenericInfo(declaration).WithConstraintClauses(constraintClauses)); }
public static Task <Document> RefactorAsync( Document document, BaseTypeSyntax baseType, CancellationToken cancellationToken) { SyntaxRemoveOptions removeOptions = RemoveHelper.DefaultRemoveOptions; if (baseType.GetLeadingTrivia().All(f => f.IsWhitespaceTrivia())) { removeOptions &= ~SyntaxRemoveOptions.KeepLeadingTrivia; } if (baseType.GetTrailingTrivia().All(f => f.IsWhitespaceTrivia())) { var baseList = (BaseListSyntax)baseType.Parent; if (baseList.Types.IsLast(baseType) && !SyntaxInfo.GenericInfo(baseList.Parent).ConstraintClauses.Any()) { removeOptions &= ~SyntaxRemoveOptions.KeepTrailingTrivia; } } return(document.RemoveNodeAsync(baseType, removeOptions, cancellationToken)); }
private static GenericInfo ToSingleLine(GenericInfo info) { SyntaxNode declaration = info.Node; SyntaxList <TypeParameterConstraintClauseSyntax> constraintClauses = info.ConstraintClauses; SyntaxToken previousToken = declaration.FindToken(constraintClauses.First().FullSpan.Start - 1); declaration = declaration.ReplaceToken(previousToken, previousToken.WithTrailingTrivia(TriviaList(ElasticSpace))); int count = constraintClauses.Count; for (int i = 0; i < count; i++) { TypeParameterConstraintClauseSyntax constraintClause = constraintClauses[i]; TextSpan?span = null; if (i == count - 1) { span = TextSpan.FromBounds(constraintClause.FullSpan.Start, constraintClause.Span.End); } TypeParameterConstraintClauseSyntax newNode = constraintClause .RemoveWhitespace(span) .WithFormatterAnnotation(); constraintClauses = constraintClauses.ReplaceAt(i, newNode); } return(SyntaxInfo.GenericInfo(declaration).WithConstraintClauses(constraintClauses)); }
private static void AnalyzeTypeParameterList(SyntaxNodeAnalysisContext context) { var typeParameterList = (TypeParameterListSyntax)context.Node; GenericInfo genericInfo = SyntaxInfo.GenericInfo(typeParameterList); if (!genericInfo.Success) { return; } if (!genericInfo.TypeParameters.Any()) { return; } if (!genericInfo.ConstraintClauses.Any()) { return; } if (genericInfo.ConstraintClauses.SpanContainsDirectives()) { return; } if (!IsFixable(genericInfo.TypeParameters, genericInfo.ConstraintClauses)) { return; } DiagnosticHelpers.ReportDiagnostic(context, DiagnosticDescriptors.OrderTypeParameterConstraints, genericInfo.ConstraintClauses[0]); }
private static Task <Document> WrapBaseListAsync( Document document, BaseListSyntax baseList, CancellationToken cancellationToken = default) { List <TextChange> textChanges = GetFixListChanges( baseList, baseList.ColonToken, baseList.Types, ListFixMode.Wrap, cancellationToken); if (baseList.Types.Count > 1) { GenericInfo genericInfo = SyntaxInfo.GenericInfo(baseList.Parent); SyntaxList <TypeParameterConstraintClauseSyntax> constraintClauses = genericInfo.ConstraintClauses; if (constraintClauses.Any()) { List <TextChange> textChanges2 = GetFixListChanges( genericInfo.Node, constraintClauses.First().WhereKeyword.GetPreviousToken(), constraintClauses, ListFixMode.Wrap, cancellationToken); textChanges.AddRange(textChanges2); } } return(document.WithTextChangesAsync(textChanges, cancellationToken)); }
public sealed override async Task RegisterCodeFixesAsync(CodeFixContext context) { if (!Settings.IsCodeFixEnabled(CodeFixIdentifiers.RemoveTypeParameter)) { return; } SyntaxNode root = await context.GetSyntaxRootAsync().ConfigureAwait(false); if (!TryFindFirstAncestorOrSelf(root, context.Span, out TypeParameterSyntax typeParameter)) { return; } foreach (Diagnostic diagnostic in context.Diagnostics) { switch (diagnostic.Id) { case CompilerDiagnosticIdentifiers.TypeParameterHasSameNameAsTypeParameterFromOuterType: { TypeParameterInfo typeParameterInfo = SyntaxInfo.TypeParameterInfo(typeParameter); if (!typeParameterInfo.Success) { break; } CodeAction codeAction = CodeAction.Create( $"Remove type parameter '{typeParameterInfo.Name}'", cancellationToken => { GenericInfo genericInfo = SyntaxInfo.GenericInfo(typeParameterInfo.Declaration); GenericInfo newGenericInfo = genericInfo.RemoveTypeParameter(typeParameter); TypeParameterConstraintClauseSyntax constraintClause = typeParameterInfo.ConstraintClause; if (constraintClause != null) { newGenericInfo = newGenericInfo.RemoveConstraintClause(constraintClause); } return(context.Document.ReplaceNodeAsync(genericInfo.Declaration, newGenericInfo.Declaration, cancellationToken)); }, GetEquivalenceKey(diagnostic)); context.RegisterCodeFix(codeAction, diagnostic); break; } } } }
private static Task <Document> RefactorAsync( Document document, SyntaxNode node, CancellationToken cancellationToken) { GenericInfo genericInfo = SyntaxInfo.GenericInfo(node); SyntaxList <TypeParameterConstraintClauseSyntax> newConstraintClauses = SortConstraints(genericInfo.TypeParameters, genericInfo.ConstraintClauses); GenericInfo newInfo = genericInfo.WithConstraintClauses(newConstraintClauses); return(document.ReplaceNodeAsync(genericInfo.Node, newInfo.Node, cancellationToken)); }
public override async Task RegisterCodeFixesAsync(CodeFixContext context) { Diagnostic diagnostic = context.Diagnostics[0]; if (!Settings.IsEnabled(diagnostic.Id, CodeFixIdentifiers.RemoveTypeParameter)) { return; } SyntaxNode root = await context.GetSyntaxRootAsync().ConfigureAwait(false); if (!TryFindFirstAncestorOrSelf(root, context.Span, out TypeParameterSyntax typeParameter)) { return; } string name = typeParameter.Identifier.ValueText; if (string.IsNullOrEmpty(name)) { return; } CodeAction codeAction = CodeAction.Create( $"Remove type parameter '{name}'", cancellationToken => { GenericInfo genericInfo = SyntaxInfo.GenericInfo(typeParameter); GenericInfo newGenericInfo = genericInfo.RemoveTypeParameter(typeParameter); TypeParameterConstraintClauseSyntax constraintClause = genericInfo.FindConstraintClause(name); if (constraintClause != null) { newGenericInfo = newGenericInfo.RemoveConstraintClause(constraintClause); } return(context.Document.ReplaceNodeAsync(genericInfo.Node, newGenericInfo.Node, cancellationToken)); }, GetEquivalenceKey(diagnostic)); context.RegisterCodeFix(codeAction, diagnostic); }
public static void ComputeRefactoring(RefactoringContext context, TypeParameterConstraintClauseSyntax constraintClause) { GenericInfo genericInfo = SyntaxInfo.GenericInfo(constraintClause); if (!genericInfo.Success) { return; } SyntaxList <TypeParameterConstraintClauseSyntax> constraintClauses = genericInfo.ConstraintClauses; if (constraintClauses.IsSingleLine()) { if (constraintClauses.Count > 1) { context.RegisterRefactoring( "Wrap constraints", ct => { GenericInfo newInfo = WrapConstraints(genericInfo); return(context.Document.ReplaceNodeAsync(genericInfo.Node, newInfo.Node, ct)); }, RefactoringDescriptors.WrapConstraintClauses); } } else if (constraintClause.DescendantTrivia(constraintClause.Span).All(f => f.IsWhitespaceOrEndOfLineTrivia()) && constraintClauses[0].GetFirstToken().GetPreviousToken().TrailingTrivia.IsEmptyOrWhitespace()) { context.RegisterRefactoring( "Unwrap constraints", ct => { GenericInfo newInfo = UnwrapConstraints(genericInfo); return(context.Document.ReplaceNodeAsync(genericInfo.Node, newInfo.Node, ct)); }, RefactoringDescriptors.WrapConstraintClauses); } }
public static void ComputeRefactoring(RefactoringContext context, TypeParameterConstraintClauseSyntax constraintClause) { GenericInfo genericInfo = SyntaxInfo.GenericInfo(constraintClause); if (!genericInfo.Success) { return; } SyntaxList <TypeParameterConstraintClauseSyntax> constraintClauses = genericInfo.ConstraintClauses; if (constraintClauses.IsSingleLine()) { if (constraintClauses.Count > 1) { context.RegisterRefactoring( "Format constraints on separate lines", cancellationToken => { GenericInfo newInfo = ToMultiLine(genericInfo); return(context.Document.ReplaceNodeAsync(genericInfo.Node, newInfo.Node, cancellationToken)); }, RefactoringIdentifiers.FormatConstraintClauses); } } else if (constraintClause.DescendantTrivia(constraintClause.Span).All(f => f.IsWhitespaceOrEndOfLineTrivia()) && constraintClauses[0].GetFirstToken().GetPreviousToken().TrailingTrivia.IsEmptyOrWhitespace()) { context.RegisterRefactoring( "Format constraints on a single line", cancellationToken => { GenericInfo newInfo = ToSingleLine(genericInfo); return(context.Document.ReplaceNodeAsync(genericInfo.Node, newInfo.Node, cancellationToken)); }, RefactoringIdentifiers.FormatConstraintClauses); } }
public static void ComputeRefactoring(RefactoringContext context, TypeParameterConstraintClauseSyntax constraintClause) { GenericInfo genericInfo = SyntaxInfo.GenericInfo(constraintClause); if (!genericInfo.Success) { return; } SyntaxList <TypeParameterConstraintClauseSyntax> constraintClauses = genericInfo.ConstraintClauses; if (constraintClauses.IsSingleLine()) { if (constraintClauses.Count > 1) { context.RegisterRefactoring( "Format constraints on separate lines", cancellationToken => { GenericInfo newInfo = ToMultiLine(genericInfo); return(context.Document.ReplaceNodeAsync(genericInfo.Node, newInfo.Node, cancellationToken)); }); } } else { context.RegisterRefactoring( "Format constraints on a single line", cancellationToken => { GenericInfo newInfo = ToSingleLine(genericInfo); return(context.Document.ReplaceNodeAsync(genericInfo.Node, newInfo.Node, cancellationToken)); }); } }
public sealed override async Task RegisterCodeFixesAsync(CodeFixContext context) { if (!Settings.IsAnyEnabled( CodeFixIdentifiers.RemoveConstraintClauses, CodeFixIdentifiers.CombineConstraintClauses)) { return; } SyntaxNode root = await context.GetSyntaxRootAsync().ConfigureAwait(false); if (!TryFindFirstAncestorOrSelf(root, context.Span, out TypeParameterConstraintClauseSyntax constraintClause)) { return; } foreach (Diagnostic diagnostic in context.Diagnostics) { switch (diagnostic.Id) { case CompilerDiagnosticIdentifiers.ConstraintsAreNotAllowedOnNonGenericDeclarations: { if (!Settings.IsEnabled(CodeFixIdentifiers.RemoveConstraintClauses)) { break; } GenericInfo genericInfo = SyntaxInfo.GenericInfo(constraintClause); if (!genericInfo.Success) { break; } CodeAction codeAction = CodeAction.Create( "Remove constraints", cancellationToken => { GenericInfo newGenericInfo = genericInfo.RemoveAllConstraintClauses(); return(context.Document.ReplaceNodeAsync(genericInfo.Node, newGenericInfo.Node, cancellationToken)); }, GetEquivalenceKey(diagnostic)); context.RegisterCodeFix(codeAction, diagnostic); break; } case CompilerDiagnosticIdentifiers.ConstraintClauseHasAlreadyBeenSpecified: { if (!Settings.IsEnabled(CodeFixIdentifiers.CombineConstraintClauses)) { break; } GenericInfo genericInfo = SyntaxInfo.GenericInfo(constraintClause); int index = genericInfo.ConstraintClauses.IndexOf(constraintClause); string name = constraintClause.Name.Identifier.ValueText; TypeParameterConstraintClauseSyntax constraintClause2 = genericInfo.FindConstraintClause(name); if (constraintClause2 == null) { break; } CodeAction codeAction = CodeAction.Create( $"Combine constraints for '{name}'", cancellationToken => { TypeParameterConstraintClauseSyntax newConstraintClause = constraintClause2.WithConstraints(constraintClause2.Constraints.AddRange(constraintClause.Constraints)); SyntaxList <TypeParameterConstraintClauseSyntax> newConstraintClauses = genericInfo.ConstraintClauses .Replace(constraintClause2, newConstraintClause) .RemoveAt(index); GenericInfo newGenericInfo = genericInfo.WithConstraintClauses(newConstraintClauses); return(context.Document.ReplaceNodeAsync(genericInfo.Node, newGenericInfo.Node, cancellationToken)); }, GetEquivalenceKey(diagnostic)); context.RegisterCodeFix(codeAction, diagnostic); break; } } } }