Skip to content

Commit 790e5b5

Browse files
authored
Fix languge server functions when not Cfn (#307)
* Validate template is CloudFormation before determining symbols * When validating if a template is cfn make sure there are enough lines
1 parent a9bed18 commit 790e5b5

File tree

2 files changed

+96
-2
lines changed

2 files changed

+96
-2
lines changed

server/src/requestTypes.ts

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,3 +27,9 @@ export namespace PreviewClosed {
2727
"cfn/previewClosed"
2828
);
2929
}
30+
31+
export namespace ResultLimitReachedNotification {
32+
export const type: NotificationType<string> = new NotificationType(
33+
"cfn/resultLimitReached"
34+
);
35+
}

server/src/server/handlers/languageHandlers.ts

Lines changed: 90 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,9 @@ import { Connection } from "vscode-languageserver";
1717
import {
1818
TextDocumentPositionParams,
1919
DocumentFormattingParams,
20+
DocumentSymbolParams,
21+
DocumentSymbol,
22+
SymbolInformation,
2023
} from "vscode-languageserver-protocol";
2124
import { CompletionList, TextEdit, Hover } from "vscode-languageserver-types";
2225
import { SettingsState } from "../../cfnSettings";
@@ -31,11 +34,14 @@ import {
3134
} from "yaml-language-server/out/server/src/languageservice/parser/jsonParser07";
3235
import { MarkdownString } from "../../utils/markdownString";
3336
import { LanguageService } from "../../service/cfnLanguageService";
37+
import { ResultLimitReachedNotification } from "../../requestTypes";
38+
import * as path from "path";
3439

3540
// code adopted from https://github.com/redhat-developer/yaml-language-server/blob/main/src/languageserver/handlers/languageHandlers.ts
3641
export class LanguageHandlers extends YamlLanguageHandlers {
3742
private cfnLanguageService: LanguageService;
3843
private cfnSettings: SettingsState;
44+
private cfnConnection: Connection;
3945

4046
pendingLimitExceededWarnings: {
4147
[uri: string]: {
@@ -51,6 +57,7 @@ export class LanguageHandlers extends YamlLanguageHandlers {
5157
validationHandler: ValidationHandler
5258
) {
5359
super(connection, languageService, cfnSettings, validationHandler);
60+
this.cfnConnection = connection;
5461
this.cfnSettings = cfnSettings;
5562
this.cfnLanguageService = languageService;
5663
}
@@ -75,14 +82,18 @@ export class LanguageHandlers extends YamlLanguageHandlers {
7582
return Promise.resolve(result);
7683
}
7784

85+
let [node, template] = getNode(textDocument, textDocumentPosition);
86+
87+
if (!template.isValidTemplate && textDocument.lineCount > 4) {
88+
return Promise.resolve(result);
89+
}
90+
7891
const results = await this.cfnLanguageService.doComplete(
7992
textDocument,
8093
textDocumentPosition.position,
8194
false
8295
);
8396

84-
let [node, template] = getNode(textDocument, textDocumentPosition);
85-
8697
function addResources(prefix: string) {
8798
template.resources.forEach((value: TypeInfoImpl, key: string) => {
8899
results.items.push({
@@ -173,6 +184,53 @@ export class LanguageHandlers extends YamlLanguageHandlers {
173184
return this.cfnLanguageService.doFormat(document, customFormatterSettings);
174185
}
175186

187+
/**
188+
* Called when the code outline in an editor needs to be populated
189+
* Returns a list of symbols that is then shown in the code outline
190+
*/
191+
documentSymbolHandler(
192+
documentSymbolParams: DocumentSymbolParams
193+
): DocumentSymbol[] | SymbolInformation[] {
194+
const document = this.cfnSettings.documents.get(
195+
documentSymbolParams.textDocument.uri
196+
);
197+
198+
if (!document) {
199+
// @ts-ignore
200+
return;
201+
}
202+
203+
let [_, template] = getNode(document, {
204+
textDocument: document,
205+
position: {
206+
line: 0,
207+
character: 0,
208+
},
209+
});
210+
211+
if (!template.isValidTemplate) {
212+
// @ts-ignore
213+
return;
214+
}
215+
216+
const onResultLimitExceeded = this.onCfnResultLimitExceeded(
217+
document.uri,
218+
this.cfnSettings.maxItemsComputed,
219+
"document symbols"
220+
);
221+
222+
const context = {
223+
resultLimit: this.cfnSettings.maxItemsComputed,
224+
onResultLimitExceeded,
225+
};
226+
227+
if (this.cfnSettings.hierarchicalDocumentSymbolSupport) {
228+
return this.cfnLanguageService.findDocumentSymbols2(document, context);
229+
} else {
230+
return this.cfnLanguageService.findDocumentSymbols(document, context);
231+
}
232+
}
233+
176234
/**
177235
* Called when the user hovers with their mouse over a keyword
178236
* Returns an informational tooltip
@@ -240,4 +298,34 @@ export class LanguageHandlers extends YamlLanguageHandlers {
240298

241299
return hover;
242300
}
301+
302+
private onCfnResultLimitExceeded(
303+
uri: string,
304+
resultLimit: number,
305+
name: string
306+
) {
307+
return () => {
308+
let warning = this.pendingLimitExceededWarnings[uri];
309+
if (warning) {
310+
if (!warning.timeout) {
311+
// already shown
312+
return;
313+
}
314+
warning.features[name] = name;
315+
warning.timeout.refresh();
316+
} else {
317+
warning = { features: { [name]: name } };
318+
warning.timeout = setTimeout(() => {
319+
this.cfnConnection.sendNotification(
320+
ResultLimitReachedNotification.type,
321+
`${path.basename(uri)}: For performance reasons, ${Object.keys(
322+
warning.features
323+
).join(" and ")} have been limited to ${resultLimit} items.`
324+
);
325+
warning.timeout = undefined;
326+
}, 2000);
327+
this.pendingLimitExceededWarnings[uri] = warning;
328+
}
329+
};
330+
}
243331
}

0 commit comments

Comments
 (0)