X-Git-Url: https://git.m6w6.name/?p=m6w6%2Fext-psi;a=blobdiff_plain;f=src%2Ftypes%2Fset_func.c;h=96ab6a19c2da884e17381394badac965366553d4;hp=21189bff33668f8b35e4ec32ab5d7ec2e74bbdc7;hb=a0f437f26cd0f121ee911a55327a68a3544bf15f;hpb=b78637d9020222f1032349f231c0dc84a69797bc diff --git a/src/types/set_func.c b/src/types/set_func.c index 21189bf..96ab6a1 100644 --- a/src/types/set_func.c +++ b/src/types/set_func.c @@ -26,13 +26,13 @@ #include "php_psi_stdinc.h" #include "data.h" -struct psi_set_func *psi_set_func_init(token_t type, const char *name, +struct psi_set_func *psi_set_func_init(token_t type, zend_string *name, struct psi_decl_var *var) { - struct psi_set_func *func = calloc(1, sizeof(*func)); + struct psi_set_func *func = pecalloc(1, sizeof(*func), 1); func->type = type; - func->name = strdup(name); + func->name = zend_string_copy(name); func->var = var; return func; @@ -44,39 +44,37 @@ void psi_set_func_free(struct psi_set_func **func_ptr) struct psi_set_func *func = *func_ptr; *func_ptr = NULL; - if (func->token) { - free(func->token); - } + psi_token_free(&func->token); psi_decl_var_free(&func->var); - free(func->name); + zend_string_release(func->name); free(func); } } -void psi_set_func_dump(int fd, struct psi_set_func *func, unsigned level) +void psi_set_func_dump(struct psi_dump *dump, struct psi_set_func *func, unsigned level) { - dprintf(fd, "%s(", func->name); - psi_decl_var_dump(fd, func->var); - dprintf(fd, "\t/* fqn=%s */", func->var->fqn); + PSI_DUMP(dump, "%s(", func->name->val); + psi_decl_var_dump(dump, func->var); + PSI_DUMP(dump, "\t/* fqn=%s */", func->var->fqn->val); if (func->inner && !func->recursive) { size_t i = 0, count = psi_plist_count(func->inner); struct psi_set_exp *inner; - dprintf(fd, ","); + PSI_DUMP(dump, ","); ++level; while (psi_plist_get(func->inner, i++, &inner)) { - dprintf(fd, "\n"); - psi_set_exp_dump(fd, inner, level, i == count); + PSI_DUMP(dump, "\n"); + psi_set_exp_dump(dump, inner, level, i == count); } --level; } if (func->recursive) { - dprintf(fd, ", ..."); + PSI_DUMP(dump, ", ..."); } if (func->inner && !func->recursive) { - dprintf(fd, "\n%s", psi_t_indent(level)); + PSI_DUMP(dump, "\n%s", psi_t_indent(level)); } - dprintf(fd, ")"); + PSI_DUMP(dump, ")"); } static inline bool psi_set_func_validate_to_string(struct psi_data *data, @@ -133,7 +131,7 @@ static inline bool psi_set_func_validate_to_array(struct psi_data *data, PSI_WARNING, "Expected to_type() cast expression"); return false; } - if (strcmp(set_var->name, psi_set_exp_get_decl_var(sub_exp)->name)) { + if (!zend_string_equals(set_var->name, psi_set_exp_get_decl_var(sub_exp)->name)) { /* no warning, because of ambiguity with a one-field-struct monstrosity */ goto complex; } @@ -151,13 +149,14 @@ static inline bool psi_set_func_validate_to_array(struct psi_data *data, PSI_WARNING, "Expected to_type() cast expression"); return false; } - if (strcmp(set_var->name, psi_set_exp_get_decl_var(sub_exp)->name)) { + if (!zend_string_equals(set_var->name, psi_set_exp_get_decl_var(sub_exp)->name)) { data->error(data, **(struct psi_token ***) &sub_exp->data, PSI_WARNING, "Expected %s(%s) cast expression to reference the same" " variable like the outer `set` statement, '%s'", - sub_exp->data.func->name, - psi_set_exp_get_decl_var(sub_exp)->name, set_var); + sub_exp->data.func->name->val, + psi_set_exp_get_decl_var(sub_exp)->name->val, + set_var->name->val); return false; } func->handler = psi_set_to_array_counted; @@ -173,7 +172,7 @@ static inline bool psi_set_func_validate_to_array(struct psi_data *data, data->error(data, func->token, PSI_WARNING, "Expected struct or union type for complex to_array()" " cast expression, got '%s'", - set_var->arg->type->name); + set_var->arg->type->name->val); return false; } func->handler = psi_set_to_array; @@ -191,7 +190,7 @@ static inline bool psi_set_func_validate_to_recursive(struct psi_data *data, data->error(data, func->token, PSI_WARNING, "Expected to_array() as parent to recursion in `set` statement" " of implementation '%s'", - impl->func->name); + impl->func->name->val); return false; } @@ -202,14 +201,15 @@ static inline bool psi_set_func_validate_to_recursive(struct psi_data *data, } bool psi_set_func_validate(struct psi_data *data, struct psi_set_func *func, - struct psi_set_exp *set, struct psi_impl *impl, struct psi_decl *cb_decl) + struct psi_validate_scope *scope) { - if (!psi_decl_var_validate(data, func->var, NULL, impl->decl, NULL, set) - && !psi_decl_var_validate(data, func->var, NULL, cb_decl, NULL, NULL) - && !psi_impl_get_temp_let_arg(impl, func->var)) { + struct psi_set_exp *set = scope->current_set; + + if (!psi_decl_var_validate(data, func->var, scope) + && !psi_impl_get_temp_let_arg(scope->impl, func->var)) { data->error(data, func->var->token, PSI_WARNING, "Unknown variable '%s' in implementation %s", - func->var->name, impl->func->name); + func->var->name->val, scope->impl->func->name->val); return false; } @@ -222,7 +222,6 @@ bool psi_set_func_validate(struct psi_data *data, struct psi_set_func *func, } if (func->inner && (!set->outer || set->outer->inner != func->inner)) { - size_t i = 0; struct psi_set_exp *inner; @@ -231,17 +230,26 @@ bool psi_set_func_validate(struct psi_data *data, struct psi_set_func *func, struct psi_plist *sub_args; inner->outer = set; + scope->current_set = inner; + /* skip to "fail:" if field does not exists */ sub_var = psi_set_exp_get_decl_var(inner); sub_args = psi_decl_type_get_args(func->var->arg->type, NULL); - if (sub_var && sub_args && !psi_decl_arg_get_by_var(sub_var, sub_args, NULL)) { - /* remove expr for portability with different struct members */ - psi_plist_del(func->inner, --i, NULL); - psi_set_exp_free(&inner); - } else if (!psi_set_exp_validate(data, inner, impl, cb_decl)) { - /* remove exp for portability */ - psi_plist_del(func->inner, --i, NULL); + if (sub_var && sub_args) { + if (!psi_decl_arg_get_by_var(sub_var, sub_args, NULL)) { + goto fail; + } + } + + if (psi_set_exp_validate(data, inner, scope)) { + scope->current_set = set; + continue; } + fail: + scope->current_set = set; + /* remove expr for portability with different struct members */ + psi_plist_del(func->inner, --i, NULL); + psi_set_exp_free(&inner); } } @@ -265,19 +273,19 @@ bool psi_set_func_validate(struct psi_data *data, struct psi_set_func *func, func->handler = psi_set_to_object; break; case PSI_T_TO_STRING: - if (!psi_set_func_validate_to_string(data, func, set, impl)) { + if (!psi_set_func_validate_to_string(data, func, set, scope->impl)) { return false; } break; case PSI_T_TO_ARRAY: - if (!psi_set_func_validate_to_array(data, func, set, impl)) { + if (!psi_set_func_validate_to_array(data, func, set, scope->impl)) { return false; } break; default: data->error(data, func->token, PSI_WARNING, "Unknown cast '%s' in `set` statement of implementation '%s'", - func->name, impl->func->name); + func->name->val, scope->impl->func->name->val); return false; }