MCPcopy Create free account
hub / github.com/colbymchenry/codegraph / delegateScriptTag

Method delegateScriptTag

src/extraction/cfml-extractor.ts:335–395  ·  view source on GitHub ↗

* Delegate a ` ... ` tag body to the cfscript grammar. * With `parentClassName` set (the block sits at component scope), functions * declared at the script's top level are the component's methods * (` function configure(){}` — the standard ColdBox

(scriptTag: SyntaxNode, parentId: string | undefined, parentClassName?: string)

Source from the content-addressed store, hash-verified

333 * (closures) keep kind `function`.
334 */
335 private delegateScriptTag(scriptTag: SyntaxNode, parentId: string | undefined, parentClassName?: string): void {
336 const content = scriptTag.namedChildren.find((c: SyntaxNode) => c.type === 'cf_script_content');
337 if (!content) return;
338
339 const inner = this.source.substring(content.startIndex, content.endIndex);
340 const startLine = content.startPosition.row;
341
342 const extractor = new TreeSitterExtractor(this.filePath, inner, 'cfscript');
343 const result = extractor.extract();
344
345 // The inner TreeSitterExtractor always synthesizes its own `file`-kind
346 // node scoped to just this snippet — drop it (and any edges touching it)
347 // since this tag-based file already owns one correctly-ranged file node
348 // (see createFileNode); the per-node `parentId` contains-edge below
349 // already links every emitted symbol into the real tree.
350 const innerFileNodeId = result.nodes.find((n) => n.kind === 'file')?.id;
351 // Snippet-top-level symbols are the ones the inner extractor attached
352 // directly to its (dropped) snippet file node — as opposed to closures
353 // nested inside another function.
354 const topLevelIds = new Set(
355 result.edges
356 .filter((e) => e.kind === 'contains' && e.source === innerFileNodeId)
357 .map((e) => e.target)
358 );
359 for (const node of result.nodes) {
360 if (node.kind === 'file') continue;
361 node.startLine += startLine;
362 node.endLine += startLine;
363 node.language = this.language;
364 if (parentClassName) {
365 if (node.kind === 'function' && topLevelIds.has(node.id)) {
366 node.kind = 'method';
367 }
368 node.qualifiedName = `${parentClassName}::${node.qualifiedName}`;
369 }
370 this.nodes.push(node);
371 if (parentId) {
372 this.edges.push({ source: parentId, target: node.id, kind: 'contains' });
373 }
374 }
375 for (const edge of result.edges) {
376 if (edge.source === innerFileNodeId || edge.target === innerFileNodeId) continue;
377 if (edge.line) edge.line += startLine;
378 this.edges.push(edge);
379 }
380 for (const ref of result.unresolvedReferences) {
381 ref.line += startLine;
382 ref.filePath = this.filePath;
383 ref.language = this.language;
384 // Calls inside a <cfscript> body with no enclosing function (rare — a
385 // top-level script in a .cfm template, or any statement directly in
386 // the snippet body) attribute to the filtered-out snippet file node by
387 // default — redirect those (and any genuinely unset ones) to parentId.
388 if ((!ref.fromNodeId || ref.fromNodeId === innerFileNodeId) && parentId) ref.fromNodeId = parentId;
389 this.unresolvedReferences.push(ref);
390 }
391 for (const error of result.errors) {
392 if (error.line) error.line += startLine;

Callers 3

walkProgramMethod · 0.95
extractComponentMethod · 0.95
delegateNestedTagsMethod · 0.95

Calls 2

extractMethod · 0.95
hasMethod · 0.80

Tested by

no test coverage detected