From 616ea4feffef4cd9fa8c69f93292d991599c9d04 Mon Sep 17 00:00:00 2001 From: Hackerpilot Date: Sun, 1 Sep 2013 00:31:56 +0000 Subject: [PATCH] Fixes #23, among other things --- actypes.d | 40 ++++++++++++++++--------- acvisitor.d | 41 ++++++++++++++++++++++---- autocomplete.d | 23 +++++---------- dscanner | 2 +- editors/textadept/modules/dmd/dcd.lua | 36 ++++++++++------------ editors/textadept/modules/dmd/init.lua | 6 ++-- 6 files changed, 90 insertions(+), 58 deletions(-) diff --git a/actypes.d b/actypes.d index 5876d08..1d053b1 100644 --- a/actypes.d +++ b/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; + } + } + } } /** diff --git a/acvisitor.d b/acvisitor.d index 091e3fd..95c7331 100644 --- a/acvisitor.d +++ b/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_; diff --git a/autocomplete.d b/autocomplete.d index 4bd28aa..8d88512 100644 --- a/autocomplete.d +++ b/autocomplete.d @@ -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 */ diff --git a/dscanner b/dscanner index 270cd6d..ce53b16 160000 --- a/dscanner +++ b/dscanner @@ -1 +1 @@ -Subproject commit 270cd6d9a1196ea802e79958605c9705c5ea22d4 +Subproject commit ce53b1643b17b614adf222f932fb54831cb7c678 diff --git a/editors/textadept/modules/dmd/dcd.lua b/editors/textadept/modules/dmd/dcd.lua index 07ba108..3247bf2 100644 --- a/editors/textadept/modules/dmd/dcd.lua +++ b/editors/textadept/modules/dmd/dcd.lua @@ -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 =[[ diff --git a/editors/textadept/modules/dmd/init.lua b/editors/textadept/modules/dmd/init.lua index cda5f90..3302e79 100644 --- a/editors/textadept/modules/dmd/init.lua +++ b/editors/textadept/modules/dmd/init.lua @@ -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