From 2faa0aebf2abdec52439ea9a61cb14ee5c30fdd0 Mon Sep 17 00:00:00 2001 From: Hackerpilot Date: Sun, 11 Aug 2013 18:24:40 +0000 Subject: [PATCH] Show call tips for opCall and constructors --- README.md | 1 + acvisitor.d | 63 ++++++++++++++++++++++++++++++++++++++++++++++---- autocomplete.d | 20 +++++++++++++++- 3 files changed, 79 insertions(+), 5 deletions(-) diff --git a/README.md b/README.md index d04dc98..8b19893 100644 --- a/README.md +++ b/README.md @@ -22,6 +22,7 @@ back to the client. * UFCS * Templated 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 * Public imports * That one feature that you *REALLY* needed diff --git a/acvisitor.d b/acvisitor.d index 36d5a4c..045a627 100644 --- a/acvisitor.d +++ b/acvisitor.d @@ -131,9 +131,67 @@ class AutocompleteVisitor : ASTVisitor 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) { -// writeln("FunctionDeclaration visit"); ACSymbol symbol = new ACSymbol; symbol.name = dec.name.value; 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) { symbol.calltip = format("%s %s%s", dec.returnType.toString(), @@ -163,7 +220,6 @@ class AutocompleteVisitor : ASTVisitor } auto p = parentSymbol; parentSymbol = symbol; -// writeln("Call tip created"); BlockStatement functionBody = dec.functionBody is null ? null : (dec.functionBody.bodyStatement !is null @@ -171,7 +227,6 @@ class AutocompleteVisitor : ASTVisitor if (functionBody !is null) { -// writeln("Processing function body"); auto s = scope_; scope_ = new Scope(functionBody.startLocation, functionBody.endLocation); diff --git a/autocomplete.d b/autocomplete.d index b7bb49f..5177d31 100644 --- a/autocomplete.d +++ b/autocomplete.d @@ -298,7 +298,7 @@ void setCompletions(T)(ref AutocompleteResponse response, if (completionType == CompletionType.identifiers) { 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"); response.completionKinds ~= s.kind; @@ -308,6 +308,24 @@ void setCompletions(T)(ref AutocompleteResponse response, } 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.completionType = CompletionType.calltips; }