Visual studio code VSCode语言扩展,具有分层大纲、DocumentSymbol

Visual studio code VSCode语言扩展,具有分层大纲、DocumentSymbol,visual-studio-code,vscode-extensions,Visual Studio Code,Vscode Extensions,我正在尝试使用VScode中的自定义语言来获取大纲。我有下面的代码,但我觉得它是缓慢的,因为我在课堂上找到一个范围的方式。是否有更好的方法找到范围并分配子项。我考虑过只跟踪括号的深度,并将更高深度的所有函数/方法/类分配到上一个深度的最后一项中 它是根据一本书改编的 类JSLDocumentSymbolProvider实现vscode.DocumentSymbolProvider{ 公共提供的文档符号(文档:vscode.TextDocument, 令牌:vscode.CancellationT

我正在尝试使用VScode中的自定义语言来获取大纲。我有下面的代码,但我觉得它是缓慢的,因为我在课堂上找到一个范围的方式。是否有更好的方法找到范围并分配子项。我考虑过只跟踪括号的深度,并将更高深度的所有函数/方法/类分配到上一个深度的最后一项中

它是根据一本书改编的

类JSLDocumentSymbolProvider实现vscode.DocumentSymbolProvider{ 公共提供的文档符号(文档:vscode.TextDocument, 令牌:vscode.CancellationToken):表{ 返回新承诺((解决、拒绝)=>{ 变量符号:vscode.DocumentSymbol[]=[]; var深度=0; 对于(var i=0;i0;i_线++){ 让class_line=document.lineAt(i_line); 设mtxt=class_line.text; 让ic; 如果(i==i_线)ic=16; 否则ic=0; 对于(i_char=ic;i_char
}

也许这是一个代码审查的问题,因为您声称代码有效且“速度很慢”?看起来您有很多嵌套循环;随着输入大小的增加,这些循环可能会导致严重的性能问题。请纠正我的错误,最坏情况下的时间复杂度是否为O(n^3)?@Peter,如果放在更好的地方,我可以移动它。我不知道有代码检查堆栈交换。不,一个函数可以创建一个类,该类可以包含包含函数的方法。这肯定不是最佳做法,但我以前见过。“不,一个函数可以创建一个类,该类可以包含包含函数的方法。这肯定不是最佳实践,但我以前见过。“我不知道你在说什么;我只是根据嵌套循环猜测你的代码的时间复杂度。也许这是一个需要代码审查的问题,因为你声称代码可以工作并且“速度很慢”?看起来您有很多嵌套循环;随着输入大小的增长,这些循环可能会导致严重的性能问题。如果我错了,请纠正我,最糟糕的时间复杂度是
O(n^3)
?@Peter,如果放在更好的地方,我可以移动它。我不知道有代码检查堆栈交换。不,一个函数可以创建一个类,该类可以包含包含函数的方法。这肯定不是最佳做法,但我以前见过。“不,一个函数可以创建一个类,该类可以包含包含函数的方法。这肯定不是最佳实践,但我以前见过。”我不知道你在说什么;我只是根据嵌套循环猜测代码的时间复杂性。
class JSLDocumentSymbolProvider implements vscode.DocumentSymbolProvider {
public provideDocumentSymbols(document: vscode.TextDocument,
        token: vscode.CancellationToken): Thenable<vscode.DocumentSymbol[]> {
    return new Promise((resolve, reject) => {
        var symbols: vscode.DocumentSymbol[] = [];
        var depth = 0;
        for (var i = 0; i < document.lineCount; i++) {
            var line = document.lineAt(i);
            var txt = line.text;
            var ltxt = txt.toLowerCase();
            let open_brackets = ltxt.match(/\(/g) || [];
            let close_brackets = ltxt.match(/\)/g) || [];
            // console.log(ltxt)
            // console.log(open_brackets, close_brackets)
            //console.log(i, open_brackets.length, close_brackets.length)

            depth += open_brackets.length - close_brackets.length;
            //console.log(depth);

            if (ltxt.includes("define class(")) {
                let sname = txt.trim().substr(14, txt.trim().length - 16); //this is hard coded right now but it's kind of working
                let detail = "ARGS:x, y returns z";
                let start_pos = new vscode.Position(i, 0); 
                let n_bracket = 1;
                let i_char = 0;
                //let children: vscode.DocumentSymbol[] = []
                let ds = new vscode.DocumentSymbol(sname, detail, vscode.SymbolKind.Class, line.range, line.range);

                for(var i_line = i; n_bracket > 0; i_line++){
                    let class_line = document.lineAt(i_line);
                    let mtxt = class_line.text;
                    let ic;
                    if(i == i_line) ic = 16;
                    else ic = 0;
                    for(i_char = ic; i_char < mtxt.length; i_char++){
                        if(mtxt[i_char] === "(") n_bracket++;
                        else if(mtxt[i_char] === ")") n_bracket--;
                        if(n_bracket === 0) break
                    }
                    if (/(\w[\w\d\s]*)=\s*method\({((?:\s*(?:\w[\w\d\s]*)(?:=[^,]*)?,?\s*)*)},/i.test(mtxt)) { 
                        let result = mtxt.match(/(\w[\w\d\s]*)=\s*method\({((?:\s*(?:\w[\w\d\s]*)(?:=[^,]*)?,?\s*)*)},/i)!;
                        let mname = result[1].trim();
                        let m_details = ""
                        if(result.length == 3){
                            m_details = result[2].trim();
                        }
                        ds.children.push(new vscode.DocumentSymbol(mname, m_details, vscode.SymbolKind.Method, class_line.range, class_line.range));
                    }
                    if(n_bracket === 0) break
                }
                let end_pos = new vscode.Position(i_line, i_char);
                let rng = new vscode.Range(start_pos, end_pos);
                ds.range = rng;
                //ds.children = children;
                symbols.push(ds);
            }
            else if (/(\w[\w\d\s]*)=\s*function\({((?:\s*(?:\w[\w\d\s]*)(?:=[^,]*)?,?\s*)*)},/.test(ltxt)) { 
                let result = txt.match(/(\w[\w\d\s]*)=\s*function\({((?:\s*(?:\w[\w\d\s]*)(?:=[^,]*)?,?\s*)*)},/i)!;
                let sname = result[1].trim();
                let detail = "";
                if(result.length == 3){
                    detail = "(" + result[2].trim() + ")";
                }
                symbols.push(new vscode.DocumentSymbol(sname, detail, vscode.SymbolKind.Function, line.range, line.range));
            }
        } 

        resolve(symbols);
    });
}