@@ -184,6 +184,26 @@ std::vector<SourceBuffer> SourceLoader::loadSources() {
184184 return results;
185185}
186186
187+ SourceBuffer SourceLoader::findBuffer (std::string_view name) const {
188+ for (auto & dir : searchDirectories) {
189+ fs::path path (dir);
190+ path /= name;
191+
192+ for (auto & ext : searchExtensions) {
193+ path.replace_extension (ext);
194+ if (!sourceManager.isCached (path)) {
195+ // This file is never part of a library because if
196+ // it was we would have already loaded it earlier.
197+ auto readResult = sourceManager.readSource (path, /* library */ nullptr );
198+ if (readResult) {
199+ return *readResult;
200+ }
201+ }
202+ }
203+ }
204+ return {};
205+ }
206+
187207SourceLoader::SyntaxTreeList SourceLoader::loadAndParseSources (const Bag& optionBag) {
188208 SyntaxTreeList syntaxTrees;
189209 std::vector<SourceBuffer> singleUnitBuffers;
@@ -332,76 +352,65 @@ SourceLoader::SyntaxTreeList SourceLoader::loadAndParseSources(const Bag& option
332352 }
333353
334354 if (!searchDirectories.empty ()) {
335- // If library directories are specified, see if we have any unknown instantiations
336- // or package names for which we should search for additional source files to load.
337- flat_hash_set<std::string_view> knownNames;
338- auto addKnownNames = [&](const std::shared_ptr<SyntaxTree>& tree) {
339- auto & meta = tree->getMetadata ();
340- meta.visitDeclaredSymbols ([&](std::string_view name) { knownNames.emplace (name); });
341- };
342-
343- auto findMissingNames = [&](const std::shared_ptr<SyntaxTree>& tree,
344- flat_hash_set<std::string_view>& missing) {
345- auto & meta = tree->getMetadata ();
346- meta.visitReferencedSymbols ([&](std::string_view name) {
347- if (knownNames.find (name) == knownNames.end ())
348- missing.emplace (name);
349- });
350- };
351-
352- for (auto & tree : syntaxTrees)
353- addKnownNames (tree);
354-
355- flat_hash_set<std::string_view> missingNames;
356- for (auto & tree : syntaxTrees)
357- findMissingNames (tree, missingNames);
358-
359- // Keep loading new files as long as we are making forward progress.
360- flat_hash_set<std::string_view> nextMissingNames;
361- while (true ) {
362- for (auto name : missingNames) {
363- SourceBuffer buffer;
364- for (auto & dir : searchDirectories) {
365- fs::path path (dir);
366- path /= name;
367-
368- for (auto & ext : searchExtensions) {
369- path.replace_extension (ext);
370- if (!sourceManager.isCached (path)) {
371- // This file is never part of a library because if
372- // it was we would have already loaded it earlier.
373- auto readResult = sourceManager.readSource (path, /* library */ nullptr );
374- if (readResult) {
375- buffer = *readResult;
376- break ;
377- }
378- }
379- }
355+ loadTrees (
356+ syntaxTrees, [this ](std::string_view name) { return findBuffer (name); }, sourceManager,
357+ optionBag, inheritedMacros);
358+ }
380359
381- if (buffer)
382- break ;
383- }
360+ return syntaxTrees;
361+ }
384362
385- if (buffer) {
386- auto tree = SyntaxTree::fromBuffer (buffer, sourceManager, optionBag,
387- inheritedMacros);
388- tree->isLibraryUnit = true ;
389- syntaxTrees.emplace_back (tree);
363+ void SourceLoader::loadTrees (
364+ SyntaxTreeList& syntaxTrees, function_ref<SourceBuffer(std::string_view)> findBufferFunc,
365+ SourceManager& sourceManager, const Bag& optionBag,
366+ std::span<const syntax::DefineDirectiveSyntax* const > inheritedMacros) {
367+ // If library directories are specified, see if we have any unknown instantiations
368+ // or package names for which we should search for additional source files to load.
369+ flat_hash_set<std::string_view> knownNames;
370+ auto addKnownNames = [&](const std::shared_ptr<syntax::SyntaxTree>& tree) {
371+ auto & meta = tree->getMetadata ();
372+ meta.visitDeclaredSymbols ([&](std::string_view name) { knownNames.emplace (name); });
373+ };
390374
391- addKnownNames (tree);
392- findMissingNames (tree, nextMissingNames);
393- }
394- }
375+ auto findMissingNames = [&](const std::shared_ptr<syntax::SyntaxTree>& tree,
376+ flat_hash_set<std::string_view>& missing) {
377+ auto & meta = tree->getMetadata ();
378+ meta.visitReferencedSymbols ([&](std::string_view name) {
379+ if (knownNames.find (name) == knownNames.end ())
380+ missing.emplace (name);
381+ });
382+ };
395383
396- if (nextMissingNames. empty () )
397- break ;
384+ for ( auto & tree : syntaxTrees )
385+ addKnownNames (tree) ;
398386
399- missingNames = std::move (nextMissingNames);
400- nextMissingNames = {};
387+ flat_hash_set<std::string_view> missingNames;
388+ for (auto & tree : syntaxTrees)
389+ findMissingNames (tree, missingNames);
390+
391+ // Keep loading new files as long as we are making forward progress.
392+ flat_hash_set<std::string_view> nextMissingNames;
393+ while (true ) {
394+ for (auto name : missingNames) {
395+ auto buffer = findBufferFunc (name);
396+
397+ if (buffer) {
398+ auto tree = syntax::SyntaxTree::fromBuffer (buffer, sourceManager, optionBag,
399+ inheritedMacros);
400+ tree->isLibraryUnit = true ;
401+ syntaxTrees.emplace_back (tree);
402+
403+ addKnownNames (tree);
404+ findMissingNames (tree, nextMissingNames);
405+ }
401406 }
402- }
403407
404- return syntaxTrees;
408+ if (nextMissingNames.empty ())
409+ break ;
410+
411+ missingNames = std::move (nextMissingNames);
412+ nextMissingNames = {};
413+ }
405414}
406415
407416SourceLibrary* SourceLoader::getOrAddLibrary (std::string_view name) {
0 commit comments