Узлы AST: типы и поля

AST (Abstract Syntax Tree) в SWC представляет собой строго типизированную и иерархическую структуру, отражающую синтаксис JavaScript/TypeScript после парсинга исходного кода. Узлы AST формируются на основе спецификации ECMAScript и расширяются собственными типами SWC для поддержки современных возможностей языка и трансформаций.

Каждый узел AST в SWC имеет фиксированный набор полей, обеспечивающих идентификацию типа конструкции, её позицию в исходном коде, а также внутренние метаданные, используемые при трансформациях и генерации кода.


Базовая структура узла

Практически все узлы AST в SWC содержат общий набор полей, определяемых через базовые интерфейсы:

Поле type

Ключевое поле, определяющее разновидность узла.

  • Строковое значение
  • Используется для дискриминации типов в union-структурах
  • Пример: “BinaryExpression”, “FunctionDeclaration”, “Identifier”

Поле span

Описание позиции узла в исходном коде.

Содержит:

  • start: начальная позиция
  • end: конечная позиция
  • ctxt: контекст (используется для внутренних целей компилятора)

Это поле критично для:

  • source maps
  • диагностики ошибок
  • точных трансформаций кода

Поле comments

Необязательное поле, содержащее привязанные комментарии.

  • leading: комментарии перед узлом
  • trailing: комментарии после узла
  • inner: комментарии внутри конструкции

Узлы верхнего уровня

Program

Корневой узел AST.

Содержит:

  • body: массив инструкций верхнего уровня
  • shebang: строка shebang (если присутствует)
  • span: диапазон всего файла

Применяется как контейнер для модулей и скриптов.


Module

Представляет ES Module.

Поля:

  • body: список ModuleItem
  • span: границы модуля
  • type: всегда “Module”

ModuleItem включает:

  • объявления (ModuleDecl)
  • экспортированные элементы
  • импортированные зависимости

Узлы объявлений

VariableDeclaration

Описывает объявление переменной.

Основные поля:

  • kind: “var” | “let” | “const”
  • decls: массив VariableDeclarator
  • span

VariableDeclarator

Один элемент объявления.

Содержит:

  • id: паттерн (Identifier или Object/Array pattern)
  • init: выражение инициализации (может быть null)
  • span

FunctionDeclaration

Функция в декларативной форме.

Поля:

  • identifier: имя функции
  • params: список параметров
  • body: блок инструкций
  • generator: признак генератора
  • async: асинхронная функция
  • span

ClassDeclaration

Объявление класса.

Содержит:

  • identifier: имя класса
  • class: структура Class
  • span

Узлы выражений

Identifier

Базовый узел идентификатора.

Поля:

  • value: имя переменной
  • optional: флаг optional chaining контекста
  • span

Используется практически во всех синтаксических конструкциях.


Literal выражения

StringLiteral

  • value: строка
  • raw: исходное представление
  • span

NumericLiteral

  • value: число
  • raw: строковое представление

BooleanLiteral

  • value: true | false

NullLiteral

Не содержит дополнительных полей, кроме span.


BinaryExpression

Бинарные операции.

Поля:

  • left: левый операнд
  • operator: строка оператора (+, -, *, /, ==, и др.)
  • right: правый операнд
  • span

CallExpression

Вызов функции.

Содержит:

  • callee: вызываемое выражение
  • arguments: массив аргументов
  • typeArguments: generics (для TypeScript)
  • span

MemberExpression

Доступ к свойству объекта.

Поля:

  • object: объект
  • property: свойство
  • computed: доступ через []
  • optional: optional chaining (?.)

Узлы операторов управления

IfStatement

Условная конструкция.

Поля:

  • test: условие
  • consequent: блок при истинном условии
  • alternate: блок else (может отсутствовать)
  • span

ForStatement

Цикл for.

Поля:

  • init: инициализация
  • test: условие
  • update: обновление
  • body: тело цикла

WhileStatement

Цикл while.

  • test: условие
  • body: тело

ReturnStatement

Возврат значения из функции.

  • argument: возвращаемое выражение (может быть null)

Узлы блоков и областей видимости

BlockStatement

Блок кода.

Содержит:

  • stmts: массив инструкций
  • span

Используется в функциях, циклах, условных конструкциях.


Script (в старых режимах)

Аналог Module, используется для non-module контекста.


Узлы TypeScript-расширений

SWC поддерживает расширения TypeScript через дополнительные AST-узлы.

TSInterfaceDeclaration

Интерфейс.

Поля:

  • id: имя интерфейса
  • body: описание свойств
  • typeParams: generics

TSTypeAnnotation

Аннотация типа.

  • typeAnnotation: выражение типа

TSTypeReference

Ссылка на тип.

  • typeName: идентификатор типа
  • typeParams: параметры типа

Узлы шаблонов и литералов

TemplateLiteral

Шаблонные строки.

Поля:

  • quasis: статические части
  • expressions: вставляемые выражения

TaggedTemplateExpression

Шаблон с тегом.

  • tag: функция-обработчик
  • template: TemplateLiteral

Паттерны (Patterns)

Используются в деструктуризации и объявлениях.

ObjectPattern

  • properties: список свойств

ArrayPattern

  • elements: элементы массива

RestElement

  • argument: остаточный элемент (…rest)

Общие принципы организации полей AST

Иммутабельность структуры

AST-узлы SWC проектируются как неизменяемые структуры. Трансформации создают новые узлы, а не модифицируют существующие.


Дискриминированные union-типы

Поле type используется для строгой типизации:

  • ускоряет сопоставление
  • упрощает трансформации
  • снижает необходимость runtime-типизации

Композиция узлов

Большинство сложных конструкций строится из базовых:

  • выражения
  • идентификаторы
  • блоки
  • декларации

Это обеспечивает единообразие структуры и предсказуемость трансформаций.


Связь с позициями исходного кода

Поле span присутствует практически в каждом узле, обеспечивая:

  • восстановление оригинального кода
  • точное отображение ошибок
  • генерацию source maps
  • поддержку tooling (lint, format, transform pipelines)

Взаимосвязь типов узлов

AST SWC формирует строгую иерархию:

  • Program / Module

    • ModuleItem

      • Statement

      • ModuleDeclaration

        • Import / Export

        • Declaration

          • Function / Class / Variable
      • ExpressionStatement

        • Expression

          • Call / Binary / Member / Literal

Эта структура обеспечивает предсказуемую навигацию по дереву и упрощает реализацию трансформационных проходов (passes), используемых в компиляции и оптимизации кода.