diff options
Diffstat (limited to 'subprojects/frontend/src/xtext/ContentAssistService.ts')
-rw-r--r-- | subprojects/frontend/src/xtext/ContentAssistService.ts | 39 |
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 | ||
34 | function findToken({ pos, state }: CompletionContext): IFoundToken | null { | 34 | function 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 | ||
52 | function shouldCompleteImplicitly( | 49 | function 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 { | |||
107 | export default class ContentAssistService { | 106 | export 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( |