diff --git a/core/odin/parser/file_tags.odin b/core/odin/parser/file_tags.odin index 514e1b046..b12c3b5fd 100644 --- a/core/odin/parser/file_tags.odin +++ b/core/odin/parser/file_tags.odin @@ -205,3 +205,35 @@ parse_file_tags :: proc(file: ast.File, allocator := context.allocator) -> (tags return } + +Build_Target :: struct { + os: runtime.Odin_OS_Type, + arch: runtime.Odin_Arch_Type, + project_name: string, +} + +@require_results +match_build_tags :: proc(file_tags: File_Tags, target: Build_Target) -> bool { + + project_name_correct := len(target.project_name) == 0 || len(file_tags.build_project_name) == 0 + + for group in file_tags.build_project_name { + group_correct := true + for name in group { + if name[0] == '!' { + group_correct &&= target.project_name != name[1:] + } else { + group_correct &&= target.project_name == name + } + } + project_name_correct ||= group_correct + } + + os_and_arch_correct := len(file_tags.build) == 0 + + for kind in file_tags.build { + os_and_arch_correct ||= target.os in kind.os && target.arch in kind.arch + } + + return !file_tags.ignore && project_name_correct && os_and_arch_correct +} diff --git a/tests/core/odin/test_file_tags.odin b/tests/core/odin/test_file_tags.odin index f321d78d3..b2b378c9d 100644 --- a/tests/core/odin/test_file_tags.odin +++ b/tests/core/odin/test_file_tags.odin @@ -13,8 +13,12 @@ test_parse_file_tags :: proc(t: ^testing.T) { runtime.DEFAULT_TEMP_ALLOCATOR_TEMP_GUARD() Test_Case :: struct { - src: string, - tags: parser.File_Tags, + src: string, + tags: parser.File_Tags, + matching_targets: []struct{ + target: parser.Build_Target, + result: bool, + }, } test_cases := []Test_Case{ @@ -26,6 +30,9 @@ test_parse_file_tags :: proc(t: ^testing.T) { package main `, tags = {}, + matching_targets = { + {{.Windows, .amd64, "foo"}, true}, + }, }, {// [2] src = ` //+build linux, darwin, freebsd, openbsd, netbsd, haiku @@ -44,6 +51,11 @@ package main {os = runtime.ALL_ODIN_OS_TYPES, arch = {.arm64}}, }, }, + matching_targets = { + {{.Linux, .amd64, "foo"}, true}, + {{.Windows, .arm64, "foo"}, true}, + {{.Windows, .amd64, "foo"}, false}, + }, }, {// [3] src = ` // +private @@ -59,6 +71,9 @@ package main lazy = true, ignore = true, }, + matching_targets = { + {{.Linux, .amd64, "foo"}, false}, + }, }, {// [4] src = ` //+build-project-name foo !bar, baz @@ -77,14 +92,14 @@ package main }, }, }, + matching_targets = { + {{.JS, .wasm32, "foo"}, true}, + {{.JS, .wasm64p32, "baz"}, true}, + {{.JS, .wasm64p32, "bar"}, false}, + }, }, } - 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 { file := ast.File{ @@ -107,28 +122,35 @@ package main } 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) - } + testing.expectf(t, build_project_name_the_same, + "[%d] file_tags.build_project_name expected:\n%#v, got:\n%#v", + i, test_case.tags.build_project_name, tags.build_project_name) - if !slice.equal(test_case.tags.build, tags.build) { - error_expected("build", i, test_case.tags.build, tags.build,) - } + testing.expectf(t, slice.equal(test_case.tags.build, tags.build), + "[%d] file_tags.build expected:\n%#v, got:\n%#v", + i, test_case.tags.build, tags.build) - if test_case.tags.private != tags.private { - error_expected("private", i, test_case.tags.private, tags.private) - } + testing.expectf(t, test_case.tags.private == tags.private, + "[%d] file_tags.private expected:\n%v, got:\n%v", + i, test_case.tags.private, tags.private) - if test_case.tags.ignore != tags.ignore { - error_expected("ignore", i, test_case.tags.ignore, tags.ignore) - } + testing.expectf(t, test_case.tags.ignore == tags.ignore, + "[%d] file_tags.ignore expected:\n%v, got:\n%v", + i, test_case.tags.ignore, tags.ignore) - if test_case.tags.lazy != tags.lazy { - error_expected("lazy", i, test_case.tags.lazy, tags.lazy) - } + testing.expectf(t, test_case.tags.lazy == tags.lazy, + "[%d] file_tags.lazy expected:\n%v, got:\n%v", + 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) + testing.expectf(t, test_case.tags.no_instrumentation == tags.no_instrumentation, + "[%d] file_tags.no_instrumentation expected:\n%v, got:\n%v", + i, test_case.tags.no_instrumentation, tags.no_instrumentation) + + for target in test_case.matching_targets { + matches := parser.match_build_tags(test_case.tags, target.target) + testing.expectf(t, matches == target.result, + "[%d] Expected parser.match_build_tags(%#v) == %v, got %v", + i, target.target, target.result, matches) } } }