<commit_before>package php.runtime.invoke;

import php.runtime.Memory;
import php.runtime.common.HintType;
import php.runtime.common.Messages;
import php.runtime.common.StringUtils;
import php.runtime.env.Environment;
import php.runtime.env.TraceInfo;
import php.runtime.exceptions.support.ErrorType;
import php.runtime.ext.core.classes.WrapJavaExceptions;
import php.runtime.lang.ForeachIterator;
import php.runtime.lang.Generator;
import php.runtime.memory.ArrayMemory;
import php.runtime.memory.ObjectMemory;
import php.runtime.memory.ReferenceMemory;
import php.runtime.memory.helper.VariadicMemory;
import php.runtime.reflection.ClassEntity;
import php.runtime.reflection.MethodEntity;
import php.runtime.reflection.ParameterEntity;

import java.lang.reflect.Field;
import java.util.ArrayList;
import java.util.List;

public class InvokeArgumentHelper {
    private static final String INVALID_TYPE_MESSAGE = "Only arrays and Traversables can be unpacked";

    public static Memory[] makeArguments(Environment env, Memory[] args,
                                         ParameterEntity[] parameters,
                                         String originClassName, String originMethodName,
                                         TraceInfo trace) {
        if (parameters == null)
            return args;

        args = unpackArgs(env, trace, args, parameters);

        Memory[] passed = args;

        if ((args == null && parameters.length > 0) || (args != null && args.length < parameters.length)) {
            passed = new Memory[parameters.length];

            if (args != null && args.length > 0) {
                System.arraycopy(args, 0, passed, 0, args.length);
            }
        }

        int i = 0;

        if (passed != null) {
            for (ParameterEntity param : parameters) {
                Memory arg = passed[i];

                if (param.isVariadic()) {
                    ArrayMemory variadicArgs = new ArrayMemory();

                    int _i = i;
                    boolean variadicMemoryExists = false;

                    while (arg != null) {
                        if (arg instanceof VariadicMemory) {
                            variadicMemoryExists = true;

                            ForeachIterator iterator = arg.getNewIterator(env, param.isReference(), false);

                            if (iterator == null) {
                                env.warning(trace, INVALID_TYPE_MESSAGE);
                            } else {
                                makeVariadic(iterator, variadicArgs, param, env, trace, _i, originClassName, originMethodName);
                            }
                        } else {
                            if (variadicMemoryExists) {
                                env.error(trace, "Cannot use positional argument after argument unpacking");
                            }

                            if (!param.checkTypeHinting(env, arg)) {
                                invalidType(env, trace, param, _i + 1, arg, originClassName, originMethodName);
                            }

                            variadicArgs.add(makeValue(param, arg, env, trace));
                        }

                        i++;
                        if (i < passed.length) {
                            arg = passed[i];
                        } else {
                            break;
                        }
                    }

                    passed[_i] = variadicArgs;

                    break;
                }

                if (arg == null) {
                    Memory def = param.getDefaultValue();

                    if (def != null) {
                        if (!param.isReference()) {
                            passed[i] = param.isMutable() ? def.toImmutable(env, trace) : def;
                        } else {
                            passed[i] = new ReferenceMemory(param.isMutable() ? def.toImmutable(env, trace) : def);
                        }
                    } else {
                        if (param.getTypeClass() != null) {
                            invalidType(env, trace, param, i + 1, null, originClassName, originMethodName);
                        }

                        env.error(trace, ErrorType.E_ERROR,
                                Messages.ERR_MISSING_ARGUMENT, (i + 1) + " ($" + param.getName() + ")",
                                originMethodName == null ? originClassName : originClassName + "::" + originMethodName
                        );
                        passed[i] = param.isReference() ? new ReferenceMemory() : Memory.NULL;
                    }
                } else {
                    if (param.isReference()) {
                        if (!arg.isReference() && !arg.isObject()) {
                            env.error(trace, ErrorType.E_ERROR, "Only variables can be passed by reference");
                            passed[i] = new ReferenceMemory(arg);
                        }
                    } else {
                        passed[i] = param.isMutable() ? arg.toImmutable() : arg.toValue();
                    }
                }

                if (!param.checkTypeHinting(env, passed[i])) {
                    invalidType(env, trace, param, i + 1, passed[i], originClassName, originMethodName);
                }
                i++;
            }
        }

        return passed;
    }

