rucoa 0.4.0 → 0.6.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.rubocop.yml +3 -0
- data/Gemfile +1 -0
- data/Gemfile.lock +12 -2
- data/README.md +47 -17
- data/data/definitions_ruby_3_1 +0 -0
- data/images/diagnostics.gif +0 -0
- data/images/document-formatting.gif +0 -0
- data/images/document-symbol.gif +0 -0
- data/images/selection-ranges.gif +0 -0
- data/lib/rucoa/cli.rb +3 -2
- data/lib/rucoa/configuration.rb +111 -32
- data/lib/rucoa/definition_archiver.rb +29 -0
- data/lib/rucoa/definition_builders/rbs_constant_definition_builder.rb +44 -0
- data/lib/rucoa/definition_builders/rbs_method_definition_builder.rb +106 -0
- data/lib/rucoa/definition_builders/yard_method_definition_builder.rb +218 -0
- data/lib/rucoa/definition_builders.rb +9 -0
- data/lib/rucoa/definition_store.rb +63 -0
- data/lib/rucoa/definitions/base.rb +12 -0
- data/lib/rucoa/definitions/constant_definition.rb +51 -0
- data/lib/rucoa/definitions/method_definition.rb +126 -0
- data/lib/rucoa/definitions/method_parameter_definition.rb +30 -0
- data/lib/rucoa/definitions.rb +9 -0
- data/lib/rucoa/handlers/base.rb +8 -0
- data/lib/rucoa/handlers/exit_handler.rb +11 -0
- data/lib/rucoa/handlers/initialize_handler.rb +13 -0
- data/lib/rucoa/handlers/initialized_handler.rb +10 -0
- data/lib/rucoa/handlers/shutdown_handler.rb +12 -0
- data/lib/rucoa/handlers/text_document_completion_handler.rb +216 -0
- data/lib/rucoa/handlers/text_document_did_change_handler.rb +1 -20
- data/lib/rucoa/handlers/text_document_did_open_handler.rb +11 -4
- data/lib/rucoa/handlers/text_document_document_symbol_handler.rb +5 -4
- data/lib/rucoa/handlers/text_document_hover_handler.rb +76 -0
- data/lib/rucoa/handlers/text_document_range_formatting_handler.rb +1 -1
- data/lib/rucoa/handlers/text_document_selection_range_handler.rb +3 -3
- data/lib/rucoa/handlers/text_document_signature_help_handler.rb +68 -0
- data/lib/rucoa/handlers.rb +5 -0
- data/lib/rucoa/node_inspector.rb +111 -0
- data/lib/rucoa/nodes/base.rb +30 -0
- data/lib/rucoa/nodes/def_node.rb +59 -0
- data/lib/rucoa/nodes/lvar_node.rb +25 -0
- data/lib/rucoa/nodes/send_node.rb +43 -0
- data/lib/rucoa/nodes.rb +1 -0
- data/lib/rucoa/parser_builder.rb +1 -0
- data/lib/rucoa/position.rb +14 -3
- data/lib/rucoa/range.rb +64 -14
- data/lib/rucoa/rbs_document_loader.rb +43 -0
- data/lib/rucoa/rubocop_autocorrector.rb +1 -1
- data/lib/rucoa/rubocop_investigator.rb +1 -1
- data/lib/rucoa/server.rb +63 -13
- data/lib/rucoa/source.rb +59 -4
- data/lib/rucoa/source_store.rb +6 -10
- data/lib/rucoa/types/method_type.rb +23 -0
- data/lib/rucoa/types.rb +7 -0
- data/lib/rucoa/version.rb +1 -1
- data/lib/rucoa/yard_glob_document_loader.rb +47 -0
- data/lib/rucoa/yard_string_document_loader.rb +70 -0
- data/lib/rucoa.rb +9 -0
- data/rucoa.gemspec +2 -0
- metadata +58 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: f31a0a81d1013267e3bfc0358911e1306e22f0b34f40249604050914da18d8f4
|
4
|
+
data.tar.gz: b999e9fe78ee1dbb0b11662756c84399b474fb8522476429c90becb454fb0fd1
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 1af0f2fed0d7d7930f69768234263e77707f1f22d80e93392ae126c0cfa72d11b3356de6ba5c6f3476ff7b3f27239c1667ac1c2442e9e12301bdadb0a25fec47
|
7
|
+
data.tar.gz: bdd44ba9cb0284a16589798ec20ee7d9e9bf01989e054108859f3f8286a3f6382a45d84be056dd7a755de8b14d4cf9e28610652489e8e57f9c009b1f81c7f432
|
data/.rubocop.yml
CHANGED
data/Gemfile
CHANGED
data/Gemfile.lock
CHANGED
@@ -1,9 +1,11 @@
|
|
1
1
|
PATH
|
2
2
|
remote: .
|
3
3
|
specs:
|
4
|
-
rucoa (0.
|
4
|
+
rucoa (0.6.0)
|
5
5
|
parser
|
6
|
+
rbs
|
6
7
|
rubocop
|
8
|
+
yard
|
7
9
|
|
8
10
|
GEM
|
9
11
|
remote: https://rubygems.org/
|
@@ -16,6 +18,7 @@ GEM
|
|
16
18
|
ast (~> 2.4.1)
|
17
19
|
rainbow (3.1.1)
|
18
20
|
rake (13.0.6)
|
21
|
+
rbs (2.6.0)
|
19
22
|
regexp_parser (2.5.0)
|
20
23
|
rexml (3.2.5)
|
21
24
|
rspec (3.11.0)
|
@@ -51,9 +54,15 @@ GEM
|
|
51
54
|
rubocop-rspec (2.12.1)
|
52
55
|
rubocop (~> 1.31)
|
53
56
|
ruby-progressbar (1.11.0)
|
54
|
-
sevencop (0.
|
57
|
+
sevencop (0.10.0)
|
55
58
|
rubocop
|
56
59
|
unicode-display_width (2.2.0)
|
60
|
+
webrick (1.7.0)
|
61
|
+
yard (0.9.28)
|
62
|
+
webrick (~> 1.7.0)
|
63
|
+
yardspec (0.2.0)
|
64
|
+
rspec
|
65
|
+
yard
|
57
66
|
|
58
67
|
PLATFORMS
|
59
68
|
x86_64-linux
|
@@ -67,6 +76,7 @@ DEPENDENCIES
|
|
67
76
|
rubocop-rspec
|
68
77
|
rucoa!
|
69
78
|
sevencop
|
79
|
+
yardspec
|
70
80
|
|
71
81
|
BUNDLED WITH
|
72
82
|
2.3.21
|
data/README.md
CHANGED
@@ -15,15 +15,6 @@ To install rucoa gem, if your project is managed by bundler, add to your Gemfile
|
|
15
15
|
gem 'rucoa'
|
16
16
|
```
|
17
17
|
|
18
|
-
or in Rails application, we'll recommend you to do like this:
|
19
|
-
|
20
|
-
```ruby
|
21
|
-
# Gemfile
|
22
|
-
group :development do
|
23
|
-
gem 'rucoa', require: false
|
24
|
-
end
|
25
|
-
```
|
26
|
-
|
27
18
|
If bundler is not being used to manage dependencies, simply install the gem:
|
28
19
|
|
29
20
|
```bash
|
@@ -32,16 +23,55 @@ gem install rucoa
|
|
32
23
|
|
33
24
|
## Features
|
34
25
|
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
26
|
+
### Diagnostics
|
27
|
+
|
28
|
+
Displays RuboCop offenses and provides Quick Fix action for autocorrection.
|
29
|
+
|
30
|
+
![demo](images/diagnostics.gif)
|
31
|
+
|
32
|
+
### Formatting
|
33
|
+
|
34
|
+
Run "Format Document" command or enable "Format On Save" in the settings to autocorrect RuboCop offenses.
|
35
|
+
|
36
|
+
![demo](images/document-formatting.gif)
|
37
|
+
|
38
|
+
### Selection
|
39
|
+
|
40
|
+
Run "Expand Selection" command to select appropriate ranges.
|
41
|
+
|
42
|
+
![demo](images/selection-ranges.gif)
|
43
|
+
|
44
|
+
### Symbol
|
45
|
+
|
46
|
+
See Outline section in the explorer panel to see document symbols in the current file, or run "Go to Symbol" command to search for symbols.
|
47
|
+
|
48
|
+
This extension supports the folowiing types of symbols:
|
49
|
+
|
50
|
+
- class
|
51
|
+
- module
|
52
|
+
- constant
|
53
|
+
- instance method
|
54
|
+
- singleton method (a.k.a. class method)
|
55
|
+
- attribute (attr_accessor, attr_reader, and attr_writer)
|
56
|
+
|
57
|
+
![demo](images/document-symbol.gif)
|
58
|
+
|
59
|
+
## Experimental features
|
60
|
+
|
61
|
+
### Completion
|
62
|
+
|
63
|
+
Provides completion items for constant names and method names.
|
64
|
+
|
65
|
+
### Hover
|
66
|
+
|
67
|
+
Shows documentation for the symbol under the cursor.
|
68
|
+
|
69
|
+
### Signature help
|
70
|
+
|
71
|
+
Shows method signature help when you start to type method arguments like `"100".to_i(`.
|
40
72
|
|
41
|
-
|
73
|
+
## Coming soon
|
42
74
|
|
43
|
-
- Completion
|
44
|
-
- Documentation
|
45
75
|
- Go to Definition
|
46
76
|
- Highlight
|
47
77
|
- Semantic Tokens
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
data/lib/rucoa/cli.rb
CHANGED
data/lib/rucoa/configuration.rb
CHANGED
@@ -2,57 +2,114 @@
|
|
2
2
|
|
3
3
|
module Rucoa
|
4
4
|
class Configuration
|
5
|
-
DEFAULT_SETTINGS = {
|
6
|
-
'base' => {
|
7
|
-
'enable' => 'auto',
|
8
|
-
'useBundler' => 'auto'
|
9
|
-
},
|
10
|
-
'feature' => {
|
11
|
-
'codeAction' => {
|
12
|
-
'enable' => true
|
13
|
-
},
|
14
|
-
'diagnostics' => {
|
15
|
-
'enable' => true
|
16
|
-
},
|
17
|
-
'documentSymbol' => {
|
18
|
-
'enable' => true
|
19
|
-
},
|
20
|
-
'formatting' => {
|
21
|
-
'enable' => true
|
22
|
-
},
|
23
|
-
'selectionRange' => {
|
24
|
-
'enable' => true
|
25
|
-
}
|
26
|
-
}
|
27
|
-
}.freeze
|
28
|
-
|
29
5
|
def initialize
|
30
|
-
|
6
|
+
@settings = {}
|
7
|
+
end
|
8
|
+
|
9
|
+
# @return [void]
|
10
|
+
def disable_code_action
|
11
|
+
disable_feature('codeAction')
|
12
|
+
end
|
13
|
+
|
14
|
+
# @return [void]
|
15
|
+
def disable_completion
|
16
|
+
disable_feature('completion')
|
17
|
+
end
|
18
|
+
|
19
|
+
# @return [void]
|
20
|
+
def disable_diagnostics
|
21
|
+
disable_feature('diagnostics')
|
22
|
+
end
|
23
|
+
|
24
|
+
# @return [void]
|
25
|
+
def disable_document_symbol
|
26
|
+
disable_feature('documentSymbol')
|
27
|
+
end
|
28
|
+
|
29
|
+
# @return [void]
|
30
|
+
def disable_formatting
|
31
|
+
disable_feature('formatting')
|
32
|
+
end
|
33
|
+
|
34
|
+
# @return [void]
|
35
|
+
def disable_hover
|
36
|
+
disable_feature('hover')
|
37
|
+
end
|
38
|
+
|
39
|
+
# @return [void]
|
40
|
+
def disable_selection_range
|
41
|
+
disable_feature('selectionRange')
|
42
|
+
end
|
43
|
+
|
44
|
+
# @return [void]
|
45
|
+
def disable_signature_help
|
46
|
+
disable_feature('signatureHelp')
|
47
|
+
end
|
48
|
+
|
49
|
+
# @return [void]
|
50
|
+
def enable_debug
|
51
|
+
@settings ||= {}
|
52
|
+
@settings['base'] ||= {}
|
53
|
+
@settings['base']['debug'] = true
|
31
54
|
end
|
32
55
|
|
33
56
|
# @return [Boolean]
|
57
|
+
# @example returns false if the configuration is empty
|
58
|
+
# configuration = Rucoa::Configuration.new
|
59
|
+
# expect(configuration).not_to be_enables_debug
|
60
|
+
# @example returns true if the configuration enables debug
|
61
|
+
# configuration = Rucoa::Configuration.new
|
62
|
+
# configuration.update('base' => { 'debug' => true })
|
63
|
+
# expect(configuration).to be_enables_debug
|
64
|
+
def enables_debug?
|
65
|
+
fetch('base', 'debug', default: false)
|
66
|
+
end
|
67
|
+
|
68
|
+
# @return [Boolean]
|
69
|
+
# @example returns true if the configuration is empty
|
70
|
+
# configuration = Rucoa::Configuration.new
|
71
|
+
# expect(configuration).to be_enables_code_action
|
72
|
+
# @example returns false if the configuration disables code action
|
73
|
+
# configuration = Rucoa::Configuration.new
|
74
|
+
# configuration.disable_code_action
|
75
|
+
# expect(configuration).not_to be_enables_code_action
|
34
76
|
def enables_code_action?
|
35
|
-
|
77
|
+
enables_feature?('codeAction')
|
78
|
+
end
|
79
|
+
|
80
|
+
# @return [Boolean]
|
81
|
+
def enables_completion?
|
82
|
+
enables_feature?('completion')
|
36
83
|
end
|
37
84
|
|
38
85
|
# @return [Boolean]
|
39
86
|
def enables_diagnostics?
|
40
|
-
|
87
|
+
enables_feature?('diagnostics')
|
41
88
|
end
|
42
89
|
|
43
90
|
# @return [Boolean]
|
44
91
|
def enables_document_symbol?
|
45
|
-
|
92
|
+
enables_feature?('documentSymbol')
|
46
93
|
end
|
47
94
|
|
48
95
|
# @return [Boolean]
|
49
96
|
def enables_formatting?
|
50
|
-
|
97
|
+
enables_feature?('formatting')
|
98
|
+
end
|
99
|
+
|
100
|
+
# @return [Boolean]
|
101
|
+
def enables_hover?
|
102
|
+
enables_feature?('hover')
|
51
103
|
end
|
52
104
|
|
53
105
|
# @return [Boolean]
|
54
106
|
def enables_selection_range?
|
55
|
-
|
107
|
+
enables_feature?('selectionRange')
|
108
|
+
end
|
109
|
+
|
110
|
+
# @return [Boolean]
|
111
|
+
def enables_signature_help?
|
112
|
+
enables_feature?('signatureHelp')
|
56
113
|
end
|
57
114
|
|
58
115
|
# @param settings [Hash]
|
@@ -63,9 +120,31 @@ module Rucoa
|
|
63
120
|
|
64
121
|
private
|
65
122
|
|
123
|
+
# @param feature [String]
|
66
124
|
# @return [void]
|
67
|
-
def
|
68
|
-
@settings
|
125
|
+
def disable_feature(feature)
|
126
|
+
@settings ||= {}
|
127
|
+
@settings['feature'] ||= {}
|
128
|
+
@settings['feature'][feature] ||= {}
|
129
|
+
@settings['feature'][feature]['enable'] = false
|
130
|
+
end
|
131
|
+
|
132
|
+
# @param feature [String]
|
133
|
+
# @return [Boolean]
|
134
|
+
def enables_feature?(feature)
|
135
|
+
fetch('feature', feature, 'enable', default: true)
|
136
|
+
end
|
137
|
+
|
138
|
+
# @param keys [Array<String>]
|
139
|
+
# @param default [Object]
|
140
|
+
# @return [Object]
|
141
|
+
def fetch(*keys, default:)
|
142
|
+
value = @settings.dig(*keys)
|
143
|
+
if value.nil?
|
144
|
+
default
|
145
|
+
else
|
146
|
+
value
|
147
|
+
end
|
69
148
|
end
|
70
149
|
end
|
71
150
|
end
|
@@ -0,0 +1,29 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'pathname'
|
4
|
+
|
5
|
+
module Rucoa
|
6
|
+
class DefinitionArchiver
|
7
|
+
RUBY_DEFINITIONS_DUMP_PATH = ::File.expand_path('../../data/definitions_ruby_3_1', __dir__).freeze
|
8
|
+
private_constant :RUBY_DEFINITIONS_DUMP_PATH
|
9
|
+
|
10
|
+
class << self
|
11
|
+
# @param definitions [Array<Rucoa::Definition::Base>]
|
12
|
+
# @return [void]
|
13
|
+
def dump(definitions)
|
14
|
+
pathname = ::Pathname.new(RUBY_DEFINITIONS_DUMP_PATH)
|
15
|
+
pathname.parent.mkpath
|
16
|
+
pathname.write(
|
17
|
+
::Marshal.dump(definitions)
|
18
|
+
)
|
19
|
+
end
|
20
|
+
|
21
|
+
# @return [Array<Rucoa::Definition::Base>]
|
22
|
+
def load
|
23
|
+
::Marshal.load(
|
24
|
+
::File.binread(RUBY_DEFINITIONS_DUMP_PATH)
|
25
|
+
)
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
@@ -0,0 +1,44 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Rucoa
|
4
|
+
module DefinitionBuilders
|
5
|
+
# Build Rucoa contant definition from RBS constant declaration.
|
6
|
+
class RbsConstantDefinitionBuilder
|
7
|
+
class << self
|
8
|
+
# @param declaration [RBS::AST::Declarations::Constant]
|
9
|
+
# @return [Rucoa::Definitions::ConstantDefinition]
|
10
|
+
def call(declaration:)
|
11
|
+
new(
|
12
|
+
declaration: declaration
|
13
|
+
).call
|
14
|
+
end
|
15
|
+
end
|
16
|
+
|
17
|
+
# @param declaration [RBS::AST::Declarations::Constant]
|
18
|
+
# @return [Rucoa::Definitions::ConstantDefinition]
|
19
|
+
def initialize(declaration:)
|
20
|
+
@declaration = declaration
|
21
|
+
end
|
22
|
+
|
23
|
+
# @return [Rucoa::Definitions::ConstantDefinition]
|
24
|
+
def call
|
25
|
+
::Rucoa::Definitions::ConstantDefinition.new(
|
26
|
+
full_qualified_name: full_qualified_name,
|
27
|
+
source_path: source_path
|
28
|
+
)
|
29
|
+
end
|
30
|
+
|
31
|
+
private
|
32
|
+
|
33
|
+
# @return [String]
|
34
|
+
def full_qualified_name
|
35
|
+
@declaration.name.to_s.delete_prefix('::')
|
36
|
+
end
|
37
|
+
|
38
|
+
# @return [String]
|
39
|
+
def source_path
|
40
|
+
@declaration.location.name
|
41
|
+
end
|
42
|
+
end
|
43
|
+
end
|
44
|
+
end
|
@@ -0,0 +1,106 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'rbs'
|
4
|
+
|
5
|
+
module Rucoa
|
6
|
+
module DefinitionBuilders
|
7
|
+
# Build Rucoa method definition from RBS method definition.
|
8
|
+
class RbsMethodDefinitionBuilder
|
9
|
+
class << self
|
10
|
+
# @param declaration [RBS::AST::Declarations::Class, RBS::AST::Declarations::Module]
|
11
|
+
# @param method_definition [RBS::AST::Members::MethodDefinition]
|
12
|
+
# @return [Rucoa::Definitions::MethodDefinition]
|
13
|
+
def call(declaration:, method_definition:)
|
14
|
+
new(
|
15
|
+
declaration: declaration,
|
16
|
+
method_definition: method_definition
|
17
|
+
).call
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
21
|
+
# @param declaration [RBS::AST::Declarations::Class, RBS::AST::Declarations::Module]
|
22
|
+
# @param method_definition [RBS::AST::Members::MethodDefinition]
|
23
|
+
def initialize(declaration:, method_definition:)
|
24
|
+
@declaration = declaration
|
25
|
+
@method_definition = method_definition
|
26
|
+
end
|
27
|
+
|
28
|
+
# @return [Rucoa::Definitions::MethodDefinition]
|
29
|
+
def call
|
30
|
+
Definitions::MethodDefinition.new(
|
31
|
+
description: description,
|
32
|
+
kind: kind,
|
33
|
+
method_name: method_name,
|
34
|
+
namespace: namespace,
|
35
|
+
source_path: source_path,
|
36
|
+
types: types
|
37
|
+
)
|
38
|
+
end
|
39
|
+
|
40
|
+
private
|
41
|
+
|
42
|
+
# @return [Array<Rucoa::Types::MethodType>]
|
43
|
+
def types
|
44
|
+
@method_definition.types.map do |method_type|
|
45
|
+
RbsMethodTypeToRucoaMethodTypeMapper.call(
|
46
|
+
method_type: method_type
|
47
|
+
)
|
48
|
+
end
|
49
|
+
end
|
50
|
+
|
51
|
+
# @return [String, nil]
|
52
|
+
def description
|
53
|
+
@method_definition.comment&.string&.sub(/\A\s*<!--.*-->\s*/m, '')
|
54
|
+
end
|
55
|
+
|
56
|
+
# @return [String]
|
57
|
+
def namespace
|
58
|
+
@declaration.name.to_s.delete_prefix('::')
|
59
|
+
end
|
60
|
+
|
61
|
+
# @return [String]
|
62
|
+
def method_name
|
63
|
+
@method_definition.name.to_s
|
64
|
+
end
|
65
|
+
|
66
|
+
# @return [Symbol]
|
67
|
+
def kind
|
68
|
+
@method_definition.kind
|
69
|
+
end
|
70
|
+
|
71
|
+
# @return [String]
|
72
|
+
def source_path
|
73
|
+
@declaration.location.name
|
74
|
+
end
|
75
|
+
|
76
|
+
class RbsMethodTypeToRucoaMethodTypeMapper
|
77
|
+
class << self
|
78
|
+
# @param method_type [RBS::Types::MethodType]
|
79
|
+
# @return [Rucoa::Types::MethodType]
|
80
|
+
def call(method_type:)
|
81
|
+
new(method_type: method_type).call
|
82
|
+
end
|
83
|
+
|
84
|
+
# @param type [RBS::Types::Base]
|
85
|
+
# @return [String]
|
86
|
+
def stringify(type)
|
87
|
+
type.to_s.delete_prefix('::')
|
88
|
+
end
|
89
|
+
end
|
90
|
+
|
91
|
+
# @param method_type [RBS::Types::MethodType]
|
92
|
+
def initialize(method_type:)
|
93
|
+
@method_type = method_type
|
94
|
+
end
|
95
|
+
|
96
|
+
# @return [Rucoa::Types::MethodType]
|
97
|
+
def call
|
98
|
+
Types::MethodType.new(
|
99
|
+
parameters_string: @method_type.type.param_to_s,
|
100
|
+
return_type: self.class.stringify(@method_type.type.return_type)
|
101
|
+
)
|
102
|
+
end
|
103
|
+
end
|
104
|
+
end
|
105
|
+
end
|
106
|
+
end
|