mirror of
https://github.com/godotengine/godot-vscode-plugin.git
synced 2025-12-31 13:48:24 +03:00
Implement document symbol parser
This commit is contained in:
71
src/gdscript/symbolprovider.ts
Normal file
71
src/gdscript/symbolprovider.ts
Normal file
@@ -0,0 +1,71 @@
|
||||
import {
|
||||
DocumentSymbolProvider,
|
||||
TextDocument,
|
||||
SymbolInformation,
|
||||
CancellationToken,
|
||||
SymbolKind,
|
||||
Range
|
||||
} from 'vscode';
|
||||
|
||||
class GDScriptSymbolProvider implements DocumentSymbolProvider {
|
||||
constructor() {}
|
||||
|
||||
provideDocumentSymbols(document: TextDocument, token: CancellationToken): SymbolInformation[] | Thenable<SymbolInformation[]> {
|
||||
|
||||
const symbols: SymbolInformation[] = [];
|
||||
const text =document.getText();
|
||||
const lines = text.split(/\r?\n/);
|
||||
|
||||
const getMatches = (string, regex, index=1) => {
|
||||
var matches = [];
|
||||
var match;
|
||||
while (match = regex.exec(string)) {
|
||||
matches.push(match[index]);
|
||||
}
|
||||
return matches;
|
||||
};
|
||||
|
||||
const findLineRanges = (symbols, reg)=>{
|
||||
const sm = {};
|
||||
symbols.map((name:string)=>{
|
||||
let line = 0;
|
||||
let curline = 0;
|
||||
lines.map(l=>{
|
||||
const nreg = reg.replace("$X$", name);
|
||||
if(l.match(nreg) != null) {
|
||||
line = curline;
|
||||
return;
|
||||
}
|
||||
curline += 1;
|
||||
});
|
||||
sm[name] = line;
|
||||
});
|
||||
return sm;
|
||||
}
|
||||
|
||||
let funcsnames = getMatches(text, /func\s+([_A-Za-z]+[_A-Za-z0-9]*)\s*\(.*\)/gi, 1);
|
||||
const funcs = findLineRanges(funcsnames, "func\\s+$X$\\s*\\(.*\\)");
|
||||
for (let key of Object.keys(funcs))
|
||||
symbols.push(new SymbolInformation(key, SymbolKind.Function, new Range(funcs[key], 0, funcs[key],lines[funcs[key]].length)));
|
||||
|
||||
let signalnames = getMatches(text, /signal\s+([_A-Za-z]+[_A-Za-z0-9]*)\s*\(.*\)/gi, 1);
|
||||
const signals = findLineRanges(signalnames, "signal\\s+$X$\\s*\\(.*\\)");
|
||||
for (let key of Object.keys(signals))
|
||||
symbols.push(new SymbolInformation(key, SymbolKind.Interface, new Range(signals[key], 0, signals[key],lines[signals[key]].length)));
|
||||
|
||||
let varnames = getMatches(text, /var\s+([_A-Za-z]+[_A-Za-z0-9]*)\s*/gi, 1);
|
||||
const vars = findLineRanges(varnames, "var\\s+$X$\\s*");
|
||||
for (let key of Object.keys(vars))
|
||||
symbols.push(new SymbolInformation(key, SymbolKind.Variable, new Range(vars[key], 0, vars[key],lines[vars[key]].length)));
|
||||
|
||||
let constnames = getMatches(text, /const\s+([_A-Za-z]+[_A-Za-z0-9]*)\s*/gi, 1);
|
||||
const consts = findLineRanges(constnames, "const\\s+$X$\\s*");
|
||||
for (let key of Object.keys(consts))
|
||||
symbols.push(new SymbolInformation(key, SymbolKind.Constant, new Range(consts[key], 0, consts[key],lines[consts[key]].length)));
|
||||
|
||||
return symbols;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
export default GDScriptSymbolProvider;
|
||||
@@ -1,16 +1,20 @@
|
||||
import * as vscode from 'vscode';
|
||||
import DocDataManager from './docdata';
|
||||
import godotRequest from './request';
|
||||
import GDScriptSymbolProvider from './gdscript/symbolprovider';
|
||||
|
||||
class ToolManager {
|
||||
|
||||
private workspaceDir: string = "";
|
||||
private docs: DocDataManager = null;
|
||||
|
||||
private symbolprovider: GDScriptSymbolProvider = null;
|
||||
|
||||
constructor(context: vscode.ExtensionContext) {
|
||||
this.workspaceDir = vscode.workspace.rootPath;
|
||||
this.validate();
|
||||
this.docs = new DocDataManager(context.extensionPath);
|
||||
this.symbolprovider = new GDScriptSymbolProvider();
|
||||
vscode.languages.registerDocumentSymbolProvider('gdscript', this.symbolprovider);
|
||||
}
|
||||
|
||||
validate() {
|
||||
|
||||
Reference in New Issue
Block a user