파서 `<` 처리 작업 기록

이 작업은 어렵진 않았는데, 그래도 기억할 게 있어서 기록하기로 했다.

처음엔 매우 간단한 작업 같았다. 문제가 되는 테스트케이스는 다음과 같다.

declare let fn: any, x: any, y: any;
declare function z<A, B>(_: any): any;
fn(z<Number, Object>(y));
fn((z<Number, Object> = y));
fn(x < y, x > y);
fn(x < y, x >= y);
fn(x < y, x >> y);
fn(x < y, (x >>= y));
fn(x < y, (x >>>= y));
fn(x < y, x < y, (x >>= y));
fn(x < y, x < y, x >>> y);
fn(x < y, x < y, (x >>>= y));

딱 봐도 짜증나는 종류긴하다. 그래도 시간 좀 들이면 해결되는 종류의 이슈다.

테스트 추가하고 가장 먼저 실패하는, 즉 가장 위에 있는 버그를 고쳤다. 그런데 테스트케이스의 나머지 코드를 보니까, 파싱 자체가 실패하는 게 문제가 아니고, 잘못된 값으로 파싱하는 게 문제더라. 그래서 테스트 파일을 쪼갰다. 1개의 파일은 1개의 줄만 갖고 있도록 쪼개니까 작업하기 편해졌다.

보니까 type 컨텍스트에서 <>을 무지성으로 <>로 렉싱하는 게 문제였다. 그래서 해당 코드를 없앴다. 그랬는데 Regression이 많더라. 처음엔 >=, >>=, >>>=만 배제하면 되나 싶어서 그걸 배제하도록 짰는데, 타입스크립트는 만만하지 않았다. 디버깅하다가 이게 컨텍스트로 해결해야하는 문제임을 깨닫고 Context를 손보기 시작했다. 우선 Context 기반으로 분기하는 코드를 넣었다. 로깅 계속 추가해가면서 문제되는 Context들을 하나씩 손봤고, 해결됐다.

앞에서 얘기한 기억해둬야하는 건 말로 어떻게 표현해야할지 모르곘으니 적지 않곘다.