commit:     8abeb154ed6047cd730ceb242a2fa08a486f739f
Author:     Arthur Zamarin <arthurzam <AT> gentoo <DOT> org>
AuthorDate: Tue Sep 19 18:09:54 2023 +0000
Commit:     Arthur Zamarin <arthurzam <AT> gentoo <DOT> org>
CommitDate: Sat Sep 23 15:36:03 2023 +0000
URL:        
https://gitweb.gentoo.org/proj/pkgcore/pkgcheck.git/commit/?id=8abeb154

DuplicateFunctionDefinition: new check for duplicate global functions

Closes: https://bugs.gentoo.org/365691
Resolves: https://github.com/pkgcore/pkgcheck/issues/624
Signed-off-by: Arthur Zamarin <arthurzam <AT> gentoo.org>

 src/pkgcheck/checks/codingstyle.py                 | 28 ++++++++++++++++++----
 .../DuplicateFunctionDefinition/expected.json      |  2 ++
 .../DuplicateFunctionDefinition-0.ebuild           | 21 ++++++++++++++++
 3 files changed, 47 insertions(+), 4 deletions(-)

diff --git a/src/pkgcheck/checks/codingstyle.py 
b/src/pkgcheck/checks/codingstyle.py
index 58634515..d0b5d861 100644
--- a/src/pkgcheck/checks/codingstyle.py
+++ b/src/pkgcheck/checks/codingstyle.py
@@ -1457,14 +1457,27 @@ class VariableShadowed(results.LinesResult, 
results.Warning):
         return f"variable {self.var_name!r} may be shadowed, {self.lines_str}"
 
 
+class DuplicateFunctionDefinition(results.LinesResult, results.Error):
+    """Function is defined multiple times. This is a definetly typo."""
+
+    def __init__(self, func_name, *args, **kwargs):
+        super().__init__(*args, **kwargs)
+        self.func_name = func_name
+
+    @property
+    def desc(self):
+        return f"multiple definitions of function {self.func_name!r} were 
found, {self.lines_str}"
+
+
 class DeclarationShadowedCheck(Check):
     """Scan ebuilds for shadowed variable assignments in global scope."""
 
     _source = sources.EbuildParseRepoSource
-    known_results = frozenset({VariableShadowed})
+    known_results = frozenset({VariableShadowed, DuplicateFunctionDefinition})
 
     def feed(self, pkg: bash.ParseTree):
-        assigns = defaultdict(list)
+        var_assigns = defaultdict(list)
+        func_declares = defaultdict(list)
 
         for node in pkg.tree.root_node.children:
             if node.type == "variable_assignment":
@@ -1477,9 +1490,16 @@ class DeclarationShadowedCheck(Check):
                         for node, _ in bash.var_query.captures(value_node)
                     ):
                         continue
-                assigns[used_name].append(node)
+                var_assigns[used_name].append(node)
+            elif node.type == "function_definition":
+                used_name = pkg.node_str(node.child_by_field_name("name"))
+                func_declares[used_name].append(node)
 
-        for var_name, nodes in assigns.items():
+        for var_name, nodes in var_assigns.items():
             if len(nodes) > 1:
                 lines = sorted(node.start_point[0] + 1 for node in nodes)
                 yield VariableShadowed(var_name, lines=lines, pkg=pkg)
+        for func_name, nodes in func_declares.items():
+            if len(nodes) > 1:
+                lines = sorted(node.start_point[0] + 1 for node in nodes)
+                yield DuplicateFunctionDefinition(func_name, lines=lines, 
pkg=pkg)

diff --git 
a/testdata/data/repos/standalone/DeclarationShadowedCheck/DuplicateFunctionDefinition/expected.json
 
b/testdata/data/repos/standalone/DeclarationShadowedCheck/DuplicateFunctionDefinition/expected.json
new file mode 100644
index 00000000..c560713b
--- /dev/null
+++ 
b/testdata/data/repos/standalone/DeclarationShadowedCheck/DuplicateFunctionDefinition/expected.json
@@ -0,0 +1,2 @@
+{"__class__": "DuplicateFunctionDefinition", "category": 
"DeclarationShadowedCheck", "package": "DuplicateFunctionDefinition", 
"version": "0", "lines": [11, 15], "func_name": "any_function"}
+{"__class__": "DuplicateFunctionDefinition", "category": 
"DeclarationShadowedCheck", "package": "DuplicateFunctionDefinition", 
"version": "0", "lines": [7, 19], "func_name": "pkg_preinst"}

diff --git 
a/testdata/repos/standalone/DeclarationShadowedCheck/DuplicateFunctionDefinition/DuplicateFunctionDefinition-0.ebuild
 
b/testdata/repos/standalone/DeclarationShadowedCheck/DuplicateFunctionDefinition/DuplicateFunctionDefinition-0.ebuild
new file mode 100644
index 00000000..ad8ec8b7
--- /dev/null
+++ 
b/testdata/repos/standalone/DeclarationShadowedCheck/DuplicateFunctionDefinition/DuplicateFunctionDefinition-0.ebuild
@@ -0,0 +1,21 @@
+
+HOMEPAGE="https://github.com/pkgcore/pkgcheck";
+DESCRIPTION="ebuild with shadowed variables"
+SLOT="0"
+LICENSE="BSD"
+
+pkg_preinst() {
+       :
+}
+
+any_function() {
+       :
+}
+
+any_function() {
+       :
+}
+
+pkg_preinst() {
+       any_function
+}

Reply via email to