Skip to content

9. 클래스 시스템: 인스턴스, 상속, 멤버 해석

'달빛 약속'의 클래스 기능은 단순 문법을 넘어서, 실행기와 스코프 시스템 위에서 동작하는 별도 런타임 계층을 가집니다. 이 문서는 클래스 관련 핵심 코드가 어디에 있고, 어떤 순서로 동작하는지 정리합니다.

핵심 파일

값 모델

클래스 관련 런타임 값은 세 가지로 분리됩니다.

  • ClassValue: 클래스 정의 본문(Block), 선언 시점 Scope, 부모 클래스 정보를 보관합니다.
  • InstanceValue: 실제 인스턴스입니다. 멤버 조회 기준 스코프(memberLookupRootScope)와 현재 실행 스코프를 가집니다.
  • SuperValue: 상위 접근 전용 래퍼 값입니다. 부모 쪽 스코프 체인으로 멤버 해석을 시작할 때 사용합니다.

이 타입들은 /core/node/class/core.ts에 정의되어 있습니다.

클래스 선언 흐름

클래스 선언 노드(DeclareClass)는 실행 시 다음을 수행합니다.

  1. 이름 충돌 검증 (hasExistingClassNameConflict)
  2. 중복 멤버 메서드 이름 검증
  3. 부모 클래스 해석 및 타입 검증
  4. ClassValue 생성 후 현재 스코프에 등록

유효성 검사(validate) 단계에서는 검증용 더미 클래스/인스턴스를 만들어 클래스 본문을 사전 점검합니다. 이 과정에서 중복 생성자 arity, 멤버 이름 충돌도 함께 잡아냅니다.

인스턴스 생성 흐름

인스턴스 생성 노드(NewInstance)는 다음 순서로 동작합니다.

  1. 클래스 이름이 실제 ClassValue인지 확인
  2. 상속 체인 기반으로 레이어 스코프 생성
  3. 각 클래스 본문을 부모부터 실행해 필드/메서드 구성
  4. 인자 개수(arity)로 __준비__ 선택
  5. 선택된 생성자가 있으면 실행, 없으면 그대로 인스턴스 반환

생성자 선택 규칙은 /core/node/class/new-instance-constructor.ts에 있습니다.

  • 같은 클래스 레이어에서 같은 arity 생성자가 여러 개면 ambiguous 오류
  • 어떤 생성자도 없으면 none으로 처리되어 생성 인자는 무시
  • 생성자는 있지만 전달 arity가 안 맞으면 mismatch 오류

멤버 해석 규칙

멤버 접근/호출은 member-runtime 유틸로 공통 처리됩니다.

  • 점(.) 접근 대상은 InstanceValue 또는 SuperValue만 허용됩니다.
  • 멤버 변수 조회는 현재 레이어에서 memberLookupRootScope까지 체인을 타고 탐색합니다.
  • 멤버 메서드도 같은 체인에서 탐색합니다.
  • 전역 변수/전역 함수로 폴백하지 않습니다.

FetchMember는 변수 조회 실패 시 무인자 멤버 메서드 자동 호출을 시도합니다. 둘 다 없으면 MemberNotFoundError를 발생시킵니다.

검증 단계의 멤버 분석

클래스는 실행 전에 멤버 접근 오류를 최대한 잡기 위해 보수적 분석을 수행합니다.

  • createValidationInstanceFromClass: 상속 체인 스코프를 구성하고, 본문에서 확정적으로 쓰이는 멤버를 미리 시드(seed)합니다.
  • collectLikelyMemberNamesInClass: 조건문/루프 내부의 자신.멤버/상위.멤버 할당 흔적까지 모아 "멤버 후보" 집합을 만듭니다.

이 덕분에, 실제 실행 전에 o.없는멤버 같은 실수를 상당수 검출하면서도 상속/분기 문맥에서의 오탐을 줄입니다.

파서 진입점

클래스 헤더 파싱은 /core/prepare/parse/dynamicRule/functions/declare-rule/class-header.ts에서 처리합니다.

  • 클래스, A
  • 클래스, B(부모)
  • 클래스, C, 부모

세 형태를 모두 지원하며, 부모 지정 문법 오류는 UnexpectedTokenError/UnexpectedEndOfCodeError로 보고됩니다.