|
8 | 8 | "github.com/microsoft/typescript-go/shim/ast"
|
9 | 9 | "github.com/microsoft/typescript-go/shim/bundled"
|
10 | 10 | "github.com/microsoft/typescript-go/shim/compiler"
|
| 11 | + "github.com/microsoft/typescript-go/shim/core" |
11 | 12 | "github.com/microsoft/typescript-go/shim/scanner"
|
12 | 13 | "github.com/microsoft/typescript-go/shim/tspath"
|
13 | 14 | "github.com/microsoft/typescript-go/shim/vfs/cachedvfs"
|
@@ -138,7 +139,7 @@ func (h *IPCHandler) HandleLint(req api.LintRequest) (*api.LintResponse, error)
|
138 | 139 | // Convert TextRange to character positions
|
139 | 140 | startPos := fix.Range.Pos()
|
140 | 141 | endPos := fix.Range.End()
|
141 |
| - |
| 142 | + |
142 | 143 | fixes = append(fixes, api.Fix{
|
143 | 144 | Text: fix.Text,
|
144 | 145 | StartPos: startPos,
|
@@ -189,53 +190,73 @@ func (h *IPCHandler) HandleLint(req api.LintRequest) (*api.LintResponse, error)
|
189 | 190 |
|
190 | 191 | // HandleApplyFixes handles apply fixes requests in IPC mode
|
191 | 192 | func (h *IPCHandler) HandleApplyFixes(req api.ApplyFixesRequest) (*api.ApplyFixesResponse, error) {
|
192 |
| - |
193 |
| - // Apply fixes directly using the client-provided fix data |
194 |
| - var appliedCount int |
195 |
| - var unappliedCount int |
196 |
| - wasFixed := false |
197 |
| - |
198 |
| - // Collect all fixes |
199 |
| - var allFixes []struct { |
200 |
| - startPos int |
201 |
| - endPos int |
202 |
| - text string |
203 |
| - } |
204 |
| - |
| 193 | + // Convert API diagnostics to rule diagnostics for use with linter.ApplyRuleFixes |
| 194 | + var ruleDiagnostics []rule.RuleDiagnostic |
| 195 | + |
205 | 196 | for _, clientDiag := range req.Diagnostics {
|
| 197 | + if len(clientDiag.Fixes) == 0 { |
| 198 | + continue |
| 199 | + } |
| 200 | + |
| 201 | + // Convert API fixes to rule fixes |
| 202 | + var ruleFixes []rule.RuleFix |
206 | 203 | for _, clientFix := range clientDiag.Fixes {
|
207 |
| - allFixes = append(allFixes, struct { |
208 |
| - startPos int |
209 |
| - endPos int |
210 |
| - text string |
211 |
| - }{ |
212 |
| - startPos: clientFix.StartPos, |
213 |
| - endPos: clientFix.EndPos, |
214 |
| - text: clientFix.Text, |
215 |
| - }) |
| 204 | + // Create TextRange from start and end positions |
| 205 | + textRange := core.NewTextRange(clientFix.StartPos, clientFix.EndPos) |
| 206 | + |
| 207 | + ruleFix := rule.RuleFix{ |
| 208 | + Text: clientFix.Text, |
| 209 | + Range: textRange, |
| 210 | + } |
| 211 | + ruleFixes = append(ruleFixes, ruleFix) |
216 | 212 | }
|
| 213 | + |
| 214 | + // Create rule diagnostic |
| 215 | + ruleDiag := rule.RuleDiagnostic{ |
| 216 | + Range: core.NewTextRange(0, 0), // Not used by ApplyRuleFixes |
| 217 | + RuleName: clientDiag.RuleName, |
| 218 | + Message: rule.RuleMessage{ |
| 219 | + Id: clientDiag.MessageId, |
| 220 | + Description: clientDiag.Message, |
| 221 | + }, |
| 222 | + FixesPtr: &ruleFixes, |
| 223 | + } |
| 224 | + |
| 225 | + ruleDiagnostics = append(ruleDiagnostics, ruleDiag) |
217 | 226 | }
|
| 227 | + |
| 228 | + // Use linter.ApplyRuleFixes to apply the fixes |
| 229 | + code := req.FileContent |
| 230 | + outputs := []string{} |
| 231 | + wasFixed := false |
218 | 232 |
|
219 |
| - // Apply fixes from end to beginning to avoid position shifting |
220 |
| - fixedContent := req.FileContent |
221 |
| - for i := len(allFixes) - 1; i >= 0; i-- { |
222 |
| - fix := allFixes[i] |
223 |
| - if fix.startPos >= 0 && fix.endPos <= len(fixedContent) && fix.startPos < fix.endPos { |
224 |
| - // Apply the fix |
225 |
| - fixedContent = fixedContent[:fix.startPos] + fix.text + fixedContent[fix.endPos:] |
226 |
| - appliedCount++ |
227 |
| - wasFixed = true |
228 |
| - } else { |
229 |
| - unappliedCount++ |
| 233 | + // Apply fixes iteratively to handle overlapping fixes |
| 234 | + for { |
| 235 | + fixedContent,unapplied, fixed := linter.ApplyRuleFixes(code, ruleDiagnostics) |
| 236 | + if !fixed { |
| 237 | + break |
| 238 | + } |
| 239 | + |
| 240 | + outputs = append(outputs, fixedContent) |
| 241 | + code = fixedContent |
| 242 | + wasFixed = true |
| 243 | + |
| 244 | + // Update diagnostics to only include unapplied ones for next iteration |
| 245 | + ruleDiagnostics = unapplied |
| 246 | + if len(ruleDiagnostics) == 0 { |
| 247 | + break |
230 | 248 | }
|
231 | 249 | }
|
232 |
| - |
233 |
| - |
| 250 | + |
| 251 | + // Count applied and unapplied fixes |
| 252 | + appliedCount := len(req.Diagnostics) - len(ruleDiagnostics) |
| 253 | + unappliedCount := len(ruleDiagnostics) |
| 254 | + |
234 | 255 | return &api.ApplyFixesResponse{
|
235 |
| - FixedContent: fixedContent, |
236 |
| - WasFixed: wasFixed, |
237 |
| - AppliedCount: appliedCount, |
238 |
| - UnappliedCount: unappliedCount, |
| 256 | + FixedContent: outputs, |
| 257 | + WasFixed: wasFixed, |
| 258 | + AppliedCount: appliedCount, |
| 259 | + UnappliedCount: unappliedCount, |
239 | 260 | }, nil
|
240 | 261 | }
|
241 | 262 |
|
|
0 commit comments