Skip to content

Commit

Permalink
Merge branch 'Shopify:main' into patch-1
Browse files Browse the repository at this point in the history
  • Loading branch information
bibstha authored Jun 7, 2024
2 parents c9075fd + 53cf57a commit b09351f
Show file tree
Hide file tree
Showing 181 changed files with 28,197 additions and 15,707 deletions.
2 changes: 1 addition & 1 deletion .github/CODEOWNERS
Validating CODEOWNERS rules …
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
# Request a review from @Shopify/ruby-dev-exp when a new PR is created
* @Shopify/ruby-dev-exp
* @Shopify/ruby-dx
2 changes: 2 additions & 0 deletions .github/dependabot.yml
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ updates:
- "patch"
exclude-patterns:
- "prism"
open-pull-requests-limit: 100
- package-ecosystem: "npm"
directory: "vscode/"
schedule:
Expand All @@ -29,6 +30,7 @@ updates:
update-types:
- "minor"
- "patch"
open-pull-requests-limit: 100
- package-ecosystem: "gitsubmodule"
directory: "/"
schedule:
Expand Down
47 changes: 47 additions & 0 deletions .github/workflows/auto_assign.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
name: Auto assign

on:
issues:
types: [opened]

jobs:
auto_assign:
runs-on: ubuntu-latest

steps:
- uses: actions/checkout@v4
name: Checkout

- name: Randomly assign reviewers to community issues
uses: actions/github-script@v7
with:
github-token: "${{ secrets.GITHUB_TOKEN }}"
script: |
const fullTeam = [
"andyw8",
"dirceu",
"paracycle",
"vinistock",
"rafaelfranca",
"Morriar",
"st0012",
"egiurleo",
"KaanOzkan"
];
const author = "${{ github.event.issue.user.login }}";
if (!fullTeam.includes(author)) {
const dxReviewers = [
"andyw8",
"vinistock",
"st0012",
];
const assignee = dxReviewers[Math.floor(Math.random() * dxReviewers.length)];
await github.rest.issues.addAssignees({
owner: context.repo.owner,
repo: context.repo.repo,
issue_number: ${{ github.event.issue.number }},
assignees: [assignee]
});
}
4 changes: 3 additions & 1 deletion .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ jobs:
fail-fast: false
matrix:
os: [ubuntu-latest, macos-latest, windows-latest]
ruby: ["3.0", "3.1", "3.2", "3.3"]
ruby: ["3.1", "3.2", "3.3"]
runs-on: ${{ matrix.os }}
timeout-minutes: 30
name: Ruby ${{ matrix.ruby }} on ${{ matrix.os }}
Expand Down Expand Up @@ -86,6 +86,8 @@ jobs:
# We need some Ruby installed for the environment activation tests
- name: Set up Ruby
uses: ruby/setup-ruby@v1
with:
bundler-cache: true

- name: Download shadowenv
if: matrix.os == 'ubuntu-latest' || matrix.os == 'macos-latest'
Expand Down
5 changes: 4 additions & 1 deletion .github/workflows/require_labels.yml
Original file line number Diff line number Diff line change
@@ -1,11 +1,14 @@
name: Pull Request Labels

on:
pull_request_review:
types: [submitted]
pull_request:
types: [opened, synchronize, reopened, labeled, unlabeled]
types: [labeled, unlabeled]

jobs:
check-labels:
if: github.event.review.state == 'APPROVED'
runs-on: ubuntu-latest
env:
GH_TOKEN: ${{ github.token }}
Expand Down
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -14,3 +14,4 @@ vscode/dist
vscode/node_modules
vscode/.vscode-test/
vscode/*.vsix
vscode/*.log
2 changes: 2 additions & 0 deletions .rubocop.yml
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ inherit_gem:

require:
- rubocop-sorbet
- rubocop-md
- rubocop-minitest
- rubocop-rake
- ./lib/rubocop/cop/ruby_lsp/use_language_server_aliases
Expand All @@ -15,6 +16,7 @@ AllCops:
- "sorbet/rbi/shims/**/*.rbi"
Exclude:
- "vendor/**/*"
- "vscode/**/*"
- "features/**/*"
- "test/fixtures/**/*"
- "test/expectations/**/*"
Expand Down
2 changes: 1 addition & 1 deletion .ruby-version
Original file line number Diff line number Diff line change
@@ -1 +1 @@
3.3.0
3.3.1
4 changes: 2 additions & 2 deletions .vscode/settings.json
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
{
// Set this value to `verbose` to see the full JSON content of LSP requests and responses
// Set this value to `messages` to see names of LSP requests and responses,
// or to `verbose` to see the full JSON content of LSP requests and responses
"ruby lsp.trace.server": "off",
"[ruby]": {
"editor.defaultFormatter": "Shopify.ruby-lsp"
Expand Down Expand Up @@ -44,5 +45,4 @@
]
}
],
"sorbet.highlightUntyped": "everywhere-but-tests"
}
109 changes: 71 additions & 38 deletions ADDONS.md
Original file line number Diff line number Diff line change
Expand Up @@ -60,20 +60,15 @@ require "ruby_lsp/addon"
module RubyLsp
module MyGem
class Addon < ::RubyLsp::Addon
extend T::Sig

