/// <inheritdoc /> public sealed override async Task RegisterCodeFixesAsync(CodeFixContext context) { var root = await context.Document.GetSyntaxRootAsync(context.CancellationToken); var diagnostic = context.Diagnostics.First(); var diagnosticSpan = diagnostic.Location.SourceSpan; var diagnosedNode = root.FindToken(diagnosticSpan.Start).Parent; var elementAccess = diagnosedNode.AncestorsAndSelf().OfType <ElementAccessExpressionSyntax>().FirstOrDefault() ?? diagnosedNode.DescendantNodesAndSelf().OfType <ElementAccessExpressionSyntax>().FirstOrDefault(); if (elementAccess == null) { return; } var usingNamespace = "CMS.Helpers"; var codeFixHelper = new CodeFixHelper(context); var assignmentExpression = elementAccess.FirstAncestorOrSelf <AssignmentExpressionSyntax>(); var sessionKey = GetElementAccessKey(elementAccess); var valueToBeAssigned = assignmentExpression.Right; SyntaxNode oldNode = assignmentExpression; SyntaxNode newNode = SyntaxFactory.ParseExpression($@"SessionHelper.SetValue({sessionKey}, {valueToBeAssigned})"); context.RegisterCodeFix( CodeAction.Create( title: CodeFixMessagesProvider.GetReplaceWithMessage(newNode), createChangedDocument: c => codeFixHelper.ReplaceExpressionWith(oldNode, newNode, c, usingNamespace), equivalenceKey: nameof(HttpSessionElementAccessSetCodeFixProvider)), diagnostic); }
/// <inheritdoc /> public sealed override async Task RegisterCodeFixesAsync(CodeFixContext context) { var diagnostic = context.Diagnostics.First(); if (!diagnostic.IsMarkedAsSimpleMemberAccess()) { // no codefix for conditional accesses return; } var editor = new MemberAccessCodeFixHelper(context); var memberAccess = await editor.GetDiagnosedMemberAccess(); if (memberAccess == null) { return; } var usingNamespace = "CMS.Helpers"; var newMemberAccess = SyntaxFactory.ParseExpression("SessionHelper.GetSessionID()"); context.RegisterCodeFix( CodeAction.Create( title: CodeFixMessagesProvider.GetReplaceWithMessage(newMemberAccess), createChangedDocument: c => editor.ReplaceExpressionWith(memberAccess, newMemberAccess, c, usingNamespace), equivalenceKey: nameof(HttpSessionSessionIdCodeFixProvider)), diagnostic); }
/// <inheritdoc /> public sealed override async Task RegisterCodeFixesAsync(CodeFixContext context) { var codeFixHelper = new MemberInvocationCodeFixHelper(context); var diagnostic = codeFixHelper.GetFirstDiagnostic(); var invocationExpression = await codeFixHelper.GetDiagnosedInvocation(); if (invocationExpression == null) { return; } var oldArgument = invocationExpression.ArgumentList.Arguments.First(); var newArgumentName = GetNewMethodArgument(oldArgument); if (newArgumentName == null) { return; } context.RegisterCodeFix( CodeAction.Create( title: CodeFixMessagesProvider.GetReplaceWithMessage(newArgumentName), createChangedDocument: c => codeFixHelper.ReplaceExpressionWith(oldArgument, newArgumentName, c, "CMS.EventLog"), equivalenceKey: nameof(EventLogArgumentsCodeFixProvider)), diagnostic); }
/// <inheritdoc /> public sealed override async Task RegisterCodeFixesAsync(CodeFixContext context) { var diagnostic = context.Diagnostics.First(); var diagnosticSpan = diagnostic.Location.SourceSpan; var editor = new CodeFixHelper(context); var root = await context.Document.GetSyntaxRootAsync(context.CancellationToken); var diagnosedNode = root.FindNode(diagnosticSpan).FirstAncestorOrSelf <QualifiedNameSyntax>() ?? (NameSyntax)root.FindNode(diagnosticSpan).FirstAncestorOrSelf <IdentifierNameSyntax>(); if (diagnosedNode == null) { return; } const string usingNamespace = "CMS.DataEngine"; var newIdentifierNameNode = SyntaxFactory.ParseExpression("ISearchDocument"); context.RegisterCodeFix( CodeAction.Create( title: CodeFixMessagesProvider.GetReplaceWithMessage(newIdentifierNameNode), createChangedDocument: c => editor.ReplaceExpressionWith(diagnosedNode, newIdentifierNameNode, c, usingNamespace), equivalenceKey: nameof(LuceneSearchDocumentCodeFixProvider)), diagnostic); }
/// <inheritdoc /> public sealed override async Task RegisterCodeFixesAsync(CodeFixContext context) { var editor = new MemberInvocationCodeFixHelper(context); var invocation = await editor.GetDiagnosedInvocation(); if (invocation == null) { return; } var diagnostic = context.Diagnostics.First(); var newInvocation1 = GetNewInvocationWithInvariantMethod(invocation); var newInvocation2 = GetNewInvocationWithCultureInfoParameter(invocation); context.RegisterCodeFix( CodeAction.Create( title: CodeFixMessagesProvider.GetReplaceWithMessage(newInvocation1), createChangedDocument: c => editor.ReplaceExpressionWith(invocation, newInvocation1, c), equivalenceKey: $"{nameof(StringManipulationMethodsCodeFixProvider)}-InvariantCulture"), diagnostic); context.RegisterCodeFix( CodeAction.Create( title: CodeFixMessagesProvider.GetReplaceWithMessage(newInvocation2), createChangedDocument: c => editor.ReplaceExpressionWith(invocation, newInvocation2, c, "System.Globalization"), equivalenceKey: $"{nameof(StringManipulationMethodsCodeFixProvider)}-CurrentCulture"), diagnostic); }
/// <inheritdoc /> public sealed override async Task RegisterCodeFixesAsync(CodeFixContext context) { var editor = new MemberInvocationCodeFixHelper(context); // invoked always statically no need for conditional access filtering var invocationExpression = await editor.GetDiagnosedInvocation(); if (invocationExpression == null || !invocationExpression.Expression.IsKind(SyntaxKind.SimpleMemberAccessExpression)) { return; } var usingNamespace = "CMS.Membership"; // parenthesis (for method invocation) will be reused from previous code var newExpressionBody = SyntaxFactory.ParseExpression("AuthenticationHelper.SignOut"); var diagnostic = context.Diagnostics.First(); context.RegisterCodeFix( CodeAction.Create( title: CodeFixMessagesProvider.GetReplaceWithMessage(newExpressionBody), createChangedDocument: c => editor.ReplaceExpressionWith(invocationExpression.Expression, newExpressionBody, c, usingNamespace), equivalenceKey: nameof(FormsAuthenticationSignOutCodeFixProvider)), diagnostic); }
/// <inheritdoc /> public sealed override async Task RegisterCodeFixesAsync(CodeFixContext context) { var editor = new MemberInvocationCodeFixHelper(context); var invocationExpression = await editor.GetDiagnosedInvocation(); if (invocationExpression == null) { return; } var argumentsToSustain = invocationExpression.ArgumentList.Arguments.Take(2).ToArray(); var newInvocation = SyntaxFactory.InvocationExpression( SyntaxFactory.ParseExpression($"{invocationExpression.Expression}System")); newInvocation = newInvocation.AppendArguments(argumentsToSustain); var diagnostic = context.Diagnostics.First(); context.RegisterCodeFix( CodeAction.Create( title: CodeFixMessagesProvider.GetReplaceWithMessage(newInvocation), createChangedDocument: c => editor.ReplaceExpressionWith(invocationExpression, newInvocation, c, "CMS.Helpers"), equivalenceKey: nameof(ValidationHelperGetCodeFixProvider)), diagnostic); }
private void RegisterCodeFixVariant(CodeFixContext context, CodeFixHelper codeFixHelper, SimpleNameSyntax oldMethodName, SimpleNameSyntax newMethodName) { context.RegisterCodeFix( CodeAction.Create( title: CodeFixMessagesProvider.GetReplaceWithMessage(newMethodName), createChangedDocument: c => codeFixHelper.ReplaceExpressionWith(oldMethodName, newMethodName, c), equivalenceKey: newMethodName.ToString()), codeFixHelper.GetFirstDiagnostic()); }
/// <inheritdoc /> public sealed override async Task RegisterCodeFixesAsync(CodeFixContext context) { var editor = new MemberInvocationCodeFixHelper(context); var diagnostic = editor.GetFirstDiagnostic(); if (diagnostic.IsMarkedAsConditionalAccess()) { // currently no support for fixing complicated cases with Conditional Access return; } var invocation = await editor.GetDiagnosedInvocation(); if (invocation == null || !invocation.Expression.IsKind(SyntaxKind.SimpleMemberAccessExpression)) { return; } // only apply codefix if invocation is placed in class inheriting from System.Web.Ui.Control // since as first argument we add 'this' and it has to have right type var enclosingClassName = invocation.FirstAncestorOrSelf <ClassDeclarationSyntax>(); if (enclosingClassName == null) { return; } var semanticModel = await context.Document.GetSemanticModelAsync(); var enclosingClassType = semanticModel.GetDeclaredSymbol(enclosingClassName); var uiControlType = "System.Web.UI.Control"; if (enclosingClassType == null || !enclosingClassType.IsDerivedFrom(uiControlType, semanticModel.Compilation)) { return; } var usingNamespace = "CMS.Base.Web.UI"; var newInvocationExpression = GetNewInvocationExpression(invocation); if (newInvocationExpression == null) { return; } context.RegisterCodeFix( CodeAction.Create( title: CodeFixMessagesProvider.GetReplaceWithMessage(newInvocationExpression), createChangedDocument: c => editor.ReplaceExpressionWith(invocation, newInvocationExpression, c, usingNamespace), equivalenceKey: nameof(ClientScriptMethodsCodeFixProvider)), diagnostic); }
/// <inheritdoc /> public sealed override async Task RegisterCodeFixesAsync(CodeFixContext context) { var editor = new MemberInvocationCodeFixHelper(context); var invocation = await editor.GetDiagnosedInvocation(); if (invocation == null) { return; } const string namespacesToBeReferenced = "System"; var tempInvocation = invocation; var stringComparisonOptions = StringComparisonOptions.GetAll(); // if it was diagnosed and overload with three or six arguments is called it must be: // public static int Compare(string strA, string strB, bool ignoreCase) // OR // public static int Compare(string strA, int indexA, string strB, int indexB, int length, bool ignoreCase) // therefore we will apply only suitable fixes var originalArguments = invocation.ArgumentList.Arguments; if (originalArguments.Count == 3 || originalArguments.Count == 6) { var ignoreCaseAttribute = originalArguments.Last().Expression.ToString(); bool ignoreCase; if (!bool.TryParse(ignoreCaseAttribute, out ignoreCase)) { // could not detect value of 'ignoreCase' argument -> no codefix provided return; } // delete last argument of the previous invocation tempInvocation = tempInvocation.WithArgumentList(SyntaxFactory.ArgumentList(originalArguments.RemoveAt(originalArguments.Count - 1))); stringComparisonOptions = ignoreCase ? StringComparisonOptions.GetCaseInsensitive() : StringComparisonOptions.GetCaseSensitive(); } foreach (var stringComparisonOption in stringComparisonOptions) { var newInvocation = tempInvocation.AppendArguments(stringComparisonOption); context.RegisterCodeFix( CodeAction.Create( title: CodeFixMessagesProvider.GetReplaceWithMessage(newInvocation), createChangedDocument: c => editor.ReplaceExpressionWith(invocation, newInvocation, c, namespacesToBeReferenced), equivalenceKey: $"{nameof(StringCompareStaticMethodCodeFixProvider)}-{stringComparisonOption}"), context.Diagnostics.First()); } }
/// <inheritdoc /> public sealed override async Task RegisterCodeFixesAsync(CodeFixContext context) { var diagnostic = context.Diagnostics.First(); if (!diagnostic.IsMarkedAsSimpleMemberAccess()) { // no support yet for complicated cases as conditional access return; } var editor = new MemberInvocationCodeFixHelper(context); var invocationExpression = await editor.GetDiagnosedInvocation(); if (invocationExpression == null || !invocationExpression.Expression.IsKind(SyntaxKind.SimpleMemberAccessExpression)) { return; } var usingNamespace = "CMS.Helpers"; var codeFix1 = SyntaxFactory.InvocationExpression(SyntaxFactory.ParseExpression("URLHelper.Redirect"), invocationExpression.ArgumentList); var codeFix2 = SyntaxFactory.InvocationExpression(SyntaxFactory.ParseExpression("URLHelper.LocalRedirect"), invocationExpression.ArgumentList); var message1 = $"{CodeFixMessagesProvider.GetReplaceWithMessage(codeFix2)} {CmsApiReplacementsResources.RedirectCodeFixLocal}"; var message2 = $"{CodeFixMessagesProvider.GetReplaceWithMessage(codeFix2)} {CmsApiReplacementsResources.RedirectCodeFixExternal}"; context.RegisterCodeFix( CodeAction.Create( title: message1, createChangedDocument: c => editor.ReplaceExpressionWith(invocationExpression, codeFix1, c, usingNamespace), equivalenceKey: nameof(HttpResponseRedirectCodeFixProvider)), diagnostic); context.RegisterCodeFix( CodeAction.Create( title: message2, createChangedDocument: c => editor.ReplaceExpressionWith(invocationExpression, codeFix2, c, usingNamespace), equivalenceKey: nameof(HttpResponseRedirectCodeFixProvider) + "Local"), diagnostic); }
/// <inheritdoc /> public sealed override async Task RegisterCodeFixesAsync(CodeFixContext context) { var editor = new MemberInvocationCodeFixHelper(context); var invocation = await editor.GetDiagnosedInvocation(); if (!IsFixable(invocation)) { return; } var memberAccess = (MemberAccessExpressionSyntax)invocation.Expression; if (IsChainedMemberAccesses(memberAccess)) { // if this is the case, we cannot apply codefix directly as it is a static method call // new variable needs to be introduced to keep the result of the call // this variable would be later used in member access chain return; } const string namespacesToBeReferenced = "System"; var firstString = SyntaxFactory.Argument(memberAccess.Expression); var secondString = invocation.ArgumentList.Arguments.First(); var staticInvocation = SyntaxFactory.ParseExpression("string.Compare()") as InvocationExpressionSyntax; foreach (var stringComparisonOption in StringComparisonOptions.GetAll()) { var newInvocation = staticInvocation.AppendArguments(firstString, secondString).AppendArguments(stringComparisonOption); context.RegisterCodeFix( CodeAction.Create( title: CodeFixMessagesProvider.GetReplaceWithMessage(newInvocation), createChangedDocument: c => editor.ReplaceExpressionWith(invocation, newInvocation, c, namespacesToBeReferenced), equivalenceKey: $"{nameof(StringCompareToMethodCodeFixProvider)}-{stringComparisonOption}"), context.Diagnostics.First()); } }
/// <inheritdoc /> public sealed override async Task RegisterCodeFixesAsync(CodeFixContext context) { var editor = new MemberInvocationCodeFixHelper(context); var invocation = await editor.GetDiagnosedInvocation(); if (invocation == null) { return; } const string namespacesToBeReferenced = "System"; foreach (var stringComparisonOption in StringComparisonOptions.GetAll()) { var newInvocation = invocation.AppendArguments(stringComparisonOption); context.RegisterCodeFix( CodeAction.Create( title: CodeFixMessagesProvider.GetReplaceWithMessage(newInvocation), createChangedDocument: c => editor.ReplaceExpressionWith(invocation, newInvocation, c, namespacesToBeReferenced), equivalenceKey: $"{nameof(StringComparisonMethodsWithModifierCodeFixProvider)}-{stringComparisonOption}"), context.Diagnostics.First()); } }