From 21a2c97fca271247b13f687f6afe64a13d5deecf Mon Sep 17 00:00:00 2001 From: Chad Smith Date: Wed, 18 Feb 2026 21:26:32 -0800 Subject: [PATCH 1/5] fix storeInterfaceMetadata to handle inline struct types --- src/codegen/expressions/access/member.ts | 24 ++++++++++++++++++++++++ 1 file changed, 24 insertions(+) diff --git a/src/codegen/expressions/access/member.ts b/src/codegen/expressions/access/member.ts index e7c1d675..1ffb59a6 100644 --- a/src/codegen/expressions/access/member.ts +++ b/src/codegen/expressions/access/member.ts @@ -940,6 +940,30 @@ export class MemberAccessGenerator { this.ctx.setJsonObjectMetadata(register, { keys, types, tsTypes, interfaceType: undefined }); } else if (tsType === 'Expression' || tsType === 'Statement') { this.ctx.setJsonObjectMetadata(register, { keys: ['type'], types: ['i8*'], tsTypes: ['string'], interfaceType: undefined }); + } else { + let strippedType = tsType; + if (strippedType.includes(' | ')) { + const parts = strippedType.split(' | '); + for (let i = 0; i < parts.length; i++) { + const p = parts[i].trim(); + if (p.startsWith('{')) { strippedType = p; break; } + } + } + if (strippedType.startsWith('{') && strippedType.endsWith('}')) { + const inlineFields = this.parseInlineObjectTypeForAssertion(strippedType); + if (inlineFields && inlineFields.length > 0) { + const keys: string[] = []; + const tsTypes: string[] = []; + const types: string[] = []; + for (let i = 0; i < inlineFields.length; i++) { + const f = inlineFields[i] as InterfaceField; + keys.push(f.name); + tsTypes.push(f.type); + types.push(this.convertTsType(f.type)); + } + this.ctx.setJsonObjectMetadata(register, { keys, types, tsTypes, interfaceType: undefined }); + } + } } } From 125532010bfc83252ee76936617f977312cbc728 Mon Sep 17 00:00:00 2001 From: Chad Smith Date: Wed, 18 Feb 2026 21:34:05 -0800 Subject: [PATCH 2/5] revert TryStatement flattening now that inline struct types work --- src/analysis/semantic-analyzer.ts | 8 ++++---- src/ast/types.ts | 3 +-- src/ast/visitor.ts | 4 ++-- src/codegen/infrastructure/closure-analyzer.ts | 9 ++++----- src/codegen/statements/control-flow.ts | 8 ++++---- src/parser-native/transformer.ts | 10 +++++----- src/parser-ts/handlers/statements.ts | 10 +++++----- 7 files changed, 25 insertions(+), 27 deletions(-) diff --git a/src/analysis/semantic-analyzer.ts b/src/analysis/semantic-analyzer.ts index ef9aafc3..574d77b4 100644 --- a/src/analysis/semantic-analyzer.ts +++ b/src/analysis/semantic-analyzer.ts @@ -381,14 +381,14 @@ export class SemanticAnalyzer { } else if (stmtType === 'try') { const tryStmt = stmt as TryStatement; if (tryStmt.tryBlock) this.analyzeBlock(tryStmt.tryBlock); - if (tryStmt.catchParam) { - this.symbols.set(tryStmt.catchParam, { - name: tryStmt.catchParam, + if (tryStmt.catchClause) { + this.symbols.set(tryStmt.catchClause.param, { + name: tryStmt.catchClause.param, type: 'string', llvmType: 'i8*', }); + this.analyzeBlock(tryStmt.catchClause.body); } - if (tryStmt.catchBody) this.analyzeBlock(tryStmt.catchBody); if (tryStmt.finallyBlock) this.analyzeBlock(tryStmt.finallyBlock); } else if (stmtType === 'return') { const retStmt = stmt as ReturnStatement; diff --git a/src/ast/types.ts b/src/ast/types.ts index 1fd5f9af..e9644bca 100644 --- a/src/ast/types.ts +++ b/src/ast/types.ts @@ -304,8 +304,7 @@ export interface ThrowStatement { export interface TryStatement { type: 'try'; tryBlock: BlockStatement; - catchParam: string | null; - catchBody: BlockStatement | null; + catchClause: { param: string; body: BlockStatement } | null; finallyBlock: BlockStatement | null; loc?: SourceLocation; } diff --git a/src/ast/visitor.ts b/src/ast/visitor.ts index fd3a7104..60643492 100644 --- a/src/ast/visitor.ts +++ b/src/ast/visitor.ts @@ -210,8 +210,8 @@ export class RecursiveASTVisitor { visitTryStatement(node: TryStatement): void { this.visitBlock(node.tryBlock); - if (node.catchBody) { - this.visitBlock(node.catchBody); + if (node.catchClause) { + this.visitBlock(node.catchClause.body); } if (node.finallyBlock) { this.visitBlock(node.finallyBlock); diff --git a/src/codegen/infrastructure/closure-analyzer.ts b/src/codegen/infrastructure/closure-analyzer.ts index f01724a0..3163e971 100644 --- a/src/codegen/infrastructure/closure-analyzer.ts +++ b/src/codegen/infrastructure/closure-analyzer.ts @@ -78,8 +78,7 @@ interface CatchHandler { interface TryNode { type: string; tryBlock: BlockStatement; - catchParam: string | null; - catchBody: BlockStatement | null; + catchClause: { param: string; body: BlockStatement } | null; finallyBlock: BlockStatement | null; } @@ -323,10 +322,10 @@ export class ClosureAnalyzer { this.walkExpression(s.iterable); this.walkBlock(s.body); } else if (stmtType === 'try') { - const tryStmt = stmt as { type: string; tryBlock: BlockStatement; catchParam: string | null; catchBody: BlockStatement | null; finallyBlock: BlockStatement | null }; + const tryStmt = stmt as { type: string; tryBlock: BlockStatement; catchClause: { param: string; body: BlockStatement } | null; finallyBlock: BlockStatement | null }; this.walkBlock(tryStmt.tryBlock); - if (tryStmt.catchBody !== null) { - this.walkBlock(tryStmt.catchBody); + if (tryStmt.catchClause !== null) { + this.walkBlock(tryStmt.catchClause.body); } if (tryStmt.finallyBlock !== null) { this.walkBlock(tryStmt.finallyBlock); diff --git a/src/codegen/statements/control-flow.ts b/src/codegen/statements/control-flow.ts index 0e70ae09..ff2eb040 100644 --- a/src/codegen/statements/control-flow.ts +++ b/src/codegen/statements/control-flow.ts @@ -1329,7 +1329,7 @@ export class ControlFlowGenerator { if (stmt.type !== 'try') { throw new Error('Expected try statement'); } - const tryStmt = stmt as { type: string; tryBlock: BlockStatement; catchParam: string | null; catchBody: BlockStatement | null; finallyBlock: BlockStatement | null }; + const tryStmt = stmt as { type: string; tryBlock: BlockStatement; catchClause: { param: string; body: BlockStatement } | null; finallyBlock: BlockStatement | null }; const frameRaw = this.nextTemp(); this.emit(`${frameRaw} = call i8* @GC_malloc(i64 216)`); @@ -1369,8 +1369,8 @@ export class ControlFlowGenerator { this.ctx.setCurrentLabel(catchEntryLabel); this.emit(`store i8* ${prevFrame}, i8** @__exception_stack`); - if (tryStmt.catchBody) { - const paramName = tryStmt.catchParam; + if (tryStmt.catchClause) { + const paramName = tryStmt.catchClause.param; if (paramName) { const excMsg = this.nextTemp(); this.emit(`${excMsg} = load i8*, i8** @__exception_message`); @@ -1379,7 +1379,7 @@ export class ControlFlowGenerator { this.emit(`store i8* ${excMsg}, i8** ${paramAlloca}`); this.ctx.defineVariable(paramName, paramAlloca, 'i8*', SymbolKind.String, 'local'); } - this.ctx.generateBlock(tryStmt.catchBody, params); + this.ctx.generateBlock(tryStmt.catchClause.body, params); } const catchHasTerminator = this.ctx.lastInstructionIsTerminator(); diff --git a/src/parser-native/transformer.ts b/src/parser-native/transformer.ts index 2cfc5450..1604289f 100644 --- a/src/parser-native/transformer.ts +++ b/src/parser-native/transformer.ts @@ -1624,14 +1624,14 @@ function transformTryStatement(node: TreeSitterNode): TryStatement { const tryBlock = bodyNode ? transformStatementBlock(bodyNode) : createEmptyBlock(); - let catchParam: string | null = null; - let catchBody: BlockStatement | null = null; + let catchClause: { param: string; body: BlockStatement } | null = null; if (handlerNode) { const paramNode = getChildByFieldName(handlerNode, 'parameter'); const catchBodyNode = getChildByFieldName(handlerNode, 'body'); - catchParam = paramNode ? (paramNode as NodeBase).text : 'e'; - catchBody = catchBodyNode ? transformStatementBlock(catchBodyNode) : createEmptyBlock(); + const param = paramNode ? (paramNode as NodeBase).text : 'e'; + const body = catchBodyNode ? transformStatementBlock(catchBodyNode) : createEmptyBlock(); + catchClause = { param, body }; } let finallyBlock: BlockStatement | null = null; @@ -1642,7 +1642,7 @@ function transformTryStatement(node: TreeSitterNode): TryStatement { } } - return { type: 'try', tryBlock, catchParam, catchBody, finallyBlock }; + return { type: 'try', tryBlock, catchClause, finallyBlock }; } function transformSwitchStatement(node: TreeSitterNode): BlockStatement { diff --git a/src/parser-ts/handlers/statements.ts b/src/parser-ts/handlers/statements.ts index e71cf60b..8ad38757 100644 --- a/src/parser-ts/handlers/statements.ts +++ b/src/parser-ts/handlers/statements.ts @@ -426,13 +426,13 @@ function transformThrowStatement(node: ts.ThrowStatement, checker: ts.TypeChecke function transformTryStatement(node: ts.TryStatement, checker: ts.TypeChecker | undefined): TryStatement { const tryBlock = transformBlock(node.tryBlock, checker); - let catchParam: string | null = null; - let catchBody: BlockStatement | null = null; + let catchClause: { param: string; body: BlockStatement } | null = null; if (node.catchClause) { - catchParam = node.catchClause.variableDeclaration && ts.isIdentifier(node.catchClause.variableDeclaration.name) + const param = node.catchClause.variableDeclaration && ts.isIdentifier(node.catchClause.variableDeclaration.name) ? node.catchClause.variableDeclaration.name.text : 'e'; - catchBody = transformBlock(node.catchClause.block, checker); + const body = transformBlock(node.catchClause.block, checker); + catchClause = { param, body }; } let finallyBlock: BlockStatement | null = null; @@ -440,7 +440,7 @@ function transformTryStatement(node: ts.TryStatement, checker: ts.TypeChecker | finallyBlock = transformBlock(node.finallyBlock, checker); } - return { type: 'try', tryBlock, catchParam, catchBody, finallyBlock, loc: getLoc(node) }; + return { type: 'try', tryBlock, catchClause, finallyBlock, loc: getLoc(node) }; } export function transformBlock(block: ts.Block, checker: ts.TypeChecker | undefined): BlockStatement { From 9b77c611d7e580dfa2d5f958c4095f452cf4736c Mon Sep 17 00:00:00 2001 From: Chad Smith Date: Wed, 18 Feb 2026 21:35:26 -0800 Subject: [PATCH 3/5] add code style guidelines to rules --- .claude/rules.md | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/.claude/rules.md b/.claude/rules.md index 76b8ef31..e98ad31b 100644 --- a/.claude/rules.md +++ b/.claude/rules.md @@ -130,6 +130,11 @@ available on `BaseGenerator`, `LLVMGenerator`, and `MockGeneratorContext` for ty 6. **`ret void` not `unreachable`** at end of void functions 7. **Class structs: boolean is `i1`; Interface structs: boolean is `double`** +## Code Style + +- One-line comments are helpful on dense codegen blocks — explain the "why" or the LLVM IR pattern, not the "what" +- Use named AST types from `src/ast/types.ts` for type assertions instead of inline `as { ... }` structs + ## Patterns That Crash Native Code 1. **`new` in class field initializers is silently dropped** — codegen only emits type-based defaults. Move `new` calls to constructors. When removing a `new X()` initializer, you MUST add a constructor init. From a23954be2a1b5712ccb7e80dcf5e5808b09e2daa Mon Sep 17 00:00:00 2001 From: Chad Smith Date: Wed, 18 Feb 2026 21:39:47 -0800 Subject: [PATCH 4/5] replace inline type assertions with InterfaceField named type --- src/codegen/expressions/access/member.ts | 26 +++++------ .../method-calls/class-dispatch.ts | 8 ++-- .../infrastructure/function-generator.ts | 8 ++-- src/codegen/infrastructure/type-inference.ts | 6 +-- .../type-resolver/type-resolver.ts | 24 +++++----- .../infrastructure/variable-allocator.ts | 44 +++++++++--------- src/codegen/llvm-generator.ts | 2 +- src/codegen/statements/control-flow.ts | 46 +++++++++---------- src/codegen/stdlib/json.ts | 10 ++-- src/codegen/stdlib/response.ts | 8 ++-- .../types/interface-struct-generator.ts | 6 +-- src/codegen/types/objects/class.ts | 10 ++-- src/codegen/types/objects/object.ts | 4 +- 13 files changed, 102 insertions(+), 100 deletions(-) diff --git a/src/codegen/expressions/access/member.ts b/src/codegen/expressions/access/member.ts index 1ffb59a6..840ea310 100644 --- a/src/codegen/expressions/access/member.ts +++ b/src/codegen/expressions/access/member.ts @@ -624,7 +624,7 @@ export class MemberAccessGenerator { const tsTypes: string[] = []; const nestedProps = nestedInterface.properties as InterfaceProperty[]; for (let pi = 0; pi < nestedProps.length; pi++) { - const p = nestedProps[pi] as { name: string; type: string }; + const p = nestedProps[pi] as InterfaceField; keys.push(stripOptional(p.name)); types.push(this.convertTsType(p.type)); tsTypes.push(p.type); @@ -931,7 +931,7 @@ export class MemberAccessGenerator { const types: string[] = []; if (interfaceDef.fields) { for (let i = 0; i < interfaceDef.fields.length; i++) { - const f = interfaceDef.fields[i] as { name: string; type: string }; + const f = interfaceDef.fields[i] as InterfaceField; keys.push(stripOptional(f.name)); tsTypes.push(f.type); types.push(this.convertTsType(f.type)); @@ -1043,7 +1043,7 @@ export class MemberAccessGenerator { const types: string[] = []; if (nestedInterfaceDef.fields) { for (let i = 0; i < nestedInterfaceDef.fields.length; i++) { - const f = nestedInterfaceDef.fields[i] as { name: string; type: string }; + const f = nestedInterfaceDef.fields[i] as InterfaceField; keys.push(stripOptional(f.name)); tsTypes.push(f.type); types.push(this.convertTsType(f.type)); @@ -1558,7 +1558,7 @@ export class MemberAccessGenerator { let propIndex = -1; let propTsType: string | undefined; for (let i = 0; i < interfaceDef.fields.length; i++) { - const f = interfaceDef.fields[i] as { name: string; type: string }; + const f = interfaceDef.fields[i] as InterfaceField; const fName = stripOptional(f.name); if (fName === expr.property) { propIndex = i; @@ -1900,7 +1900,7 @@ export class MemberAccessGenerator { const types: string[] = []; const tsTypes: string[] = []; for (let j = 0; j < fields.length; j++) { - const f = fields[j] as { name: string; type: string }; + const f = fields[j] as InterfaceField; keys.push(stripOptional(f.name)); tsTypes.push(f.type); if (f.type === 'string') { @@ -1931,7 +1931,7 @@ export class MemberAccessGenerator { const types: string[] = []; const tsTypes: string[] = []; for (let j = 0; j < fields.length; j++) { - const f = fields[j] as { name: string; type: string }; + const f = fields[j] as InterfaceField; keys.push(stripOptional(f.name)); tsTypes.push(f.type); if (f.type === 'string') { @@ -2203,7 +2203,7 @@ export class MemberAccessGenerator { let propIndex = -1; for (let i = 0; i < interfaceDef.fields.length; i++) { - const f = interfaceDef.fields[i] as { name: string; type: string }; + const f = interfaceDef.fields[i] as InterfaceField; if (f.name === expr.property) { propIndex = i; break; @@ -2212,17 +2212,17 @@ export class MemberAccessGenerator { if (propIndex === -1) { const fieldNames: string[] = []; for (let i = 0; i < interfaceDef.fields.length; i++) { - const field = interfaceDef.fields[i] as { name: string; type: string }; + const field = interfaceDef.fields[i] as InterfaceField; fieldNames.push(field.name); } throw new Error(`Unknown property: ${expr.property} on interface ${valueType}. Available properties: ${fieldNames.join(', ')}`); } - const propField = interfaceDef.fields[propIndex] as { name: string; type: string }; + const propField = interfaceDef.fields[propIndex] as InterfaceField; const propType = this.convertTsType(propField.type); const structTypes: string[] = []; for (let i = 0; i < interfaceDef.fields.length; i++) { - const field = interfaceDef.fields[i] as { name: string; type: string }; + const field = interfaceDef.fields[i] as InterfaceField; structTypes.push(this.convertTsType(field.type)); } const structType = `{ ${structTypes.join(', ')} }`; @@ -3025,7 +3025,7 @@ export class MemberAccessGenerator { let fieldIndex = -1; for (let i = 0; i < fields.length; i++) { - const f = fields[i] as { name: string; type: string }; + const f = fields[i] as InterfaceField; if (f.name === property) { fieldIndex = i; break; @@ -3033,12 +3033,12 @@ export class MemberAccessGenerator { } if (fieldIndex === -1) return null; - const field = fields[fieldIndex] as { name: string; type: string }; + const field = fields[fieldIndex] as InterfaceField; const fieldLlvmType = this.convertTsType(field.type); const types: string[] = []; for (let i = 0; i < fields.length; i++) { - const f = fields[i] as { name: string; type: string }; + const f = fields[i] as InterfaceField; types.push(this.convertTsType(f.type)); } const structType = `{ ${types.join(', ')} }`; diff --git a/src/codegen/expressions/method-calls/class-dispatch.ts b/src/codegen/expressions/method-calls/class-dispatch.ts index 8530104b..3b458d32 100644 --- a/src/codegen/expressions/method-calls/class-dispatch.ts +++ b/src/codegen/expressions/method-calls/class-dispatch.ts @@ -28,7 +28,7 @@ export function getInterfaceFromAST(ctx: MethodCallGeneratorContext, name: strin if (!ifaceItem) continue; const properties: { name: string; type: string }[] = []; for (let j = 0; j < ifaceItem.fields.length; j++) { - const field = ifaceItem.fields[j] as { name: string; type: string }; + const field = ifaceItem.fields[j] as InterfaceField; properties.push({ name: field.name, type: field.type }); } return { properties }; @@ -311,13 +311,13 @@ export function resolveNestedMemberAccessType(ctx: MethodCallGeneratorContext, e if (interfaceDeclResult) { let fieldResult: InterfaceField | null = null; for (let i = 0; i < interfaceDecl.fields.length; i++) { - const f = interfaceDecl.fields[i] as { name: string; type: string }; + const f = interfaceDecl.fields[i] as InterfaceField; if (f.name === memberAccess.property) { fieldResult = f; break; } } - const field = fieldResult as { name: string; type: string }; + const field = fieldResult as InterfaceField; if (fieldResult) { let fieldType = field.type; if (fieldType.endsWith(' | null') || fieldType.endsWith(' | undefined')) { @@ -517,7 +517,7 @@ export function handleClassMethods(ctx: MethodCallGeneratorContext, expr: Method if (interfaceDeclResult) { const interfaceDecl = interfaceDeclResult as InterfaceDeclaration; for (let i = 0; i < interfaceDecl.fields.length; i++) { - const f = interfaceDecl.fields[i] as { name: string; type: string }; + const f = interfaceDecl.fields[i] as InterfaceField; if (f.name === memberAccess.property) { let fieldType = f.type; if (fieldType.endsWith(' | null') || fieldType.endsWith(' | undefined')) { diff --git a/src/codegen/infrastructure/function-generator.ts b/src/codegen/infrastructure/function-generator.ts index ca1f40b0..4125aa2b 100644 --- a/src/codegen/infrastructure/function-generator.ts +++ b/src/codegen/infrastructure/function-generator.ts @@ -1,4 +1,4 @@ -import { FunctionNode, BlockStatement, Expression, FunctionParameter, AST, VariableDeclaration, IfStatement, WhileStatement, ForStatement, ForOfStatement, AssignmentStatement, CommonField, SwitchStatement, SourceLocation, Statement } from '../../ast/types.js'; +import { FunctionNode, BlockStatement, Expression, FunctionParameter, AST, VariableDeclaration, IfStatement, WhileStatement, ForStatement, ForOfStatement, AssignmentStatement, CommonField, SwitchStatement, SourceLocation, Statement, InterfaceField } from '../../ast/types.js'; import { SymbolKind, SymbolTable, createPointerAllocaMetadata, createInterfacePointerAllocaMetadata, createClassMetadata, createObjectMetadataWithInterface, createInterfaceMetadata, createMapMetadataSymbol, SymbolMetadata } from './symbol-table.js'; import type { ClosureInfo } from './closure-analyzer.js'; import type { TypeChecker } from '../../typescript/type-checker.js'; @@ -267,7 +267,7 @@ export class FunctionGenerator { const keys: string[] = []; const types: string[] = []; for (let j = 0; j < interfaceDefFields.length; j++) { - const field = interfaceDefFields[j] as { name: string; type: string }; + const field = interfaceDefFields[j] as InterfaceField; if (!field || !field.name) continue; const fieldName = stripOptional(field.name); keys.push(fieldName); @@ -626,7 +626,7 @@ export class FunctionGenerator { const commonFields: CommonField[] = []; for (let fi = 0; fi < firstFields.length; fi++) { - const field = firstFields[fi] as { name: string; type: string }; + const field = firstFields[fi] as InterfaceField; if (!field || !field.name) continue; let isCommon = true; for (let ii = 0; ii < interfaces.length; ii++) { @@ -637,7 +637,7 @@ export class FunctionGenerator { } let found = false; for (let fj = 0; fj < ifaceTyped.fields.length; fj++) { - const f = ifaceTyped.fields[fj] as { name: string; type: string }; + const f = ifaceTyped.fields[fj] as InterfaceField; if (!f || !f.name) continue; if (f.name === field.name && this.areTypesCompatible(f.type, field.type)) { found = true; diff --git a/src/codegen/infrastructure/type-inference.ts b/src/codegen/infrastructure/type-inference.ts index 67f32063..5a88c925 100644 --- a/src/codegen/infrastructure/type-inference.ts +++ b/src/codegen/infrastructure/type-inference.ts @@ -577,7 +577,7 @@ export class TypeInference { const iface = this.getInterface(interfaceName); if (!iface) return null; for (let i = 0; i < iface.fields.length; i++) { - const f = iface.fields[i] as { name: string; type: string }; + const f = iface.fields[i] as InterfaceField; let fieldName = f.name; if (fieldName.endsWith('?')) { fieldName = fieldName.slice(0, -1); @@ -746,7 +746,7 @@ export class TypeInference { if (iface) { const field = this.getInterfaceProperty(typeName, fieldName); if (field) { - const fieldTyped = field as { name: string; type: string }; + const fieldTyped = field as InterfaceField; return fieldTyped.type; } } @@ -764,7 +764,7 @@ export class TypeInference { if (inner.length === 0) return null; const fields = this.parseInlineObjectFields(inner); for (let i = 0; i < fields.length; i++) { - const field = fields[i] as { name: string; type: string }; + const field = fields[i] as InterfaceField; const cleanName = field.name.replace(/\?$/, ''); if (cleanName === fieldName) { return field.type; diff --git a/src/codegen/infrastructure/type-resolver/type-resolver.ts b/src/codegen/infrastructure/type-resolver/type-resolver.ts index 5ebbd28c..93fddce0 100644 --- a/src/codegen/infrastructure/type-resolver/type-resolver.ts +++ b/src/codegen/infrastructure/type-resolver/type-resolver.ts @@ -349,7 +349,7 @@ export class TypeResolver { const types: string[] = []; const tsTypes: string[] = []; for (let i = 0; i < iface.fields.length; i++) { - const f = iface.fields[i] as { name: string; type: string }; + const f = iface.fields[i] as InterfaceField; keys.push(stripOptional(f.name)); types.push(this.convertTsType(f.type)); tsTypes.push(f.type); @@ -364,7 +364,7 @@ export class TypeResolver { const iface = this.getInterface(interfaceName); if (!iface) return null; for (let i = 0; i < iface.fields.length; i++) { - const f = iface.fields[i] as { name: string; type: string }; + const f = iface.fields[i] as InterfaceField; if (!f || !f.name) { continue; } @@ -380,7 +380,7 @@ export class TypeResolver { if (!iface) return null; const properties: { name: string; type: string }[] = []; for (let i = 0; i < iface.fields.length; i++) { - const f = iface.fields[i] as { name: string; type: string }; + const f = iface.fields[i] as InterfaceField; properties.push({ name: f.name, type: f.type }); } return { properties }; @@ -520,13 +520,13 @@ export class TypeResolver { const commonFields: CommonField[] = []; for (let fi = 0; fi < firstFields.length; fi++) { - const field = firstFields[fi] as { name: string; type: string }; + const field = firstFields[fi] as InterfaceField; let isCommon = true; for (let ii = 0; ii < interfaces.length; ii++) { const iface = interfaces[ii] as InterfaceDeclaration; let hasMatch = false; for (let jj = 0; jj < iface.fields.length; jj++) { - const f = iface.fields[jj] as { name: string; type: string }; + const f = iface.fields[jj] as InterfaceField; if (f.name === field.name && this.areTypesCompatible(f.type, field.type)) { hasMatch = true; break; @@ -768,7 +768,7 @@ export class TypeResolver { field: string ): string | null { for (let i = 0; i < fields.length; i++) { - const f = fields[i] as { name: string; type: string }; + const f = fields[i] as InterfaceField; if (f.name === field) { if (f.type === `'${value}'` || f.type === `"${value}"`) { return ifaceName; @@ -843,14 +843,14 @@ export class TypeResolver { const iface = ifaceDecl as InterfaceDeclaration; let field: { name: string; type: string } | null = null; for (let i = 0; i < iface.fields.length; i++) { - const f = iface.fields[i] as { name: string; type: string }; + const f = iface.fields[i] as InterfaceField; if (f.name === memberExpr.property) { field = f; break; } } if (field) { - const fieldTyped = field as { name: string; type: string }; + const fieldTyped = field as InterfaceField; const mapParsed = parseMapTypeString(fieldTyped.type); if (mapParsed) { return { fieldName: memberExpr.property, keyType: mapParsed.keyType, valueType: mapParsed.valueType }; @@ -900,14 +900,14 @@ export class TypeResolver { const iface = ifaceDecl as InterfaceDeclaration; let field: { name: string; type: string } | null = null; for (let i = 0; i < iface.fields.length; i++) { - const f = iface.fields[i] as { name: string; type: string }; + const f = iface.fields[i] as InterfaceField; if (f.name === memberExpr.property) { field = f; break; } } if (field) { - const fieldTyped = field as { name: string; type: string }; + const fieldTyped = field as InterfaceField; let fieldType = fieldTyped.type; if (fieldType.endsWith(' | null') || fieldType.endsWith(' | undefined')) { fieldType = fieldType.replace(/ \| null$/, '').replace(/ \| undefined$/, ''); @@ -996,14 +996,14 @@ export class TypeResolver { const iface = ifaceDecl as InterfaceDeclaration; let field: { name: string; type: string } | null = null; for (let i = 0; i < iface.fields.length; i++) { - const f = iface.fields[i] as { name: string; type: string }; + const f = iface.fields[i] as InterfaceField; if (f.name === memberExpr.property) { field = f; break; } } if (field) { - const fieldTyped = field as { name: string; type: string }; + const fieldTyped = field as InterfaceField; const mapParsed = parseMapTypeString(fieldTyped.type); if (mapParsed) { return mapParsed.keyType; diff --git a/src/codegen/infrastructure/variable-allocator.ts b/src/codegen/infrastructure/variable-allocator.ts index cdfaf217..4f3a80bb 100644 --- a/src/codegen/infrastructure/variable-allocator.ts +++ b/src/codegen/infrastructure/variable-allocator.ts @@ -315,7 +315,7 @@ export class VariableAllocator { for (let fi = 0; fi < inlineFields.length; fi++) { const fieldRaw = inlineFields[fi]; if (!fieldRaw) continue; - const field = fieldRaw as { name: string; type: string }; + const field = fieldRaw as InterfaceField; if (!field.name || !field.type) continue; keys.push(stripOptional(field.name)); types.push(this.convertTsType(field.type)); @@ -337,7 +337,7 @@ export class VariableAllocator { for (let fi = 0; fi < interfaceDef.fields.length; fi++) { const fieldRaw = interfaceDef.fields[fi]; if (!fieldRaw) continue; - const field = fieldRaw as { name: string; type: string }; + const field = fieldRaw as InterfaceField; if (!field.name || !field.type) continue; keys.push(stripOptional(field.name)); types.push(this.convertTsType(field.type)); @@ -543,7 +543,7 @@ export class VariableAllocator { const inlineFields = this.parseInlineObjectType(interfaceName); if (inlineFields) { for (let i = 0; i < inlineFields.length; i++) { - const field = inlineFields[i] as { name: string; type: string }; + const field = inlineFields[i] as InterfaceField; keys.push(stripOptional(field.name)); types.push(this.convertTsType(field.type)); tsTypes.push(field.type); @@ -553,7 +553,7 @@ export class VariableAllocator { const interfaceDefResult = this.getInterface(interfaceName); const interfaceDef = interfaceDefResult as InterfaceDeclaration; for (let i = 0; i < interfaceDef.fields.length; i++) { - const field = interfaceDef.fields[i] as { name: string; type: string }; + const field = interfaceDef.fields[i] as InterfaceField; keys.push(stripOptional(field.name)); types.push(this.convertTsType(field.type)); tsTypes.push(field.type); @@ -576,7 +576,7 @@ export class VariableAllocator { const inlineFields = this.parseInlineObjectType(interfaceName); if (inlineFields) { for (let i = 0; i < inlineFields.length; i++) { - const field = inlineFields[i] as { name: string; type: string }; + const field = inlineFields[i] as InterfaceField; keys.push(stripOptional(field.name)); types.push(this.convertTsType(field.type)); tsTypes.push(field.type); @@ -586,7 +586,7 @@ export class VariableAllocator { const interfaceDefResult = this.getInterface(interfaceName); const interfaceDef = interfaceDefResult as InterfaceDeclaration; for (let i = 0; i < interfaceDef.fields.length; i++) { - const field = interfaceDef.fields[i] as { name: string; type: string }; + const field = interfaceDef.fields[i] as InterfaceField; keys.push(stripOptional(field.name)); types.push(this.convertTsType(field.type)); tsTypes.push(field.type); @@ -609,7 +609,7 @@ export class VariableAllocator { const inlineFields = this.parseInlineObjectType(elementType); if (inlineFields) { for (let i = 0; i < inlineFields.length; i++) { - const field = inlineFields[i] as { name: string; type: string }; + const field = inlineFields[i] as InterfaceField; elementKeys.push(stripOptional(field.name)); elementTypes.push(this.convertTsType(field.type)); elementTsTypes.push(field.type); @@ -620,7 +620,7 @@ export class VariableAllocator { if (interfaceDefResult) { const interfaceDef = interfaceDefResult as InterfaceDeclaration; for (let i = 0; i < interfaceDef.fields.length; i++) { - const field = interfaceDef.fields[i] as { name: string; type: string }; + const field = interfaceDef.fields[i] as InterfaceField; elementKeys.push(stripOptional(field.name)); elementTypes.push(this.convertTsType(field.type)); elementTsTypes.push(field.type); @@ -720,7 +720,7 @@ export class VariableAllocator { const inlineFields = this.parseInlineObjectType(interfaceName); if (inlineFields) { for (let i = 0; i < inlineFields.length; i++) { - const field = inlineFields[i] as { name: string; type: string }; + const field = inlineFields[i] as InterfaceField; keys.push(stripOptional(field.name)); types.push(this.convertTsType(field.type)); tsTypes.push(field.type); @@ -731,7 +731,7 @@ export class VariableAllocator { const interfaceDef = interfaceDefResult as InterfaceDeclaration; const allFields = this.getAllInterfaceFields(interfaceDef); for (let i = 0; i < allFields.length; i++) { - const field = allFields[i] as { name: string; type: string }; + const field = allFields[i] as InterfaceField; keys.push(stripOptional(field.name)); types.push(this.convertTsType(field.type)); tsTypes.push(field.type); @@ -810,7 +810,7 @@ export class VariableAllocator { const types: string[] = []; const tsTypes: string[] = []; for (let i = 0; i < interfaceDef.fields.length; i++) { - const field = interfaceDef.fields[i] as { name: string; type: string }; + const field = interfaceDef.fields[i] as InterfaceField; keys.push(stripOptional(field.name)); types.push(this.convertTsType(field.type)); tsTypes.push(field.type); @@ -878,7 +878,7 @@ export class VariableAllocator { const objIface = objectInterface as InterfaceDeclaration; if (!objIface.fields) return null; for (let i = 0; i < objIface.fields.length; i++) { - const field = objIface.fields[i] as { name: string; type: string }; + const field = objIface.fields[i] as InterfaceField; if (!field || !field.name) continue; const fieldName = stripOptional(field.name); if (fieldName === memberExpr.property) { @@ -901,7 +901,7 @@ export class VariableAllocator { const types: string[] = []; const tsTypes: string[] = []; for (let i = 0; i < interfaceDef.fields.length; i++) { - const field = interfaceDef.fields[i] as { name: string; type: string }; + const field = interfaceDef.fields[i] as InterfaceField; keys.push(stripOptional(field.name)); types.push(this.convertTsType(field.type)); tsTypes.push(field.type); @@ -1079,7 +1079,7 @@ export class VariableAllocator { const tsTypes: string[] = []; const types: string[] = []; for (let i = 0; i < interfaceDef.fields.length; i++) { - const field = interfaceDef.fields[i] as { name: string; type: string }; + const field = interfaceDef.fields[i] as InterfaceField; keys.push(stripOptional(field.name)); tsTypes.push(field.type); types.push(this.convertTsTypeJson(field.type)); @@ -1109,7 +1109,7 @@ export class VariableAllocator { types = []; tsTypes = []; for (let i = 0; i < interfaceDef.fields.length; i++) { - const field = interfaceDef.fields[i] as { name: string; type: string }; + const field = interfaceDef.fields[i] as InterfaceField; keys.push(stripOptional(field.name)); types.push(this.convertTsType(field.type)); tsTypes.push(field.type); @@ -1480,7 +1480,7 @@ export class VariableAllocator { const types: string[] = []; const tsTypes: string[] = []; for (let fi = 0; fi < inlineFields.length; fi++) { - const field = inlineFields[fi] as { name: string; type: string }; + const field = inlineFields[fi] as InterfaceField; keys.push(stripOptional(field.name)); types.push(this.convertTsType(field.type)); tsTypes.push(field.type); @@ -1498,7 +1498,7 @@ export class VariableAllocator { const types: string[] = []; const tsTypes: string[] = []; for (let fi = 0; fi < interfaceDef.fields.length; fi++) { - const field = interfaceDef.fields[fi] as { name: string; type: string }; + const field = interfaceDef.fields[fi] as InterfaceField; keys.push(stripOptional(field.name)); types.push(this.convertTsType(field.type)); tsTypes.push(field.type); @@ -1789,7 +1789,7 @@ export class VariableAllocator { if (!ifaceResult) return null; const iface = ifaceResult as InterfaceDeclaration; for (let i = 0; i < iface.fields.length; i++) { - const f = iface.fields[i] as { name: string; type: string }; + const f = iface.fields[i] as InterfaceField; if (f.name === fieldName) { return f.type; } @@ -1811,7 +1811,7 @@ export class VariableAllocator { const types: string[] = []; const tsTypes: string[] = []; for (let i = 0; i < inlineFields.length; i++) { - const field = inlineFields[i] as { name: string; type: string }; + const field = inlineFields[i] as InterfaceField; keys.push(stripOptional(field.name)); types.push(this.convertTsType(field.type)); tsTypes.push(field.type); @@ -1827,7 +1827,7 @@ export class VariableAllocator { const types: string[] = []; const tsTypes: string[] = []; for (let i = 0; i < interfaceDef.fields.length; i++) { - const field = interfaceDef.fields[i] as { name: string; type: string }; + const field = interfaceDef.fields[i] as InterfaceField; keys.push(stripOptional(field.name)); types.push(this.convertTsType(field.type)); tsTypes.push(field.type); @@ -1873,13 +1873,13 @@ export class VariableAllocator { const commonFields: CommonField[] = []; for (let fi = 0; fi < firstFields.length; fi++) { - const field = firstFields[fi] as { name: string; type: string }; + const field = firstFields[fi] as InterfaceField; let isCommon = true; for (let ii = 0; ii < interfaces.length; ii++) { const ifaceTyped = interfaces[ii] as { fields: { name: string; type: string }[] }; let found = false; for (let fj = 0; fj < ifaceTyped.fields.length; fj++) { - const f = ifaceTyped.fields[fj] as { name: string; type: string }; + const f = ifaceTyped.fields[fj] as InterfaceField; if (f.name === field.name && this.areTypesCompatible(f.type, field.type)) { found = true; break; diff --git a/src/codegen/llvm-generator.ts b/src/codegen/llvm-generator.ts index f07df57d..b0e0ff9d 100644 --- a/src/codegen/llvm-generator.ts +++ b/src/codegen/llvm-generator.ts @@ -1516,7 +1516,7 @@ export class LLVMGenerator extends BaseGenerator implements IGeneratorContext { const tsTypes: string[] = []; const types: string[] = []; for (let i = 0; i < interfaceDef.fields.length; i++) { - const field = interfaceDef.fields[i] as { name: string; type: string }; + const field = interfaceDef.fields[i] as InterfaceField; keys.push(stripOptional(field.name)); tsTypes.push(field.type); types.push(this.tsTypeToLlvmJsonWithEnums(field.type)); diff --git a/src/codegen/statements/control-flow.ts b/src/codegen/statements/control-flow.ts index ff2eb040..895bb00b 100644 --- a/src/codegen/statements/control-flow.ts +++ b/src/codegen/statements/control-flow.ts @@ -490,7 +490,7 @@ export class ControlFlowGenerator { for (let i = 0; i < fields.length; i++) { const fRaw = fields[i]; if (!fRaw) continue; - const f = fRaw as { name: string; type: string }; + const f = fRaw as InterfaceField; if (!f.name || !f.type) continue; elementKeys.push(f.name); elementTsTypes.push(f.type); @@ -521,7 +521,7 @@ export class ControlFlowGenerator { for (let i = 0; i < ifaceTyped.fields.length; i++) { const fRaw = ifaceTyped.fields[i]; if (!fRaw) continue; - const f = fRaw as { name: string; type: string }; + const f = fRaw as InterfaceField; if (!f.name || !f.type) continue; elementKeys.push(f.name); elementTsTypes.push(f.type); @@ -583,7 +583,7 @@ export class ControlFlowGenerator { for (let i = 0; i < ifaceTyped.fields.length; i++) { const fRaw = ifaceTyped.fields[i]; if (!fRaw) continue; - const f = fRaw as { name: string; type: string }; + const f = fRaw as InterfaceField; if (!f.name) continue; if (f.name === fieldName) { return f.type; @@ -636,7 +636,7 @@ export class ControlFlowGenerator { for (let i = 0; i < fields.length; i++) { const fRaw = fields[i]; if (!fRaw) continue; - const f = fRaw as { name: string; type: string }; + const f = fRaw as InterfaceField; if (!f.name || !f.type) continue; elementKeys.push(f.name); elementTsTypes.push(f.type); @@ -670,7 +670,7 @@ export class ControlFlowGenerator { const elementTypes: string[] = []; const elementTsTypes: string[] = []; for (let i = 0; i < fields.length; i++) { - const f = fields[i] as { name: string; type: string }; + const f = fields[i] as InterfaceField; elementKeys.push(f.name); elementTsTypes.push(f.type); if (f.type === 'string') { @@ -700,7 +700,7 @@ export class ControlFlowGenerator { for (let i = 0; i < elemIfaceTyped.fields.length; i++) { const fRaw = elemIfaceTyped.fields[i]; if (!fRaw) continue; - const f = fRaw as { name: string; type: string }; + const f = fRaw as InterfaceField; if (!f.name || !f.type) continue; elementKeys.push(f.name); elementTsTypes.push(f.type); @@ -785,7 +785,7 @@ export class ControlFlowGenerator { for (let i = 0; i < ifaceTyped.fields.length; i++) { const fRaw = ifaceTyped.fields[i]; if (!fRaw) continue; - const f = fRaw as { name: string; type: string }; + const f = fRaw as InterfaceField; if (!f.name) continue; const fieldName = f.name.replace('?', ''); if (fieldName === ma.property) { @@ -817,15 +817,15 @@ export class ControlFlowGenerator { for (let i = 0; i < ifaceTyped.fields.length; i++) { const fRaw = ifaceTyped.fields[i]; if (!fRaw) continue; - const f = fRaw as { name: string; type: string }; + const f = fRaw as InterfaceField; if (!f.name) continue; const fieldName = f.name.replace('?', ''); if (fieldName === propName) { - fieldDefResult = f as { name: string; type: string }; + fieldDefResult = f as InterfaceField; break; } } - const fieldDef = fieldDefResult as { name: string; type: string }; + const fieldDef = fieldDefResult as InterfaceField; if (!fieldDefResult || !fieldDef.type.endsWith('[]')) { return null; } @@ -841,7 +841,7 @@ export class ControlFlowGenerator { for (let i = 0; i < fields.length; i++) { const fRaw = fields[i]; if (!fRaw) continue; - const f = fRaw as { name: string; type: string }; + const f = fRaw as InterfaceField; if (!f.name || !f.type) continue; elementKeys.push(f.name); elementTsTypes.push(f.type); @@ -883,7 +883,7 @@ export class ControlFlowGenerator { const elementTypes: string[] = []; const elementTsTypes: string[] = []; for (let i = 0; i < elementIfaceTyped.fields.length; i++) { - const f = elementIfaceTyped.fields[i] as { name: string; type: string }; + const f = elementIfaceTyped.fields[i] as InterfaceField; elementKeys.push(f.name); elementTsTypes.push(f.type); if (f.type === 'string') { @@ -929,7 +929,7 @@ export class ControlFlowGenerator { for (let i = 0; i < fields.length; i++) { const fRaw = fields[i]; if (!fRaw) continue; - const f = fRaw as { name: string; type: string }; + const f = fRaw as InterfaceField; if (!f.name || !f.type) continue; elementKeys.push(f.name); elementTsTypes.push(f.type); @@ -964,7 +964,7 @@ export class ControlFlowGenerator { const elementTypes: string[] = []; const elementTsTypes: string[] = []; for (let i = 0; i < elementIfaceTyped.fields.length; i++) { - const f = elementIfaceTyped.fields[i] as { name: string; type: string }; + const f = elementIfaceTyped.fields[i] as InterfaceField; elementKeys.push(f.name); elementTsTypes.push(f.type); if (f.type === 'string') { @@ -1055,13 +1055,13 @@ export class ControlFlowGenerator { const firstFields = new Map(); const firstInterface = memberInterfaces[0] as { name: string; extends: string[]; fields: { name: string; type: string }[] }; for (let i = 0; i < firstInterface.fields.length; i++) { - const f = firstInterface.fields[i] as { name: string; type: string }; + const f = firstInterface.fields[i] as InterfaceField; firstFields.set(f.name, f.type); } const commonFields: CommonField[] = []; for (let _ffi = 0; _ffi < firstInterface.fields.length; _ffi++) { - const firstField = firstInterface.fields[_ffi] as { name: string; type: string }; + const firstField = firstInterface.fields[_ffi] as InterfaceField; const fieldName = firstField.name; const fieldType = firstField.type; let isCommon = true; @@ -1070,13 +1070,13 @@ export class ControlFlowGenerator { const otherIface = memberInterfaces[i] as { name: string; extends: string[]; fields: { name: string; type: string }[] }; let otherFieldResult: InterfaceField | null = null; for (let j = 0; j < otherIface.fields.length; j++) { - const f = otherIface.fields[j] as { name: string; type: string }; + const f = otherIface.fields[j] as InterfaceField; if (f.name === fieldName) { otherFieldResult = f; break; } } - const otherField = otherFieldResult as { name: string; type: string }; + const otherField = otherFieldResult as InterfaceField; if (!otherFieldResult) { isCommon = false; break; @@ -1518,13 +1518,13 @@ export class ControlFlowGenerator { const commonFields: CommonField[] = []; for (let fi = 0; fi < firstFields.length; fi++) { - const field = firstFields[fi] as { name: string; type: string }; + const field = firstFields[fi] as InterfaceField; let isCommon = true; for (let ii = 0; ii < interfaces.length; ii++) { const ifaceTyped = interfaces[ii] as { fields: { name: string; type: string }[] }; let found = false; for (let fj = 0; fj < ifaceTyped.fields.length; fj++) { - const f = ifaceTyped.fields[fj] as { name: string; type: string }; + const f = ifaceTyped.fields[fj] as InterfaceField; if (f.name === field.name && this.areTypesCompatible(f.type, field.type)) { found = true; break; @@ -1651,7 +1651,7 @@ export class ControlFlowGenerator { const currentKeys: string[] = objMeta.keys as string[]; const ifaceKeys: string[] = []; for (let fi = 0; fi < iface.fields.length; fi++) { - const f = iface.fields[fi] as { name: string; type: string }; + const f = iface.fields[fi] as InterfaceField; ifaceKeys.push(f.name); } let isCompatible = true; @@ -1667,7 +1667,7 @@ export class ControlFlowGenerator { const types: string[] = []; const tsTypes: string[] = []; for (let i = 0; i < iface.fields.length; i++) { - const f = iface.fields[i] as { name: string; type: string }; + const f = iface.fields[i] as InterfaceField; keys.push(stripOptional(f.name)); types.push(this.fieldTypeToLlvm(f.type)); tsTypes.push(f.type); @@ -1689,7 +1689,7 @@ export class ControlFlowGenerator { private checkDiscriminant(ifaceName: string, fields: { name: string; type: string }[], discriminantValue: string): string | null { for (let i = 0; i < fields.length; i++) { - const f = fields[i] as { name: string; type: string }; + const f = fields[i] as InterfaceField; if (f.name === 'type') { const fieldType = f.type; if (fieldType === `'${discriminantValue}'` || fieldType === `"${discriminantValue}"`) { diff --git a/src/codegen/stdlib/json.ts b/src/codegen/stdlib/json.ts index 40e1a5aa..d84476dd 100644 --- a/src/codegen/stdlib/json.ts +++ b/src/codegen/stdlib/json.ts @@ -1,4 +1,4 @@ -import { Expression, MethodCallNode } from '../../ast/types.js'; +import { Expression, MethodCallNode, InterfaceField } from '../../ast/types.js'; interface ExprBase { type: string; } @@ -207,7 +207,7 @@ export class JsonGenerator { const fieldTypes: string[] = []; for (let fi = 0; fi < interfaceDef.fields.length; fi++) { - const fieldItem = interfaceDef.fields[fi] as { name: string; type: string }; + const fieldItem = interfaceDef.fields[fi] as InterfaceField; const fieldType = fieldItem.type; if (fieldType === 'string') { fieldTypes.push('i8*'); @@ -243,7 +243,7 @@ export class JsonGenerator { this.generatedStructs.add(parserKey); for (let fi = 0; fi < interfaceDef.fields.length; fi++) { - const fieldItem = interfaceDef.fields[fi] as { name: string; type: string }; + const fieldItem = interfaceDef.fields[fi] as InterfaceField; const fieldType = fieldItem.type; if (fieldType !== 'string' && fieldType !== 'number' && fieldType !== 'boolean') { const nestedDef = this.getInterfaceFields(fieldType); @@ -261,7 +261,7 @@ export class JsonGenerator { parserIR += ` %struct_ptr = bitcast i8* %struct_bytes to %${typeName}*\n`; for (let fieldIndex = 0; fieldIndex < interfaceDef.fields.length; fieldIndex++) { - const fieldEntry = interfaceDef.fields[fieldIndex] as { name: string; type: string }; + const fieldEntry = interfaceDef.fields[fieldIndex] as InterfaceField; if (fieldEntry.type === 'string') { parserIR += ` %init_ptr_${fieldIndex} = getelementptr inbounds %${typeName}, %${typeName}* %struct_ptr, i32 0, i32 ${fieldIndex}\n`; parserIR += ` store i8* getelementptr inbounds ([1 x i8], [1 x i8]* @.empty_str, i64 0, i64 0), i8** %init_ptr_${fieldIndex}\n`; @@ -285,7 +285,7 @@ export class JsonGenerator { parserIR += ` br label %field_0\n\n`; for (let fieldIndex = 0; fieldIndex < fieldCount; fieldIndex++) { - const fieldEntry = interfaceDef.fields[fieldIndex] as { name: string; type: string }; + const fieldEntry = interfaceDef.fields[fieldIndex] as InterfaceField; const fieldName = fieldEntry.name; const fieldType = fieldEntry.type; const nextLabel = (fieldIndex + 1 < fieldCount) ? `field_${fieldIndex + 1}` : 'json_cleanup'; diff --git a/src/codegen/stdlib/response.ts b/src/codegen/stdlib/response.ts index 5817d400..0d405193 100644 --- a/src/codegen/stdlib/response.ts +++ b/src/codegen/stdlib/response.ts @@ -8,6 +8,8 @@ * - response.ok - Boolean indicating success (status 200-299) */ +import { InterfaceField } from '../../ast/types.js'; + interface InterfaceStructGenerator { hasInterface(name: string): boolean; } @@ -149,7 +151,7 @@ export class ResponseGenerator { ): void { const fieldTypes: string[] = []; for (let i = 0; i < interfaceDef.properties.length; i++) { - const prop = interfaceDef.properties[i] as { name: string; type: string }; + const prop = interfaceDef.properties[i] as InterfaceField; if (prop.type === 'string') { fieldTypes.push('i8*'); } else if (prop.type === 'number') { @@ -192,7 +194,7 @@ export class ResponseGenerator { parserIR += `json_error:` + '\n'; for (let fieldIndex = 0; fieldIndex < interfaceDef.properties.length; fieldIndex++) { - const prop = interfaceDef.properties[fieldIndex] as { name: string; type: string }; + const prop = interfaceDef.properties[fieldIndex] as InterfaceField; const propType = prop.type; const fieldPtr = `%err_field_ptr_${fieldIndex}`; parserIR += ` ${fieldPtr} = getelementptr inbounds %${typeName}, %${typeName}* %struct_ptr, i32 0, i32 ${fieldIndex}` + '\n'; @@ -208,7 +210,7 @@ export class ResponseGenerator { parserIR += `json_ok:` + '\n'; for (let fieldIndex = 0; fieldIndex < interfaceDef.properties.length; fieldIndex++) { - const prop = interfaceDef.properties[fieldIndex] as { name: string; type: string }; + const prop = interfaceDef.properties[fieldIndex] as InterfaceField; const propName = prop.name; const propType = prop.type; const fieldNameConst = this.ctx.nextString(); diff --git a/src/codegen/types/interface-struct-generator.ts b/src/codegen/types/interface-struct-generator.ts index 140b55eb..b3bd20f3 100644 --- a/src/codegen/types/interface-struct-generator.ts +++ b/src/codegen/types/interface-struct-generator.ts @@ -1,4 +1,4 @@ -import { InterfaceDeclaration } from '../../ast/types.js'; +import { InterfaceDeclaration, InterfaceField } from '../../ast/types.js'; import { tsTypeToLlvm } from '../infrastructure/type-system.js'; const BUILTIN_TYPES = [ @@ -107,7 +107,7 @@ export class InterfaceStructGenerator { const pFieldsLen = pFields.length; if (pFieldsLen === 0) continue; for (let j = 0; j < pFieldsLen; j++) { - const f = pFields[j] as { name: string; type: string }; + const f = pFields[j] as InterfaceField; let fieldName = f.name; if (fieldName.endsWith('?')) { fieldName = fieldName.slice(0, -1); @@ -131,7 +131,7 @@ export class InterfaceStructGenerator { } const fields = this.getInterfaceFields(idx); for (let i = 0; i < fields.length; i++) { - const f = fields[i] as { name: string; type: string }; + const f = fields[i] as InterfaceField; let fieldName = f.name; if (fieldName.endsWith('?')) { fieldName = fieldName.slice(0, -1); diff --git a/src/codegen/types/objects/class.ts b/src/codegen/types/objects/class.ts index 32500cbe..3ceb3aae 100644 --- a/src/codegen/types/objects/class.ts +++ b/src/codegen/types/objects/class.ts @@ -1,4 +1,4 @@ -import { Expression, ClassNode, ClassMethod, ClassField, VariableNode, InterfaceDeclaration, CommonField } from '../../../ast/types.js'; +import { Expression, ClassNode, ClassMethod, ClassField, VariableNode, InterfaceDeclaration, CommonField, InterfaceField } from '../../../ast/types.js'; import { IGeneratorContext } from '../../infrastructure/generator-context.js'; import { SymbolKind, createObjectMetadata, createObjectMetadataWithInterfaceAndPointerAlloca, createClassMetadata } from '../../infrastructure/symbol-table.js'; import { stripOptional, tsTypeToLlvm } from '../../infrastructure/type-system.js'; @@ -1076,7 +1076,7 @@ export class ClassGenerator { const types: string[] = []; const tsTypes: string[] = []; for (let fi = 0; fi < interfaceDef.fields.length; fi++) { - const f = interfaceDef.fields[fi] as { name: string; type: string }; + const f = interfaceDef.fields[fi] as InterfaceField; keys.push(stripOptional(f.name)); types.push(this.fieldTypeToLlvm(f.type)); tsTypes.push(f.type); @@ -1132,7 +1132,7 @@ export class ClassGenerator { const types: string[] = []; const tsTypes: string[] = []; for (let fi = 0; fi < inlineFields.length; fi++) { - const f = inlineFields[fi] as { name: string; type: string }; + const f = inlineFields[fi] as InterfaceField; keys.push(stripOptional(f.name)); types.push(this.fieldTypeToLlvm(f.type)); tsTypes.push(f.type); @@ -1228,13 +1228,13 @@ export class ClassGenerator { const commonFields: CommonField[] = []; for (let fi = 0; fi < firstFields.length; fi++) { - const field = firstFields[fi] as { name: string; type: string }; + const field = firstFields[fi] as InterfaceField; let isCommon = true; for (let ii = 0; ii < interfaces.length; ii++) { const ifaceTyped = interfaces[ii] as { name: string; extends: string[]; fields: { name: string; type: string }[]; methods: { name: string }[] }; let found = false; for (let fj = 0; fj < ifaceTyped.fields.length; fj++) { - const f = ifaceTyped.fields[fj] as { name: string; type: string }; + const f = ifaceTyped.fields[fj] as InterfaceField; if (f.name === field.name && this.areTypesCompatible(f.type, field.type)) { found = true; break; diff --git a/src/codegen/types/objects/object.ts b/src/codegen/types/objects/object.ts index 65e44e95..621462e0 100644 --- a/src/codegen/types/objects/object.ts +++ b/src/codegen/types/objects/object.ts @@ -1,4 +1,4 @@ -import { Expression, ObjectNode, ObjectProperty } from '../../../ast/types.js'; +import { Expression, ObjectNode, ObjectProperty, InterfaceField } from '../../../ast/types.js'; import { IGeneratorContext } from '../../infrastructure/generator-context.js'; import type { InterfaceStructGenerator } from '../interface-struct-generator.js'; import { tsTypeToLlvm } from '../../infrastructure/type-system.js'; @@ -88,7 +88,7 @@ export class ObjectGenerator { const orderedFields: { key: string; llvmType: string; value: string }[] = []; for (let fieldIdx = 0; fieldIdx < fields.length; fieldIdx++) { - const field = fields[fieldIdx] as { name: string; type: string }; + const field = fields[fieldIdx] as InterfaceField; const llvmType = this.tsTypeToLlvm(field.type); const valueExpr = propMap.get(field.name); let finalValue: string; From 6a95a1a62b8cb2f625279a3bdc95de3e18fc9cb5 Mon Sep 17 00:00:00 2001 From: Chad Smith Date: Wed, 18 Feb 2026 21:51:15 -0800 Subject: [PATCH 5/5] Revert "replace inline type assertions with InterfaceField named type" This reverts commit 60b7efcc153deab07852caf66983ddcb5f0e44c1. --- src/codegen/expressions/access/member.ts | 26 +++++------ .../method-calls/class-dispatch.ts | 8 ++-- .../infrastructure/function-generator.ts | 8 ++-- src/codegen/infrastructure/type-inference.ts | 6 +-- .../type-resolver/type-resolver.ts | 24 +++++----- .../infrastructure/variable-allocator.ts | 44 +++++++++--------- src/codegen/llvm-generator.ts | 2 +- src/codegen/statements/control-flow.ts | 46 +++++++++---------- src/codegen/stdlib/json.ts | 10 ++-- src/codegen/stdlib/response.ts | 8 ++-- .../types/interface-struct-generator.ts | 6 +-- src/codegen/types/objects/class.ts | 10 ++-- src/codegen/types/objects/object.ts | 4 +- 13 files changed, 100 insertions(+), 102 deletions(-) diff --git a/src/codegen/expressions/access/member.ts b/src/codegen/expressions/access/member.ts index 840ea310..1ffb59a6 100644 --- a/src/codegen/expressions/access/member.ts +++ b/src/codegen/expressions/access/member.ts @@ -624,7 +624,7 @@ export class MemberAccessGenerator { const tsTypes: string[] = []; const nestedProps = nestedInterface.properties as InterfaceProperty[]; for (let pi = 0; pi < nestedProps.length; pi++) { - const p = nestedProps[pi] as InterfaceField; + const p = nestedProps[pi] as { name: string; type: string }; keys.push(stripOptional(p.name)); types.push(this.convertTsType(p.type)); tsTypes.push(p.type); @@ -931,7 +931,7 @@ export class MemberAccessGenerator { const types: string[] = []; if (interfaceDef.fields) { for (let i = 0; i < interfaceDef.fields.length; i++) { - const f = interfaceDef.fields[i] as InterfaceField; + const f = interfaceDef.fields[i] as { name: string; type: string }; keys.push(stripOptional(f.name)); tsTypes.push(f.type); types.push(this.convertTsType(f.type)); @@ -1043,7 +1043,7 @@ export class MemberAccessGenerator { const types: string[] = []; if (nestedInterfaceDef.fields) { for (let i = 0; i < nestedInterfaceDef.fields.length; i++) { - const f = nestedInterfaceDef.fields[i] as InterfaceField; + const f = nestedInterfaceDef.fields[i] as { name: string; type: string }; keys.push(stripOptional(f.name)); tsTypes.push(f.type); types.push(this.convertTsType(f.type)); @@ -1558,7 +1558,7 @@ export class MemberAccessGenerator { let propIndex = -1; let propTsType: string | undefined; for (let i = 0; i < interfaceDef.fields.length; i++) { - const f = interfaceDef.fields[i] as InterfaceField; + const f = interfaceDef.fields[i] as { name: string; type: string }; const fName = stripOptional(f.name); if (fName === expr.property) { propIndex = i; @@ -1900,7 +1900,7 @@ export class MemberAccessGenerator { const types: string[] = []; const tsTypes: string[] = []; for (let j = 0; j < fields.length; j++) { - const f = fields[j] as InterfaceField; + const f = fields[j] as { name: string; type: string }; keys.push(stripOptional(f.name)); tsTypes.push(f.type); if (f.type === 'string') { @@ -1931,7 +1931,7 @@ export class MemberAccessGenerator { const types: string[] = []; const tsTypes: string[] = []; for (let j = 0; j < fields.length; j++) { - const f = fields[j] as InterfaceField; + const f = fields[j] as { name: string; type: string }; keys.push(stripOptional(f.name)); tsTypes.push(f.type); if (f.type === 'string') { @@ -2203,7 +2203,7 @@ export class MemberAccessGenerator { let propIndex = -1; for (let i = 0; i < interfaceDef.fields.length; i++) { - const f = interfaceDef.fields[i] as InterfaceField; + const f = interfaceDef.fields[i] as { name: string; type: string }; if (f.name === expr.property) { propIndex = i; break; @@ -2212,17 +2212,17 @@ export class MemberAccessGenerator { if (propIndex === -1) { const fieldNames: string[] = []; for (let i = 0; i < interfaceDef.fields.length; i++) { - const field = interfaceDef.fields[i] as InterfaceField; + const field = interfaceDef.fields[i] as { name: string; type: string }; fieldNames.push(field.name); } throw new Error(`Unknown property: ${expr.property} on interface ${valueType}. Available properties: ${fieldNames.join(', ')}`); } - const propField = interfaceDef.fields[propIndex] as InterfaceField; + const propField = interfaceDef.fields[propIndex] as { name: string; type: string }; const propType = this.convertTsType(propField.type); const structTypes: string[] = []; for (let i = 0; i < interfaceDef.fields.length; i++) { - const field = interfaceDef.fields[i] as InterfaceField; + const field = interfaceDef.fields[i] as { name: string; type: string }; structTypes.push(this.convertTsType(field.type)); } const structType = `{ ${structTypes.join(', ')} }`; @@ -3025,7 +3025,7 @@ export class MemberAccessGenerator { let fieldIndex = -1; for (let i = 0; i < fields.length; i++) { - const f = fields[i] as InterfaceField; + const f = fields[i] as { name: string; type: string }; if (f.name === property) { fieldIndex = i; break; @@ -3033,12 +3033,12 @@ export class MemberAccessGenerator { } if (fieldIndex === -1) return null; - const field = fields[fieldIndex] as InterfaceField; + const field = fields[fieldIndex] as { name: string; type: string }; const fieldLlvmType = this.convertTsType(field.type); const types: string[] = []; for (let i = 0; i < fields.length; i++) { - const f = fields[i] as InterfaceField; + const f = fields[i] as { name: string; type: string }; types.push(this.convertTsType(f.type)); } const structType = `{ ${types.join(', ')} }`; diff --git a/src/codegen/expressions/method-calls/class-dispatch.ts b/src/codegen/expressions/method-calls/class-dispatch.ts index 3b458d32..8530104b 100644 --- a/src/codegen/expressions/method-calls/class-dispatch.ts +++ b/src/codegen/expressions/method-calls/class-dispatch.ts @@ -28,7 +28,7 @@ export function getInterfaceFromAST(ctx: MethodCallGeneratorContext, name: strin if (!ifaceItem) continue; const properties: { name: string; type: string }[] = []; for (let j = 0; j < ifaceItem.fields.length; j++) { - const field = ifaceItem.fields[j] as InterfaceField; + const field = ifaceItem.fields[j] as { name: string; type: string }; properties.push({ name: field.name, type: field.type }); } return { properties }; @@ -311,13 +311,13 @@ export function resolveNestedMemberAccessType(ctx: MethodCallGeneratorContext, e if (interfaceDeclResult) { let fieldResult: InterfaceField | null = null; for (let i = 0; i < interfaceDecl.fields.length; i++) { - const f = interfaceDecl.fields[i] as InterfaceField; + const f = interfaceDecl.fields[i] as { name: string; type: string }; if (f.name === memberAccess.property) { fieldResult = f; break; } } - const field = fieldResult as InterfaceField; + const field = fieldResult as { name: string; type: string }; if (fieldResult) { let fieldType = field.type; if (fieldType.endsWith(' | null') || fieldType.endsWith(' | undefined')) { @@ -517,7 +517,7 @@ export function handleClassMethods(ctx: MethodCallGeneratorContext, expr: Method if (interfaceDeclResult) { const interfaceDecl = interfaceDeclResult as InterfaceDeclaration; for (let i = 0; i < interfaceDecl.fields.length; i++) { - const f = interfaceDecl.fields[i] as InterfaceField; + const f = interfaceDecl.fields[i] as { name: string; type: string }; if (f.name === memberAccess.property) { let fieldType = f.type; if (fieldType.endsWith(' | null') || fieldType.endsWith(' | undefined')) { diff --git a/src/codegen/infrastructure/function-generator.ts b/src/codegen/infrastructure/function-generator.ts index 4125aa2b..ca1f40b0 100644 --- a/src/codegen/infrastructure/function-generator.ts +++ b/src/codegen/infrastructure/function-generator.ts @@ -1,4 +1,4 @@ -import { FunctionNode, BlockStatement, Expression, FunctionParameter, AST, VariableDeclaration, IfStatement, WhileStatement, ForStatement, ForOfStatement, AssignmentStatement, CommonField, SwitchStatement, SourceLocation, Statement, InterfaceField } from '../../ast/types.js'; +import { FunctionNode, BlockStatement, Expression, FunctionParameter, AST, VariableDeclaration, IfStatement, WhileStatement, ForStatement, ForOfStatement, AssignmentStatement, CommonField, SwitchStatement, SourceLocation, Statement } from '../../ast/types.js'; import { SymbolKind, SymbolTable, createPointerAllocaMetadata, createInterfacePointerAllocaMetadata, createClassMetadata, createObjectMetadataWithInterface, createInterfaceMetadata, createMapMetadataSymbol, SymbolMetadata } from './symbol-table.js'; import type { ClosureInfo } from './closure-analyzer.js'; import type { TypeChecker } from '../../typescript/type-checker.js'; @@ -267,7 +267,7 @@ export class FunctionGenerator { const keys: string[] = []; const types: string[] = []; for (let j = 0; j < interfaceDefFields.length; j++) { - const field = interfaceDefFields[j] as InterfaceField; + const field = interfaceDefFields[j] as { name: string; type: string }; if (!field || !field.name) continue; const fieldName = stripOptional(field.name); keys.push(fieldName); @@ -626,7 +626,7 @@ export class FunctionGenerator { const commonFields: CommonField[] = []; for (let fi = 0; fi < firstFields.length; fi++) { - const field = firstFields[fi] as InterfaceField; + const field = firstFields[fi] as { name: string; type: string }; if (!field || !field.name) continue; let isCommon = true; for (let ii = 0; ii < interfaces.length; ii++) { @@ -637,7 +637,7 @@ export class FunctionGenerator { } let found = false; for (let fj = 0; fj < ifaceTyped.fields.length; fj++) { - const f = ifaceTyped.fields[fj] as InterfaceField; + const f = ifaceTyped.fields[fj] as { name: string; type: string }; if (!f || !f.name) continue; if (f.name === field.name && this.areTypesCompatible(f.type, field.type)) { found = true; diff --git a/src/codegen/infrastructure/type-inference.ts b/src/codegen/infrastructure/type-inference.ts index 5a88c925..67f32063 100644 --- a/src/codegen/infrastructure/type-inference.ts +++ b/src/codegen/infrastructure/type-inference.ts @@ -577,7 +577,7 @@ export class TypeInference { const iface = this.getInterface(interfaceName); if (!iface) return null; for (let i = 0; i < iface.fields.length; i++) { - const f = iface.fields[i] as InterfaceField; + const f = iface.fields[i] as { name: string; type: string }; let fieldName = f.name; if (fieldName.endsWith('?')) { fieldName = fieldName.slice(0, -1); @@ -746,7 +746,7 @@ export class TypeInference { if (iface) { const field = this.getInterfaceProperty(typeName, fieldName); if (field) { - const fieldTyped = field as InterfaceField; + const fieldTyped = field as { name: string; type: string }; return fieldTyped.type; } } @@ -764,7 +764,7 @@ export class TypeInference { if (inner.length === 0) return null; const fields = this.parseInlineObjectFields(inner); for (let i = 0; i < fields.length; i++) { - const field = fields[i] as InterfaceField; + const field = fields[i] as { name: string; type: string }; const cleanName = field.name.replace(/\?$/, ''); if (cleanName === fieldName) { return field.type; diff --git a/src/codegen/infrastructure/type-resolver/type-resolver.ts b/src/codegen/infrastructure/type-resolver/type-resolver.ts index 93fddce0..5ebbd28c 100644 --- a/src/codegen/infrastructure/type-resolver/type-resolver.ts +++ b/src/codegen/infrastructure/type-resolver/type-resolver.ts @@ -349,7 +349,7 @@ export class TypeResolver { const types: string[] = []; const tsTypes: string[] = []; for (let i = 0; i < iface.fields.length; i++) { - const f = iface.fields[i] as InterfaceField; + const f = iface.fields[i] as { name: string; type: string }; keys.push(stripOptional(f.name)); types.push(this.convertTsType(f.type)); tsTypes.push(f.type); @@ -364,7 +364,7 @@ export class TypeResolver { const iface = this.getInterface(interfaceName); if (!iface) return null; for (let i = 0; i < iface.fields.length; i++) { - const f = iface.fields[i] as InterfaceField; + const f = iface.fields[i] as { name: string; type: string }; if (!f || !f.name) { continue; } @@ -380,7 +380,7 @@ export class TypeResolver { if (!iface) return null; const properties: { name: string; type: string }[] = []; for (let i = 0; i < iface.fields.length; i++) { - const f = iface.fields[i] as InterfaceField; + const f = iface.fields[i] as { name: string; type: string }; properties.push({ name: f.name, type: f.type }); } return { properties }; @@ -520,13 +520,13 @@ export class TypeResolver { const commonFields: CommonField[] = []; for (let fi = 0; fi < firstFields.length; fi++) { - const field = firstFields[fi] as InterfaceField; + const field = firstFields[fi] as { name: string; type: string }; let isCommon = true; for (let ii = 0; ii < interfaces.length; ii++) { const iface = interfaces[ii] as InterfaceDeclaration; let hasMatch = false; for (let jj = 0; jj < iface.fields.length; jj++) { - const f = iface.fields[jj] as InterfaceField; + const f = iface.fields[jj] as { name: string; type: string }; if (f.name === field.name && this.areTypesCompatible(f.type, field.type)) { hasMatch = true; break; @@ -768,7 +768,7 @@ export class TypeResolver { field: string ): string | null { for (let i = 0; i < fields.length; i++) { - const f = fields[i] as InterfaceField; + const f = fields[i] as { name: string; type: string }; if (f.name === field) { if (f.type === `'${value}'` || f.type === `"${value}"`) { return ifaceName; @@ -843,14 +843,14 @@ export class TypeResolver { const iface = ifaceDecl as InterfaceDeclaration; let field: { name: string; type: string } | null = null; for (let i = 0; i < iface.fields.length; i++) { - const f = iface.fields[i] as InterfaceField; + const f = iface.fields[i] as { name: string; type: string }; if (f.name === memberExpr.property) { field = f; break; } } if (field) { - const fieldTyped = field as InterfaceField; + const fieldTyped = field as { name: string; type: string }; const mapParsed = parseMapTypeString(fieldTyped.type); if (mapParsed) { return { fieldName: memberExpr.property, keyType: mapParsed.keyType, valueType: mapParsed.valueType }; @@ -900,14 +900,14 @@ export class TypeResolver { const iface = ifaceDecl as InterfaceDeclaration; let field: { name: string; type: string } | null = null; for (let i = 0; i < iface.fields.length; i++) { - const f = iface.fields[i] as InterfaceField; + const f = iface.fields[i] as { name: string; type: string }; if (f.name === memberExpr.property) { field = f; break; } } if (field) { - const fieldTyped = field as InterfaceField; + const fieldTyped = field as { name: string; type: string }; let fieldType = fieldTyped.type; if (fieldType.endsWith(' | null') || fieldType.endsWith(' | undefined')) { fieldType = fieldType.replace(/ \| null$/, '').replace(/ \| undefined$/, ''); @@ -996,14 +996,14 @@ export class TypeResolver { const iface = ifaceDecl as InterfaceDeclaration; let field: { name: string; type: string } | null = null; for (let i = 0; i < iface.fields.length; i++) { - const f = iface.fields[i] as InterfaceField; + const f = iface.fields[i] as { name: string; type: string }; if (f.name === memberExpr.property) { field = f; break; } } if (field) { - const fieldTyped = field as InterfaceField; + const fieldTyped = field as { name: string; type: string }; const mapParsed = parseMapTypeString(fieldTyped.type); if (mapParsed) { return mapParsed.keyType; diff --git a/src/codegen/infrastructure/variable-allocator.ts b/src/codegen/infrastructure/variable-allocator.ts index 4f3a80bb..cdfaf217 100644 --- a/src/codegen/infrastructure/variable-allocator.ts +++ b/src/codegen/infrastructure/variable-allocator.ts @@ -315,7 +315,7 @@ export class VariableAllocator { for (let fi = 0; fi < inlineFields.length; fi++) { const fieldRaw = inlineFields[fi]; if (!fieldRaw) continue; - const field = fieldRaw as InterfaceField; + const field = fieldRaw as { name: string; type: string }; if (!field.name || !field.type) continue; keys.push(stripOptional(field.name)); types.push(this.convertTsType(field.type)); @@ -337,7 +337,7 @@ export class VariableAllocator { for (let fi = 0; fi < interfaceDef.fields.length; fi++) { const fieldRaw = interfaceDef.fields[fi]; if (!fieldRaw) continue; - const field = fieldRaw as InterfaceField; + const field = fieldRaw as { name: string; type: string }; if (!field.name || !field.type) continue; keys.push(stripOptional(field.name)); types.push(this.convertTsType(field.type)); @@ -543,7 +543,7 @@ export class VariableAllocator { const inlineFields = this.parseInlineObjectType(interfaceName); if (inlineFields) { for (let i = 0; i < inlineFields.length; i++) { - const field = inlineFields[i] as InterfaceField; + const field = inlineFields[i] as { name: string; type: string }; keys.push(stripOptional(field.name)); types.push(this.convertTsType(field.type)); tsTypes.push(field.type); @@ -553,7 +553,7 @@ export class VariableAllocator { const interfaceDefResult = this.getInterface(interfaceName); const interfaceDef = interfaceDefResult as InterfaceDeclaration; for (let i = 0; i < interfaceDef.fields.length; i++) { - const field = interfaceDef.fields[i] as InterfaceField; + const field = interfaceDef.fields[i] as { name: string; type: string }; keys.push(stripOptional(field.name)); types.push(this.convertTsType(field.type)); tsTypes.push(field.type); @@ -576,7 +576,7 @@ export class VariableAllocator { const inlineFields = this.parseInlineObjectType(interfaceName); if (inlineFields) { for (let i = 0; i < inlineFields.length; i++) { - const field = inlineFields[i] as InterfaceField; + const field = inlineFields[i] as { name: string; type: string }; keys.push(stripOptional(field.name)); types.push(this.convertTsType(field.type)); tsTypes.push(field.type); @@ -586,7 +586,7 @@ export class VariableAllocator { const interfaceDefResult = this.getInterface(interfaceName); const interfaceDef = interfaceDefResult as InterfaceDeclaration; for (let i = 0; i < interfaceDef.fields.length; i++) { - const field = interfaceDef.fields[i] as InterfaceField; + const field = interfaceDef.fields[i] as { name: string; type: string }; keys.push(stripOptional(field.name)); types.push(this.convertTsType(field.type)); tsTypes.push(field.type); @@ -609,7 +609,7 @@ export class VariableAllocator { const inlineFields = this.parseInlineObjectType(elementType); if (inlineFields) { for (let i = 0; i < inlineFields.length; i++) { - const field = inlineFields[i] as InterfaceField; + const field = inlineFields[i] as { name: string; type: string }; elementKeys.push(stripOptional(field.name)); elementTypes.push(this.convertTsType(field.type)); elementTsTypes.push(field.type); @@ -620,7 +620,7 @@ export class VariableAllocator { if (interfaceDefResult) { const interfaceDef = interfaceDefResult as InterfaceDeclaration; for (let i = 0; i < interfaceDef.fields.length; i++) { - const field = interfaceDef.fields[i] as InterfaceField; + const field = interfaceDef.fields[i] as { name: string; type: string }; elementKeys.push(stripOptional(field.name)); elementTypes.push(this.convertTsType(field.type)); elementTsTypes.push(field.type); @@ -720,7 +720,7 @@ export class VariableAllocator { const inlineFields = this.parseInlineObjectType(interfaceName); if (inlineFields) { for (let i = 0; i < inlineFields.length; i++) { - const field = inlineFields[i] as InterfaceField; + const field = inlineFields[i] as { name: string; type: string }; keys.push(stripOptional(field.name)); types.push(this.convertTsType(field.type)); tsTypes.push(field.type); @@ -731,7 +731,7 @@ export class VariableAllocator { const interfaceDef = interfaceDefResult as InterfaceDeclaration; const allFields = this.getAllInterfaceFields(interfaceDef); for (let i = 0; i < allFields.length; i++) { - const field = allFields[i] as InterfaceField; + const field = allFields[i] as { name: string; type: string }; keys.push(stripOptional(field.name)); types.push(this.convertTsType(field.type)); tsTypes.push(field.type); @@ -810,7 +810,7 @@ export class VariableAllocator { const types: string[] = []; const tsTypes: string[] = []; for (let i = 0; i < interfaceDef.fields.length; i++) { - const field = interfaceDef.fields[i] as InterfaceField; + const field = interfaceDef.fields[i] as { name: string; type: string }; keys.push(stripOptional(field.name)); types.push(this.convertTsType(field.type)); tsTypes.push(field.type); @@ -878,7 +878,7 @@ export class VariableAllocator { const objIface = objectInterface as InterfaceDeclaration; if (!objIface.fields) return null; for (let i = 0; i < objIface.fields.length; i++) { - const field = objIface.fields[i] as InterfaceField; + const field = objIface.fields[i] as { name: string; type: string }; if (!field || !field.name) continue; const fieldName = stripOptional(field.name); if (fieldName === memberExpr.property) { @@ -901,7 +901,7 @@ export class VariableAllocator { const types: string[] = []; const tsTypes: string[] = []; for (let i = 0; i < interfaceDef.fields.length; i++) { - const field = interfaceDef.fields[i] as InterfaceField; + const field = interfaceDef.fields[i] as { name: string; type: string }; keys.push(stripOptional(field.name)); types.push(this.convertTsType(field.type)); tsTypes.push(field.type); @@ -1079,7 +1079,7 @@ export class VariableAllocator { const tsTypes: string[] = []; const types: string[] = []; for (let i = 0; i < interfaceDef.fields.length; i++) { - const field = interfaceDef.fields[i] as InterfaceField; + const field = interfaceDef.fields[i] as { name: string; type: string }; keys.push(stripOptional(field.name)); tsTypes.push(field.type); types.push(this.convertTsTypeJson(field.type)); @@ -1109,7 +1109,7 @@ export class VariableAllocator { types = []; tsTypes = []; for (let i = 0; i < interfaceDef.fields.length; i++) { - const field = interfaceDef.fields[i] as InterfaceField; + const field = interfaceDef.fields[i] as { name: string; type: string }; keys.push(stripOptional(field.name)); types.push(this.convertTsType(field.type)); tsTypes.push(field.type); @@ -1480,7 +1480,7 @@ export class VariableAllocator { const types: string[] = []; const tsTypes: string[] = []; for (let fi = 0; fi < inlineFields.length; fi++) { - const field = inlineFields[fi] as InterfaceField; + const field = inlineFields[fi] as { name: string; type: string }; keys.push(stripOptional(field.name)); types.push(this.convertTsType(field.type)); tsTypes.push(field.type); @@ -1498,7 +1498,7 @@ export class VariableAllocator { const types: string[] = []; const tsTypes: string[] = []; for (let fi = 0; fi < interfaceDef.fields.length; fi++) { - const field = interfaceDef.fields[fi] as InterfaceField; + const field = interfaceDef.fields[fi] as { name: string; type: string }; keys.push(stripOptional(field.name)); types.push(this.convertTsType(field.type)); tsTypes.push(field.type); @@ -1789,7 +1789,7 @@ export class VariableAllocator { if (!ifaceResult) return null; const iface = ifaceResult as InterfaceDeclaration; for (let i = 0; i < iface.fields.length; i++) { - const f = iface.fields[i] as InterfaceField; + const f = iface.fields[i] as { name: string; type: string }; if (f.name === fieldName) { return f.type; } @@ -1811,7 +1811,7 @@ export class VariableAllocator { const types: string[] = []; const tsTypes: string[] = []; for (let i = 0; i < inlineFields.length; i++) { - const field = inlineFields[i] as InterfaceField; + const field = inlineFields[i] as { name: string; type: string }; keys.push(stripOptional(field.name)); types.push(this.convertTsType(field.type)); tsTypes.push(field.type); @@ -1827,7 +1827,7 @@ export class VariableAllocator { const types: string[] = []; const tsTypes: string[] = []; for (let i = 0; i < interfaceDef.fields.length; i++) { - const field = interfaceDef.fields[i] as InterfaceField; + const field = interfaceDef.fields[i] as { name: string; type: string }; keys.push(stripOptional(field.name)); types.push(this.convertTsType(field.type)); tsTypes.push(field.type); @@ -1873,13 +1873,13 @@ export class VariableAllocator { const commonFields: CommonField[] = []; for (let fi = 0; fi < firstFields.length; fi++) { - const field = firstFields[fi] as InterfaceField; + const field = firstFields[fi] as { name: string; type: string }; let isCommon = true; for (let ii = 0; ii < interfaces.length; ii++) { const ifaceTyped = interfaces[ii] as { fields: { name: string; type: string }[] }; let found = false; for (let fj = 0; fj < ifaceTyped.fields.length; fj++) { - const f = ifaceTyped.fields[fj] as InterfaceField; + const f = ifaceTyped.fields[fj] as { name: string; type: string }; if (f.name === field.name && this.areTypesCompatible(f.type, field.type)) { found = true; break; diff --git a/src/codegen/llvm-generator.ts b/src/codegen/llvm-generator.ts index b0e0ff9d..f07df57d 100644 --- a/src/codegen/llvm-generator.ts +++ b/src/codegen/llvm-generator.ts @@ -1516,7 +1516,7 @@ export class LLVMGenerator extends BaseGenerator implements IGeneratorContext { const tsTypes: string[] = []; const types: string[] = []; for (let i = 0; i < interfaceDef.fields.length; i++) { - const field = interfaceDef.fields[i] as InterfaceField; + const field = interfaceDef.fields[i] as { name: string; type: string }; keys.push(stripOptional(field.name)); tsTypes.push(field.type); types.push(this.tsTypeToLlvmJsonWithEnums(field.type)); diff --git a/src/codegen/statements/control-flow.ts b/src/codegen/statements/control-flow.ts index 895bb00b..ff2eb040 100644 --- a/src/codegen/statements/control-flow.ts +++ b/src/codegen/statements/control-flow.ts @@ -490,7 +490,7 @@ export class ControlFlowGenerator { for (let i = 0; i < fields.length; i++) { const fRaw = fields[i]; if (!fRaw) continue; - const f = fRaw as InterfaceField; + const f = fRaw as { name: string; type: string }; if (!f.name || !f.type) continue; elementKeys.push(f.name); elementTsTypes.push(f.type); @@ -521,7 +521,7 @@ export class ControlFlowGenerator { for (let i = 0; i < ifaceTyped.fields.length; i++) { const fRaw = ifaceTyped.fields[i]; if (!fRaw) continue; - const f = fRaw as InterfaceField; + const f = fRaw as { name: string; type: string }; if (!f.name || !f.type) continue; elementKeys.push(f.name); elementTsTypes.push(f.type); @@ -583,7 +583,7 @@ export class ControlFlowGenerator { for (let i = 0; i < ifaceTyped.fields.length; i++) { const fRaw = ifaceTyped.fields[i]; if (!fRaw) continue; - const f = fRaw as InterfaceField; + const f = fRaw as { name: string; type: string }; if (!f.name) continue; if (f.name === fieldName) { return f.type; @@ -636,7 +636,7 @@ export class ControlFlowGenerator { for (let i = 0; i < fields.length; i++) { const fRaw = fields[i]; if (!fRaw) continue; - const f = fRaw as InterfaceField; + const f = fRaw as { name: string; type: string }; if (!f.name || !f.type) continue; elementKeys.push(f.name); elementTsTypes.push(f.type); @@ -670,7 +670,7 @@ export class ControlFlowGenerator { const elementTypes: string[] = []; const elementTsTypes: string[] = []; for (let i = 0; i < fields.length; i++) { - const f = fields[i] as InterfaceField; + const f = fields[i] as { name: string; type: string }; elementKeys.push(f.name); elementTsTypes.push(f.type); if (f.type === 'string') { @@ -700,7 +700,7 @@ export class ControlFlowGenerator { for (let i = 0; i < elemIfaceTyped.fields.length; i++) { const fRaw = elemIfaceTyped.fields[i]; if (!fRaw) continue; - const f = fRaw as InterfaceField; + const f = fRaw as { name: string; type: string }; if (!f.name || !f.type) continue; elementKeys.push(f.name); elementTsTypes.push(f.type); @@ -785,7 +785,7 @@ export class ControlFlowGenerator { for (let i = 0; i < ifaceTyped.fields.length; i++) { const fRaw = ifaceTyped.fields[i]; if (!fRaw) continue; - const f = fRaw as InterfaceField; + const f = fRaw as { name: string; type: string }; if (!f.name) continue; const fieldName = f.name.replace('?', ''); if (fieldName === ma.property) { @@ -817,15 +817,15 @@ export class ControlFlowGenerator { for (let i = 0; i < ifaceTyped.fields.length; i++) { const fRaw = ifaceTyped.fields[i]; if (!fRaw) continue; - const f = fRaw as InterfaceField; + const f = fRaw as { name: string; type: string }; if (!f.name) continue; const fieldName = f.name.replace('?', ''); if (fieldName === propName) { - fieldDefResult = f as InterfaceField; + fieldDefResult = f as { name: string; type: string }; break; } } - const fieldDef = fieldDefResult as InterfaceField; + const fieldDef = fieldDefResult as { name: string; type: string }; if (!fieldDefResult || !fieldDef.type.endsWith('[]')) { return null; } @@ -841,7 +841,7 @@ export class ControlFlowGenerator { for (let i = 0; i < fields.length; i++) { const fRaw = fields[i]; if (!fRaw) continue; - const f = fRaw as InterfaceField; + const f = fRaw as { name: string; type: string }; if (!f.name || !f.type) continue; elementKeys.push(f.name); elementTsTypes.push(f.type); @@ -883,7 +883,7 @@ export class ControlFlowGenerator { const elementTypes: string[] = []; const elementTsTypes: string[] = []; for (let i = 0; i < elementIfaceTyped.fields.length; i++) { - const f = elementIfaceTyped.fields[i] as InterfaceField; + const f = elementIfaceTyped.fields[i] as { name: string; type: string }; elementKeys.push(f.name); elementTsTypes.push(f.type); if (f.type === 'string') { @@ -929,7 +929,7 @@ export class ControlFlowGenerator { for (let i = 0; i < fields.length; i++) { const fRaw = fields[i]; if (!fRaw) continue; - const f = fRaw as InterfaceField; + const f = fRaw as { name: string; type: string }; if (!f.name || !f.type) continue; elementKeys.push(f.name); elementTsTypes.push(f.type); @@ -964,7 +964,7 @@ export class ControlFlowGenerator { const elementTypes: string[] = []; const elementTsTypes: string[] = []; for (let i = 0; i < elementIfaceTyped.fields.length; i++) { - const f = elementIfaceTyped.fields[i] as InterfaceField; + const f = elementIfaceTyped.fields[i] as { name: string; type: string }; elementKeys.push(f.name); elementTsTypes.push(f.type); if (f.type === 'string') { @@ -1055,13 +1055,13 @@ export class ControlFlowGenerator { const firstFields = new Map(); const firstInterface = memberInterfaces[0] as { name: string; extends: string[]; fields: { name: string; type: string }[] }; for (let i = 0; i < firstInterface.fields.length; i++) { - const f = firstInterface.fields[i] as InterfaceField; + const f = firstInterface.fields[i] as { name: string; type: string }; firstFields.set(f.name, f.type); } const commonFields: CommonField[] = []; for (let _ffi = 0; _ffi < firstInterface.fields.length; _ffi++) { - const firstField = firstInterface.fields[_ffi] as InterfaceField; + const firstField = firstInterface.fields[_ffi] as { name: string; type: string }; const fieldName = firstField.name; const fieldType = firstField.type; let isCommon = true; @@ -1070,13 +1070,13 @@ export class ControlFlowGenerator { const otherIface = memberInterfaces[i] as { name: string; extends: string[]; fields: { name: string; type: string }[] }; let otherFieldResult: InterfaceField | null = null; for (let j = 0; j < otherIface.fields.length; j++) { - const f = otherIface.fields[j] as InterfaceField; + const f = otherIface.fields[j] as { name: string; type: string }; if (f.name === fieldName) { otherFieldResult = f; break; } } - const otherField = otherFieldResult as InterfaceField; + const otherField = otherFieldResult as { name: string; type: string }; if (!otherFieldResult) { isCommon = false; break; @@ -1518,13 +1518,13 @@ export class ControlFlowGenerator { const commonFields: CommonField[] = []; for (let fi = 0; fi < firstFields.length; fi++) { - const field = firstFields[fi] as InterfaceField; + const field = firstFields[fi] as { name: string; type: string }; let isCommon = true; for (let ii = 0; ii < interfaces.length; ii++) { const ifaceTyped = interfaces[ii] as { fields: { name: string; type: string }[] }; let found = false; for (let fj = 0; fj < ifaceTyped.fields.length; fj++) { - const f = ifaceTyped.fields[fj] as InterfaceField; + const f = ifaceTyped.fields[fj] as { name: string; type: string }; if (f.name === field.name && this.areTypesCompatible(f.type, field.type)) { found = true; break; @@ -1651,7 +1651,7 @@ export class ControlFlowGenerator { const currentKeys: string[] = objMeta.keys as string[]; const ifaceKeys: string[] = []; for (let fi = 0; fi < iface.fields.length; fi++) { - const f = iface.fields[fi] as InterfaceField; + const f = iface.fields[fi] as { name: string; type: string }; ifaceKeys.push(f.name); } let isCompatible = true; @@ -1667,7 +1667,7 @@ export class ControlFlowGenerator { const types: string[] = []; const tsTypes: string[] = []; for (let i = 0; i < iface.fields.length; i++) { - const f = iface.fields[i] as InterfaceField; + const f = iface.fields[i] as { name: string; type: string }; keys.push(stripOptional(f.name)); types.push(this.fieldTypeToLlvm(f.type)); tsTypes.push(f.type); @@ -1689,7 +1689,7 @@ export class ControlFlowGenerator { private checkDiscriminant(ifaceName: string, fields: { name: string; type: string }[], discriminantValue: string): string | null { for (let i = 0; i < fields.length; i++) { - const f = fields[i] as InterfaceField; + const f = fields[i] as { name: string; type: string }; if (f.name === 'type') { const fieldType = f.type; if (fieldType === `'${discriminantValue}'` || fieldType === `"${discriminantValue}"`) { diff --git a/src/codegen/stdlib/json.ts b/src/codegen/stdlib/json.ts index d84476dd..40e1a5aa 100644 --- a/src/codegen/stdlib/json.ts +++ b/src/codegen/stdlib/json.ts @@ -1,4 +1,4 @@ -import { Expression, MethodCallNode, InterfaceField } from '../../ast/types.js'; +import { Expression, MethodCallNode } from '../../ast/types.js'; interface ExprBase { type: string; } @@ -207,7 +207,7 @@ export class JsonGenerator { const fieldTypes: string[] = []; for (let fi = 0; fi < interfaceDef.fields.length; fi++) { - const fieldItem = interfaceDef.fields[fi] as InterfaceField; + const fieldItem = interfaceDef.fields[fi] as { name: string; type: string }; const fieldType = fieldItem.type; if (fieldType === 'string') { fieldTypes.push('i8*'); @@ -243,7 +243,7 @@ export class JsonGenerator { this.generatedStructs.add(parserKey); for (let fi = 0; fi < interfaceDef.fields.length; fi++) { - const fieldItem = interfaceDef.fields[fi] as InterfaceField; + const fieldItem = interfaceDef.fields[fi] as { name: string; type: string }; const fieldType = fieldItem.type; if (fieldType !== 'string' && fieldType !== 'number' && fieldType !== 'boolean') { const nestedDef = this.getInterfaceFields(fieldType); @@ -261,7 +261,7 @@ export class JsonGenerator { parserIR += ` %struct_ptr = bitcast i8* %struct_bytes to %${typeName}*\n`; for (let fieldIndex = 0; fieldIndex < interfaceDef.fields.length; fieldIndex++) { - const fieldEntry = interfaceDef.fields[fieldIndex] as InterfaceField; + const fieldEntry = interfaceDef.fields[fieldIndex] as { name: string; type: string }; if (fieldEntry.type === 'string') { parserIR += ` %init_ptr_${fieldIndex} = getelementptr inbounds %${typeName}, %${typeName}* %struct_ptr, i32 0, i32 ${fieldIndex}\n`; parserIR += ` store i8* getelementptr inbounds ([1 x i8], [1 x i8]* @.empty_str, i64 0, i64 0), i8** %init_ptr_${fieldIndex}\n`; @@ -285,7 +285,7 @@ export class JsonGenerator { parserIR += ` br label %field_0\n\n`; for (let fieldIndex = 0; fieldIndex < fieldCount; fieldIndex++) { - const fieldEntry = interfaceDef.fields[fieldIndex] as InterfaceField; + const fieldEntry = interfaceDef.fields[fieldIndex] as { name: string; type: string }; const fieldName = fieldEntry.name; const fieldType = fieldEntry.type; const nextLabel = (fieldIndex + 1 < fieldCount) ? `field_${fieldIndex + 1}` : 'json_cleanup'; diff --git a/src/codegen/stdlib/response.ts b/src/codegen/stdlib/response.ts index 0d405193..5817d400 100644 --- a/src/codegen/stdlib/response.ts +++ b/src/codegen/stdlib/response.ts @@ -8,8 +8,6 @@ * - response.ok - Boolean indicating success (status 200-299) */ -import { InterfaceField } from '../../ast/types.js'; - interface InterfaceStructGenerator { hasInterface(name: string): boolean; } @@ -151,7 +149,7 @@ export class ResponseGenerator { ): void { const fieldTypes: string[] = []; for (let i = 0; i < interfaceDef.properties.length; i++) { - const prop = interfaceDef.properties[i] as InterfaceField; + const prop = interfaceDef.properties[i] as { name: string; type: string }; if (prop.type === 'string') { fieldTypes.push('i8*'); } else if (prop.type === 'number') { @@ -194,7 +192,7 @@ export class ResponseGenerator { parserIR += `json_error:` + '\n'; for (let fieldIndex = 0; fieldIndex < interfaceDef.properties.length; fieldIndex++) { - const prop = interfaceDef.properties[fieldIndex] as InterfaceField; + const prop = interfaceDef.properties[fieldIndex] as { name: string; type: string }; const propType = prop.type; const fieldPtr = `%err_field_ptr_${fieldIndex}`; parserIR += ` ${fieldPtr} = getelementptr inbounds %${typeName}, %${typeName}* %struct_ptr, i32 0, i32 ${fieldIndex}` + '\n'; @@ -210,7 +208,7 @@ export class ResponseGenerator { parserIR += `json_ok:` + '\n'; for (let fieldIndex = 0; fieldIndex < interfaceDef.properties.length; fieldIndex++) { - const prop = interfaceDef.properties[fieldIndex] as InterfaceField; + const prop = interfaceDef.properties[fieldIndex] as { name: string; type: string }; const propName = prop.name; const propType = prop.type; const fieldNameConst = this.ctx.nextString(); diff --git a/src/codegen/types/interface-struct-generator.ts b/src/codegen/types/interface-struct-generator.ts index b3bd20f3..140b55eb 100644 --- a/src/codegen/types/interface-struct-generator.ts +++ b/src/codegen/types/interface-struct-generator.ts @@ -1,4 +1,4 @@ -import { InterfaceDeclaration, InterfaceField } from '../../ast/types.js'; +import { InterfaceDeclaration } from '../../ast/types.js'; import { tsTypeToLlvm } from '../infrastructure/type-system.js'; const BUILTIN_TYPES = [ @@ -107,7 +107,7 @@ export class InterfaceStructGenerator { const pFieldsLen = pFields.length; if (pFieldsLen === 0) continue; for (let j = 0; j < pFieldsLen; j++) { - const f = pFields[j] as InterfaceField; + const f = pFields[j] as { name: string; type: string }; let fieldName = f.name; if (fieldName.endsWith('?')) { fieldName = fieldName.slice(0, -1); @@ -131,7 +131,7 @@ export class InterfaceStructGenerator { } const fields = this.getInterfaceFields(idx); for (let i = 0; i < fields.length; i++) { - const f = fields[i] as InterfaceField; + const f = fields[i] as { name: string; type: string }; let fieldName = f.name; if (fieldName.endsWith('?')) { fieldName = fieldName.slice(0, -1); diff --git a/src/codegen/types/objects/class.ts b/src/codegen/types/objects/class.ts index 3ceb3aae..32500cbe 100644 --- a/src/codegen/types/objects/class.ts +++ b/src/codegen/types/objects/class.ts @@ -1,4 +1,4 @@ -import { Expression, ClassNode, ClassMethod, ClassField, VariableNode, InterfaceDeclaration, CommonField, InterfaceField } from '../../../ast/types.js'; +import { Expression, ClassNode, ClassMethod, ClassField, VariableNode, InterfaceDeclaration, CommonField } from '../../../ast/types.js'; import { IGeneratorContext } from '../../infrastructure/generator-context.js'; import { SymbolKind, createObjectMetadata, createObjectMetadataWithInterfaceAndPointerAlloca, createClassMetadata } from '../../infrastructure/symbol-table.js'; import { stripOptional, tsTypeToLlvm } from '../../infrastructure/type-system.js'; @@ -1076,7 +1076,7 @@ export class ClassGenerator { const types: string[] = []; const tsTypes: string[] = []; for (let fi = 0; fi < interfaceDef.fields.length; fi++) { - const f = interfaceDef.fields[fi] as InterfaceField; + const f = interfaceDef.fields[fi] as { name: string; type: string }; keys.push(stripOptional(f.name)); types.push(this.fieldTypeToLlvm(f.type)); tsTypes.push(f.type); @@ -1132,7 +1132,7 @@ export class ClassGenerator { const types: string[] = []; const tsTypes: string[] = []; for (let fi = 0; fi < inlineFields.length; fi++) { - const f = inlineFields[fi] as InterfaceField; + const f = inlineFields[fi] as { name: string; type: string }; keys.push(stripOptional(f.name)); types.push(this.fieldTypeToLlvm(f.type)); tsTypes.push(f.type); @@ -1228,13 +1228,13 @@ export class ClassGenerator { const commonFields: CommonField[] = []; for (let fi = 0; fi < firstFields.length; fi++) { - const field = firstFields[fi] as InterfaceField; + const field = firstFields[fi] as { name: string; type: string }; let isCommon = true; for (let ii = 0; ii < interfaces.length; ii++) { const ifaceTyped = interfaces[ii] as { name: string; extends: string[]; fields: { name: string; type: string }[]; methods: { name: string }[] }; let found = false; for (let fj = 0; fj < ifaceTyped.fields.length; fj++) { - const f = ifaceTyped.fields[fj] as InterfaceField; + const f = ifaceTyped.fields[fj] as { name: string; type: string }; if (f.name === field.name && this.areTypesCompatible(f.type, field.type)) { found = true; break; diff --git a/src/codegen/types/objects/object.ts b/src/codegen/types/objects/object.ts index 621462e0..65e44e95 100644 --- a/src/codegen/types/objects/object.ts +++ b/src/codegen/types/objects/object.ts @@ -1,4 +1,4 @@ -import { Expression, ObjectNode, ObjectProperty, InterfaceField } from '../../../ast/types.js'; +import { Expression, ObjectNode, ObjectProperty } from '../../../ast/types.js'; import { IGeneratorContext } from '../../infrastructure/generator-context.js'; import type { InterfaceStructGenerator } from '../interface-struct-generator.js'; import { tsTypeToLlvm } from '../../infrastructure/type-system.js'; @@ -88,7 +88,7 @@ export class ObjectGenerator { const orderedFields: { key: string; llvmType: string; value: string }[] = []; for (let fieldIdx = 0; fieldIdx < fields.length; fieldIdx++) { - const field = fields[fieldIdx] as InterfaceField; + const field = fields[fieldIdx] as { name: string; type: string }; const llvmType = this.tsTypeToLlvm(field.type); const valueExpr = propMap.get(field.name); let finalValue: string;