Skip to content

Commit b49ee64

Browse files
committed
more linting fixes
1 parent e27bd9b commit b49ee64

File tree

4 files changed

+58
-76
lines changed

4 files changed

+58
-76
lines changed

CHANGELOG.md

+4
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,9 @@
11
# Geode for VS Code Changelog
22

3+
## [1.19.3]
4+
- More fixes to missing resources linting
5+
- Multiple lints can now be suppressed at once via `@geode-ignore(x, y, z)` (not yet supported for ignore ranges)
6+
37
## [1.19.2]
48
- Fix lint for missing resources having poor performance & not updating on resource change
59
- Add option to disable lints alltogether

package.json

+1-1
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
"name": "geode",
33
"displayName": "Geode",
44
"description": "Utilities for the Geode Geometry Dash modding framework",
5-
"version": "1.19.2",
5+
"version": "1.19.3",
66
"engines": {
77
"vscode": "^1.72.0"
88
},

src/browser/database.ts

+5
Original file line numberDiff line numberDiff line change
@@ -250,6 +250,11 @@ export class Database {
250250
);
251251
}
252252

253+
refreshModSprites(mod: Project) {
254+
// Delete existing database for this mod
255+
this.collections = this.collections.filter(c => c.id !== sourceID(mod));
256+
this.addSpritesFromMod(mod);
257+
}
253258
refresh() {
254259
// reset database
255260
this.collections = [];

src/project/lint.ts

+48-75
Original file line numberDiff line numberDiff line change
@@ -131,10 +131,13 @@ function lint(
131131

132132
// Look for matches for the regex
133133
for (const match of document.data.matchAll(new RegExp(
134-
`(?<ignore>\\/\\/\\s*@geode-ignore\\(${code}\\).*?$\\r?\\n^.*?|\\/\\/.*?)?${regex.source}`,
134+
`${/((\/\/\s*@geode-ignore\((?<ignoreTags>[^\)]*)\).*?$\r?\n^.*?)|(\/\/.*?))?/.source}${regex.source}`,
135135
regex.flags.includes("m") ? regex.flags : regex.flags + "m"
136136
))) {
137-
if (match.index === undefined || match.groups?.ignore || ignoreRanges.some(range => range.from <= match.index! && range.to >= match.index!)) {
137+
if (
138+
match.index === undefined || match.groups?.ignoreTags?.includes(code) ||
139+
ignoreRanges.some(range => range.from <= match.index! && range.to >= match.index!)
140+
) {
138141
continue;
139142
}
140143

@@ -227,8 +230,8 @@ function lintSettings(document: MaybeDocument, diagnostics: Diagnostic[]) {
227230
// }
228231

229232
function lintUnknownResource(document: MaybeDocument, diagnostics: Diagnostic[], initialRun: boolean) {
230-
const modJson = getProjectFromDocument(document.uri)?.modJson;
231-
if (!modJson) {
233+
const mod = getProjectFromDocument(document.uri);
234+
if (!mod) {
232235
return;
233236
}
234237

@@ -238,94 +241,60 @@ function lintUnknownResource(document: MaybeDocument, diagnostics: Diagnostic[],
238241

239242
// Reload DB on filesave (in case new resources have been added to fix the issues)
240243
if (!initialRun) {
241-
db.refresh();
244+
db.refreshModSprites(mod);
242245
}
243246

244-
if (modJson?.dependencies) {
247+
if (mod.modJson.dependencies) {
245248
// TODO: Deprecate
246-
if (modJson.dependencies instanceof Array) {
247-
dependencies.push(...modJson.dependencies.map((d) => d.id));
249+
if (mod.modJson.dependencies instanceof Array) {
250+
dependencies.push(...mod.modJson.dependencies.map((d) => d.id));
248251
} else {
249-
dependencies.push(...Object.keys(modJson.dependencies));
252+
dependencies.push(...Object.keys(mod.modJson.dependencies));
250253
}
251254
}
252255

253256
lint(
254257
document, diagnostics,
255258
"unknown-resource",
256-
/(?<method>expandSpriteName|[Ss]prite|[Ll]abel)(?<args>.*("[^"]+\.[^"]+"(_spr)?))+/gs,
257-
({ groups: { method, args }, offset }) => {
258-
// Don't lint `expandSpriteName` because if someone is using it they
259-
// should know what they are doing
260-
if (method === "expandSpriteName") {
259+
// Match resource-name-looking strings ("x.png", "thing.fnt" etc.)
260+
// todo: this method doesn't actually match mistakes like "thing" where you forget the file extension
261+
/"(?<modID>[a-z0-9\-_\.]+\/)?(?<name>\.?([\w\-\s]+\.)+(png|fnt|ogg|mp3))"(?<suffix>_spr)?/g,
262+
({ groups: { modID, name, suffix }, range }) => {
263+
// Resource might have the same name as a GD resource, so first
264+
// try to find it in the mod's resources
265+
const item = db.getCollectionById(`mod:${mod.modJson.id}`)?.findByName(name)
266+
?? db.findItemByName(name);
267+
268+
// Avoid matching resources from dependencies
269+
if (modID && dependencies.includes(modID)) {
261270
return undefined;
262271
}
263272

264-
const results = [];
265-
266-
// Extract any arguments that look like "sprite.png"
267-
for (const arg of args.matchAll(/"(?<name>[^"]+\.[^"]+)"(?<suffix>_spr)?/g)) {
268-
const { name, suffix } = arg.groups!;
269-
// `offset` is the offset of the lint regex, `method.length` is
270-
// because we are matching only the `args` match
271-
const nameRange = rangeFromRegex(document, arg, offset + method.length);
272-
273-
// Resource might have the same name as a GD resource, so first
274-
// try to find it in the mod's resources
275-
const item = db.getCollectionById(`mod:${modJson.id}`)?.findByName(name)
276-
?? db.findItemByName(name);
277-
278-
{
279-
// Avoid matching stuff that doesnt look like a resource
280-
const parts = name.split(".");
281-
if (parts.length < 2) {
282-
continue;
283-
}
284-
const ext = parts[parts.length - 1].toLowerCase();
285-
if (!knownResourceExts.includes(ext)) {
286-
continue;
287-
}
288-
289-
let shouldBreak = false;
290-
291-
// Avoid matching resources from dependencies
292-
for (const dep of dependencies) {
293-
if (name.startsWith(`${dep}/`)) {
294-
shouldBreak = true;
295-
break;
296-
}
297-
}
298-
299-
if (shouldBreak) {
300-
continue;
301-
}
302-
}
303-
304-
if (!item) {
305-
results.push({
273+
if (!item) {
274+
return [{
275+
level: DiagnosticSeverity.Warning,
276+
msg: `Resource "${name}" doesn't exist`,
277+
range,
278+
}];
279+
}
280+
else {
281+
if (!suffix && typeIsProject(item.src)) {
282+
return [{
306283
level: DiagnosticSeverity.Warning,
307-
msg: `Resource "${name}" doesn't exist`,
308-
range: nameRange,
309-
});
284+
msg: `Resource is missing _spr, perhaps you meant "${name}"_spr?`,
285+
range,
286+
}];
310287
}
311-
else {
312-
if (!suffix && typeIsProject(item.src)) {
313-
results.push({
314-
level: DiagnosticSeverity.Warning,
315-
msg: `Resource is missing _spr, perhaps you meant "${name}"_spr?`,
316-
range: nameRange,
317-
});
318-
}
319-
else if (suffix && !typeIsProject(item.src)) {
320-
results.push({
321-
level: DiagnosticSeverity.Warning,
322-
msg: `Resource "${name}" was not found in mod.json`,
323-
range: nameRange,
324-
});
325-
}
288+
else if (suffix && !typeIsProject(item.src)) {
289+
return [{
290+
level: DiagnosticSeverity.Warning,
291+
msg: `Resource "${name}" was not found in mod.json`,
292+
range,
293+
}];
326294
}
327295
}
328-
return results;
296+
297+
return undefined;
329298
}
330299
);
331300
}
@@ -381,6 +350,10 @@ export function registerLinters(context: ExtensionContext) {
381350
if (getExtConfig().get<boolean>("lints.enable")) {
382351
applyGeodeLints({ uri: ev.document.uri, data: ev.document.getText() }, geodeDiagnostics, false);
383352
}
353+
// If lints aren't enabled, reset diagnostics to remove existing ones
354+
else {
355+
geodeDiagnostics.set(ev.document.uri, []);
356+
}
384357
}));
385358

386359
// This is for adding Quick Fixes for those diagnostics

0 commit comments

Comments
 (0)