Skip to content

Commit 2f744a7

Browse files
committed
fix: Place Swift headers at the bottom of the umbrella header
They define macros which may alter the way some iOS SDK methods and properties are declared refs NativeScript/ios-jsc#1153
1 parent ed368b5 commit 2f744a7

File tree

1 file changed

+31
-23
lines changed

1 file changed

+31
-23
lines changed

src/HeadersParser/Parser.cpp

Lines changed: 31 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -5,46 +5,38 @@
55
#include <clang/Lex/Preprocessor.h>
66
#include <clang/Tooling/Tooling.h>
77
#include <iostream>
8+
#include <sstream>
89
#include <llvm/ADT/StringSwitch.h>
910
#include <llvm/Support/Path.h>
1011

1112
using namespace clang;
1213
namespace path = llvm::sys::path;
1314
namespace fs = llvm::sys::fs;
1415

15-
static SmallVectorImpl<char>& operator+=(SmallVectorImpl<char>& includes, StringRef rhs)
16+
static std::error_code addHeaderInclude(StringRef headerName, std::vector<SmallString<256>>& includes)
1617
{
17-
includes.append(rhs.begin(), rhs.end());
18-
return includes;
19-
}
20-
21-
static std::error_code addHeaderInclude(StringRef headerName, SmallVectorImpl<char>& includes)
22-
{
23-
includes += "#import \"";
2418

2519
// Use an absolute path for the include; there's no reason to think whether a relative path will
2620
// work ('.' might not be on our include path) or that it will find the same file.
2721
if (path::is_absolute(headerName)) {
28-
includes += headerName;
22+
includes.push_back(headerName);
2923
}
3024
else {
3125
SmallString<256> header = headerName;
3226
if (std::error_code err = fs::make_absolute(header))
3327
return err;
34-
includes += header;
28+
includes.push_back(header);
3529
}
3630

37-
includes += "\"\n";
38-
3931
return std::error_code();
4032
}
4133

42-
static std::error_code addHeaderInclude(const FileEntry* header, SmallVectorImpl<char>& includes)
34+
static std::error_code addHeaderInclude(const FileEntry* header, std::vector<SmallString<256>>& includes)
4335
{
4436
return addHeaderInclude(header->getName(), includes);
4537
}
4638

47-
static std::error_code collectModuleHeaderIncludes(FileManager& fileMgr, ModuleMap& modMap, const Module* module, SmallVectorImpl<char>& includes)
39+
static std::error_code collectModuleHeaderIncludes(FileManager& fileMgr, ModuleMap& modMap, const Module* module, std::vector<SmallString<256>>& includes)
4840
{
4941
// Don't collect any headers for unavailable modules.
5042
if (!module->isAvailable())
@@ -91,7 +83,7 @@ static std::error_code collectModuleHeaderIncludes(FileManager& fileMgr, ModuleM
9183
return std::error_code();
9284
}
9385

94-
static std::error_code CreateUmbrellaHeaderForAmbientModules(const std::vector<std::string>& args, std::string* umbrellaHeaderContents, const std::vector<std::string>& moduleBlacklist, std::vector<std::string>& includePaths)
86+
static std::error_code CreateUmbrellaHeaderForAmbientModules(const std::vector<std::string>& args, std::vector<SmallString<256>>& umbrellaHeaders, const std::vector<std::string>& moduleBlacklist, std::vector<std::string>& includePaths)
9587
{
9688
std::unique_ptr<clang::ASTUnit> ast = clang::tooling::buildASTFromCodeWithArgs("", args, "umbrella.h");
9789
if (!ast)
@@ -106,7 +98,6 @@ static std::error_code CreateUmbrellaHeaderForAmbientModules(const std::vector<s
10698
ModuleMap& moduleMap = headerSearch.getModuleMap();
10799
FileManager& fileManager = ast->getFileManager();
108100

109-
SmallString<256> headerContents;
110101
std::function<void(const Module*)> collector = [&](const Module* module) {
111102
// uncomment for debugging unavailable modules
112103
// if (!module->isAvailable()) {
@@ -124,24 +115,41 @@ static std::error_code CreateUmbrellaHeaderForAmbientModules(const std::vector<s
124115
includePaths.push_back(includeString);
125116
}
126117

127-
collectModuleHeaderIncludes(fileManager, moduleMap, module, headerContents);
118+
collectModuleHeaderIncludes(fileManager, moduleMap, module, umbrellaHeaders);
128119
std::for_each(module->submodule_begin(), module->submodule_end(), collector);
129120
};
130121

131122
std::for_each(modules.begin(), modules.end(), collector);
132123

133-
if (umbrellaHeaderContents)
134-
*umbrellaHeaderContents = headerContents.str();
135-
136124
return std::error_code();
137125
}
138126

127+
// Sort headers so that -Swift headers come last (see https://github.com/NativeScript/ios-runtime/issues/1153)
128+
int headerPriority(SmallString<256> h) {
129+
if (std::string::npos != h.find("-Swift")) {
130+
return 1;
131+
} else {
132+
return 0;
133+
}
134+
}
135+
136+
139137
std::string CreateUmbrellaHeader(const std::vector<std::string>& clangArgs, std::vector<std::string>& includePaths)
140138
{
141-
std::string umbrellaHeaderContents;
142139
std::vector<std::string> moduleBlacklist;
143140

144141
// Generate umbrella header for all modules from the sdk
145-
CreateUmbrellaHeaderForAmbientModules(clangArgs, &umbrellaHeaderContents, moduleBlacklist, includePaths);
146-
return umbrellaHeaderContents;
142+
std::vector<SmallString<256>> umbrellaHeaders;
143+
CreateUmbrellaHeaderForAmbientModules(clangArgs, umbrellaHeaders, moduleBlacklist, includePaths);
144+
145+
std::sort(umbrellaHeaders.begin(), umbrellaHeaders.end(), [](const SmallString<256>& h1, const SmallString<256>& h2) {
146+
return headerPriority(h1) < headerPriority(h2);
147+
});
148+
149+
std::stringstream umbrellaHeaderContents;
150+
for (auto& h : umbrellaHeaders) {
151+
umbrellaHeaderContents << "#import \"" << h.c_str() << "\"" << std::endl;
152+
}
153+
154+
return umbrellaHeaderContents.str();
147155
}

0 commit comments

Comments
 (0)