1

I'm trying to get outline working with a custom language in VScode. I have the below code but I feel like it is slow because of the way I find a range in class. Are there better ways to find the range and assign children. I've thought about just keeping track of the depth of the brackets and assigning all functions/methods/classes in higher depths into the last item of previous depth.

It was based off of this answer.

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);
    });
}

}

Faller
  • 1,588
  • 3
  • 16
  • 27
  • Perhaps this is a question for Code Review since you claim the code works and "it is slow"? – Peter Aug 14 '19 at 17:17
  • Looks like you have alot of nested loops; these can potentially cause major performance issues as your input size grows. Correct me if I am wrong, would the worst-case time complexity be `O(n^3)`? – Peter Aug 14 '19 at 17:22
  • @Peter, I can move it if that's a better place to put it. Didn't realize there was a code review stack exchange. And no, a function can create a class which can have methods that have functions inside them. It's definitely not the best practice, but I've seen it before. – Faller Aug 14 '19 at 17:32
  • "And no, a function can create a class which can have methods that have functions inside them. It's definitely not the best practice, but I've seen it before." I have no idea what you are talking about; I was simply taking a guess at the time complexity of your code based on the nested loops. – Peter Aug 14 '19 at 17:38

0 Answers0