Skip to content

Commit bb97dc6

Browse files
authored
Merge pull request #65978 from rintaro/macros-plugin-searchorder-rdar109163929
[Macros] Rearrange plugin search order
2 parents 9d474bc + 3637885 commit bb97dc6

File tree

6 files changed

+195
-106
lines changed

6 files changed

+195
-106
lines changed

include/swift/AST/ASTContext.h

Lines changed: 0 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -1501,39 +1501,6 @@ class ASTContext final {
15011501
/// Get the plugin loader.
15021502
PluginLoader &getPluginLoader();
15031503

1504-
/// Lookup a library plugin that can handle \p moduleName and return the path
1505-
/// to it.
1506-
/// The path is valid within the VFS, use `FS.getRealPath()` for the
1507-
/// underlying path.
1508-
Optional<std::string> lookupLibraryPluginByModuleName(Identifier moduleName);
1509-
1510-
/// Load the specified dylib plugin path resolving the path with the
1511-
/// current VFS. If it fails to load the plugin, a diagnostic is emitted, and
1512-
/// returns a nullptr.
1513-
/// NOTE: This method is idempotent. If the plugin is already loaded, the same
1514-
/// instance is simply returned.
1515-
LoadedLibraryPlugin *loadLibraryPlugin(StringRef path);
1516-
1517-
/// Lookup an executable plugin that is declared to handle \p moduleName
1518-
/// module by '-load-plugin-executable'.
1519-
/// The path is valid within the VFS, use `FS.getRealPath()` for the
1520-
/// underlying path.
1521-
Optional<StringRef> lookupExecutablePluginByModuleName(Identifier moduleName);
1522-
1523-
/// Look for dynamic libraries in paths from `-external-plugin-path` and
1524-
/// return a pair of `(library path, plugin server executable)` if found.
1525-
/// These paths are valid within the VFS, use `FS.getRealPath()` for their
1526-
/// underlying path.
1527-
Optional<std::pair<std::string, std::string>>
1528-
lookupExternalLibraryPluginByModuleName(Identifier moduleName);
1529-
1530-
/// Launch the specified executable plugin path resolving the path with the
1531-
/// current VFS. If it fails to load the plugin, a diagnostic is emitted, and
1532-
/// returns a nullptr.
1533-
/// NOTE: This method is idempotent. If the plugin is already loaded, the same
1534-
/// instance is simply returned.
1535-
LoadedExecutablePlugin *loadExecutablePlugin(StringRef path);
1536-
15371504
/// Get the output backend. The output backend needs to be initialized via
15381505
/// constructor or `setOutputBackend`.
15391506
llvm::vfs::OutputBackend &getOutputBackend() const {

include/swift/AST/PluginLoader.h

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -53,10 +53,16 @@ class PluginLoader {
5353
PluginRegistry *getRegistry();
5454

5555
/// Lookup a library plugin that can handle \p moduleName and return the path
56-
/// to it from `-plugin-path` or `-load-plugin-library`.
56+
/// to it from `-load-plugin-library`.
5757
/// The path returned can be loaded by 'loadLibraryPlugin' method.
5858
llvm::Optional<std::string>
59-
lookupLibraryPluginByModuleName(Identifier moduleName);
59+
lookupExplicitLibraryPluginByModuleName(Identifier moduleName);
60+
61+
/// Lookup a library plugin that can handle \p moduleName and return the path
62+
/// to it from `-plugin-path`.
63+
/// The path returned can be loaded by 'loadLibraryPlugin' method.
64+
llvm::Optional<std::string>
65+
lookupLibraryPluginInSearchPathByModuleName(Identifier moduleName);
6066

6167
/// Lookup an executable plugin that is declared to handle \p moduleName
6268
/// module by '-load-plugin-executable'.

lib/AST/ASTContext.cpp

Lines changed: 3 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -6269,29 +6269,9 @@ void ASTContext::setPluginLoader(std::unique_ptr<PluginLoader> loader) {
62696269
getImpl().Plugins = std::move(loader);
62706270
}
62716271

6272-
PluginLoader &ASTContext::getPluginLoader() { return *getImpl().Plugins; }
6273-
6274-
Optional<std::string>
6275-
ASTContext::lookupLibraryPluginByModuleName(Identifier moduleName) {
6276-
return getImpl().Plugins->lookupLibraryPluginByModuleName(moduleName);
6277-
}
6278-
6279-
Optional<StringRef>
6280-
ASTContext::lookupExecutablePluginByModuleName(Identifier moduleName) {
6281-
return getImpl().Plugins->lookupExecutablePluginByModuleName(moduleName);
6282-
}
6283-
6284-
Optional<std::pair<std::string, std::string>>
6285-
ASTContext::lookupExternalLibraryPluginByModuleName(Identifier moduleName) {
6286-
return getImpl().Plugins->lookupExternalLibraryPluginByModuleName(moduleName);
6287-
}
6288-
6289-
LoadedLibraryPlugin *ASTContext::loadLibraryPlugin(StringRef path) {
6290-
return getImpl().Plugins->loadLibraryPlugin(path);
6291-
}
6292-
6293-
LoadedExecutablePlugin *ASTContext::loadExecutablePlugin(StringRef path) {
6294-
return getImpl().Plugins->loadExecutablePlugin(path);
6272+
PluginLoader &ASTContext::getPluginLoader() {
6273+
assert(getImpl().Plugins && "PluginLoader must be setup before using");
6274+
return *getImpl().Plugins;
62956275
}
62966276

62976277
Type ASTContext::getNamedSwiftType(ModuleDecl *module, StringRef name) {

lib/AST/PluginLoader.cpp

Lines changed: 13 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -47,9 +47,7 @@ PluginRegistry *PluginLoader::getRegistry() {
4747
}
4848

4949
llvm::Optional<std::string>
50-
PluginLoader::lookupLibraryPluginByModuleName(Identifier moduleName) {
51-
auto fs = Ctx.SourceMgr.getFileSystem();
52-
50+
PluginLoader::lookupExplicitLibraryPluginByModuleName(Identifier moduleName) {
5351
// Look for 'lib${module name}(.dylib|.so)'.
5452
SmallString<64> expectedBasename;
5553
expectedBasename.append("lib");
@@ -63,8 +61,20 @@ PluginLoader::lookupLibraryPluginByModuleName(Identifier moduleName) {
6361
return libPath;
6462
}
6563
}
64+
return None;
65+
}
66+
67+
llvm::Optional<std::string>
68+
PluginLoader::lookupLibraryPluginInSearchPathByModuleName(
69+
Identifier moduleName) {
70+
// Look for 'lib${module name}(.dylib|.so)'.
71+
SmallString<64> expectedBasename;
72+
expectedBasename.append("lib");
73+
expectedBasename.append(moduleName.str());
74+
expectedBasename.append(LTDL_SHLIB_EXT);
6675

6776
// Try '-plugin-path'.
77+
auto fs = Ctx.SourceMgr.getFileSystem();
6878
for (const auto &searchPath : Ctx.SearchPathOpts.PluginSearchPaths) {
6979
SmallString<128> fullPath(searchPath);
7080
llvm::sys::path::append(fullPath, expectedBasename);

lib/Sema/TypeCheckMacros.cpp

Lines changed: 39 additions & 45 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@
1515
//===----------------------------------------------------------------------===//
1616

1717
#include "TypeCheckMacros.h"
18+
#include "../AST/InlinableText.h"
1819
#include "TypeChecker.h"
1920
#include "swift/ABI/MetadataValues.h"
2021
#include "swift/AST/ASTContext.h"
@@ -23,9 +24,9 @@
2324
#include "swift/AST/CASTBridging.h"
2425
#include "swift/AST/DiagnosticsFrontend.h"
2526
#include "swift/AST/Expr.h"
26-
#include "../AST/InlinableText.h"
2727
#include "swift/AST/MacroDefinition.h"
2828
#include "swift/AST/NameLookupRequests.h"
29+
#include "swift/AST/PluginLoader.h"
2930
#include "swift/AST/PluginRegistry.h"
3031
#include "swift/AST/PrettyStackTrace.h"
3132
#include "swift/AST/SourceFile.h"
@@ -272,42 +273,10 @@ MacroDefinition MacroDefinitionRequest::evaluate(
272273
#endif
273274
}
274275

275-
/// Load a plugin library based on a module name.
276-
static LoadedLibraryPlugin *loadLibraryPluginByName(ASTContext &ctx,
277-
Identifier moduleName) {
278-
std::string libraryPath;
279-
if (auto found = ctx.lookupLibraryPluginByModuleName(moduleName)) {
280-
libraryPath = *found;
281-
} else {
282-
return nullptr;
283-
}
284-
285-
// Load the plugin.
286-
return ctx.loadLibraryPlugin(libraryPath);
287-
}
288-
289276
static LoadedExecutablePlugin *
290-
loadExecutablePluginByName(ASTContext &ctx, Identifier moduleName) {
291-
// Find an executable plugin.
292-
std::string libraryPath;
293-
std::string executablePluginPath;
294-
295-
if (auto found = ctx.lookupExternalLibraryPluginByModuleName(moduleName)) {
296-
// Found in '-external-plugin-path'.
297-
std::tie(libraryPath, executablePluginPath) = found.value();
298-
} else if (auto found = ctx.lookupExecutablePluginByModuleName(moduleName)) {
299-
// Found in '-load-plugin-executable'.
300-
executablePluginPath = found->str();
301-
}
302-
if (executablePluginPath.empty())
303-
return nullptr;
304-
305-
// Launch the plugin.
306-
LoadedExecutablePlugin *executablePlugin =
307-
ctx.loadExecutablePlugin(executablePluginPath);
308-
if (!executablePlugin)
309-
return nullptr;
310-
277+
initializeExecutablePlugin(ASTContext &ctx,
278+
LoadedExecutablePlugin *executablePlugin,
279+
StringRef libraryPath, Identifier moduleName) {
311280
// Lock the plugin while initializing.
312281
// Note that'executablePlugn' can be shared between multiple ASTContext.
313282
executablePlugin->lock();
@@ -333,7 +302,7 @@ loadExecutablePluginByName(ASTContext &ctx, Identifier moduleName) {
333302
auto fs = ctx.SourceMgr.getFileSystem();
334303
if (auto err = fs->getRealPath(libraryPath, resolvedLibraryPath)) {
335304
ctx.Diags.diagnose(SourceLoc(), diag::compiler_plugin_not_loaded,
336-
executablePluginPath, err.message());
305+
executablePlugin->getExecutablePath(), err.message());
337306
return nullptr;
338307
}
339308
std::string resolvedLibraryPathStr(resolvedLibraryPath);
@@ -369,16 +338,41 @@ loadExecutablePluginByName(ASTContext &ctx, Identifier moduleName) {
369338
LoadedCompilerPlugin
370339
CompilerPluginLoadRequest::evaluate(Evaluator &evaluator, ASTContext *ctx,
371340
Identifier moduleName) const {
372-
// Check dynamic link library plugins.
373-
// i.e. '-plugin-path', and '-load-plugin-library'.
374-
if (auto found = loadLibraryPluginByName(*ctx, moduleName)) {
375-
return found;
341+
PluginLoader &loader = ctx->getPluginLoader();
342+
343+
std::string libraryPath;
344+
std::string executablePath;
345+
346+
// '-load-plugin-libarary'.
347+
if (auto found = loader.lookupExplicitLibraryPluginByModuleName(moduleName)) {
348+
libraryPath = found.value();
349+
}
350+
// '-load-plugin-executable'.
351+
else if (auto found = loader.lookupExecutablePluginByModuleName(moduleName)) {
352+
executablePath = found->str();
353+
}
354+
// '-plugin-path'.
355+
else if (auto found =
356+
loader.lookupLibraryPluginInSearchPathByModuleName(moduleName)) {
357+
libraryPath = found.value();
358+
}
359+
// '-external-plugin-path'.
360+
else if (auto found =
361+
loader.lookupExternalLibraryPluginByModuleName(moduleName)) {
362+
std::tie(libraryPath, executablePath) = found.value();
376363
}
377364

378-
// Fall back to executable plugins.
379-
// i.e. '-external-plugin-path', and '-load-plugin-executable'.
380-
if (auto *found = loadExecutablePluginByName(*ctx, moduleName)) {
381-
return found;
365+
if (!executablePath.empty()) {
366+
if (LoadedExecutablePlugin *executablePlugin =
367+
loader.loadExecutablePlugin(executablePath)) {
368+
return initializeExecutablePlugin(*ctx, executablePlugin, libraryPath,
369+
moduleName);
370+
}
371+
} else if (!libraryPath.empty()) {
372+
if (LoadedLibraryPlugin *libraryPlugin =
373+
loader.loadLibraryPlugin(libraryPath)) {
374+
return libraryPlugin;
375+
}
382376
}
383377

384378
return nullptr;
Lines changed: 132 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,132 @@
1+
2+
// REQUIRES: swift_swift_parser
3+
4+
// RUN: %empty-directory(%t)
5+
6+
// RUN: mkdir -p %t/src
7+
// RUN: mkdir -p %t/bin
8+
// RUN: mkdir -p %t/lib/tmp
9+
// RUN: mkdir -p %t/lib/plugins
10+
// RUN: mkdir -p %t/external
11+
// RUN: mkdir -p %t/libexec
12+
13+
// RUN: split-file %s %t/src
14+
15+
//#-- For -plugin-path
16+
// RUN: %host-build-swift \
17+
// RUN: -swift-version 5 \
18+
// RUN: -emit-library -o %t/lib/plugins/%target-library-name(MacroDefinition) \
19+
// RUN: -module-name MacroDefinition \
20+
// RUN: -D PLUGIN_PATH \
21+
// RUN: %t/src/MacroDefinition.swift \
22+
// RUN: -g -no-toolchain-stdlib-rpath
23+
24+
//#-- For -load-plugin-library
25+
// RUN: %host-build-swift \
26+
// RUN: -swift-version 5 \
27+
// RUN: -emit-library -o %t/lib/tmp/%target-library-name(MacroDefinition) \
28+
// RUN: -module-name MacroDefinition \
29+
// RUN: -D LOAD_PLUGIN_LIBRARY \
30+
// RUN: %t/src/MacroDefinition.swift \
31+
// RUN: -g -no-toolchain-stdlib-rpath
32+
33+
//#-- For -external-plugin-path
34+
// RUN: %host-build-swift \
35+
// RUN: -swift-version 5 \
36+
// RUN: -emit-library -o %t/external/%target-library-name(MacroDefinition) \
37+
// RUN: -module-name MacroDefinition \
38+
// RUN: -D EXTERNAL_PLUGIN_PATH \
39+
// RUN: %t/src/MacroDefinition.swift \
40+
// RUN: -g -no-toolchain-stdlib-rpath
41+
42+
//#-- For -load-plugin-executable
43+
// RUN: %clang \
44+
// RUN: -isysroot %host_sdk \
45+
// RUN: -I %swift_src_root/include \
46+
// RUN: -L %swift-lib-dir -l_swiftMockPlugin \
47+
// RUN: -Wl,-rpath,%swift-lib-dir \
48+
// RUN: -o %t/libexec/MacroDefinitionPlugin \
49+
// RUN: %t/src/MacroDefinition.c
50+
51+
//#-- Expect -load-plugin-library
52+
// RUN: %target-build-swift %t/src/test.swift \
53+
// RUN: -o %t/main1 \
54+
// RUN: -module-name test \
55+
// RUN: -plugin-path %t/lib/plugins \
56+
// RUN: -external-plugin-path %t/external#%swift-plugin-server \
57+
// RUN: -load-plugin-library %t/lib/tmp/%target-library-name(MacroDefinition) \
58+
// RUN: -load-plugin-executable %t/libexec/MacroDefinitionPlugin#MacroDefinition
59+
// RUN: %target-codesign %t/main1
60+
// RUN: %target-run %t/main1 | %FileCheck --check-prefix=CHECK_LOAD_PLUGIN_LIBRARY %s
61+
62+
//#-- Expect -load-plugin-executable
63+
// RUN: %target-build-swift %t/src/test.swift \
64+
// RUN: -o %t/main2 \
65+
// RUN: -module-name test \
66+
// RUN: -plugin-path %t/lib/plugins \
67+
// RUN: -external-plugin-path %t/external#%swift-plugin-server \
68+
// RUN: -load-plugin-executable %t/libexec/MacroDefinitionPlugin#MacroDefinition
69+
// RUN: %target-codesign %t/main2
70+
// RUN: %target-run %t/main2 | %FileCheck --check-prefix=CHECK_LOAD_PLUGIN_EXECUTABLE %s
71+
72+
//#-- Expect -plugin-path
73+
// RUN: %target-build-swift %t/src/test.swift \
74+
// RUN: -o %t/main3 \
75+
// RUN: -module-name test \
76+
// RUN: -plugin-path %t/lib/plugins \
77+
// RUN: -external-plugin-path %t/external#%swift-plugin-server
78+
// RUN: %target-codesign %t/main3
79+
// RUN: %target-run %t/main3 | %FileCheck --check-prefix=CHECK_PLUGIN_PATH %s
80+
81+
//#-- Expect -external-plugin-path
82+
// RUN: %target-build-swift %t/src/test.swift \
83+
// RUN: -o %t/main4 \
84+
// RUN: -module-name test \
85+
// RUN: -external-plugin-path %t/external#%swift-plugin-server
86+
// RUN: %target-codesign %t/main4
87+
// RUN: %target-run %t/main4 | %FileCheck --check-prefix=CHECK_EXTERNAL_PLUGIN_PATH %s
88+
89+
// CHECK_LOAD_PLUGIN_LIBRARY: load-plugin-library
90+
// CHECK_LOAD_PLUGIN_EXECUTABLE: load-plugin-executable
91+
// CHECK_PLUGIN_PATH: plugin-path
92+
// CHECK_EXTERNAL_PLUGIN_PATH: external-plugin-path
93+
94+
//--- test.swift
95+
@freestanding(expression) macro testMacro() -> String = #externalMacro(module: "MacroDefinition", type: "TestMacro")
96+
97+
print(#testMacro)
98+
99+
//--- MacroDefinition.swift
100+
import SwiftSyntax
101+
import SwiftSyntaxMacros
102+
103+
public struct TestMacro: ExpressionMacro {
104+
public static func expansion(
105+
of node: some FreestandingMacroExpansionSyntax,
106+
in context: some MacroExpansionContext
107+
) throws -> ExprSyntax {
108+
#if PLUGIN_PATH
109+
return #""plugin-path""#
110+
#elseif LOAD_PLUGIN_LIBRARY
111+
return #""load-plugin-library""#
112+
#elseif EXTERNAL_PLUGIN_PATH
113+
return #""external-plugin-path""#
114+
#endif
115+
}
116+
}
117+
118+
//--- MacroDefinition.c
119+
#include "swift-c/MockPlugin/MockPlugin.h"
120+
121+
MOCK_PLUGIN([
122+
{
123+
"expect": {"getCapability": {}},
124+
"response": {"getCapabilityResult": {"capability": {"protocolVersion": 1}}}
125+
},
126+
{
127+
"expect": {"expandFreestandingMacro": {
128+
"macro": {"moduleName": "MacroDefinition", "typeName": "TestMacro"},
129+
"syntax": {"kind": "expression", "source": "#testMacro"}}},
130+
"response": {"expandFreestandingMacroResult": {"expandedSource": "\"load-plugin-executable\"", "diagnostics": []}}
131+
}
132+
])

0 commit comments

Comments
 (0)