[TS] 컴파일러 구조

  • 컴파일러는 하나의 프로그램으로 이를 구현한 소스 파일이 존재한다. 타입스크립트 공식 깃허브에는 compiler라는 별도의 폴더로 구성된 타입스크립트 컴파일가 있다.
  • 해당 폴더는 타입스크립트 컴파일러가 동작하는 데 중요한 몇 가지 구성 요소를 가지고 있다. 주요 구성 요소로는 스캐너, 파서, 바인더, 체커, 이미터가 있다.
  • 타입스크립트 컴파일러는 다섯 단계를 거쳐 타입 검사와 자바스크립트 소스 변환을 수행한다.

Program

  • 타입스크립트 컴파일러는 tsc 명령어로 실행된다. 컴파일러는 tsconfig.json에 명시된 컴파일 옵션을 기반으로 컴파일을 수행한다.
  • 가장 먼저 전체적인 컴파일 과정을 관리하는 프로그램 객체(인스턴스)가 생성된다. 이 객체는 컴파일할 소스 파일과 소스 파일 내에서 임포트된 파일을 불러온다. 가장 최초로 불러온 파일을 기준으로 컴파일 과정이 시작된다.

Scanner

  • 스캐너는 타입스크립트 소스 파일을 어휘적 분석을 통해 토큰을 생성하는 역할을 한다. 소스코드를 작은 단위로 나누어 의미 있는 토큰으로 변환하는 작업을 수행한다.
  • 타입스크립트 소스의 최소 단위인 토큰에 대한 리스트는 타입스크립트 레포SyntaxKind 변수를 통해 확인할 수 있다.
const a = 1;

/*
    Scan results
    - ConstKeyword
    - WhitespaceTrivia
    - Identifier
    - WhitespaceTrivia
    - EqualsToken
    - WhitespaceTrivia
    - NumericLiteral
    - SemicolonToken
    - EndOfFileToken
*/
  • 파서가 재스캔을 수행한다고 한다.

Parser

  • 파서는 생성된 토큰 목록을 활용하여 구문적 분석을 수행해 AST를 생성한다. AST는 소스코드의 구조를 트리 자료구조로 표현한다. AST의 최상위 노드는 타입스크립트 소스 파일이며, 최하위 노드는 파일의 끝 지점(EndOfFileToken)으로 구성된다.
  • 각각의 노드는 코드상의 위치, 구문 종류, 코드 내용과 같은 정보를 가지고 있다. 예를 들어 () 에 해당하는 토큰이 있을 때 파서가 AST를 생성하는 과정에서 이 토큰이 실질적으로 함수의 호출인지, 함수의 인자인지 또는 그룹 연산자인지가 결정된다.

스크린샷 2025-02-01 오후 3.37.45.png

Binder

  • 바인더의 주요 역할은 체커 단계에서 타입 검사를 할 수 있도록 기반을 마련하는 것이다.
  • 타입 검사를 위해 심볼이라는 데이터 구조를 생성한다. 심볼은 이전 단계의 AST에서 선언된 타입의 노드 정보를 저장한다. 심볼의 일부 구성 요소로는 flag , escapeName , declarations 가 있다.
  • flag 는 AST에서 선언된 타입의 노드 정보를 저장하는 식별자이다. declarations 는 AST 노드의 배열 형태를 보인다. 결과적으로 바인더는 심볼을 생성하고 해당 심볼과 그에 대응하는 AST 노드를 연결하는 역할을 수행한다.
export interface Symbol {
  flags: SymbolFlags;
  escapeName: string;
  declarations?: Declaration[];
}

Checker

  • 체커는 파서가 생성한 AST와 바인더가 생성한 심볼을 활용하여 타입 검사를 수행한다. AST 노드를 탐색하면서 심볼 정보를 불러와 주어진 소스 파일에 대해 타입 검사를 진행하는 것이다.
  • 체커의 타입 검사는 다음 컴파일 단계인 이미터에서 실행된다. checker.ts의 getDiagnostics() 함수를 사용해서 타입을 검증하고 타입 에러에 대한 정보를 보여줄 에러 메시지를 저장한다.

Emitter

  • 이미터는 타입스크립트 소스 파일을 변환하는 역할을 한다. 타입스크립트 소스를 자바스크립트 파일과 타입 선언 파일(d.ts)로 생성한다.
  • 타입스크립트 소스 파일을 변환하는 과정에서 개발자가 설정한 타입스크립트 설정 파일을 읽어오고, 체커를 통해 코드에 대한 타입 검증 정보를 가져온다. 그리고 emitter.ts의 emitFiles() 함수를 사용하여 소스 변환을 진행한다.

'TypeScript' 카테고리의 다른 글

[TS] DetailedHTMLProps, ComponentPropsWithoutRef  (0) 2025.02.11
[TS] Superstruct  (0) 2025.02.04
[TS] 런타임과 컴파일  (0) 2025.01.31
[TS] Record 원시 타입 키 개선  (1) 2025.01.30
[TS] 불변 객체 타입  (0) 2025.01.29