Граф коммитов

13 Коммитов

Автор SHA1 Сообщение Дата
Rob Findley 08edf75c4d gopls/internal/regtest/marker: port half of the suggestedfix markers
Port the fillstruct and self_assignment suggestedfix marker tests.

The fillstruct marker test in particular had incredibly verbose golden
content, which made the tests very difficult to read. To mitigate this,
introduce a new 'codeactionedit' marker which only stores edits in the
golden directory, rather than complete file content. Additionally,
narrow the unified diff to have no edges, for brevity. Since none of the
fillstruct tests require multi-line ranges, use a single location for
the range.

Furthermore, standardize on putting locations before action kind in code
action markers. This is more consistent with other markers.

For golang/go#54845

Change-Id: Id5d713b77fa751bfe8be473b19304376bc3bb139
Reviewed-on: https://go-review.googlesource.com/c/tools/+/539655
Reviewed-by: Alan Donovan <adonovan@google.com>
LUCI-TryBot-Result: Go LUCI <golang-scoped@luci-project-accounts.iam.gserviceaccount.com>
2023-11-03 15:49:45 +00:00
Alan Donovan 0b4461babc internal/diff: fix LineEdits bug in slow path
Previously, the expandEdit operation would expand to
the end of the line unconditionally, but this caused it
to gulp an extra line if it was already line-aligned.

This change causes it to do the expansion only if
the end is not line-aligned, or the replacement text
doesn't end with a newline.

Now, removing the fast path no longer causes tests to fail.
This also allows us to remove the logic added in CL 489695
to work around issue golang/go#59232.

Fixes golang/go#60379
Fixes golang/go#59232

Change-Id: Ia40e4e3bb714d75acb95103a38e8c49a8ef456de
Reviewed-on: https://go-review.googlesource.com/c/tools/+/499377
Run-TryBot: Alan Donovan <adonovan@google.com>
gopls-CI: kokoro <noreply+kokoro@google.com>
TryBot-Result: Gopher Robot <gobot@golang.org>
Reviewed-by: Peter Weinberger <pjw@google.com>
2023-06-01 18:40:17 +00:00
Alan Donovan 1943c1e3e1 internal/diff: fix LineEdits bug in fast path
The fast-path "optimization" that skips the main
algorithm when the input is already line-aligned
failed to check that the replacement text consisted
of complete lines.

(Scare quotes because removing the "optimization" causes
tests to fail. See CL 499377 next in stack for why.)

Thanks to pjw for diagnosing the root cause and
providing the test case in CL 498975.

Fixes golang/go#60379

Change-Id: I2ff92de4550754691442362b8a8932ee42971461
Reviewed-on: https://go-review.googlesource.com/c/tools/+/499376
gopls-CI: kokoro <noreply+kokoro@google.com>
Run-TryBot: Alan Donovan <adonovan@google.com>
TryBot-Result: Gopher Robot <gobot@golang.org>
Reviewed-by: Peter Weinberger <pjw@google.com>
2023-06-01 18:40:08 +00:00
Peter Weinbergr 1faecd32c9 tools/internal/diff: fix off-by-one error in computing diffs
In the removed code
if endCol := end - 1 - strings.LastIndex(src[:end], "\n"); endCol > 0
the endCol test is off by one. It should have been endCol >= 0, otherwise
there are cases where extending the edit won't be considered.
But endCol is always >= 0, as LastIndex(src[:end], "\n") is <= end-1.
Another way of saying all this is the extending the edit doesn't need
endCol at all.

The effect of this was to fail to extend edits if the edit started
the line.

The tests were revised to check unified diffs by using the
patch command.

Fixes: golang/go#457256

Change-Id: Idb23f1a28d36f92a7b8712e9459df86a3d420d7e
Reviewed-on: https://go-review.googlesource.com/c/tools/+/459236
TryBot-Result: Gopher Robot <gobot@golang.org>
Reviewed-by: Alan Donovan <adonovan@google.com>
gopls-CI: kokoro <noreply+kokoro@google.com>
Run-TryBot: Peter Weinberger <pjw@google.com>
2023-01-21 15:27:42 +00:00
Alan Donovan 6df6eee463 internal/diff/lcs: optimize inner loop
The core operation of the diff algorithm is to advance
a cursor forwards or backwards over common substrings
of the two sequences. This change refactors the sequence
abstraction to express this, permitting faster and type-
specialized implementations of the common-prefix and
common-suffix operations.

This improves the running time on the new LargeFileSmallDiff
benchmark by 17%:

Before:
BenchmarkLargeFileSmallDiff/bytes-8         	    9838	    521006 ns/op
BenchmarkLargeFileSmallDiff/runes-8         	   10000	    522915 ns/op

After:
BenchmarkLargeFileSmallDiff/string-8         	   14545	    412497 ns/op
BenchmarkLargeFileSmallDiff/bytes-8          	   13868	    432577 ns/op (-17%)
BenchmarkLargeFileSmallDiff/runes-8          	   13744	    436548 ns/op (-17%)

