Skip to content

Commit

Permalink
Create RBSDocument (#2437)
Browse files Browse the repository at this point in the history
  • Loading branch information
vinistock authored Aug 15, 2024
1 parent a9b5515 commit e650df9
Show file tree
Hide file tree
Showing 6 changed files with 88 additions and 3 deletions.
1 change: 1 addition & 0 deletions lib/ruby_lsp/document.rb
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ class LanguageId < T::Enum
enums do
Ruby = new("ruby")
ERB = new("erb")
RBS = new("rbs")
end
end

Expand Down
1 change: 1 addition & 0 deletions lib/ruby_lsp/internal.rb
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@
require "ruby_lsp/document"
require "ruby_lsp/ruby_document"
require "ruby_lsp/erb_document"
require "ruby_lsp/rbs_document"
require "ruby_lsp/store"
require "ruby_lsp/addon"
require "ruby_lsp/requests/support/rubocop_runner"
Expand Down
41 changes: 41 additions & 0 deletions lib/ruby_lsp/rbs_document.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
# typed: strict
# frozen_string_literal: true

module RubyLsp
class RBSDocument < Document
extend T::Sig
extend T::Generic

ParseResultType = type_member { { fixed: T::Array[RBS::AST::Declarations::Base] } }

sig { params(source: String, version: Integer, uri: URI::Generic, encoding: Encoding).void }
def initialize(source:, version:, uri:, encoding: Encoding::UTF_8)
@syntax_error = T.let(false, T::Boolean)
super
end

sig { override.returns(ParseResultType) }
def parse
return @parse_result unless @needs_parsing

@needs_parsing = false

_, _, declarations = RBS::Parser.parse_signature(@source)
@syntax_error = false
@parse_result = declarations
rescue RBS::ParsingError
@syntax_error = true
@parse_result
end

sig { override.returns(T::Boolean) }
def syntax_error?
@syntax_error
end

sig { override.returns(LanguageId) }
def language_id
LanguageId::RBS
end
end
end
3 changes: 3 additions & 0 deletions lib/ruby_lsp/server.rb
Original file line number Diff line number Diff line change
Expand Up @@ -298,9 +298,12 @@ def text_document_did_open(message)
language_id = case text_document[:languageId]
when "erb", "eruby"
Document::LanguageId::ERB
when "rbs"
Document::LanguageId::RBS
else
Document::LanguageId::Ruby
end

@store.set(
uri: text_document[:uri],
source: text_document[:text],
Expand Down
10 changes: 7 additions & 3 deletions lib/ruby_lsp/store.rb
Original file line number Diff line number Diff line change
Expand Up @@ -44,8 +44,11 @@ def get(uri)
raise NonExistingDocumentError, uri.to_s unless path

ext = File.extname(path)
language_id = if ext == ".erb" || ext == ".rhtml"
language_id = case ext
when ".erb", ".rhtml"
Document::LanguageId::ERB
when ".rbs"
Document::LanguageId::RBS
else
Document::LanguageId::Ruby
end
Expand All @@ -66,13 +69,14 @@ def get(uri)
).void
end
def set(uri:, source:, version:, language_id:, encoding: Encoding::UTF_8)
document = case language_id
@state[uri.to_s] = case language_id
when Document::LanguageId::ERB
ERBDocument.new(source: source, version: version, uri: uri, encoding: encoding)
when Document::LanguageId::RBS
RBSDocument.new(source: source, version: version, uri: uri, encoding: encoding)
else
RubyDocument.new(source: source, version: version, uri: uri, encoding: encoding)
end
@state[uri.to_s] = document
end

sig { params(uri: URI::Generic, edits: T::Array[T::Hash[Symbol, T.untyped]], version: Integer).void }
Expand Down
35 changes: 35 additions & 0 deletions test/rbs_document_test.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
# typed: true
# frozen_string_literal: true

require "test_helper"

class RBSDocumentTest < Minitest::Test
def test_parse_result_is_array_of_declarations
document = RubyLsp::RBSDocument.new(source: <<~RBS, version: 1, uri: URI("file:///foo.rbs"))
class Foo
def bar: () -> void
end
RBS

refute_predicate(document, :syntax_error?)
assert_equal(:Foo, T.cast(document.parse_result[0], RBS::AST::Declarations::Class).name.name)
end

def test_parsing_remembers_syntax_errors
# The syntax error is that `-` should be `->`
document = RubyLsp::RBSDocument.new(source: +<<~RBS, version: 1, uri: URI("file:///foo.rbs"))
class Foo
def bar: () - void
end
RBS

assert_predicate(document, :syntax_error?)

document.push_edits(
[{ range: { start: { line: 1, character: 15 }, end: { line: 1, character: 15 } }, text: ">" }],
version: 2,
)
document.parse
refute_predicate(document, :syntax_error?)
end
end

0 comments on commit e650df9

Please sign in to comment.