    public static Memory[] unpackArgs(Environment env, TraceInfo trace, Memory[] passed, ParameterEntity[] parameters) {
        List<Memory> varPassed = null;

        if (passed == null) {
            return null;
        }

        int cnt = 0, paramCnt = 0;

        ParameterEntity parameterEntity = null;
        boolean variadicMemoryExists = false;

        for (Memory arg : passed) {
            if (arg instanceof VariadicMemory) {
                variadicMemoryExists = true;

                if (varPassed == null) {
                    varPassed = new ArrayList<Memory>();

                    for (int i = 0; i < cnt; i++) {
                        varPassed.add(passed[i]);
                    }
                }<commit_msg>Fix passing undeclared args to methods and functions.<commit_after>package php.runtime.invoke;

import php.runtime.Memory;
import php.runtime.common.HintType;
import php.runtime.common.Messages;
import php.runtime.common.StringUtils;
import php.runtime.env.Environment;
import php.runtime.env.TraceInfo;
import php.runtime.exceptions.support.ErrorType;
import php.runtime.ext.core.classes.WrapJavaExceptions;
import php.runtime.lang.ForeachIterator;
import php.runtime.lang.Generator;
import php.runtime.memory.ArrayMemory;
import php.runtime.memory.ObjectMemory;
import php.runtime.memory.ReferenceMemory;
import php.runtime.memory.helper.VariadicMemory;
import php.runtime.reflection.ClassEntity;
import php.runtime.reflection.MethodEntity;
import php.runtime.reflection.ParameterEntity;

import java.lang.reflect.Field;
import java.util.ArrayList;
import java.util.List;

public class InvokeArgumentHelper {
    private static final String INVALID_TYPE_MESSAGE = "Only arrays and Traversables can be unpacked";

    public static Memory[] makeArguments(Environment env, Memory[] args,
                                         ParameterEntity[] parameters,
                                         String originClassName, String originMethodName,
                                         TraceInfo trace) {
        if (parameters == null)
            return args;

        args = unpackArgs(env, trace, args, parameters);

        Memory[] passed = args;

        if ((args == null && parameters.length > 0) || (args != null && args.length < parameters.length)) {
            passed = new Memory[parameters.length];

            if (args != null && args.length > 0) {
                System.arraycopy(args, 0, passed, 0, args.length);
            }
        }

        int i = 0;

        if (passed != null) {
            boolean variadicMemoryExists = false;

            for (ParameterEntity param : parameters) {
                Memory arg = passed[i];

                if (param.isVariadic()) {
                    ArrayMemory variadicArgs = new ArrayMemory();

                    int _i = i;

                    while (arg != null) {
                        if (arg instanceof VariadicMemory) {
                            variadicMemoryExists = true;

                            ForeachIterator iterator = arg.getNewIterator(env, param.isReference(), false);

                            if (iterator == null) {
                                env.warning(trace, INVALID_TYPE_MESSAGE);
                            } else {
                                makeVariadic(iterator, variadicArgs, param, env, trace, _i, originClassName, originMethodName);
                            }
                        } else {
                            if (variadicMemoryExists) {
                                env.error(trace, "Cannot use positional argument after argument unpacking");
                            }

                            if (!param.checkTypeHinting(env, arg)) {
                                invalidType(env, trace, param, _i + 1, arg, originClassName, originMethodName);
                            }

                            variadicArgs.add(makeValue(param, arg, env, trace));
                        }

                        i++;
                        if (i < passed.length) {
                            arg = passed[i];
                        } else {
                            break;
                        }
                    }

                    passed[_i] = variadicArgs;

                    break;
                }

                if (arg == null) {
                    Memory def = param.getDefaultValue();

                    if (def != null) {
                        if (!param.isReference()) {
                            passed[i] = param.isMutable() ? def.toImmutable(env, trace) : def;
                        } else {
                            passed[i] = new ReferenceMemory(param.isMutable() ? def.toImmutable(env, trace) : def);
                        }
                    } else {
                        if (param.getTypeClass() != null) {
                            invalidType(env, trace, param, i + 1, null, originClassName, originMethodName);
                        }

                        env.error(trace, ErrorType.E_ERROR,
                                Messages.ERR_MISSING_ARGUMENT, (i + 1) + " ($" + param.getName() + ")",
                                originMethodName == null ? originClassName : originClassName + "::" + originMethodName
                        );
                        passed[i] = param.isReference() ? new ReferenceMemory() : Memory.NULL;
                    }
                } else {
                    if (param.isReference()) {
                        if (!arg.isReference() && !arg.isObject()) {
                            env.error(trace, ErrorType.E_ERROR, "Only variables can be passed by reference");
                            passed[i] = new ReferenceMemory(arg);
                        }
                    } else {
                        passed[i] = param.isMutable() ? arg.toImmutable() : arg.toValue();
                    }
                }

                if (!param.checkTypeHinting(env, passed[i])) {
                    invalidType(env, trace, param, i + 1, passed[i], originClassName, originMethodName);
                }
                i++;
            }

            if (!variadicMemoryExists) {
                for (int j = parameters.length ; j < passed.length; j++) {
                    passed[j] = passed[j].toImmutable();
                }
            }
        }

        return passed;
    }

    public static Memory[] unpackArgs(Environment env, TraceInfo trace, Memory[] passed, ParameterEntity[] parameters) {
        List<Memory> varPassed = null;

        if (passed == null) {
            return null;
        }

        int cnt = 0, paramCnt = 0;

        ParameterEntity parameterEntity = null;
        boolean variadicMemoryExists = false;

        for (Memory arg : passed) {
            if (arg instanceof VariadicMemory) {
                variadicMemoryExists = true;

                if (varPassed == null) {
                    varPassed = new ArrayList<Memory>();

                    for (int i = 0; i < cnt; i++) {
                        varPassed.add(passed[i]);
                    }
                }
{'fraction_non_alphanumeric': 0.09524950099800399, 'fraction_numerical': 0.0019161676646706587, 'mean_word_length': 1.3072389021919322, 'pattern_counts': {'":': 2, '<': 14, '<?xml version=': 0, '>': 11, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 12, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '2767460', 'n_tokens_mistral': 3115, 'n_tokens_neox': 2833, 'n_words': 698}