Also, some cleanups:
- Compute is replaced by three Diff{Strings,Bytes,Runes} functions.
- The LCS result is now internal, as it is needed only by tests.
- The caller's maxDiff constant is moved into this package.
- Test{Forward,Backward,TwoSided} are factored together.
- Delete unused randlines().
- {append,prepend}lcs are now methods
- Diff declaration moved to more prominent location.
- A test of the three DiffT functions.

Future work:
- faster common-prefix implementations are possible: the two
  operations still account for about 5% of this benchmark.
- common-suffix for strings is about 50% faster than for bytes.
  Find out why.
- There appear to be opportunities for much bigger gains
  on the above benchmark by stripping the common prefix and
  suffix as a first step. See comments in benchmark.

Change-Id: I475b7fc731d628d54e652a4ace7ce67c6c2755c2
Reviewed-on: https://go-review.googlesource.com/c/tools/+/446575
TryBot-Result: Gopher Robot <gobot@golang.org>
Reviewed-by: Peter Weinberger <pjw@google.com>
Run-TryBot: Alan Donovan <adonovan@google.com>
gopls-CI: kokoro <noreply+kokoro@google.com>
2022-12-19 23:49:02 +00:00
Alan Donovan a410e98a82 internal/diff: ToUnified may fail
LineEdits has similar consistency preconditions to ApplyEdits.
Previously they were assumed, and bad input would create bad
output or crashes; now it uses the same validation logic
as ApplyEdits. Since it reports an error, computation of a
unified diff can also fail if the edits are inconsistent.

The ToUnified([]Edit) function now returns an error. For
convenience we also provide a wrapper (Unified) that cannot
fail since it calls Strings and ToUnified consistently.

LineEdits itself is now private.

Change-Id: I3780827f501d7d5c9665ec8be5656331c0dcda8e
Reviewed-on: https://go-review.googlesource.com/c/tools/+/440175
Reviewed-by: Robert Findley <rfindley@google.com>
TryBot-Result: Gopher Robot <gobot@golang.org>
Run-TryBot: Alan Donovan <adonovan@google.com>
Auto-Submit: Alan Donovan <adonovan@google.com>
2022-10-07 15:16:55 +00:00
Alan Donovan 26a95e6901 gopls/internal/span: move internal/span into gopls
Spans are logically part of gopls, but could not be moved
into the gopls module because of a number of depenencies
from packagestest, analysis, and internal/diff.
Those edges are now broken.

Change-Id: Icba5ebec6b27974f832a1186120a4b87d5f87103
Reviewed-on: https://go-review.googlesource.com/c/tools/+/440176
Reviewed-by: Robert Findley <rfindley@google.com>
Run-TryBot: Alan Donovan <adonovan@google.com>
Auto-Submit: Alan Donovan <adonovan@google.com>
gopls-CI: kokoro <noreply+kokoro@google.com>
TryBot-Result: Gopher Robot <gobot@golang.org>
2022-10-07 14:50:44 +00:00
Alan Donovan f2c4579afe internal/diff: avoid unnecessary allocations
Previously, a diff of non-ASCII strings would incur
three complete copies of the buffers; this changes
reduces it to one.

Also:
- add diff.Bytes function, to avoid unnecessary conversions.
- remove unused diff.Lines and LineEdits functions from API.
- remove TODO to use []bytes everywhere.
  We tried it in CL 439277 and didn't like it.
- Document that the diff is textual, even when given []byte.

Change-Id: I2da3257cc3d12c569218a2d7ce182452e8647a96
Reviewed-on: https://go-review.googlesource.com/c/tools/+/439835
Reviewed-by: Robert Findley <rfindley@google.com>
Run-TryBot: Alan Donovan <adonovan@google.com>
Auto-Submit: Alan Donovan <adonovan@google.com>
TryBot-Result: Gopher Robot <gobot@golang.org>
gopls-CI: kokoro <noreply+kokoro@google.com>
2022-10-07 14:48:35 +00:00
Alan Donovan 60ddccae85 internal/diff: Apply: validate inputs
Apply now checks that its edits are valid
(not out of bounds or overlapping),
and reports an error if not.

It also sorts them, if necessary, using (start, end)
as the key, to ensure that insertions (end=start)
are ordered before deletions at the same point
(but without changing the relative order of insertions).

Two other implementations of the diff.Apply algorithm
have been eliminated. (One of them failed to sort edits,
requiring the protocol sender to do so; that burden
is now gone.)

