api/vim,functests: Add tests for nvim_parse_expression, fix found bugs

This commit is contained in:
ZyX
2017-11-05 02:41:44 +03:00
parent 07ec709141
commit 7bc6de7526
7 changed files with 6908 additions and 27 deletions

View File

@@ -995,21 +995,21 @@ Dictionary nvim_parse_expression(String expr, String flags, Boolean highlight,
&pstate, parser_simple_get_line, &plines_p, colors_p); &pstate, parser_simple_get_line, &plines_p, colors_p);
ExprAST east = viml_pexpr_parse(&pstate, pflags); ExprAST east = viml_pexpr_parse(&pstate, pflags);
const size_t dict_size = ( const size_t ret_size = (
1 // "ast" 1 // "ast"
+ (size_t)(east.err.arg != NULL) // "error" + (size_t)(east.err.msg != NULL) // "error"
+ (size_t)highlight // "highlight" + (size_t)highlight // "highlight"
); );
Dictionary ret = { Dictionary ret = {
.items = xmalloc(dict_size * sizeof(ret.items[0])), .items = xmalloc(ret_size * sizeof(ret.items[0])),
.size = 0, .size = 0,
.capacity = dict_size, .capacity = ret_size,
}; };
ret.items[ret.size++] = (KeyValuePair) { ret.items[ret.size++] = (KeyValuePair) {
.key = STATIC_CSTR_TO_STRING("ast"), .key = STATIC_CSTR_TO_STRING("ast"),
.value = NIL, .value = NIL,
}; };
if (east.err.arg != NULL) { if (east.err.msg != NULL) {
Dictionary err_dict = { Dictionary err_dict = {
.items = xmalloc(2 * sizeof(err_dict.items[0])), .items = xmalloc(2 * sizeof(err_dict.items[0])),
.size = 2, .size = 2,
@@ -1017,15 +1017,22 @@ Dictionary nvim_parse_expression(String expr, String flags, Boolean highlight,
}; };
err_dict.items[0] = (KeyValuePair) { err_dict.items[0] = (KeyValuePair) {
.key = STATIC_CSTR_TO_STRING("message"), .key = STATIC_CSTR_TO_STRING("message"),
.value = STRING_OBJ(cstr_to_string(east.err.arg)), .value = STRING_OBJ(cstr_to_string(east.err.msg)),
};
err_dict.items[1] = (KeyValuePair) {
.key = STATIC_CSTR_TO_STRING("arg"),
.value = STRING_OBJ(((String) {
.data = xmemdupz(east.err.arg, (size_t)east.err.arg_len),
.size = (size_t)east.err.arg_len,
})),
}; };
if (east.err.arg == NULL) {
err_dict.items[1] = (KeyValuePair) {
.key = STATIC_CSTR_TO_STRING("arg"),
.value = STRING_OBJ(STRING_INIT),
};
} else {
err_dict.items[1] = (KeyValuePair) {
.key = STATIC_CSTR_TO_STRING("arg"),
.value = STRING_OBJ(((String) {
.data = xmemdupz(east.err.arg, (size_t)east.err.arg_len),
.size = (size_t)east.err.arg_len,
})),
};
}
ret.items[ret.size++] = (KeyValuePair) { ret.items[ret.size++] = (KeyValuePair) {
.key = STATIC_CSTR_TO_STRING("error"), .key = STATIC_CSTR_TO_STRING("error"),
.value = DICTIONARY_OBJ(err_dict), .value = DICTIONARY_OBJ(err_dict),
@@ -1055,6 +1062,7 @@ Dictionary nvim_parse_expression(String expr, String flags, Boolean highlight,
.value = ARRAY_OBJ(hl), .value = ARRAY_OBJ(hl),
}; };
} }
kvi_destroy(colors);
// Walk over the AST, freeing nodes in process. // Walk over the AST, freeing nodes in process.
ExprASTConvStack ast_conv_stack; ExprASTConvStack ast_conv_stack;
@@ -1065,11 +1073,11 @@ Dictionary nvim_parse_expression(String expr, String flags, Boolean highlight,
})); }));
while (kv_size(ast_conv_stack)) { while (kv_size(ast_conv_stack)) {
ExprASTConvStackItem cur_item = kv_last(ast_conv_stack); ExprASTConvStackItem cur_item = kv_last(ast_conv_stack);
if (*cur_item.node_p == NULL) { ExprASTNode *const node = *cur_item.node_p;
if (node == NULL) {
assert(kv_size(ast_conv_stack) == 1); assert(kv_size(ast_conv_stack) == 1);
kv_drop(ast_conv_stack, 1); kv_drop(ast_conv_stack, 1);
} else { } else {
ExprASTNode *const node = *cur_item.node_p;
if (cur_item.ret_node_p->type == kObjectTypeNil) { if (cur_item.ret_node_p->type == kObjectTypeNil) {
const size_t ret_node_items_size = (size_t)( const size_t ret_node_items_size = (size_t)(
3 // "type", "start" and "len" 3 // "type", "start" and "len"
@@ -1116,7 +1124,7 @@ Dictionary nvim_parse_expression(String expr, String flags, Boolean highlight,
})); }));
} else if (node->next != NULL) { } else if (node->next != NULL) {
kvi_push(ast_conv_stack, ((ExprASTConvStackItem) { kvi_push(ast_conv_stack, ((ExprASTConvStackItem) {
.node_p = &node->children, .node_p = &node->next,
.ret_node_p = cur_item.ret_node_p + 1, .ret_node_p = cur_item.ret_node_p + 1,
})); }));
} else if (node != NULL) { } else if (node != NULL) {
@@ -1145,7 +1153,10 @@ Dictionary nvim_parse_expression(String expr, String flags, Boolean highlight,
case kExprNodeSingleQuotedString: { case kExprNodeSingleQuotedString: {
ret_node->items[ret_node->size++] = (KeyValuePair) { ret_node->items[ret_node->size++] = (KeyValuePair) {
.key = STATIC_CSTR_TO_STRING("svalue"), .key = STATIC_CSTR_TO_STRING("svalue"),
.value = STRING_OBJ(cstr_as_string(node->data.str.value)), .value = STRING_OBJ(((String) {
.data = node->data.str.value,
.size = node->data.str.size,
})),
}; };
break; break;
} }
@@ -1217,7 +1228,7 @@ Dictionary nvim_parse_expression(String expr, String flags, Boolean highlight,
ret_node->items[ret_node->size++] = (KeyValuePair) { ret_node->items[ret_node->size++] = (KeyValuePair) {
.key = STATIC_CSTR_TO_STRING("ccs_strategy"), .key = STATIC_CSTR_TO_STRING("ccs_strategy"),
.value = STRING_OBJ(cstr_to_string( .value = STRING_OBJ(cstr_to_string(
eltkn_cmp_type_tab[node->data.cmp.ccs])), ccs_tab[node->data.cmp.ccs])),
}; };
ret_node->items[ret_node->size++] = (KeyValuePair) { ret_node->items[ret_node->size++] = (KeyValuePair) {
.key = STATIC_CSTR_TO_STRING("invert"), .key = STATIC_CSTR_TO_STRING("invert"),

View File

@@ -1492,7 +1492,7 @@ static void parse_quoted_string(ParserState *const pstate,
node->data.str.value = NULL; node->data.str.value = NULL;
} else { } else {
char *v_p; char *v_p;
v_p = node->data.str.value = xmalloc(size); v_p = node->data.str.value = xmallocz(size);
p = s + 1; p = s + 1;
while (p < e) { while (p < e) {
const char *const chunk_e = memchr(p, '\'', (size_t)(e - p)); const char *const chunk_e = memchr(p, '\'', (size_t)(e - p));

File diff suppressed because it is too large Load Diff

View File

@@ -394,6 +394,11 @@ local function format_string(fmt, ...)
return ret return ret
end end
local function intchar2lua(ch)
ch = tonumber(ch)
return (20 <= ch and ch < 127) and ('%c'):format(ch) or ch
end
return { return {
eq = eq, eq = eq,
neq = neq, neq = neq,
@@ -412,4 +417,5 @@ return {
dedent = dedent, dedent = dedent,
format_luav = format_luav, format_luav = format_luav,
format_string = format_string, format_string = format_string,
intchar2lua = intchar2lua,
} }

View File

@@ -11,11 +11,11 @@ local eq = helpers.eq
local conv_ccs = viml_helpers.conv_ccs local conv_ccs = viml_helpers.conv_ccs
local new_pstate = viml_helpers.new_pstate local new_pstate = viml_helpers.new_pstate
local intchar2lua = viml_helpers.intchar2lua
local conv_cmp_type = viml_helpers.conv_cmp_type local conv_cmp_type = viml_helpers.conv_cmp_type
local pstate_set_str = viml_helpers.pstate_set_str local pstate_set_str = viml_helpers.pstate_set_str
local shallowcopy = global_helpers.shallowcopy local shallowcopy = global_helpers.shallowcopy
local intchar2lua = global_helpers.intchar2lua
local lib = cimport('./src/nvim/viml/parser/expressions.h') local lib = cimport('./src/nvim/viml/parser/expressions.h')

View File

@@ -15,12 +15,12 @@ local eq = helpers.eq
local conv_ccs = viml_helpers.conv_ccs local conv_ccs = viml_helpers.conv_ccs
local new_pstate = viml_helpers.new_pstate local new_pstate = viml_helpers.new_pstate
local intchar2lua = viml_helpers.intchar2lua
local conv_cmp_type = viml_helpers.conv_cmp_type local conv_cmp_type = viml_helpers.conv_cmp_type
local pstate_set_str = viml_helpers.pstate_set_str local pstate_set_str = viml_helpers.pstate_set_str
local format_string = global_helpers.format_string local format_string = global_helpers.format_string
local format_luav = global_helpers.format_luav local format_luav = global_helpers.format_luav
local intchar2lua = global_helpers.intchar2lua
local lib = cimport('./src/nvim/viml/parser/expressions.h') local lib = cimport('./src/nvim/viml/parser/expressions.h')
@@ -260,7 +260,8 @@ describe('Expressions parser', function()
alloc_log:check({}) alloc_log:check({})
end) end)
if not err then if not err then
msg = format_string('Error while processing test (%r, %u):\n%s', str, flags, msg) msg = format_string('Error while processing test (%r, %u):\n%s',
str, flags, msg)
error(msg) error(msg)
end end
end end

View File

@@ -52,11 +52,6 @@ local function new_pstate(strings)
return ret return ret
end end
local function intchar2lua(ch)
ch = tonumber(ch)
return (20 <= ch and ch < 127) and ('%c'):format(ch) or ch
end
local function pline2lua(pline) local function pline2lua(pline)
return ffi.string(pline.data, pline.size) return ffi.string(pline.data, pline.size)
end end