Show call tips for opCall and constructors

This commit is contained in:
Hackerpilot 2013-08-11 18:24:40 +00:00
parent bf3c7ba500
commit 2faa0aebf2
3 changed files with 79 additions and 5 deletions

View File

@ -22,6 +22,7 @@ back to the client.
* UFCS * UFCS
* Templated declarations * Templated declarations
* *auto* declarations * *auto* declarations
* alias declarations
* Determining the type of an enum member when no base type is specified, but the first member has an initialaizer * Determining the type of an enum member when no base type is specified, but the first member has an initialaizer
* Public imports * Public imports
* That one feature that you *REALLY* needed * That one feature that you *REALLY* needed

View File

@ -131,9 +131,67 @@ class AutocompleteVisitor : ASTVisitor
scope_.symbols ~= symbol; scope_.symbols ~= symbol;
} }
override void visit(Constructor dec)
{
ACSymbol symbol = new ACSymbol("*constructor*");
symbol.location = dec.location;
symbol.kind = CompletionKind.functionName;
//symbol.type = dec.returnType;
ACSymbol[] parameterSymbols;
if (dec.parameters !is null)
{
foreach (parameter; dec.parameters.parameters)
{
// writeln("Adding parameter ", parameter.name.value);
ACSymbol paramSymbol = new ACSymbol;
paramSymbol.name = parameter.name.value;
paramSymbol.type = parameter.type;
paramSymbol.kind = CompletionKind.variableName;
paramSymbol.location = parameter.name.startIndex;
parameterSymbols ~= paramSymbol;
}
}
if (dec.parameters !is null)
{
symbol.calltip = format("%s this%s", parentSymbol.name,
dec.parameters.toString());
}
auto p = parentSymbol;
parentSymbol = symbol;
BlockStatement functionBody = dec.functionBody is null ? null
: (dec.functionBody.bodyStatement !is null
? dec.functionBody.bodyStatement.blockStatement : dec.functionBody.blockStatement);
if (functionBody !is null)
{
auto s = scope_;
scope_ = new Scope(functionBody.startLocation,
functionBody.endLocation);
scope_.parent = s;
foreach (parameterSymbol; parameterSymbols)
{
parameterSymbol.location = functionBody.startLocation;
scope_.symbols ~= parameterSymbol;
}
if (functionBody.declarationsAndStatements !is null)
functionBody.declarationsAndStatements.accept(this);
s.children ~= scope_;
scope_ = s;
}
parentSymbol = p;
if (parentSymbol is null)
symbols ~= symbol;
else
parentSymbol.parts ~= symbol;
scope_.symbols ~= symbol;
}
override void visit(FunctionDeclaration dec) override void visit(FunctionDeclaration dec)
{ {
// writeln("FunctionDeclaration visit");
ACSymbol symbol = new ACSymbol; ACSymbol symbol = new ACSymbol;
symbol.name = dec.name.value; symbol.name = dec.name.value;
symbol.location = dec.name.startIndex; symbol.location = dec.name.startIndex;
@ -155,7 +213,6 @@ class AutocompleteVisitor : ASTVisitor
} }
} }
// writeln("Parameter symbols added");
if (dec.returnType !is null && dec.parameters !is null) if (dec.returnType !is null && dec.parameters !is null)
{ {
symbol.calltip = format("%s %s%s", dec.returnType.toString(), symbol.calltip = format("%s %s%s", dec.returnType.toString(),
@ -163,7 +220,6 @@ class AutocompleteVisitor : ASTVisitor
} }
auto p = parentSymbol; auto p = parentSymbol;
parentSymbol = symbol; parentSymbol = symbol;
// writeln("Call tip created");
BlockStatement functionBody = dec.functionBody is null ? null BlockStatement functionBody = dec.functionBody is null ? null
: (dec.functionBody.bodyStatement !is null : (dec.functionBody.bodyStatement !is null
@ -171,7 +227,6 @@ class AutocompleteVisitor : ASTVisitor
if (functionBody !is null) if (functionBody !is null)
{ {
// writeln("Processing function body");
auto s = scope_; auto s = scope_;
scope_ = new Scope(functionBody.startLocation, scope_ = new Scope(functionBody.startLocation,
functionBody.endLocation); functionBody.endLocation);

View File

@ -298,7 +298,7 @@ void setCompletions(T)(ref AutocompleteResponse response,
if (completionType == CompletionType.identifiers) if (completionType == CompletionType.identifiers)
{ {
writeln("Writing completions for ", symbol.name); writeln("Writing completions for ", symbol.name);
foreach (s; symbol.parts) foreach (s; symbol.parts.filter!(a => a.name[0] != '*'))
{ {
writeln("Adding ", s.name, " to the completion list"); writeln("Adding ", s.name, " to the completion list");
response.completionKinds ~= s.kind; response.completionKinds ~= s.kind;
@ -308,6 +308,24 @@ void setCompletions(T)(ref AutocompleteResponse response,
} }
else else
{ {
if (symbol.kind != CompletionKind.functionName)
{
auto call = symbol.getPartByName("opCall");
if (call !is null)
{
symbol = call;
goto setCallTips;
}
auto constructor = symbol.getPartByName("*constructor*");
if (constructor is null)
return;
else
{
symbol = constructor;
goto setCallTips;
}
}
setCallTips:
response.completions ~= symbol.calltip; response.completions ~= symbol.calltip;
response.completionType = CompletionType.calltips; response.completionType = CompletionType.calltips;
} }