# Performs any activation that needs to happen once when the language server is booted
sig { override.params(message_queue: Thread::Queue).void }
def activate(message_queue)
def activate(global_state, message_queue)
end

# Performs any cleanup when shutting down the server, like terminating a subprocess
sig { override.void }
def deactivate
end

# Returns the name of the addon
sig { override.returns(String) }
def name
"Ruby LSP My Gem"
end
Expand Down Expand Up @@ -136,40 +131,26 @@ following listener implementation.
module RubyLsp
module MyGem
class Addon < ::RubyLsp::Addon
extend T::Sig

sig { override.params(message_queue: Thread::Queue).void }
def activate(message_queue)
def activate(global_state, message_queue)
@message_queue = message_queue
@config = SomeConfiguration.new
end

sig { override.void }
def deactivate
end

sig { override.returns(String) }
def name
"Ruby LSP My Gem"
end

sig do
override.params(
response_builder: ResponseBuilders::Hover,
nesting: T::Array[String],
index: RubyIndexer::Index,
dispatcher: Prism::Dispatcher,
).void
end
def create_hover_listener(response_builder, nesting, index, dispatcher)
def create_hover_listener(response_builder, node_context, index, dispatcher)
# Use the listener factory methods to instantiate listeners with parameters sent by the LSP combined with any
# pre-computed information in the addon. These factory methods are invoked on every request
Hover.new(client, response_builder, @config, dispatcher)
end
end

class Hover
extend T::Sig

# The Requests::Support::Common module provides some helper methods you may find helpful.
include Requests::Support::Common

Expand All @@ -180,7 +161,6 @@ module RubyLsp
# to this object, which will then build the Ruby LSP's response.
# Additionally, listeners are instantiated with a message_queue to push notifications (not used in this example).
# See "Sending notifications to the client" for more information.
sig { params(client: RailsClient, response_builder: ResponseBuilders::Hover, config: SomeConfiguration, dispatcher: Prism::Dispatcher).void }
def initialize(client, response_builder, config, dispatcher)
super(dispatcher)

Expand All @@ -195,11 +175,11 @@ module RubyLsp

# Listeners must define methods for each event they registered with the dispatcher. In this case, we have to
# define `on_constant_read_node_enter` to specify what this listener should do every time we find a constant
sig { params(node: Prism::ConstantReadNode).void }
def on_constant_read_node_enter(node)
# Certain builders are made available to listeners to build LSP responses. The classes under `RubyLsp::ResponseBuilders`
# are used to build responses conforming to the LSP Specification.
# ResponseBuilders::Hover itself also requires a content category to be specified (title, links, or documentation).
# Certain builders are made available to listeners to build LSP responses. The classes under
# `RubyLsp::ResponseBuilders` are used to build responses conforming to the LSP Specification.
# ResponseBuilders::Hover itself also requires a content category to be specified (title, links,
# or documentation).
@response_builder.push("Hello!", category: :documentation)
end
end
Expand All @@ -222,15 +202,13 @@ class MyFormatterRubyLspAddon < RubyLsp::Addon
def activate(global_state, message_queue)
# The first argument is an identifier users can pick to select this formatter. To use this formatter, users must
# have rubyLsp.formatter configured to "my_formatter"
# The second argument is a singleton instance that implements the `FormatterRunner` interface (see below)
global_state.register_formatter("my_formatter", MyFormatterRunner.instance)
# The second argument is a class instance that implements the `FormatterRunner` interface (see below)
global_state.register_formatter("my_formatter", MyFormatterRunner.new)
end
end

# Custom formatter
class MyFormatter
# Make it a singleton class
include Singleton
# If using Sorbet to develop the addon, then include this interface to make sure the class is properly implemented
include RubyLsp::Requests::Support::Formatter

