Repository navigation
Release 0.1.5 - #1667
Merged
Merged
Release 0.1.5#1667
Conversation
… keeps its own version) Co-authored-by: axiomcode-bot[bot] <334110751+axiomcode-bot[bot]@users.noreply.github.com>
…1537, #1539, #1527, #1528, #1529, #1531, #1512) Fixture visibility now follows the runner's own rules instead of a name match. Engine (framework-behavior/dispatch.dl, knobs.dl): - a fixture belongs to every module it is an attribute of, so a conftest's star import makes it that conftest's fixture (#1537) - a module named in pytest_plugins registers its fixtures for the session (#1537) - the registered name is the decorator's name= when it gives one (#1539) - an argument the test's own parametrize supplies directly requests no fixture; an indirect one still does (#1529) - a fixture a class declares serves that class and its subclasses and shadows the module's fixture of the name (#1512) Impact (axiomcode-impact, dl/impact.dl, graph_sql.py): - a parameter is joined to a fixture through the engine's fixture_injection edge where the engine ran, not by name - a fixture injected by name is no longer credited to every test of its file or class (#1527) - a usefixtures marker on a class, a module's pytestmark and the ini usefixtures option reach the tests they apply to (#1528), including a fixture from a plugin module or a star-imported fixtures module - a declaration decorated @fixture is never a test, and conftest.py is never collected (#1531) Cases: graph/test/python/cases/30-fixture-visibility and tests/cases/python/fixture-reaches-its-requesters, each with near-miss controls (a same-named fixture in a sibling directory, a def name that is not the registered name, an unloaded fixtures module, an indirect argument, a sibling class).
…sters or is injected with them (#1392, #1396, #1414) A class Spring Boot registers without a stereotype was not a bean, so every injection of it read unsatisfied and a change to it or to the class that registers it looked local. Engine (config-resolution): - The parser reads META-INF/spring/<service>.imports and META-INF/spring.factories (one descriptor per key, Properties syntax). A class named in an imports file or under a configuration key of spring.factories is an auto_configuration bean with its constructor reached; any other spring.factories key names a registered type whose documented callbacks are entry points, not a bean. - @EnableConfigurationProperties({T.class}) and @ConfigurationPropertiesScan register properties beans; @MapperScan (value, basePackages, basePackageClasses, Ant patterns, annotationClass, markerInterface) and MyBatis @Mapper register mapper proxy beans. MapStruct's @Mapper is excluded by its import. Query layer (impact): - registers(t, by, kind): a bean whose definition site is an annotation on another type. impact on the type lists that type as "registers it as a bean". - A type target lists who is injected with a bean one of its own @bean methods defines, so a change to a configuration class no longer reads as local. - Both rules are in impact.dl and in the SQL port; IMPACT_VERSION 30. Tests: java case 65-boot-bean-registration (near misses: a comment-only entry, an unrelated properties value, an unregistered properties class, interfaces outside every scan, MapStruct's @Mapper, a plain interface), plugin case bean-registered-or-defined-by-a-class (near misses: an unregistered properties class of the same shape, a non-@bean method returning an injected type).
…ibility python: a pytest fixture reaches exactly the tests that receive it (#1537)
…type fits (#1391) publishEvent(e) ended at the library boundary, so path from a publisher to its @eventlistener said the two were independent and impact on a listener said the change was local. call-edge-generation/event_dispatch.dl adds an event_dispatch call edge from the publish site to every listener whose declared event type the published type is assignable to: the exact type, any ancestor of it, and the catch-all ApplicationEvent and Object listeners. A listener is an @eventlistener or @TransactionalEventListener method (the classes named on the annotation win, else its one parameter) or the onApplicationEvent override of an ApplicationListener<E> implementation, which also becomes a queue entry point. Publishers are a knob table (knobs.dl section 17) matched against the receiver's declared type, so a project class with its own publishEvent stays an ordinary call. A listener for a subtype does not receive the supertype's event, and a listener for an unrelated type receives nothing. Query layer: an event_dispatch caller reads "publishes an event this handles" and is not reported as a call that bypasses the container proxy. Case 65-spring-application-events and plugin case event-reaches-its-listeners, with controls. next-step-reads-the-whole-answer keeps its unmodelled library-call check on an Object-typed event.
… the rebase Co-authored-by: axiomcode-bot[bot] <334110751+axiomcode-bot[bot]@users.noreply.github.com
…spatch and the fixture reading does not survive (#1391)
…_view() (#1510) A Django-style route table dispatched only to an undecorated function named directly in `urlpatterns`. A view under @login_required, a route in a list mounted with include(), and a class-based view routed with .as_view() were not url entry points, so impact called a change to them local. A test that requested the URL reached the view only when the pattern started with a slash and the view was imported by name. Engine (dispatch.dl, knobs.dl): - a route names the def written under its decorators, not the wrapper - a list handed to include() (by name, inline, or in a (list, ns) tuple) is a route table - X.as_view() dispatches to X's HTTP-verb methods, found through the MRO - the url_dispatch edge carries the path the route serves, composed through every include() that mounts its table; a regular-expression pattern keeps the generic label Plugin: - routes are registration keys by the engine's served path, so a test that requests /api/v1/status/ reaches a view registered as "status/" under include() at "api/v1/"; a typed converter narrows the match and a verbatim key wins over a parameterised one - context answers "what does this URL run" from the served path; a test method that requests a URL is never said to serve it, and a pattern in a table the engine read is not taken for the whole path - impact's verification accepts the rules' own decorator-by-name hop Fixes #1510, #1511, #1513, #1482, #1483
…t type (#1383) mediator.Send(new GetOrder(id)) runs IRequestHandler<GetOrder, R>.Handle in process, and no call site names the handler, so path called the two independent and impact on the handler said only "entry point". framework-behavior/dispatch.dl now adds an event_dispatch call edge from the site to the handler chosen by the request's TYPE, beside the site's own row for the library method. One rule, keyed on cs_med_dispatch(SendMethod, HandlerBase, Fan) in knobs.dl, whose handler method is the one the cs_framework_callback table (the entry-point table) already names for that base: - Send -> IRequestHandler, the exact type, with a generic request's type arguments (GetById<Order> does not reach the handler of GetById<Widget>; an open generic handler serves any); - Publish -> every INotificationHandler of the type and of each of its bases (the interface is contravariant); - Send -> IPipelineBehavior, IRequestPreProcessor, IRequestPostProcessor: the step for its own request, and an open generic step for every request; - a request declared as a base (not an interface) fans to the handler of each type in its family; one declared as the marker interface links nothing. The request's type is read by the rules that already read a bus message's (msg_arg_type_name), and where both ends resolve, the resolved type decides and not the simple name. A receiver that is a property of another value (services.Mediator.Send) is now named by the property's declared type, for every by-name framework receiver. A send whose request is a mock's argument matcher (Arg.Any<T>(), It.IsAny<T>()) links nothing: it is a stub, not a dispatch. Case 18-mediator-send with controls (a handler of another request type, a generic request closed over another type, a sibling notification, a notification Sent rather than Published, a non-mediator receiver, a mock stub); tools/mediator-dispatch-test.sh asserts the edges in the package-in-source and package-unstaged shapes.
… waits (#1606) The compiled query programs (impact.dl, path*.dl) were cached inside the plugin's own dl/.cache, so every plugin copy recompiled identical rules, and the build compiled them only after publishing the graph, so the first query raced the compile and paid it (43-79 s). - dl_program: cache in ${XDG_CACHE_HOME:-~/.cache}/axiomcode/queries, keyed by the rules and the platform; an older dl/.cache binary is still used. A query with no binary answers from the Souffle interpreter and starts one detached background compile under a lock. - axiomcode-build starts that compile when the build starts, beside the engine, and only reports its state after publishing. - impact: the untyped-receiver caller sample is ordered by file and line, not by symbol id, so two builds of one tree show the same sample. - tests/query_rules.py and a python case with a control.
…hey cannot analyse - --range a..b reads from `git merge-base a b`, not a's tip, and says so when a has moved: commits the base branch received after the fork were reported as the branch's own changes and their tests selected. `a` alone is a..HEAD. - a clean working tree over committed work answers "no change" and names the --range that holds the commits; not on a base branch itself. - a copy without git is refused with what to pass, instead of a diff against an empty text. Named files (`changed <file>`, `test-impact <file>`, MCP files=[...]) count whole when there is no edit to diff. - a file the base does not have is one `added <file>` line, plus each new declaration something outside the file already calls. Docstring lines are never read as headers, and an added declaration carries its own line. - an insertion strictly inside a callable is its body change; an insertion slides past equal lines so a new type starts after the brace above it; package / import / using / namespace lines declare nothing. - changed files outside every indexed language are named, never dropped; test-impact lists the test files whose text names them, and code that is also run as a program is looked for by name, with a lower-bound note when no test names it. An edited test file is itself a test to run. - extensionless scripts the graph holds are no longer dropped from the diff; the name tier stays in the changed file's language; .cs picks dotnet test; --in no longer reaches changed as a file list; an answer with no rows past page 1 is not paged; --impact output follows the list it belongs to. - MCP descriptions, SKILL.md and reference/changed-and-tests.md describe it.
… the index chose `axiomcode graph` ran axiomcode-build with no flags, which detects every language in the tree. On a repository indexed with --lang it rebuilt the whole graph on every call, started JavaScript/TypeScript compiles for stray files, left a graph for each, and recorded the detected languages as the index's choice, so every later refresh solved them too. - graph draws from graph.sqlite when the file table says it is current, and otherwise rebuilds with the recorded --lang/--src/--library (ax_fresh.rebuild_env, shared with the background refresh) - axiomcode-build: a build that names no language keeps an explicit --lang (and --src) recorded in the file table (ax_fresh.py chosen), so the refresh, a broken-graph repair, a bare index and graph never solve a language the index left out; detected languages are still detected again - the page draws every language graph the repository has - prose counts, the page's absolute path, and `axiomcode index --library` as the advice; help, SKILL.md, the MCP description and README agree - tests/graph_verb.py: 21 checks with a detected-languages control
…asks, not by symbol ids When several declarations matched the task's words with the same score (a mapper method, a repository method, a service method and a query method all named findByX), the first seed and its three siblings were whichever came first in the graph's symbol ids. Those ids are hashes that change with the directory a project is indexed in, so the same question on the same code named the mapper method and its XML in one copy and dropped both in another. - pick_seeds breaks a tie by: a declaration bound by a text file of the kind the question asks about (the mapper method whose XML holds the SQL, for a SQL question); then the one whose own name holds more of the matched words; then its name and place. A question that asks about no text file walks no tree and gets no preference. - The text-binding ring takes an interface seed's implementation callees at their nearer distance. A mapper call one hop inside the implementation was skipped whenever the closure walk had already placed it at hop 3. - context --source on a SQL or config question crashed: the printed code replaced the question text before the text-file check read it. Test: java case context-sql-tie-picks-the-bound-method (four equal matches that sort before the mapper by name; near misses: another mapper XML with the same statement id under a different namespace, and the same words without a SQL question, which lists no XML).
java: a published Spring application event reaches the listeners its type fits (#1391)
…h-r2 python: a route reaches its view through decorators, include() and as_view(), and carries the path it serves (#1510)
csharp: a mediator Send or Publish reaches the handler for the request type (#1383)
plugin: compile the query rules once per machine, never while a query waits (#1606)
…e-base changed / test-impact: read a branch from its merge-base, name what they cannot analyse (#1504)
…-flags graph: draw the existing graph, and every rebuild keeps the languages the index chose (#1480)
java: context orders equal-scoring entry points by the text file the question asks about (#1392)
…oints, and impact names who receives a provider (#1109) The decorator relation already gave Nest and Angular their roots (route handlers, container-built constructors, lifecycle hooks). What it did not give was the wiring: in `@Controller() class C { constructor(private svc: OrderService) {} }` nothing in the repository passes an OrderService to C, the container does, so a change to OrderService read as if no class received it. config-resolution/di.dl reads the decorator projection once more: - bean_def: a class carrying @Injectable is a provider, keyed by its own class. - inject_point: a constructor parameter of a container-owned class (the same class decorators the roots use), typed by its declared class. A parameter carrying @Inject(TOKEN), or an integration's @Inject<Name>(...), is wired by token, not by type, and is not a slot. - di_edge: known_bean when a provider of exactly that class exists, unsatisfied otherwise. Both containers key by class, so a subtype never satisfies a slot; an abstract class bound with `{ provide, useClass }` is reported, not guessed. inject_point and di_edge are exported under Java's names and column orders, so the query layer, which already reads ext_inject_point for every language, lists the receiving constructor as "receives it by dependency injection (ctor_param)" with no change there. bean_def stays internal: the query layer reads it as a proxying container, which neither of these is. Measured: case 68 fixture di_edge 0 -> 4 (3 known_bean, 1 unsatisfied); edges and entries of the existing code unchanged a real Nest app di_edge 0 -> 23 (17 known_bean, 6 unsatisfied: every one an abstract repository bound by useClass in a module); call edges 2023 = 2023, entry points 164 = 164; index 7.0s -> 6.2s a real Angular app di_edge 0 -> 19 known_bean; call edges 1947 = 1947, entry points 289 = 289; index 5.75s -> 5.68s Controls: an undecorated class with the same constructor parameter, and an @Inject(TOKEN) parameter whose declared type is an interface, produce no slot. Case 68's entries golden now prints di_edge (tools/entry_report.py); with the inject_point rule removed it fails. The plugin case typescript/injected-provider checks impact on a provider (fails without the rule), on an @InjectRepository slot typed by a provider (no injection row; fails without the Inject<Name> match), and on a plain class passed to an ordinary constructor (no injection row). Closes #1109 Co-authored-by: axiomcode-bot[bot] <334110751+axiomcode-bot[bot]@users.noreply.github.com>
…lects the generic overload (#334) `create<K extends keyof WidgetMap>(kind: K)` declared before `create(kind: string)`: the compiler takes the generic for `create('video')` and the widening signature for `create(k)` with `k: string`. Once an interface's overloads shared a declarationGroupKey, specificity decided both sites for `string`, because the literal matched `string` concretely and matched nothing in `K`. The overload rules now evaluate the constraint: a string literal matches a type-variable parameter constrained by `keyof X` when X declares that key (a field or a method). Both signatures then match and declaration order decides, as the compiler does. A general string and a literal that is not a key still fall to `string`. Case 24's accepted gap is removed. New case 78 covers library fields, library methods and a client class, with controls for a non-key literal, a string variable and the widening signature declared first. Every site agrees with the compiler. Co-authored-by: axiomcode-bot[bot] <334110751+axiomcode-bot[bot]@users.noreply.github.com>
…ory, or file:line:col is the declaration at that line (#1600) A file:line is taken the way editors, stack traces and test runners print it: a leading ./ is dropped, an absolute path under the repository root is read relative to it, and a trailing :col is accepted. An absolute path outside the repository is named as outside instead of 'no callable spans'. A root-relative /src/... still answers as before. Closes #1600 Co-authored-by: axiomcode-bot[bot] <334110751+axiomcode-bot[bot]@users.noreply.github.com> Co-Authored-By: Claude <noreply@anthropic.com>
…skill Answering a question from the graph meant first finding out, with raw sqlite3, which table holds each fact in each language. reference/schema.md now says it for Python, Java and C#: decorations, resolved and library base types, entry points by reason, fields and properties and who writes them, call-edge tiers, strings and non-source text, tests and rungs, and where each language's graph lives. Each entry names the verb or the query, and what is not recorded. Every query was run on a fresh index of one project per language. SKILL.md links it in one line. Three schema notes the graph carries were stale and now agree: Python entry_points is not empty, C# fills fields, and type_use is empty for C#. The Python field extractor wrote tree-sitter's 0-based row as the field line, while every other Python relation is 1-based. Every field sat one line above its write, and a nested class's first field landed on its `class Meta:` line. Each site now adds 1. A new gate checks six write forms with class and method lines as controls; the golden had frozen the old values and moves by exactly one line on each of its 49 field rows.
…ite's argument returns (#695) A wrapper that returns a closure whose result is the call of the wrapper's parameter (memoize, once, lazy) now gives each wrapping call site a value of its own. A call through it takes its value from that site's argument only, instead of the union of every caller's argument, or nothing once the wrapper is over the parameter fan cap. Case 64: two memoized getters of different modules each reach their own module's member (were ambient_terminal); once/lazy getters resolve to one target instead of two. Controls (a closure returning its parameter, a closure calling its parameter but returning something else) are unchanged. Co-authored-by: axiomcode-bot[bot] <334110751+axiomcode-bot[bot]@users.noreply.github.com>
A multi-language repository could be left with no .axiomcode/out/graph.sqlite after its first build: the other languages' graphs sat unpublished under .axiomcode/out/<lang>, every query said "no graph yet — building one", rebuilt every language, and lost the main graph again. The build a query starts ran in the query's process group. A caller that stops the query (a timeout, Ctrl-C, a host that ends the command's process group) stopped the build with it: before the main graph was published, or while it was being indexed, which the build took for a failure and answered by deleting the solved graph. On a repository whose first build outlasts the caller's timeout, every query repeated it. - ax_contract.ensure_graph starts the build in a session of its own, as the background refresher already is, so it finishes whatever becomes of the query that started it; a later query finds it running and waits for it. - axiomcode-build: a signal that arrives once the main language is solved is held until graph.sqlite points at that graph (the indexer runs in its own process group); the languages still unsolved are recorded in out/partial, so the graph reads as stale and the next build builds them. A signal before the main language is solved stops the build at once, as before. - A query waiting on a refresh no longer stops waiting when the main graph is published while the language that holds the edited file is still being solved: it answered from that language's previous graph. Tests: tests/multi_language.py gains the stopped-query and stopped-index checks (single-language and stopped-before-solve controls); its refresh and upgrade checks pass again. tests/refresh_races.py waits for the repair build before holding the lock and accepts the wait message #1555 introduced. Co-authored-by: axiomcode-bot[bot] <334110751+axiomcode-bot[bot]@users.noreply.github.com>
…edef identities A property write through a `str` value or a JSDoc typedef `shape` landed on every other expression sharing that identity: a string is one value per text, a typedef one value per typedef. On a real bundler's source these writes were ~73K member_write rows and the source of its widest value sets (hundreds of parameters holding the same 552 values). - shared_identity_kind (ambient, str) guards every member-write rule (plain, computed key, keyed and enumerated copy, Object.assign-likes, defineProperty, defineProperties, setPrototypeOf); dropped writes are declared as member_write_refused(a, "shared_identity"). - A write through a shape keeps only func/ctor values (a handler stored on an untracked object is still callable through its typedef) and drops data stores. - keys_helper atoms reordered so each is bound by the previous one (it was a cross product of first params and loop heads, re-run every iteration). - path_value's two path-text regex tests hoisted into non-recursive helpers. New golden case 64-shared-identity-writes with controls: object literal and class-instance writes, typedef-declared members, and a handler written through a typedef all keep their edges. Co-authored-by: axiomcode-bot[bot] <334110751+axiomcode-bot[bot]@users.noreply.github.com>
…terated
A store through a JSDoc typedef dropped every value that was not a function or a
class, so `ctx.logger = new Logger()`, `ctx.api = { fetch() {} }`,
`ctx.util = require('./util')` and `ctx.list = [a, b]` no longer reached the calls
made through the same typedef elsewhere (`ctx.logger.log()`, `for (const f of
ctx.list) f()`), which had resolved before. Instances, object literals, module
namespaces, arrays and collections are kept now; string, symbol and other scalar
stores stay dropped, which is where the width came from.
Golden case 64 gains the module and iterated-array shapes and a string-store
control that must stay unresolved.
Co-authored-by: axiomcode-bot[bot] <334110751+axiomcode-bot[bot]@users.noreply.github.com>
…ved (#536) tsc resolves a call through a variable's ANNOTATION. Where that annotation needs the checker -- an indexed access through a generic alias such as `StoreApi<S>['setState']`, a named interface, an alias to an alias -- the parser fell through to the arrow initialiser and claimed it with `overloadCandidateCount = 1`, where tsc names one arm of an overload pair. The row is now left unresolved (count 0) instead. Unannotated arrows and annotations the parser can read (a function type, a type literal, one alias hop) resolve exactly as before, including the all-optional signature set that keeps the initialiser with the full candidate count. On a real state-management library: 9 call sites move from arrow/1 to unresolved, exactly the 9 that disagreed with getResolvedSignature; engine edges 4492 -> 4492. Goldens unchanged. Co-authored-by: axiomcode-bot[bot] <334110751+axiomcode-bot[bot]@users.noreply.github.com> Co-Authored-By: Claude <noreply@anthropic.com>
…ambda parameter takes its type (#1401) A `var` local whose type does not come from its initializer expression was left a declared unknown in three shapes, recorded as known-missing in case 61: - the element variable of `for (var x : xs)`: now the component type of an array, the written type argument of a platform collection (or an `? extends` bound), or the Iterable<T> argument of a client type, read from what the client wrote when the platform is not staged; - a try-with-resources resource: its implicit close() is now a synthesised `resource_close` edge to the resource type's no-argument close(), declared or `var`; - a lambda parameter, `var` or implicit, whose target is a platform functional interface: a table maps each parameter to the interface's type argument. The bundle positions a resource_close site at the resource local's declaration. Case 61 gains the shapes with controls (raw list, `? super`, an unlisted interface, a second type argument, a var resource of unknown type that gets no close()). Its three known-missing edges now resolve, so the file is removed; the bytecode oracle agrees 37/37.
javascript: a call through a memoize/once wrapper returns what that site's argument returns (#695)
typescript: a string literal that is a key of a keyof constraint selects the generic overload (#334)
…bstract-test-command hooks: C# edits get a graph line, the directive speaks once per session and names the verb, test-impact runs concrete test classes (#1504)
java: a var in an enhanced for, a try-with-resources resource and a lambda parameter takes its type (#1401)
typescript: a decorator container's constructor slots are injection points, and impact names who receives a provider (#1109)
…p a cached engine that dies with SIGILL The engine is compiled with -march=native, and the CI cache key named the CPU by its model name only. Hosted runners that report the same model name do not all expose the same instruction set, so a binary compiled on one was restored onto another and died with an illegal instruction on every TypeScript case. The key now hashes the model name and the flags line of /proc/cpuinfo. The driver also removes a locally cached binary that exits with SIGILL, so a bad entry in a shared cache kills one run, not every run after it.
…hat iterates or indexes it (#967) `const steps = [a, b]; for (const s of steps) s(node)` left `a` and `b` with no caller, and everything they reach lost its tests: impact answered "0 tests" for a helper three hops below a pipeline whose tests were indexed. The value-flow holder rules now follow a function one step further, into the elements of an array or object literal a variable, field or parameter holds (through `as const`/`satisfies`, `push`/`unshift` and a spread). A read of an element runs what the elements hold: a for-of binding (also over `Object.values(h)`), `h[i]` / `h[key]`, the element parameter of a forEach/map/filter/reduce callback, and `h.name` over a literal, which reaches only the property of that name. Each such call is a `fn_value_call`, the dispatch rung that impact, path and test selection walk. No call-site answer moves: for several elements the compiler names one arbitrary member of the union, so the call-site sites stay pinned as known-missing. Case 78 covers every shape, with controls that must not change: an array nothing iterates, a for-in over the table, a direct call, and a written key that must not reach the other entries. Co-authored-by: axiomcode-bot[bot] <334110751+axiomcode-bot[bot]@users.noreply.github.com>
Carry 0.1.4 fixes forward into 0.1.5
ci: key the engine cache on CPU flags, drop a cached engine that dies with SIGILL (#1657)
typescript: a function held in an array or table is run by the call that iterates or indexes it (#967)
…labels worded from the reason (#1389, #1423, #1544) One row per dependent: impact keyed its must-change and direct rows on (callable, reason), so a callable with two reasons printed twice and the section header counted it once per rung. Rows are now keyed on the callable within each section; the surest reason names the row and the others follow as "also:". --json keeps every reason. path next: names each caller once, and the Grep preview prints overloads in one file as one line. Non-source text: a name matched inside a .sh or .dl file (or an extensionless shell script) is out of scope and dropped. A plain-word name (note, export, validate) written with no call, quote or qualifier around it is prose: counted with the grep that lists it, listed under --page all or --limit, flagged "prose" in --json, and never counted as a binding. Labels: entry points are worded from one table in ax_edges.py. A route, main, RPC, CLI or message surface keeps today's sentence; a framework callback (an ORM hook, a bean constructor, a lifecycle method) says the framework calls it back and a change breaks that contract. An event or request hop says it sends what the handler handles. The tests line names test-code callables the answer lists but the count does not credit.
…te; the grouping case uses an engine reason token
…nd its entry line credits the publisher rows
swapnilpaliwal-sd
requested review from
JaredHLZhang,
Whua689 and
suyashpaliwal26
as code owners
September 28, 2026 16:22
…alified name says (#1598) `defines` is derived from line spans, and on an equal span the builder nested an anonymous callable under the named one beside it. `function first() {…} const xs = [1].map(function (v) {…});` and `const named = () => f(); const listed = [2].map(() => g());` each walked a fake hop from the named callable to the anonymous one, so every caller of `first` or `named` was reported as reaching what the other one calls. JavaScript's qualified names follow the source's nesting (`keys.outer.<function-expression>` is written inside `keys.outer`; `keys.<function-expression>` beside it), so on an equal span an anonymous JavaScript callable now nests only under a callable whose qualified name its own extends; otherwise the builder looks further down the stack. Java, C# and TypeScript name a lambda after its type, not its method, and are unchanged. Both builders (path export and the impact fast path) pass the qualified name to ax_edges.defines_edges; EXPORT_VERSION 3 and IMPACT_VERSION 33 re-export old caches. Defines edges: engine JS test graph 777 -> 773 (the two arrows at 15-jsdoc-forms main.js:8 move from the `onDone` arrow beside them to `main`); a real Express app with a minified bundle 860 -> 787, edges whose child name extends the definer's 394 -> 548; five other real apps and 13 corpus apps unchanged. Java and C# span cases unchanged (19/19). Build time unchanged (1.12 s). Co-authored-by: axiomcode-bot[bot] <334110751+axiomcode-bot[bot]@users.noreply.github.com>
The vendored parser keeps its own version and moves once per release, only when parser code changed. dev and main ship it at 0.1.1. On 0.1.4, four merged changes touched parser/: #1592 (a concise arrow body is owned by the arrow), #1616 (generated-output detection), #1621 (a package's published API is rooted from package.json) and #1625 (the Java walk and build directories). So 0.1.2, one bump for the release. (cherry picked from commit 51c5e8e) Co-authored-by: axiomcode-bot[bot] <334110751+axiomcode-bot[bot]@users.noreply.github.com>
parser: 0.1.2 on 0.1.5 (forward-port of #1668)
javascript: on one line an anonymous function nests only where its qualified name says (#1598)
Co-authored-by: axiomcode-bot[bot] <334110751+axiomcode-bot[bot]@users.noreply.github.com>
Merge dev (the 0.1.4 release) into 0.1.5
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Promotes
0.1.5todev: 23 fixes merged into0.1.5.varlocal is typed as an external class namedvar, so its calls get anexternal:var.<m>library edge #1401) (java: a var in an enhanced for, a try-with-resources resource and a lambda parameter takes its type (#1401) #1632)Work continues on the next patch branch, cut from
0.1.5.