private void AddComponentAccessFromTag(RazorCodeActionContext context, MarkupStartTagSyntax startTag, List <RazorCodeAction> container) { var matching = FindMatchingTagHelpers(context, startTag); // For all the matches, add options for add @using and fully qualify foreach (var tagHelperPair in matching.Values) { if (tagHelperPair._fullyQualified is null) { continue; } var fullyQualifiedName = tagHelperPair._short.Name; // Insert @using if (AddUsingsCodeActionProviderHelper.TryCreateAddUsingResolutionParams(fullyQualifiedName, context.Request.TextDocument.Uri, out var @namespace, out var resolutionParams)) { var addUsingCodeAction = RazorCodeActionFactory.CreateAddComponentUsing(@namespace, resolutionParams); container.Add(addUsingCodeAction); } // Fully qualify var renameTagWorkspaceEdit = CreateRenameTagEdit(context, startTag, fullyQualifiedName); var fullyQualifiedCodeAction = RazorCodeActionFactory.CreateFullyQualifyComponent(fullyQualifiedName, renameTagWorkspaceEdit); container.Add(fullyQualifiedCodeAction); } }
public void TryCreateAddUsingResolutionParams_CreatesResolutionParams() { // Arrange var fqn = "Abc.Xyz"; var docUri = DocumentUri.From("c:/path"); // Act var result = AddUsingsCodeActionProviderHelper.TryCreateAddUsingResolutionParams(fqn, docUri, out var @namespace, out var resolutionParams); // Assert Assert.True(result); Assert.Equal("Abc", @namespace); Assert.NotNull(resolutionParams); }
private static IEnumerable <RazorCodeAction> ProcessCodeActionsVSCode( RazorCodeActionContext context, IEnumerable <RazorCodeAction> codeActions) { var diagnostics = context.Request.Context.Diagnostics.Where(diagnostic => diagnostic.Severity == DiagnosticSeverity.Error && diagnostic.Code?.IsString == true && s_supportedDiagnostics.Any(d => diagnostic.Code.Value.String.Equals(d, StringComparison.OrdinalIgnoreCase))); if (diagnostics is null || !diagnostics.Any()) { return(Array.Empty <RazorCodeAction>()); } var typeAccessibilityCodeActions = new List <RazorCodeAction>(); foreach (var diagnostic in diagnostics) { // Corner case handling for diagnostics which (momentarily) linger after // @code block is cleared out if (diagnostic.Range.End.Line > context.SourceText.Lines.Count || diagnostic.Range.End.Character > context.SourceText.Lines[diagnostic.Range.End.Line].End) { continue; } var diagnosticSpan = diagnostic.Range.AsTextSpan(context.SourceText); // Based on how we compute `Range.AsTextSpan` it's possible to have a span // which goes beyond the end of the source text. Something likely changed // between the capturing of the diagnostic (by the platform) and the retrieval of the // document snapshot / source text. In such a case, we skip processing of the diagnostic. if (diagnosticSpan.End > context.SourceText.Length) { continue; } foreach (var codeAction in codeActions) { if (!codeAction.Name.Equals(LanguageServerConstants.CodeActions.CodeActionFromVSCode, StringComparison.Ordinal)) { continue; } var associatedValue = context.SourceText.GetSubTextString(diagnosticSpan); var fqn = string.Empty; // When there's only one FQN suggestion, code action title is of the form: // `System.Net.Dns` if (!codeAction.Title.Any(c => char.IsWhiteSpace(c)) && codeAction.Title.EndsWith(associatedValue, StringComparison.OrdinalIgnoreCase)) { fqn = codeAction.Title; } // When there are multiple FQN suggestions, the code action title is of the form: // `Fully qualify 'Dns' -> System.Net.Dns` else { var expectedCodeActionPrefix = $"Fully qualify '{associatedValue}' -> "; if (codeAction.Title.StartsWith(expectedCodeActionPrefix, StringComparison.OrdinalIgnoreCase)) { fqn = codeAction.Title.Substring(expectedCodeActionPrefix.Length); } } if (string.IsNullOrEmpty(fqn)) { continue; } var fqnCodeAction = CreateFQNCodeAction(context, diagnostic, codeAction, fqn); typeAccessibilityCodeActions.Add(fqnCodeAction); if (AddUsingsCodeActionProviderHelper.TryCreateAddUsingResolutionParams(fqn, context.Request.TextDocument.Uri, out var @namespace, out var resolutionParams)) { var addUsingCodeAction = RazorCodeActionFactory.CreateAddComponentUsing(@namespace, resolutionParams); typeAccessibilityCodeActions.Add(addUsingCodeAction); } } } return(typeAccessibilityCodeActions); }