Change-Id: Ia76e485e6869db4a165835c3312fd14bc7d43db2
Reviewed-on: https://go-review.googlesource.com/c/tools/+/439278
Auto-Submit: Alan Donovan <adonovan@google.com>
gopls-CI: kokoro <noreply+kokoro@google.com>
TryBot-Result: Gopher Robot <gobot@golang.org>
Reviewed-by: Robert Findley <rfindley@google.com>
Run-TryBot: Alan Donovan <adonovan@google.com>
2022-10-07 14:24:20 +00:00
Alan Donovan d96b2388c6 internal/diff: simplify API, break span dependency
diff.TextEdit (now called simply Edit) no longer has a Span,
and no longer depends on the span package, which is really
part of gopls. Instead, it records only start/end byte
offsets within an (implied) file.

The diff algorithms have been simplified to avoid the need to
map offsets to line/column numbers (e.g. using a token.File).
All the conditions actually needed by the logic can be derived
by local string operations on the source text.

This change will allow us to move the span package into the
gopls module.

I was expecting that gopls would want to define its own
Span-augmented TextEdit type but, surprisingly, diff.Edit
is quite convenient to use throughout the entire repo:
in all places in gopls that manipulate Edits, the implied
file is obvious. In most cases, less conversion boilerplate
is required than before.

API Notes:
- diff.TextEdit -> Edit (it needn't be text)
- diff.ApplyEdits -> Apply
- source.protocolEditsFromSource is now private

Change-Id: I4d7cef078dfbd189b4aef477f845db320af6c5f6
Reviewed-on: https://go-review.googlesource.com/c/tools/+/436781
Run-TryBot: Alan Donovan <adonovan@google.com>
TryBot-Result: Gopher Robot <gobot@golang.org>
gopls-CI: kokoro <noreply+kokoro@google.com>
Reviewed-by: Robert Findley <rfindley@google.com>
Auto-Submit: Alan Donovan <adonovan@google.com>
2022-10-05 20:32:15 +00:00
Alan Donovan 9856077059 internal/diff: abolish errors
Computing the difference between two strings is logically an
infallible operation. This change makes the code reflect that. The
actual failures were unreachable given consistent inputs, but that was
hard to see from the complexity of the logic surrounding span.Span.
(The problem only occurs when converting offsets beyond the end of the
file to Spans, but the code preserves the integrity of offsets.)

gopls' "old" hooks.ComputeEdits impl (based on sergi/go-diff) now
reports a bug and returns a single diff for the entire file if it
panics.

Also, first steps towards simpler API and a
reusable diff package in x/tools:

- add TODO for new API. In particular, the diff package shouldn't care
  about filenames, spans, and URIs. These are gopls concerns.
- diff.String is the main diff function.
- diff.Unified prints edits in unified form;
  all its internals are now hidden.
- the ComputeEdits func type is moved to gopls (source.DiffFunction)
- remove all non-critical uses of myers.ComputeEdits. The only
  remaining one is in gopls' defaults, but perhaps that gets
  overridden by the default GoDiff setting in hooks, to BothDiffs
  (sergi + pjw impls), so maybe it's now actually unused in practice?

Change-Id: I6ceb5c670897abbf285b243530a7372dfa41edf6
Reviewed-on: https://go-review.googlesource.com/c/tools/+/436778
Run-TryBot: Alan Donovan <adonovan@google.com>
Reviewed-by: Robert Findley <rfindley@google.com>
TryBot-Result: Gopher Robot <gobot@golang.org>
gopls-CI: kokoro <noreply+kokoro@google.com>
2022-10-05 20:30:46 +00:00
Alan Donovan 55e5cff611 internal/diff: unified: match GNU diff for empty file
GNU diff -u prints -0,0 for the special case of inserting
into an empty file. (I don't understand why this case is
special, but it's fair to assume it has been debugged;
perhaps patch(1) has a bug.)

This change matches that special behavior, and adds a test.
It also adds a (disabled) test for another bug I encountered.

Also, remove some overzealous uses of t.Helper() that served
to obscure the failure.

Change-Id: I3e0c389c478cde45163353130e36f2f8741a8659
Reviewed-on: https://go-review.googlesource.com/c/tools/+/436782
gopls-CI: kokoro <noreply+kokoro@google.com>
Reviewed-by: Robert Findley <rfindley@google.com>
TryBot-Result: Gopher Robot <gobot@golang.org>
Run-TryBot: Alan Donovan <adonovan@google.com>
2022-10-03 15:32:10 +00:00
Robert Findley b15dac2b88 gopls: migrate internal/lsp to gopls/internal/lsp
This CL was created using the following commands:

    ./gopls/internal/migrate.sh
    git add .
    git codereview gofmt

For golang/go#54509

Change-Id: Iceeec602748a5e6f609c3ceda8d19157e5c94009
Reviewed-on: https://go-review.googlesource.com/c/tools/+/426796
gopls-CI: kokoro <noreply+kokoro@google.com>
Run-TryBot: Robert Findley <rfindley@google.com>
Reviewed-by: Peter Weinberger <pjw@google.com>
TryBot-Result: Gopher Robot <gobot@golang.org>
2022-09-07 16:44:44 +00:00