This commit is contained in:
ryuukk 2023-01-31 01:00:44 -08:00 committed by GitHub
commit 9bda62b4d2
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 94 additions and 22 deletions

View File

@ -359,28 +359,26 @@ final class FirstPass : ASTVisitor
dec.accept(this); dec.accept(this);
} }
override void visit(const Module mod) override void visit(const Module mod)
{ {
rootSymbol = allocateSemanticSymbol(null, CompletionKind.moduleName, rootSymbol = allocateSemanticSymbol(null, CompletionKind.moduleName,
symbolFile); symbolFile);
currentSymbol = rootSymbol; currentSymbol = rootSymbol;
moduleScope = GCAllocator.instance.make!Scope(0, uint.max); moduleScope = GCAllocator.instance.make!Scope(0, uint.max);
currentScope = moduleScope; currentScope = moduleScope;
auto objectLocation = cache.resolveImportLocation("object"); auto numResolved = cache.resolveImportLocations("object", (objectLocation) {
if (objectLocation is null) auto objectImport = allocateSemanticSymbol(IMPORT_SYMBOL_NAME,
warning("Could not locate object.d or object.di"); CompletionKind.importSymbol, objectLocation);
else objectImport.acSymbol.skipOver = true;
{ currentSymbol.addChild(objectImport, true);
auto objectImport = allocateSemanticSymbol(IMPORT_SYMBOL_NAME, currentScope.addSymbol(objectImport.acSymbol, false);
CompletionKind.importSymbol, objectLocation); });
objectImport.acSymbol.skipOver = true; if (numResolved == 0)
currentSymbol.addChild(objectImport, true); warning("Could not locate any object.d or object.di");
currentScope.addSymbol(objectImport.acSymbol, false); foreach (s; builtinSymbols[])
} currentScope.addSymbol(s, false);
foreach (s; builtinSymbols[]) mod.accept(this);
currentScope.addSymbol(s, false); }
mod.accept(this);
}
override void visit(const EnumDeclaration dec) override void visit(const EnumDeclaration dec)
{ {

View File

@ -329,6 +329,80 @@ struct ModuleCache
return alternative.length > 0 ? istring(alternative) : istring(null); return alternative.length > 0 ? istring(alternative) : istring(null);
} }
/**
* Params:
* moduleName = the name of the module being imported, in "a/b/c" style
* cb = the callback used to be called whenever a module is found,
* the absolute path is passed as parameter
* Returns:
* The number of resolved paths
*/
size_t resolveImportLocations(string moduleName, scope void delegate(istring) cb)
{
assert(moduleName !is null, "module name is null");
if (isRooted(moduleName))
{
cb(istring(moduleName));
return 1;
}
size_t count = 0;
string alternative;
foreach (importPath; importPaths[])
{
auto path = importPath.path;
// import path is a filename
// first check string if this is a feasable path (no filesystem usage)
if (path.stripExtension.endsWith(moduleName)
&& path.existsAnd!isFile)
{
// prefer exact import names above .di/package.d files
cb(istring(path));
count++;
}
// no exact matches and no .di/package.d matches either
else if (!alternative.length)
{
string dotDi = buildPath(path, moduleName) ~ ".di";
string dotD = dotDi[0 .. $ - 1];
string withoutSuffix = dotDi[0 .. $ - 3];
if (existsAnd!isFile(dotD))
{
cb(istring(dotD));
count++;
}
else if (existsAnd!isFile(dotDi))
alternative = dotDi;
else if (existsAnd!isDir(withoutSuffix))
{
string packagePath = buildPath(withoutSuffix, "package.di");
if (existsAnd!isFile(packagePath[0 .. $ - 1]))
alternative = packagePath[0 .. $ - 1];
else if (existsAnd!isFile(packagePath))
alternative = packagePath;
}
}
// we have a potential .di/package.d file but continue searching for
// exact .d file matches to use instead
else
{
string dotD = buildPath(path, moduleName) ~ ".d";
if (existsAnd!isFile(dotD))
{
cb(istring(dotD));
count++;
}
}
}
if (alternative.length > 0)
{
cb(istring(alternative));
count++;
alternative = "";
}
return count;
}
auto getImportPaths() const auto getImportPaths() const
{ {
return importPaths[].map!(a => a.path); return importPaths[].map!(a => a.path);