fixed contract parsing. Improved autocomplete. Initial support for call tips
This commit is contained in:
parent
dbf2be29b7
commit
f354b6ec4c
|
@ -109,7 +109,7 @@ body
|
||||||
case TokenType.RBracket:
|
case TokenType.RBracket:
|
||||||
if (i == 0)
|
if (i == 0)
|
||||||
break loop;
|
break loop;
|
||||||
skipBrackets(tokens, i);
|
skipBrackets()(tokens, i);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
if (i == 0)
|
if (i == 0)
|
||||||
|
@ -156,7 +156,6 @@ struct AutoComplete
|
||||||
if (expression.length == 0)
|
if (expression.length == 0)
|
||||||
return "void";
|
return "void";
|
||||||
auto type = typeOfVariable(expression[0], cursor);
|
auto type = typeOfVariable(expression[0], cursor);
|
||||||
stderr.writeln("type of ", expression[0].value , " is ", type);
|
|
||||||
if (type is null)
|
if (type is null)
|
||||||
return "void";
|
return "void";
|
||||||
size_t index = 1;
|
size_t index = 1;
|
||||||
|
@ -240,13 +239,9 @@ struct AutoComplete
|
||||||
// Find all struct or class bodies that we're in.
|
// Find all struct or class bodies that we're in.
|
||||||
// Check for the symbol in those class/struct/interface bodies
|
// Check for the symbol in those class/struct/interface bodies
|
||||||
// if match is found, return it
|
// if match is found, return it
|
||||||
if (symbol == "this")
|
|
||||||
stderr.writeln("this");
|
|
||||||
auto structs = context.getStructsContaining(cursor);
|
auto structs = context.getStructsContaining(cursor);
|
||||||
stderr.writeln(structs.length, " structs contain cursor position ", cursor);
|
|
||||||
if (symbol == "this" && structs.length > 0)
|
if (symbol == "this" && structs.length > 0)
|
||||||
{
|
{
|
||||||
stderr.writeln("this");
|
|
||||||
return minCount!("a.bodyStart > b.bodyStart")(structs)[0].name;
|
return minCount!("a.bodyStart > b.bodyStart")(structs)[0].name;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -286,10 +281,11 @@ struct AutoComplete
|
||||||
case TokenType.Switch:
|
case TokenType.Switch:
|
||||||
return "";
|
return "";
|
||||||
default:
|
default:
|
||||||
// size_t startIndex = findBeginningOfExpression(tokens, index);
|
size_t startIndex = findBeginningOfExpression(tokens, index);
|
||||||
// auto expressionType = getTypeOfExpression(tokens[startIndex .. index],
|
auto callChain = splitCallChain(tokens[startIndex .. index + 1]);
|
||||||
// tokens, index);
|
auto expressionType = getTypeOfExpression(
|
||||||
return "";
|
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;
|
auto index = assumeSorted(tokens).lowerBound(cursor).length - 1;
|
||||||
Token t = tokens[index];
|
Token t = tokens[index];
|
||||||
size_t startIndex = findBeginningOfExpression(tokens, index);
|
size_t startIndex = findBeginningOfExpression(tokens, index);
|
||||||
stderr.writeln("call chain: ", splitCallChain(tokens[startIndex .. index]));
|
|
||||||
auto expressionType = getTypeOfExpression(
|
auto expressionType = getTypeOfExpression(
|
||||||
splitCallChain(tokens[startIndex .. index]), tokens, cursor);
|
splitCallChain(tokens[startIndex .. index]), tokens, cursor);
|
||||||
|
|
||||||
|
|
7
parser.d
7
parser.d
|
@ -593,11 +593,18 @@ body
|
||||||
|
|
||||||
if (tokens[index] == TokenType.If)
|
if (tokens[index] == TokenType.If)
|
||||||
f.constraint = parseConstraint(tokens, index);
|
f.constraint = parseConstraint(tokens, index);
|
||||||
|
|
||||||
while (index < tokens.length &&
|
while (index < tokens.length &&
|
||||||
(tokens[index] == TokenType.In || tokens[index] == TokenType.Out
|
(tokens[index] == TokenType.In || tokens[index] == TokenType.Out
|
||||||
|| tokens[index] == TokenType.Body))
|
|| tokens[index] == TokenType.Body))
|
||||||
{
|
{
|
||||||
++index;
|
++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)
|
if (index < tokens.length && tokens[index] == TokenType.LBrace)
|
||||||
tokens.skipBlockStatement(index);
|
tokens.skipBlockStatement(index);
|
||||||
}
|
}
|
||||||
|
|
68
types.d
68
types.d
|
@ -173,6 +173,21 @@ public:
|
||||||
return null;
|
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)
|
string[] getCtags(string fileName)
|
||||||
{
|
{
|
||||||
auto app = appender!(string[])();
|
auto app = appender!(string[])();
|
||||||
|
@ -230,6 +245,19 @@ public:
|
||||||
/// Parameter list; may be empty
|
/// Parameter list; may be empty
|
||||||
Variable[] parameters;
|
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:
|
protected:
|
||||||
override void printMembers(File f, uint indent) const
|
override void printMembers(File f, uint indent) const
|
||||||
{
|
{
|
||||||
|
@ -631,13 +659,30 @@ public:
|
||||||
{
|
{
|
||||||
if (s.bodyStart <= cursorPosition && s.bodyEnd >= cursorPosition)
|
if (s.bodyStart <= cursorPosition && s.bodyEnd >= cursorPosition)
|
||||||
app.put(s);
|
app.put(s);
|
||||||
else
|
|
||||||
stderr.writeln(s.name, " does not contain ", cursorPosition,
|
|
||||||
"(", s.bodyStart, ", ", s.bodyEnd, ")");
|
|
||||||
}
|
}
|
||||||
return app.data();
|
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)
|
void addModule(Module mod)
|
||||||
{
|
{
|
||||||
modules ~= mod;
|
modules ~= mod;
|
||||||
|
@ -645,4 +690,21 @@ public:
|
||||||
|
|
||||||
Module currentModule;
|
Module currentModule;
|
||||||
Module[] modules;
|
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;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue