From f01fbf9cd43c52fdb8fe6dce162c9772637ec199 Mon Sep 17 00:00:00 2001 From: Florian Schanda Date: Mon, 7 Aug 2023 08:47:06 +0200 Subject: [PATCH] #276 Correctly raise error on function names with dots outside class Fixes #276 --- CHANGELOG.md | 3 +++ miss_hit_core/m_parser.py | 24 ++++++++++++------- .../expected_out.html | 19 +++++++++++++++ .../expected_out.txt | 9 +++++++ .../bug_276_ice_on_dodgy_function_name/test.m | 3 +++ .../test.m_fixed | 3 +++ 6 files changed, 53 insertions(+), 8 deletions(-) create mode 100644 tests/style/bug_276_ice_on_dodgy_function_name/expected_out.html create mode 100644 tests/style/bug_276_ice_on_dodgy_function_name/expected_out.txt create mode 100644 tests/style/bug_276_ice_on_dodgy_function_name/test.m create mode 100644 tests/style/bug_276_ice_on_dodgy_function_name/test.m_fixed diff --git a/CHANGELOG.md b/CHANGELOG.md index 138cb81..eab87a1 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -20,6 +20,9 @@ Not quite compatible with Octave yet. See #43 [octave support](https://github.co ### 0.9.43-dev +* Fix parsing error surrounding function names (only in classes may + you use a dotted name). When such a function appeared outside a + class the tools would either incorrectly accept this name or crash. * Fix hanging tools when an internal compiler error was raised. diff --git a/miss_hit_core/m_parser.py b/miss_hit_core/m_parser.py index 4307673..e041f72 100644 --- a/miss_hit_core/m_parser.py +++ b/miss_hit_core/m_parser.py @@ -710,7 +710,7 @@ def parse_octave_script_file(self, l_pragmas): # statements intermixed with (global) function definitions while not self.peek_eof(): if self.peek("KEYWORD", "function"): - l_functions.append(self.parse_function_def()) + l_functions.append(self.parse_function_def(in_class = False)) elif self.peek("KEYWORD", "pragma"): l_more_pragmas.append(self.parse_annotation_pragma()) else: @@ -751,7 +751,7 @@ def parse_function_list(self): while self.peek("KEYWORD", "function") or \ self.apeek("KEYWORD", "pragma"): if self.peek("KEYWORD", "function"): - l_functions.append(self.parse_function_def()) + l_functions.append(self.parse_function_def(in_class = False)) else: l_pragmas.append(self.parse_annotation_pragma()) @@ -780,7 +780,9 @@ def reorder_as_function_list(self, n_fdef): return functions - def parse_function_signature(self): + def parse_function_signature(self, in_class): + assert isinstance(in_class, bool) + rv = Function_Signature() # Parse returns. Either 'x' or a list '[x, y]' @@ -842,18 +844,24 @@ def parse_function_signature(self): self.match("KET") self.ct.set_ast(rv) + if isinstance(n_name, Selection) and not in_class: + self.mh.error(n_name.loc(), + "dotted name is not permitted outside class") + rv.set_name(n_name) rv.set_inputs(l_inputs) rv.set_outputs(l_outputs) self.match_eos(rv) return rv - def parse_function_def(self): + def parse_function_def(self, in_class): + assert isinstance(in_class, bool) + self.match("KEYWORD", "function") self.push_context("function") t_fun = self.ct - n_sig = self.parse_function_signature() + n_sig = self.parse_function_signature(in_class) l_body = [] l_nested = [] @@ -1059,9 +1067,9 @@ def parse_class_methods(self): while not self.peek("KEYWORD", "end"): if self.peek("KEYWORD", "function"): - rv.add_method(self.parse_function_def()) + rv.add_method(self.parse_function_def(in_class = True)) else: - rv.add_method(self.parse_function_signature()) + rv.add_method(self.parse_function_signature(in_class = True)) self.match("KEYWORD", "end") self.ct.set_ast(rv) @@ -1334,7 +1342,7 @@ def parse_statement(self): self.mh.error(self.nt.location, "nested function cannot appear inside" " %s" % self.context[-1]) - return self.parse_function_def() + return self.parse_function_def(in_class = False) else: self.mh.error(self.nt.location, "expected valid statement," diff --git a/tests/style/bug_276_ice_on_dodgy_function_name/expected_out.html b/tests/style/bug_276_ice_on_dodgy_function_name/expected_out.html new file mode 100644 index 0000000..b80e891 --- /dev/null +++ b/tests/style/bug_276_ice_on_dodgy_function_name/expected_out.html @@ -0,0 +1,19 @@ + + + + + +MISS_HIT Report + + +
MISS_HIT Report
+
+
+

Issues identified

+
+

test.m

+
test.m: line 1: error: dotted name is not permitted outside class
+
+
+ + diff --git a/tests/style/bug_276_ice_on_dodgy_function_name/expected_out.txt b/tests/style/bug_276_ice_on_dodgy_function_name/expected_out.txt new file mode 100644 index 0000000..71e8572 --- /dev/null +++ b/tests/style/bug_276_ice_on_dodgy_function_name/expected_out.txt @@ -0,0 +1,9 @@ +=== PLAIN MODE === +test.m: error: file is not auto-fixed because it contains parse errors +In test.m, line 1 +| function pth = foo.bar() +| ^ error: dotted name is not permitted outside class +MISS_HIT Style Summary: 1 file(s) analysed, 2 error(s) + +=== HTML MODE === +MISS_HIT Style Summary: 1 file(s) analysed, 1 error(s) diff --git a/tests/style/bug_276_ice_on_dodgy_function_name/test.m b/tests/style/bug_276_ice_on_dodgy_function_name/test.m new file mode 100644 index 0000000..ade97b0 --- /dev/null +++ b/tests/style/bug_276_ice_on_dodgy_function_name/test.m @@ -0,0 +1,3 @@ +function pth = foo.bar() + +end diff --git a/tests/style/bug_276_ice_on_dodgy_function_name/test.m_fixed b/tests/style/bug_276_ice_on_dodgy_function_name/test.m_fixed new file mode 100644 index 0000000..ade97b0 --- /dev/null +++ b/tests/style/bug_276_ice_on_dodgy_function_name/test.m_fixed @@ -0,0 +1,3 @@ +function pth = foo.bar() + +end