diff --git a/data/test/config_merge_test.yaml b/data/test/config_merge_test.yaml index 6a660131f..3c570a46b 100644 --- a/data/test/config_merge_test.yaml +++ b/data/test/config_merge_test.yaml @@ -46,3 +46,11 @@ merge_tree: zerg: # overwrite existing list ground_units: [] + +create_list_with_inplace_patch: + # map node without data key-value (exclude compiler directives) can be converted to list + all_ground_units: + __patch: + - __append: [scv, marine, firebat, vulture, tank] + - __append: {__include: starcraft/protoss/ground_units} + - __append: {__include: starcraft/zerg/ground_units} diff --git a/src/rime/config/config_compiler.cc b/src/rime/config/config_compiler.cc index 30557b077..474107840 100644 --- a/src/rime/config/config_compiler.cc +++ b/src/rime/config/config_compiler.cc @@ -97,8 +97,13 @@ static bool AppendToList(an target, an list) { return false; auto existing_list = As(**target); if (!existing_list) { - LOG(ERROR) << "trying to append list to other value"; - return false; + if (!(**target)->empty()) { + LOG(ERROR) << "trying to append list to incompatible node type"; + return false; + } + // convert empty node (usually map with only compiler directives) to list; + // refer to test case RimeConfigMergeTest.CreateListWithInplacePatch + existing_list = target->AsList(); } if (list->empty()) return true; diff --git a/test/config_compiler_test.cc b/test/config_compiler_test.cc index fbd905c6f..0c83c1fd7 100644 --- a/test/config_compiler_test.cc +++ b/test/config_compiler_test.cc @@ -251,6 +251,12 @@ class RimeConfigCircularDependencyTest : public RimeConfigCompilerTestBase { } }; +TEST_F(RimeConfigMergeTest, CreateListWithInplacePatch) { + const string& prefix = "create_list_with_inplace_patch/"; + EXPECT_TRUE(config_->IsList(prefix + "all_ground_units")); + EXPECT_EQ(16, config_->GetListSize(prefix + "all_ground_units")); +} + TEST_F(RimeConfigCircularDependencyTest, BestEffortResolution) { const string& prefix = "test/"; EXPECT_TRUE(config_->IsNull(prefix + "__patch"));