浏览代码

Implement document symbol parser

Geequlim 8 年之前
父节点
当前提交
71bf862172
共有 2 个文件被更改,包括 76 次插入1 次删除
  1. 71 0
      src/gdscript/symbolprovider.ts
  2. 5 1
      src/tool_manager.ts

+ 71 - 0
src/gdscript/symbolprovider.ts

@@ -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;

+ 5 - 1
src/tool_manager.ts

@@ -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() {