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);
|
||||
|
||||
thirdPass(first.moduleScope, cache, cursorPosition);
|
||||
thirdPass(first.rootSymbol, first.moduleScope, cache, 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:
|
||||
|
||||
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)
|
||||
{
|
||||
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 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);
|
||||
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