aboutsummaryrefslogtreecommitdiffstats
path: root/subprojects/frontend/src/xtext/ContentAssistService.ts
diff options
context:
space:
mode:
Diffstat (limited to 'subprojects/frontend/src/xtext/ContentAssistService.ts')
-rw-r--r--subprojects/frontend/src/xtext/ContentAssistService.ts39
1 files changed, 21 insertions, 18 deletions
diff --git a/subprojects/frontend/src/xtext/ContentAssistService.ts b/subprojects/frontend/src/xtext/ContentAssistService.ts
index dce2a902..39042812 100644
--- a/subprojects/frontend/src/xtext/ContentAssistService.ts
+++ b/subprojects/frontend/src/xtext/ContentAssistService.ts
@@ -31,15 +31,12 @@ interface IFoundToken {
31 text: string; 31 text: string;
32} 32}
33 33
34function findToken({ pos, state }: CompletionContext): IFoundToken | null { 34function findToken({ pos, state }: CompletionContext): IFoundToken | undefined {
35 const token = syntaxTree(state).resolveInner(pos, -1); 35 const token = syntaxTree(state).resolveInner(pos, -1);
36 if (token === null) {
37 return null;
38 }
39 if (token.firstChild !== null) { 36 if (token.firstChild !== null) {
40 // We only autocomplete terminal nodes. If the current node is nonterminal, 37 // We only autocomplete terminal nodes. If the current node is nonterminal,
41 // returning `null` makes us autocomplete with the empty prefix instead. 38 // returning `undefined` makes us autocomplete with the empty prefix instead.
42 return null; 39 return undefined;
43 } 40 }
44 return { 41 return {
45 from: token.from, 42 from: token.from,
@@ -50,11 +47,13 @@ function findToken({ pos, state }: CompletionContext): IFoundToken | null {
50} 47}
51 48
52function shouldCompleteImplicitly( 49function shouldCompleteImplicitly(
53 token: IFoundToken | null, 50 token: IFoundToken | undefined,
54 context: CompletionContext, 51 context: CompletionContext,
55): boolean { 52): boolean {
56 return ( 53 return (
57 token !== null && token.implicitCompletion && context.pos - token.from >= 2 54 token !== undefined &&
55 token.implicitCompletion &&
56 context.pos - token.from >= 2
58 ); 57 );
59} 58}
60 59
@@ -107,7 +106,7 @@ function createCompletion(entry: ContentAssistEntry): Completion {
107export default class ContentAssistService { 106export default class ContentAssistService {
108 private readonly updateService: UpdateService; 107 private readonly updateService: UpdateService;
109 108
110 private lastCompletion: CompletionResult | null = null; 109 private lastCompletion: CompletionResult | undefined;
111 110
112 constructor(updateService: UpdateService) { 111 constructor(updateService: UpdateService) {
113 this.updateService = updateService; 112 this.updateService = updateService;
@@ -115,7 +114,7 @@ export default class ContentAssistService {
115 114
116 onTransaction(transaction: Transaction): void { 115 onTransaction(transaction: Transaction): void {
117 if (this.shouldInvalidateCachedCompletion(transaction)) { 116 if (this.shouldInvalidateCachedCompletion(transaction)) {
118 this.lastCompletion = null; 117 this.lastCompletion = undefined;
119 } 118 }
120 } 119 }
121 120
@@ -129,7 +128,7 @@ export default class ContentAssistService {
129 } 128 }
130 let range: { from: number; to: number }; 129 let range: { from: number; to: number };
131 let prefix = ''; 130 let prefix = '';
132 if (tokenBefore === null) { 131 if (tokenBefore === undefined) {
133 range = { 132 range = {
134 from: context.pos, 133 from: context.pos,
135 to: context.pos, 134 to: context.pos,
@@ -146,14 +145,18 @@ export default class ContentAssistService {
146 } 145 }
147 } 146 }
148 if (!context.explicit && this.shouldReturnCachedCompletion(tokenBefore)) { 147 if (!context.explicit && this.shouldReturnCachedCompletion(tokenBefore)) {
148 if (this.lastCompletion === undefined) {
149 throw new Error(
150 'There is no cached completion, but we want to return it',
151 );
152 }
149 log.trace('Returning cached completion result'); 153 log.trace('Returning cached completion result');
150 // Postcondition of `shouldReturnCachedCompletion`: `lastCompletion !== null`
151 return { 154 return {
152 ...(this.lastCompletion as CompletionResult), 155 ...this.lastCompletion,
153 ...range, 156 ...range,
154 }; 157 };
155 } 158 }
156 this.lastCompletion = null; 159 this.lastCompletion = undefined;
157 const entries = await this.updateService.fetchContentAssist( 160 const entries = await this.updateService.fetchContentAssist(
158 { 161 {
159 resource: this.updateService.resourceName, 162 resource: this.updateService.resourceName,
@@ -188,9 +191,9 @@ export default class ContentAssistService {
188 } 191 }
189 192
190 private shouldReturnCachedCompletion( 193 private shouldReturnCachedCompletion(
191 token: { from: number; to: number; text: string } | null, 194 token: { from: number; to: number; text: string } | undefined,
192 ): boolean { 195 ): boolean {
193 if (token === null || this.lastCompletion === null) { 196 if (token === undefined || this.lastCompletion === undefined) {
194 return false; 197 return false;
195 } 198 }
196 const { from, to, text } = token; 199 const { from, to, text } = token;
@@ -211,11 +214,11 @@ export default class ContentAssistService {
211 } 214 }
212 215
213 private shouldInvalidateCachedCompletion(transaction: Transaction): boolean { 216 private shouldInvalidateCachedCompletion(transaction: Transaction): boolean {
214 if (!transaction.docChanged || this.lastCompletion === null) { 217 if (!transaction.docChanged || this.lastCompletion === undefined) {
215 return false; 218 return false;
216 } 219 }
217 const { from: lastFrom, to: lastTo } = this.lastCompletion; 220 const { from: lastFrom, to: lastTo } = this.lastCompletion;
218 if (!lastTo) { 221 if (lastTo === undefined) {
219 return true; 222 return true;
220 } 223 }
221 const [transformedFrom, transformedTo] = this.mapRangeInclusive( 224 const [transformedFrom, transformedTo] = this.mapRangeInclusive(