• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1// Copyright 2018 The Go Authors.
2//
3// Licensed under the Apache License, Version 2.0 (the "License");
4// you may not use this file except in compliance with the License.
5// You may obtain a copy of the License at
6//
7//     http://www.apache.org/licenses/LICENSE-2.0
8//
9// Unless required by applicable law or agreed to in writing, software
10// distributed under the License is distributed on an "AS IS" BASIS,
11// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12// See the License for the specific language governing permissions and
13// limitations under the License.
14
15// this file contains protocol<->span converters
16
17package protocol
18
19import (
20	"fmt"
21
22	"github.com/KhronosGroup/SPIRV-Tools/utils/vscode/src/lsp/span"
23
24	errors "golang.org/x/xerrors"
25)
26
27type ColumnMapper struct {
28	URI       span.URI
29	Converter *span.TokenConverter
30	Content   []byte
31}
32
33func NewURI(uri span.URI) string {
34	return string(uri)
35}
36
37func (m *ColumnMapper) Location(s span.Span) (Location, error) {
38	rng, err := m.Range(s)
39	if err != nil {
40		return Location{}, err
41	}
42	return Location{URI: NewURI(s.URI()), Range: rng}, nil
43}
44
45func (m *ColumnMapper) Range(s span.Span) (Range, error) {
46	if span.CompareURI(m.URI, s.URI()) != 0 {
47		return Range{}, errors.Errorf("column mapper is for file %q instead of %q", m.URI, s.URI())
48	}
49	s, err := s.WithAll(m.Converter)
50	if err != nil {
51		return Range{}, err
52	}
53	start, err := m.Position(s.Start())
54	if err != nil {
55		return Range{}, err
56	}
57	end, err := m.Position(s.End())
58	if err != nil {
59		return Range{}, err
60	}
61	return Range{Start: start, End: end}, nil
62}
63
64func (m *ColumnMapper) Position(p span.Point) (Position, error) {
65	chr, err := span.ToUTF16Column(p, m.Content)
66	if err != nil {
67		return Position{}, err
68	}
69	return Position{
70		Line:      float64(p.Line() - 1),
71		Character: float64(chr - 1),
72	}, nil
73}
74
75func (m *ColumnMapper) Span(l Location) (span.Span, error) {
76	return m.RangeSpan(l.Range)
77}
78
79func (m *ColumnMapper) RangeSpan(r Range) (span.Span, error) {
80	start, err := m.Point(r.Start)
81	if err != nil {
82		return span.Span{}, err
83	}
84	end, err := m.Point(r.End)
85	if err != nil {
86		return span.Span{}, err
87	}
88	return span.New(m.URI, start, end).WithAll(m.Converter)
89}
90
91func (m *ColumnMapper) PointSpan(p Position) (span.Span, error) {
92	start, err := m.Point(p)
93	if err != nil {
94		return span.Span{}, err
95	}
96	return span.New(m.URI, start, start).WithAll(m.Converter)
97}
98
99func (m *ColumnMapper) Point(p Position) (span.Point, error) {
100	line := int(p.Line) + 1
101	offset, err := m.Converter.ToOffset(line, 1)
102	if err != nil {
103		return span.Point{}, err
104	}
105	lineStart := span.NewPoint(line, 1, offset)
106	return span.FromUTF16Column(lineStart, int(p.Character)+1, m.Content)
107}
108
109func IsPoint(r Range) bool {
110	return r.Start.Line == r.End.Line && r.Start.Character == r.End.Character
111}
112
113func CompareRange(a, b Range) int {
114	if r := ComparePosition(a.Start, b.Start); r != 0 {
115		return r
116	}
117	return ComparePosition(a.End, b.End)
118}
119
120func ComparePosition(a, b Position) int {
121	if a.Line < b.Line {
122		return -1
123	}
124	if a.Line > b.Line {
125		return 1
126	}
127	if a.Character < b.Character {
128		return -1
129	}
130	if a.Character > b.Character {
131		return 1
132	}
133	return 0
134}
135
136func (r Range) Format(f fmt.State, _ rune) {
137	fmt.Fprintf(f, "%v:%v-%v:%v", r.Start.Line, r.Start.Character, r.End.Line, r.End.Character)
138}
139