已开启
修复 checkCallExpression 调用链中 node.parent 及关联空指针崩溃 #1
liyancheng创建于  9月12日
liyancheng成员
9月12日 创建

问题概述

大型多模块 ArkTS 工程执行 CompileArkTS 任务时,ets-loader 内置的 TypeScript 检查器间歇性崩溃,hvigor 仅报 Error Code: 00308018 Unknown Error,不输出任何文件位置与真实诊断信息,构建直接失败。

根因

runArkPack(@ohos/hvigor-arkts-compose)创建的合成 CallExpression 节点无 parent 指针,流入检查器时重载解析失败展开诊断路径直接访问 node.parent.kind 崩溃。

崩溃链路

runArkPack
  -> getResolvedSignature
    -> resolveSignature -> resolveCallExpression -> resolveCall
      -> chooseOverload -> getSignatureApplicabilityError
        -> checkExpressionWithContextualType -> checkExpression -> checkCallExpression  <-- 崩溃

修复内容(13 处)

node.parent 判空(7 处)

  • checkCallExpression ESSymbolLike 路径: node.parent ? walkUp(...) : node
  • checkCallExpression assertion 路径: node.parent?.kind
  • checkCallExpression ETS 组件检查: 改用安全变体 isInEtsFile
  • getContextualType: 前置 if (!parent) return undefined
  • getThisArgumentType: isOptionalChainRoot(node.parent) 提取判空
  • getEffectsSignature: node.parent?.kind
  • checkConstEnumAccess: 4 处 parent?.kind
  • utilities.ts isInETSFile: ?.scriptKind

关联空指针崩溃(6 处)

  • isExtendedByInterface: node.parent.parent 判空滞后, 改为 ?.parent
  • getTypeOfNode: getDeclaredTypeOfSymbol(getSymbolOfNode(node)) 未判空, 对齐 46238 行
  • getEffectiveDecoratorArguments: parent/symbol 判空
  • resolveAnnotation: identType.symbol.flags 在 errorType 上崩溃
  • annotationHasDefaultValue 等: node.annotationDeclaration!.members 改为 ?.
  • getReturnTypeOfSignature: signature.declaration! 改为 declaration ? ... : errorType

修复原则

所有修复对正常 AST 节点行为完全不变(parser/binder 保证 parent/symbol 有值,可选链/early-return 不触发),仅将异常节点的崩溃改为优雅降级。

关联提交

验证

  • 构建通过: npm run build:compiler + npm run build:tests
  • 崩溃场景验证: 合成 CallExpression 调 getResolvedSignature() 不再崩溃
  • 行为保持验证: assertion 收窄、Symbol() 唯一类型、const enum 访问、optional chain、泛型推断均不变

知识库

已在 docs/knowledge/type-checker-and-compat.md 补充约束、检查清单、崩溃场景文档。

回归测试

tests/cases/compiler/checkCallExpressionParentNullGuard.ts

likedislike