refactor: eliminate 4 as any casts in extraction.ts
CI / lint (push) Successful in 9m56s
CI / build (push) Failing after 5m35s
CI / unit (18) (push) Has been skipped
CI / unit (20) (push) Has been skipped
CI / unit (22) (push) Has been skipped
CI / e2e (push) Has been skipped

- Added 'contain' field to FastExtractedElement.style interface, removing
  (s as any).contain property smuggling (line 682)
- Replaced (assertion as any) duck-typing in getSelectorsFromAssertion
  with instanceof FluentRelation/FluentQuantifier/FluentAssertion checks
- Replaced (assertion as any) duck-typing in buildFluentLabel with
  same instanceof pattern
- Structural baseline ratcheted: asAny 101→98, nullishZero 62→61
This commit is contained in:
John Dvorak
2026-05-22 16:57:19 -07:00
parent 2bdda12030
commit 4142027f9b
2 changed files with 32 additions and 36 deletions
+30 -34
View File
@@ -404,6 +404,7 @@ export async function extractWorldFastGeometry(
overflowY: string overflowY: string
visibility: string visibility: string
pointerEvents: string pointerEvents: string
contain: string
opacity: number opacity: number
zIndex: string zIndex: string
lineHeight: number lineHeight: number
@@ -679,7 +680,7 @@ export async function extractWorldFastGeometry(
zIndexKind.push(s.zIndex === 'auto' ? 0 : 1) zIndexKind.push(s.zIndex === 'auto' ? 0 : 1)
zIndexValue.push(s.zIndex === 'auto' ? 0 : Number.parseInt(s.zIndex, 10) || 0) zIndexValue.push(s.zIndex === 'auto' ? 0 : Number.parseInt(s.zIndex, 10) || 0)
opacity.push(s.opacity) opacity.push(s.opacity)
const csContain = (s as any).contain const csContain = s.contain
let flags = 0 let flags = 0
if (typeof csContain === 'string') { if (typeof csContain === 'string') {
for (const part of csContain.split(/\s+/)) { for (const part of csContain.split(/\s+/)) {
@@ -1451,34 +1452,33 @@ export function compileCanonicalClauseToFormula(clause: CanonicalClauseDescripto
export function getSelectorsFromAssertion(assertion: FluentRelation | FluentAssertion | FluentQuantifier): string[] { export function getSelectorsFromAssertion(assertion: FluentRelation | FluentAssertion | FluentQuantifier): string[] {
const selectors = new Set<string>() const selectors = new Set<string>()
const rel = assertion as any
if (rel.assertion?.getSubject) { if (assertion instanceof FluentRelation) {
selectors.add(rel.assertion.getSubject()) selectors.add(assertion.assertion.getSubject())
} if (assertion.referenceSelector) {
if (rel.referenceSelector) { selectors.add(assertion.referenceSelector)
selectors.add(rel.referenceSelector) }
} if (assertion.isCompound) {
// Extract selectors from compound relation parts (.and / .or chaining) for (const part of assertion.compoundParts) {
const compoundRel = assertion as FluentRelation if (part.referenceSelector) {
if (compoundRel.isCompound) { selectors.add(part.referenceSelector)
for (const part of compoundRel.compoundParts) { }
if (part.referenceSelector) {
selectors.add(part.referenceSelector)
} }
} }
} } else if (assertion instanceof FluentQuantifier) {
if (Array.isArray(rel.bindings)) { for (const b of assertion.bindings) {
for (const b of rel.bindings) { if (b.selector) selectors.add(b.selector)
if (b?.selector) selectors.add(b.selector) if (typeof b.getAssertions === 'function') {
// Extract reference selectors from assertions inside FluentQuantifier bindings for (const inner of b.getAssertions()) {
if (typeof b?.getAssertions === 'function') { if (inner?.reference?.value) {
for (const assertion of b.getAssertions()) { selectors.add(inner.reference.value)
if (assertion?.reference?.value) {
selectors.add(assertion.reference.value)
} }
} }
} }
} }
} else {
// FluentAssertion
selectors.add(assertion.getSubject())
} }
return Array.from(selectors) return Array.from(selectors)
} }
@@ -1518,21 +1518,17 @@ export function getSelectorsFromFormula(formula: FormulaNode): string[] {
// --------------------------------------------------------------------------- // ---------------------------------------------------------------------------
export function buildFluentLabel(assertion: FluentRelation | FluentAssertion | FluentQuantifier): string { export function buildFluentLabel(assertion: FluentRelation | FluentAssertion | FluentQuantifier): string {
const rel = assertion as any if (assertion instanceof FluentQuantifier) {
const firstBinding = assertion.bindings[0]
// FluentQuantifier
if (rel.bindings && Array.isArray(rel.bindings)) {
const firstBinding = rel.bindings[0]
const selector = firstBinding?.selector || 'unknown' const selector = firstBinding?.selector || 'unknown'
return `quantified assertion over '${selector}'` return `quantified assertion over '${selector}'`
} }
// FluentRelation if (assertion instanceof FluentRelation) {
if (rel.relation && rel.assertion?.getSubject) { const subject = assertion.assertion.getSubject()
const subject = rel.assertion.getSubject() const ref = assertion.referenceSelector || ''
const ref = rel.referenceSelector || '' const opts = assertion.options || {}
const opts = rel.options || {} const parts: string[] = [`'${subject}' ${assertion.relation}`]
const parts: string[] = [`'${subject}' ${rel.relation}`]
if (ref) parts.push(`'${ref}'`) if (ref) parts.push(`'${ref}'`)
if (opts.minGap !== undefined) parts.push(`gap ${opts.minGap}px`) if (opts.minGap !== undefined) parts.push(`gap ${opts.minGap}px`)
if (opts.maxGap !== undefined) parts.push(`maxGap ${opts.maxGap}px`) if (opts.maxGap !== undefined) parts.push(`maxGap ${opts.maxGap}px`)
+2 -2
View File
@@ -1,5 +1,5 @@
{ {
"asAny": 101, "asAny": 98,
"emptyCatch": 17, "emptyCatch": 17,
"nullishZero": 62 "nullishZero": 61
} }