Fixes #23, among other things
This commit is contained in:
parent
5ba4a47047
commit
616ea4feff
40
actypes.d
40
actypes.d
|
@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
41
acvisitor.d
41
acvisitor.d
|
@ -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_;
|
||||
|
|
|
@ -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
|
||||
*/
|
||||
|
|
2
dscanner
2
dscanner
|
@ -1 +1 @@
|
|||
Subproject commit 270cd6d9a1196ea802e79958605c9705c5ea22d4
|
||||
Subproject commit ce53b1643b17b614adf222f932fb54831cb7c678
|
|
@ -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 =[[
|
||||
|
|
|
@ -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
|
||||
|
|
Loading…
Reference in New Issue