`new a.b.Batch()` made an instantiates edge, but
`createObject("component", "a.b.Batch")`, the form older CFML uses most,
was extracted as a call to the engine function createObject, which never
resolves. A call chained onto either construction, `createObject(...).init()`
or `new a.b.Batch().init()`, was extracted as a bare `init`, which the
name matcher bound to whichever component's init came first (0.4), or to
none when there are many.
Fix:
- cfscript extraction (tag expressions included): a component
createObject, with two arguments, one, or named ones, makes an
instantiates reference under the dotted path as written, not a call.
Java and other object types, and names built at runtime, are unchanged.
- A call on a construction is extracted as `<component>().<method>`.
- The resolver reads a dotted instantiates path with
resolveCfmlComponentPath, the rules extends uses, and resolves a chained
call to the method of that component or one it inherits (matched
ignoring case; inheritance is wired before calls). A bare component name
is the one in the calling file's folder, else the only one so named.
Without both, the call gets no edge rather than a guess by name.
- resolveCfmlComponentPath also accepts a component at the project root
for a path with one folder segment, its file named like it:
`wheels.JobWorker` in Wheels' own source, where `wheels` maps onto the
root. Without it Wheels' core lost calls like
`new wheels.JobWorker().processNext()` that name matching had found. It
ranks below any folder match; extends gains the same.
Validation:
- New cfml-create-object.test.ts (5 cases) and a root-component case in
cfml-inheritance-resolution.test.ts: 5 of the 6 fail on main (the sixth
pins the variable typing that already worked), all pass.
- A/B vs main d90f6abe on FW/1, BlogCFC, ColdBox, ContentBox, Preside,
CFWheels and its vendor/wheels core indexed as its own project:
1,022 edges removed: 563 resolved again to the same target by type,
444 moved from a method guessed by name to the constructed component's
own or inherited method, and 15 dropped, all name guesses for
components outside the index, without the method, or tied. 1,342 added:
641 instantiates, 38 calls, and in Wheels' core 653 extends and 10
implements to root components. Oracles over the fix graphs: of the 983
chained-construction call edges, 965 land in the file named like the
component and 18 on a method its supertypes declare (each checked); all
608 dotted instantiates and, in Wheels' core, all 786 dotted
extends/implements edges target a file named like the path's last
segment. One site is doubtful: Wheels' core public/docs/core.cfm names
the application's app.models.Model, which that subtree lacks; one
`models` folder corroborates a test asset's Model.cfc, as it would for
extends. express and flask controls byte-identical.
- Index time, median of 4 interleaved runs, CPU with workers, main vs
fix: Preside 58.7 / 54.5 s, Wheels core 32.2 / 33.0 s. Within noise.
Fixes#2652
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>