1 // Copyright 2018 The Fuchsia Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 #ifndef ZIRCON_SYSTEM_UTEST_BANJO_COMPILER_TEST_LIBRARY_H_
6 #define ZIRCON_SYSTEM_UTEST_BANJO_COMPILER_TEST_LIBRARY_H_
7
8 #include <banjo/flat_ast.h>
9 #include <banjo/json_generator.h>
10 #include <banjo/lexer.h>
11 #include <banjo/parser.h>
12 #include <banjo/source_file.h>
13
MakeSourceFile(const std::string & filename,const std::string & raw_source_code)14 static banjo::SourceFile MakeSourceFile(const std::string& filename, const std::string& raw_source_code) {
15 std::string source_code(raw_source_code);
16 // NUL terminate the string.
17 source_code.resize(source_code.size() + 1);
18 return banjo::SourceFile(filename, source_code);
19 }
20
21 class TestLibrary {
22 public:
TestLibrary(const std::string & raw_source_code)23 TestLibrary(const std::string& raw_source_code)
24 : TestLibrary("example.banjo", raw_source_code) {}
25
TestLibrary(const std::string & filename,const std::string & raw_source_code)26 TestLibrary(const std::string& filename, const std::string& raw_source_code)
27 : source_file_(MakeSourceFile(filename, raw_source_code)),
28 lexer_(source_file_, &identifier_table_),
29 parser_(&lexer_, &error_reporter_),
30 library_(std::make_unique<banjo::flat::Library>(&all_libraries_, &error_reporter_)) {
31 }
32
AddDependentLibrary(TestLibrary & dependent_library)33 bool AddDependentLibrary(TestLibrary& dependent_library) {
34 // For testing, we have conveniences to construct compiled test
35 // libraries, which we usurp here to move it into the current library
36 // under test. This would be made clearer with a helper object which
37 // owned all libraries under test.
38 if (!all_libraries_.Insert(std::unique_ptr<banjo::flat::Library>(dependent_library.library_.get()))) {
39 return false;
40 }
41 dependent_library.library_.release();
42 return true;
43 }
44
Parse(std::unique_ptr<banjo::raw::File> & ast_ptr)45 bool Parse(std::unique_ptr<banjo::raw::File>& ast_ptr) {
46 ast_ptr.reset(parser_.Parse().release());
47 return parser_.Ok();
48 }
49
Compile()50 bool Compile() {
51 auto ast = parser_.Parse();
52 return parser_.Ok() &&
53 library_->ConsumeFile(std::move(ast)) &&
54 library_->Compile();
55 }
56
GenerateJSON()57 std::string GenerateJSON() {
58 auto json_generator = banjo::JSONGenerator(library_.get());
59 auto out = json_generator.Produce();
60 return out.str();
61 }
62
AddSourceFile(const std::string & filename,const std::string & raw_source_code)63 bool AddSourceFile(const std::string& filename, const std::string& raw_source_code) {
64 auto source_file = MakeSourceFile(filename, raw_source_code);
65 banjo::IdentifierTable identifier_table;
66 banjo::Lexer lexer(source_file, &identifier_table);
67 banjo::Parser parser(&lexer, &error_reporter_);
68 auto ast = parser.Parse();
69 return parser.Ok() &&
70 library_->ConsumeFile(std::move(ast)) &&
71 library_->Compile();
72 }
73
LookupStruct(const std::string & name)74 const banjo::flat::Struct* LookupStruct(const std::string& name) {
75 for (const auto& struct_decl : library_->struct_declarations_) {
76 if (struct_decl->GetName() == name) {
77 return struct_decl.get();
78 }
79 }
80 return nullptr;
81 }
82
LookupUnion(const std::string & name)83 const banjo::flat::Union* LookupUnion(const std::string& name) {
84 for (const auto& union_decl : library_->union_declarations_) {
85 if (union_decl->GetName() == name) {
86 return union_decl.get();
87 }
88 }
89 return nullptr;
90 }
91
LookupInterface(const std::string & name)92 const banjo::flat::Interface* LookupInterface(const std::string& name) {
93 for (const auto& interface_decl : library_->interface_declarations_) {
94 if (interface_decl->GetName() == name) {
95 return interface_decl.get();
96 }
97 }
98 return nullptr;
99 }
100
source_file()101 banjo::SourceFile source_file() {
102 return source_file_;
103 }
104
errors()105 const std::vector<std::string>& errors() const {
106 return error_reporter_.errors();
107 }
108
109 private:
110 banjo::SourceFile source_file_;
111 banjo::IdentifierTable identifier_table_;
112 banjo::ErrorReporter error_reporter_;
113 banjo::Lexer lexer_;
114 banjo::Parser parser_;
115 banjo::flat::Libraries all_libraries_;
116 std::unique_ptr<banjo::flat::Library> library_;
117 };
118
119 #endif // ZIRCON_SYSTEM_UTEST_BANJO_COMPILER_TEST_LIBRARY_H_
120