aboutsummaryrefslogtreecommitdiffstats
path: root/language-web/src/main/js/editor/xtextServiceResults.ts
diff options
context:
space:
mode:
Diffstat (limited to 'language-web/src/main/js/editor/xtextServiceResults.ts')
-rw-r--r--language-web/src/main/js/editor/xtextServiceResults.ts138
1 files changed, 132 insertions, 6 deletions
diff --git a/language-web/src/main/js/editor/xtextServiceResults.ts b/language-web/src/main/js/editor/xtextServiceResults.ts
index 8a4afa40..6c3d9daf 100644
--- a/language-web/src/main/js/editor/xtextServiceResults.ts
+++ b/language-web/src/main/js/editor/xtextServiceResults.ts
@@ -22,20 +22,32 @@ export const VALID_CONFLICTS = ['invalidStateId', 'canceled'] as const;
22 22
23export type Conflict = typeof VALID_CONFLICTS[number]; 23export type Conflict = typeof VALID_CONFLICTS[number];
24 24
25export function isConflict(value: unknown): value is Conflict {
26 return typeof value === 'string' && VALID_CONFLICTS.includes(value as Conflict);
27}
28
25export interface IServiceConflictResult { 29export interface IServiceConflictResult {
26 conflict: Conflict; 30 conflict: Conflict;
27} 31}
28 32
29export function isServiceConflictResult(result: unknown): result is IServiceConflictResult { 33export function isServiceConflictResult(result: unknown): result is IServiceConflictResult {
30 const serviceConflictResult = result as IServiceConflictResult; 34 const serviceConflictResult = result as IServiceConflictResult;
31 return typeof serviceConflictResult.conflict === 'string' 35 return typeof serviceConflictResult === 'object'
32 && VALID_CONFLICTS.includes(serviceConflictResult.conflict); 36 && isConflict(serviceConflictResult.conflict);
37}
38
39export function isInvalidStateIdConflictResult(result: unknown): boolean {
40 return isServiceConflictResult(result) && result.conflict === 'invalidStateId';
33} 41}
34 42
35export const VALID_SEVERITIES = ['error', 'warning', 'info', 'ignore'] as const; 43export const VALID_SEVERITIES = ['error', 'warning', 'info', 'ignore'] as const;
36 44
37export type Severity = typeof VALID_SEVERITIES[number]; 45export type Severity = typeof VALID_SEVERITIES[number];
38 46
47export function isSeverity(value: unknown): value is Severity {
48 return typeof value === 'string' && VALID_SEVERITIES.includes(value as Severity);
49}
50
39export interface IIssue { 51export interface IIssue {
40 description: string; 52 description: string;
41 53
@@ -54,8 +66,7 @@ export function isIssue(value: unknown): value is IIssue {
54 const issue = value as IIssue; 66 const issue = value as IIssue;
55 return typeof issue === 'object' 67 return typeof issue === 'object'
56 && typeof issue.description === 'string' 68 && typeof issue.description === 'string'
57 && typeof issue.severity === 'string' 69 && isSeverity(issue.severity)
58 && VALID_SEVERITIES.includes(issue.severity)
59 && typeof issue.line === 'number' 70 && typeof issue.line === 'number'
60 && typeof issue.column === 'number' 71 && typeof issue.column === 'number'
61 && typeof issue.offset === 'number' 72 && typeof issue.offset === 'number'
@@ -66,9 +77,124 @@ export interface IValidationResult {
66 issues: IIssue[]; 77 issues: IIssue[];
67} 78}
68 79
80function isArrayOfType<T>(value: unknown, check: (entry: unknown) => entry is T): value is T[] {
81 return Array.isArray(value) && (value as T[]).every(check);
82}
83
69export function isValidationResult(result: unknown): result is IValidationResult { 84export function isValidationResult(result: unknown): result is IValidationResult {
70 const validationResult = result as IValidationResult; 85 const validationResult = result as IValidationResult;
71 return typeof validationResult === 'object' 86 return typeof validationResult === 'object'
72 && Array.isArray(validationResult.issues) 87 && isArrayOfType(validationResult.issues, isIssue);
73 && validationResult.issues.every(isIssue); 88}
89
90export interface IReplaceRegion {
91 offset: number;
92
93 length: number;
94
95 text: string;
96}
97
98export function isReplaceRegion(value: unknown): value is IReplaceRegion {
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
119export const VALID_XTEXT_CONTENT_ASSIST_ENTRY_KINDS = [
120 'TEXT',
121 'METHOD',
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}
149
150export interface IContentAssistEntry {
151 prefix: string;
152
153 proposal: string;
154
155 label?: string;
156
157 description?: string;
158
159 documentation?: string;
160
161 escapePosition?: number;
162
163 textReplacements: IReplaceRegion[];
164
165 editPositions: ITextRegion[];
166
167 kind: XtextContentAssistEntryKind | string;
168}
169
170function isStringOrUndefined(value: unknown): value is string | undefined {
171 return typeof value === 'string' || typeof value === 'undefined';
172}
173
174function isNumberOrUndefined(value: unknown): value is number | undefined {
175 return typeof value === 'number' || typeof value === 'undefined';
176}
177
178export function isContentAssistEntry(value: unknown): value is IContentAssistEntry {
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
192export interface IContentAssistResult extends IDocumentStateResult {
193 entries: IContentAssistEntry[];
194}
195
196export function isContentAssistResult(result: unknown): result is IContentAssistResult {
197 const contentAssistResult = result as IContentAssistResult;
198 return isDocumentStateResult(result)
199 && isArrayOfType(contentAssistResult.entries, isContentAssistEntry);
74} 200}