diff --git a/changelogs/unreleased/305-lsif-arrays.yml b/changelogs/unreleased/305-lsif-arrays.yml new file mode 100644 index 0000000000000000000000000000000000000000..a2cdde5f8b3e8ea57ac7712589db4f096682b490 --- /dev/null +++ b/changelogs/unreleased/305-lsif-arrays.yml @@ -0,0 +1,5 @@ +--- +title: Fix processing lsif dump with repeating lines with inVs +merge_request: 621 +author: Pavel Kuznetsov +type: fixed diff --git a/internal/lsif_transformer/parser/docs.go b/internal/lsif_transformer/parser/docs.go index 6e1138eaf29aee56e5418e8b2b55c771fd92c019..c626e07d3fec579331100554b3241d594bcbe13b 100644 --- a/internal/lsif_transformer/parser/docs.go +++ b/internal/lsif_transformer/parser/docs.go @@ -138,7 +138,7 @@ func (d *Docs) addDocRanges(line []byte) error { return err } - d.DocRanges[docRange.OutV] = docRange.RangeIds + d.DocRanges[docRange.OutV] = append(d.DocRanges[docRange.OutV], docRange.RangeIds...) return nil } diff --git a/internal/lsif_transformer/parser/docs_test.go b/internal/lsif_transformer/parser/docs_test.go index b8b1072cabb654e11b8168d5b3bd462de77b4d90..57dca8e773dd47ce3b0f430293ce70bbd2fe8dab 100644 --- a/internal/lsif_transformer/parser/docs_test.go +++ b/internal/lsif_transformer/parser/docs_test.go @@ -35,11 +35,12 @@ func TestParseContainsLine(t *testing.T) { require.NoError(t, err) defer d.Close() - line := []byte(`{"id":"5","label":"contains","outV":"1", "inVs": ["2", "3"]}` + "\n") + data := []byte(`{"id":"5","label":"contains","outV":"1", "inVs": ["2", "3"]}` + "\n") + data = append(data, []byte(`{"id":"6","label":"contains","outV":"1", "inVs": [4]}`+"\n")...) - require.NoError(t, d.Parse(bytes.NewReader(line))) + require.NoError(t, d.Parse(bytes.NewReader(data))) - require.Equal(t, []Id{2, 3}, d.DocRanges[1]) + require.Equal(t, []Id{2, 3, 4}, d.DocRanges[1]) } func TestParsingVeryLongLine(t *testing.T) { diff --git a/internal/lsif_transformer/parser/ranges_test.go b/internal/lsif_transformer/parser/ranges_test.go index f6d26026e3faa15e35d45344247eb8735f04a6ba..c1400ba61daa77b3a28846103bcceb1f89c4ac89 100644 --- a/internal/lsif_transformer/parser/ranges_test.go +++ b/internal/lsif_transformer/parser/ranges_test.go @@ -11,15 +11,20 @@ func TestRangesRead(t *testing.T) { r, cleanup := setup(t) defer cleanup() - firstRange := Range{Line: 1, Character: 2, RefId: 3} + firstRange := Range{Line: 1, Character: 2, RefId: 4} rg, err := r.getRange(1) require.NoError(t, err) require.Equal(t, &firstRange, rg) - secondRange := Range{Line: 5, Character: 4, RefId: 3} + secondRange := Range{Line: 5, Character: 4, RefId: 4} rg, err = r.getRange(2) require.NoError(t, err) require.Equal(t, &secondRange, rg) + + thirdRange := Range{Line: 7, Character: 4, RefId: 4} + rg, err = r.getRange(3) + require.NoError(t, err) + require.Equal(t, &thirdRange, rg) } func TestSerialize(t *testing.T) { @@ -30,7 +35,7 @@ func TestSerialize(t *testing.T) { var buf bytes.Buffer err := r.Serialize(&buf, []Id{1}, docs) - want := `[{"start_line":1,"start_char":2,"definition_path":"def-path#L2","hover":null,"references":[{"path":"ref-path#L6"}]}` + "\n]" + want := `[{"start_line":1,"start_char":2,"definition_path":"def-path#L2","hover":null,"references":[{"path":"ref-path#L6"},{"path":"ref-path#L8"}]}` + "\n]" require.NoError(t, err) require.Equal(t, want, buf.String()) @@ -42,9 +47,11 @@ func setup(t *testing.T) (*Ranges, func()) { require.NoError(t, r.Read("range", []byte(`{"id":1,"label":"range","start":{"line":1,"character":2}}`))) require.NoError(t, r.Read("range", []byte(`{"id":"2","label":"range","start":{"line":5,"character":4}}`))) + require.NoError(t, r.Read("range", []byte(`{"id":"3","label":"range","start":{"line":7,"character":4}}`))) - require.NoError(t, r.Read("item", []byte(`{"id":4,"label":"item","property":"definitions","outV":"3","inVs":[1],"document":"6"}`))) - require.NoError(t, r.Read("item", []byte(`{"id":"5","label":"item","property":"references","outV":3,"inVs":["2"],"document":"7"}`))) + require.NoError(t, r.Read("item", []byte(`{"id":5,"label":"item","property":"definitions","outV":"4","inVs":[1],"document":"6"}`))) + require.NoError(t, r.Read("item", []byte(`{"id":"6","label":"item","property":"references","outV":4,"inVs":["2"],"document":"7"}`))) + require.NoError(t, r.Read("item", []byte(`{"id":"7","label":"item","property":"references","outV":4,"inVs":["3"],"document":"7"}`))) cleanup := func() { require.NoError(t, r.Close()) diff --git a/internal/lsif_transformer/parser/references.go b/internal/lsif_transformer/parser/references.go index 491454c2a62cf663d7a257373707c062322f5f82..58ff9a61c02b5a972217536ed6ee1c6d4de774d8 100644 --- a/internal/lsif_transformer/parser/references.go +++ b/internal/lsif_transformer/parser/references.go @@ -53,11 +53,13 @@ func (r *References) Store(refId Id, references []Item) error { return nil } - err := r.Items.SetEntry(r.CurrentOffsetId, references) + items := append(r.getItems(refId), references...) + err := r.Items.SetEntry(r.CurrentOffsetId, items) if err != nil { return err } + size = len(items) r.Offsets.SetEntry(refId, ReferencesOffset{Id: r.CurrentOffsetId, Len: int32(size)}) r.CurrentOffsetId += Id(size)