<commit_before>package org.yinwang.pysonar.ast;

import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.yinwang.pysonar.Binding;
import org.yinwang.pysonar.Indexer;
import org.yinwang.pysonar.Scope;
import org.yinwang.pysonar.types.FunType;
import org.yinwang.pysonar.types.Type;

import java.util.ArrayList;
import java.util.List;

public class FunctionDef extends Node {

    public Name name;
    public List<Node> args;
    public List<Node> defaults;
    @Nullable
    public List<Type> defaultTypes;
    public Name vararg;  // *args

    public Name kwarg;   // **kwarg
    public Node body;
    private List<Node> decoratorList;
    public boolean called = false;


    public FunctionDef(Name name, List<Node> args, Block body, List<Node> defaults,
                       Name vararg, Name kwarg, int start, int end) {
        super(start, end);
        this.name = name;
        this.args = args;
        this.body = body;
        this.defaults = defaults;
        this.vararg = vararg;
        this.kwarg = kwarg;
        addChildren(name);
        addChildren(args);
        addChildren(defaults);
        addChildren(vararg, kwarg, this.body);
    }

    public void setDecoratorList(List<Node> decoratorList) {
        this.decoratorList = decoratorList;
        addChildren(decoratorList);
    }

    public List<Node> getDecoratorList() {
        if (decoratorList == null) {
            decoratorList = new ArrayList<Node>();
        }
        return decoratorList;
    }

    @Override
    public boolean isFunctionDef() {
        return true;
    }

    @Override
    public boolean bindsName() {
        return true;
    }

    /**
     * Returns the name of the function for indexing/qname purposes.
     * Lambdas will return a generated name.
     */
    @Nullable
    protected String getBindingName(Scope s) {
        return name.getId();
    }

    public List<Node> getArgs() {
        return args;
    }

    public List<Node> getDefaults() {
        return defaults;
    }

    @Nullable
    public List<Type> getDefaultTypes() {
        return defaultTypes;
    }
    
    public Node getBody() {
        return body;
    }

    public Name getName() {
        return name;
    }
    
    /**
     * @return the vararg
     */
    public Name getVararg() {
        return vararg;
    }

    /**
     * @param vararg the vararg to set
     */
    public void setVararg(Name vararg) {
        this.vararg = vararg;
    }

    /**
     * @return the kwarg
     */
    public Name getKwarg() {
        return kwarg;
    }

    /**
     * @param kwarg the kwarg to set
     */
    public void setKwarg(Name kwarg) {
        this.kwarg = kwarg;
    }


    /**
     * A function's environment is not necessarily the enclosing scope. A
     * method's environment is the scope of the most recent scope that is not a
     * class.
     * 
     * Be sure to distinguish the environment and the symbol table. The
     * function's table is only used for the function's attributes like
     * "im_class". Its parent should be the table of the enclosing scope, and
     * its path should be derived from that scope too for locating the names
     * "lexically".
     */
    @NotNull
    @Override
    public Type resolve(@NotNull Scope outer, int tag) {
        resolveList(decoratorList, outer, tag);   //XXX: not handling functional transformations yet
        FunType cl = new FunType(this, outer.getForwarding());
        cl.getTable().setParent(outer);
        cl.getTable().setPath(outer.extendPath(getName().getId()));
        cl.setDefaultTypes(resolveAndConstructList(defaults, outer, tag));
        Indexer.idx.addUncalled(cl);
        Binding.Kind funkind;

        if (outer.getScopeType() == Scope.ScopeType.CLASS) {
            if ("__init__".equals(name.getId())) {
                funkind = Binding.Kind.CONSTRUCTOR;
            } else {
                funkind = Binding.Kind.METHOD;
            }
        } else {
            funkind = Binding.Kind.FUNCTION;
        }

        Type outType = outer.getType();
        if (outType != null && outType.isClassType()) {
            cl.setCls(outType.asClassType());
        }

        NameBinder.bind(outer, name, cl, funkind, tag);
        return Indexer.idx.builtins.Cont;
    }

    @NotNull
    @Override
    public String toString() {
        return "<Function:" + start + ":" + name + ">";
    }

