Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -1101,7 +1101,7 @@ class Impact:
W('cs_fixture_type', sorted(x for x in fixt if not x[0].startswith('collection:')))

# ── facts: the graph, exported once (reused while graph.sqlite is unchanged) ────────────────────────────────
IMPACT_VERSION = '56' # 56: reg_key_fact carries a handler table's entries (kind table), literal a table key written as a dotted string or through a constant, and test_code; 55: cs_data_source, cs_data_type, cs_fixture_type, the C# test links a runner makes from a data attribute or a class/collection fixture (#1498, #1499); 53: implicit_new, the type a C# `new T()` constructs where T writes no constructor (#1473); 52: test_method holds a method under a composed or derived test marker declared in the repository (a Java annotation meta-annotated @Test, a C# attribute derived from FactAttribute: #1418, #1497; 51 was the C# test-links branch's number, landed as 55); 48: sigtype, a parameter / return position type_use resolves to a type, read before the textuse grep (#1422), and persist_field, the properties a persistence query reads (#1461); 47: test_method / fixture from graph_sql's one classification (a tear-down such as @AfterEach or [TestCleanup] is a fixture, [TestInitialize] is no test, an @Override is no named test: #1417 #1419 #1502), and reg_key_fact drops a string a decoration does not register under (#1413); 46: accessor carries the wither and an isX boolean's setX / withX, and a generated builder or fluent setter the engine resolved is a writer (#1404, #1409); 45: runs_before, a C# set-up an NUnit [SetUpFixture] or an MSTest assembly initializer runs for tests outside its type (#1501), stub rows for a member a Moq Protected() setup names by string (#1540), cs_config_literal for a Section:Key configuration key (#1443), and lex_parent puts a lambda under the declaration on its own line (#1556); 44: a C# MEMBER_ACCESS ref is qualified, so its qualifier decides (#1445); 41: spawns_fact, a test that runs a script by its path (ax_spawn.py); 40: test_method holds a script test's module (a test-tree file run as a program, no framework: graph_sql.script_tests); 39: a chained route link's `calls` row and `registration` label sit on the link's own line, with its own verb and path; 38: reg_key_fact drops a decoration string with a space in it (a description, not a key); 37: via_base / via_site, a caller that reaches a declaration through a base it is override-equivalent to (#1542), and injected_bean, the bean an injection point was wired to (#1384); 36: handoff_at, route_arg, callable_const, init_wrapper, init_alias, returns_fn — a const holding a wrapped handler registered at a route; 35: 0.1.5's 33 (#1598, the defines edges the path export links) joined 0.1.6's 33, two different fact sets under one number; 33 (0.1.6): calls carries the tier "stub" for a call inside a mock's stub or verification, reg_verb / lit_verb join a route by its HTTP method, and a handler's route joins its type's prefix; 32: cert_tier's why is worded per tier (an event_dispatch row says it sends the request or event), and the route facts #1633 changed (#1510), which merged without a bump; 31: event_dispatch edges (a published event reaches its listeners, #1391) and the pytest fixture_injection reading (#1631) change impact's facts; 30: registers, a bean another class's annotation registers (#1396, #1414); 29: the edges it links from the path export changed (#1402), and a cache written before it must not survive; 28: reexport_from, the file an `export *` line re-exports; 27: framework, the engine's framework_edge (#1509); 24: the test* naming convention requires a test class as owner (#1181); 23: owner/member disambiguated by file, two classes of one name no longer merging (#1188); 22: lex_parent, the innermost declaration enclosing each one by span (#1183); 21: cert_tier, the tier -> certainty table the call rules join on (#1131); 20: faccess, the engine's resolved field accesses (#1071); 3: decl_file facts (the import-time test-file rule); 14: the registration-key
IMPACT_VERSION = '57' # 57: a TypeScript object literal key is a ref of entity kind OBJECT_PROPERTY_KEY, kept past a bound access on its line; 56: reg_key_fact carries a handler table's entries (kind table), literal a table key written as a dotted string or through a constant, and test_code; 55: cs_data_source, cs_data_type, cs_fixture_type, the C# test links a runner makes from a data attribute or a class/collection fixture (#1498, #1499); 53: implicit_new, the type a C# `new T()` constructs where T writes no constructor (#1473); 52: test_method holds a method under a composed or derived test marker declared in the repository (a Java annotation meta-annotated @Test, a C# attribute derived from FactAttribute: #1418, #1497; 51 was the C# test-links branch's number, landed as 55); 48: sigtype, a parameter / return position type_use resolves to a type, read before the textuse grep (#1422), and persist_field, the properties a persistence query reads (#1461); 47: test_method / fixture from graph_sql's one classification (a tear-down such as @AfterEach or [TestCleanup] is a fixture, [TestInitialize] is no test, an @Override is no named test: #1417 #1419 #1502), and reg_key_fact drops a string a decoration does not register under (#1413); 46: accessor carries the wither and an isX boolean's setX / withX, and a generated builder or fluent setter the engine resolved is a writer (#1404, #1409); 45: runs_before, a C# set-up an NUnit [SetUpFixture] or an MSTest assembly initializer runs for tests outside its type (#1501), stub rows for a member a Moq Protected() setup names by string (#1540), cs_config_literal for a Section:Key configuration key (#1443), and lex_parent puts a lambda under the declaration on its own line (#1556); 44: a C# MEMBER_ACCESS ref is qualified, so its qualifier decides (#1445); 41: spawns_fact, a test that runs a script by its path (ax_spawn.py); 40: test_method holds a script test's module (a test-tree file run as a program, no framework: graph_sql.script_tests); 39: a chained route link's `calls` row and `registration` label sit on the link's own line, with its own verb and path; 38: reg_key_fact drops a decoration string with a space in it (a description, not a key); 37: via_base / via_site, a caller that reaches a declaration through a base it is override-equivalent to (#1542), and injected_bean, the bean an injection point was wired to (#1384); 36: handoff_at, route_arg, callable_const, init_wrapper, init_alias, returns_fn — a const holding a wrapped handler registered at a route; 35: 0.1.5's 33 (#1598, the defines edges the path export links) joined 0.1.6's 33, two different fact sets under one number; 33 (0.1.6): calls carries the tier "stub" for a call inside a mock's stub or verification, reg_verb / lit_verb join a route by its HTTP method, and a handler's route joins its type's prefix; 32: cert_tier's why is worded per tier (an event_dispatch row says it sends the request or event), and the route facts #1633 changed (#1510), which merged without a bump; 31: event_dispatch edges (a published event reaches its listeners, #1391) and the pytest fixture_injection reading (#1631) change impact's facts; 30: registers, a bean another class's annotation registers (#1396, #1414); 29: the edges it links from the path export changed (#1402), and a cache written before it must not survive; 28: reexport_from, the file an `export *` line re-exports; 27: framework, the engine's framework_edge (#1509); 24: the test* naming convention requires a test class as owner (#1181); 23: owner/member disambiguated by file, two classes of one name no longer merging (#1188); 22: lex_parent, the innermost declaration enclosing each one by span (#1183); 21: cert_tier, the tier -> certainty table the call rules join on (#1131); 20: faccess, the engine's resolved field accesses (#1071); 3: decl_file facts (the import-time test-file rule); 14: the registration-key
# layer; 15: the registration facts (two 14s landed independently, which is exactly the collision this
# guards); 16: regsite folded into ax_registration's reg_key_fact; 20: implements_pair (#1011); 17/18: the tagged-template test registrar
# (it.each`…`) and its table span
Expand Down
5 changes: 5 additions & 0 deletions plugins/axiomcode/skills/axiomcode/scripts/axiomcode-index
Original file line number Diff line number Diff line change
Expand Up @@ -94,6 +94,9 @@ A = {
# a property's name (`this.pending`, `row.setX`) is in literalValue with an empty potentialQualifiedName — 36k of 60k references in the parser repo
expr=dict(file='all-typescript-expressions.csv', kind='kind', name='potentialQualifiedName', nameFallback='literalValue', line='startLine', fileVia=('modules', 'tsModuleLinkHash'),
refKinds={'IDENTIFIER_REFERENCE', 'PROPERTY_ACCESS'}, entityKind='referencedEntityKind',
# the key of an object literal (`{ eventId: … }`) is stored with the entity kind OBJECT_PROPERTY_KEY, not
# UNKNOWN: it is never a property ACCESS, so an access the engine bound on the same line is not this name
keyRole=dict(role='edgeRole', value='OBJECT_PROPERTY_KEY'),
litKinds={'LITERAL'}, litType=('literalType', 'STRING'), litValue='literalValue'),
comments=dict(file='all-typescript-comments.csv', text='commentText', kind='commentKind', line='startLine', filePath='filePath'),
typeRefs=dict(file='all-typescript-type-references.csv', name='typeName', context='context', ownerKind='referenceOwnerKind', line='startLine', fileVia=('modules', 'tsModuleLinkHash')),
Expand Down Expand Up @@ -573,6 +576,7 @@ c.executemany("INSERT INTO symbols VALUES (?,?,?,?,?,?,?,?,?,?,?,?,?)", sym)
e = A['expr']; refs = []; lits = []
namecol = e['name'] if isinstance(e['name'], str) else dict(x.split(':') for x in e['name'])
mname = e.get('memberName'); child_ek = {}
kr = e.get('keyRole')
if mname: # the member-name child's entity kind, for the access that stands for it (the parent's own is UNKNOWN until resolved)
for r in rows(e['file']):
if r.get(mname['role']) == mname['value'] and r.get(mname['parent']): child_ek[r[mname['parent']]] = r.get(e['entityKind'], '')
Expand All @@ -591,6 +595,7 @@ for r in rows(e['file']):
n = n.rsplit('.', 1)[-1]
ek = r.get(e['entityKind'], '')
if mname and ek in ('', 'UNKNOWN'): ek = child_ek.get(r.get(mname['id'], ''), ek) or ek
if kr and ek in ('', 'UNKNOWN') and r.get(kr['role']) == kr['value']: ek = kr['value']
refs.append((n, file_of(r, e), int(r.get(e['line']) or 0), k, ek))
elif k in e['litKinds'] and r.get(e['litType'][0]) == e['litType'][1]:
v = (r.get(e['litValue']) or '')
Expand Down
5 changes: 4 additions & 1 deletion plugins/axiomcode/skills/axiomcode/scripts/dl/impact.dl
Original file line number Diff line number Diff line change
Expand Up @@ -462,7 +462,7 @@ direct(q, c, "uses", why, "by name", f, l) :- valueref(q, c, f, l), registered(q
// a FIELD: references by name, judged by where they are and how they are written
.decl fref(q:symbol, c:symbol, rk:symbol, f:symbol, l:number)
fref(q, c, rk, f, l) :- target(q, "field", fl, _), field(fl, _, n, ff, fll), ref(c, n, rk, ek, f, l), !local_kind(ek), !type_or_call_kind(ek), (f != ff ; l != fll),
!fa_line(q, f, l).
(!fa_line(q, f, l) ; ek = "OBJECT_PROPERTY_KEY").
// an enum member is written like a type, so the parser labels the genuine reference TYPE: keep those, but only in a
// file that can see the enum — its own directory, or a file that names the enum type somewhere
.decl enum_member_target(q:symbol, fl:symbol)
Expand Down Expand Up @@ -533,6 +533,9 @@ direct(q, c, "uses", "reads it", "resolved", f, l) :- target(q, "field", fl
// more, whichever callable the line is attributed to. fa_known works per caller, and a lambda written on the same line
// as the access (`m.GetOrAdd(T.Culture + k, x => ...)`) is a different callable, so its name match on T.Culture came
// back as a second, [in scope] reader that reads nothing (#1445).
// An object literal's KEY on that line is not the access the engine bound, and no field_access row ever covers one:
// `const meta: EventMeta = { eventId: options.eventId }` binds `options.eventId` to PublishOptions.eventId, and the key
// `eventId` is EventMeta's. fref keeps a ref of entity kind OBJECT_PROPERTY_KEY (TypeScript) past fa_line.
.decl fa_line(q:symbol, f:symbol, l:number)
fa_line(q, f, l) :- target(q, "field", fl, _), fa_bound(_, fl, _, f, l).
fa_line(q, f, l) :- target(q, "field", fl, _), field(fl, _, n, _, _), fa_bound(_, fl2, _, f, l), fl2 != fl, field(fl2, _, n, _, _).
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
{"lang": "typescript", "src": "src",
"checks": [
{"why": "an object literal key on the same line as a bound access of another type's same-named field is a separate reference: `{ eventId: options.eventId }` typed EventMeta writes EventMeta.eventId, and the engine binding `options.eventId` to PublishOptions.eventId must not hide it",
"run": ["impact", "EventMeta.eventId"],
"want": ["change: field EventMeta.eventId", "Bus.publish", "Recorder.wrap"],
"avoid": ["Stamper.stamp"]},
{"why": "control: a line that only reads another type's same-named field, bound by the engine, is still not this field's reader",
"run": ["impact", "EventMeta.eventId"],
"avoid": ["src/stamper.ts"]},
{"why": "control: the bound access is the other field's resolved read",
"run": ["impact", "PublishOptions.eventId"],
"want": ["[resolved] Bus.publish src/bus.ts:5 — reads it", "[resolved] Stamper.stamp src/stamper.ts:5 — reads it"],
"avoid": ["Recorder.wrap"]}
]}
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
import { EventMeta, PublishOptions } from './types';

export class Bus {
publish(name: string, options: PublishOptions = {}): EventMeta {
const meta: EventMeta = { eventId: options.eventId ?? name, name };
return meta;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
import { EventMeta } from './types';

export class Recorder {
wrap(meta: EventMeta): string {
return meta.eventId;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
import { PublishOptions } from './types';

export class Stamper {
stamp(options: PublishOptions): string {
return options.eventId ?? 'none';
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
export interface EventMeta {
readonly eventId: string;
readonly name: string;
}

export interface PublishOptions {
readonly eventId?: string;
}
Loading