|
17 | 17 | #include "swift/AST/Decl.h"
|
18 | 18 | #include "swift/AST/DiagnosticsFrontend.h"
|
19 | 19 | #include "swift/AST/DiagnosticsSema.h"
|
| 20 | +#include "swift/AST/Evaluator.h" |
| 21 | +#include "swift/AST/MacroDefinition.h" |
| 22 | +#include "swift/AST/PluginLoader.h" |
20 | 23 | #include "swift/AST/SourceFile.h"
|
| 24 | +#include "swift/AST/TypeCheckRequests.h" |
21 | 25 | #include "swift/Frontend/Frontend.h"
|
22 | 26 | #include "llvm/CAS/CASProvidingFileSystem.h"
|
23 | 27 | #include "llvm/CAS/CachingOnDiskFileSystem.h"
|
@@ -103,6 +107,21 @@ void ModuleDependencyInfo::addTestableImport(ImportPath::Module module) {
|
103 | 107 | dyn_cast<SwiftSourceModuleDependenciesStorage>(storage.get())->addTestableImport(module);
|
104 | 108 | }
|
105 | 109 |
|
| 110 | +void ModuleDependencyInfo::addMacroDependency(StringRef module, StringRef id, |
| 111 | + StringRef libraryPath, |
| 112 | + StringRef executablePath) { |
| 113 | + if (auto swiftSourceStorage = |
| 114 | + dyn_cast<SwiftSourceModuleDependenciesStorage>(storage.get())) |
| 115 | + swiftSourceStorage->addMacroDependency(module, id, libraryPath, |
| 116 | + executablePath); |
| 117 | + else if (auto swiftInterfaceStorage = |
| 118 | + dyn_cast<SwiftInterfaceModuleDependenciesStorage>(storage.get())) |
| 119 | + swiftInterfaceStorage->addMacroDependency(module, id, libraryPath, |
| 120 | + executablePath); |
| 121 | + else |
| 122 | + llvm_unreachable("Unexpected dependency kind"); |
| 123 | +} |
| 124 | + |
106 | 125 | bool ModuleDependencyInfo::isTestableImport(StringRef moduleName) const {
|
107 | 126 | if (auto swiftSourceDepStorage = getAsSwiftSourceModule())
|
108 | 127 | return swiftSourceDepStorage->testableImports.contains(moduleName);
|
@@ -132,33 +151,55 @@ void ModuleDependencyInfo::addModuleImport(
|
132 | 151 | SmallVector<Decl *, 32> decls;
|
133 | 152 | sf.getTopLevelDecls(decls);
|
134 | 153 | for (auto decl : decls) {
|
135 |
| - auto importDecl = dyn_cast<ImportDecl>(decl); |
136 |
| - if (!importDecl) |
137 |
| - continue; |
138 |
| - |
139 |
| - ImportPath::Builder scratch; |
140 |
| - auto realPath = importDecl->getRealModulePath(scratch); |
141 |
| - |
142 |
| - // Explicit 'Builtin' import is not a part of the module's |
143 |
| - // dependency set, does not exist on the filesystem, |
144 |
| - // and is resolved within the compiler during compilation. |
145 |
| - SmallString<64> importedModuleName; |
146 |
| - realPath.getString(importedModuleName); |
147 |
| - if (importedModuleName == BUILTIN_NAME) |
148 |
| - continue; |
149 |
| - |
150 |
| - // Ignore/diagnose tautological imports akin to import resolution |
151 |
| - if (!swift::dependencies::checkImportNotTautological( |
152 |
| - realPath, importDecl->getLoc(), sf, importDecl->isExported())) |
153 |
| - continue; |
| 154 | + if (auto importDecl = dyn_cast<ImportDecl>(decl)) { |
| 155 | + ImportPath::Builder scratch; |
| 156 | + auto realPath = importDecl->getRealModulePath(scratch); |
| 157 | + |
| 158 | + // Explicit 'Builtin' import is not a part of the module's |
| 159 | + // dependency set, does not exist on the filesystem, |
| 160 | + // and is resolved within the compiler during compilation. |
| 161 | + SmallString<64> importedModuleName; |
| 162 | + realPath.getString(importedModuleName); |
| 163 | + if (importedModuleName == BUILTIN_NAME) |
| 164 | + continue; |
154 | 165 |
|
155 |
| - addModuleImport(realPath, &alreadyAddedModules); |
| 166 | + // Ignore/diagnose tautological imports akin to import resolution |
| 167 | + if (!swift::dependencies::checkImportNotTautological( |
| 168 | + realPath, importDecl->getLoc(), sf, importDecl->isExported())) |
| 169 | + continue; |
156 | 170 |
|
157 |
| - // Additionally, keep track of which dependencies of a Source |
158 |
| - // module are `@Testable`. |
159 |
| - if (getKind() == swift::ModuleDependencyKind::SwiftSource && |
160 |
| - importDecl->isTestable()) |
161 |
| - addTestableImport(realPath); |
| 171 | + addModuleImport(realPath, &alreadyAddedModules); |
| 172 | + |
| 173 | + // Additionally, keep track of which dependencies of a Source |
| 174 | + // module are `@Testable`. |
| 175 | + if (getKind() == swift::ModuleDependencyKind::SwiftSource && |
| 176 | + importDecl->isTestable()) |
| 177 | + addTestableImport(realPath); |
| 178 | + } else if (auto macroDecl = dyn_cast<MacroDecl>(decl)) { |
| 179 | + auto macroDef = macroDecl->getDefinition(); |
| 180 | + auto &ctx = macroDecl->getASTContext(); |
| 181 | + if (macroDef.kind != MacroDefinition::Kind::External) |
| 182 | + continue; |
| 183 | + auto external = macroDef.getExternalMacro(); |
| 184 | + CompilerPluginLoadRequest loadRequest{¯oDecl->getASTContext(), |
| 185 | + external.moduleName}; |
| 186 | + CompilerPluginLoadResult loaded = |
| 187 | + evaluateOrDefault(macroDecl->getASTContext().evaluator, loadRequest, |
| 188 | + CompilerPluginLoadResult::error("request error")); |
| 189 | + PluginLoader &loader = ctx.getPluginLoader(); |
| 190 | + if (auto exe = loaded.getAsExecutablePlugin()) { |
| 191 | + // Lookup again to find the library path. |
| 192 | + const auto &entry = |
| 193 | + loader.lookupPluginByModuleName(external.moduleName); |
| 194 | + addMacroDependency(external.moduleName.str(), |
| 195 | + exe->getIdentity(), |
| 196 | + entry.libraryPath, entry.executablePath); |
| 197 | + } else if (auto plugin = loaded.getAsLibraryPlugin()) { |
| 198 | + addMacroDependency(external.moduleName.str(), |
| 199 | + plugin->getIdentity(), |
| 200 | + plugin->getLibraryPath(), /*executablePath=*/""); |
| 201 | + } |
| 202 | + } |
162 | 203 | }
|
163 | 204 |
|
164 | 205 | auto fileName = sf.getFilename();
|
@@ -482,58 +523,6 @@ void SwiftDependencyTracker::addCommonSearchPathDeps(
|
482 | 523 | // Add VFSOverlay file.
|
483 | 524 | for (auto &Overlay: Opts.VFSOverlayFiles)
|
484 | 525 | FS->status(Overlay);
|
485 |
| - |
486 |
| - // Add plugin dylibs from the toolchain only by look through the plugin search |
487 |
| - // directory. |
488 |
| - auto recordFiles = [&](StringRef Path) { |
489 |
| - std::error_code EC; |
490 |
| - for (auto I = FS->dir_begin(Path, EC); |
491 |
| - !EC && I != llvm::vfs::directory_iterator(); I = I.increment(EC)) { |
492 |
| - if (I->type() != llvm::sys::fs::file_type::regular_file) |
493 |
| - continue; |
494 |
| -#if defined(_WIN32) |
495 |
| - constexpr StringRef libPrefix{}; |
496 |
| - constexpr StringRef libSuffix = ".dll"; |
497 |
| -#else |
498 |
| - constexpr StringRef libPrefix = "lib"; |
499 |
| - constexpr StringRef libSuffix = LTDL_SHLIB_EXT; |
500 |
| -#endif |
501 |
| - StringRef filename = llvm::sys::path::filename(I->path()); |
502 |
| - if (filename.starts_with(libPrefix) && filename.ends_with(libSuffix)) |
503 |
| - FS->status(I->path()); |
504 |
| - } |
505 |
| - }; |
506 |
| - for (auto &entry : Opts.PluginSearchOpts) { |
507 |
| - switch (entry.getKind()) { |
508 |
| - |
509 |
| - // '-load-plugin-library <library path>'. |
510 |
| - case PluginSearchOption::Kind::LoadPluginLibrary: { |
511 |
| - auto &val = entry.get<PluginSearchOption::LoadPluginLibrary>(); |
512 |
| - FS->status(val.LibraryPath); |
513 |
| - break; |
514 |
| - } |
515 |
| - |
516 |
| - // '-load-plugin-executable <executable path>#<module name>, ...'. |
517 |
| - case PluginSearchOption::Kind::LoadPluginExecutable: { |
518 |
| - // We don't have executable plugin in toolchain. |
519 |
| - break; |
520 |
| - } |
521 |
| - |
522 |
| - // '-plugin-path <library search path>'. |
523 |
| - case PluginSearchOption::Kind::PluginPath: { |
524 |
| - auto &val = entry.get<PluginSearchOption::PluginPath>(); |
525 |
| - recordFiles(val.SearchPath); |
526 |
| - break; |
527 |
| - } |
528 |
| - |
529 |
| - // '-external-plugin-path <library search path>#<server path>'. |
530 |
| - case PluginSearchOption::Kind::ExternalPluginPath: { |
531 |
| - auto &val = entry.get<PluginSearchOption::ExternalPluginPath>(); |
532 |
| - recordFiles(val.SearchPath); |
533 |
| - break; |
534 |
| - } |
535 |
| - } |
536 |
| - } |
537 | 526 | }
|
538 | 527 |
|
539 | 528 | void SwiftDependencyTracker::startTracking() {
|
|
0 commit comments