# HG changeset patch
# User Piotr Held <pjheld@gmail.com>
# Date 1501286398 25200
#      Fri Jul 28 16:59:58 2017 -0700
# Node ID 73d5fe7b2eedd1754f42743cef97de84b7ffbe7d
# Parent  a40bd69033e675996edc78ce6b16dde60b1442b2
Aanonymous functions that reference local functions from method (Bug #51599)

* symtab.cc: when looking up local functions for an anonymous function if the function itself doesn't have file information it looks at the parents for it. Stashing the file information for anon function during initialization (in  tree_evaluator::visit_anon_fcn_handle) caused weird bugs...

* bug-51599.tst, class_bug51599.m, bug-51599/module.mk, test/module.mk: added the test that was included in the bug submission. It currently passes.

diff -r a40bd69033e6 -r 73d5fe7b2eed libinterp/corefcn/symtab.cc
--- a/libinterp/corefcn/symtab.cc	Wed Jul 26 17:10:20 2017 -0700
+++ b/libinterp/corefcn/symtab.cc	Fri Jul 28 16:59:58 2017 -0700
@@ -825,8 +825,20 @@
 
         if (current_fcn)
           {
+        
             std::string fcn_file = current_fcn->fcn_file_name ();
 
+            // For anonymous functions we look at the parent scope so that if they
+            // were defined within class methods and use local functions 
+            // (helper functions) we can still use those anonymous functions 
+            if (current_fcn->is_anonymous_function ())
+              {
+                if (fcn_file.empty () 
+                      && scope->parent_scope () != nullptr 
+                      && scope->parent_scope ()->function () != nullptr)
+                  fcn_file = scope->parent_scope ()->function ()->fcn_file_name();
+              }
+            
             if (! fcn_file.empty ())
               {
                 str_val_iterator r = local_functions.find (fcn_file);
diff -r a40bd69033e6 -r 73d5fe7b2eed test/bug-51599/bug-51599.tst
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/bug-51599/bug-51599.tst	Fri Jul 28 16:59:58 2017 -0700
@@ -0,0 +1,24 @@
+## Copyright (C) 2017 Piotr Held
+##
+## This file is part of Octave.
+##
+## Octave is free software; you can redistribute it and/or modify it
+## under the terms of the GNU General Public License as published by
+## the Free Software Foundation; either version 3 of the License, or
+## (at your option) any later version.
+##
+## Octave is distributed in the hope that it will be useful, but
+## WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+## GNU General Public License for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with Octave; see the file COPYING.  If not, see
+## <http://www.gnu.org/licenses/>.
+
+
+%% Check if function handle can be called
+%!test
+%! a = class_bug51599;
+%! a.foo
+%! assert (a.bar (0), 2) 
diff -r a40bd69033e6 -r 73d5fe7b2eed test/bug-51599/class_bug51599.m
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/bug-51599/class_bug51599.m	Fri Jul 28 16:59:58 2017 -0700
@@ -0,0 +1,18 @@
+classdef class_bug51599 < handle
+  properties
+    anon_fcn;
+  end
+  methods
+    function foo (self)
+      self.anon_fcn = @(x) my_helper(x+1);
+    end
+    function ret = bar (self, val)
+      ret = self.anon_fcn (val);
+    end
+  end
+end
+
+
+function ret = my_helper (val)
+  ret = val + 1;
+end
diff -r a40bd69033e6 -r 73d5fe7b2eed test/bug-51599/module.mk
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/bug-51599/module.mk	Fri Jul 28 16:59:58 2017 -0700
@@ -0,0 +1,5 @@
+bug_51599_TEST_FILES = \
+  %reldir%/bug-51599.tst \
+  %reldir%/class_bug51599.m
+
+TEST_FILES += $(bug_51599_TEST_FILES)
diff -r a40bd69033e6 -r 73d5fe7b2eed test/module.mk
--- a/test/module.mk	Wed Jul 26 17:10:20 2017 -0700
+++ b/test/module.mk	Fri Jul 28 16:59:58 2017 -0700
@@ -55,6 +55,7 @@
 include %reldir%/bug-50014/module.mk
 include %reldir%/bug-50035/module.mk
 include %reldir%/bug-50716/module.mk
+include %reldir%/bug-51599/module.mk
 include %reldir%/class-concat/module.mk
 include %reldir%/classdef/module.mk
 include %reldir%/classdef-multiple-inheritance/module.mk
