From a26de0c30193a63f6a1c5f637b03595a24405e11 Mon Sep 17 00:00:00 2001 From: Ian Cottrell Date: Mon, 19 Aug 2019 19:25:55 -0400 Subject: [PATCH] gopls: use go-diff for edit generation this supports sub-line diffs and is much faster Fixes golang/go#33003 Fixes golang/go#32586 Updates golang/go#31937 Change-Id: I02f82c75828e7e3ec804e8beee916893d4c14b3d Reviewed-on: https://go-review.googlesource.com/c/tools/+/191018 Run-TryBot: Ian Cottrell Reviewed-by: Rebecca Stambler --- gopls/go.mod | 2 ++ gopls/go.sum | 15 +++++++++++++++ gopls/internal/hooks/diff.go | 30 ++++++++++++++++++++++++++++++ gopls/internal/hooks/diff_test.go | 16 ++++++++++++++++ 4 files changed, 63 insertions(+) create mode 100644 gopls/internal/hooks/diff.go create mode 100644 gopls/internal/hooks/diff_test.go diff --git a/gopls/go.mod b/gopls/go.mod index d9ec987126..9f1ccd2c13 100644 --- a/gopls/go.mod +++ b/gopls/go.mod @@ -3,6 +3,8 @@ module golang.org/x/tools/gopls go 1.11 require ( + github.com/sergi/go-diff v1.0.0 + github.com/stretchr/testify v1.4.0 // indirect golang.org/x/tools v0.0.0-20190918214516-5a1a30219888 honnef.co/go/tools v0.0.1-2019.2.3 ) diff --git a/gopls/go.sum b/gopls/go.sum index c17f492e1b..4a74beec89 100644 --- a/gopls/go.sum +++ b/gopls/go.sum @@ -1,11 +1,22 @@ github.com/BurntSushi/toml v0.3.1 h1:WXkYYl6Yr3qBf1K79EBnL4mak0OimBfB0XUf9Vl28OQ= github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU= +github.com/davecgh/go-spew v1.1.0 h1:ZDRjVQ15GmhC3fiQ8ni8+OwkZQO4DARzQgrnXU1Liz8= +github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/google/renameio v0.1.0/go.mod h1:KWCgfxg9yswjAJkECMjeO8J8rahYeXnNhOm40UhjYkI= github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck= +github.com/kr/pretty v0.1.0 h1:L/CwN0zerZDmRFUapSPitk6f+Q3+0za1rQkzVuMiMFI= github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo= github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= +github.com/kr/text v0.1.0 h1:45sCR5RtlFHMR4UwH9sdQ5TC8v0qDQCHnXt+kaKSTVE= github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI= +github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= +github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4= +github.com/sergi/go-diff v1.0.0 h1:Kpca3qRNrduNnOQeazBd0ysaKrUJiIuISHxogkT9RPQ= +github.com/sergi/go-diff v1.0.0/go.mod h1:0CfEIISq7TuYL3j771MWULgwwjU+GofnZX9QAmXWZgo= +github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= +github.com/stretchr/testify v1.4.0 h1:2E4SXV/wtOkTonXsotYi4li6zVWxYlZuYNCXe9XRJyk= +github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4= golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= golang.org/x/crypto v0.0.0-20190510104115-cbcb75029529/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/mod v0.0.0-20190513183733-4bf6d317e70e/go.mod h1:mXi4GBBbnImb6dmsKGUJ2LatrhH/nqhxcFungHvyanc= @@ -18,7 +29,11 @@ golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7w golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7 h1:9zdDQZ7Thm29KFXgAX/+yaf3eVbP7djjWp/dXAppNCc= golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= +gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= +gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127 h1:qIbj1fsPNlZgppZ+VLlY7N33q108Sa+fhmuc+sWQYwY= gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/errgo.v2 v2.1.0/go.mod h1:hNsd1EY+bozCKY1Ytp96fpM3vjJbqLJn88ws8XvfDNI= +gopkg.in/yaml.v2 v2.2.2 h1:ZCJp+EgiOT7lHqUV2J862kp8Qj64Jo6az82+3Td9dZw= +gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= honnef.co/go/tools v0.0.1-2019.2.3 h1:3JgtbtFHMiCmsznwGVTUWbgGov+pVqnlf1dEJTNAXeM= honnef.co/go/tools v0.0.1-2019.2.3/go.mod h1:a3bituU0lyd329TUQxRnasdCoJDkEUEAqEt0JzvZhAg= diff --git a/gopls/internal/hooks/diff.go b/gopls/internal/hooks/diff.go new file mode 100644 index 0000000000..e2a5af5adb --- /dev/null +++ b/gopls/internal/hooks/diff.go @@ -0,0 +1,30 @@ +// Copyright 2019 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package hooks + +import ( + "github.com/sergi/go-diff/diffmatchpatch" + "golang.org/x/tools/internal/lsp/diff" + "golang.org/x/tools/internal/span" +) + +func ComputeEdits(uri span.URI, before, after string) []diff.TextEdit { + diffs := diffmatchpatch.New().DiffMain(before, after, true) + edits := make([]diff.TextEdit, 0, len(diffs)) + offset := 0 + for _, d := range diffs { + start := span.NewPoint(0, 0, offset) + switch d.Type { + case diffmatchpatch.DiffDelete: + offset += len(d.Text) + edits = append(edits, diff.TextEdit{Span: span.New(uri, start, span.NewPoint(0, 0, offset))}) + case diffmatchpatch.DiffEqual: + offset += len(d.Text) + case diffmatchpatch.DiffInsert: + edits = append(edits, diff.TextEdit{Span: span.New(uri, start, span.Point{}), NewText: d.Text}) + } + } + return edits +} diff --git a/gopls/internal/hooks/diff_test.go b/gopls/internal/hooks/diff_test.go new file mode 100644 index 0000000000..d979be78db --- /dev/null +++ b/gopls/internal/hooks/diff_test.go @@ -0,0 +1,16 @@ +// Copyright 2019 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package hooks_test + +import ( + "testing" + + "golang.org/x/tools/gopls/internal/hooks" + "golang.org/x/tools/internal/lsp/diff/difftest" +) + +func TestDiff(t *testing.T) { + difftest.DiffTest(t, hooks.ComputeEdits) +}