recache module if it wasn't parsed properly

This commit is contained in:
ryuukk 2023-01-28 05:31:21 +01:00
parent 4946d49abd
commit bf10114939
2 changed files with 18 additions and 5 deletions

View File

@ -146,7 +146,7 @@ struct ModuleCache
/** /**
* Caches the module at the given location * Caches the module at the given location
*/ */
DSymbol* cacheModule(string location) DSymbol* cacheModule(string location, bool reparse = false)
{ {
import std.stdio : File; import std.stdio : File;
@ -157,7 +157,7 @@ struct ModuleCache
if (recursionGuard.contains(&cachedLocation.data[0])) if (recursionGuard.contains(&cachedLocation.data[0]))
return null; return null;
if (!needsReparsing(cachedLocation)) if (!reparse && !needsReparsing(cachedLocation))
return getEntryFor(cachedLocation).symbol; return getEntryFor(cachedLocation).symbol;
recursionGuard.insert(&cachedLocation.data[0]); recursionGuard.insert(&cachedLocation.data[0]);

View File

@ -218,7 +218,7 @@ AutocompleteResponse dotCompletion(T)(T beforeTokens, const(Token)[] tokenArray,
RollbackAllocator rba; RollbackAllocator rba;
ScopeSymbolPair pair = generateAutocompleteTrees(tokenArray, &rba, cursorPosition, moduleCache); ScopeSymbolPair pair = generateAutocompleteTrees(tokenArray, &rba, cursorPosition, moduleCache);
scope(exit) pair.destroy(); scope(exit) pair.destroy();
response.setCompletions(pair.scope_, getExpression(beforeTokens), response.setCompletions(moduleCache, pair.scope_, getExpression(beforeTokens),
cursorPosition, CompletionType.identifiers, false, partial); cursorPosition, CompletionType.identifiers, false, partial);
break; break;
// these tokens before a "." mean "Module Scope Operator" // these tokens before a "." mean "Module Scope Operator"
@ -232,7 +232,7 @@ AutocompleteResponse dotCompletion(T)(T beforeTokens, const(Token)[] tokenArray,
RollbackAllocator rba; RollbackAllocator rba;
ScopeSymbolPair pair = generateAutocompleteTrees(tokenArray, &rba, 1, moduleCache); ScopeSymbolPair pair = generateAutocompleteTrees(tokenArray, &rba, 1, moduleCache);
scope(exit) pair.destroy(); scope(exit) pair.destroy();
response.setCompletions(pair.scope_, getExpression(beforeTokens), response.setCompletions(moduleCache, pair.scope_, getExpression(beforeTokens),
1, CompletionType.identifiers, false, partial); 1, CompletionType.identifiers, false, partial);
break; break;
default: default:
@ -304,7 +304,7 @@ AutocompleteResponse parenCompletion(T)(T beforeTokens,
ScopeSymbolPair pair = generateAutocompleteTrees(tokenArray, &rba, cursorPosition, moduleCache); ScopeSymbolPair pair = generateAutocompleteTrees(tokenArray, &rba, cursorPosition, moduleCache);
scope(exit) pair.destroy(); scope(exit) pair.destroy();
auto expression = getExpression(beforeTokens[0 .. $ - 1]); auto expression = getExpression(beforeTokens[0 .. $ - 1]);
response.setCompletions(pair.scope_, expression, response.setCompletions(moduleCache, pair.scope_, expression,
cursorPosition, CompletionType.calltips, beforeTokens[$ - 1] == tok!"["); cursorPosition, CompletionType.calltips, beforeTokens[$ - 1] == tok!"[");
break; break;
default: default:
@ -495,6 +495,7 @@ void setImportCompletions(T)(T tokens, ref AutocompleteResponse response,
* *
*/ */
void setCompletions(T)(ref AutocompleteResponse response, void setCompletions(T)(ref AutocompleteResponse response,
ref ModuleCache cache,
Scope* completionScope, T tokens, size_t cursorPosition, Scope* completionScope, T tokens, size_t cursorPosition,
CompletionType completionType, bool isBracket = false, string partial = null) CompletionType completionType, bool isBracket = false, string partial = null)
{ {
@ -558,6 +559,18 @@ void setCompletions(T)(ref AutocompleteResponse response,
DSymbol*[] symbols = getSymbolsByTokenChain(completionScope, tokens, DSymbol*[] symbols = getSymbolsByTokenChain(completionScope, tokens,
cursorPosition, completionType); cursorPosition, completionType);
// check if there isn't any symbol that is a variable
// if the type is null, that's because the module was cached
// but not parsed properly, that's due to problems like
// public import with cyclic references
// so let's recache the module properly
foreach(sym; symbols)
{
foreach (it; sym.opSlice())
if (it.kind == CompletionKind.variableName && it.type is null)
cache.cacheModule(it.symbolFile, true);
}
if (tokens.length > 2 && tokens[1] == tok!".") if (tokens.length > 2 && tokens[1] == tok!".")
{ {
symbols.getUFCSParenCompletion(completionScope, stringToken(tokens[0]), stringToken( symbols.getUFCSParenCompletion(completionScope, stringToken(tokens[0]), stringToken(