Import directories are handled much better now

This commit is contained in:
Hackerpilot 2013-08-11 14:38:56 +00:00
parent 126e101e78
commit fe11e9d359
5 changed files with 102 additions and 44 deletions

View File

@ -23,6 +23,10 @@ import stdx.d.parser;
import stdx.d.ast;
import stdx.d.lexer;
import std.stdio;
import std.algorithm;
import std.path;
import std.range;
import std.conv;
import actypes;
import messages;
@ -34,6 +38,7 @@ class AutocompleteVisitor : ASTVisitor
override void visit(Unittest dec)
{
// writeln("Unitttest visit");
auto symbol = new ACSymbol("*unittest*");
auto p = parentSymbol;
parentSymbol = symbol;
@ -43,6 +48,7 @@ class AutocompleteVisitor : ASTVisitor
override void visit(StructDeclaration dec)
{
// writeln("StructDeclaration visit");
auto symbol = new ACSymbol;
symbol.name = dec.name.value;
symbol.location = dec.name.startIndex;
@ -52,6 +58,7 @@ class AutocompleteVisitor : ASTVisitor
override void visit(ClassDeclaration dec)
{
// writeln("ClassDeclaration visit");
auto symbol = new ACSymbol;
symbol.name = dec.name.value;
symbol.location = dec.name.startIndex;
@ -61,6 +68,7 @@ class AutocompleteVisitor : ASTVisitor
override void visit(InterfaceDeclaration dec)
{
// writeln("InterfaceDeclaration visit");
auto symbol = new ACSymbol;
symbol.name = dec.name.value;
symbol.location = dec.name.startIndex;
@ -70,6 +78,7 @@ class AutocompleteVisitor : ASTVisitor
override void visit(StructBody structBody)
{
// writeln("StructBody visit");
auto s = scope_;
scope_ = new Scope(structBody.startLocation, structBody.endLocation);
scope_.symbols ~= new ACSymbol("this", CompletionKind.variableName,
@ -82,17 +91,43 @@ class AutocompleteVisitor : ASTVisitor
override void visit(EnumDeclaration dec)
{
// TODO: Store type
// writeln("EnumDeclaration visit");
auto symbol = new ACSymbol;
symbol.name = dec.name.value;
symbol.location = dec.name.startIndex;
symbol.kind = CompletionKind.enumName;
mixin (visitAndAdd);
auto type = dec.type;
auto p = parentSymbol;
parentSymbol = symbol;
if (dec.enumBody !is null)
{
foreach (member; dec.enumBody.enumMembers)
{
auto s = new ACSymbol;
s.kind = CompletionKind.enumMember;
s.name = member.name.value;
s.location = member.name.startIndex;
if (type is null)
s.resolvedType = scope_.findSymbolInScope("int");
else
s.type = type;
if (parentSymbol !is null)
parentSymbol.parts ~= s;
}
}
parentSymbol = p;
if (parentSymbol is null)
symbols ~= symbol;
else
parentSymbol.parts ~= symbol;
scope_.symbols ~= symbol;
}
override void visit(FunctionDeclaration dec)
{
// TODO: Parameters need to be added to the function body scope
// writeln("FunctionDeclaration visit");
ACSymbol symbol = new ACSymbol;
symbol.name = dec.name.value;
symbol.location = dec.name.startIndex;
@ -115,13 +150,14 @@ class AutocompleteVisitor : ASTVisitor
}
// writeln("Parameter symbols added");
if (dec.returnType !is null)
if (dec.returnType !is null && dec.parameters !is null)
{
symbol.calltip = format("%s %s%s", dec.returnType.toString(),
dec.name.value, dec.parameters.toString());
}
auto p = parentSymbol;
parentSymbol = symbol;
// writeln("Call tip created");
BlockStatement functionBody = dec.functionBody is null ? null
: (dec.functionBody.bodyStatement !is null
@ -153,18 +189,9 @@ class AutocompleteVisitor : ASTVisitor
scope_.symbols ~= symbol;
}
override void visit(EnumMember member)
{
auto s = new ACSymbol;
s.kind = CompletionKind.enumMember;
s.name = member.name.value;
s.location = member.name.startIndex;
if (parentSymbol !is null)
parentSymbol.parts ~= s;
}
override void visit(VariableDeclaration dec)
{
// writeln("VariableDeclaration visit");
foreach (d; dec.declarators)
{
auto symbol = new ACSymbol;
@ -216,17 +243,7 @@ class AutocompleteVisitor : ASTVisitor
private static string convertChainToImportPath(IdentifierChain chain)
{
string rVal;
bool first = true;
foreach (identifier; chain.identifiers)
{
if (!first)
rVal ~= "/";
rVal ~= identifier.value;
first = false;
}
rVal ~= ".d";
return rVal;
return to!string(chain.identifiers.map!"a.value"().join(dirSeparator).array) ~ ".d";
}
ACSymbol[] symbols;

View File

@ -22,6 +22,9 @@ import std.socket;
import std.stdio;
import std.getopt;
import std.array;
import std.process;
import std.algorithm;
import std.path;
import msgpack;
import messages;
@ -51,8 +54,7 @@ int main(string[] args)
printHelp(args[0]);
return 0;
}
if (shutdown || clearCache)
else if (shutdown || clearCache)
{
AutocompleteRequest request;
if (shutdown)
@ -71,10 +73,26 @@ int main(string[] args)
messageBuffer[8 .. $] = message[];
return socket.send(messageBuffer) == messageBuffer.length ? 0 : 1;
}
// cursor position is a required argument
if (cursorPos == size_t.max)
else if (importPaths.length > 0)
{
AutocompleteRequest request;
request.kind = RequestKind.addImport;
request.importPaths = importPaths.map!(a => isRooted(a) ? a : absolutePath(a)).array;
auto socket = new TcpSocket(AddressFamily.INET);
scope (exit) { socket.shutdown(SocketShutdown.BOTH); socket.close(); }
socket.connect(new InternetAddress("127.0.0.1", port));
socket.blocking = true;
socket.setOption(SocketOptionLevel.TCP, SocketOption.TCP_NODELAY, 1);
ubyte[] message = msgpack.pack(request);
ubyte[] messageBuffer = new ubyte[message.length + message.length.sizeof];
auto messageLength = message.length;
messageBuffer[0 .. 8] = (cast(ubyte*) &messageLength)[0 .. 8];
messageBuffer[8 .. $] = message[];
return socket.send(messageBuffer) == messageBuffer.length ? 0 : 1;
}
else if (cursorPos == size_t.max)
{
// cursor position is a required argument
printHelp(args[0]);
return 1;
}
@ -114,7 +132,7 @@ int main(string[] args)
scope (exit) { socket.shutdown(SocketShutdown.BOTH); socket.close(); }
socket.connect(new InternetAddress("127.0.0.1", port));
socket.blocking = true;
socket.setOption(SocketOptionLevel.TCP, SocketOption.TCP_NODELAY, 1);
//socket.setOption(SocketOptionLevel.TCP, SocketOption.TCP_NODELAY, 1);
ubyte[] messageBuffer = new ubyte[message.length + message.length.sizeof];
auto messageLength = message.length;
messageBuffer[0 .. 8] = (cast(ubyte*) &messageLength)[0 .. 8];

View File

@ -75,7 +75,6 @@ function M.autocomplete(ch)
local command = M.PATH_TO_DCD_CLIENT .. " -c" .. buffer.current_pos .. " " .. fileName
local p = io.popen(command, "r")
local r = p:read("*a")
print(r)
if r ~= "\n" then
if r:match("^identifiers.*") then
showCompletionList(r)

View File

@ -25,6 +25,7 @@ import stdx.d.parser;
import stdx.d.ast;
import std.stdio;
import std.array;
import std.path;
import acvisitor;
import actypes;
@ -56,6 +57,11 @@ struct ModuleCache
static void addImportPath(string path)
{
importPaths ~= path;
foreach (fileName; dirEntries(path, "*.{d,di}", SpanMode.depth))
{
writeln("Loading and caching completions for ", fileName);
getSymbolsInModule(fileName);
}
}
/**
@ -73,6 +79,9 @@ struct ModuleCache
if (!needsReparsing(location))
return cache[location].symbols;
auto visitor = new AutocompleteVisitor;
try
{
File f = File(location);
ubyte[] source = uninitializedArray!(ubyte[])(f.size);
f.rawRead(source);
@ -80,9 +89,15 @@ struct ModuleCache
LexerConfig config;
auto tokens = source.byToken(config).array();
Module mod = parseModule(tokens, location, &doesNothing);
auto visitor = new AutocompleteVisitor;
visitor.visit(mod);
visitor.scope_.resolveSymbolTypes();
}
catch (Exception ex)
{
writeln("Couln't parse ", location);
return [];
}
SysTime access;
SysTime modification;
getTimes(location, access, modification);
@ -103,6 +118,9 @@ struct ModuleCache
static string resolveImportLoctation(string moduleName)
{
writeln("Resolving location of ", moduleName);
if (isRooted(moduleName))
return moduleName;
foreach (path; importPaths)
{
string filePath = path ~ "/" ~ moduleName;

View File

@ -64,8 +64,10 @@ int main(string[] args)
socket.listen(0);
scope (exit)
{
writeln("Shutting down sockets...");
socket.shutdown(SocketShutdown.BOTH);
socket.close();
writeln("Sockets shut down.");
}
ubyte[1024 * 1024 * 4] buffer = void; // 4 megabytes should be enough for anybody...
while (true)
@ -102,7 +104,11 @@ int main(string[] args)
msgpack.unpack(buffer[8 .. bytesReceived], request);
if (request.kind == RequestKind.addImport)
{
//ModuleCache.addImportPath();
foreach (path; request.importPaths)
{
ModuleCache.addImportPath(path);
}
}
else if (request.kind == RequestKind.clearCache)
{