Skip to content

Commit 6a8e6ef

Browse files
committed
Basics: define a YAML-based blocklist format
An example of this format is: --- actionToTakeFor: ModuleName: - moduleName1 ProjectName: - projectName1
1 parent cd439ba commit 6a8e6ef

File tree

4 files changed

+206
-5
lines changed

4 files changed

+206
-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: 80 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+
llvm_unreachable("no dict to use");
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,72 @@ 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);
4564
auto it = dict->find(key);
4665
if (it == dict->end())
4766
return false;
4867
return llvm::is_contained(it->second, action);
4968
}
5069

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

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

unittests/Basic/BlocklistTest.cpp

Lines changed: 121 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,121 @@
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/ASTContext.h"
15+
#include "swift/AST/DiagnosticEngine.h"
16+
#include "swift/AST/SearchPathOptions.h"
17+
#include "swift/Basic/Defer.h"
18+
#include "swift/Basic/BlockList.h"
19+
#include "swift/Basic/LangOptions.h"
20+
#include "swift/Basic/SourceManager.h"
21+
22+
using namespace swift;
23+
24+
static std::string createFilename(StringRef base, StringRef name) {
25+
SmallString<256> path = base;
26+
llvm::sys::path::append(path, name);
27+
return llvm::Twine(path).str();
28+
}
29+
30+
static bool emitFileWithContents(StringRef path, StringRef contents,
31+
std::string *pathOut = nullptr) {
32+
int FD;
33+
if (llvm::sys::fs::openFileForWrite(path, FD))
34+
return true;
35+
if (pathOut)
36+
*pathOut = path.str();
37+
llvm::raw_fd_ostream file(FD, /*shouldClose=*/true);
38+
file << contents;
39+
return false;
40+
}
41+
42+
static bool emitFileWithContents(StringRef base, StringRef name,
43+
StringRef contents,
44+
std::string *pathOut = nullptr) {
45+
return emitFileWithContents(createFilename(base, name), contents, pathOut);
46+
}
47+
48+
TEST(BlocklistTest, testYamlParsing) {
49+
SmallString<256> temp;
50+
ASSERT_FALSE(llvm::sys::fs::createUniqueDirectory(
51+
"BlocklistTest.testYamlParsing", temp));
52+
SWIFT_DEFER { llvm::sys::fs::remove_directories(temp); };
53+
BlockListStore store;
54+
std::string path1, path2;
55+
ASSERT_FALSE(emitFileWithContents(temp, "block1.yaml",
56+
"---\n"
57+
"ShouldUseBinaryModule:\n"
58+
" ModuleName:\n"
59+
" - M1 #rdar12345\n"
60+
" - M2 #rdar12345\n"
61+
" - M3\n"
62+
" - M4\n"
63+
" ProjectName:\n"
64+
" - P1\n"
65+
" - P2\n"
66+
" - P3 #rdar12344\n"
67+
" - P4\n"
68+
"---\n"
69+
"ShouldUseTextualModule:\n"
70+
" ModuleName:\n"
71+
" - M1_2 #rdar12345\n"
72+
" - M2_2 #rdar12345\n"
73+
" - M3_2\n"
74+
" - M4_2\n"
75+
" ProjectName:\n"
76+
" - P1_2\n"
77+
" - P2_2\n"
78+
" - P3_2 #rdar12344\n"
79+
" - P4_2\n",
80+
&path1));
81+
ASSERT_FALSE(emitFileWithContents(temp, "block2.yml",
82+
"---\n"
83+
"ShouldUseBinaryModule:\n"
84+
" ModuleName:\n"
85+
" - M1_block2 #rdar12345\n"
86+
" ProjectName:\n"
87+
" - P1_block2\n"
88+
"---\n"
89+
"ShouldUseTextualModule:\n"
90+
" ModuleName:\n"
91+
" - M1_2_block2 #rdar12345\n"
92+
" ProjectName:\n"
93+
" - P1_2_block2\n",
94+
&path2));
95+
store.addConfigureFilePath(path1);
96+
store.addConfigureFilePath(path2);
97+
ASSERT_TRUE(store.hasBlockListAction("M1", BlockListKeyKind::ModuleName, BlockListAction::ShouldUseBinaryModule));
98+
ASSERT_TRUE(store.hasBlockListAction("M2", BlockListKeyKind::ModuleName, BlockListAction::ShouldUseBinaryModule));
99+
ASSERT_TRUE(store.hasBlockListAction("P1", BlockListKeyKind::ProjectName, BlockListAction::ShouldUseBinaryModule));
100+
ASSERT_TRUE(store.hasBlockListAction("P2", BlockListKeyKind::ProjectName, BlockListAction::ShouldUseBinaryModule));
101+
102+
ASSERT_TRUE(store.hasBlockListAction("M1_2", BlockListKeyKind::ModuleName, BlockListAction::ShouldUseTextualModule));
103+
ASSERT_TRUE(store.hasBlockListAction("M2_2", BlockListKeyKind::ModuleName, BlockListAction::ShouldUseTextualModule));
104+
ASSERT_TRUE(store.hasBlockListAction("P1_2", BlockListKeyKind::ProjectName, BlockListAction::ShouldUseTextualModule));
105+
ASSERT_TRUE(store.hasBlockListAction("P2_2", BlockListKeyKind::ProjectName, BlockListAction::ShouldUseTextualModule));
106+
107+
ASSERT_FALSE(store.hasBlockListAction("P1", BlockListKeyKind::ModuleName, BlockListAction::ShouldUseBinaryModule));
108+
ASSERT_FALSE(store.hasBlockListAction("P2", BlockListKeyKind::ModuleName, BlockListAction::ShouldUseBinaryModule));
109+
ASSERT_FALSE(store.hasBlockListAction("M1", BlockListKeyKind::ProjectName, BlockListAction::ShouldUseBinaryModule));
110+
ASSERT_FALSE(store.hasBlockListAction("M2", BlockListKeyKind::ProjectName, BlockListAction::ShouldUseBinaryModule));
111+
112+
ASSERT_TRUE(store.hasBlockListAction("M1_block2", BlockListKeyKind::ModuleName, BlockListAction::ShouldUseBinaryModule));
113+
ASSERT_TRUE(store.hasBlockListAction("P1_block2", BlockListKeyKind::ProjectName, BlockListAction::ShouldUseBinaryModule));
114+
ASSERT_TRUE(store.hasBlockListAction("M1_2_block2", BlockListKeyKind::ModuleName, BlockListAction::ShouldUseTextualModule));
115+
ASSERT_TRUE(store.hasBlockListAction("P1_2_block2", BlockListKeyKind::ProjectName, BlockListAction::ShouldUseTextualModule));
116+
117+
ASSERT_FALSE(store.hasBlockListAction("M1_block2", BlockListKeyKind::ProjectName, BlockListAction::ShouldUseBinaryModule));
118+
ASSERT_FALSE(store.hasBlockListAction("P1_block2", BlockListKeyKind::ModuleName, BlockListAction::ShouldUseBinaryModule));
119+
ASSERT_FALSE(store.hasBlockListAction("M1_2_block2", BlockListKeyKind::ProjectName, BlockListAction::ShouldUseTextualModule));
120+
ASSERT_FALSE(store.hasBlockListAction("P1_2_block2", BlockListKeyKind::ModuleName, BlockListAction::ShouldUseTextualModule));
121+
}

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)