OSSCA Chromium

기여 목록 / 8505879

Remove jsdoc-migration suppressions from HeapProfileView

DevToolsrefactordevtools/devtools-frontendMerged

panels/profiler/HeapProfileView.ts에 남아 있던 crbug.com/1172300 주석 7건을 제거한 컨트리뷰션입니다. 직접 찾은 이슈입니다.

문제 설명

5건은 SamplingHeapProfileNode 생성자의 fallback에 있었습니다.

const callFrame = node.callFrame || ({
  // @ts-expect-error
  functionName: node['functionName'],
  // @ts-expect-error
  scriptId: node['scriptId'],
  ...
} as Protocol.Runtime.CallFrame);
  • node는 Protocol.HeapProfiler.SamplingHeapProfileNode이고 해당 필드들이 타입에 없음
    • callFrame / selfSize / id / children 만 선언됨
  • 나머지 2건은 SamplingHeapProfileModel.modules
    • Protocol.HeapProfiler.SamplingHeapProfile에 modules가 없어 any + as any 로 처리되어 있었음

해결 내용

구 포맷 노드 형태를 지역 인터페이스로 기술하고 캐스팅 1회로 읽게 했습니다.

interface LegacyFlatSamplingHeapProfileNode {
  functionName: string;
  scriptId: Protocol.Runtime.ScriptId;   // branded 타입이라 string 으로는 불가
  url: string;
  lineNumber: number;
  columnNumber: number;
}

const legacyNode = node as unknown as LegacyFlatSamplingHeapProfileNode;
const callFrame = node.callFrame || {
  functionName: legacyNode.functionName,
  ...
};
  • 리터럴이 자체로 Protocol.Runtime.CallFrame을 만족해 기존 as 단언도 불필요해짐
  • modules는 타입을 주는 대신 필드를 삭제
    • 처음에는 Protocol.Memory.Module[]로 지정했으나, 리뷰에서 Simon Zünd 님이 "진짜 미사용이면 이 CL 에서 그냥 지우자" 고 함
    • 전수 조사 결과 할당부 외에 참조가 없었음. 이를 쓰던 native memory view 가 2020년에 제거된 상태
    • 커밋 메시지에 미사용으로 보인다는 점을 먼저 적어둔 것이 리뷰 왕복을 줄였음

건드리지 않은 것

  • node.callFrame || ... fallback
    • WritableProfileHeader가 사용자가 import한 .heapprofile을 검증 없이 파싱하므로 런타임 도달 가능
  • lineNumber - 1 / columnNumber - 1
    • 구 포맷이 1-based, Protocol.Runtime.CallFrame이 0-based라 변환 역할

테스트 방법

  1. panels/profiler:unittests 빌드
  2. HeapProfileView.test.ts → 6/6 통과
  3. npm run check-gn -- --all 로 의존성 변화 없음 확인
  4. 동작 변경 없음 (타입 선언과 캐스팅에 한정)

배운 점

  • union 과 교차 타입으로는 해결되지 않음
    • union 은 프로퍼티 접근이 모든 멤버에 존재해야 하고, node.callFrame 의 truthiness 는 node 를 좁히지 않음
    • & Partial<CallFrame> 는 possibly undefined 가 떠서 non-null 단언 5개로 바뀔 뿐
    • 지역 인터페이스 + 캐스팅 1회가 가장 작은 해법이었음
  • 억제가 가리던 게 "타입 누락" 이 아니라 문서화되지 않은 구 포맷 호환 경로 였음
    • 지우는 게 아니라 그 형태를 타입으로 적어두는 것이 정답

참고 자료

  • third_party/devtools-frontend/src/front_end/panels/profiler/HeapProfileView.ts
  • third_party/devtools-frontend/src/front_end/core/sdk/HeapProfilerModel.ts

리뷰 대응

  • Simon Zünd 님, Wolfgang Beyer 님 +1 후 두 분 CQ+2 로 머지
  • Simon 님이 modules 에 대해 "진짜 미사용이면 이 CL 에서 그냥 지우자" 고 함
    • 타입 지정에서 필드 삭제로 변경. 코드가 바뀌므로 Code-Review 표 2개가 리셋됨
    • Simon 님이 1분 만에 재승인
  • 미해결 코멘트가 머지를 막고 있었음
    • No-Unresolved-Comments 요건이 UNSATISFIED 면 CQ+2 를 받아도 CV 가 시작되지 않음
    • 답변만으로는 해결되지 않고 unresolved: false 가 필요하며, 부모 코멘트와 같은 패치셋에 달아야 함
    • 이를 해소한 직후 Wolfgang 님 +1 과 CQ+2 가 바로 붙음
  • 커밋 메시지 줄바꿈을 72자로 맞춤 (Chromium 제한)