run a lightweight version of second phase to make sure no symbols are left out
This commit is contained in:
parent
33fd0db07d
commit
953d32f2fa
|
@ -51,7 +51,7 @@ ScopeSymbolPair generateAutocompleteTrees(const(Token)[] tokens,
|
||||||
|
|
||||||
secondPass(first.rootSymbol, first.moduleScope, cache);
|
secondPass(first.rootSymbol, first.moduleScope, cache);
|
||||||
|
|
||||||
thirdPass(first.moduleScope, cache, cursorPosition);
|
thirdPass(first.rootSymbol, first.moduleScope, cache, cursorPosition);
|
||||||
|
|
||||||
auto ufcsSymbols = getUFCSSymbolsForCursor(first.moduleScope, tokens, cursorPosition);
|
auto ufcsSymbols = getUFCSSymbolsForCursor(first.moduleScope, tokens, cursorPosition);
|
||||||
|
|
||||||
|
|
|
@ -311,6 +311,97 @@ do
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void resolveTypeFromInitializer(DSymbol* symbol, TypeLookup* lookup,
|
||||||
|
Scope* moduleScope, ref ModuleCache cache)
|
||||||
|
{
|
||||||
|
if (lookup.breadcrumbs.length == 0)
|
||||||
|
return;
|
||||||
|
DSymbol* currentSymbol = null;
|
||||||
|
size_t i = 0;
|
||||||
|
|
||||||
|
auto crumbs = lookup.breadcrumbs[];
|
||||||
|
foreach (crumb; crumbs)
|
||||||
|
{
|
||||||
|
if (i == 0)
|
||||||
|
{
|
||||||
|
currentSymbol = moduleScope.getFirstSymbolByNameAndCursor(
|
||||||
|
symbolNameToTypeName(crumb), symbol.location);
|
||||||
|
|
||||||
|
if (currentSymbol is null)
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
else if (crumb == ARRAY_LITERAL_SYMBOL_NAME)
|
||||||
|
{
|
||||||
|
auto arr = GCAllocator.instance.make!(DSymbol)(ARRAY_LITERAL_SYMBOL_NAME, CompletionKind.dummy, currentSymbol);
|
||||||
|
arr.qualifier = SymbolQualifier.array;
|
||||||
|
currentSymbol = arr;
|
||||||
|
}
|
||||||
|
else if (crumb == ARRAY_SYMBOL_NAME)
|
||||||
|
{
|
||||||
|
typeSwap(currentSymbol);
|
||||||
|
if (currentSymbol is null)
|
||||||
|
return;
|
||||||
|
|
||||||
|
// Index expressions can be on a pointer, an array or an AA
|
||||||
|
if (currentSymbol.qualifier == SymbolQualifier.array
|
||||||
|
|| currentSymbol.qualifier == SymbolQualifier.assocArray
|
||||||
|
|| currentSymbol.qualifier == SymbolQualifier.pointer
|
||||||
|
|| currentSymbol.kind == CompletionKind.aliasName)
|
||||||
|
{
|
||||||
|
if (currentSymbol.type !is null)
|
||||||
|
currentSymbol = currentSymbol.type;
|
||||||
|
else
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
auto opIndex = currentSymbol.getFirstPartNamed(internString("opIndex"));
|
||||||
|
if (opIndex !is null)
|
||||||
|
currentSymbol = opIndex.type;
|
||||||
|
else
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (crumb == "foreach")
|
||||||
|
{
|
||||||
|
typeSwap(currentSymbol);
|
||||||
|
if (currentSymbol is null)
|
||||||
|
return;
|
||||||
|
if (currentSymbol.qualifier == SymbolQualifier.array
|
||||||
|
|| currentSymbol.qualifier == SymbolQualifier.assocArray)
|
||||||
|
{
|
||||||
|
currentSymbol = currentSymbol.type;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
auto front = currentSymbol.getFirstPartNamed(internString("front"));
|
||||||
|
if (front !is null)
|
||||||
|
{
|
||||||
|
currentSymbol = front.type;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
auto opApply = currentSymbol.getFirstPartNamed(internString("opApply"));
|
||||||
|
if (opApply !is null)
|
||||||
|
{
|
||||||
|
currentSymbol = opApply.type;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
typeSwap(currentSymbol);
|
||||||
|
if (currentSymbol is null)
|
||||||
|
return;
|
||||||
|
currentSymbol = currentSymbol.getFirstPartNamed(crumb);
|
||||||
|
}
|
||||||
|
++i;
|
||||||
|
if (currentSymbol is null)
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
typeSwap(currentSymbol);
|
||||||
|
symbol.type = currentSymbol;
|
||||||
|
symbol.ownType = false;
|
||||||
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
||||||
void resolveInheritance(DSymbol* symbol, ref TypeLookups typeLookups,
|
void resolveInheritance(DSymbol* symbol, ref TypeLookups typeLookups,
|
||||||
|
@ -425,97 +516,6 @@ void resolveType(DSymbol* symbol, ref TypeLookups typeLookups,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void resolveTypeFromInitializer(DSymbol* symbol, TypeLookup* lookup,
|
|
||||||
Scope* moduleScope, ref ModuleCache cache)
|
|
||||||
{
|
|
||||||
if (lookup.breadcrumbs.length == 0)
|
|
||||||
return;
|
|
||||||
DSymbol* currentSymbol = null;
|
|
||||||
size_t i = 0;
|
|
||||||
|
|
||||||
auto crumbs = lookup.breadcrumbs[];
|
|
||||||
foreach (crumb; crumbs)
|
|
||||||
{
|
|
||||||
if (i == 0)
|
|
||||||
{
|
|
||||||
currentSymbol = moduleScope.getFirstSymbolByNameAndCursor(
|
|
||||||
symbolNameToTypeName(crumb), symbol.location);
|
|
||||||
|
|
||||||
if (currentSymbol is null)
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
else if (crumb == ARRAY_LITERAL_SYMBOL_NAME)
|
|
||||||
{
|
|
||||||
auto arr = GCAllocator.instance.make!(DSymbol)(ARRAY_LITERAL_SYMBOL_NAME, CompletionKind.dummy, currentSymbol);
|
|
||||||
arr.qualifier = SymbolQualifier.array;
|
|
||||||
currentSymbol = arr;
|
|
||||||
}
|
|
||||||
else if (crumb == ARRAY_SYMBOL_NAME)
|
|
||||||
{
|
|
||||||
typeSwap(currentSymbol);
|
|
||||||
if (currentSymbol is null)
|
|
||||||
return;
|
|
||||||
|
|
||||||
// Index expressions can be on a pointer, an array or an AA
|
|
||||||
if (currentSymbol.qualifier == SymbolQualifier.array
|
|
||||||
|| currentSymbol.qualifier == SymbolQualifier.assocArray
|
|
||||||
|| currentSymbol.qualifier == SymbolQualifier.pointer
|
|
||||||
|| currentSymbol.kind == CompletionKind.aliasName)
|
|
||||||
{
|
|
||||||
if (currentSymbol.type !is null)
|
|
||||||
currentSymbol = currentSymbol.type;
|
|
||||||
else
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
auto opIndex = currentSymbol.getFirstPartNamed(internString("opIndex"));
|
|
||||||
if (opIndex !is null)
|
|
||||||
currentSymbol = opIndex.type;
|
|
||||||
else
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else if (crumb == "foreach")
|
|
||||||
{
|
|
||||||
typeSwap(currentSymbol);
|
|
||||||
if (currentSymbol is null)
|
|
||||||
return;
|
|
||||||
if (currentSymbol.qualifier == SymbolQualifier.array
|
|
||||||
|| currentSymbol.qualifier == SymbolQualifier.assocArray)
|
|
||||||
{
|
|
||||||
currentSymbol = currentSymbol.type;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
auto front = currentSymbol.getFirstPartNamed(internString("front"));
|
|
||||||
if (front !is null)
|
|
||||||
{
|
|
||||||
currentSymbol = front.type;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
auto opApply = currentSymbol.getFirstPartNamed(internString("opApply"));
|
|
||||||
if (opApply !is null)
|
|
||||||
{
|
|
||||||
currentSymbol = opApply.type;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
typeSwap(currentSymbol);
|
|
||||||
if (currentSymbol is null)
|
|
||||||
return;
|
|
||||||
currentSymbol = currentSymbol.getFirstPartNamed(crumb);
|
|
||||||
}
|
|
||||||
++i;
|
|
||||||
if (currentSymbol is null)
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
typeSwap(currentSymbol);
|
|
||||||
symbol.type = currentSymbol;
|
|
||||||
symbol.ownType = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
void typeSwap(ref DSymbol* currentSymbol)
|
void typeSwap(ref DSymbol* currentSymbol)
|
||||||
{
|
{
|
||||||
while (currentSymbol !is null && currentSymbol.type !is currentSymbol
|
while (currentSymbol !is null && currentSymbol.type !is currentSymbol
|
||||||
|
|
|
@ -34,10 +34,46 @@ import containers.hashset;
|
||||||
* If it is, then it'll set its type
|
* If it is, then it'll set its type
|
||||||
* If the symbol is not found, then it'll do nothing
|
* If the symbol is not found, then it'll do nothing
|
||||||
*/
|
*/
|
||||||
void thirdPass(Scope* mscope, ref ModuleCache cache, size_t cursorPosition)
|
void thirdPass(SemanticSymbol* root, Scope* mscope, ref ModuleCache cache, size_t cursorPosition)
|
||||||
{
|
{
|
||||||
auto desired = mscope.getScopeByCursor(cursorPosition);
|
auto desired = mscope.getScopeByCursor(cursorPosition);
|
||||||
tryResolve(desired, cache);
|
tryResolve(desired, cache);
|
||||||
|
|
||||||
|
// Check if there are any left out symbols
|
||||||
|
// Check issue 717 and test tc717
|
||||||
|
checkMissingTypes(root, mscope, cache);
|
||||||
|
}
|
||||||
|
|
||||||
|
void checkMissingTypes(SemanticSymbol* currentSymbol, Scope* moduleScope, ref ModuleCache cache)
|
||||||
|
{
|
||||||
|
import dsymbol.conversion.second;
|
||||||
|
import dsymbol.type_lookup;
|
||||||
|
|
||||||
|
with (CompletionKind) switch (currentSymbol.acSymbol.kind)
|
||||||
|
{
|
||||||
|
case withSymbol:
|
||||||
|
case variableName:
|
||||||
|
case memberVariableName:
|
||||||
|
case functionName:
|
||||||
|
case ufcsName:
|
||||||
|
case aliasName:
|
||||||
|
if (currentSymbol.acSymbol.type is null)
|
||||||
|
{
|
||||||
|
if (currentSymbol.typeLookups.length == 0)
|
||||||
|
break;
|
||||||
|
auto lookup = currentSymbol.typeLookups.front;
|
||||||
|
if (lookup.kind == TypeLookupKind.varOrFunType)
|
||||||
|
resolveTypeFromType(currentSymbol.acSymbol, lookup, moduleScope, cache, null);
|
||||||
|
else if (lookup.kind == TypeLookupKind.initializer)
|
||||||
|
resolveTypeFromInitializer(currentSymbol.acSymbol, lookup, moduleScope, cache);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
foreach (child; currentSymbol.children)
|
||||||
|
checkMissingTypes(child, moduleScope, cache);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
Loading…
Reference in New Issue