aboutsummaryrefslogtreecommitdiffstats
path: root/language-web/src/main/js/xtext/xtextServiceResults.ts
diff options
context:
space:
mode:
Diffstat (limited to 'language-web/src/main/js/xtext/xtextServiceResults.ts')
-rw-r--r--language-web/src/main/js/xtext/xtextServiceResults.ts287
1 files changed, 80 insertions, 207 deletions
diff --git a/language-web/src/main/js/xtext/xtextServiceResults.ts b/language-web/src/main/js/xtext/xtextServiceResults.ts
index b2de1e4a..f79b059c 100644
--- a/language-web/src/main/js/xtext/xtextServiceResults.ts
+++ b/language-web/src/main/js/xtext/xtextServiceResults.ts
@@ -1,239 +1,112 @@
1export interface IPongResult { 1import { z } from 'zod';
2 pong: string;
3}
4
5export function isPongResult(result: unknown): result is IPongResult {
6 const pongResult = result as IPongResult;
7 return typeof pongResult === 'object'
8 && typeof pongResult.pong === 'string';
9}
10
11export interface IDocumentStateResult {
12 stateId: string;
13}
14
15export function isDocumentStateResult(result: unknown): result is IDocumentStateResult {
16 const documentStateResult = result as IDocumentStateResult;
17 return typeof documentStateResult === 'object'
18 && typeof documentStateResult.stateId === 'string';
19}
20
21export const VALID_CONFLICTS = ['invalidStateId', 'canceled'] as const;
22
23export type Conflict = typeof VALID_CONFLICTS[number];
24
25export function isConflict(value: unknown): value is Conflict {
26 return typeof value === 'string' && VALID_CONFLICTS.includes(value as Conflict);
27}
28
29export interface IServiceConflictResult {
30 conflict: Conflict;
31}
32
33export function isServiceConflictResult(result: unknown): result is IServiceConflictResult {
34 const serviceConflictResult = result as IServiceConflictResult;
35 return typeof serviceConflictResult === 'object'
36 && isConflict(serviceConflictResult.conflict);
37}
38
39export function isInvalidStateIdConflictResult(result: unknown): boolean {
40 return isServiceConflictResult(result) && result.conflict === 'invalidStateId';
41}
42
43export const VALID_SEVERITIES = ['error', 'warning', 'info', 'ignore'] as const;
44
45export type Severity = typeof VALID_SEVERITIES[number];
46
47export function isSeverity(value: unknown): value is Severity {
48 return typeof value === 'string' && VALID_SEVERITIES.includes(value as Severity);
49}
50
51export interface IIssue {
52 description: string;
53
54 severity: Severity;
55
56 line: number;
57
58 column: number;
59
60 offset: number;
61 2
62 length: number; 3export const pongResult = z.object({
63} 4 pong: z.string().nonempty(),
5});
64 6
65export function isIssue(value: unknown): value is IIssue { 7export type PongResult = z.infer<typeof pongResult>;
66 const issue = value as IIssue;
67 return typeof issue === 'object'
68 && typeof issue.description === 'string'
69 && isSeverity(issue.severity)
70 && typeof issue.line === 'number'
71 && typeof issue.column === 'number'
72 && typeof issue.offset === 'number'
73 && typeof issue.length === 'number';
74}
75 8
76export interface IValidationResult { 9export const documentStateResult = z.object({
77 issues: IIssue[]; 10 stateId: z.string().nonempty(),
78} 11});
79 12
80function isArrayOfType<T>(value: unknown, check: (entry: unknown) => entry is T): value is T[] { 13export type DocumentStateResult = z.infer<typeof documentStateResult>;
81 return Array.isArray(value) && (value as T[]).every(check);
82}
83 14
84export function isValidationResult(result: unknown): result is IValidationResult { 15export const conflict = z.enum(['invalidStateId', 'canceled']);
85 const validationResult = result as IValidationResult;
86 return typeof validationResult === 'object'
87 && isArrayOfType(validationResult.issues, isIssue);
88}
89
90export interface IReplaceRegion {
91 offset: number;
92 16
93 length: number; 17export type Conflict = z.infer<typeof conflict>;
94 18
95 text: string; 19export const serviceConflictResult = z.object({
96} 20 conflict,
21});
97 22
98export function isReplaceRegion(value: unknown): value is IReplaceRegion { 23export type ServiceConflictResult = z.infer<typeof serviceConflictResult>;
99 const replaceRegion = value as IReplaceRegion;
100 return typeof replaceRegion === 'object'
101 && typeof replaceRegion.offset === 'number'
102 && typeof replaceRegion.length === 'number'
103 && typeof replaceRegion.text === 'string';
104}
105
106export interface ITextRegion {
107 offset: number;
108
109 length: number;
110}
111
112export function isTextRegion(value: unknown): value is ITextRegion {
113 const textRegion = value as ITextRegion;
114 return typeof textRegion === 'object'
115 && typeof textRegion.offset === 'number'
116 && typeof textRegion.length === 'number';
117}
118 24
119export const VALID_XTEXT_CONTENT_ASSIST_ENTRY_KINDS = [ 25export function isConflictResult(result: unknown, conflictType: Conflict): boolean {
120 'TEXT', 26 const parsedConflictResult = serviceConflictResult.safeParse(result);
121 'METHOD', 27 return parsedConflictResult.success && parsedConflictResult.data.conflict === conflictType;
122 'FUNCTION',
123 'CONSTRUCTOR',
124 'FIELD',
125 'VARIABLE',
126 'CLASS',
127 'INTERFACE',
128 'MODULE',
129 'PROPERTY',
130 'UNIT',
131 'VALUE',
132 'ENUM',
133 'KEYWORD',
134 'SNIPPET',
135 'COLOR',
136 'FILE',
137 'REFERENCE',
138 'UNKNOWN',
139] as const;
140
141export type XtextContentAssistEntryKind = typeof VALID_XTEXT_CONTENT_ASSIST_ENTRY_KINDS[number];
142
143export function isXtextContentAssistEntryKind(
144 value: unknown,
145): value is XtextContentAssistEntryKind {
146 return typeof value === 'string'
147 && VALID_XTEXT_CONTENT_ASSIST_ENTRY_KINDS.includes(value as XtextContentAssistEntryKind);
148} 28}
149 29
150export interface IContentAssistEntry { 30export const severity = z.enum(['error', 'warning', 'info', 'ignore']);
151 prefix: string;
152 31
153 proposal: string; 32export type Severity = z.infer<typeof severity>;
154 33
155 label?: string; 34export const issue = z.object({
35 description: z.string().nonempty(),
36 severity,
37 line: z.number().int(),
38 column: z.number().int().nonnegative(),
39 offset: z.number().int().nonnegative(),
40 length: z.number().int().nonnegative(),
41});
156 42
157 description?: string; 43export type Issue = z.infer<typeof issue>;
158 44
159 documentation?: string; 45export const validationResult = z.object({
46 issues: issue.array(),
47});
160 48
161 escapePosition?: number; 49export type ValidationResult = z.infer<typeof validationResult>;
162 50
163 textReplacements: IReplaceRegion[]; 51export const replaceRegion = z.object({
52 offset: z.number().int().nonnegative(),
53 length: z.number().int().nonnegative(),
54 text: z.string(),
55});
164 56
165 editPositions: ITextRegion[]; 57export type ReplaceRegion = z.infer<typeof replaceRegion>;
166 58
167 kind: XtextContentAssistEntryKind | string; 59export const textRegion = z.object({
168} 60 offset: z.number().int().nonnegative(),
61 length: z.number().int().nonnegative(),
62});
169 63
170function isStringOrUndefined(value: unknown): value is string | undefined { 64export type TextRegion = z.infer<typeof textRegion>;
171 return typeof value === 'string' || typeof value === 'undefined';
172}
173 65
174function isNumberOrUndefined(value: unknown): value is number | undefined { 66export const contentAssistEntry = z.object({
175 return typeof value === 'number' || typeof value === 'undefined'; 67 prefix: z.string(),
176} 68 proposal: z.string().nonempty(),
69 label: z.string().optional(),
70 description: z.string().nonempty().optional(),
71 documentation: z.string().nonempty().optional(),
72 escapePosition: z.number().int().nonnegative().optional(),
73 textReplacements: replaceRegion.array(),
74 editPositions: textRegion.array(),
75 kind: z.string().nonempty(),
76});
177 77
178export function isContentAssistEntry(value: unknown): value is IContentAssistEntry { 78export type ContentAssistEntry = z.infer<typeof contentAssistEntry>;
179 const entry = value as IContentAssistEntry;
180 return typeof entry === 'object'
181 && typeof entry.prefix === 'string'
182 && typeof entry.proposal === 'string'
183 && isStringOrUndefined(entry.label)
184 && isStringOrUndefined(entry.description)
185 && isStringOrUndefined(entry.documentation)
186 && isNumberOrUndefined(entry.escapePosition)
187 && isArrayOfType(entry.textReplacements, isReplaceRegion)
188 && isArrayOfType(entry.editPositions, isTextRegion)
189 && typeof entry.kind === 'string';
190}
191 79
192export interface IContentAssistResult extends IDocumentStateResult { 80export const contentAssistResult = documentStateResult.extend({
193 entries: IContentAssistEntry[]; 81 entries: contentAssistEntry.array(),
194} 82});
195 83
196export function isContentAssistResult(result: unknown): result is IContentAssistResult { 84export type ContentAssistResult = z.infer<typeof contentAssistResult>;
197 const contentAssistResult = result as IContentAssistResult;
198 return isDocumentStateResult(result)
199 && isArrayOfType(contentAssistResult.entries, isContentAssistEntry);
200}
201 85
202export interface IHighlightingRegion { 86export const highlightingRegion = z.object({
203 offset: number; 87 offset: z.number().int().nonnegative(),
88 length: z.number().int().nonnegative(),
89 styleClasses: z.string().nonempty().array(),
90});
204 91
205 length: number; 92export type HighlightingRegion = z.infer<typeof highlightingRegion>;
206 93
207 styleClasses: string[]; 94export const highlightingResult = z.object({
208} 95 regions: highlightingRegion.array(),
96});
209 97
210export function isHighlightingRegion(value: unknown): value is IHighlightingRegion { 98export type HighlightingResult = z.infer<typeof highlightingResult>;
211 const region = value as IHighlightingRegion;
212 return typeof region === 'object'
213 && typeof region.offset === 'number'
214 && typeof region.length === 'number'
215 && isArrayOfType(region.styleClasses, (s): s is string => typeof s === 'string');
216}
217
218export interface IHighlightingResult {
219 regions: IHighlightingRegion[];
220}
221 99
222export function isHighlightingResult(result: unknown): result is IHighlightingResult { 100export const occurrencesResult = documentStateResult.extend({
223 const highlightingResult = result as IHighlightingResult; 101 writeRegions: textRegion.array(),
224 return typeof highlightingResult === 'object' 102 readRegions: textRegion.array(),
225 && isArrayOfType(highlightingResult.regions, isHighlightingRegion); 103});
226}
227 104
228export interface IOccurrencesResult extends IDocumentStateResult { 105export type OccurrencesResult = z.infer<typeof occurrencesResult>;
229 writeRegions: ITextRegion[];
230 106
231 readRegions: ITextRegion[]; 107export const formattingResult = documentStateResult.extend({
232} 108 formattedText: z.string(),
109 replaceRegion: textRegion,
110});
233 111
234export function isOccurrencesResult(result: unknown): result is IOccurrencesResult { 112export type FormattingResult = z.infer<typeof formattingResult>;
235 const occurrencesResult = result as IOccurrencesResult;
236 return isDocumentStateResult(occurrencesResult)
237 && isArrayOfType(occurrencesResult.writeRegions, isTextRegion)
238 && isArrayOfType(occurrencesResult.readRegions, isTextRegion);
239}