Fixes #23, among other things

This commit is contained in:
Hackerpilot 2013-09-01 00:31:56 +00:00
parent 5ba4a47047
commit 616ea4feff
6 changed files with 90 additions and 58 deletions

View File

@ -90,6 +90,9 @@ public:
*/
ACSymbol[] parts;
/**
* Listing of superclasses
*/
string[] superClasses;
/**
@ -159,6 +162,10 @@ public:
this.end = end;
}
/**
* Gets all symbols in the scope that contains the cursor as well as its
* parent scopes.
*/
ACSymbol[] getSymbolsInCurrentScope(size_t cursorPosition)
{
Scope s = findCurrentScope(cursorPosition);
@ -168,6 +175,9 @@ public:
return s.getSymbols();
}
/**
* Gets all symbols in this scope and its parent scopes.
*/
ACSymbol[] getSymbols()
{
ACSymbol[] rVal;
@ -229,20 +239,6 @@ public:
*/
void resolveSymbolTypes()
{
foreach (ref ACSymbol c; symbols.filter!(a => a.kind == CompletionKind.className
|| a.kind == CompletionKind.interfaceName))
{
foreach (string sc; c.superClasses)
{
ACSymbol[] s = findSymbolsInScope(sc);
if (s.length > 0)
{
foreach (part; s[0].parts)
c.parts ~= part;
}
}
}
// We only care about resolving types of variables, all other symbols
// don't have any indirection
foreach (ref s; symbols.filter!(a => (a.kind == CompletionKind.variableName
@ -321,10 +317,26 @@ public:
}
}
}
foreach (c; children)
{
c.resolveSymbolTypes();
}
foreach (ref ACSymbol c; symbols.filter!(a => a.kind == CompletionKind.className
|| a.kind == CompletionKind.interfaceName))
{
foreach (string sc; c.superClasses)
{
//writeln("Adding inherited fields from ", sc);
ACSymbol[] s = findSymbolsInScope(sc);
if (s.length > 0)
{
foreach (part; s[0].parts)
c.parts ~= part;
}
}
}
}
/**

View File

@ -93,7 +93,7 @@ class AutocompleteVisitor : ASTVisitor
symbol.type = t;
symbol.kind = CompletionKind.variableName;
symbols ~= symbol;
writeln("For statement variable ", symbol.name, " of type ", symbol.type, " added.");
//writeln("For statement variable ", symbol.name, " of type ", symbol.type, " added.");
}
BlockStatement block = forStatement.statementNoCaseNoDefault.blockStatement;
auto s = new Scope(forStatement.startIndex,
@ -105,14 +105,14 @@ class AutocompleteVisitor : ASTVisitor
foreach (symbol; symbols)
{
writeln("added ", symbol.name, " to scope");
//writeln("added ", symbol.name, " to scope");
symbol.location = scope_.start;
scope_.symbols ~= symbol;
}
if (block.declarationsAndStatements !is null)
{
writeln("visiting body");
//writeln("visiting body");
visit(block.declarationsAndStatements);
}
scope_ = p;
@ -314,9 +314,23 @@ class AutocompleteVisitor : ASTVisitor
}
}
if (dec.returnType !is null && dec.parameters !is null)
if (dec.parameters !is null)
{
symbol.calltip = format("%s %s%s", dec.returnType.toString(),
string returnType;
if (dec.returnType !is null)
returnType = dec.returnType.toString();
else
{
if (dec.hasAuto)
{
returnType = "auto";
if (dec.hasRef)
returnType = "auto ref";
}
else if (dec.hasRef)
returnType = "ref";
}
symbol.calltip = format("%s %s%s", returnType,
dec.name.value, dec.parameters.toString());
}
auto p = parentSymbol;
@ -448,6 +462,23 @@ class AutocompleteVisitor : ASTVisitor
}
}
override void visit(BaseClassList classList)
{
if (parentSymbol is null)
return;
foreach (BaseClass bc; classList.items)
{
if (bc.identifierOrTemplateChain is null)
continue;
if (bc.identifierOrTemplateChain.identifiersOrTemplateInstances.length != 1)
continue;
IdentifierOrTemplateInstance i = bc.identifierOrTemplateChain.identifiersOrTemplateInstances[0];
if (i is null || i.identifier == TokenType.invalid)
continue;
parentSymbol.superClasses ~= i.identifier.value;
}
}
override void visit(BlockStatement blockStatement)
{
auto s = scope_;

View File

@ -31,6 +31,7 @@ import std.uni;
import stdx.d.ast;
import stdx.d.lexer;
import stdx.d.parser;
import std.string;
import messages;
import acvisitor;
@ -38,7 +39,6 @@ import actypes;
import constants;
import modulecache;
AutocompleteResponse complete(AutocompleteRequest request, string[] importPaths)
{
writeln("Got a completion request");
@ -180,7 +180,7 @@ void setCompletions(T)(ref AutocompleteResponse response,
{
// writeln("Showing all symbols in current scope that start with ", partial);
foreach (s; visitor.scope_.getSymbolsInCurrentScope(cursorPosition)
.filter!(a => a.name.startsWith(partial)))
.filter!(a => a.name.toUpper().startsWith(partial.toUpper())))
{
response.completionKinds ~= s.kind;
response.completions ~= s.name;
@ -348,9 +348,10 @@ void setCompletions(T)(ref AutocompleteResponse response,
{
foreach (s; symbols[0].parts.filter!(a => a.name !is null
&& a.name[0] != '*'
&& (partial is null ? true : a.name.startsWith(partial))))
&& (partial is null ? true : a.name.toUpper().startsWith(partial.toUpper()))
&& !response.completions.canFind(a.name)))
{
// writeln("Adding ", s.name, " to the completion list");
//writeln("Adding ", s.name, " to the completion list");
response.completionKinds ~= s.kind;
response.completions ~= s.name;
}
@ -505,26 +506,16 @@ void setImportCompletions(T)(T tokens, ref AutocompleteResponse response)
{
response.completions ~= name.baseName(".d").baseName(".di");
response.completionKinds ~= CompletionKind.moduleName;
}
}
else if (isDir(name))
{
response.completions ~= name.baseName();
response.completionKinds ~= CompletionKind.packageName;
}
}
}
}
}
string createCamelCaseRegex(string input)
{
return to!string(input.map!(a => isLower(a) ? [a] : ".*"d ~ a).join());
}
unittest
{
assert("ClNa".createCamelCaseRegex() == "Cl.*Na.*");
}
/**
* Initializes builtin types and the various properties of builtin types
*/

@ -1 +1 @@
Subproject commit 270cd6d9a1196ea802e79958605c9705c5ea22d4
Subproject commit ce53b1643b17b614adf222f932fb54831cb7c678

View File

@ -25,7 +25,7 @@ local function showCompletionList(r)
buffer.auto_c_choose_single = false;
buffer.auto_c_max_width = 0
local completions = {}
for symbol, kind in r:gmatch("([@%w_%p]+)\t(%a)\n") do
for symbol, kind in r:gmatch("([^%s]+)\t(%a)\n") do
completion = symbol
if kind == "k" then
completion = completion .. "?5"
@ -109,27 +109,23 @@ end)
function M.autocomplete(ch)
if buffer:get_lexer() ~= "dmd" then return end
if ch > 255 then return end
local character = string.char(ch)
if character == "." or character == "(" then
local fileName = os.tmpname()
local command = M.PATH_TO_DCD_CLIENT .. " -c" .. buffer.current_pos .. " > " .. fileName
local p = io.popen(command, "w")
p:write(buffer:get_text())
p:flush()
p:close()
local tmpFile = io.open(fileName, "r")
local r = tmpFile:read("*a")
--print(r)
if r ~= "\n" then
if r:match("^identifiers.*") then
showCompletionList(r)
else
showCalltips(r)
end
local fileName = os.tmpname()
local command = M.PATH_TO_DCD_CLIENT .. " -c" .. buffer.current_pos .. " > " .. fileName
local p = io.popen(command, "w")
p:write(buffer:get_text())
p:flush()
p:close()
local tmpFile = io.open(fileName, "r")
local r = tmpFile:read("*a")
print(r)
if r ~= "\n" then
if r:match("^identifiers.*") then
showCompletionList(r)
else
showCalltips(r)
end
os.remove(fileName)
end
os.remove(fileName)
end
M.ALIAS =[[

View File

@ -11,12 +11,14 @@ if type(_G.keys) == 'table' then
end
events.connect(events.CHAR_ADDED, function(ch)
_M.dcd.autocomplete(ch)
if string.char(ch) == '(' or string.char(ch) == '.' then
_M.dcd.autocomplete(ch)
end
end)
local function autocomplete()
_M.dcd.registerImages()
_M.dcd.autocomplete(string.byte('.'))
_M.dcd.autocomplete()
if not buffer:auto_c_active() then
_M.textadept.editing.autocomplete_word(keywords)
end