diff --git a/actypes.d b/actypes.d index 6c6afbf..541a2bc 100644 --- a/actypes.d +++ b/actypes.d @@ -533,29 +533,53 @@ static this() auto void_ = allocate!ACSymbol(Mallocator.it, "void", CompletionKind.keyword); builtinSymbols.insert(bool_); + bool_.type = bool_; builtinSymbols.insert(int_); + int_.type = int_; builtinSymbols.insert(long_); + long_.type = long_; builtinSymbols.insert(byte_); + byte_.type = byte_; builtinSymbols.insert(char_); + char_.type = char_; builtinSymbols.insert(dchar_); + dchar_.type = dchar_; builtinSymbols.insert(short_); + short_.type = short_; builtinSymbols.insert(ubyte_); + ubyte_.type = ubyte_; builtinSymbols.insert(uint_); + uint_.type = uint_; builtinSymbols.insert(ulong_); + ulong_.type = ulong_; builtinSymbols.insert(ushort_); + ushort_.type = ushort_; builtinSymbols.insert(wchar_); + wchar_.type = wchar_; builtinSymbols.insert(cdouble_); + cdouble_.type = cdouble_; builtinSymbols.insert(cent_); + cent_.type = cent_; builtinSymbols.insert(cfloat_); + cfloat_.type = cfloat_; builtinSymbols.insert(creal_); + creal_.type = creal_; builtinSymbols.insert(double_); + double_.type = double_; builtinSymbols.insert(float_); + float_.type = float_; builtinSymbols.insert(idouble_); + idouble_.type = idouble_; builtinSymbols.insert(ifloat_); + ifloat_.type = ifloat_; builtinSymbols.insert(ireal_); + ireal_.type = ireal_; builtinSymbols.insert(real_); + real_.type = real_; builtinSymbols.insert(ucent_); + ucent_.type = ucent_; builtinSymbols.insert(void_); + void_.type = void_; // writeln(">>Builtin symbols"); // foreach (symbol; builtinSymbols[]) diff --git a/autocomplete.d b/autocomplete.d index 7adfe57..12eab8f 100644 --- a/autocomplete.d +++ b/autocomplete.d @@ -571,7 +571,6 @@ T getExpression(T)(T beforeTokens) size_t i = beforeTokens.length - 1; IdType open; IdType close; - bool hasSpecialPrefix = false; expressionLoop: while (true) { switch (beforeTokens[i].type) @@ -603,15 +602,9 @@ T getExpression(T)(T beforeTokens) case tok!"creal": case tok!"this": case tok!"identifier": - if (hasSpecialPrefix) - i++; break; case tok!".": break; - case tok!"*": - case tok!"&": - hasSpecialPrefix = true; - break; case tok!")": open = tok!")"; close = tok!"("; @@ -653,8 +646,6 @@ T getExpression(T)(T beforeTokens) } break; default: - if (hasSpecialPrefix) - i++; i++; break expressionLoop; } @@ -676,15 +667,15 @@ void setImportCompletions(T)(T tokens, ref AutocompleteResponse response) { response.completionType = CompletionType.identifiers; auto moduleParts = tokens.filter!(a => a.type == tok!"identifier").map!("a.text").array(); - if (moduleParts.length == 0) - return; string path = buildPath(moduleParts); + foreach (importDirectory; ModuleCache.getImportPaths()) { string p = buildPath(importDirectory, path); Log.trace("Checking for ", p); if (!exists(p)) continue; + foreach (string name; dirEntries(p, SpanMode.shallow)) { if (isFile(name) && (name.endsWith(".d") || name.endsWith(".di"))) diff --git a/client.d b/client.d index bb7a6d8..5c3469a 100644 --- a/client.d +++ b/client.d @@ -57,6 +57,8 @@ int main(string[] args) return 1; } + AutocompleteRequest request; + if (help) { printHelp(args[0]); @@ -64,7 +66,6 @@ int main(string[] args) } else if (shutdown || clearCache) { - AutocompleteRequest request; if (shutdown) request.kind = RequestKind.shutdown; else if (clearCache) @@ -75,12 +76,16 @@ int main(string[] args) } else if (importPaths.length > 0) { - AutocompleteRequest request; - request.kind = RequestKind.addImport; + request.kind |= RequestKind.addImport; request.importPaths = importPaths.map!(a => absolutePath(a)).array; - TcpSocket socket = createSocket(port); - scope (exit) { socket.shutdown(SocketShutdown.BOTH); socket.close(); } - return sendRequest(socket, request) ? 0 : 1; + if (cursorPos == size_t.max) + { + TcpSocket socket = createSocket(port); + scope (exit) { socket.shutdown(SocketShutdown.BOTH); socket.close(); } + if (!sendRequest(socket, request)) + return 1; + return 0; + } } else if (cursorPos == size_t.max) { @@ -116,18 +121,17 @@ int main(string[] args) f.rawRead(sourceCode); } - // Create message - AutocompleteRequest request; request.fileName = fileName; request.importPaths = importPaths; request.sourceCode = sourceCode; request.cursorPosition = cursorPos; + if (symbolLocation) - request.kind = RequestKind.symbolLocation; + request.kind |= RequestKind.symbolLocation; else if (doc) - request.kind = RequestKind.doc; + request.kind |= RequestKind.doc; else - request.kind = RequestKind.autocomplete; + request.kind |= RequestKind.autocomplete; // Send message to server TcpSocket socket = createSocket(port); diff --git a/conversion/second.d b/conversion/second.d index 3577288..a7362e4 100644 --- a/conversion/second.d +++ b/conversion/second.d @@ -45,6 +45,7 @@ public: void run() { + rootSymbol.acSymbol.parts.insert(builtinSymbols[]); assignToScopes(rootSymbol.acSymbol); resolveImports(moduleScope); } @@ -62,8 +63,8 @@ private: s.symbols.insert(currentSymbol); foreach (part; currentSymbol.parts[]) { - std.utf.validate(part.name); - assignToScopes(part); + if (part.kind != CompletionKind.keyword) + assignToScopes(part); } } diff --git a/conversion/third.d b/conversion/third.d index 59bee29..9d34561 100644 --- a/conversion/third.d +++ b/conversion/third.d @@ -149,9 +149,8 @@ private: else if (t.type2.symbol !is null) { // TODO: global scoped symbol handling - string[] symbolParts = cast(string[]) Mallocator.it.allocate( - t.type2.symbol.identifierOrTemplateChain.identifiersOrTemplateInstances.length - * string.sizeof); + size_t l = t.type2.symbol.identifierOrTemplateChain.identifiersOrTemplateInstances.length; + string[] symbolParts = (cast(string*) Mallocator.it.allocate(l * string.sizeof))[0 .. l]; scope(exit) Mallocator.it.deallocate(symbolParts); expandSymbol(symbolParts, t.type2.symbol.identifierOrTemplateChain); auto symbols = moduleScope.getSymbolsByNameAndCursor( @@ -179,7 +178,10 @@ private: { auto identOrTemplate = chain.identifiersOrTemplateInstances[i]; if (identOrTemplate is null) + { + strings[i] = null; continue; + } strings[i] = internString(identOrTemplate.templateInstance is null ? identOrTemplate.identifier.text : identOrTemplate.templateInstance.identifier.text); diff --git a/dscanner b/dscanner index 25f0d93..f54f782 160000 --- a/dscanner +++ b/dscanner @@ -1 +1 @@ -Subproject commit 25f0d93b90cf039577ed2fb7091efd18770dc06c +Subproject commit f54f7823dc62c14b7afb6b7db6e7693e79be34fa diff --git a/messages.d b/messages.d index 841b71d..70d2f59 100644 --- a/messages.d +++ b/messages.d @@ -111,18 +111,19 @@ enum CompletionType : string */ enum RequestKind : ubyte { + uninitialized = 0b00000000, /// Autocompletion - autocomplete, + autocomplete = 0b00000001, /// Clear the completion cache - clearCache, + clearCache = 0b00000010, /// Add import directory to server - addImport, + addImport = 0b00000100, /// Shut down the server - shutdown, + shutdown = 0b00001000, /// Get declaration location of given symbol - symbolLocation, + symbolLocation = 0b00010000, /// Get the doc comments for the symbol - doc + doc = 0b00100000, } /** diff --git a/modulecache.d b/modulecache.d index 05177a5..d3ef1fb 100644 --- a/modulecache.d +++ b/modulecache.d @@ -141,7 +141,10 @@ struct ModuleCache import std.stdio; import std.typecons; File f = File(cachedLocation); - ubyte[] source = cast(ubyte[]) Mallocator.it.allocate(cast(size_t)f.size); + immutable fileSize = cast(size_t)f.size; + if (fileSize == 0) + return symbols; + ubyte[] source = cast(ubyte[]) Mallocator.it.allocate(fileSize); f.rawRead(source); LexerConfig config; config.fileName = cachedLocation; diff --git a/server.d b/server.d index 27349b1..f630d45 100644 --- a/server.d +++ b/server.d @@ -145,32 +145,28 @@ int main(string[] args) AutocompleteRequest request; msgpack.unpack(buffer[size_t.sizeof .. bytesReceived], request); - final switch (request.kind) + if (request.kind & RequestKind.clearCache) { - case RequestKind.addImport: - ModuleCache.addImportPaths(request.importPaths); - break; - case RequestKind.clearCache: Log.info("Clearing cache."); ModuleCache.clear(); - break; - case RequestKind.shutdown: + } + else if (request.kind & RequestKind.shutdown) + { Log.info("Shutting down."); break serverLoop; - case RequestKind.autocomplete: -// try -// { - AutocompleteResponse response = complete(request); - ubyte[] responseBytes = msgpack.pack(response); - s.send(responseBytes); -// } -// catch (Exception e) -// { -// Log.error("Could not handle autocomplete request due to an exception:", -// e.msg); -// } - break; - case RequestKind.doc: + } + if (request.kind & RequestKind.addImport) + ModuleCache.addImportPaths(request.importPaths); + else if (request.kind & RequestKind.autocomplete) + { + Log.info("Getting completions"); + AutocompleteResponse response = complete(request); + ubyte[] responseBytes = msgpack.pack(response); + s.send(responseBytes); + } + else if (request.kind & RequestKind.doc) + { + Log.info("Getting doc comment"); try { AutocompleteResponse response = getDoc(request); @@ -181,9 +177,9 @@ int main(string[] args) { Log.error("Could not get DDoc information", e.msg); } - - break; - case RequestKind.symbolLocation: + } + else if (request.kind & RequestKind.symbolLocation) + { try { AutocompleteResponse response = findDeclaration(request); @@ -194,8 +190,9 @@ int main(string[] args) { Log.error("Could not get symbol location", e.msg); } - break; } + else + Log.error("Unknown request type"); Log.info("Request processed in ", requestWatch.peek().to!("msecs", float), " milliseconds"); } return 0; diff --git a/string_interning.d b/string_interning.d index 244e5e1..60dd18b 100644 --- a/string_interning.d +++ b/string_interning.d @@ -18,7 +18,7 @@ module string_interning; -import std.lexer; +import std.d.lexer; string internString(string s) {