diff --git a/core/odin/parser/file_tags.odin b/core/odin/parser/file_tags.odin index cce34b2da..514e1b046 100644 --- a/core/odin/parser/file_tags.odin +++ b/core/odin/parser/file_tags.odin @@ -18,7 +18,7 @@ Build_Kind :: struct { } File_Tags :: struct { - build_project_name: []string, + build_project_name: [][]string, build: []Build_Kind, private: Private_Flag, ignore: bool, @@ -48,7 +48,9 @@ get_build_arch_from_string :: proc(str: string) -> runtime.Odin_Arch_Type { } @require_results -parse_file_tags :: proc(file: ast.File) -> (tags: File_Tags) { +parse_file_tags :: proc(file: ast.File, allocator := context.allocator) -> (tags: File_Tags) { + context.allocator = allocator + if file.docs == nil { return } @@ -87,7 +89,10 @@ parse_file_tags :: proc(file: ast.File) -> (tags: File_Tags) { build_kinds: [dynamic]Build_Kind defer shrink(&build_kinds) - build_project_names: [dynamic]string + build_project_name_strings: [dynamic]string + defer shrink(&build_project_name_strings) + + build_project_names: [dynamic][]string defer shrink(&build_project_names) for comment in file.docs.list { @@ -116,23 +121,32 @@ parse_file_tags :: proc(file: ast.File) -> (tags: File_Tags) { tags.private = .Package } case "build-project-name": - values_loop: for { - skip_whitespace(text, &i) + groups_loop: for { + index_start := len(build_project_name_strings) - name_start := i + defer append(&build_project_names, build_project_name_strings[index_start:]) - switch next_char(text, &i) { - case 0, '\n': - i -= 1 - break values_loop - case '!': - // include ! in the name - case: - i -= 1 + for { + skip_whitespace(text, &i) + name_start := i + + switch next_char(text, &i) { + case 0, '\n': + i -= 1 + break groups_loop + case ',': + continue groups_loop + case '!': + // include ! in the name + case: + i -= 1 + } + + scan_value(text, &i) + append(&build_project_name_strings, text[name_start:i]) } - scan_value(text, &i) - append(&build_project_names, text[name_start:i]) + append(&build_project_names, build_project_name_strings[index_start:]) } case "build": kinds_loop: for { diff --git a/tests/core/odin/test_file_tags.odin b/tests/core/odin/test_file_tags.odin index a9f10b833..f321d78d3 100644 --- a/tests/core/odin/test_file_tags.odin +++ b/tests/core/odin/test_file_tags.odin @@ -3,6 +3,7 @@ package test_core_odin_parser import "base:runtime" import "core:testing" import "core:slice" +import "core:log" import "core:odin/ast" import "core:odin/parser" @@ -60,12 +61,12 @@ package main }, }, {// [4] src = ` -//+build-project-name foo !bar +//+build-project-name foo !bar, baz //+build js wasm32, js wasm64p32 package main `, tags = { - build_project_name = {"foo", "!bar"}, + build_project_name = {{"foo", "!bar"}, {"baz"}}, build = { { os = {.JS}, @@ -79,11 +80,9 @@ package main }, } - expect :: proc(t: ^testing.T, ok: bool, name: string, i: int, expected, actual: $T, loc := #caller_location) { - testing.expectf(t, ok, - "[%d] expected %s:\n\e[0;32m%#v\e[0m, actual:\n\e[0;31m%#v\e[0m", - i, name, expected, actual, loc=loc - ) + error_expected :: proc(name: string, i: int, expected, actual: $T, loc := #caller_location) { + log.errorf("[%d] expected %s:\n\e[0;32m%#v\e[0m, actual:\n\e[0;31m%#v\e[0m", + i, name, expected, actual, location=loc) } for test_case, i in test_cases { @@ -100,34 +99,36 @@ package main tags := parser.parse_file_tags(file) - expect(t, - slice.equal(test_case.tags.build_project_name, tags.build_project_name), - "build_project_name", i, test_case.tags.build_project_name, tags.build_project_name, - ) - expect(t, - slice.equal(test_case.tags.build, tags.build), - "build", i, test_case.tags.build, tags.build, - ) + build_project_name_the_same: bool + check: if len(test_case.tags.build_project_name) == len(tags.build_project_name) { + for tag, i in test_case.tags.build_project_name { + slice.equal(tag, tags.build_project_name[i]) or_break check + } + build_project_name_the_same = true + } + if !build_project_name_the_same { + error_expected("build_project_name", i, test_case.tags.build_project_name, tags.build_project_name) + } - expect(t, - test_case.tags.private == tags.private, - "private", i, test_case.tags.private, tags.private, - ) + if !slice.equal(test_case.tags.build, tags.build) { + error_expected("build", i, test_case.tags.build, tags.build,) + } - expect(t, - test_case.tags.ignore == tags.ignore, - "ignore", i, test_case.tags.ignore, tags.ignore, - ) + if test_case.tags.private != tags.private { + error_expected("private", i, test_case.tags.private, tags.private) + } - expect(t, - test_case.tags.lazy == tags.lazy, - "lazy", i, test_case.tags.lazy, tags.lazy, - ) + if test_case.tags.ignore != tags.ignore { + error_expected("ignore", i, test_case.tags.ignore, tags.ignore) + } - expect(t, - test_case.tags.no_instrumentation == tags.no_instrumentation, - "no_instrumentation", i, test_case.tags.no_instrumentation, tags.no_instrumentation, - ) + if test_case.tags.lazy != tags.lazy { + error_expected("lazy", i, test_case.tags.lazy, tags.lazy) + } + + if test_case.tags.no_instrumentation != tags.no_instrumentation { + error_expected("no_instrumentation", i, test_case.tags.no_instrumentation, tags.no_instrumentation) + } } }