3232#include < emscripten/val.h>
3333
3434#include < format>
35+ #include < iostream>
3536#include < sstream>
3637
3738using namespace emscripten ;
@@ -61,42 +62,121 @@ struct DiagnosticsClient final : cxx::DiagnosticsClient {
6162struct WrappedUnit {
6263 std::unique_ptr<DiagnosticsClient> diagnosticsClient;
6364 std::unique_ptr<cxx::TranslationUnit> unit;
65+ val api;
6466
65- WrappedUnit (std::string source, std::string filename) {
67+ WrappedUnit (std::string source, std::string filename, val api = {})
68+ : api(api) {
6669 diagnosticsClient = std::make_unique<DiagnosticsClient>();
70+
6771 unit = std::make_unique<cxx::TranslationUnit>(diagnosticsClient.get ());
72+
6873 if (auto preprocessor = unit->preprocessor ()) {
69- preprocessor->setCanResolveFiles (false );
74+ preprocessor->setCanResolveFiles (true );
7075 }
7176
72- unit->setSource (std::move (source), std::move (filename));
77+ unit->beginPreprocessing (std::move (source), std::move (filename));
78+ }
79+
80+ auto getUnitHandle () const -> std::intptr_t {
81+ return (std::intptr_t )unit.get ();
7382 }
7483
75- std:: intptr_t getUnitHandle () const { return (std::intptr_t )unit. get (); }
84+ auto getHandle () const -> std::intptr_t { return (std::intptr_t )unit-> ast (); }
7685
77- std:: intptr_t getHandle () const { return (std:: intptr_t )unit-> ast () ; }
86+ auto getDiagnostics () const -> val { return diagnosticsClient-> messages ; }
7887
79- val getDiagnostics () const { return diagnosticsClient->messages ; }
88+ auto parse () -> val {
89+ val resolve = val::undefined ();
90+
91+ if (!api.isUndefined ()) {
92+ resolve = api[" resolve" ];
93+ }
94+
95+ struct {
96+ auto operator ()(const cxx::SystemInclude& include) -> val {
97+ return val (include.fileName );
98+ }
99+ auto operator ()(const cxx::QuoteInclude& include) -> val {
100+ return val (include.fileName );
101+ }
102+ } getHeaderName;
103+
104+ struct {
105+ val quoted{" quoted" };
106+ val angled{" angled" };
107+
108+ auto operator ()(const cxx::SystemInclude& include) -> val {
109+ return angled;
110+ }
111+ auto operator ()(const cxx::QuoteInclude& include) -> val {
112+ return quoted;
113+ }
114+ } getIncludeType;
115+
116+ while (true ) {
117+ auto state = unit->continuePreprocessing ();
118+
119+ if (std::holds_alternative<cxx::ProcessingComplete>(state)) break ;
120+
121+ if (auto pendingInclude = std::get_if<cxx::PendingInclude>(&state)) {
122+ if (resolve.isUndefined ()) {
123+ pendingInclude->resolveWith (std::nullopt );
124+ continue ;
125+ }
126+
127+ auto header = std::visit (getHeaderName, pendingInclude->include );
128+ auto includeType = std::visit (getIncludeType, pendingInclude->include );
129+
130+ val resolved = co_await resolve (header, includeType,
131+ pendingInclude->isIncludeNext );
132+
133+ if (resolved.isString ()) {
134+ pendingInclude->resolveWith (resolved.as <std::string>());
135+ } else {
136+ pendingInclude->resolveWith (std::nullopt );
137+ }
138+
139+ } else if (auto pendingHasIncludes =
140+ std::get_if<cxx::PendingHasIncludes>(&state)) {
141+ for (auto & request : pendingHasIncludes->requests ) {
142+ if (resolve.isUndefined ()) {
143+ request.setExists (false );
144+ continue ;
145+ }
146+
147+ auto header = std::visit (getHeaderName, request.include );
148+ auto includeType = std::visit (getIncludeType, request.include );
149+
150+ val resolved =
151+ co_await resolve (header, includeType, request.isIncludeNext );
152+
153+ request.setExists (resolved.isString ());
154+ }
155+ }
156+ }
157+
158+ unit->endPreprocessing ();
80159
81- bool parse () {
82160 unit->parse ();
83- return true ;
161+
162+ co_return val{true };
84163 }
85164};
86165
87- std::string getTokenText (std::intptr_t handle, std::intptr_t unitHandle) {
166+ auto getTokenText (std::intptr_t handle, std::intptr_t unitHandle)
167+ -> std::string {
88168 auto unit = reinterpret_cast <cxx::TranslationUnit*>(unitHandle);
89169 auto text = unit->tokenText (cxx::SourceLocation (handle));
90170 return text;
91171}
92172
93- int getTokenKind (std::intptr_t handle, std::intptr_t unitHandle) {
173+ auto getTokenKind (std::intptr_t handle, std::intptr_t unitHandle) -> int {
94174 auto unit = reinterpret_cast <cxx::TranslationUnit*>(unitHandle);
95175 auto kind = unit->tokenKind (cxx::SourceLocation (handle));
96176 return static_cast <int >(kind);
97177}
98178
99- val getTokenLocation (std::intptr_t handle, std::intptr_t unitHandle) {
179+ auto getTokenLocation (std::intptr_t handle, std::intptr_t unitHandle) -> val {
100180 auto unit = reinterpret_cast <cxx::TranslationUnit*>(unitHandle);
101181
102182 cxx::SourceLocation loc (handle);
@@ -114,71 +194,71 @@ val getTokenLocation(std::intptr_t handle, std::intptr_t unitHandle) {
114194 return result;
115195}
116196
117- val getStartLocation (std::intptr_t handle, std::intptr_t unitHandle) {
197+ auto getStartLocation (std::intptr_t handle, std::intptr_t unitHandle) -> val {
118198 auto ast = reinterpret_cast <cxx::AST*>(handle);
119199 const auto loc = ast->firstSourceLocation ();
120200 if (!loc) return {};
121201 return getTokenLocation (loc.index (), unitHandle);
122202}
123203
124- val getEndLocation (std::intptr_t handle, std::intptr_t unitHandle) {
204+ auto getEndLocation (std::intptr_t handle, std::intptr_t unitHandle) -> val {
125205 auto ast = reinterpret_cast <cxx::AST*>(handle);
126206 const auto loc = ast->lastSourceLocation ().previous ();
127207 if (!loc) return {};
128208 return getTokenLocation (loc.index (), unitHandle);
129209}
130210
131- val getIdentifierValue (std::intptr_t handle) {
211+ auto getIdentifierValue (std::intptr_t handle) -> val {
132212 auto id = reinterpret_cast <const cxx::Identifier*>(handle);
133213 if (!id) return {};
134214 return val (id->value ());
135215}
136216
137- val getLiteralValue (std::intptr_t handle) {
217+ auto getLiteralValue (std::intptr_t handle) -> val {
138218 auto id = reinterpret_cast <const cxx::Literal*>(handle);
139219 if (!id) return {};
140220 return val (id->value ());
141221}
142222
143- int getASTKind (std::intptr_t handle) {
223+ auto getASTKind (std::intptr_t handle) -> int {
144224 return static_cast <int >(((cxx::AST*)handle)->kind ());
145225}
146226
147- int getListValue (std::intptr_t handle) {
227+ auto getListValue (std::intptr_t handle) -> int {
148228 auto list = reinterpret_cast <cxx::List<cxx::AST*>*>(handle);
149229 return std::intptr_t (list->value );
150230}
151231
152- std:: intptr_t getListNext (std::intptr_t handle) {
232+ auto getListNext (std::intptr_t handle) -> std::intptr_t {
153233 auto list = reinterpret_cast <cxx::List<cxx::AST*>*>(handle);
154234 return std::intptr_t (list->next );
155235}
156236
157- std:: intptr_t getASTSlot (std::intptr_t handle, int slot) {
237+ auto getASTSlot (std::intptr_t handle, int slot) -> std::intptr_t {
158238 auto ast = reinterpret_cast <cxx::AST*>(handle);
159239 auto [value, slotKind, slotNameIndex, slotCount] = getSlot (ast, slot);
160240 return value;
161241}
162242
163- int getASTSlotKind (std::intptr_t handle, int slot) {
243+ auto getASTSlotKind (std::intptr_t handle, int slot) -> int {
164244 auto ast = reinterpret_cast <cxx::AST*>(handle);
165245 auto [value, slotKind, slotNameIndex, slotCount] = getSlot (ast, slot);
166246 return static_cast <int >(slotKind);
167247}
168248
169- int getASTSlotName (std::intptr_t handle, int slot) {
249+ auto getASTSlotName (std::intptr_t handle, int slot) -> int {
170250 auto ast = reinterpret_cast <cxx::AST*>(handle);
171251 auto [value, slotKind, slotName, slotCount] = getSlot (ast, slot);
172252 return static_cast <int >(slotName);
173253}
174254
175- int getASTSlotCount (std::intptr_t handle, int slot) {
255+ auto getASTSlotCount (std::intptr_t handle, int slot) -> int {
176256 auto ast = reinterpret_cast <cxx::AST*>(handle);
177257 auto [value, slotKind, slotNameIndex, slotCount] = getSlot (ast, slot);
178258 return static_cast <int >(slotCount);
179259}
180260
181- WrappedUnit* createUnit (std::string source, std::string filename) {
261+ auto createUnit (std::string source, std::string filename) -> WrappedUnit* {
182262 auto wrapped = new WrappedUnit (std::move (source), std::move (filename));
183263
184264 return wrapped;
@@ -196,17 +276,6 @@ auto lexerNext(cxx::Lexer& lexer) -> int {
196276 return static_cast <int >(lexer.next ());
197277}
198278
199- void preprocessorSetup (cxx::Preprocessor& preprocessor, val fileExistsFn,
200- val readFileFn) {
201- preprocessor.setFileExistsFunction ([fileExistsFn](std::string fileName) {
202- return fileExistsFn (fileName).as <bool >();
203- });
204-
205- preprocessor.setReadFileFunction ([readFileFn](std::string fileName) {
206- return readFileFn (fileName).as <std::string>();
207- });
208- }
209-
210279auto preprocesorPreprocess (cxx::Preprocessor& preprocessor, std::string source,
211280 std::string filename) -> std::string {
212281 std::vector<cxx::Token> tokens;
@@ -241,7 +310,6 @@ auto register_preprocessor(const char* name = "Preprocessor")
241310 return class_<cxx::Preprocessor>(name)
242311 .constructor <cxx::Control*, cxx::DiagnosticsClient*>()
243312 .function (" preprocess" , &preprocesorPreprocess)
244- .function (" setup" , &preprocessorSetup)
245313 .function (" addIncludePath" , &cxx::Preprocessor::addSystemIncludePath)
246314 .function (" defineMacro" , &cxx::Preprocessor::defineMacro)
247315 .function (" undefineMacro" , &cxx::Preprocessor::undefMacro)
@@ -283,7 +351,7 @@ auto register_translation_unit(const char* name = "TranslationUnit")
283351
284352} // namespace
285353
286- EMSCRIPTEN_BINDINGS (my_module ) {
354+ EMSCRIPTEN_BINDINGS (cxx ) {
287355 register_control ();
288356 register_diagnostics_client ();
289357 register_preprocessor ();
0 commit comments