Skip to content

Commit 9bde2dc

Browse files
V628-012: Improve highlighter robustness
Fix "Basic decl having multiple defining names" property errors. Add generic exception handler and log the error when ALS.HIGHIGHTERS.DEBUG is active. Add simple test.
1 parent 0bcd113 commit 9bde2dc

File tree

7 files changed

+303
-16
lines changed

7 files changed

+303
-16
lines changed

source/ada/lsp-ada_documents.adb

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1730,7 +1730,7 @@ package body LSP.Ada_Documents is
17301730
Unit : constant Libadalang.Analysis.Analysis_Unit :=
17311731
Self.Unit (Context);
17321732
begin
1733-
return Highlighter.Get_Tokens (Unit, Span);
1733+
return Highlighter.Get_Tokens (Unit, Context.Trace, Span);
17341734
end Get_Tokens;
17351735

17361736
-----------------

source/ada/lsp-ada_highlighters.adb

Lines changed: 27 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -21,12 +21,16 @@ with Langkit_Support.Slocs;
2121
with Langkit_Support.Token_Data_Handlers;
2222
with Libadalang.Common;
2323

24-
with VSS.Strings;
25-
24+
with LSP.Common;
2625
with LSP.Lal_Utils;
2726

27+
with VSS.Strings;
28+
2829
package body LSP.Ada_Highlighters is
2930

31+
Highlighter_Debug : constant GNATCOLL.Traces.Trace_Handle :=
32+
GNATCOLL.Traces.Create ("ALS.HIGHLIGHTERS.DEBUG", GNATCOLL.Traces.Off);
33+
3034
package Highlights_Holders is
3135
type Highlights_Holder is tagged limited private;
3236
-- Highlights_Holder stores style for each token in the range given
@@ -245,9 +249,10 @@ package body LSP.Ada_Highlighters is
245249
----------------
246250

247251
function Get_Tokens
248-
(Self : Ada_Highlighter'Class;
249-
Unit : Libadalang.Analysis.Analysis_Unit;
250-
Span : LSP.Messages.Span)
252+
(Self : Ada_Highlighter'Class;
253+
Unit : Libadalang.Analysis.Analysis_Unit;
254+
Trace : GNATCOLL.Traces.Trace_Handle;
255+
Span : LSP.Messages.Span)
251256
return LSP.Messages.uinteger_Vector
252257
is
253258
use type LSP.Types.Line_Number;
@@ -619,8 +624,8 @@ package body LSP.Ada_Highlighters is
619624
end;
620625

621626
begin
622-
if Decl.P_Has_Aspect (Self.Obsolescent)
623-
or else not Decl.P_Get_Pragma (Self.Obsolescent).Is_Null
627+
if Def.P_Has_Aspect (Self.Obsolescent)
628+
or else not Def.P_Get_Pragma (Self.Obsolescent).Is_Null
624629
then
625630
Highlight_Token (Node.Token_Start, deprecated);
626631
end if;
@@ -648,10 +653,6 @@ package body LSP.Ada_Highlighters is
648653
-- Fallback to some default for any unresolved identifier
649654
Highlight_Token (Node.Token_Start, modifier);
650655
end if;
651-
652-
exception
653-
when Libadalang.Common.Property_Error =>
654-
null;
655656
end Highlight_Name;
656657

657658
Holder : Highlights_Holders.Highlights_Holder;
@@ -684,6 +685,12 @@ package body LSP.Ada_Highlighters is
684685
end case;
685686

686687
return Libadalang.Common.Into;
688+
exception
689+
when E : Libadalang.Common.Property_Error =>
690+
if Highlighter_Debug.Is_Active then
691+
LSP.Common.Log (Trace, E, "In Highlight_Node");
692+
end if;
693+
return Libadalang.Common.Into;
687694
end Highlight_Node;
688695

689696
---------------------
@@ -727,14 +734,22 @@ package body LSP.Ada_Highlighters is
727734
begin
728735
case Node.Kind is
729736
when Libadalang.Common.Ada_Basic_Decl =>
730-
return Node.As_Basic_Decl.P_Is_Ghost_Code;
737+
declare
738+
Name : constant Libadalang.Analysis.Defining_Name :=
739+
Node.As_Basic_Decl.P_Defining_Name;
740+
begin
741+
return (not Name.Is_Null) and then Name.P_Is_Ghost_Code;
742+
end;
731743
when Libadalang.Common.Ada_Aspect_Spec =>
732744
-- Mark all aspects as a ghost code, because most of aspects
733745
-- are contract specifications.
734746
return True;
735747
when others =>
736748
return False;
737749
end case;
750+
exception
751+
when Libadalang.Common.Property_Error =>
752+
return False;
738753
end Is_Ghost_Root_Node;
739754

