Skip to content

Commit 7f5912b

Browse files
authored
Merge pull request #65009 from nkcsgexi/add-yaml-block-list
Basics: define a YAML-based blocklist format
2 parents 4cbd4a1 + b758c4a commit 7f5912b

File tree

4 files changed

+204
-5
lines changed

4 files changed

+204
-5
lines changed

include/swift/Basic/BlockList.h

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -24,25 +24,26 @@
2424
namespace swift {
2525

2626
enum class BlockListAction: uint8_t {
27-
ShouldUseBinaryModule = 0,
27+
Undefined = 0,
28+
ShouldUseBinaryModule,
2829
ShouldUseTextualModule,
2930
};
3031

3132
enum class BlockListKeyKind: uint8_t {
33+
Undefined = 0,
3234
ModuleName,
3335
ProjectName
3436
};
3537

3638
class BlockListStore {
3739
public:
3840
struct Implementation;
41+
void addConfigureFilePath(StringRef path);
3942
bool hasBlockListAction(StringRef key, BlockListKeyKind keyKind,
4043
BlockListAction action);
4144
BlockListStore();
4245
~BlockListStore();
4346
private:
44-
friend class ASTContext;
45-
void addConfigureFilePath(StringRef path);
4647
Implementation &Impl;
4748
};
4849

lib/Basic/BlockList.cpp

Lines changed: 82 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -18,11 +18,31 @@
1818
#include "swift/Basic/SourceManager.h"
1919

2020
struct swift::BlockListStore::Implementation {
21+
SourceManager SM;
2122
llvm::StringMap<std::vector<BlockListAction>> ModuleActionDict;
2223
llvm::StringMap<std::vector<BlockListAction>> ProjectActionDict;
2324
void addConfigureFilePath(StringRef path);
2425
bool hasBlockListAction(StringRef key, BlockListKeyKind keyKind,
2526
BlockListAction action);
27+
void collectBlockList(llvm::yaml::Node *N, BlockListAction action);
28+
29+
llvm::StringMap<std::vector<BlockListAction>> *getDictToUse(BlockListKeyKind kind) {
30+
switch (kind) {
31+
case BlockListKeyKind::ModuleName:
32+
return &ModuleActionDict;
33+
case BlockListKeyKind::ProjectName:
34+
return &ProjectActionDict;
35+
case BlockListKeyKind::Undefined:
36+
return nullptr;
37+
}
38+
}
39+
static std::string getScalaString(llvm::yaml::Node *N) {
40+
llvm::SmallString<64> Buffer;
41+
if (auto *scala = dyn_cast<llvm::yaml::ScalarNode>(N)) {
42+
return scala->getValue(Buffer).str();
43+
}
44+
return std::string();
45+
}
2646
};
2747

2848
swift::BlockListStore::BlockListStore(): Impl(*new Implementation()) {}
@@ -40,14 +60,74 @@ void swift::BlockListStore::addConfigureFilePath(StringRef path) {
4060

4161
bool swift::BlockListStore::Implementation::hasBlockListAction(StringRef key,
4262
BlockListKeyKind keyKind, BlockListAction action) {
43-
auto *dict = keyKind == BlockListKeyKind::ModuleName ? &ModuleActionDict :
44-
&ProjectActionDict;
63+
auto *dict = getDictToUse(keyKind);
64+
assert(dict);
4565
auto it = dict->find(key);
4666
if (it == dict->end())
4767
return false;
4868
return llvm::is_contained(it->second, action);
4969
}
5070

71+
void swift::BlockListStore::Implementation::collectBlockList(llvm::yaml::Node *N,
72+
BlockListAction action) {
73+
namespace yaml = llvm::yaml;
74+
auto *pair = dyn_cast<yaml::KeyValueNode>(N);
75+
if (!pair)
76+
return;
77+
std::string rawKey = getScalaString(pair->getKey());
78+
auto keyKind = llvm::StringSwitch<BlockListKeyKind>(rawKey)
79+
#define CASE(X) .Case(#X, BlockListKeyKind::X)
80+
CASE(ModuleName)
81+
CASE(ProjectName)
82+
#undef CASE
83+
.Default(BlockListKeyKind::Undefined);
84+
if (keyKind == BlockListKeyKind::Undefined)
85+
return;
86+
auto *dictToUse = getDictToUse(keyKind);
87+
assert(dictToUse);
88+
auto *seq = dyn_cast<yaml::SequenceNode>(pair->getValue());
89+
if (!seq)
90+
return;
91+
for (auto &node: *seq) {
92+
std::string name = getScalaString(&node);
93+
dictToUse->insert({name, std::vector<BlockListAction>()})
94+
.first->second.push_back(action);
95+
}
96+
}
97+
5198
void swift::BlockListStore::Implementation::addConfigureFilePath(StringRef path) {
99+
namespace yaml = llvm::yaml;
52100

101+
// Load the input file.
102+
llvm::ErrorOr<std::unique_ptr<llvm::MemoryBuffer>> FileBufOrErr =
103+
vfs::getFileOrSTDIN(*SM.getFileSystem(), path,
104+
/*FileSize*/-1, /*RequiresNullTerminator*/true,
105+
/*IsVolatile*/false, /*RetryCount*/30);
106+
if (!FileBufOrErr) {
107+
return;
108+
}
109+
StringRef Buffer = FileBufOrErr->get()->getBuffer();
110+
yaml::Stream Stream(llvm::MemoryBufferRef(Buffer, path),
111+
SM.getLLVMSourceMgr());
112+
for (auto DI = Stream.begin(); DI != Stream.end(); ++ DI) {
113+
assert(DI != Stream.end() && "Failed to read a document");
114+
yaml::Node *N = DI->getRoot();
115+
for (auto &pair: *dyn_cast<yaml::MappingNode>(N)) {
116+
std::string key = getScalaString(pair.getKey());
117+
auto action = llvm::StringSwitch<BlockListAction>(key)
118+
#define CASE(X) .Case(#X, BlockListAction::X)
119+
CASE(ShouldUseBinaryModule)
120+
CASE(ShouldUseTextualModule)
121+
#undef CASE
122+
.Default(BlockListAction::Undefined);
123+
if (action == BlockListAction::Undefined)
124+
continue;
125+
auto *map = dyn_cast<yaml::MappingNode>(pair.getValue());
126+
if (!map)
127+
continue;
128+
for (auto &innerPair: *map) {
129+
collectBlockList(&innerPair, action);
130+
}
131+
}
132+
}
53133
}

unittests/Basic/BlocklistTest.cpp

Lines changed: 117 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,117 @@
1+
//===------- BlocklistTest.cpp --------------------------------------------===//
2+
//
3+
// This source file is part of the Swift.org open source project
4+
//
5+
// Copyright (c) 2014 - 2017 Apple Inc. and the Swift project authors
6+
// Licensed under Apache License v2.0 with Runtime Library Exception
7+
//
8+
// See https://swift.org/LICENSE.txt for license information
9+
// See https://swift.org/CONTRIBUTORS.txt for the list of Swift project authors
10+
//
11+
//===----------------------------------------------------------------------===//
12+
13+
#include "gtest/gtest.h"
14+
#include "swift/AST/SearchPathOptions.h"
15+
#include "swift/Basic/Defer.h"
16+
#include "swift/Basic/BlockList.h"
17+
18+
using namespace swift;
19+
20+
static std::string createFilename(StringRef base, StringRef name) {
21+
SmallString<256> path = base;
22+
llvm::sys::path::append(path, name);
23+
return llvm::Twine(path).str();
24+
}
25+
26+
static bool emitFileWithContents(StringRef path, StringRef contents,
27+
std::string *pathOut = nullptr) {
28+
int FD;
29+
if (llvm::sys::fs::openFileForWrite(path, FD))
30+
return true;
31+
if (pathOut)
32+
*pathOut = path.str();
33+
llvm::raw_fd_ostream file(FD, /*shouldClose=*/true);
34+
file << contents;
35+
return false;
36+
}
37+
38+
static bool emitFileWithContents(StringRef base, StringRef name,
39+
StringRef contents,
40+
std::string *pathOut = nullptr) {
41+
return emitFileWithContents(createFilename(base, name), contents, pathOut);
42+
}
43+
44+
TEST(BlocklistTest, testYamlParsing) {
45+
SmallString<256> temp;
46+
ASSERT_FALSE(llvm::sys::fs::createUniqueDirectory(
47+
"BlocklistTest.testYamlParsing", temp));
48+
SWIFT_DEFER { llvm::sys::fs::remove_directories(temp); };
49+
BlockListStore store;
50+
std::string path1, path2;
51+
ASSERT_FALSE(emitFileWithContents(temp, "block1.yaml",
52+
"---\n"
53+
"ShouldUseBinaryModule:\n"
54+
" ModuleName:\n"
55+
" - M1 #rdar12345\n"
56+
" - M2 #rdar12345\n"
57+
" - M3\n"
58+
" - M4\n"
59+
" ProjectName:\n"
60+
" - P1\n"
61+
" - P2\n"
62+
" - P3 #rdar12344\n"
63+
" - P4\n"
64+
"---\n"
65+
"ShouldUseTextualModule:\n"
66+
" ModuleName:\n"
67+
" - M1_2 #rdar12345\n"
68+
" - M2_2 #rdar12345\n"
69+
" - M3_2\n"
70+
" - M4_2\n"
71+
" ProjectName:\n"
72+
" - P1_2\n"
73+
" - P2_2\n"
74+
" - P3_2 #rdar12344\n"
75+
" - P4_2\n",
76+
&path1));
77+
ASSERT_FALSE(emitFileWithContents(temp, "block2.yml",
78+
"---\n"
79+
"ShouldUseBinaryModule:\n"
80+
" ModuleName:\n"
81+
" - M1_block2 #rdar12345\n"
82+
" ProjectName:\n"
83+
" - P1_block2\n"
84+
"---\n"
85+
"ShouldUseTextualModule:\n"
86+
" ModuleName:\n"
87+
" - M1_2_block2 #rdar12345\n"
88+
" ProjectName:\n"
89+
" - P1_2_block2\n",
90+
&path2));
91+
store.addConfigureFilePath(path1);
92+
store.addConfigureFilePath(path2);
93+
ASSERT_TRUE(store.hasBlockListAction("M1", BlockListKeyKind::ModuleName, BlockListAction::ShouldUseBinaryModule));
94+
ASSERT_TRUE(store.hasBlockListAction("M2", BlockListKeyKind::ModuleName, BlockListAction::ShouldUseBinaryModule));
95+
ASSERT_TRUE(store.hasBlockListAction("P1", BlockListKeyKind::ProjectName, BlockListAction::ShouldUseBinaryModule));
96+
ASSERT_TRUE(store.hasBlockListAction("P2", BlockListKeyKind::ProjectName, BlockListAction::ShouldUseBinaryModule));
97+
98+
ASSERT_TRUE(store.hasBlockListAction("M1_2", BlockListKeyKind::ModuleName, BlockListAction::ShouldUseTextualModule));
99+
ASSERT_TRUE(store.hasBlockListAction("M2_2", BlockListKeyKind::ModuleName, BlockListAction::ShouldUseTextualModule));
100+
ASSERT_TRUE(store.hasBlockListAction("P1_2", BlockListKeyKind::ProjectName, BlockListAction::ShouldUseTextualModule));
101+
ASSERT_TRUE(store.hasBlockListAction("P2_2", BlockListKeyKind::ProjectName, BlockListAction::ShouldUseTextualModule));
102+
103+
ASSERT_FALSE(store.hasBlockListAction("P1", BlockListKeyKind::ModuleName, BlockListAction::ShouldUseBinaryModule));
104+
ASSERT_FALSE(store.hasBlockListAction("P2", BlockListKeyKind::ModuleName, BlockListAction::ShouldUseBinaryModule));
105+
ASSERT_FALSE(store.hasBlockListAction("M1", BlockListKeyKind::ProjectName, BlockListAction::ShouldUseBinaryModule));
106+
ASSERT_FALSE(store.hasBlockListAction("M2", BlockListKeyKind::ProjectName, BlockListAction::ShouldUseBinaryModule));
107+
108+
ASSERT_TRUE(store.hasBlockListAction("M1_block2", BlockListKeyKind::ModuleName, BlockListAction::ShouldUseBinaryModule));
109+
ASSERT_TRUE(store.hasBlockListAction("P1_block2", BlockListKeyKind::ProjectName, BlockListAction::ShouldUseBinaryModule));
110+
ASSERT_TRUE(store.hasBlockListAction("M1_2_block2", BlockListKeyKind::ModuleName, BlockListAction::ShouldUseTextualModule));
111+
ASSERT_TRUE(store.hasBlockListAction("P1_2_block2", BlockListKeyKind::ProjectName, BlockListAction::ShouldUseTextualModule));
112+
113+
ASSERT_FALSE(store.hasBlockListAction("M1_block2", BlockListKeyKind::ProjectName, BlockListAction::ShouldUseBinaryModule));
114+
ASSERT_FALSE(store.hasBlockListAction("P1_block2", BlockListKeyKind::ModuleName, BlockListAction::ShouldUseBinaryModule));
115+
ASSERT_FALSE(store.hasBlockListAction("M1_2_block2", BlockListKeyKind::ProjectName, BlockListAction::ShouldUseTextualModule));
116+
ASSERT_FALSE(store.hasBlockListAction("P1_2_block2", BlockListKeyKind::ModuleName, BlockListAction::ShouldUseTextualModule));
117+
}

unittests/Basic/CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ handle_gyb_sources(
77

88
add_swift_unittest(SwiftBasicTests
99
BlotMapVectorTest.cpp
10+
BlocklistTest.cpp
1011
CacheTest.cpp
1112
ClangImporterOptionsTest.cpp
1213
ClusteredBitVectorTest.cpp

0 commit comments

Comments
 (0)