From daf209e4ae7015c6b8b54c449a0d96fdd78f2f98 Mon Sep 17 00:00:00 2001 From: Prasanna Swaminathan Date: Sun, 22 May 2022 14:45:40 -0400 Subject: [PATCH] Add support for parsing multiple modules (#144) * Add support for parsing multiple modules * Allow multiple modules for header collection --- .../modulemap_parser/collect_module.bzl | 2 + spm/private/spm_repositories.bzl | 19 +++--- .../modulemap_parser/collect_module_tests.bzl | 63 +++++++++++++++++++ 3 files changed, 73 insertions(+), 11 deletions(-) diff --git a/spm/private/modulemap_parser/collect_module.bzl b/spm/private/modulemap_parser/collect_module.bzl index 508adca8..f074b387 100644 --- a/spm/private/modulemap_parser/collect_module.bzl +++ b/spm/private/modulemap_parser/collect_module.bzl @@ -118,6 +118,8 @@ def collect_module(parsed_tokens, is_submodule = False, prefix_tokens = []): if err != None: return None, err members.extend(collect_result.declarations) + consumed_count += collect_result.count - 1 + break elif tokens.is_a(token, tts.square_bracket_open): collect_result, err = _collect_attribute(parsed_tokens[idx:]) diff --git a/spm/private/spm_repositories.bzl b/spm/private/spm_repositories.bzl index e82ede7a..5c5abf0b 100644 --- a/spm/private/spm_repositories.bzl +++ b/spm/private/spm_repositories.bzl @@ -338,21 +338,18 @@ def _get_hdr_paths_from_modulemap(repository_ctx, modulemap_path): fail("Errors parsing the %s. %s" % (modulemap_path, err)) module_decls = [d for d in decls if d.decl_type == dts.module] - module_decls_len = len(module_decls) - if module_decls_len == 0: + if len(module_decls) == 0: fail("No module declarations were found in %s." % (modulemap_path)) - if module_decls_len > 1: - fail("Expected a single module definition but found %s." % (module_decls_len)) - module_decl = module_decls[0] modulemap_dirname = paths.dirname(modulemap_path) hdrs = [] - for cdecl in module_decl.members: - if cdecl.decl_type == dts.single_header and not cdecl.private and not cdecl.textual: - # Resolve the path relative to the modulemap - hdr_path = paths.join(modulemap_dirname, cdecl.path) - normalized_hdr_path = paths.normalize(hdr_path) - hdrs.append(normalized_hdr_path) + for module_decl in module_decls: + for cdecl in module_decl.members: + if cdecl.decl_type == dts.single_header and not cdecl.private and not cdecl.textual: + # Resolve the path relative to the modulemap + hdr_path = paths.join(modulemap_dirname, cdecl.path) + normalized_hdr_path = paths.normalize(hdr_path) + hdrs.append(normalized_hdr_path) return hdrs diff --git a/test/modulemap_parser/collect_module_tests.bzl b/test/modulemap_parser/collect_module_tests.bzl index efbecb27..4b21e2b4 100644 --- a/test/modulemap_parser/collect_module_tests.bzl +++ b/test/modulemap_parser/collect_module_tests.bzl @@ -29,6 +29,69 @@ def _collect_module_test(ctx): ], ) + do_parse_test( + env, + "module with members", + text = """ + module MyModule { + header "SomeHeader.h" + } + """, + expected = [ + declarations.module( + module_id = "MyModule", + framework = False, + explicit = False, + attributes = [], + members = [ + struct(attribs = None, decl_type = "single_header", path = "SomeHeader.h", private = False, textual = False), + ], + ), + ], + ) + + do_parse_test( + env, + "two modules with members and exports with newlines", + text = """ + module MyModule { + header "SomeHeader.h" + header "SomeOtherHeader.h" + export * + } + + module MyModuleTwo { + header "SecondHeader.h" + header "ThirdHeader.h" + export * + } + """, + expected = [ + declarations.module( + module_id = "MyModule", + framework = False, + explicit = False, + attributes = [], + members = [ + struct(attribs = None, decl_type = "single_header", path = "SomeHeader.h", private = False, textual = False), + struct(attribs = None, decl_type = "single_header", path = "SomeOtherHeader.h", private = False, textual = False), + struct(decl_type = "export", identifiers = [], wildcard = True), + ], + ), + declarations.module( + module_id = "MyModuleTwo", + framework = False, + explicit = False, + attributes = [], + members = [ + struct(attribs = None, decl_type = "single_header", path = "SecondHeader.h", private = False, textual = False), + struct(attribs = None, decl_type = "single_header", path = "ThirdHeader.h", private = False, textual = False), + struct(decl_type = "export", identifiers = [], wildcard = True), + ], + ), + ], + ) + do_parse_test( env, "module with qualifiers",