Skip to content

Commit c48373f

Browse files
committed
temp
1 parent a132922 commit c48373f

21 files changed

+128615
-34693
lines changed

docs/issues.md

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
# Known Issues
2+
3+
## v0.1.0
4+
**1. ⚠️ Inconsistent Completions ⚠️**
5+
Sometimes completions for simple values like INT, FLOAT, BOOLEAN, etc.. do not get shown. This is parsly because of the ANTLR grammar and Antlr4-c3 library taking to long to "walk" down every possible path and parsly because i do not know what i am doing ;\).
6+
7+
**2. ⚠️ ArmorTypes contain DamageTypes ⚠️**
8+
Yes, for a simpler parser the two share the same names, this only affects ArmorTypes that has KILL_GARRISONED & STATUS as ArmorType even tho they are DamageTypes
9+
10+
**3. ⚠️ Inconsistent completions with VETERENCY ⚠️**
11+
There have been obsereved issue where completions wont show correctly after a VETERENCY value (VETERAN, ELITE, HEROIC).

server/src/completion/helpers.ts

Lines changed: 194 additions & 49 deletions
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@ export function findTokenIndex(tokens: Token[], offset: number): number {
1818
return tokens.length - 1;
1919
}
2020

21-
export function generateCompletionItems(candidates: CandidatesCollection, parser: MapIniParser): CompletionItem[] {
21+
export async function generateCompletionItems(candidates: CandidatesCollection, parser: MapIniParser): Promise<CompletionItem[]> {
2222
const completionItems: CompletionItem[] = [];
2323

2424
// Process token candidates (keywords, symbols)
@@ -34,12 +34,66 @@ export function generateCompletionItems(candidates: CandidatesCollection, parser
3434
? tokenName.substring(1, tokenName.length - 1)
3535
: tokenName;
3636

37-
switch(label) {
3837

38+
completionItems.push(createCompletionItem(label, CompletionItemKind.Field, tokenType, `Rule: ${label}`));
39+
40+
switch (label) {
41+
3942
case 'NEWLINE':
4043
case 'COMMENT':
4144
break;
4245

46+
case 'BOOLEAN':
47+
completionItems.push(createCompletionItem('Yes', CompletionItemKind.Field, tokenType, `Rule: ${label}`))
48+
completionItems.push(createCompletionItem('No', CompletionItemKind.Field, tokenType, `Rule: ${label}`))
49+
break;
50+
51+
case 'PERCENT':
52+
completionItems.push({
53+
label,
54+
kind: CompletionItemKind.Snippet,
55+
insertTextFormat: InsertTextFormat.Snippet,
56+
detail: 'Insert Percentage',
57+
insertText: '${0:100}%',
58+
documentation: `Snippet: ${label}`
59+
})
60+
break
61+
62+
case 'WEAPONSLOT':
63+
completionItems.push(createCompletionItem('PRIMARY', CompletionItemKind.Field, tokenType, `Rule: ${label}`))
64+
completionItems.push(createCompletionItem('SECONDARY', CompletionItemKind.Field, tokenType, `Rule: ${label}`))
65+
completionItems.push(createCompletionItem('TERTIARY', CompletionItemKind.Field, tokenType, `Rule: ${label}`))
66+
break;
67+
68+
69+
case 'VETERENCY':
70+
completionItems.push(createCompletionItem('VETERAN', CompletionItemKind.Field, tokenType, `Rule: ${label}`))
71+
completionItems.push(createCompletionItem('ELITE', CompletionItemKind.Field, tokenType, `Rule: ${label}`))
72+
completionItems.push(createCompletionItem('HEROIC', CompletionItemKind.Field, tokenType, `Rule: ${label}`))
73+
break;
74+
75+
case 'RGB':
76+
completionItems.push({
77+
label,
78+
kind: CompletionItemKind.Snippet,
79+
insertTextFormat: InsertTextFormat.Snippet,
80+
detail: 'Insert RGB',
81+
insertText: 'R:${1:0} G:${2:0} B:${0:0}',
82+
documentation: `Snippet: ${label}`
83+
})
84+
break;
85+
86+
case 'RGBA':
87+
completionItems.push({
88+
label,
89+
kind: CompletionItemKind.Snippet,
90+
insertTextFormat: InsertTextFormat.Snippet,
91+
detail: 'Insert RGBA',
92+
insertText: 'R:${1:0} G:${2:0} B:${3:0} A:${0:0}',
93+
documentation: `Snippet: ${label}`
94+
})
95+
break;
96+
4397
case 'Coords':
4498
completionItems.push({
4599
label,
@@ -51,103 +105,189 @@ export function generateCompletionItems(candidates: CandidatesCollection, parser
51105
})
52106
break;
53107

54-
default:
108+
case 'XCOORD':
109+
completionItems.push({
110+
label,
111+
kind: CompletionItemKind.Snippet,
112+
insertTextFormat: InsertTextFormat.Snippet,
113+
detail: 'Insert X coordinate',
114+
insertText: 'X:${0:0}',
115+
documentation: `Snippet: ${label}`
116+
})
117+
break;
118+
119+
case 'YCOORD':
120+
completionItems.push({
121+
label,
122+
kind: CompletionItemKind.Snippet,
123+
insertTextFormat: InsertTextFormat.Snippet,
124+
detail: 'Insert Y coordinate',
125+
insertText: 'Y:${0:0}',
126+
documentation: `Snippet: ${label}`
127+
})
128+
break;
129+
130+
case 'ZCOORD':
131+
completionItems.push({
132+
label,
133+
kind: CompletionItemKind.Snippet,
134+
insertTextFormat: InsertTextFormat.Snippet,
135+
detail: 'Insert Z coordinate',
136+
insertText: 'Z:${0:0}',
137+
documentation: `Snippet: ${label}`
138+
})
139+
break;
140+
141+
case 'Location':
55142
completionItems.push({
56143
label,
57-
kind: CompletionItemKind.Field,
58-
data: tokenType,
59-
documentation: `Keyword: ${label}`,
60-
});
144+
kind: CompletionItemKind.Snippet,
145+
insertTextFormat: InsertTextFormat.Snippet,
146+
detail: 'Insert X: & Y: coordinate',
147+
insertText: 'Location = X:${1:0} Y:${0:0}',
148+
documentation: `Snippet: ${label}`
149+
})
150+
break;
151+
152+
default:
61153
break;
62154
}
63155
}
64156

65157
// Process rule candidates (snippets, templates)
66-
for (const [ruleIndex, candidate] of candidates.rules) {
67-
const ruleName = parser.ruleNames[ruleIndex];
158+
// for (const [ruleIndex, candidate] of candidates.rules) {
159+
// const ruleName = parser.ruleNames[ruleIndex];
68160

69-
completionItems.push({
70-
label: ruleName,
71-
kind: CompletionItemKind.Snippet,
72-
data: ruleIndex,
73-
documentation: `Rule: ${ruleName}`,
74-
});
75-
}
161+
// completionItems.push({
162+
// label: ruleName,
163+
// kind: CompletionItemKind.Snippet,
164+
// data: ruleIndex,
165+
// documentation: `Rule: ${ruleName}`,
166+
// });
167+
// }
76168

77169
return completionItems;
78170
}
79171

172+
function createCompletionItem(label: string, kind: CompletionItemKind, data: any, documentation: string): CompletionItem {
173+
return {
174+
label: label,
175+
kind: kind,
176+
data: data,
177+
documentation: documentation
178+
}
179+
}
180+
80181
export function findContextAtPosition(tree: ParserRuleContext, position: number): ParserRuleContext | null {
81182
if (!tree || tree.start === null || tree.stop === null) {
82-
return null;
183+
return null;
83184
}
84185

85-
console.log(`Start: ${tree.start.start}, End: ${tree.stop.stop}, Position: ${position}`)
86-
186+
// console.log(`Start: ${tree.start.start}, End: ${tree.stop.stop}, Position: ${position}`)
187+
87188
const start = tree.start.start;
88189
const stop = tree.stop.stop + 1;
89-
190+
90191
if (position < start || position > stop) {
91-
console.log('out of range')
92-
return null;
192+
// console.log('out of range')
193+
return null;
93194
}
94-
195+
95196
// If the node covers the position, check its children
96197
for (let i = 0; i < tree.getChildCount(); i++) {
97-
const child = tree.getChild(i);
98-
99-
if (child instanceof ParserRuleContext) {
100-
const result = findContextAtPosition(child, position);
101-
if (result !== null) {
102-
return result;
198+
const child = tree.getChild(i);
199+
200+
if (child instanceof ParserRuleContext) {
201+
const result = findContextAtPosition(child, position);
202+
if (result !== null) {
203+
return result;
204+
}
103205
}
104-
}
105206
}
106-
207+
107208
// If no children cover the position, return this node
108209
return tree;
109-
}
210+
}
110211

111-
export function getContextSpecificCompletions(ruleName: string): CompletionItem[] {
212+
export async function getContextSpecificCompletions(ruleName: string): Promise<CompletionItem[]> {
112213
const completionItems: CompletionItem[] = [];
113214

114215
console.log(`Rules: ${ruleName}`)
115216

116217
//TODO: Add retrievels here
117218
switch (ruleName) {
118-
case 'cb_command_property':
119-
completionItems.push(...getCompletionItemsFromStringArray(list.CommandButtonCommandValues))
219+
case 'audioevent_value':
220+
completionItems.push(...getCompletionItemsFromRBTree(list.audioEvent))
221+
completionItems.push(...getCompletionItemsFromRBTree(list.customAudioEvent))
222+
break;
223+
224+
case 'commandbutton_value':
225+
completionItems.push(...getCompletionItemsFromRBTree(list.commandButtons))
226+
completionItems.push(...getCompletionItemsFromRBTree(list.customCommandButtons))
227+
break;
228+
229+
case 'dialogevent_value':
230+
completionItems.push(...getCompletionItemsFromRBTree(list.dialogEvent))
231+
completionItems.push(...getCompletionItemsFromRBTree(list.customDialogEvent))
120232
break;
121233

122-
case 'cb_options_property':
123-
completionItems.push(...getCompletionItemsFromStringArray(list.CommandButtonOptionValues))
234+
case 'fxlist_value':
235+
completionItems.push(...getCompletionItemsFromRBTree(list.fxLists))
236+
completionItems.push(...getCompletionItemsFromRBTree(list.customFXLists))
124237
break;
125238

126-
case 'cb_buttonbordertype_property':
127-
completionItems.push(...getCompletionItemsFromStringArray(list.CommandButtonBorderTypeValues))
239+
case 'mappedimage_value':
240+
completionItems.push(...getCompletionItemsFromRBTree(list.mappedImages))
241+
completionItems.push(...getCompletionItemsFromRBTree(list.customMappedImages))
128242
break;
129243

130-
case 'object_property':
244+
case 'object_value':
131245
completionItems.push(...getCompletionItemsFromRBTree(list.objects))
132-
completionItems.push(...getCompletionItemsFromRBTree(list.customObjects))
246+
completionItems.push(...getCompletionItemsFromRBTree(list.customObjects))
133247
break;
134248

135-
case 'science_property':
249+
case 'science_value':
136250
completionItems.push(...getCompletionItemsFromRBTree(list.science))
137251
completionItems.push(...getCompletionItemsFromRBTree(list.customScience))
138252
break;
139253

140-
case 'specialpower_property':
254+
case 'specialpower_value':
141255
completionItems.push(...getCompletionItemsFromRBTree(list.specialPower))
142256
completionItems.push(...getCompletionItemsFromRBTree(list.customSpecialPower))
143257
break;
144258

145-
case 'upgrade_property':
146-
// Add completion items relevant to function declarations
259+
case 'rand_value':
260+
completionItems.push({
261+
label: 'Random Value Distribution',
262+
kind: CompletionItemKind.Snippet,
263+
insertTextFormat: InsertTextFormat.Snippet,
264+
detail: 'Insert rand_value',
265+
insertText: '${1:0} ${2:0} ${3|CONSTANT,UNIFORM,GAUSSIAN,TRIANGULAR,LOW_BIAS,HIGH_BIAS|}',
266+
documentation: `Snippet: Random Value Distribution}`
267+
})
268+
break;
269+
270+
case 'coord3D':
271+
completionItems.push({
272+
label: '3D Coordinates',
273+
kind: CompletionItemKind.Snippet,
274+
insertTextFormat: InsertTextFormat.Snippet,
275+
detail: 'Insert X: Y: & Z:',
276+
insertText: 'X:${1:0} Y:${2:0} Z:${0:0}',
277+
documentation: `Snippet: 3D Coordinates`
278+
})
279+
break;
280+
281+
case 'particlesystem_value':
282+
completionItems.push(...getCompletionItemsFromRBTree(list.particleSystem))
283+
completionItems.push(...getCompletionItemsFromRBTree(list.customParticleSystem))
284+
break;
147285

286+
case 'upgrade_value':
148287
completionItems.push(...getCompletionItemsFromRBTree(list.upgrades));
149288
completionItems.push(...getCompletionItemsFromRBTree(list.customUpgrades));
150289
break;
290+
151291
// Add more cases for different contexts
152292
default:
153293
break;
@@ -167,7 +307,7 @@ function getCompletionItemsFromRBTree(tree: RBTree<string>): CompletionItem[] {
167307
tree.each((value: string) => {
168308
completionItems.push({
169309
label: value,
170-
kind: CompletionItemKind.Text,
310+
kind: CompletionItemKind.Field,
171311
data: value,
172312
documentation: `Value: ${value}`,
173313
});
@@ -178,15 +318,20 @@ function getCompletionItemsFromRBTree(tree: RBTree<string>): CompletionItem[] {
178318

179319
function getCompletionItemsFromStringArray(stringArray: string[]): CompletionItem[] {
180320
const completionItems: CompletionItem[] = [];
181-
321+
182322
stringArray.forEach(string => {
183323
completionItems.push({
184324
label: string,
185-
kind: CompletionItemKind.Text,
325+
kind: CompletionItemKind.Field,
186326
data: string,
187327
documentation: `Value: ${string}`,
188328
});
189329
});
190-
330+
191331
return completionItems;
332+
}
333+
334+
export function withTimeout<T>(promise: Promise<T>, ms: number, fallback: T): Promise<T> {
335+
const timeout = new Promise<T>(resolve => setTimeout(() => resolve(fallback), ms));
336+
return Promise.race([promise, timeout]);
192337
}

server/src/diagnostic/classVisitor.ts

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
import { ParseTreeVisitor } from "antlr4ng/dist/tree/ParseTreeVisitor"
22
import { AbstractParseTreeVisitor } from "antlr4ng/dist/tree/AbstractParseTreeVisitor"
3-
import { Animation2DClassContext, ArmorClassContext, ClassesContext, CommandButtonClassContext, MappedImageClassContext, ProgramContext } from "../utils/antlr4ng/MapIniParser";
3+
import { Animation2DClassContext, ArmorClassContext, ClassesContext, CommandButtonClassContext, MappedImageClassContext, ParticleSystemClassContext, ProgramContext } from "../utils/antlr4ng/MapIniParser";
44
import * as list from '../utils/lists'
55

66
export class DiagnosticVisitor extends AbstractParseTreeVisitor<void> implements ParseTreeVisitor<void> {
@@ -24,6 +24,8 @@ export class DiagnosticVisitor extends AbstractParseTreeVisitor<void> implements
2424
} else if (child instanceof CommandButtonClassContext) {
2525
list.customCommandButtons.remove(child.ID().getText().toUpperCase())
2626
list.customCommandButtons.insert(child.ID().getText().toUpperCase())
27+
} else if (child instanceof ParticleSystemClassContext) {
28+
console.log(`"${child.ID().getText()}",`)
2729
}
2830
}
2931

0 commit comments

Comments
 (0)