Ruby LSP 애드온 시스템 소개

An Introduction to the Ruby LSP Add-on System | Rails at Scale

3줄 요약

  • Ruby LSP는 동적 특성과 DSL로 인한 코드 분석의 한계를 극복하기 위해 애드온 시스템을 도입했습니다.
  • 이 시스템은 다른 젬들이 Ruby LSP에 자신들의 DSL 처리 방법을 가르치고, 정적 분석의 한계를 넘는 기능을 추가할 수 있게 합니다.
  • 애드온은 개발 경험 향상, 반복 작업 감소, 리소스 효율성 증대에 기여하며, Rails, Standard 등 다양한 사례를 통해 효과가 입증되었습니다.

Ruby LSP(Language Server Protocol)는 Ruby 코드 작성을 간소화하는 언어 서버 구현체입니다. 정적 분석을 활용하여 에디터 기능을 제공하지만, Ruby 생태계, 특히 Rails에서 흔히 사용되는 동적 프로그래밍 및 DSL(Domain-Specific Language)은 정적 분석만으로는 완벽하게 처리하기 어렵습니다. 각 젬이 고유의 DSL을 정의할 수 있기에, 모든 DSL에 대한 처리를 Ruby LSP 자체에 내장하는 것은 비현실적이며 성능 및 정확성 저하를 야기할 수 있습니다. 또한, 여러 언어 서버를 사용하는 방식은 반복적인 작업, 리소스 낭비, 복잡한 설정 등의 단점을 가집니다. 이러한 문제를 해결하고, Ruby LSP가 다양한 DSL을 이해하며 정적 분석의 한계를 넘어설 수 있도록 **Ruby LSP 애드온 시스템**이 도입되었습니다.

Ruby LSP 애드온 시스템은 개발자가 Ruby LSP의 기능을 확장하고 향상시킬 수 있도록 설계되었습니다. 애드온은 RubyLsp::Addon 클래스를 상속하는 Ruby 클래스로 작성되며, 특정 명명 규칙을 따르면 Ruby LSP 서버에 의해 자동으로 로드됩니다. 애드온은 Ruby의 빠르고 현대적인 파서인 Prism을 기반으로 작동하며, Prism의 디스패처와 옵저버 패턴을 활용하여 AST(추상 구문 트리)를 한 번만 순회하며 효율적으로 이벤트를 처리합니다. 애드온은 global_state 객체를 통해 코드베이스의 인덱스, 설정 등 공유 정보에 접근할 수 있으며, message_queue를 통해 에디터와 통신할 수 있습니다.

애드온은 다양한 기능을 향상시킬 수 있는 풍부한 API를 제공합니다. 예를 들어, 코드렌즈(CodeLens), 자동 완성(Completion), 정의 이동(Definition), 문서 심볼(DocumentSymbol), 호버(Hover) 등의 LSP 요청에 대한 응답을 보강할 수 있습니다. 특히, 메타 프로그래밍으로 생성되어 정적 분석으로는 파악하기 어려운 선언(declarations)이나 호출 시점 DSL(call-site DSLs)을 인덱스에 추가하여 ‘정의 이동’과 같은 기능을 지원하는 인덱싱 향상이 가능합니다. 이를 통해 belongs_to와 같이 동적으로 정의되는 메소드도 에디터에서 인식하고 탐색할 수 있게 됩니다.

애드온 시스템의 효과는 실제 사례를 통해 입증되었습니다. Ruby LSP Rails 애드온은 Shopify에서 개발되었으며, 호버 시 데이터베이스 스키마 정보 표시, 연관 관계 및 콜백 정의 이동, 선언적 테스트 실행 코드렌즈 등 Rails 개발에 특화된 기능을 제공합니다. 특히 개발 중인 Rails 앱과 직접 통신하여 컨트롤러 액션에서 해당 라우트로 이동하는 것과 같이 정적 분석만으로는 불가능한 기능도 구현했습니다. 또 다른 사례인 Standard는 기존의 독립적인 LSP 서버에서 Ruby LSP 애드온으로 전환하여, 중복 구현 없이 Standard의 린팅 및 포매팅 기능을 Ruby LSP에 통합했습니다. 이 외에도 rspec, reek, rubyfmt 등 다양한 젬들이 애드온 형태로 기능을 제공하고 있습니다. 현재 애드온은 서버 측 기능 확장만 지원하며, 에디터 UI 요소 추가는 각 에디터의 API가 다르므로 지원하지 않습니다.

결론적으로, Ruby LSP 애드온 시스템은 Ruby의 동적 특성과 다양한 DSL로 인해 발생하는 코드 분석 및 에디터 도구 통합의 어려움을 효과적으로 해결하는 혁신적인 접근 방식입니다. 다른 젬들이 Ruby LSP에 쉽게 통합되어 특정 라이브러리나 프레임워크에 특화된 기능을 제공할 수 있게 함으로써, 반복적인 LSP 서버 구현 노력과 리소스 낭비를 줄이고 개발 경험을 크게 향상시킵니다. Shopify는 Ruby LSP가 강력한 언어 서버를 넘어 풍부한 애드온 생태계를 가진 플랫폼으로 발전하기를 기대하고 있으며, 더 많은 젬들이 애드온을 포함하여 배포되기를 장려합니다. 커뮤니티의 참여를 통해 API를 안정화하고, 최종적으로는 사용자가 별도의 설정 없이도 애드온의 혜택을 누릴 수 있도록 하는 것이 목표입니다. Ruby LSP 문서와 Slack 채널을 통해 애드온 개발에 참여하고 Ruby 개발 경험을 함께 개선해 나갈 수 있습니다.