diff --git a/dsymbol/src/dsymbol/conversion/package.d b/dsymbol/src/dsymbol/conversion/package.d index d2774af..6b0df50 100644 --- a/dsymbol/src/dsymbol/conversion/package.d +++ b/dsymbol/src/dsymbol/conversion/package.d @@ -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); diff --git a/dsymbol/src/dsymbol/conversion/second.d b/dsymbol/src/dsymbol/conversion/second.d index 5eb2f97..a7b3580 100644 --- a/dsymbol/src/dsymbol/conversion/second.d +++ b/dsymbol/src/dsymbol/conversion/second.d @@ -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 diff --git a/dsymbol/src/dsymbol/conversion/third.d b/dsymbol/src/dsymbol/conversion/third.d index 88b7cd3..1148dac 100644 --- a/dsymbol/src/dsymbol/conversion/third.d +++ b/dsymbol/src/dsymbol/conversion/third.d @@ -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); } /**