Skip to content

Commit 024db0b

Browse files
committed
feat: enhance AngularAnalyzer with new IndexChunk interface and refactor signal input/output handling
- Introduced IndexChunk interface for better type definition of chunk properties. - Refactored signal input() and output() handling to improve clarity and type safety. - Simplified logic for determining required properties in signal-based inputs and outputs. - Updated type assertions to leverage the new IndexChunk interface for chunk processing.
1 parent 57e3130 commit 024db0b

File tree

2 files changed

+35
-12
lines changed

2 files changed

+35
-12
lines changed

AGENTS.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -128,6 +128,11 @@ If an agent has to call the tool twice to understand the response, the tool fail
128128
- `src/core/` is framework-agnostic. No hardcoded framework strings (Angular, React, Vue, etc.).
129129
- CLI code belongs in `src/cli.ts`. Never in `src/index.ts`.
130130
- Framework analyzers self-register their own patterns (e.g., Angular computed+effect pairing belongs in the Angular analyzer, not protocol layer).
131+
- **Types and interfaces must be framework-agnostic in core and shared utilities.**
132+
Framework-specific field names (Angular-only, React-only, etc.) belong exclusively in their
133+
respective analyzer files under `src/analyzers/`. Never add named framework-specific fields
134+
to interfaces in `src/types/`, `src/utils/`, or `src/core/`.
135+
Use `Record<string, T>` for open-ended data that frameworks extend at runtime.
131136

132137
### Release Checklist
133138

src/analyzers/angular/index.ts

Lines changed: 30 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,14 @@ interface AngularOutput {
3939
style: 'decorator' | 'signal';
4040
}
4141

42+
interface IndexChunk {
43+
filePath?: string;
44+
startLine?: number;
45+
endLine?: number;
46+
componentType?: string;
47+
layer?: string;
48+
}
49+
4250
export class AngularAnalyzer implements FrameworkAnalyzer {
4351
readonly name = 'angular';
4452
readonly version = '1.0.0';
@@ -600,18 +608,28 @@ export class AngularAnalyzer implements FrameworkAnalyzer {
600608
}
601609

602610
// Check for signal-based input() (Angular v17.1+)
603-
if (member.value && member.key && 'name' in member.key) {
604-
const callee = member.value.type === 'CallExpression'
605-
? (member.value.callee as { type: string; name?: string; object?: { name?: string }; property?: { name?: string } })
606-
: null;
607-
const valueStr = callee?.name ?? callee?.object?.name ?? null;
611+
if (member.value && member.key && 'name' in member.key && member.value.type === 'CallExpression') {
612+
const callee = member.value.callee;
613+
let valueStr: string | null = null;
614+
let isRequired = false;
615+
616+
if (callee.type === 'Identifier') {
617+
valueStr = callee.name;
618+
} else if (callee.type === 'MemberExpression') {
619+
if (callee.object.type === 'Identifier') {
620+
valueStr = callee.object.name;
621+
}
622+
if (callee.property.type === 'Identifier') {
623+
isRequired = callee.property.name === 'required';
624+
}
625+
}
608626

609627
if (valueStr === 'input') {
610628
inputs.push({
611629
name: member.key.name,
612630
type: 'InputSignal',
613631
style: 'signal',
614-
required: callee?.property?.name === 'required'
632+
required: isRequired
615633
});
616634
}
617635
}
@@ -650,11 +668,9 @@ export class AngularAnalyzer implements FrameworkAnalyzer {
650668
}
651669

652670
// Check for signal-based output() (Angular v17.1+)
653-
if (member.value && member.key && 'name' in member.key) {
654-
const callee = member.value.type === 'CallExpression'
655-
? (member.value.callee as { type: string; name?: string })
656-
: null;
657-
const valueStr = callee?.name ?? null;
671+
if (member.value && member.key && 'name' in member.key && member.value.type === 'CallExpression') {
672+
const callee = member.value.callee;
673+
const valueStr = callee.type === 'Identifier' ? callee.name : null;
658674

659675
if (valueStr === 'output') {
660676
outputs.push({
@@ -933,7 +949,9 @@ export class AngularAnalyzer implements FrameworkAnalyzer {
933949
}
934950

935951
const parsedObj = parsed as { chunks?: unknown };
936-
const chunks = parsedObj && Array.isArray(parsedObj.chunks) ? (parsedObj.chunks as Array<{ filePath?: string; startLine?: number; endLine?: number; componentType?: string; layer?: string }>) : null;
952+
const chunks = parsedObj && Array.isArray(parsedObj.chunks)
953+
? (parsedObj.chunks as IndexChunk[])
954+
: null;
937955
if (Array.isArray(chunks) && chunks.length > 0) {
938956
console.error(`Loading statistics from ${indexPath}: ${chunks.length} chunks`);
939957

0 commit comments

Comments
 (0)