diff --git a/plugins/axiomcode/skills/axiomcode/scripts/axiomcode-impact b/plugins/axiomcode/skills/axiomcode/scripts/axiomcode-impact index ebf4d9da3..62e97a540 100755 --- a/plugins/axiomcode/skills/axiomcode/scripts/axiomcode-impact +++ b/plugins/axiomcode/skills/axiomcode/scripts/axiomcode-impact @@ -270,7 +270,12 @@ class Impact: Resolution matches a declaration by its TRAILING segments, so `zzzz.qqqq.Owner.member` and the true fully-qualified spelling are indistinguishable once matched: both come back as `Owner.member`. Comparing the typed string against every qualified_name and display a - candidate carries is what tells a real package apart from one that is not in the graph.""" + candidate carries is what tells a real package apart from one that is not in the graph. + + A file:line is not a dotted name: its dots are the file's (`user.controller.js:7`), and the + resolver already matched that path against the index, so there is no prefix left to check.""" + m = re.match(r'^(.+?):(\d+)$', typed.strip().strip('`"\'')) + if m and ('/' in m.group(1) or '.' in m.group(1)): return '' typed = re.sub(r'\(.*\)$', '', typed).replace('#', '.').strip('.') if typed.count('.') < 2: return '' # Owner.member carries no prefix to validate names = [] diff --git a/tests/cases/javascript/fileline-dotted-basename/case.json b/tests/cases/javascript/fileline-dotted-basename/case.json new file mode 100644 index 000000000..4bcedc31f --- /dev/null +++ b/tests/cases/javascript/fileline-dotted-basename/case.json @@ -0,0 +1,18 @@ +{"lang": "javascript", "src": "src", + "checks": [ + {"why": "a file:line whose basename carries an extra dot (order.service.js) is the declaration at that line, not package 'order' + 'service.js'", + "run": ["impact", "src/services/order.service.js:3"], + "want": ["change: placeOrder (at src/services/order.service.js:3)", "createOrder"], + "avoid": ["matches no package"]}, + {"why": "the same in a controllers directory (user.controller.js)", + "run": ["impact", "src/controllers/user.controller.js:4"], + "want": ["change: createOrder (at src/controllers/user.controller.js:4)"], + "avoid": ["matches no package"]}, + {"why": "control: an undotted basename answers as before", + "run": ["impact", "src/services/userService.js:2"], + "want": ["change: findUser (at src/services/userService.js:2)", "placeOrder"], + "avoid": ["matches no package"]}, + {"why": "control: a dotted basename under a directory the index does not have is still refused", + "run": ["impact", "zzz/order.service.js:3"], + "expect_error": true, + "want": ["no callable spans zzz/order.service.js:3"]}]} diff --git a/tests/cases/javascript/fileline-dotted-basename/src/controllers/user.controller.js b/tests/cases/javascript/fileline-dotted-basename/src/controllers/user.controller.js new file mode 100644 index 000000000..1bcd133f7 --- /dev/null +++ b/tests/cases/javascript/fileline-dotted-basename/src/controllers/user.controller.js @@ -0,0 +1,7 @@ +const { placeOrder } = require('../services/order.service'); + +function createOrder(req, res) { + res.json(placeOrder(req.params.id, req.body)); +} + +module.exports = { createOrder }; diff --git a/tests/cases/javascript/fileline-dotted-basename/src/services/order.service.js b/tests/cases/javascript/fileline-dotted-basename/src/services/order.service.js new file mode 100644 index 000000000..fe0e1688b --- /dev/null +++ b/tests/cases/javascript/fileline-dotted-basename/src/services/order.service.js @@ -0,0 +1,6 @@ +const { findUser } = require('./userService'); +function placeOrder(userId, item) { + const user = findUser(userId); + return { user, item }; +} +module.exports = { placeOrder }; diff --git a/tests/cases/javascript/fileline-dotted-basename/src/services/userService.js b/tests/cases/javascript/fileline-dotted-basename/src/services/userService.js new file mode 100644 index 000000000..70b9d91b5 --- /dev/null +++ b/tests/cases/javascript/fileline-dotted-basename/src/services/userService.js @@ -0,0 +1,4 @@ +function findUser(id) { + return { id }; +} +module.exports = { findUser }; diff --git a/tests/cases/typescript/fileline-dotted-basename/case.json b/tests/cases/typescript/fileline-dotted-basename/case.json new file mode 100644 index 000000000..d282220f8 --- /dev/null +++ b/tests/cases/typescript/fileline-dotted-basename/case.json @@ -0,0 +1,18 @@ +{"lang": "typescript", "src": "src", + "checks": [ + {"why": "a file:line in a NestJS/Angular-style file (user.service.ts) is the declaration at that line, not package 'user' + 'service.ts'", + "run": ["impact", "src/user.service.ts:3"], + "want": ["change: UserService.find (at src/user.service.ts:3)", "UserController.get"], + "avoid": ["matches no package"]}, + {"why": "the same for user.controller.ts", + "run": ["impact", "src/user.controller.ts:7"], + "want": ["change: UserController.get (at src/user.controller.ts:7)"], + "avoid": ["matches no package"]}, + {"why": "control: an undotted basename answers as before", + "run": ["impact", "src/userHelper.ts:2"], + "want": ["change: helper (at src/userHelper.ts:2)"], + "avoid": ["matches no package"]}, + {"why": "control: a dotted NAME with a fabricated prefix is still refused by the prefix check", + "run": ["impact", "zzz.qqq.UserService.find"], + "expect_error": true, + "want": ["'zzz.qqq' matches no package"]}]} diff --git a/tests/cases/typescript/fileline-dotted-basename/src/user.controller.ts b/tests/cases/typescript/fileline-dotted-basename/src/user.controller.ts new file mode 100644 index 000000000..36210904d --- /dev/null +++ b/tests/cases/typescript/fileline-dotted-basename/src/user.controller.ts @@ -0,0 +1,9 @@ +import { UserService } from './user.service'; + +export class UserController { + constructor(private readonly users: UserService) {} + + get(id: string): string { + return this.users.find(id); + } +} diff --git a/tests/cases/typescript/fileline-dotted-basename/src/user.service.ts b/tests/cases/typescript/fileline-dotted-basename/src/user.service.ts new file mode 100644 index 000000000..26a54b707 --- /dev/null +++ b/tests/cases/typescript/fileline-dotted-basename/src/user.service.ts @@ -0,0 +1,5 @@ +export class UserService { + find(id: string): string { + return id; + } +} diff --git a/tests/cases/typescript/fileline-dotted-basename/src/userHelper.ts b/tests/cases/typescript/fileline-dotted-basename/src/userHelper.ts new file mode 100644 index 000000000..3bf28b37d --- /dev/null +++ b/tests/cases/typescript/fileline-dotted-basename/src/userHelper.ts @@ -0,0 +1,3 @@ +export function helper(id: string): string { + return id; +}