blob: 33820c99754a8e96409118cd2f2f3adad29472e2 [file] [log] [blame]
Ben Clayton7b1819b2024-03-15 19:59:54 +00001// Copyright 2024 The Dawn & Tint Authors
2//
3// Redistribution and use in source and binary forms, with or without
4// modification, are permitted provided that the following conditions are met:
5//
6// 1. Redistributions of source code must retain the above copyright notice, this
7// list of conditions and the following disclaimer.
8//
9// 2. Redistributions in binary form must reproduce the above copyright notice,
10// this list of conditions and the following disclaimer in the documentation
11// and/or other materials provided with the distribution.
12//
13// 3. Neither the name of the copyright holder nor the names of its
14// contributors may be used to endorse or promote products derived from
15// this software without specific prior written permission.
16//
17// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
18// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
19// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
20// DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
21// FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
22// DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
23// SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
24// CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
25// OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
26// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27
28#include <string_view>
29
30#include "gmock/gmock.h"
31
32#include "langsvr/lsp/lsp.h"
33#include "langsvr/lsp/primitives.h"
34#include "langsvr/lsp/printer.h"
35#include "src/tint/lang/wgsl/ls/helpers_test.h"
36
37namespace tint::wgsl::ls {
38namespace {
39
40namespace lsp = langsvr::lsp;
41
42struct Case {
43 const std::string_view wgsl;
44 const std::vector<lsp::DocumentSymbol> symbols;
45};
46
Ben Claytonc69f7692024-03-15 20:02:12 +000047std::ostream& operator<<(std::ostream& stream, const Case& c) {
48 return stream << "wgsl: '" << c.wgsl << "'";
49}
50
Ben Clayton7b1819b2024-03-15 19:59:54 +000051struct Symbol : lsp::DocumentSymbol {
52 explicit Symbol(std::string_view n) { name = n; }
53
54 Symbol& Kind(lsp::SymbolKind k) {
55 kind = k;
56 return *this;
57 }
58
59 Symbol& Range(lsp::Uinteger start_line,
60 lsp::Uinteger start_column,
61 lsp::Uinteger end_line,
62 lsp::Uinteger end_column) {
63 range = lsp::Range{{start_line, start_column}, {end_line, end_column}};
64 return *this;
65 }
66
67 Symbol& SelectionRange(lsp::Uinteger start_line,
68 lsp::Uinteger start_column,
69 lsp::Uinteger end_line,
70 lsp::Uinteger end_column) {
71 selection_range = lsp::Range{{start_line, start_column}, {end_line, end_column}};
72 return *this;
73 }
74};
75
Ben Clayton7b1819b2024-03-15 19:59:54 +000076using LsSymbolsTest = LsTestWithParam<Case>;
77TEST_P(LsSymbolsTest, Symbols) {
78 lsp::TextDocumentDocumentSymbolRequest req{};
79 req.text_document.uri = OpenDocument(GetParam().wgsl);
80 auto future = client_session_.Send(req);
81 ASSERT_EQ(future, langsvr::Success);
82 auto res = future->get();
83 if (GetParam().symbols.empty()) {
84 ASSERT_TRUE(res.Is<lsp::Null>());
85 } else {
86 ASSERT_TRUE(res.Is<std::vector<lsp::DocumentSymbol>>());
87 EXPECT_THAT(*res.Get<std::vector<lsp::DocumentSymbol>>(),
88 testing::ContainerEq(GetParam().symbols));
89 }
90}
91
92INSTANTIATE_TEST_SUITE_P(,
93 LsSymbolsTest,
94 ::testing::ValuesIn(std::vector<Case>{
95 {
96 "",
97 {},
98 },
99 {
100 ""
101 /* 0 */ "const C = 1;\n"
102 /* 1 */ "/* blah */ var V : i32 = 2i;\n"
103 /* 2 */ "override O = 3f;\n",
104 {
105 Symbol{"C"}
106 .Kind(lsp::SymbolKind::kConstant)
107 .Range(0, 0, 0, 11)
108 .SelectionRange(0, 6, 0, 7),
109 Symbol{"V"}
110 .Kind(lsp::SymbolKind::kVariable)
111 .Range(1, 11, 1, 27)
112 .SelectionRange(1, 15, 1, 16),
113 Symbol{"O"}
114 .Kind(lsp::SymbolKind::kVariable)
115 .Range(2, 0, 2, 15)
116 .SelectionRange(2, 9, 2, 10),
117 },
118 },
119 {
120 ""
121 /* 0 */ "fn fa() {}\n"
122 /* 1 */ "/* blah */ fn fb() -> i32 {\n"
123 /* 2 */ " return 1;\n"
124 /* 3 */ "} // blah",
125 {
126 Symbol{"fa"}
127 .Kind(lsp::SymbolKind::kFunction)
128 .Range(0, 0, 0, 10)
129 .SelectionRange(0, 3, 0, 5),
130 Symbol{"fb"}
131 .Kind(lsp::SymbolKind::kFunction)
132 .Range(1, 11, 3, 1)
133 .SelectionRange(1, 14, 1, 16),
134 },
135 },
136 {
137 ""
138 /* 0 */ "struct s1 { i : i32 }\n"
139 /* 1 */ "alias A = i32;\n"
140 /* 2 */ "/* blah */ struct s2 {\n"
141 /* 3 */ " a : i32,\n"
142 /* 4 */ "} // blah",
143 {
144 Symbol{"s1"}
145 .Kind(lsp::SymbolKind::kStruct)
146 .Range(0, 0, 0, 21)
147 .SelectionRange(0, 7, 0, 9),
148 Symbol{"A"}
149 .Kind(lsp::SymbolKind::kObject)
150 .Range(1, 0, 1, 13)
151 .SelectionRange(1, 6, 1, 7),
152 Symbol{"s2"}
153 .Kind(lsp::SymbolKind::kStruct)
154 .Range(2, 11, 4, 1)
155 .SelectionRange(2, 18, 2, 20),
156 },
157 },
158 }));
159
160} // namespace
161} // namespace tint::wgsl::ls