diff --git a/gopls/internal/regtest/misc/formatting_test.go b/gopls/internal/regtest/misc/formatting_test.go index 1e14237afc..67e7939134 100644 --- a/gopls/internal/regtest/misc/formatting_test.go +++ b/gopls/internal/regtest/misc/formatting_test.go @@ -268,3 +268,36 @@ func main() { }) } } + +func TestFormattingOfGeneratedFile_Issue49555(t *testing.T) { + const input = ` +-- main.go -- +// Code generated by generator.go. DO NOT EDIT. + +package main + +import "fmt" + +func main() { + + + + + fmt.Print("hello") +} +` + + Run(t, input, func(t *testing.T, env *Env) { + wantErrSuffix := "file is generated" + + env.OpenFile("main.go") + err := env.Editor.FormatBuffer(env.Ctx, "main.go") + if err == nil { + t.Fatal("expected error, got nil") + } + // Check only the suffix because an error contains a dynamic path to main.go + if !strings.HasSuffix(err.Error(), wantErrSuffix) { + t.Fatalf("unexpected error %q, want suffix %q", err.Error(), wantErrSuffix) + } + }) +} diff --git a/internal/lsp/source/format.go b/internal/lsp/source/format.go index 16e72c2372..4f02e4f34e 100644 --- a/internal/lsp/source/format.go +++ b/internal/lsp/source/format.go @@ -29,6 +29,11 @@ func Format(ctx context.Context, snapshot Snapshot, fh FileHandle) ([]protocol.T ctx, done := event.Start(ctx, "source.Format") defer done() + // Generated files shouldn't be edited. So, don't format them + if IsGenerated(ctx, snapshot, fh.URI()) { + return nil, fmt.Errorf("can't format %q: file is generated", fh.URI().Filename()) + } + pgf, err := snapshot.ParseGo(ctx, fh, ParseFull) if err != nil { return nil, err