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;
|
ACSymbol[] parts;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Listing of superclasses
|
||||||
|
*/
|
||||||
string[] superClasses;
|
string[] superClasses;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -159,6 +162,10 @@ public:
|
||||||
this.end = end;
|
this.end = end;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets all symbols in the scope that contains the cursor as well as its
|
||||||
|
* parent scopes.
|
||||||
|
*/
|
||||||
ACSymbol[] getSymbolsInCurrentScope(size_t cursorPosition)
|
ACSymbol[] getSymbolsInCurrentScope(size_t cursorPosition)
|
||||||
{
|
{
|
||||||
Scope s = findCurrentScope(cursorPosition);
|
Scope s = findCurrentScope(cursorPosition);
|
||||||
|
@ -168,6 +175,9 @@ public:
|
||||||
return s.getSymbols();
|
return s.getSymbols();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets all symbols in this scope and its parent scopes.
|
||||||
|
*/
|
||||||
ACSymbol[] getSymbols()
|
ACSymbol[] getSymbols()
|
||||||
{
|
{
|
||||||
ACSymbol[] rVal;
|
ACSymbol[] rVal;
|
||||||
|
@ -229,20 +239,6 @@ public:
|
||||||
*/
|
*/
|
||||||
void resolveSymbolTypes()
|
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
|
// We only care about resolving types of variables, all other symbols
|
||||||
// don't have any indirection
|
// don't have any indirection
|
||||||
foreach (ref s; symbols.filter!(a => (a.kind == CompletionKind.variableName
|
foreach (ref s; symbols.filter!(a => (a.kind == CompletionKind.variableName
|
||||||
|
@ -321,10 +317,26 @@ public:
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
foreach (c; children)
|
foreach (c; children)
|
||||||
{
|
{
|
||||||
c.resolveSymbolTypes();
|
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.type = t;
|
||||||
symbol.kind = CompletionKind.variableName;
|
symbol.kind = CompletionKind.variableName;
|
||||||
symbols ~= symbol;
|
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;
|
BlockStatement block = forStatement.statementNoCaseNoDefault.blockStatement;
|
||||||
auto s = new Scope(forStatement.startIndex,
|
auto s = new Scope(forStatement.startIndex,
|
||||||
|
@ -105,14 +105,14 @@ class AutocompleteVisitor : ASTVisitor
|
||||||
|
|
||||||
foreach (symbol; symbols)
|
foreach (symbol; symbols)
|
||||||
{
|
{
|
||||||
writeln("added ", symbol.name, " to scope");
|
//writeln("added ", symbol.name, " to scope");
|
||||||
symbol.location = scope_.start;
|
symbol.location = scope_.start;
|
||||||
scope_.symbols ~= symbol;
|
scope_.symbols ~= symbol;
|
||||||
|
|
||||||
}
|
}
|
||||||
if (block.declarationsAndStatements !is null)
|
if (block.declarationsAndStatements !is null)
|
||||||
{
|
{
|
||||||
writeln("visiting body");
|
//writeln("visiting body");
|
||||||
visit(block.declarationsAndStatements);
|
visit(block.declarationsAndStatements);
|
||||||
}
|
}
|
||||||
scope_ = p;
|
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());
|
dec.name.value, dec.parameters.toString());
|
||||||
}
|
}
|
||||||
auto p = parentSymbol;
|
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)
|
override void visit(BlockStatement blockStatement)
|
||||||
{
|
{
|
||||||
auto s = scope_;
|
auto s = scope_;
|
||||||
|
|
|
@ -31,6 +31,7 @@ import std.uni;
|
||||||
import stdx.d.ast;
|
import stdx.d.ast;
|
||||||
import stdx.d.lexer;
|
import stdx.d.lexer;
|
||||||
import stdx.d.parser;
|
import stdx.d.parser;
|
||||||
|
import std.string;
|
||||||
|
|
||||||
import messages;
|
import messages;
|
||||||
import acvisitor;
|
import acvisitor;
|
||||||
|
@ -38,7 +39,6 @@ import actypes;
|
||||||
import constants;
|
import constants;
|
||||||
import modulecache;
|
import modulecache;
|
||||||
|
|
||||||
|
|
||||||
AutocompleteResponse complete(AutocompleteRequest request, string[] importPaths)
|
AutocompleteResponse complete(AutocompleteRequest request, string[] importPaths)
|
||||||
{
|
{
|
||||||
writeln("Got a completion request");
|
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);
|
// writeln("Showing all symbols in current scope that start with ", partial);
|
||||||
foreach (s; visitor.scope_.getSymbolsInCurrentScope(cursorPosition)
|
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.completionKinds ~= s.kind;
|
||||||
response.completions ~= s.name;
|
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
|
foreach (s; symbols[0].parts.filter!(a => a.name !is null
|
||||||
&& a.name[0] != '*'
|
&& 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.completionKinds ~= s.kind;
|
||||||
response.completions ~= s.name;
|
response.completions ~= s.name;
|
||||||
}
|
}
|
||||||
|
@ -515,16 +516,6 @@ void setImportCompletions(T)(T tokens, ref AutocompleteResponse response)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
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
|
* 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_choose_single = false;
|
||||||
buffer.auto_c_max_width = 0
|
buffer.auto_c_max_width = 0
|
||||||
local completions = {}
|
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
|
completion = symbol
|
||||||
if kind == "k" then
|
if kind == "k" then
|
||||||
completion = completion .. "?5"
|
completion = completion .. "?5"
|
||||||
|
@ -109,9 +109,6 @@ end)
|
||||||
|
|
||||||
function M.autocomplete(ch)
|
function M.autocomplete(ch)
|
||||||
if buffer:get_lexer() ~= "dmd" then return end
|
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 fileName = os.tmpname()
|
||||||
local command = M.PATH_TO_DCD_CLIENT .. " -c" .. buffer.current_pos .. " > " .. fileName
|
local command = M.PATH_TO_DCD_CLIENT .. " -c" .. buffer.current_pos .. " > " .. fileName
|
||||||
local p = io.popen(command, "w")
|
local p = io.popen(command, "w")
|
||||||
|
@ -120,7 +117,7 @@ function M.autocomplete(ch)
|
||||||
p:close()
|
p:close()
|
||||||
local tmpFile = io.open(fileName, "r")
|
local tmpFile = io.open(fileName, "r")
|
||||||
local r = tmpFile:read("*a")
|
local r = tmpFile:read("*a")
|
||||||
--print(r)
|
print(r)
|
||||||
if r ~= "\n" then
|
if r ~= "\n" then
|
||||||
if r:match("^identifiers.*") then
|
if r:match("^identifiers.*") then
|
||||||
showCompletionList(r)
|
showCompletionList(r)
|
||||||
|
@ -129,7 +126,6 @@ function M.autocomplete(ch)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
os.remove(fileName)
|
os.remove(fileName)
|
||||||
end
|
|
||||||
end
|
end
|
||||||
|
|
||||||
M.ALIAS =[[
|
M.ALIAS =[[
|
||||||
|
|
|
@ -11,12 +11,14 @@ if type(_G.keys) == 'table' then
|
||||||
end
|
end
|
||||||
|
|
||||||
events.connect(events.CHAR_ADDED, function(ch)
|
events.connect(events.CHAR_ADDED, function(ch)
|
||||||
|
if string.char(ch) == '(' or string.char(ch) == '.' then
|
||||||
_M.dcd.autocomplete(ch)
|
_M.dcd.autocomplete(ch)
|
||||||
|
end
|
||||||
end)
|
end)
|
||||||
|
|
||||||
local function autocomplete()
|
local function autocomplete()
|
||||||
_M.dcd.registerImages()
|
_M.dcd.registerImages()
|
||||||
_M.dcd.autocomplete(string.byte('.'))
|
_M.dcd.autocomplete()
|
||||||
if not buffer:auto_c_active() then
|
if not buffer:auto_c_active() then
|
||||||
_M.textadept.editing.autocomplete_word(keywords)
|
_M.textadept.editing.autocomplete_word(keywords)
|
||||||
end
|
end
|
||||||
|
|
Loading…
Reference in New Issue