Commit 2cbc8edf authored by Nick Thomas's avatar Nick Thomas

Merge branch 'id-lsif-flex-int-for-ids' into 'master'

Accept string or int type for LSIF ids

See merge request gitlab-org/gitlab-workhorse!499
parents ce7b2d8d d3318859
...@@ -12,19 +12,19 @@ type Line struct { ...@@ -12,19 +12,19 @@ type Line struct {
type Docs struct { type Docs struct {
Root string Root string
Entries map[string]string Entries map[Id]string
DocRanges map[string][]string DocRanges map[Id][]Id
Ranges *Ranges Ranges *Ranges
} }
type Document struct { type Document struct {
Id string `json:"id"` Id Id `json:"id"`
Uri string `json:"uri"` Uri string `json:"uri"`
} }
type DocumentRange struct { type DocumentRange struct {
OutV string `json:"outV"` OutV Id `json:"outV"`
RangeIds []string `json:"inVs"` RangeIds []Id `json:"inVs"`
} }
type Metadata struct { type Metadata struct {
...@@ -39,8 +39,8 @@ func NewDocs(tempDir string) (*Docs, error) { ...@@ -39,8 +39,8 @@ func NewDocs(tempDir string) (*Docs, error) {
return &Docs{ return &Docs{
Root: "file:///", Root: "file:///",
Entries: make(map[string]string), Entries: make(map[Id]string),
DocRanges: make(map[string][]string), DocRanges: make(map[Id][]Id),
Ranges: ranges, Ranges: ranges,
}, nil }, nil
} }
......
...@@ -23,9 +23,9 @@ func TestRead(t *testing.T) { ...@@ -23,9 +23,9 @@ func TestRead(t *testing.T) {
require.NoError(t, d.Read(createLine("3", "document", "file:///Users/nested/folder/file.rb"))) require.NoError(t, d.Read(createLine("3", "document", "file:///Users/nested/folder/file.rb")))
require.NoError(t, d.Read(createLine("4", "document", "file:///Users/wrong/file.rb"))) require.NoError(t, d.Read(createLine("4", "document", "file:///Users/wrong/file.rb")))
require.Equal(t, d.Entries["2"], "file.rb") require.Equal(t, d.Entries[2], "file.rb")
require.Equal(t, d.Entries["3"], "folder/file.rb") require.Equal(t, d.Entries[3], "folder/file.rb")
require.Equal(t, d.Entries["4"], "file:///Users/wrong/file.rb") require.Equal(t, d.Entries[4], "file:///Users/wrong/file.rb")
} }
func TestReadContainsLine(t *testing.T) { func TestReadContainsLine(t *testing.T) {
...@@ -37,5 +37,5 @@ func TestReadContainsLine(t *testing.T) { ...@@ -37,5 +37,5 @@ func TestReadContainsLine(t *testing.T) {
require.NoError(t, d.Read(line)) require.NoError(t, d.Read(line))
require.Equal(t, []string{"2", "3"}, d.DocRanges["1"]) require.Equal(t, []Id{2, 3}, d.DocRanges[1])
} }
...@@ -12,7 +12,7 @@ type Offset struct { ...@@ -12,7 +12,7 @@ type Offset struct {
} }
type Hovers struct { type Hovers struct {
Offsets map[string]*Offset Offsets map[Id]*Offset
File *os.File File *os.File
CurrentOffset int CurrentOffset int
} }
...@@ -22,18 +22,18 @@ type RawResult struct { ...@@ -22,18 +22,18 @@ type RawResult struct {
} }
type RawData struct { type RawData struct {
Id string `json:"id"` Id Id `json:"id"`
Result RawResult `json:"result"` Result RawResult `json:"result"`
} }
type HoverRef struct { type HoverRef struct {
ResultSetId string `json:"outV"` ResultSetId Id `json:"outV"`
HoverId string `json:"inV"` HoverId Id `json:"inV"`
} }
type ResultSetRef struct { type ResultSetRef struct {
ResultSetId string `json:"outV"` ResultSetId Id `json:"outV"`
RefId string `json:"inV"` RefId Id `json:"inV"`
} }
func NewHovers(tempDir string) (*Hovers, error) { func NewHovers(tempDir string) (*Hovers, error) {
...@@ -43,7 +43,7 @@ func NewHovers(tempDir string) (*Hovers, error) { ...@@ -43,7 +43,7 @@ func NewHovers(tempDir string) (*Hovers, error) {
} }
return &Hovers{ return &Hovers{
Offsets: make(map[string]*Offset), Offsets: make(map[Id]*Offset),
File: file, File: file,
CurrentOffset: 0, CurrentOffset: 0,
}, nil }, nil
...@@ -68,7 +68,7 @@ func (h *Hovers) Read(label string, line []byte) error { ...@@ -68,7 +68,7 @@ func (h *Hovers) Read(label string, line []byte) error {
return nil return nil
} }
func (h *Hovers) For(refId string) json.RawMessage { func (h *Hovers) For(refId Id) json.RawMessage {
offset, ok := h.Offsets[refId] offset, ok := h.Offsets[refId]
if !ok || offset == nil { if !ok || offset == nil {
return nil return nil
......
...@@ -9,7 +9,7 @@ import ( ...@@ -9,7 +9,7 @@ import (
func TestHoversRead(t *testing.T) { func TestHoversRead(t *testing.T) {
h := setupHovers(t) h := setupHovers(t)
require.Equal(t, `[{"value":"hello"}]`, string(h.For("1"))) require.Equal(t, `[{"value":"hello"}]`, string(h.For(1)))
require.NoError(t, h.Close()) require.NoError(t, h.Close())
} }
...@@ -19,8 +19,8 @@ func setupHovers(t *testing.T) *Hovers { ...@@ -19,8 +19,8 @@ func setupHovers(t *testing.T) *Hovers {
require.NoError(t, err) require.NoError(t, err)
require.NoError(t, h.Read("hoverResult", []byte(`{"id":"2","label":"hoverResult","result":{"contents": ["hello"]}}`))) require.NoError(t, h.Read("hoverResult", []byte(`{"id":"2","label":"hoverResult","result":{"contents": ["hello"]}}`)))
require.NoError(t, h.Read("textDocument/hover", []byte(`{"id":"4","label":"textDocument/hover","outV":"3","inV":"2"}`))) require.NoError(t, h.Read("textDocument/hover", []byte(`{"id":4,"label":"textDocument/hover","outV":"3","inV":2}`)))
require.NoError(t, h.Read("textDocument/references", []byte(`{"id":"3","label":"textDocument/references","outV":"3","inV":"1"}`))) require.NoError(t, h.Read("textDocument/references", []byte(`{"id":"3","label":"textDocument/references","outV":3,"inV":"1"}`)))
return h return h
} }
package parser
import (
"encoding/json"
"errors"
"strconv"
)
const (
minId = 1
maxId = 20 * 1000 * 1000
)
type Id int32
func (id *Id) UnmarshalJSON(b []byte) error {
if b[0] != '"' {
if err := id.unmarshalInt(b); err != nil {
return err
}
} else {
if err := id.unmarshalString(b); err != nil {
return err
}
}
if *id < minId || *id > maxId {
return errors.New("json: id is invalid")
}
return nil
}
func (id *Id) unmarshalInt(b []byte) error {
return json.Unmarshal(b, (*int32)(id))
}
func (id *Id) unmarshalString(b []byte) error {
var s string
if err := json.Unmarshal(b, &s); err != nil {
return err
}
i, err := strconv.Atoi(s)
if err != nil {
return err
}
*id = Id(i)
return nil
}
package parser
import (
"encoding/json"
"testing"
"github.com/stretchr/testify/require"
)
type jsonWithId struct {
Value Id `json:"value"`
}
func TestId(t *testing.T) {
var v jsonWithId
require.NoError(t, json.Unmarshal([]byte(`{ "value": 1230 }`), &v))
require.Equal(t, Id(1230), v.Value)
require.NoError(t, json.Unmarshal([]byte(`{ "value": "1230" }`), &v))
require.Equal(t, Id(1230), v.Value)
require.Error(t, json.Unmarshal([]byte(`{ "value": "1.5" }`), &v))
require.Error(t, json.Unmarshal([]byte(`{ "value": 1.5 }`), &v))
require.Error(t, json.Unmarshal([]byte(`{ "value": "-1" }`), &v))
require.Error(t, json.Unmarshal([]byte(`{ "value": -1 }`), &v))
require.Error(t, json.Unmarshal([]byte(`{ "value": 21000000 }`), &v))
require.Error(t, json.Unmarshal([]byte(`{ "value": "21000000" }`), &v))
}
...@@ -10,37 +10,37 @@ const Definitions = "definitions" ...@@ -10,37 +10,37 @@ const Definitions = "definitions"
const References = "references" const References = "references"
type Ranges struct { type Ranges struct {
Entries map[string]*Range Entries map[Id]*Range
DefRefs map[string]*DefRef DefRefs map[Id]*DefRef
Hovers *Hovers Hovers *Hovers
} }
type RawRange struct { type RawRange struct {
Id string `json:"id"` Id Id `json:"id"`
Data Range `json:"start"` Data Range `json:"start"`
} }
type Range struct { type Range struct {
Line int `json:"line"` Line int32 `json:"line"`
Character int `json:"character"` Character int32 `json:"character"`
RefId string RefId Id
} }
type RawDefRef struct { type RawDefRef struct {
Property string `json:"property"` Property string `json:"property"`
RefId string `json:"outV"` RefId Id `json:"outV"`
RangeIds []string `json:"inVs"` RangeIds []Id `json:"inVs"`
DocId string `json:"document"` DocId Id `json:"document"`
} }
type DefRef struct { type DefRef struct {
Line string Line string
DocId string DocId Id
} }
type SerializedRange struct { type SerializedRange struct {
StartLine int `json:"start_line"` StartLine int32 `json:"start_line"`
StartChar int `json:"start_char"` StartChar int32 `json:"start_char"`
DefinitionPath string `json:"definition_path,omitempty"` DefinitionPath string `json:"definition_path,omitempty"`
Hover json.RawMessage `json:"hover"` Hover json.RawMessage `json:"hover"`
} }
...@@ -52,8 +52,8 @@ func NewRanges(tempDir string) (*Ranges, error) { ...@@ -52,8 +52,8 @@ func NewRanges(tempDir string) (*Ranges, error) {
} }
return &Ranges{ return &Ranges{
Entries: make(map[string]*Range), Entries: make(map[Id]*Range),
DefRefs: make(map[string]*DefRef), DefRefs: make(map[Id]*DefRef),
Hovers: hovers, Hovers: hovers,
}, nil }, nil
} }
...@@ -75,7 +75,7 @@ func (r *Ranges) Read(label string, line []byte) error { ...@@ -75,7 +75,7 @@ func (r *Ranges) Read(label string, line []byte) error {
return nil return nil
} }
func (r *Ranges) Serialize(f io.Writer, rangeIds []string, docs map[string]string) error { func (r *Ranges) Serialize(f io.Writer, rangeIds []Id, docs map[Id]string) error {
encoder := json.NewEncoder(f) encoder := json.NewEncoder(f)
n := len(rangeIds) n := len(rangeIds)
...@@ -112,7 +112,7 @@ func (r *Ranges) Close() error { ...@@ -112,7 +112,7 @@ func (r *Ranges) Close() error {
return r.Hovers.Close() return r.Hovers.Close()
} }
func (r *Ranges) definitionPathFor(docs map[string]string, refId string) string { func (r *Ranges) definitionPathFor(docs map[Id]string, refId Id) string {
defRef, ok := r.DefRefs[refId] defRef, ok := r.DefRefs[refId]
if !ok { if !ok {
return "" return ""
...@@ -157,7 +157,7 @@ func (r *Ranges) addItem(line []byte) error { ...@@ -157,7 +157,7 @@ func (r *Ranges) addItem(line []byte) error {
defRange := r.Entries[defRef.RangeIds[0]] defRange := r.Entries[defRef.RangeIds[0]]
r.DefRefs[defRef.RefId] = &DefRef{ r.DefRefs[defRef.RefId] = &DefRef{
Line: strconv.Itoa(defRange.Line + 1), Line: strconv.Itoa(int(defRange.Line + 1)),
DocId: defRef.DocId, DocId: defRef.DocId,
} }
......
...@@ -11,21 +11,21 @@ func TestRangesRead(t *testing.T) { ...@@ -11,21 +11,21 @@ func TestRangesRead(t *testing.T) {
r, cleanup := setup(t) r, cleanup := setup(t)
defer cleanup() defer cleanup()
firstRange := Range{Line: 1, Character: 2, RefId: "3"} firstRange := Range{Line: 1, Character: 2, RefId: 3}
require.Equal(t, &firstRange, r.Entries["1"]) require.Equal(t, &firstRange, r.Entries[1])
secondRange := Range{Line: 5, Character: 4, RefId: "3"} secondRange := Range{Line: 5, Character: 4, RefId: 3}
require.Equal(t, &secondRange, r.Entries["2"]) require.Equal(t, &secondRange, r.Entries[2])
} }
func TestSerialize(t *testing.T) { func TestSerialize(t *testing.T) {
r, cleanup := setup(t) r, cleanup := setup(t)
defer cleanup() defer cleanup()
docs := map[string]string{"6": "def-path"} docs := map[Id]string{6: "def-path"}
var buf bytes.Buffer var buf bytes.Buffer
err := r.Serialize(&buf, []string{"1"}, docs) err := r.Serialize(&buf, []Id{1}, docs)
want := `[{"start_line":1,"start_char":2,"definition_path":"def-path#L2","hover":null}` + "\n]" want := `[{"start_line":1,"start_char":2,"definition_path":"def-path#L2","hover":null}` + "\n]"
require.NoError(t, err) require.NoError(t, err)
...@@ -36,11 +36,11 @@ func setup(t *testing.T) (*Ranges, func()) { ...@@ -36,11 +36,11 @@ func setup(t *testing.T) (*Ranges, func()) {
r, err := NewRanges("") r, err := NewRanges("")
require.NoError(t, err) require.NoError(t, err)
require.NoError(t, r.Read("range", []byte(`{"id":"1","label":"range","start":{"line":1,"character":2}}`))) 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":"2","label":"range","start":{"line":5,"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":4,"label":"item","property":"definitions","outV":"3","inVs":[1],"document":"6"}`)))
require.NoError(t, r.Read("item", []byte(`{"id":"4","label":"item","property":"references","outV":"3","inVs":["2"]}`))) require.NoError(t, r.Read("item", []byte(`{"id":"5","label":"item","property":"references","outV":3,"inVs":["2"]}`)))
cleanup := func() { cleanup := func() {
require.NoError(t, r.Close()) require.NoError(t, r.Close())
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment