Skip to content

Correctly map SuggestedCorrection to MarkerCorrection #1749

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 3 commits into from
Mar 31, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -208,22 +208,20 @@ public async Task<string> GetCommentHelpText(string functionText, string helpLoc

ScriptFileMarker[] analysisResults = await AnalysisEngine.AnalyzeScriptAsync(functionText, commentHelpSettings).ConfigureAwait(false);

if (analysisResults.Length == 0
|| analysisResults[0]?.Correction?.Edits == null
|| analysisResults[0].Correction.Edits.Length == 0)
if (analysisResults.Length == 0 || !analysisResults[0].Corrections.Any())
{
return null;
}

return analysisResults[0].Correction.Edits[0].Text;
return analysisResults[0].Corrections.First().Edit.Text;
}

/// <summary>
/// Get the most recent corrections computed for a given script file.
/// </summary>
/// <param name="documentUri">The URI string of the file to get code actions for.</param>
/// <returns>A threadsafe readonly dictionary of the code actions of the particular file.</returns>
public async Task<IReadOnlyDictionary<string, MarkerCorrection>> GetMostRecentCodeActionsForFileAsync(DocumentUri uri)
public async Task<IReadOnlyDictionary<string, IEnumerable<MarkerCorrection>>> GetMostRecentCodeActionsForFileAsync(DocumentUri uri)
{
if (!_workspaceService.TryGetFile(uri, out ScriptFile file)
|| !_mostRecentCorrectionsByFile.TryGetValue(file, out CorrectionTableEntry corrections))
Expand Down Expand Up @@ -404,10 +402,10 @@ private void PublishScriptDiagnostics(ScriptFile scriptFile, IReadOnlyList<Scrip

Diagnostic diagnostic = GetDiagnosticFromMarker(marker);

if (marker.Correction != null)
if (marker.Corrections is not null)
{
string diagnosticId = GetUniqueIdFromDiagnostic(diagnostic);
fileCorrections.Corrections[diagnosticId] = marker.Correction;
fileCorrections.Corrections[diagnosticId] = marker.Corrections;
}

diagnostics[i] = diagnostic;
Expand Down Expand Up @@ -511,11 +509,11 @@ private class CorrectionTableEntry

public CorrectionTableEntry()
{
Corrections = new ConcurrentDictionary<string, MarkerCorrection>();
Corrections = new ConcurrentDictionary<string, IEnumerable<MarkerCorrection>>();
DiagnosticPublish = Task.CompletedTask;
}

public ConcurrentDictionary<string, MarkerCorrection> Corrections { get; }
public ConcurrentDictionary<string, IEnumerable<MarkerCorrection>> Corrections { get; }

public Task DiagnosticPublish { get; set; }
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,7 @@ public override async Task<CommandOrCodeActionContainer> Handle(CodeActionParams
return Array.Empty<CommandOrCodeAction>();
}

IReadOnlyDictionary<string, MarkerCorrection> corrections = await _analysisService.GetMostRecentCodeActionsForFileAsync(
IReadOnlyDictionary<string, IEnumerable<MarkerCorrection>> corrections = await _analysisService.GetMostRecentCodeActionsForFileAsync(
request.TextDocument.Uri)
.ConfigureAwait(false);

Expand All @@ -75,13 +75,13 @@ public override async Task<CommandOrCodeActionContainer> Handle(CodeActionParams
}

string diagnosticId = AnalysisService.GetUniqueIdFromDiagnostic(diagnostic);
if (corrections.TryGetValue(diagnosticId, out MarkerCorrection correction))
if (corrections.TryGetValue(diagnosticId, out IEnumerable<MarkerCorrection> markerCorrections))
{
foreach (ScriptRegion edit in correction.Edits)
foreach (MarkerCorrection markerCorrection in markerCorrections)
{
codeActions.Add(new CodeAction
{
Title = correction.Name,
Title = markerCorrection.Name,
Kind = CodeActionKind.QuickFix,
Edit = new WorkspaceEdit
{
Expand All @@ -93,7 +93,7 @@ public override async Task<CommandOrCodeActionContainer> Handle(CodeActionParams
{
Uri = request.TextDocument.Uri
},
Edits = new TextEditContainer(ScriptRegion.ToTextEdit(edit))
Edits = new TextEditContainer(ScriptRegion.ToTextEdit(markerCorrection.Edit))
}))
}
});
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,9 +21,9 @@ public sealed class MarkerCorrection
public string Name { get; set; }

/// <summary>
/// Gets or sets the list of ScriptRegions that define the edits to be made by the correction.
/// Gets or sets the ScriptRegion that define the edit to be made by the correction.
/// </summary>
public ScriptRegion[] Edits { get; set; }
public ScriptRegion Edit { get; set; }
}

/// <summary>
Expand Down Expand Up @@ -79,9 +79,9 @@ public class ScriptFileMarker
public ScriptRegion ScriptRegion { get; set; }

/// <summary>
/// Gets or sets an optional code correction that can be applied based on this marker.
/// Gets or sets a optional code corrections that can be applied based on its marker.
/// </summary>
public MarkerCorrection Correction { get; set; }
public IEnumerable<MarkerCorrection> Corrections { get; set; }

/// <summary>
/// Gets or sets the name of the marker's source like "PowerShell"
Expand Down Expand Up @@ -110,7 +110,6 @@ internal static ScriptFileMarker FromParseError(
internal static ScriptFileMarker FromDiagnosticRecord(PSObject psObject)
{
Validate.IsNotNull(nameof(psObject), psObject);
MarkerCorrection correction = null;

// make sure psobject is of type DiagnosticRecord
if (!psObject.TypeNames.Contains(
Expand All @@ -124,32 +123,25 @@ internal static ScriptFileMarker FromDiagnosticRecord(PSObject psObject)
// the diagnostic record's properties directly i.e. <instance>.<propertyName>
// without having to go through PSObject's Members property.
dynamic diagnosticRecord = psObject;

List<MarkerCorrection> markerCorrections = new();
if (diagnosticRecord.SuggestedCorrections != null)
{
List<ScriptRegion> editRegions = new();
string correctionMessage = null;
foreach (dynamic suggestedCorrection in diagnosticRecord.SuggestedCorrections)
{
editRegions.Add(
new ScriptRegion(
diagnosticRecord.ScriptPath,
suggestedCorrection.Text,
startLineNumber: suggestedCorrection.StartLineNumber,
startColumnNumber: suggestedCorrection.StartColumnNumber,
endLineNumber: suggestedCorrection.EndLineNumber,
endColumnNumber: suggestedCorrection.EndColumnNumber,
startOffset: -1,
endOffset: -1));

correctionMessage = suggestedCorrection.Description;
markerCorrections.Add(new MarkerCorrection
{
Name = suggestedCorrection.Description ?? diagnosticRecord.Message,
Edit = new ScriptRegion(
diagnosticRecord.ScriptPath,
suggestedCorrection.Text,
startLineNumber: suggestedCorrection.StartLineNumber,
startColumnNumber: suggestedCorrection.StartColumnNumber,
startOffset: -1,
endLineNumber: suggestedCorrection.EndLineNumber,
endColumnNumber: suggestedCorrection.EndColumnNumber,
endOffset: -1),
});
}

correction = new MarkerCorrection
{
Name = correctionMessage ?? diagnosticRecord.Message,
Edits = editRegions.ToArray()
};
}

string severity = diagnosticRecord.Severity.ToString();
Expand All @@ -166,7 +158,7 @@ internal static ScriptFileMarker FromDiagnosticRecord(PSObject psObject)
RuleName = diagnosticRecord.RuleName as string ?? string.Empty,
Level = level,
ScriptRegion = ScriptRegion.Create(diagnosticRecord.Extent as IScriptExtent),
Correction = correction,
Corrections = markerCorrections,
Source = "PSScriptAnalyzer"
};
}
Expand Down