@@ -19,13 +19,16 @@ import (
1919 errors "golang.org/x/xerrors"
2020)
2121
22- // SuggestedFixFunc is a function used to get the suggested fixes for a given
23- // gopls command, some of which are provided by go/analysis.Analyzers. Some of
24- // the analyzers in internal/lsp/analysis are not efficient enough to include
25- // suggested fixes with their diagnostics, so we have to compute them
26- // separately. Such analyzers should provide a function with a signature of
27- // SuggestedFixFunc.
28- type SuggestedFixFunc func (fset * token.FileSet , rng span.Range , src []byte , file * ast.File , pkg * types.Package , info * types.Info ) (* analysis.SuggestedFix , error )
22+ type (
23+ // SuggestedFixFunc is a function used to get the suggested fixes for a given
24+ // gopls command, some of which are provided by go/analysis.Analyzers. Some of
25+ // the analyzers in internal/lsp/analysis are not efficient enough to include
26+ // suggested fixes with their diagnostics, so we have to compute them
27+ // separately. Such analyzers should provide a function with a signature of
28+ // SuggestedFixFunc.
29+ SuggestedFixFunc func (ctx context.Context , snapshot Snapshot , fh VersionedFileHandle , pRng protocol.Range ) (* analysis.SuggestedFix , error )
30+ singleFileFixFunc func (fset * token.FileSet , rng span.Range , src []byte , file * ast.File , pkg * types.Package , info * types.Info ) (* analysis.SuggestedFix , error )
31+ )
2932
3033const (
3134 FillStruct = "fill_struct"
@@ -37,11 +40,22 @@ const (
3740
3841// suggestedFixes maps a suggested fix command id to its handler.
3942var suggestedFixes = map [string ]SuggestedFixFunc {
40- FillStruct : fillstruct .SuggestedFix ,
41- UndeclaredName : undeclaredname .SuggestedFix ,
42- ExtractVariable : extractVariable ,
43- ExtractFunction : extractFunction ,
44- ExtractMethod : extractMethod ,
43+ FillStruct : singleFile (fillstruct .SuggestedFix ),
44+ UndeclaredName : singleFile (undeclaredname .SuggestedFix ),
45+ ExtractVariable : singleFile (extractVariable ),
46+ ExtractFunction : singleFile (extractFunction ),
47+ ExtractMethod : singleFile (extractMethod ),
48+ }
49+
50+ // singleFile calls analyzers that expect inputs for a single file
51+ func singleFile (sf singleFileFixFunc ) SuggestedFixFunc {
52+ return func (ctx context.Context , snapshot Snapshot , fh VersionedFileHandle , pRng protocol.Range ) (* analysis.SuggestedFix , error ) {
53+ fset , rng , src , file , pkg , info , err := getAllSuggestedFixInputs (ctx , snapshot , fh , pRng )
54+ if err != nil {
55+ return nil , err
56+ }
57+ return sf (fset , rng , src , file , pkg , info )
58+ }
4559}
4660
4761func SuggestedFixFromCommand (cmd protocol.Command , kind protocol.CodeActionKind ) SuggestedFix {
@@ -59,55 +73,66 @@ func ApplyFix(ctx context.Context, fix string, snapshot Snapshot, fh VersionedFi
5973 if ! ok {
6074 return nil , fmt .Errorf ("no suggested fix function for %s" , fix )
6175 }
62- fset , rng , src , file , m , pkg , info , err := getAllSuggestedFixInputs (ctx , snapshot , fh , pRng )
63- if err != nil {
64- return nil , err
65- }
66- suggestion , err := handler (fset , rng , src , file , pkg , info )
76+ suggestion , err := handler (ctx , snapshot , fh , pRng )
6777 if err != nil {
6878 return nil , err
6979 }
7080 if suggestion == nil {
7181 return nil , nil
7282 }
73-
74- var edits [] protocol.TextEdit
83+ fset := snapshot . FileSet ()
84+ editsPerFile := map [span. URI ] * protocol.TextDocumentEdit {}
7585 for _ , edit := range suggestion .TextEdits {
76- rng := span .NewRange (fset , edit .Pos , edit .End )
77- spn , err := rng .Span ()
86+ spn , err := span .NewRange (fset , edit .Pos , edit .End ).Span ()
7887 if err != nil {
7988 return nil , err
8089 }
81- clRng , err := m .Range (spn )
90+ fh , err := snapshot .GetVersionedFile (ctx , spn .URI ())
91+ if err != nil {
92+ return nil , err
93+ }
94+ te , ok := editsPerFile [spn .URI ()]
95+ if ! ok {
96+ te = & protocol.TextDocumentEdit {
97+ TextDocument : protocol.OptionalVersionedTextDocumentIdentifier {
98+ Version : fh .Version (),
99+ TextDocumentIdentifier : protocol.TextDocumentIdentifier {
100+ URI : protocol .URIFromSpanURI (fh .URI ()),
101+ },
102+ },
103+ }
104+ editsPerFile [spn .URI ()] = te
105+ }
106+ _ , pgf , err := GetParsedFile (ctx , snapshot , fh , NarrowestPackage )
82107 if err != nil {
83108 return nil , err
84109 }
85- edits = append (edits , protocol.TextEdit {
86- Range : clRng ,
110+ rng , err := pgf .Mapper .Range (spn )
111+ if err != nil {
112+ return nil , err
113+ }
114+ te .Edits = append (te .Edits , protocol.TextEdit {
115+ Range : rng ,
87116 NewText : string (edit .NewText ),
88117 })
89118 }
90- return []protocol.TextDocumentEdit {{
91- TextDocument : protocol.OptionalVersionedTextDocumentIdentifier {
92- Version : fh .Version (),
93- TextDocumentIdentifier : protocol.TextDocumentIdentifier {
94- URI : protocol .URIFromSpanURI (fh .URI ()),
95- },
96- },
97- Edits : edits ,
98- }}, nil
119+ var edits []protocol.TextDocumentEdit
120+ for _ , edit := range editsPerFile {
121+ edits = append (edits , * edit )
122+ }
123+ return edits , nil
99124}
100125
101126// getAllSuggestedFixInputs is a helper function to collect all possible needed
102127// inputs for an AppliesFunc or SuggestedFixFunc.
103- func getAllSuggestedFixInputs (ctx context.Context , snapshot Snapshot , fh FileHandle , pRng protocol.Range ) (* token.FileSet , span.Range , []byte , * ast.File , * protocol. ColumnMapper , * types.Package , * types.Info , error ) {
128+ func getAllSuggestedFixInputs (ctx context.Context , snapshot Snapshot , fh FileHandle , pRng protocol.Range ) (* token.FileSet , span.Range , []byte , * ast.File , * types.Package , * types.Info , error ) {
104129 pkg , pgf , err := GetParsedFile (ctx , snapshot , fh , NarrowestPackage )
105130 if err != nil {
106- return nil , span.Range {}, nil , nil , nil , nil , nil , errors .Errorf ("getting file for Identifier: %w" , err )
131+ return nil , span.Range {}, nil , nil , nil , nil , errors .Errorf ("getting file for Identifier: %w" , err )
107132 }
108133 rng , err := pgf .Mapper .RangeToSpanRange (pRng )
109134 if err != nil {
110- return nil , span.Range {}, nil , nil , nil , nil , nil , err
135+ return nil , span.Range {}, nil , nil , nil , nil , err
111136 }
112- return snapshot .FileSet (), rng , pgf .Src , pgf .File , pgf . Mapper , pkg .GetTypes (), pkg .GetTypesInfo (), nil
137+ return snapshot .FileSet (), rng , pgf .Src , pgf .File , pkg .GetTypes (), pkg .GetTypesInfo (), nil
113138}
0 commit comments