Skip to content

Commit 42eb61f

Browse files
committed
Fixes #339
1 parent ea5780b commit 42eb61f

File tree

3 files changed

+35
-29
lines changed

3 files changed

+35
-29
lines changed

CHANGELOG.md

+1
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
- Fix issue [#336](https://github.com/intersystems/language-server/issues/336): Add intellisense for variables set to the returned value of a method, or a property, with a declared type
55
- Fix issue [#337](https://github.com/intersystems/language-server/issues/337): Improve Hover headers
66
- Fix issue [#338](https://github.com/intersystems/language-server/issues/338): Add intellisense for macros in Embedded SQL
7+
- Fix issue [#339](https://github.com/intersystems/language-server/issues/339): Macro intellisense doesn't respect `#undef` directive
78

89
## [2.5.1] - 2024-07-09
910
- Fix issue [#328](https://github.com/intersystems/language-server/issues/328): Fix namespace detection for Diagnostic computation

server/src/providers/completion.ts

+19-11
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import { CompletionItem, CompletionItemKind, CompletionItemTag, CompletionParams, InsertTextFormat, Position, Range, TextEdit } from 'vscode-languageserver/node';
1+
import { CompletionItem, CompletionItemKind, CompletionItemTag, CompletionParams, InsertTextFormat, MarkupKind, Position, Range, TextEdit } from 'vscode-languageserver/node';
22
import { getServerSpec, getLanguageServerSettings, getMacroContext, makeRESTRequest, normalizeSystemName, getImports, findFullRange, getClassMemberContext, quoteUDLIdentifier, documaticHtmlToMarkdown, determineClassNameParameterClass, storageKeywordsKeyForToken, getParsedDocument, currentClass, normalizeClassname } from '../utils/functions';
33
import { ServerSpec, QueryData, KeywordDoc, MacroContext, compressedline } from '../utils/types';
44
import { documents, corePropertyParams } from '../utils/variables';
@@ -759,20 +759,24 @@ export async function onCompletion(params: CompletionParams): Promise<Completion
759759
}
760760

761761
// Scan up through the file, looking for macro definitions
762+
const undefs: string[] = [];
762763
for (let ln = params.position.line-1; ln >= 0; ln--) {
763-
if (parsed[ln].length < 4) {
764-
continue;
765-
}
766-
if (parsed[ln][0].l == ld.cos_langindex && parsed[ln][0].s == ld.cos_ppc_attrindex) {
764+
if (!parsed[ln]?.length) continue;
765+
if (parsed[ln].length > 1 && parsed[ln][0].l == ld.cos_langindex && parsed[ln][0].s == ld.cos_ppc_attrindex) {
767766
// This line begins with a preprocessor command
768767
const ppctext = doc.getText(Range.create(
769768
ln,parsed[ln][1].p,
770769
ln,parsed[ln][1].p+parsed[ln][1].c
771770
)).toLowerCase();
772-
if (ppctext == "define" || ppctext == "def1arg") {
771+
if (parsed[ln].length > 3 && ["define","def1arg"].includes(ppctext)) {
773772
// This is a macro definition
773+
const macro = doc.getText(Range.create(ln,parsed[ln][2].p,ln,parsed[ln][2].p+parsed[ln][2].c));
774+
if (undefs.includes(macro)) {
775+
// Don't suggest this macro because it was #undef'd before the completion line
776+
continue;
777+
}
774778
const macrodef: CompletionItem = {
775-
label: doc.getText(Range.create(ln,parsed[ln][2].p,ln,parsed[ln][2].p+parsed[ln][2].c)),
779+
label: macro,
776780
kind: CompletionItemKind.Text,
777781
data: ["macro",doc.uri]
778782
};
@@ -830,7 +834,7 @@ export async function onCompletion(params: CompletionParams): Promise<Completion
830834
}
831835
if (docstr != macrodef.label) {
832836
macrodef.documentation = {
833-
kind: "plaintext",
837+
kind: MarkupKind.PlainText,
834838
value: docstr
835839
};
836840
}
@@ -852,14 +856,18 @@ export async function onCompletion(params: CompletionParams): Promise<Completion
852856
const valmatchres = restofline.match(valregex);
853857
if (valmatchres !== null) {
854858
macrodef.documentation = {
855-
kind: "plaintext",
859+
kind: MarkupKind.PlainText,
856860
value: docstr + "\n" + valmatchres[1]
857861
};
858862
}
859863
}
860864
result.push(macrodef);
865+
} else if (parsed[ln].length > 2 && ppctext == "undef") {
866+
// This is a macro un-definition
867+
undefs.push(doc.getText(Range.create(ln,parsed[ln][2].p,ln,parsed[ln][2].p+parsed[ln][2].c)));
861868
}
862869
}
870+
if (parsed[ln].some((t) => t.l == ld.cls_langindex)) break;
863871
}
864872
}
865873
else if (prevline.slice(-1) === "$" && prevline.charAt(prevline.length-2) !== "$" && triggerlang === ld.cos_langindex) {
@@ -2127,7 +2135,7 @@ export async function onCompletionResolve(item: CompletionItem): Promise<Complet
21272135
if (respdata !== undefined && respdata.data.result.content.length > 0) {
21282136
// The class was found
21292137
item.documentation = {
2130-
kind: "markdown",
2138+
kind: MarkupKind.Markdown,
21312139
value: documaticHtmlToMarkdown(respdata.data.result.content[0].Description)
21322140
};
21332141
}
@@ -2156,7 +2164,7 @@ export async function onCompletionResolve(item: CompletionItem): Promise<Complet
21562164
defstr = defstr.concat(parts[0],"\n",parts.slice(1).join());
21572165
}
21582166
item.documentation = {
2159-
kind: "plaintext",
2167+
kind: MarkupKind.PlainText,
21602168
value: defstr
21612169
};
21622170
}

server/src/utils/functions.ts

+15-18
Original file line numberDiff line numberDiff line change
@@ -1116,32 +1116,29 @@ export async function createDefinitionUri(paramsUri: string, filename: string, e
11161116
* @param macro The selected macro.
11171117
*/
11181118
export function isMacroDefinedAbove(doc: TextDocument, parsed: compressedline[], line: number, macro: string): number {
1119-
var result: number = -1;
1119+
let result: number = -1;
11201120

11211121
// Scan up through the file, looking for macro definitions
11221122
for (let ln = line-1; ln >= 0; ln--) {
1123-
if (parsed[ln].length < 4) {
1124-
continue;
1125-
}
1126-
if (parsed[ln][0].l == ld.cos_langindex && parsed[ln][0].s == ld.cos_ppc_attrindex) {
1123+
if (!parsed[ln]?.length) continue;
1124+
if (parsed[ln].length > 1 && parsed[ln][0].l == ld.cos_langindex && parsed[ln][0].s == ld.cos_ppc_attrindex) {
11271125
// This line begins with a preprocessor command
11281126
const ppctext = doc.getText(Range.create(
1129-
Position.create(ln,parsed[ln][1].p),
1130-
Position.create(ln,parsed[ln][1].p+parsed[ln][1].c)
1127+
ln,parsed[ln][1].p,
1128+
ln,parsed[ln][1].p+parsed[ln][1].c
11311129
)).toLowerCase();
1132-
if (ppctext === "define" || ppctext === "def1arg") {
1133-
// This is a macro definition
1134-
const macrotext = doc.getText(Range.create(
1135-
Position.create(ln,parsed[ln][2].p),
1136-
Position.create(ln,parsed[ln][2].p+parsed[ln][2].c)
1137-
));
1138-
if (macrotext === macro) {
1139-
// We found the definition for the selected macro
1140-
result = ln;
1141-
break;
1142-
}
1130+
if (
1131+
parsed[ln].length > 2 && ["define","def1arg","undef"].includes(ppctext) && doc.getText(Range.create(
1132+
ln,parsed[ln][2].p,
1133+
ln,parsed[ln][2].p+parsed[ln][2].c
1134+
)) == macro
1135+
) {
1136+
// We found the (un-)definition for the selected macro
1137+
if (ppctext != "undef") result = ln;
1138+
break;
11431139
}
11441140
}
1141+
if (parsed[ln].some((t) => t.l == ld.cls_langindex)) break;
11451142
}
11461143

11471144
return result;

0 commit comments

Comments
 (0)