Expand Down Expand Up @@ -271,7 +249,7 @@ interested in using it.
module RubyLsp
module MyGem
class Addon < ::RubyLsp::Addon
def activate(message_queue)
def activate(global_state, message_queue)
@message_queue = message_queue
end

Expand All @@ -281,23 +259,78 @@ module RubyLsp
"Ruby LSP My Gem"
end

def create_hover_listener(response_builder, nesting, index, dispatcher)
MyHoverListener.new(@message_queue, response_builder, nesting, index, dispatcher)
def create_hover_listener(response_builder, node_context, index, dispatcher)
MyHoverListener.new(@message_queue, response_builder, node_context, index, dispatcher)
end
end

class MyHoverListener
def initialize(message_queue, response_builder, nesting, index, dispatcher)
def initialize(message_queue, response_builder, node_context, index, dispatcher)
@message_queue = message_queue

@message_queue << Notification.new(
message: "$/progress",
params: Interface::ProgressParams.new(
token: "progress-token-id",
value: Interface::WorkDoneProgressBegin.new(kind: "begin", title: "Starting slow work!"),
)
),
)
end
end
end
end
```

### Registering for file update events

By default, the Ruby LSP listens for changes to files ending in `.rb` to continuously update its index when Ruby source
code is modified. If your addon uses a tool that is configured through a file (like RuboCop and its `.rubocop.yml`)
you can register for changes to these files and react when the configuration changes.

**Note**: you will receive events from `ruby-lsp` and other addons as well, in addition to your own registered ones.


```ruby
module RubyLsp
module MyGem
class Addon < ::RubyLsp::Addon
def activate(global_state, message_queue)
register_additional_file_watchers(global_state, message_queue)
end

def deactivate; end

def register_additional_file_watchers(global_state, message_queue)
# Clients are not required to implement this capability
return unless global_state.supports_watching_files

message_queue << Request.new(
id: "ruby-lsp-my-gem-file-watcher",
method: "client/registerCapability",
params: Interface::RegistrationParams.new(
registrations: [
Interface::Registration.new(
id: "workspace/didChangeWatchedFilesMyGem",
method: "workspace/didChangeWatchedFiles",
register_options: Interface::DidChangeWatchedFilesRegistrationOptions.new(
watchers: [
Interface::FileSystemWatcher.new(
glob_pattern: "**/.my-config.yml",
kind: Constant::WatchKind::CREATE | Constant::WatchKind::CHANGE | Constant::WatchKind::DELETE,
),
],
),
),
],
),
)
end

def workspace_did_change_watched_files(changes)
if changes.any? { |change| change[:uri].end_with?(".my-config.yml") }
# Do something to reload the config here
end
end
end
end
end
Expand All @@ -316,7 +349,7 @@ require "ruby_lsp/check_docs"
# The second argument is the file list of GIF files with the demos of all listeners
RubyLsp::CheckDocs.new(
FileList["#{__dir__}/lib/ruby_lsp/ruby_lsp_rails/**/*.rb"],
FileList.new("#{__dir__}/misc/**/*.gif")
FileList.new("#{__dir__}/misc/**/*.gif"),
)
```

Expand Down
8 changes: 2 additions & 6 deletions CONTRIBUTING.md
Original file line number Diff line number Diff line change
Expand Up @@ -67,10 +67,8 @@ To add a new expectations test runner for a new request handler:
- Add a new file under `test/requests/MY_REQUEST_expectations_test.rb`

```ruby
# frozen_string_literal: true

require "test_helper"
require "expectations/expectations_test_runner"
require_relative "support/expectations_test_runner"

class MyRequestExpectationsTest < ExpectationsTestRunner
# The first argument is the fully qualified name of the request class
Expand All @@ -84,10 +82,8 @@ the base run and assert method to achieve the right behaviour. See `diagnostics_
example

```ruby
# frozen_string_literal: true

require "test_helper"
require "expectations/expectations_test_runner"
require_relative "support/expectations_test_runner"

class MyRequestExpectationsTest < ExpectationsTestRunner
expectations_tests RubyLsp::Requests::MyRequest, "my_request"
Expand Down
2 changes: 1 addition & 1 deletion DESIGN_AND_ROADMAP.md
Original file line number Diff line number Diff line change
Expand Up @@ -77,7 +77,7 @@ long term roadmap to see what’s planned
"".upcase
1.to_s
{}.merge!({ a: 1 })
[].concat([])
[].push(1)

## Scenarios where can assume the receiver type
class Foo
Expand Down
Loading

0 comments on commit b09351f

Please sign in to comment.