diff --git a/library/LuaTypes.cpp b/library/LuaTypes.cpp index 7e1ab67cb..1cc83be31 100644 --- a/library/LuaTypes.cpp +++ b/library/LuaTypes.cpp @@ -1426,19 +1426,16 @@ static void AddFieldInfoTable(lua_State *state, int ftable_idx, struct_identity lua_settable(state, -3); } + // freeze_table(state); // TODO: make pairs() work lua_settable(state, ix_fields); lua_pop(state, 1); // field name } + // lua_pushvalue(state, ix_fields); + // freeze_table(state); // TODO: figure out why this creates an __index cycle for nonexistent fields lua_pushvalue(state, ix_wrapper); lua_setfield(state, ftable_idx, "_fields"); - lua_pushvalue(state, ix_fieldinfo); - lua_setfield(state, ftable_idx, "_fieldsinfo"); - lua_pushvalue(state, ix_meta); - lua_setfield(state, ftable_idx, "_fieldsmeta"); - lua_pushvalue(state, ix_fielditer); - lua_setfield(state, ftable_idx, "_fieldsiter"); } void LuaWrapper::IndexStatics(lua_State *state, int meta_idx, int ftable_idx, struct_identity *pstruct) diff --git a/test/structures/struct_fields.lua b/test/structures/struct_fields.lua new file mode 100644 index 000000000..e94c9fbc5 --- /dev/null +++ b/test/structures/struct_fields.lua @@ -0,0 +1,54 @@ +config.target = 'core' + +local COORD_FIELD_NAMES = {'x', 'y', 'z', 'isValid', 'clear'} +local COORD_FIELD_EXPECTED_DATA = { + x = {type_name='int16_t'}, + y = {type_name='int16_t'}, + z = {type_name='int16_t'}, + isValid = {type_name='function'}, + clear = {type_name='function'}, +} + +local READONLY_MSG = 'Attempt to change a read%-only table.' + +function test.access() + local fields = df.coord._fields + expect.true_(fields) + expect.eq(fields, df.coord._fields) + + for name, expected in pairs(COORD_FIELD_EXPECTED_DATA) do + expect.true_(fields[name], name) + expect.eq(fields[name].name, name, name) + expect.eq(fields[name].type_name, expected.type_name, name) + expect.eq(type(fields[name].offset), 'number', name) + end +end + +function test.order() + local i = 0 + for name in pairs(df.coord._fields) do + i = i + 1 + expect.eq(name, COORD_FIELD_NAMES[i], i) + end + expect.eq(i, #COORD_FIELD_NAMES) +end + +function test.nonexistent() + expect.nil_(df.coord._fields.nonexistent) +end + +function test.readonly() + expect.error_match(READONLY_MSG, function() + df.coord._fields.x = 'foo' + end) + expect.error_match(READONLY_MSG, function() + df.coord._fields.nonexistent = 'foo' + end) + -- see TODOs in LuaTypes.cpp + -- expect.error_match(READONLY_MSG, function() + -- df.coord._fields.x.name = 'foo' + -- end) + + expect.eq(df.coord._fields.x.name, 'x') + expect.nil_(df.coord._fields.nonexistent) +end