def _handle_function_node(self, func_node):
        # We should interrupt traversing, because a node of the function
        # name should be added to the parent scope before the current
        # scope switched to a new scope of the function.
        # We approach to it by the following 5 steps.
        #   1. Add the function to the current scope
        #   2. Create a new scope of the function
        #   3. The current scope point to the new scope
        #   4. Add parameters to the new scope
        #   5. Add variables in the function body to the new scope

        # 1. Add the function to the current scope
        func_name_node = func_node['left']
        traverse(func_name_node, on_enter=self._find_variable_like_nodes)

        # 2. Create a new scope of the function
        # 3. The current scope point to the new scope
        self._scope_tree_builder.enter_new_scope(ScopeVisibility.FUNCTION_LOCAL)

        has_variadic = False

        # 4. Add parameters to the new scope
        param_nodes = func_node['rlist']
        for param_node in param_nodes:
            if param_node['value'] == '...':
                has_variadic = True
            else:
                # the param_node type is always NodeType.IDENTIFIER
                self._scope_tree_builder.handle_new_parameter_found(param_node)

        # We can always access a:0, a:000
        self._scope_tree_builder.handle_new_parameters_list_and_length_found()

        # In a variadic function, we can access a:1 ... a:n
        # (n = 20 - explicit parameters length). See :help a:0
        if has_variadic:
            # -1 means ignore '...'
            self._scope_tree_builder.handle_new_index_parameters_found(len(param_nodes) + 1)

        # We can access "a:firstline" and "a:lastline" if the function is
        # declared with an attribute "range". See :func-range
        attr = func_node['attr']
        is_declared_with_range = attr['range'] is not 0
        if is_declared_with_range:
            self._scope_tree_builder.handle_new_range_parameters_found()

        # We can access "l:self" is declared with an attribute "dict" or
        # the function is a member of a dict. See :help self
        is_declared_with_dict = attr['dict'] is not 0 \
            or NodeType(func_name_node['type']) in FunctionNameNodesDeclaringVariableSelf
        if is_declared_with_dict:
            self._scope_tree_builder.handle_new_dict_parameter_found()

        # 5. Add variables in the function body to the new scope
        func_body_nodes = func_node['body']
        for func_body_node in func_body_nodes:
            traverse(func_body_node,
                     on_enter=self._enter_handler,
                     on_leave=self._leave_handler)

        # Skip child nodes traversing
        return SKIP_CHILDREN
dataset/ETHPy150Open Kuniwak/vint/vint/ast/plugin/scope_plugin/scope_linker.py/ScopeLinker._handle_function_node/operator `-` -> `+`