diff --git a/plugins/axiomcode/hooks/direct.py b/plugins/axiomcode/hooks/direct.py index 4857a2157..37eaf8d3e 100755 --- a/plugins/axiomcode/hooks/direct.py +++ b/plugins/axiomcode/hooks/direct.py @@ -68,11 +68,12 @@ def identifiers(pat): if COMMON.fullmatch(n) or re.fullmatch(r'[A-Z0-9_]+', n) or n in out: continue # a keyword or a CONSTANT_SHAPED word is not a callable's name # a plain lowercase word (`once`, `path`, `session`) is as likely prose or a flag as a name, unless THAT - # word is written as code: `locate\(`, `def locate`, `.locate`, `function render`. Code elsewhere in the - # pattern does not count: in `expr_child("client"` the name is expr_child, and client is a string. + # word is written as code: `locate\(`, `def locate`, `obj.locate(`, `function render`. Code elsewhere in the + # pattern does not count: in `expr_child("client"` the name is expr_child, and client is a string. A dot + # alone is not code either: `\.json` is an extension and `\.decl` a Datalog directive. if n.islower() and '_' not in n and not ( re.match(r'\\?\(', br[m.end():]) - or re.search(r'(\b(def|function|fn|func|void|class)\s+|\\?\.|::|->)$', br[:m.start()])): + or re.search(r'(\b(def|function|fn|func|void|class)\s+|::|->)$', br[:m.start()])): continue out.append(n) return out[:6] diff --git a/tests/directive.py b/tests/directive.py index 20462f5a1..7c572f168 100644 --- a/tests/directive.py +++ b/tests/directive.py @@ -121,6 +121,14 @@ def check(why, cond, detail=''): check('CONTROL: a name declared in more than a handful of places says nothing about which one, and is not named', rc == 0 and out == '', f'out={out[:120]}') + rc, out, _ = fire(repo, 'Grep', {'pattern': r'^\.work ref|\.work\b'}, session='s3') + check('CONTROL: a lowercase word behind a dot alone (`\\.json`, a Datalog `.decl`) is an extension or a directive, not named', + rc == 0 and out == '', f'out={out[:120]}') + + rc, out, _ = fire(repo, 'Grep', {'pattern': r'\.work\('}, session='s10') + check('the same word called behind a dot (`.work(`) is a name, and is told', + rc == 0 and ctx(out) and 'src/util.py:1' in ctx(out), f'out={out[:200]}') + rc, out, _ = fire(repo, 'Grep', {'pattern': 'def render(', 'path': 'lib'}, session='s9') check('the declaration inside the searched path is the one named, not the first in the repository', rc == 0 and ctx(out) and 'lib/view.py:5' in ctx(out) and 'src/' not in ctx(out), f'out={out[:200]}')