Skip to content

Commit

Permalink
feat: Now ensuring that go-to-definition works for all types mentione…
Browse files Browse the repository at this point in the history
…d in JSDocs
  • Loading branch information
adam-coster committed Aug 2, 2023
1 parent d1eec5c commit 7d1c4c3
Show file tree
Hide file tree
Showing 2 changed files with 62 additions and 45 deletions.
106 changes: 62 additions & 44 deletions packages/vscode/src/extension.definitions.mts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { Signifier } from '@bscotch/gml-parser';
import vscode from 'vscode';
import { swallowThrown } from './assert.mjs';
import type { StitchProvider } from './extension.provider.mjs';
import { locationOf } from './lib.mjs';

Expand All @@ -9,55 +9,73 @@ export class StitchDefinitionsProvider implements vscode.DefinitionProvider {
document: vscode.TextDocument,
position: vscode.Position,
): vscode.Location | undefined {
return swallowThrown(() => {
const ref = this.provider.getReference(document, position);
const item = ref?.item;
const assetName = item?.asset
? item.name
: item?.getTypeByKind('Id.Instance')?.name ||
item?.getTypeByKind('Asset.GMObject')?.name;
const offset = document.offsetAt(position);
const file = this.provider.getGmlFile(document);
const ref = file?.getReferenceAt(offset);
let item: Signifier | undefined;

if (item && !item.native && item.def?.file) {
return locationOf(item.def);
} else if (ref && item?.name === 'event_inherited') {
// Then this should take us to the parent event.
let parent = ref.file.asset.parent;
const eventName = ref.file.name;
let emergencyBreak = 0;
while (parent) {
// Get the file for the same event.
for (const file of parent.gmlFilesArray) {
if (file.name === eventName) {
return locationOf(file.startRange);
}
}
emergencyBreak++;
if (emergencyBreak > 10) {
break;
if (!file) return;

// If we don't have a reference, see if we're on a typename in
// a JSDoc comment.
if (!ref) {
// Make sure we're in a JSDoc comment.
if (!file.getJsdocAt(offset)) return;

const wordRange = document.getWordRangeAtPosition(position, /[\w.]+/);
if (!wordRange) return;
const typeName = document.getText(wordRange);
console.log('WORD RANGE', typeName);
item = file.project.types.get(typeName)?.signifier;
if (!item) return;
}

item ||= ref?.item;
const assetName = item?.asset
? item.name
: item?.getTypeByKind('Id.Instance')?.name ||
item?.getTypeByKind('Asset.GMObject')?.name;

if (item && !item.native && item.def?.file) {
return locationOf(item.def);
} else if (ref && item?.name === 'event_inherited') {
// Then this should take us to the parent event.
let parent = ref.file.asset.parent;
const eventName = ref.file.name;
let emergencyBreak = 0;
while (parent) {
// Get the file for the same event.
for (const file of parent.gmlFilesArray) {
if (file.name === eventName) {
return locationOf(file.startRange);
}
parent = parent.parent;
}
} else if (ref && item && assetName) {
// Then we can go to the asset's defining file.
const asset = ref.file.project.getAssetByName(assetName);
if (asset?.assetKind === 'objects') {
const files = asset.gmlFilesArray;
for (const file of files) {
if (file.isCreateEvent) {
return locationOf(file.startRange);
} else if (file.isStepEvent) {
return locationOf(file.startRange);
}
}
// Otherwise just whatever step we have,
// if any.
if (files.length > 0) {
return locationOf(files[0].startRange);
emergencyBreak++;
if (emergencyBreak > 20) {
break;
}
parent = parent.parent;
}
} else if (ref && item && assetName) {
// Then we can go to the asset's defining file.
const asset = ref.file.project.getAssetByName(assetName);
if (asset?.assetKind === 'objects') {
const files = asset.gmlFilesArray;
for (const file of files) {
if (file.isCreateEvent) {
return locationOf(file.startRange);
} else if (file.isStepEvent) {
return locationOf(file.startRange);
}
}
// Otherwise just whatever step we have,
// if any.
if (files.length > 0) {
return locationOf(files[0].startRange);
}
}
return;
});
}
return;
}

register() {
Expand Down
1 change: 0 additions & 1 deletion packages/vscode/src/inspector.mts
Original file line number Diff line number Diff line change
Expand Up @@ -189,7 +189,6 @@ export class GameMakerInspectorProvider
return [new ObjectItem(this.asset.parent, 'parents')];
} else if (element instanceof ObjectSpriteFolder) {
const sprite = this.asset.sprite;
logger.info('Found sprite?', !!sprite, sprite?.name);
if (sprite) {
return [new ObjectSpriteItem(sprite)];
}
Expand Down

0 comments on commit 7d1c4c3

Please sign in to comment.