Skip to content

Commit d381e0a

Browse files
committed
WIP
1 parent 350ad43 commit d381e0a

1 file changed

Lines changed: 153 additions & 20 deletions

File tree

tools/wit-codegen/code_generator.cpp

Lines changed: 153 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -1766,11 +1766,18 @@ void CodeGenerator::generateExternalPackageStubs(std::ofstream &out,
17661766
{
17671767
for (const auto &use_stmt : iface.use_statements)
17681768
{
1769-
if (!use_stmt.source_package.empty() &&
1770-
external_packages.find(use_stmt.source_package) == external_packages.end())
1769+
if (!use_stmt.source_package.empty())
17711770
{
1772-
newly_discovered.insert(use_stmt.source_package);
1773-
external_packages.insert(use_stmt.source_package);
1771+
if (!use_stmt.source_interface.empty())
1772+
{
1773+
package_interfaces[use_stmt.source_package].insert(use_stmt.source_interface);
1774+
}
1775+
1776+
if (external_packages.find(use_stmt.source_package) == external_packages.end())
1777+
{
1778+
newly_discovered.insert(use_stmt.source_package);
1779+
external_packages.insert(use_stmt.source_package);
1780+
}
17741781
}
17751782
}
17761783
}
@@ -1855,23 +1862,102 @@ void CodeGenerator::generateExternalPackageStubs(std::ofstream &out,
18551862
out << "namespace " << cpp_namespace << " {\n";
18561863

18571864
// Determine which interfaces to generate
1858-
std::set<std::string> interfaces_to_generate;
1865+
std::set<std::string> requested_interfaces;
18591866
if (package_interfaces.count(package_spec) && !package_interfaces[package_spec].empty())
18601867
{
18611868
// Specific interfaces requested via use statements
1862-
interfaces_to_generate = package_interfaces[package_spec];
1869+
requested_interfaces = package_interfaces[package_spec];
18631870
}
18641871
else
18651872
{
18661873
// Generate all interfaces in the package (for world imports/exports)
18671874
for (const auto &iface : package->interfaces)
18681875
{
1869-
interfaces_to_generate.insert(iface.name);
1876+
requested_interfaces.insert(iface.name);
18701877
}
18711878
}
18721879

1873-
// Generate stub interfaces
1880+
// Expand requested interfaces to include same-package dependencies via use statements
1881+
std::set<std::string> interfaces_to_generate;
1882+
std::function<void(const std::string &)> add_interface_with_deps = [&](const std::string &iface_name)
1883+
{
1884+
if (!interfaces_to_generate.insert(iface_name).second)
1885+
{
1886+
return; // already processed
1887+
}
1888+
1889+
if (auto *iface_ptr_dep = package->get_interface(iface_name))
1890+
{
1891+
for (const auto &use_stmt_dep : iface_ptr_dep->use_statements)
1892+
{
1893+
if (use_stmt_dep.source_package.empty() && !use_stmt_dep.source_interface.empty())
1894+
{
1895+
add_interface_with_deps(use_stmt_dep.source_interface);
1896+
}
1897+
}
1898+
}
1899+
};
1900+
1901+
if (!requested_interfaces.empty())
1902+
{
1903+
for (const auto &iface_name : requested_interfaces)
1904+
{
1905+
add_interface_with_deps(iface_name);
1906+
}
1907+
}
1908+
else
1909+
{
1910+
for (const auto &iface : package->interfaces)
1911+
{
1912+
add_interface_with_deps(iface.name);
1913+
}
1914+
}
1915+
1916+
// Build dependency map for ordering (same-package dependencies only)
1917+
std::map<std::string, std::set<std::string>> interface_deps;
18741918
for (const auto &iface_name : interfaces_to_generate)
1919+
{
1920+
if (auto *iface_ptr_dep = package->get_interface(iface_name))
1921+
{
1922+
for (const auto &use_stmt_dep : iface_ptr_dep->use_statements)
1923+
{
1924+
if (use_stmt_dep.source_package.empty() && !use_stmt_dep.source_interface.empty() &&
1925+
interfaces_to_generate.count(use_stmt_dep.source_interface))
1926+
{
1927+
interface_deps[iface_name].insert(use_stmt_dep.source_interface);
1928+
}
1929+
}
1930+
}
1931+
}
1932+
1933+
std::vector<std::string> interface_order;
1934+
std::set<std::string> visited_interfaces;
1935+
std::function<void(const std::string &)> visit_interface = [&](const std::string &iface_name)
1936+
{
1937+
if (visited_interfaces.count(iface_name))
1938+
{
1939+
return;
1940+
}
1941+
visited_interfaces.insert(iface_name);
1942+
1943+
if (interface_deps.count(iface_name))
1944+
{
1945+
for (const auto &dep : interface_deps[iface_name])
1946+
{
1947+
visit_interface(dep);
1948+
}
1949+
}
1950+
1951+
interface_order.push_back(iface_name);
1952+
};
1953+
1954+
for (const auto &iface_name : interfaces_to_generate)
1955+
{
1956+
visit_interface(iface_name);
1957+
}
1958+
1959+
// Generate stub interfaces
1960+
for (const auto &iface_name : interface_order)
18751961
{
18761962
auto *iface_ptr = package->get_interface(iface_name);
18771963
if (!iface_ptr)
@@ -1881,27 +1967,74 @@ void CodeGenerator::generateExternalPackageStubs(std::ofstream &out,
18811967

18821968
out << " namespace " << sanitize_identifier(iface_name) << " {\n";
18831969

1884-
// Generate use declarations (type imports from other packages)
1970+
// Generate use declarations (type imports from other packages or interfaces)
1971+
auto emit_using_decls = [&](const UseStatement &use_stmt, const std::string &ns_prefix)
1972+
{
1973+
for (const auto &type_name : use_stmt.imported_types)
1974+
{
1975+
std::string local_name = use_stmt.type_renames.count(type_name)
1976+
? use_stmt.type_renames.at(type_name)
1977+
: type_name;
1978+
out << " using " << sanitize_identifier(local_name)
1979+
<< " = ::" << ns_prefix << "::" << sanitize_identifier(use_stmt.source_interface)
1980+
<< "::" << sanitize_identifier(type_name) << ";\n";
1981+
}
1982+
};
1983+
1984+
bool emitted_use_decl = false;
18851985
for (const auto &use_stmt : iface_ptr->use_statements)
18861986
{
18871987
if (!use_stmt.source_package.empty())
18881988
{
1889-
// This is a cross-package use - generate using declaration
1890-
auto use_pkg_id = PackageId::parse(use_stmt.source_package);
1891-
if (use_pkg_id)
1989+
// Cross-package use statement
1990+
if (auto use_pkg_id = PackageId::parse(use_stmt.source_package))
18921991
{
1893-
std::string use_cpp_ns = use_pkg_id->to_cpp_namespace();
1894-
for (const auto &type_name : use_stmt.imported_types)
1992+
emit_using_decls(use_stmt, use_pkg_id->to_cpp_namespace());
1993+
emitted_use_decl = true;
1994+
}
1995+
}
1996+
else if (!use_stmt.source_interface.empty() && use_stmt.source_interface != iface_name)
1997+
{
1998+
// Same-package interface reference
1999+
emit_using_decls(use_stmt, cpp_namespace);
2000+
emitted_use_decl = true;
2001+
}
2002+
}
2003+
2004+
if (emitted_use_decl)
2005+
{
2006+
out << "\n";
2007+
}
2008+
2009+
// Generate resource handle stubs
2010+
if (!iface_ptr->resources.empty())
2011+
{
2012+
for (const auto &resource : iface_ptr->resources)
2013+
{
2014+
out << " // Resource type (handle represented as uint32_t): "
2015+
<< resource.name << "\n";
2016+
out << " using " << sanitize_identifier(resource.name) << " = uint32_t;\n";
2017+
}
2018+
out << "\n";
2019+
}
2020+
2021+
// Generate flag definitions
2022+
if (!iface_ptr->flags.empty())
2023+
{
2024+
for (const auto &flags_def : iface_ptr->flags)
2025+
{
2026+
out << " using " << sanitize_identifier(flags_def.name) << " = cmcpp::flags_t<";
2027+
for (size_t i = 0; i < flags_def.flags.size(); ++i)
2028+
{
2029+
out << "\"" << sanitize_identifier(flags_def.flags[i]) << "\"";
2030+
if (i < flags_def.flags.size() - 1)
18952031
{
1896-
std::string local_name = use_stmt.type_renames.count(type_name)
1897-
? use_stmt.type_renames.at(type_name)
1898-
: type_name;
1899-
out << " using " << sanitize_identifier(local_name)
1900-
<< " = ::" << use_cpp_ns << "::" << sanitize_identifier(use_stmt.source_interface)
1901-
<< "::" << sanitize_identifier(type_name) << ";\n";
2032+
out << ", ";
19022033
}
19032034
}
2035+
out << ">;\n";
19042036
}
2037+
out << "\n";
19052038
}
19062039

19072040
// Generate type aliases for types used from this interface

0 commit comments

Comments
 (0)