Fix #304
This commit is contained in:
parent
5832c0a538
commit
7cee649587
|
|
@ -756,11 +756,43 @@ bool isSliceExpression(T)(T tokens, size_t index)
|
||||||
DSymbol*[] getSymbolsByTokenChain(T)(Scope* completionScope,
|
DSymbol*[] getSymbolsByTokenChain(T)(Scope* completionScope,
|
||||||
T tokens, size_t cursorPosition, CompletionType completionType)
|
T tokens, size_t cursorPosition, CompletionType completionType)
|
||||||
{
|
{
|
||||||
|
//writeln(">>>");
|
||||||
|
//dumpTokens(tokens.release);
|
||||||
|
//writeln(">>>");
|
||||||
|
|
||||||
|
static size_t skipEnd(T tokenSlice, size_t i, IdType open, IdType close)
|
||||||
|
{
|
||||||
|
size_t j = i + 1;
|
||||||
|
for (int depth = 1; depth > 0 && j < tokenSlice.length; j++)
|
||||||
|
{
|
||||||
|
if (tokenSlice[j].type == open)
|
||||||
|
depth++;
|
||||||
|
else if (tokenSlice[j].type == close)
|
||||||
|
{
|
||||||
|
depth--;
|
||||||
|
if (depth == 0) break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return j;
|
||||||
|
}
|
||||||
|
|
||||||
// Find the symbol corresponding to the beginning of the chain
|
// Find the symbol corresponding to the beginning of the chain
|
||||||
DSymbol*[] symbols;
|
DSymbol*[] symbols;
|
||||||
if (tokens.length == 0)
|
if (tokens.length == 0)
|
||||||
return [];
|
return [];
|
||||||
if (tokens[0] == tok!"." && tokens.length > 1)
|
// Recurse in case the symbol chain starts with an expression in parens
|
||||||
|
// e.g. (a.b!c).d
|
||||||
|
if (tokens[0] == tok!"(")
|
||||||
|
{
|
||||||
|
immutable j = skipEnd(tokens, 0, tok!"(", tok!")");
|
||||||
|
symbols = getSymbolsByTokenChain(completionScope, tokens[1 .. j],
|
||||||
|
cursorPosition, completionType);
|
||||||
|
tokens = tokens[j + 1 .. $];
|
||||||
|
//writeln("<<<");
|
||||||
|
//dumpTokens(tokens.release);
|
||||||
|
//writeln("<<<");
|
||||||
|
}
|
||||||
|
else if (tokens[0] == tok!"." && tokens.length > 1)
|
||||||
{
|
{
|
||||||
tokens = tokens[1 .. $];
|
tokens = tokens[1 .. $];
|
||||||
symbols = completionScope.getSymbolsAtGlobalScope(stringToken(tokens[0]));
|
symbols = completionScope.getSymbolsAtGlobalScope(stringToken(tokens[0]));
|
||||||
|
|
@ -810,6 +842,7 @@ DSymbol*[] getSymbolsByTokenChain(T)(Scope* completionScope,
|
||||||
|
|
||||||
if (shouldSwapWithType(completionType, symbols[0].kind, 0, tokens.length - 1))
|
if (shouldSwapWithType(completionType, symbols[0].kind, 0, tokens.length - 1))
|
||||||
{
|
{
|
||||||
|
//trace("Swapping types");
|
||||||
if (symbols.length == 0 || symbols[0].type is null || symbols[0].type is symbols[0])
|
if (symbols.length == 0 || symbols[0].type is null || symbols[0].type is symbols[0])
|
||||||
return [];
|
return [];
|
||||||
else if (symbols[0].type.kind == CompletionKind.functionName)
|
else if (symbols[0].type.kind == CompletionKind.functionName)
|
||||||
|
|
@ -825,22 +858,11 @@ DSymbol*[] getSymbolsByTokenChain(T)(Scope* completionScope,
|
||||||
|
|
||||||
loop: for (size_t i = 1; i < tokens.length; i++)
|
loop: for (size_t i = 1; i < tokens.length; i++)
|
||||||
{
|
{
|
||||||
IdType open;
|
void skip(IdType open, IdType close)
|
||||||
IdType close;
|
|
||||||
void skip()
|
|
||||||
{
|
{
|
||||||
i++;
|
i = skipEnd(tokens, i, open, close);
|
||||||
for (int depth = 1; depth > 0 && i < tokens.length; i++)
|
|
||||||
{
|
|
||||||
if (tokens[i].type == open)
|
|
||||||
depth++;
|
|
||||||
else if (tokens[i].type == close)
|
|
||||||
{
|
|
||||||
depth--;
|
|
||||||
if (depth == 0) break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
switch (tokens[i].type)
|
switch (tokens[i].type)
|
||||||
{
|
{
|
||||||
case tok!"int":
|
case tok!"int":
|
||||||
|
|
@ -916,18 +938,22 @@ DSymbol*[] getSymbolsByTokenChain(T)(Scope* completionScope,
|
||||||
}
|
}
|
||||||
if (symbols.length == 0)
|
if (symbols.length == 0)
|
||||||
break loop;
|
break loop;
|
||||||
|
if (tokens[i].type == tok!"!")
|
||||||
|
{
|
||||||
|
i++;
|
||||||
|
if (tokens[i].type == tok!"(")
|
||||||
|
goto case;
|
||||||
|
else
|
||||||
|
i++;
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
case tok!"(":
|
case tok!"(":
|
||||||
open = tok!"(";
|
skip(tok!"(", tok!")");
|
||||||
close = tok!")";
|
|
||||||
skip();
|
|
||||||
break;
|
break;
|
||||||
case tok!"[":
|
case tok!"[":
|
||||||
open = tok!"[";
|
|
||||||
close = tok!"]";
|
|
||||||
if (symbols[0].qualifier == SymbolQualifier.array)
|
if (symbols[0].qualifier == SymbolQualifier.array)
|
||||||
{
|
{
|
||||||
skip();
|
skip(tok!"[", tok!"]");
|
||||||
if (!isSliceExpression(tokens, i))
|
if (!isSliceExpression(tokens, i))
|
||||||
{
|
{
|
||||||
symbols = symbols[0].type is null || symbols[0].type is symbols[0] ? [] : [symbols[0].type];
|
symbols = symbols[0].type is null || symbols[0].type is symbols[0] ? [] : [symbols[0].type];
|
||||||
|
|
@ -938,11 +964,11 @@ DSymbol*[] getSymbolsByTokenChain(T)(Scope* completionScope,
|
||||||
else if (symbols[0].qualifier == SymbolQualifier.assocArray)
|
else if (symbols[0].qualifier == SymbolQualifier.assocArray)
|
||||||
{
|
{
|
||||||
symbols = symbols[0].type is null || symbols[0].type is symbols[0] ? [] : [symbols[0].type];
|
symbols = symbols[0].type is null || symbols[0].type is symbols[0] ? [] : [symbols[0].type];
|
||||||
skip();
|
skip(tok!"[", tok!"]");
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
skip();
|
skip(tok!"[", tok!"]");
|
||||||
DSymbol*[] overloads;
|
DSymbol*[] overloads;
|
||||||
if (isSliceExpression(tokens, i))
|
if (isSliceExpression(tokens, i))
|
||||||
overloads = symbols[0].getPartsByName(internString("opSlice"));
|
overloads = symbols[0].getPartsByName(internString("opSlice"));
|
||||||
|
|
@ -1357,7 +1383,9 @@ bool shouldSwapWithType(CompletionType completionType, CompletionKind kind,
|
||||||
|| kind == CompletionKind.structName
|
|| kind == CompletionKind.structName
|
||||||
|| kind == CompletionKind.interfaceName
|
|| kind == CompletionKind.interfaceName
|
||||||
|| kind == CompletionKind.enumName
|
|| kind == CompletionKind.enumName
|
||||||
|| kind == CompletionKind.unionName)
|
|| kind == CompletionKind.unionName
|
||||||
|
|| kind == CompletionKind.templateName
|
||||||
|
|| kind == CompletionKind.keyword)
|
||||||
{
|
{
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
@ -1380,3 +1408,9 @@ istring stringToken()(auto ref const Token a)
|
||||||
{
|
{
|
||||||
return internString(a.text is null ? str(a.type) : a.text);
|
return internString(a.text is null ? str(a.type) : a.text);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//void dumpTokens(const Token[] tokens)
|
||||||
|
//{
|
||||||
|
//foreach (t; tokens)
|
||||||
|
//writeln(t.line, ":", t.column, " ", stringToken(t));
|
||||||
|
//}
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,9 @@
|
||||||
|
identifiers
|
||||||
|
T l
|
||||||
|
alignof k
|
||||||
|
bar f
|
||||||
|
init k
|
||||||
|
mangleof k
|
||||||
|
sizeof k
|
||||||
|
stringof k
|
||||||
|
tupleof k
|
||||||
|
|
@ -0,0 +1,9 @@
|
||||||
|
template Foo(T)
|
||||||
|
{
|
||||||
|
void bar();
|
||||||
|
}
|
||||||
|
|
||||||
|
void main(string[] args)
|
||||||
|
{
|
||||||
|
(Foo!int).
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,5 @@
|
||||||
|
set -e
|
||||||
|
set -u
|
||||||
|
|
||||||
|
../../bin/dcd-client $1 file.d -c78 > actual.txt
|
||||||
|
diff actual.txt expected.txt
|
||||||
Loading…
Reference in New Issue