740755
Root : constant Libadalang.Analysis.Ada_Node :=

source/ada/lsp-ada_highlighters.ads

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,8 @@
1818
with Ada.Containers.Hashed_Maps;
1919
with Ada.Strings.Wide_Wide_Unbounded;
2020

21+
with GNATCOLL.Traces;
22+
2123
with Libadalang.Analysis;
2224

2325
with LSP.Messages;
@@ -33,9 +35,10 @@ package LSP.Ada_Highlighters is
3335
Legend : out LSP.Messages.SemanticTokensLegend);
3436

3537
function Get_Tokens
36-
(Self : Ada_Highlighter'Class;
37-
Unit : Libadalang.Analysis.Analysis_Unit;
38-
Span : LSP.Messages.Span)
38+
(Self : Ada_Highlighter'Class;
39+
Unit : Libadalang.Analysis.Analysis_Unit;
40+
Trace : GNATCOLL.Traces.Trace_Handle;
41+
Span : LSP.Messages.Span)
3942
return LSP.Messages.uinteger_Vector;
4043
-- If Span isn't empty then return unit tokens in given Span, otherwise
4144
-- return all tokens in the Unit.
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
project Default is
2+
3+
for Main use ("foo.adb");
4+
5+
end Default;
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
procedure Foo is
2+
3+
type My_Type is new Integer range 1 .. 10;
4+
5+
X, Y : My_Type := 1; -- Decl with multiple defining names
6+
begin
7+
X := Y + My_Type (9);
8+
end Foo;
Lines changed: 255 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,255 @@
1+
[
2+
{
3+
"comment": [
4+
"Basic test for semanticTokens"
5+
]
6+
},
7+
{
8+
"start": {
9+
"cmd": [
10+
"${ALS}"
11+
]
12+
}
13+
},
14+
{
15+
"send": {
16+
"request": {
17+
"params": {
18+
"processId": 31570,
19+
"capabilities": {
20+
"textDocument": {
21+
"completion": {
22+
"completionItem": {
23+
"documentationFormat": [
24+
"plaintext",
25+
"markdown"
26+
],
27+
"snippetSupport": true
28+
},
29+
"dynamicRegistration": true
30+
},
31+
"semanticTokens": {
32+
"refreshSupport":true,
33+
"dynamicRegistration":true,
34+
"tokenTypes": ["namespace","type","class","enum","interface","struct","typeParameter","parameter","variable","property","enumMember","event","function","method","macro","keyword","modifier","comment","string","number","regexp","operator"],
35+
"tokenModifiers": ["declaration","definition","readonly","static","deprecated","abstract","async","modification","documentation","defaultLibrary"],
36+
"formats":["relative"],
37+
"requests": {
38+
"range": true,
39+
"full": true
40+
},
41+
"overlappingTokenSupport" : true,
42+
"multilineTokenSupport" : true
43+
},
44+
"definition": {},
45+
"hover": {},
46+
"formatting": {
47+
"dynamicRegistration": true
48+
},
49+
"implementation": {},
50+
"codeLens": {},
51+
"typeDefinition": {},
52+
"selectionRange": {},
53+
"documentHighlight": {},
54+
"documentSymbol": {
55+
"hierarchicalDocumentSymbolSupport": true
56+
},
57+
"synchronization": {},
58+
"references": {},
59+
"rangeFormatting": {},
60+
"onTypeFormatting": {},
61+
"declaration": {},
62+
"foldingRange": {
63+
"lineFoldingOnly": true
64+
},
65+
"colorProvider": {}
66+
},
67+
"workspace": {
68+
"applyEdit": true,
69+
"executeCommand": {},
70+
"didChangeWatchedFiles": {},
71+
"workspaceEdit": {},
72+
"didChangeConfiguration": {},
73+
"semanticTokens": {
74+
"refreshSupport": true
75+
}
76+
}
77+
},
78+
"rootUri": "$URI{.}"
79+
},
80+
"jsonrpc": "2.0",
81+
"id": 1,
82+
"method": "initialize"
83+
},
84+
"wait": [
85+
{
86+
"jsonrpc": "2.0",
87+
"id": 1,
88+
"result": {
89+
"capabilities": {
90+
"textDocumentSync": 2,
91+
"completionProvider": {
92+
"triggerCharacters": [
93+
".",
94+
",",
95+
"'",
96+
"("
97+
],
98+
"resolveProvider": true
99+
},
100+
"semanticTokensProvider": {
101+
"legend": {
102+
"tokenTypes": ["namespace","type","class","enum","interface","struct","typeParameter","parameter","variable","property","enumMember","function","keyword","modifier","comment","string","number","operator"],
103+
"tokenModifiers": ["declaration","definition","readonly","static","deprecated","abstract","modification","documentation","defaultLibrary"]
104+
},
105+
"range": true,
106+
"full": {}
107+
},
108+
"hoverProvider": true,
109+
"declarationProvider": true,
110+
"definitionProvider": true,
111+
"typeDefinitionProvider": true,
112+
"implementationProvider": true,
113+
"referencesProvider": true,
114+
"codeActionProvider": {
115+
},
116+
"renameProvider": {
117+
},
118+
"foldingRangeProvider": true,
119+
"executeCommandProvider": {},
120+
"alsReferenceKinds": [
121+
"reference",
122+
"access",
123+
"write",
124+
"call",
125+
"dispatching call",
126+
"parent",
127+
"child",
128+
"overriding"
129+
]
130+
}
131+
}
132+
}
133+
]
134+
}
135+
},
136+
{
137+
"send": {
138+
"request": {
139+
"jsonrpc": "2.0",
140+
"method": "initialized"
141+
},
142+
"wait": []
143+
}
144+
},
145+
{
146+
"send": {
147+
"request": {
148+
"params": {
149+
"settings": {
150+
"ada": {
151+
"projectFile": "$URI{default.gpr}",
152+
"scenarioVariables": {},
153+
"defaultCharset": "ISO-8859-1"
154+
}
155+
}
156+
},
157+
"jsonrpc": "2.0",
158+
"method": "workspace/didChangeConfiguration"
159+
},
160+
"wait": []
161+
}
162+
},
163+
{
164+
"send": {
165+
"request": {
166+
"jsonrpc": "2.0",
167+
"method": "textDocument/didOpen",
168+
"params": {
169+
"textDocument": {
170+
"uri": "$URI{foo.adb}",
171+
"languageId": "Ada",
172+
"version": 0,
173+
"text": "procedure Foo is\n\n type My_Type is new Integer range 1 .. 10;\n\n X, Y : My_Type := 1; -- Decl with multiple defining names\nbegin\n X := Y + My_Type (9);\nend Foo;\n"
174+
}
175+
}
176+
},
177+
"wait": []
178+
}
179+
},
180+
{
181+
"send": {
182+
"request": {
183+
"jsonrpc": "2.0",
184+
"id": 2,
185+
"method": "textDocument/semanticTokens/range",
186+
"params": {
187+
"textDocument": {
188+
"uri": "$URI{foo.adb}"
189+
},
190+
"range": {
191+
"start": {
192+
"line": 0,
193+
"character": 0
194+
},
195+
"end": {
196+
"line": 4,
197+
"character": 0
198+
}
199+
}
200+
}
201+
},
202+
"wait": [
203+
{
204+
"jsonrpc": "2.0",
205+
"id": 2,
206+
"result": {
207+
"data": [0,10,3,11,1,2,8,7,1,9,0,15,7,1,264,2,3,1,8,1,0,3,1,8,1,0,4,7,1,8]}
208+
}
209+
]
210+
211+
}
212+
},
213+
{
214+
"send": {
215+
"request": {
216+
"jsonrpc": "2.0",
217+
"id": 3,
218+
"method": "textDocument/semanticTokens/full",
219+
"params": {
220+
"textDocument": {
221+
"uri": "$URI{foo.adb}"
222+
}
223+
}
224+
},
225+
"wait": [
226+
{
227+
"jsonrpc": "2.0",
228+
"id": 3,
229+
"result": {
230+
"data": [0,10,3,11,1,2,8,7,1,9,0,15,7,1,264,2,3,1,8,1,0,3,1,8,1,0,4,7,1,8,2,3,1,8,64,0,5,1,8,0,0,4,7,1,8,1,4,3,11,0]
231+
}
232+
}
233+
]
234+
}
235+
},
236+
{
237+
"send": {
238+
"request": {
239+
"jsonrpc": "2.0",
240+
"method": "textDocument/didClose",
241+
"params": {
242+
"textDocument": {
243+
"uri": "$URI{foo.adb}"
244+
}
245+
}
246+
},
247+
"wait": []
248+
}
249+
},
250+
{
251+
"stop": {
252+
"exit_code": 0
253+
}
254+
}
255+
]
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
title: 'V628-012.highlighting.defining_names'

0 commit comments

Comments
 (0)