Merge duplicate implementations of skip in server

+ some code duplication removal
This commit is contained in:
WebFreak001 2017-08-24 21:31:40 +02:00
parent 843a7783c3
commit fa81ad2d59
5 changed files with 102 additions and 127 deletions

View File

@ -59,12 +59,8 @@ public AutocompleteResponse complete(const AutocompleteRequest request,
request.cursorPosition, stringCache, tokenArray);
if (beforeTokens.length >= 2)
{
if (beforeTokens[$ - 1] == tok!"(" || beforeTokens[$ - 1] == tok!"[")
{
return parenCompletion(beforeTokens, tokenArray, request.cursorPosition,
moduleCache);
}
else if (beforeTokens[$ - 1] == tok!",")
if (beforeTokens[$ - 1] == tok!"(" || beforeTokens[$ - 1] == tok!"["
|| beforeTokens[$ - 1] == tok!",")
{
immutable size_t end = goBackToOpenParen(beforeTokens);
if (end != size_t.max)
@ -80,7 +76,7 @@ public AutocompleteResponse complete(const AutocompleteRequest request,
beforeTokens = beforeTokens[$-1 .. $];
return dotCompletion(beforeTokens, tokenArray, request.cursorPosition,
moduleCache);
}
}
else
return importCompletion(beforeTokens, kind, moduleCache);
}
@ -122,16 +118,14 @@ AutocompleteResponse dotCompletion(T)(T beforeTokens, const(Token)[] tokenArray,
significantTokenType = tok!"identifier";
beforeTokens = beforeTokens[0 .. $ - 1];
}
else if (beforeTokens.length >= 2 && beforeTokens[$ - 1] == tok!".")
else if (beforeTokens.length >= 2 && beforeTokens[$ - 1] == tok!".")
significantTokenType = beforeTokens[$ - 2].type;
else
return response;
switch (significantTokenType)
{
case tok!"stringLiteral":
case tok!"wstringLiteral":
case tok!"dstringLiteral":
mixin(STRING_LITERAL_CASES);
foreach (symbol; arraySymbols)
{
response.completionKinds ~= symbol.kind;
@ -139,34 +133,9 @@ AutocompleteResponse dotCompletion(T)(T beforeTokens, const(Token)[] tokenArray,
}
response.completionType = CompletionType.identifiers;
break;
case tok!"int":
case tok!"uint":
case tok!"long":
case tok!"ulong":
case tok!"char":
case tok!"wchar":
case tok!"dchar":
case tok!"bool":
case tok!"byte":
case tok!"ubyte":
case tok!"short":
case tok!"ushort":
case tok!"cent":
case tok!"ucent":
case tok!"float":
case tok!"ifloat":
case tok!"cfloat":
case tok!"idouble":
case tok!"cdouble":
case tok!"double":
case tok!"real":
case tok!"ireal":
case tok!"creal":
case tok!"identifier":
mixin(TYPE_IDENT_CASES);
case tok!")":
case tok!"]":
case tok!"this":
case tok!"super":
auto allocator = scoped!(ASTAllocator)();
RollbackAllocator rba;
ScopeSymbolPair pair = generateAutocompleteTrees(tokenArray, allocator,
@ -227,7 +196,6 @@ AutocompleteResponse parenCompletion(T)(T beforeTokens,
break;
case tok!"characterLiteral":
case tok!"doubleLiteral":
case tok!"dstringLiteral":
case tok!"floatLiteral":
case tok!"identifier":
case tok!"idoubleLiteral":
@ -236,14 +204,13 @@ AutocompleteResponse parenCompletion(T)(T beforeTokens,
case tok!"irealLiteral":
case tok!"longLiteral":
case tok!"realLiteral":
case tok!"stringLiteral":
case tok!"uintLiteral":
case tok!"ulongLiteral":
case tok!"wstringLiteral":
case tok!"this":
case tok!"super":
case tok!")":
case tok!"]":
mixin(STRING_LITERAL_CASES);
auto allocator = scoped!(ASTAllocator)();
RollbackAllocator rba;
ScopeSymbolPair pair = generateAutocompleteTrees(tokenArray, allocator,

View File

@ -147,36 +147,15 @@ SymbolStuff getSymbolsForCompletion(const AutocompleteRequest request,
request.cursorPosition, type), pair.symbol, pair.scope_);
}
static void skip(alias O, alias C, T)(T t, ref size_t i)
{
int depth = 1;
while (i < t.length) switch (t[i].type)
{
case O:
i++;
depth++;
break;
case C:
i++;
depth--;
if (depth <= 0)
return;
break;
default:
i++;
break;
}
}
bool isSliceExpression(T)(T tokens, size_t index)
{
while (index < tokens.length) switch (tokens[index].type)
{
case tok!"[":
skip!(tok!"[", tok!"]")(tokens, index);
tokens.skipParen(index, tok!"[", tok!"]");
break;
case tok!"(":
skip!(tok!"(", tok!")")(tokens, index);
tokens.skipParen(index, tok!"(", tok!")");
break;
case tok!"]":
case tok!"}":
@ -200,22 +179,6 @@ DSymbol*[] getSymbolsByTokenChain(T)(Scope* completionScope,
//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
DSymbol*[] symbols;
if (tokens.length == 0)
@ -224,7 +187,8 @@ DSymbol*[] getSymbolsByTokenChain(T)(Scope* completionScope,
// e.g. (a.b!c).d
if (tokens[0] == tok!"(")
{
immutable j = skipEnd(tokens, 0, tok!"(", tok!")");
size_t j;
tokens.skipParen(j, tok!"(", tok!")");
symbols = getSymbolsByTokenChain(completionScope, tokens[1 .. j],
cursorPosition, completionType);
tokens = tokens[j + 1 .. $];
@ -307,7 +271,7 @@ DSymbol*[] getSymbolsByTokenChain(T)(Scope* completionScope,
{
void skip(IdType open, IdType close)
{
i = skipEnd(tokens, i, open, close);
tokens.skipParen(i, open, close);
}
switch (tokens[i].type)
@ -438,7 +402,7 @@ DSymbol*[] getSymbolsByTokenChain(T)(Scope* completionScope,
return symbols;
}
private enum TYPE_IDENT_AND_LITERAL_CASES = q{
enum TYPE_IDENT_CASES = q{
case tok!"int":
case tok!"uint":
case tok!"long":
@ -465,11 +429,16 @@ private enum TYPE_IDENT_AND_LITERAL_CASES = q{
case tok!"this":
case tok!"super":
case tok!"identifier":
};
enum STRING_LITERAL_CASES = q{
case tok!"stringLiteral":
case tok!"wstringLiteral":
case tok!"dstringLiteral":
};
enum TYPE_IDENT_AND_LITERAL_CASES = TYPE_IDENT_CASES ~ STRING_LITERAL_CASES;
/**
*
*/
@ -516,18 +485,7 @@ T getExpression(T)(T beforeTokens)
skip:
mixin (EXPRESSION_LOOP_BREAK);
immutable bookmark = i;
int depth = 1;
do
{
if (depth == 0 || i == 0)
break;
else
i--;
if (beforeTokens[i].type == open)
depth++;
else if (beforeTokens[i].type == close)
depth--;
} while (true);
beforeTokens.skipParenReverse(i, open, close);
skipCount++;
@ -622,11 +580,11 @@ bool isUdaExpression(T)(ref T tokens)
{
bool result;
ptrdiff_t skip;
ptrdiff_t i = tokens.length - 2;
auto i = cast(ptrdiff_t) tokens.length - 2;
if (i < 1)
return result;
// skips the UDA ctor
if (tokens[i].type == tok!")")
{
@ -650,7 +608,7 @@ bool isUdaExpression(T)(ref T tokens)
}
}
}
if (skip == 0)
{
// @UDA!SingleTemplateParameter
@ -665,10 +623,14 @@ bool isUdaExpression(T)(ref T tokens)
result = true;
}
}
return result;
}
/**
* Traverses a token slice in reverse to find the opening parentheses or square bracket
* that begins the block the last token is in.
*/
size_t goBackToOpenParen(T)(T beforeTokens)
in
{
@ -677,8 +639,6 @@ in
body
{
size_t i = beforeTokens.length - 1;
IdType open;
IdType close;
while (true) switch (beforeTokens[i].type)
{
case tok!",":
@ -706,36 +666,69 @@ body
case tok!"[":
return i + 1;
case tok!")":
open = tok!")";
close = tok!"(";
goto skip;
beforeTokens.skipParenReverse!true(i, tok!")", tok!"(");
break;
case tok!"}":
open = tok!"}";
close = tok!"{";
goto skip;
beforeTokens.skipParenReverse!true(i, tok!"}", tok!"{");
break;
case tok!"]":
open = tok!"]";
close = tok!"[";
skip:
if (i == 0)
return size_t.max;
else
i--;
int depth = 1;
do
{
if (depth == 0 || i == 0)
break;
else
i--;
if (beforeTokens[i].type == open)
depth++;
else if (beforeTokens[i].type == close)
depth--;
} while (true);
beforeTokens.skipParenReverse!true(i, tok!"]", tok!"[");
break;
default:
return size_t.max;
}
return size_t.max;
}
/**
* Skips blocks of parentheses until the starting block has been closed
*/
void skipParen(T)(T tokenSlice, ref size_t i, IdType open, IdType close)
{
if (i >= tokenSlice.length || tokenSlice.length <= 0)
return;
int depth = 1;
while (depth != 0 && i + 1 != tokenSlice.length)
{
i++;
if (tokenSlice[i].type == open)
depth++;
else if (tokenSlice[i].type == close)
depth--;
}
}
/**
* Skips blocks of parentheses in reverse until the starting block has been opened
*/
void skipParenReverse(bool before = false, T)(T beforeTokens, ref size_t i, IdType open, IdType close)
{
if (i == 0)
return;
int depth = 1;
while (depth != 0 && i != 0)
{
i--;
if (beforeTokens[i].type == open)
depth++;
else if (beforeTokens[i].type == close)
depth--;
}
static if (before)
if (i != 0)
i--;
}
///
unittest
{
Token[] t = [
Token(tok!"identifier"), Token(tok!"identifier"), Token(tok!"("),
Token(tok!"identifier"), Token(tok!"("), Token(tok!")"), Token(tok!",")
];
size_t i = t.length - 1;
skipParenReverse!false(t, i, tok!")", tok!"(");
assert(i == 2);
i = t.length - 1;
skipParenReverse!true(t, i, tok!")", tok!"(");
assert(i == 1);
}

View File

@ -0,0 +1,2 @@
calltips
void doStuff(int a, int b)

8
tests/tc058/file.d Normal file
View File

@ -0,0 +1,8 @@
void doStuff(int a, int b) { return; }
int getInt(int i, int[] b) { return i; }
int b(int a) { return a; }
void main(string[] args)
{
doStuff(getInt(1, [b(3)]),);
auto x = 10, 20;
}

5
tests/tc058/run.sh Executable file
View File

@ -0,0 +1,5 @@
set -e
set -u
../../bin/dcd-client $1 file.d -c161 > actual1.txt
diff actual1.txt expected1.txt