From b92b8944b5308a56a2b6453270cb255d9f339e79 Mon Sep 17 00:00:00 2001 From: Hackerpilot Date: Mon, 3 Aug 2015 16:38:40 -0700 Subject: [PATCH] Use new dsymbol code --- src/server/autocomplete.d | 116 +++++++++++++++++++++----------------- src/server/server.d | 29 +++++----- 2 files changed, 79 insertions(+), 66 deletions(-) diff --git a/src/server/autocomplete.d b/src/server/autocomplete.d index 433efd8..d663470 100644 --- a/src/server/autocomplete.d +++ b/src/server/autocomplete.d @@ -20,6 +20,7 @@ module server.autocomplete; import std.algorithm; import std.experimental.allocator; +import std.experimental.logger; import std.array; import std.conv; import std.experimental.logger; @@ -48,8 +49,6 @@ import memory.allocators; import common.constants; import common.messages; -private alias ASTAllocator = CAllocatorImpl!(AllocatorList!(n => Region!Mallocator(1024 * 64))); - /** * Gets documentation for the symbol at the cursor * Params: @@ -57,14 +56,15 @@ private alias ASTAllocator = CAllocatorImpl!(AllocatorList!(n => Region!Mallocat * Returns: * the autocompletion response */ -public AutocompleteResponse getDoc(const AutocompleteRequest request) +public AutocompleteResponse getDoc(const AutocompleteRequest request, + ref ModuleCache moduleCache) { // trace("Getting doc comments"); AutocompleteResponse response; auto allocator = scoped!(ASTAllocator)(); auto cache = StringCache(StringCache.defaultBucketCount); SymbolStuff stuff = getSymbolsForCompletion(request, CompletionType.ddoc, - allocator, &cache); + allocator, cache, moduleCache); if (stuff.symbols.length == 0) warning("Could not find symbol"); else foreach (symbol; stuff.symbols.filter!(a => !a.doc.empty)) @@ -79,13 +79,14 @@ public AutocompleteResponse getDoc(const AutocompleteRequest request) * Returns: * the autocompletion response */ -public AutocompleteResponse findDeclaration(const AutocompleteRequest request) +public AutocompleteResponse findDeclaration(const AutocompleteRequest request, + ref ModuleCache moduleCache) { AutocompleteResponse response; auto allocator = scoped!(ASTAllocator)(); auto cache = StringCache(StringCache.defaultBucketCount); SymbolStuff stuff = getSymbolsForCompletion(request, - CompletionType.location, allocator, &cache); + CompletionType.location, allocator, cache, moduleCache); scope(exit) stuff.destroy(); if (stuff.symbols.length > 0) { @@ -104,40 +105,45 @@ public AutocompleteResponse findDeclaration(const AutocompleteRequest request) * Returns: * the autocompletion response */ -public AutocompleteResponse complete(const AutocompleteRequest request) +public AutocompleteResponse complete(const AutocompleteRequest request, + ref ModuleCache moduleCache) { const(Token)[] tokenArray; - auto cache = StringCache(StringCache.defaultBucketCount); + auto stringCache = StringCache(StringCache.defaultBucketCount); auto beforeTokens = getTokensBeforeCursor(request.sourceCode, - request.cursorPosition, &cache, tokenArray); + request.cursorPosition, stringCache, tokenArray); if (beforeTokens.length >= 2) { if (beforeTokens[$ - 1] == tok!"(" || beforeTokens[$ - 1] == tok!"[") { - return parenCompletion(beforeTokens, tokenArray, request.cursorPosition); + return parenCompletion(beforeTokens, tokenArray, request.cursorPosition, + moduleCache); } else if (beforeTokens[$ - 1] == tok!",") { immutable size_t end = goBackToOpenParen(beforeTokens); if (end != size_t.max) - return parenCompletion(beforeTokens[0 .. end], tokenArray, request.cursorPosition); + return parenCompletion(beforeTokens[0 .. end], tokenArray, + request.cursorPosition, moduleCache); } else { ImportKind kind = determineImportKind(beforeTokens); if (kind == ImportKind.neither) - return dotCompletion(beforeTokens, tokenArray, request.cursorPosition); + return dotCompletion(beforeTokens, tokenArray, request.cursorPosition, + moduleCache); else - return importCompletion(beforeTokens, kind); + return importCompletion(beforeTokens, kind, moduleCache); } } - return dotCompletion(beforeTokens, tokenArray, request.cursorPosition); + return dotCompletion(beforeTokens, tokenArray, request.cursorPosition, moduleCache); } /** * */ -public AutocompleteResponse symbolSearch(const AutocompleteRequest request) +public AutocompleteResponse symbolSearch(const AutocompleteRequest request, + ref ModuleCache moduleCache) { import containers.ttree : TTree; @@ -148,7 +154,7 @@ public AutocompleteResponse symbolSearch(const AutocompleteRequest request) config, &cache); auto allocator = scoped!(ASTAllocator)(); ScopeSymbolPair pair = generateAutocompleteTrees(tokenArray, allocator, - request.cursorPosition); + request.cursorPosition, moduleCache); scope(exit) pair.destroy(); static struct SearchResults @@ -183,7 +189,7 @@ public AutocompleteResponse symbolSearch(const AutocompleteRequest request) { symbol.getAllPartsNamed(request.searchName, results); } - foreach (s; ModuleCache.getAllSymbols()) + foreach (s; moduleCache.getAllSymbols()) { s.symbol.getAllPartsNamed(request.searchName, results); } @@ -203,7 +209,7 @@ public AutocompleteResponse symbolSearch(const AutocompleteRequest request) /******************************************************************************/ private: -enum ImportKind +enum ImportKind : ubyte { selective, normal, @@ -219,8 +225,8 @@ enum ImportKind * Returns: * the autocompletion response */ -AutocompleteResponse dotCompletion(T)(T beforeTokens, - const(Token)[] tokenArray, size_t cursorPosition) +AutocompleteResponse dotCompletion(T)(T beforeTokens, const(Token)[] tokenArray, + size_t cursorPosition, ref ModuleCache moduleCache) { AutocompleteResponse response; @@ -239,8 +245,8 @@ AutocompleteResponse dotCompletion(T)(T beforeTokens, // responses when the cursor is in the middle of an identifier instead // of at the end auto t = beforeTokens[$ - 1]; - partial = t.text[0 .. cursorPosition - t.index]; - + if (cursorPosition - t.index >= 0 && cursorPosition - t.index <= t.text.length) + partial = t.text[0 .. cursorPosition - t.index]; significantTokenType = tok!"identifier"; beforeTokens = beforeTokens[0 .. $ - 1]; } @@ -291,7 +297,7 @@ AutocompleteResponse dotCompletion(T)(T beforeTokens, case tok!"super": auto allocator = scoped!(ASTAllocator)(); ScopeSymbolPair pair = generateAutocompleteTrees(tokenArray, allocator, - cursorPosition); + cursorPosition, moduleCache); scope(exit) pair.destroy(); response.setCompletions(pair.scope_, getExpression(beforeTokens), cursorPosition, CompletionType.identifiers, false, partial); @@ -316,11 +322,11 @@ AutocompleteResponse dotCompletion(T)(T beforeTokens, * a sorted range of tokens before the cursor position */ auto getTokensBeforeCursor(const(ubyte[]) sourceCode, size_t cursorPosition, - StringCache* cache, out const(Token)[] tokenArray) + ref StringCache cache, out const(Token)[] tokenArray) { LexerConfig config; config.fileName = ""; - tokenArray = getTokensForParser(cast(ubyte[]) sourceCode, config, cache); + tokenArray = getTokensForParser(cast(ubyte[]) sourceCode, config, &cache); auto sortedTokens = assumeSorted(tokenArray); return sortedTokens.lowerBound(cast(size_t) cursorPosition); } @@ -334,13 +340,14 @@ auto getTokensBeforeCursor(const(ubyte[]) sourceCode, size_t cursorPosition, * the request's source code, cursor position, and completion type. */ SymbolStuff getSymbolsForCompletion(const AutocompleteRequest request, - const CompletionType type, IAllocator allocator, StringCache* cache) + const CompletionType type, IAllocator allocator, ref StringCache cache, + ref ModuleCache moduleCache) { const(Token)[] tokenArray; auto beforeTokens = getTokensBeforeCursor(request.sourceCode, request.cursorPosition, cache, tokenArray); ScopeSymbolPair pair = generateAutocompleteTrees(tokenArray, allocator, - request.cursorPosition); + request.cursorPosition, moduleCache); auto expression = getExpression(beforeTokens); return SymbolStuff(getSymbolsByTokenChain(pair.scope_, expression, request.cursorPosition, type), pair.symbol, pair.scope_); @@ -369,7 +376,7 @@ struct SymbolStuff * the autocompletion response */ AutocompleteResponse parenCompletion(T)(T beforeTokens, - const(Token)[] tokenArray, size_t cursorPosition) + const(Token)[] tokenArray, size_t cursorPosition, ref ModuleCache moduleCache) { AutocompleteResponse response; immutable(string)[] completions; @@ -418,7 +425,7 @@ AutocompleteResponse parenCompletion(T)(T beforeTokens, case tok!"]": auto allocator = scoped!(ASTAllocator)(); ScopeSymbolPair pair = generateAutocompleteTrees(tokenArray, allocator, - cursorPosition); + cursorPosition, moduleCache); scope(exit) pair.destroy(); auto expression = getExpression(beforeTokens[0 .. $ - 1]); response.setCompletions(pair.scope_, expression, @@ -437,7 +444,8 @@ ImportKind determineImportKind(T)(T tokens) { assert (tokens.length > 1); size_t i = tokens.length - 1; - if (!(tokens[i] == tok!":" || tokens[i] == tok!"," || tokens[i] == tok!"." || tokens[i] == tok!"identifier")) + if (!(tokens[i] == tok!":" || tokens[i] == tok!"," || tokens[i] == tok!"." + || tokens[i] == tok!"identifier")) return ImportKind.neither; bool foundColon = false; while (true) switch (tokens[i].type) @@ -484,7 +492,8 @@ unittest * import std.algorithm: balancedParens; * --- */ -AutocompleteResponse importCompletion(T)(T beforeTokens, ImportKind kind) +AutocompleteResponse importCompletion(T)(T beforeTokens, ImportKind kind, + ref ModuleCache moduleCache) in { assert (beforeTokens.length >= 2); @@ -501,7 +510,7 @@ body { while (beforeTokens[i].type != tok!"," && beforeTokens[i].type != tok!"import") i--; - setImportCompletions(beforeTokens[i .. $], response); + setImportCompletions(beforeTokens[i .. $], response, moduleCache); return response; } @@ -550,13 +559,13 @@ body } } - string resolvedLocation = ModuleCache.resolveImportLocation(path); + string resolvedLocation = moduleCache.resolveImportLocation(path); if (resolvedLocation is null) { warning("Could not resolve location of ", path); return response; } - auto symbols = ModuleCache.getModuleSymbol(resolvedLocation); + auto symbols = moduleCache.getModuleSymbol(internString(resolvedLocation)); import containers.hashset : HashSet; HashSet!string h; @@ -575,8 +584,9 @@ body foreach (s; symbols.opSlice()) { - if (s.kind == CompletionKind.importSymbol) foreach (sy; s.type.opSlice()) - addSymbolToResponses(sy); + if (s.kind == CompletionKind.importSymbol && s.type !is null) + foreach (sy; s.type.opSlice()) + addSymbolToResponses(sy); else addSymbolToResponses(s); } @@ -590,7 +600,8 @@ body * tokens = the tokens after the "import" keyword and before the cursor * response = the response that should be populated */ -void setImportCompletions(T)(T tokens, ref AutocompleteResponse response) +void setImportCompletions(T)(T tokens, ref AutocompleteResponse response, + ref ModuleCache cache) { response.completionType = CompletionType.identifiers; string partial = null; @@ -604,7 +615,7 @@ void setImportCompletions(T)(T tokens, ref AutocompleteResponse response) bool found = false; - foreach (importDirectory; ModuleCache.getImportPaths()) + foreach (importDirectory; cache.getImportPaths()) { string p = buildPath(importDirectory, path); if (!exists(p)) @@ -732,11 +743,11 @@ DSymbol*[] getSymbolsByTokenChain(T)(Scope* completionScope, break loop; } -// Log.trace("looking for ", tokens[i].text, " in ", symbols[0].name); +// trace("looking for ", tokens[i].text, " in ", symbols[0].name); symbols = symbols[0].getPartsByName(internString(tokens[i].text)); if (symbols.length == 0) { -// Log.trace("Couldn't find it."); +// trace("Couldn't find it."); break loop; } if (shouldSwapWithType(completionType, symbols[0].kind, i, @@ -820,7 +831,8 @@ void setCompletions(T)(ref AutocompleteResponse response, // based on the currently entered text. if (partial !is null && tokens.length == 0) { - foreach (s; completionScope.getSymbolsInCursorScope(cursorPosition) + auto currentSymbols = completionScope.getSymbolsInCursorScope(cursorPosition); + foreach (s; currentSymbols .filter!(a => a.name.toUpper().startsWith(partial.toUpper()))) { response.completionKinds ~= s.kind; @@ -848,26 +860,24 @@ void setCompletions(T)(ref AutocompleteResponse response, if (symbols.length == 0) return; } - foreach (sym; symbols[0].opSlice()) + if (symbols[0].kind != CompletionKind.importSymbol) { - if (sym.kind == CompletionKind.importSymbol) foreach (s; sym.type.opSlice()) + foreach (sym; symbols[0].opSlice()) { - response.completionKinds ~= s.kind; - response.completions ~= s.name.dup; - } - else if (sym.name !is null && sym.name.length > 0 && sym.name[0] != '*' - && (partial is null ? true : sym.name.toUpper().startsWith(partial.toUpper())) - && !response.completions.canFind(sym.name)) - { - response.completionKinds ~= sym.kind; - response.completions ~= sym.name.dup; + if (sym.name !is null && sym.name.length > 0 && sym.name[0] != '*' + && (partial is null ? true : sym.name.toUpper().startsWith(partial.toUpper())) + && !response.completions.canFind(sym.name)) + { + response.completionKinds ~= sym.kind; + response.completions ~= sym.name.dup; + } } } response.completionType = CompletionType.identifiers; } else if (completionType == CompletionType.calltips) { -// Log.trace("Showing call tips for ", symbols[0].name, " of kind ", symbols[0].kind); +// trace("Showing call tips for ", symbols[0].name, " of kind ", symbols[0].kind); if (symbols[0].kind != CompletionKind.functionName && symbols[0].callTip is null) { diff --git a/src/server/server.d b/src/server/server.d index cf692d1..826b1b7 100644 --- a/src/server/server.d +++ b/src/server/server.d @@ -58,12 +58,13 @@ int main(string[] args) ushort port = 9166; bool help; bool printVersion; + bool ignoreConfig; string[] importPaths; try { getopt(args, "port|p", &port, "I", &importPaths, "help|h", &help, - "version", & printVersion); + "version", &printVersion, "ignoreConfig", &ignoreConfig); } catch (ConvException e) { @@ -87,7 +88,8 @@ int main(string[] args) return 0; } - importPaths ~= loadConfiguredImportDirs(); + if (!ignoreConfig) + importPaths ~= loadConfiguredImportDirs(); auto socket = new TcpSocket(AddressFamily.INET); socket.blocking = true; @@ -102,14 +104,15 @@ int main(string[] args) info("Sockets shut down."); } - ModuleCache.addImportPaths(importPaths); - infof("Import directories:\n %-(%s\n %)", ModuleCache.getImportPaths()); + ModuleCache cache = ModuleCache(new ASTAllocator); + cache.addImportPaths(importPaths); + infof("Import directories:\n %-(%s\n %)", cache.getImportPaths()); ubyte[] buffer = cast(ubyte[]) Mallocator.it.allocate(1024 * 1024 * 4); // 4 megabytes should be enough for anybody... scope(exit) Mallocator.it.deallocate(buffer); sw.stop(); - info(ModuleCache.symbolsAllocated, " symbols cached."); + info(cache.symbolsAllocated, " symbols cached."); info("Startup completed in ", sw.peek().to!("msecs", float), " milliseconds."); // No relative paths @@ -167,7 +170,7 @@ int main(string[] args) if (request.kind & RequestKind.clearCache) { info("Clearing cache."); - ModuleCache.clear(); + cache.clear(); } else if (request.kind & RequestKind.shutdown) { @@ -184,12 +187,12 @@ int main(string[] args) } if (request.kind & RequestKind.addImport) { - ModuleCache.addImportPaths(request.importPaths); + cache.addImportPaths(request.importPaths); } if (request.kind & RequestKind.listImports) { AutocompleteResponse response; - response.importPaths = ModuleCache.getImportPaths().array(); + response.importPaths = cache.getImportPaths().array(); ubyte[] responseBytes = msgpack.pack(response); info("Returning import path list"); s.send(responseBytes); @@ -197,7 +200,7 @@ int main(string[] args) else if (request.kind & RequestKind.autocomplete) { info("Getting completions"); - AutocompleteResponse response = complete(request); + AutocompleteResponse response = complete(request, cache); ubyte[] responseBytes = msgpack.pack(response); s.send(responseBytes); } @@ -206,7 +209,7 @@ int main(string[] args) info("Getting doc comment"); try { - AutocompleteResponse response = getDoc(request); + AutocompleteResponse response = getDoc(request, cache); ubyte[] responseBytes = msgpack.pack(response); s.send(responseBytes); } @@ -219,7 +222,7 @@ int main(string[] args) { try { - AutocompleteResponse response = findDeclaration(request); + AutocompleteResponse response = findDeclaration(request, cache); ubyte[] responseBytes = msgpack.pack(response); s.send(responseBytes); } @@ -230,7 +233,7 @@ int main(string[] args) } else if (request.kind & RequestKind.search) { - AutocompleteResponse response = symbolSearch(request); + AutocompleteResponse response = symbolSearch(request, cache); ubyte[] responseBytes = msgpack.pack(response); s.send(responseBytes); } @@ -304,7 +307,7 @@ string[] loadConfiguredImportDirs() info("Loading configuration from ", configLocation); File f = File(configLocation, "rt"); return f.byLine(KeepTerminator.no) - .filter!(a => a.length > 0 && existanceCheck(a)) + .filter!(a => a.length > 0 && a[0] != '#' && existanceCheck(a)) .map!(a => a.idup) .array(); }