Properly implement pointer types
- special DCD pointer symbols are actually inserted now - they are implicitly dereferenced (max 1 deref) for member access - index accessing them yields proper types (one pointer removed) - they return standard type properties on pointer pointers
This commit is contained in:
parent
795ea87f80
commit
690d6254db
|
@ -40,6 +40,11 @@ TTree!(DSymbol*, SymbolsAllocator, true, "a < b") classSymbols;
|
||||||
*/
|
*/
|
||||||
TTree!(DSymbol*, SymbolsAllocator, true, "a < b") enumSymbols;
|
TTree!(DSymbol*, SymbolsAllocator, true, "a < b") enumSymbols;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Pointer properties (when not implicitly dereferencing)
|
||||||
|
*/
|
||||||
|
TTree!(DSymbol*, SymbolsAllocator, true, "a < b") pointerSymbols;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Variadic template parameters properties
|
* Variadic template parameters properties
|
||||||
*/
|
*/
|
||||||
|
@ -191,6 +196,12 @@ static this()
|
||||||
aggregateSymbols.insert(stringof_);
|
aggregateSymbols.insert(stringof_);
|
||||||
aggregateSymbols.insert(init);
|
aggregateSymbols.insert(init);
|
||||||
|
|
||||||
|
pointerSymbols.insert(mangleof_);
|
||||||
|
pointerSymbols.insert(alignof_);
|
||||||
|
pointerSymbols.insert(sizeof_);
|
||||||
|
pointerSymbols.insert(stringof_);
|
||||||
|
pointerSymbols.insert(init);
|
||||||
|
|
||||||
classSymbols.insert(makeSymbol("classinfo", CompletionKind.variableName));
|
classSymbols.insert(makeSymbol("classinfo", CompletionKind.variableName));
|
||||||
classSymbols.insert(tupleof);
|
classSymbols.insert(tupleof);
|
||||||
classSymbols.insert(makeSymbol("__vptr", CompletionKind.variableName));
|
classSymbols.insert(makeSymbol("__vptr", CompletionKind.variableName));
|
||||||
|
@ -283,6 +294,7 @@ static ~this()
|
||||||
destroy(aggregateSymbols);
|
destroy(aggregateSymbols);
|
||||||
destroy(classSymbols);
|
destroy(classSymbols);
|
||||||
destroy(enumSymbols);
|
destroy(enumSymbols);
|
||||||
|
destroy(pointerSymbols);
|
||||||
|
|
||||||
foreach (sym; symbolsMadeHere[])
|
foreach (sym; symbolsMadeHere[])
|
||||||
destroy(*sym);
|
destroy(*sym);
|
||||||
|
|
|
@ -1129,9 +1129,7 @@ private:
|
||||||
|
|
||||||
foreach (suffix; type.typeSuffixes)
|
foreach (suffix; type.typeSuffixes)
|
||||||
{
|
{
|
||||||
if (suffix.star != tok!"")
|
if (suffix.type)
|
||||||
continue;
|
|
||||||
else if (suffix.type)
|
|
||||||
lookup.breadcrumbs.insert(ASSOC_ARRAY_SYMBOL_NAME);
|
lookup.breadcrumbs.insert(ASSOC_ARRAY_SYMBOL_NAME);
|
||||||
else if (suffix.array)
|
else if (suffix.array)
|
||||||
lookup.breadcrumbs.insert(ARRAY_SYMBOL_NAME);
|
lookup.breadcrumbs.insert(ARRAY_SYMBOL_NAME);
|
||||||
|
|
|
@ -180,29 +180,30 @@ do
|
||||||
while (!lookup.breadcrumbs.empty)
|
while (!lookup.breadcrumbs.empty)
|
||||||
{
|
{
|
||||||
auto back = lookup.breadcrumbs.back;
|
auto back = lookup.breadcrumbs.back;
|
||||||
immutable bool isArr = back == ARRAY_SYMBOL_NAME;
|
SymbolQualifier qualifier;
|
||||||
immutable bool isAssoc = back == ASSOC_ARRAY_SYMBOL_NAME;
|
if (back == ARRAY_SYMBOL_NAME) qualifier = SymbolQualifier.array;
|
||||||
immutable bool isFunction = back == FUNCTION_SYMBOL_NAME;
|
else if (back == ASSOC_ARRAY_SYMBOL_NAME) qualifier = SymbolQualifier.assocArray;
|
||||||
if (back == POINTER_SYMBOL_NAME)
|
else if (back == FUNCTION_SYMBOL_NAME) qualifier = SymbolQualifier.func;
|
||||||
{
|
else if (back == POINTER_SYMBOL_NAME) qualifier = SymbolQualifier.pointer;
|
||||||
lastSuffix.isPointer = true;
|
else break;
|
||||||
lookup.breadcrumbs.popBack();
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
if (!isArr && !isAssoc && !isFunction)
|
|
||||||
break;
|
|
||||||
immutable qualifier = isAssoc ? SymbolQualifier.assocArray
|
|
||||||
: (isFunction ? SymbolQualifier.func : SymbolQualifier.array);
|
|
||||||
lastSuffix = GCAllocator.instance.make!DSymbol(back, CompletionKind.dummy, lastSuffix);
|
lastSuffix = GCAllocator.instance.make!DSymbol(back, CompletionKind.dummy, lastSuffix);
|
||||||
lastSuffix.qualifier = qualifier;
|
lastSuffix.qualifier = qualifier;
|
||||||
lastSuffix.ownType = true;
|
lastSuffix.ownType = true;
|
||||||
if (isFunction)
|
|
||||||
|
final switch (qualifier)
|
||||||
{
|
{
|
||||||
|
case SymbolQualifier.none:
|
||||||
|
case SymbolQualifier.selectiveImport:
|
||||||
|
assert(false, "this should never be generated");
|
||||||
|
case SymbolQualifier.func:
|
||||||
lookup.breadcrumbs.popBack();
|
lookup.breadcrumbs.popBack();
|
||||||
lastSuffix.callTip = lookup.breadcrumbs.back();
|
lastSuffix.callTip = lookup.breadcrumbs.back();
|
||||||
|
break;
|
||||||
|
case SymbolQualifier.array: lastSuffix.addChildren(arraySymbols[], false); break;
|
||||||
|
case SymbolQualifier.assocArray: lastSuffix.addChildren(assocArraySymbols[], false); break;
|
||||||
|
case SymbolQualifier.pointer: lastSuffix.addChildren(pointerSymbols[], false); break;
|
||||||
}
|
}
|
||||||
else
|
|
||||||
lastSuffix.addChildren(isArr ? arraySymbols[] : assocArraySymbols[], false);
|
|
||||||
|
|
||||||
if (suffix is null)
|
if (suffix is null)
|
||||||
suffix = lastSuffix;
|
suffix = lastSuffix;
|
||||||
|
@ -454,9 +455,10 @@ void resolveTypeFromInitializer(DSymbol* symbol, TypeLookup* lookup,
|
||||||
if (currentSymbol is null)
|
if (currentSymbol is null)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
// Index expressions can be an array index or an AA index
|
// Index expressions can be on a pointer, an array or an AA
|
||||||
if (currentSymbol.qualifier == SymbolQualifier.array
|
if (currentSymbol.qualifier == SymbolQualifier.array
|
||||||
|| currentSymbol.qualifier == SymbolQualifier.assocArray
|
|| currentSymbol.qualifier == SymbolQualifier.assocArray
|
||||||
|
|| currentSymbol.qualifier == SymbolQualifier.pointer
|
||||||
|| currentSymbol.kind == CompletionKind.aliasName)
|
|| currentSymbol.kind == CompletionKind.aliasName)
|
||||||
{
|
{
|
||||||
if (currentSymbol.type !is null)
|
if (currentSymbol.type !is null)
|
||||||
|
|
|
@ -131,6 +131,8 @@ enum SymbolQualifier : ubyte
|
||||||
func,
|
func,
|
||||||
/// Selective import
|
/// Selective import
|
||||||
selectiveImport,
|
selectiveImport,
|
||||||
|
/// The symbol is a pointer
|
||||||
|
pointer,
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -228,6 +230,11 @@ struct DSymbol
|
||||||
return;
|
return;
|
||||||
visited.insert(cast(size_t) &this);
|
visited.insert(cast(size_t) &this);
|
||||||
|
|
||||||
|
// pointers are implicitly dereferenced on members (a single layer)
|
||||||
|
if (qualifier == SymbolQualifier.pointer
|
||||||
|
&& this.type.qualifier != SymbolQualifier.pointer)
|
||||||
|
return type.getParts!OR(name, app, visited, onlyOne);
|
||||||
|
|
||||||
if (name is null)
|
if (name is null)
|
||||||
{
|
{
|
||||||
foreach (part; parts[].filter!(a => a.name != IMPORT_SYMBOL_NAME))
|
foreach (part; parts[].filter!(a => a.name != IMPORT_SYMBOL_NAME))
|
||||||
|
@ -427,10 +434,14 @@ struct DSymbol
|
||||||
// dfmt off
|
// dfmt off
|
||||||
mixin(bitfields!(bool, "ownType", 1,
|
mixin(bitfields!(bool, "ownType", 1,
|
||||||
bool, "skipOver", 1,
|
bool, "skipOver", 1,
|
||||||
bool, "isPointer", 1,
|
ubyte, "", 6));
|
||||||
ubyte, "", 5));
|
|
||||||
// dfmt on
|
// dfmt on
|
||||||
|
|
||||||
|
deprecated bool isPointer()
|
||||||
|
{
|
||||||
|
return qualifier == SymbolQualifier.pointer;
|
||||||
|
}
|
||||||
|
|
||||||
/// Protection level for this symbol
|
/// Protection level for this symbol
|
||||||
IdType protection;
|
IdType protection;
|
||||||
|
|
||||||
|
|
|
@ -381,7 +381,8 @@ DSymbol*[] getSymbolsByTokenChain(T)(Scope* completionScope,
|
||||||
case tok!"[":
|
case tok!"[":
|
||||||
if (symbols.length == 0)
|
if (symbols.length == 0)
|
||||||
break loop;
|
break loop;
|
||||||
if (symbols[0].qualifier == SymbolQualifier.array)
|
if (symbols[0].qualifier == SymbolQualifier.array
|
||||||
|
|| symbols[0].qualifier == SymbolQualifier.pointer)
|
||||||
{
|
{
|
||||||
skip(tok!"[", tok!"]");
|
skip(tok!"[", tok!"]");
|
||||||
if (!isSliceExpression(tokens, i))
|
if (!isSliceExpression(tokens, i))
|
||||||
|
|
|
@ -0,0 +1,30 @@
|
||||||
|
identifiers
|
||||||
|
alignof k
|
||||||
|
init k
|
||||||
|
mangleof k
|
||||||
|
member v int member stdin 16 int
|
||||||
|
sizeof k
|
||||||
|
stringof k
|
||||||
|
tupleof k
|
||||||
|
identifiers
|
||||||
|
alignof k
|
||||||
|
init k
|
||||||
|
mangleof k
|
||||||
|
member v int member stdin 16 int
|
||||||
|
sizeof k
|
||||||
|
stringof k
|
||||||
|
tupleof k
|
||||||
|
identifiers
|
||||||
|
alignof k
|
||||||
|
init k
|
||||||
|
mangleof k
|
||||||
|
sizeof k
|
||||||
|
stringof k
|
||||||
|
identifiers
|
||||||
|
alignof k
|
||||||
|
init k
|
||||||
|
mangleof k
|
||||||
|
member v int member stdin 16 int
|
||||||
|
sizeof k
|
||||||
|
stringof k
|
||||||
|
tupleof k
|
|
@ -0,0 +1,28 @@
|
||||||
|
struct S
|
||||||
|
{
|
||||||
|
int member;
|
||||||
|
}
|
||||||
|
|
||||||
|
void test()
|
||||||
|
{
|
||||||
|
S itemA;
|
||||||
|
itemA.
|
||||||
|
}
|
||||||
|
|
||||||
|
void test2()
|
||||||
|
{
|
||||||
|
S* itemPtr = &itemA;
|
||||||
|
itemPtr.
|
||||||
|
}
|
||||||
|
|
||||||
|
void test3()
|
||||||
|
{
|
||||||
|
S** itemPtrPtr = &itemA;
|
||||||
|
itemPtrPtr.
|
||||||
|
}
|
||||||
|
|
||||||
|
void test3()
|
||||||
|
{
|
||||||
|
S** itemPtrPtr = &itemA;
|
||||||
|
itemPtrPtr[10].
|
||||||
|
}
|
|
@ -0,0 +1,8 @@
|
||||||
|
set -e
|
||||||
|
set -u
|
||||||
|
|
||||||
|
../../bin/dcd-client $1 file.d -x -c58 > actual1.txt
|
||||||
|
../../bin/dcd-client $1 file.d -x -c108 >> actual1.txt
|
||||||
|
../../bin/dcd-client $1 file.d -x -c165 >> actual1.txt
|
||||||
|
../../bin/dcd-client $1 file.d -x -c226 >> actual1.txt
|
||||||
|
diff actual1.txt expected1.txt --strip-trailing-cr
|
Loading…
Reference in New Issue