    @Override
    public void visit(@NotNull NodeVisitor v) {
        if (v.visit(this)) {
            visitNode(name, v);<commit_msg>renaming<commit_after>package org.yinwang.pysonar.ast;

import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.yinwang.pysonar.Binding;
import org.yinwang.pysonar.Indexer;
import org.yinwang.pysonar.Scope;
import org.yinwang.pysonar.types.FunType;
import org.yinwang.pysonar.types.Type;

import java.util.ArrayList;
import java.util.List;

public class FunctionDef extends Node {

    public Name name;
    public List<Node> args;
    public List<Node> defaults;
    @Nullable
    public List<Type> defaultTypes;
    public Name vararg;  // *args

    public Name kwarg;   // **kwarg
    public Node body;
    private List<Node> decoratorList;
    public boolean called = false;


    public FunctionDef(Name name, List<Node> args, Block body, List<Node> defaults,
                       Name vararg, Name kwarg, int start, int end) {
        super(start, end);
        this.name = name;
        this.args = args;
        this.body = body;
        this.defaults = defaults;
        this.vararg = vararg;
        this.kwarg = kwarg;
        addChildren(name);
        addChildren(args);
        addChildren(defaults);
        addChildren(vararg, kwarg, this.body);
    }

    public void setDecoratorList(List<Node> decoratorList) {
        this.decoratorList = decoratorList;
        addChildren(decoratorList);
    }

    public List<Node> getDecoratorList() {
        if (decoratorList == null) {
            decoratorList = new ArrayList<Node>();
        }
        return decoratorList;
    }

    @Override
    public boolean isFunctionDef() {
        return true;
    }

    @Override
    public boolean bindsName() {
        return true;
    }

    /**
     * Returns the name of the function for indexing/qname purposes.
     * Lambdas will return a generated name.
     */
    @Nullable
    protected String getBindingName(Scope s) {
        return name.getId();
    }

    public List<Node> getArgs() {
        return args;
    }

    public List<Node> getDefaults() {
        return defaults;
    }

    @Nullable
    public List<Type> getDefaultTypes() {
        return defaultTypes;
    }
    
    public Node getBody() {
        return body;
    }

    public Name getName() {
        return name;
    }
    
    /**
     * @return the vararg
     */
    public Name getVararg() {
        return vararg;
    }

    /**
     * @param vararg the vararg to set
     */
    public void setVararg(Name vararg) {
        this.vararg = vararg;
    }

    /**
     * @return the kwarg
     */
    public Name getKwarg() {
        return kwarg;
    }

    /**
     * @param kwarg the kwarg to set
     */
    public void setKwarg(Name kwarg) {
        this.kwarg = kwarg;
    }


    /**
     * A function's environment is not necessarily the enclosing scope. A
     * method's environment is the scope of the most recent scope that is not a
     * class.
     * 
     * Be sure to distinguish the environment and the symbol table. The
     * function's table is only used for the function's attributes like
     * "im_class". Its parent should be the table of the enclosing scope, and
     * its path should be derived from that scope too for locating the names
     * "lexically".
     */
    @NotNull
    @Override
    public Type resolve(@NotNull Scope outer, int tag) {
        resolveList(decoratorList, outer, tag);   //XXX: not handling functional transformations yet
        FunType fun = new FunType(this, outer.getForwarding());
        fun.getTable().setParent(outer);
        fun.getTable().setPath(outer.extendPath(getName().getId()));
        fun.setDefaultTypes(resolveAndConstructList(defaults, outer, tag));
        Indexer.idx.addUncalled(fun);
        Binding.Kind funkind;

        if (outer.getScopeType() == Scope.ScopeType.CLASS) {
            if ("__init__".equals(name.getId())) {
                funkind = Binding.Kind.CONSTRUCTOR;
            } else {
                funkind = Binding.Kind.METHOD;
            }
        } else {
            funkind = Binding.Kind.FUNCTION;
        }

        Type outType = outer.getType();
        if (outType != null && outType.isClassType()) {
            fun.setCls(outType.asClassType());
        }

        NameBinder.bind(outer, name, fun, funkind, tag);
        return Indexer.idx.builtins.Cont;
    }

    @NotNull
    @Override
    public String toString() {
        return "<Function:" + start + ":" + name + ">";
    }

    @Override
    public void visit(@NotNull NodeVisitor v) {
        if (v.visit(this)) {
            visitNode(name, v);
{'fraction_non_alphanumeric': 0.10238982679237009, 'fraction_numerical': 0.0, 'mean_word_length': 2.1491197790818086, 'pattern_counts': {'":': 2, '<': 29, '<?xml version=': 0, '>': 29, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '2648278', 'n_tokens_mistral': 2734, 'n_tokens_neox': 2629, 'n_words': 721}