Skip to content

Commit 701d755

Browse files
authored
fix: parsing modulemaps with comments (#1105)
Fixes the tokenizer and modulemap parser to support C99 formatted comments. This is probably not amazing but we'll be able to move off this soon: bazelbuild/rules_swift#1212
1 parent b89c552 commit 701d755

File tree

3 files changed

+66
-1
lines changed

3 files changed

+66
-1
lines changed

swiftpkg/internal/modulemap_parser/parser.bzl

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@ def _parse(text):
2626
collect_result = None
2727
err = None
2828

29-
if token.type == tts.newline:
29+
if token.type == tts.newline or token.type == tts.comment:
3030
pass
3131

3232
elif token.type == tts.reserved:

swiftpkg/internal/modulemap_parser/tokenizer.bzl

Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,41 @@ def _error(char, msg):
3636
msg = msg,
3737
)
3838

39+
def _collect_single_line_comment(chars):
40+
collected_chars = []
41+
42+
for char in chars:
43+
if char == "\n":
44+
break
45+
collected_chars.append(char)
46+
47+
return _collection_result(
48+
chars = collected_chars,
49+
)
50+
51+
def _collect_multi_line_comment(chars):
52+
chars = chars[2:]
53+
collected_chars = ["/", "*"]
54+
terminated = False
55+
56+
for idx, char in enumerate(chars):
57+
collected_chars.append(char)
58+
59+
if char == "*" and idx + 1 < len(chars) and chars[idx + 1] == "/":
60+
collected_chars.append("/")
61+
terminated = True
62+
break
63+
64+
if not terminated:
65+
return _collection_result(
66+
chars = collected_chars,
67+
errors = [_error("".join(collected_chars), "Unclosed multi-line comment")],
68+
)
69+
else:
70+
return _collection_result(
71+
chars = collected_chars,
72+
)
73+
3974
def _collect_chars_in_set(chars, target_set):
4075
collected_chars = []
4176
for char in chars:
@@ -114,6 +149,14 @@ def _tokenize(text):
114149
elif sets.contains(character_sets.whitespaces, char):
115150
pass
116151

152+
elif char == "/":
153+
if idx + 1 < chars_len and chars[idx + 1] == "*":
154+
collect_result = _collect_multi_line_comment(chars[idx:])
155+
else:
156+
collect_result = _collect_single_line_comment(chars[idx:])
157+
158+
collected_tokens.append(tokens.comment(collect_result.value))
159+
117160
elif sets.contains(character_sets.newlines, char):
118161
collect_result = _collect_chars_in_set(chars[idx:], character_sets.newlines)
119162
collected_tokens.append(tokens.newline())

swiftpkg/tests/modulemap_parser/tokenizer_tests.bzl

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -82,6 +82,28 @@ def _tokenize_test(ctx):
8282
result = tokenizer.tokenize(text)
8383
asserts.equals(env, expected, result, "consume string literals")
8484

85+
text = "// single line comment 1\n/* single line comment 2 */"
86+
expected = tokenizer.result(
87+
tokens = [
88+
tokens.comment("// single line comment 1"),
89+
tokens.newline(),
90+
tokens.comment("/* single line comment 2 */"),
91+
],
92+
)
93+
result = tokenizer.tokenize(text)
94+
asserts.equals(env, expected, result, "consume single line comments")
95+
96+
text = "/*\nmulti line comment\nline 1\n // line 2\n*/\n// single line comment"
97+
expected = tokenizer.result(
98+
tokens = [
99+
tokens.comment("/*\nmulti line comment\nline 1\n // line 2\n*/"),
100+
tokens.newline(),
101+
tokens.comment("// single line comment"),
102+
],
103+
)
104+
result = tokenizer.tokenize(text)
105+
asserts.equals(env, expected, result, "consume multi line comments")
106+
85107
return unittest.end(env)
86108

87109
tokenize_test = unittest.make(_tokenize_test)

0 commit comments

Comments
 (0)