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

View File

@ -329,6 +329,80 @@ struct ModuleCache
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
{
return importPaths[].map!(a => a.path);