diff --git a/autocomplete.d b/autocomplete.d index 98625fa..3550854 100644 --- a/autocomplete.d +++ b/autocomplete.d @@ -109,7 +109,7 @@ body case TokenType.RBracket: if (i == 0) break loop; - skipBrackets(tokens, i); + skipBrackets()(tokens, i); break; default: if (i == 0) @@ -156,7 +156,6 @@ struct AutoComplete if (expression.length == 0) return "void"; auto type = typeOfVariable(expression[0], cursor); - stderr.writeln("type of ", expression[0].value , " is ", type); if (type is null) return "void"; size_t index = 1; @@ -240,13 +239,9 @@ struct AutoComplete // Find all struct or class bodies that we're in. // Check for the symbol in those class/struct/interface bodies // if match is found, return it - if (symbol == "this") - stderr.writeln("this"); auto structs = context.getStructsContaining(cursor); - stderr.writeln(structs.length, " structs contain cursor position ", cursor); if (symbol == "this" && structs.length > 0) { - stderr.writeln("this"); return minCount!("a.bodyStart > b.bodyStart")(structs)[0].name; } @@ -286,10 +281,11 @@ struct AutoComplete case TokenType.Switch: return ""; default: -// size_t startIndex = findBeginningOfExpression(tokens, index); -// auto expressionType = getTypeOfExpression(tokens[startIndex .. index], -// tokens, index); - return ""; + size_t startIndex = findBeginningOfExpression(tokens, index); + auto callChain = splitCallChain(tokens[startIndex .. index + 1]); + auto expressionType = getTypeOfExpression( + callChain[0 .. $ - 1], tokens, cursor); + return to!string(context.getCallTipsFor(expressionType, callChain[$ - 1].value).join("\n").array()); } } @@ -298,7 +294,6 @@ struct AutoComplete auto index = assumeSorted(tokens).lowerBound(cursor).length - 1; Token t = tokens[index]; size_t startIndex = findBeginningOfExpression(tokens, index); - stderr.writeln("call chain: ", splitCallChain(tokens[startIndex .. index])); auto expressionType = getTypeOfExpression( splitCallChain(tokens[startIndex .. index]), tokens, cursor); diff --git a/parser.d b/parser.d index c3b52ba..4252fa8 100644 --- a/parser.d +++ b/parser.d @@ -593,11 +593,18 @@ body if (tokens[index] == TokenType.If) f.constraint = parseConstraint(tokens, index); + while (index < tokens.length && (tokens[index] == TokenType.In || tokens[index] == TokenType.Out || tokens[index] == TokenType.Body)) { ++index; + if (index < tokens.length && tokens[index] == TokenType.LParen + && tokens[index - 1] == TokenType.Out) + { + tokens.skipParens(index); + } + if (index < tokens.length && tokens[index] == TokenType.LBrace) tokens.skipBlockStatement(index); } diff --git a/types.d b/types.d index 94497cf..1c55b0e 100644 --- a/types.d +++ b/types.d @@ -173,6 +173,21 @@ public: return null; } + string[] getFunctionDocs(string functionName) + { + auto app = appender!(string[])(); + foreach (fun; functions) + { + if (fun.name != functionName) + continue; + app.put(fun.documentString()); + } + return app.data; + // TODO: Try this again with a newer DMD + //return array(map!(a => a.documentString())( + // filter!(a => a.name == functionName)(functions))); + } + string[] getCtags(string fileName) { auto app = appender!(string[])(); @@ -230,6 +245,19 @@ public: /// Parameter list; may be empty Variable[] parameters; + string documentString() + { + string r = returnType ~ " " ~ name ~ "("; + foreach (i, param; parameters) + { + r ~= param.type ~ " " ~ param.name; + if (i + 1 < parameters.length) + r ~= ",\\n\\t"; + } + r ~= ") " ~ format("%d", line); + return r; + } + protected: override void printMembers(File f, uint indent) const { @@ -631,13 +659,30 @@ public: { if (s.bodyStart <= cursorPosition && s.bodyEnd >= cursorPosition) app.put(s); - else - stderr.writeln(s.name, " does not contain ", cursorPosition, - "(", s.bodyStart, ", ", s.bodyEnd, ")"); } return app.data(); } + + + string[] getCallTipsFor(string container, string functionName) + { + stderr.writeln("getCallTipsFor ", container, " ", functionName); + if (container == null || container.length == 0 || container == "void") + return getCallTipsFor(functionName); + + foreach (m; chain(modules, [currentModule])) + { + foreach (s; chain(m.structs, m.interfaces, m.classes, m.unions)) + { + if (s.name != container) + continue; + return s.getFunctionDocs(functionName); + } + } + return []; + } + void addModule(Module mod) { modules ~= mod; @@ -645,4 +690,21 @@ public: Module currentModule; Module[] modules; + +private: + + string[] getCallTipsFor(string functionName) + { + stderr.writeln("Getting call tips for ", functionName); + auto app = appender!(string[])(); + foreach (m; chain(modules, [currentModule])) + { + foreach (fun; m.functions) + { + if (fun.name == functionName) + app.put(fun.documentString()); + } + } + return app.data; + } }