rucoa 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +7 -0
- data/.rspec +3 -0
- data/.rubocop.yml +32 -0
- data/CODE_OF_CONDUCT.md +84 -0
- data/Gemfile +12 -0
- data/Gemfile.lock +69 -0
- data/LICENSE.txt +21 -0
- data/README.md +44 -0
- data/Rakefile +12 -0
- data/exe/rucoa +6 -0
- data/lib/rucoa/cli.rb +24 -0
- data/lib/rucoa/diagnostic_provider.rb +112 -0
- data/lib/rucoa/errors.rb +20 -0
- data/lib/rucoa/message_reader.rb +27 -0
- data/lib/rucoa/message_writer.rb +37 -0
- data/lib/rucoa/nodes/base.rb +113 -0
- data/lib/rucoa/nodes/str_node.rb +8 -0
- data/lib/rucoa/nodes.rb +8 -0
- data/lib/rucoa/parser.rb +41 -0
- data/lib/rucoa/parser_builder.rb +28 -0
- data/lib/rucoa/position.rb +55 -0
- data/lib/rucoa/range.rb +57 -0
- data/lib/rucoa/rubocop_runner.rb +47 -0
- data/lib/rucoa/selection_range_provider.rb +97 -0
- data/lib/rucoa/server.rb +132 -0
- data/lib/rucoa/source.rb +40 -0
- data/lib/rucoa/source_store.rb +38 -0
- data/lib/rucoa/version.rb +5 -0
- data/lib/rucoa.rb +21 -0
- data/rucoa.gemspec +32 -0
- metadata +105 -0
data/lib/rucoa/parser.rb
ADDED
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require 'parser/current'
|
|
4
|
+
|
|
5
|
+
module Rucoa
|
|
6
|
+
# Parses Ruby text code.
|
|
7
|
+
class Parser
|
|
8
|
+
class << self
|
|
9
|
+
# @param text [String]
|
|
10
|
+
# @return [Rucoa::Nodes::Base]
|
|
11
|
+
def call(text)
|
|
12
|
+
new(text).call
|
|
13
|
+
end
|
|
14
|
+
end
|
|
15
|
+
|
|
16
|
+
# @param text [String]
|
|
17
|
+
def initialize(text)
|
|
18
|
+
@text = text
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
# @return [Rucoa::Nodes::Base]
|
|
22
|
+
def call
|
|
23
|
+
parser.parse(
|
|
24
|
+
::Parser::Source::Buffer.new(
|
|
25
|
+
'',
|
|
26
|
+
source: @text
|
|
27
|
+
)
|
|
28
|
+
)
|
|
29
|
+
end
|
|
30
|
+
|
|
31
|
+
private
|
|
32
|
+
|
|
33
|
+
# @return [Parser::Base]
|
|
34
|
+
def parser
|
|
35
|
+
parser = ::Parser::CurrentRuby.new(ParserBuilder.new)
|
|
36
|
+
parser.diagnostics.all_errors_are_fatal = true
|
|
37
|
+
parser.diagnostics.ignore_warnings = true
|
|
38
|
+
parser
|
|
39
|
+
end
|
|
40
|
+
end
|
|
41
|
+
end
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require 'parser/current'
|
|
4
|
+
|
|
5
|
+
module Rucoa
|
|
6
|
+
class ParserBuilder < ::Parser::Builders::Default
|
|
7
|
+
NODE_CLASS_BY_TYPE = {
|
|
8
|
+
str: Nodes::StrNode
|
|
9
|
+
}.freeze
|
|
10
|
+
|
|
11
|
+
# @note Override.
|
|
12
|
+
def n(type, children, source_map)
|
|
13
|
+
node_class_for(type).new(
|
|
14
|
+
type,
|
|
15
|
+
children,
|
|
16
|
+
location: source_map
|
|
17
|
+
)
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
private
|
|
21
|
+
|
|
22
|
+
# @param type [Symbol]
|
|
23
|
+
# @return [Class]
|
|
24
|
+
def node_class_for(type)
|
|
25
|
+
NODE_CLASS_BY_TYPE.fetch(type, Nodes::Base)
|
|
26
|
+
end
|
|
27
|
+
end
|
|
28
|
+
end
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Rucoa
|
|
4
|
+
class Position
|
|
5
|
+
class << self
|
|
6
|
+
# @param range [Parser::Source::Range]
|
|
7
|
+
# @return [Rucoa::Position]
|
|
8
|
+
def from_parser_range_beginning(range)
|
|
9
|
+
new(
|
|
10
|
+
column: range.column,
|
|
11
|
+
line: range.line
|
|
12
|
+
)
|
|
13
|
+
end
|
|
14
|
+
|
|
15
|
+
# @param range [Parser::Source::Range]
|
|
16
|
+
# @return [Rucoa::Position]
|
|
17
|
+
def from_parser_range_ending(range)
|
|
18
|
+
new(
|
|
19
|
+
column: range.last_column,
|
|
20
|
+
line: range.last_line
|
|
21
|
+
)
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
# @param hash [Hash{Symbol => Integer}]
|
|
25
|
+
# @return [Rucoa::Position]
|
|
26
|
+
def from_vscode_position(hash)
|
|
27
|
+
new(
|
|
28
|
+
column: hash['character'],
|
|
29
|
+
line: hash['line'] + 1
|
|
30
|
+
)
|
|
31
|
+
end
|
|
32
|
+
end
|
|
33
|
+
|
|
34
|
+
# @return [Integer]
|
|
35
|
+
attr_reader :column
|
|
36
|
+
|
|
37
|
+
# @return [Integer]
|
|
38
|
+
attr_reader :line
|
|
39
|
+
|
|
40
|
+
# @param column [Integer] 0-origin column number
|
|
41
|
+
# @param line [Integer] 1-origin line number
|
|
42
|
+
def initialize(column:, line:)
|
|
43
|
+
@column = column
|
|
44
|
+
@line = line
|
|
45
|
+
end
|
|
46
|
+
|
|
47
|
+
# @return [Hash]
|
|
48
|
+
def to_vscode_position
|
|
49
|
+
{
|
|
50
|
+
character: @column,
|
|
51
|
+
line: @line - 1
|
|
52
|
+
}
|
|
53
|
+
end
|
|
54
|
+
end
|
|
55
|
+
end
|
data/lib/rucoa/range.rb
ADDED
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Rucoa
|
|
4
|
+
class Range
|
|
5
|
+
class << self
|
|
6
|
+
# @param range [Parser::Source::Range]
|
|
7
|
+
# @return [Rucoa::Range]
|
|
8
|
+
def from_parser_range(range)
|
|
9
|
+
new(
|
|
10
|
+
Position.from_parser_range_beginning(range.begin),
|
|
11
|
+
Position.from_parser_range_beginning(range.end)
|
|
12
|
+
)
|
|
13
|
+
end
|
|
14
|
+
|
|
15
|
+
# @param offense [RuboCop::Cop::Offense]
|
|
16
|
+
# @return [Rucoa::Range]
|
|
17
|
+
def from_rubocop_offense(offense)
|
|
18
|
+
new(
|
|
19
|
+
Position.from_parser_range_beginning(offense.location),
|
|
20
|
+
Position.from_parser_range_ending(offense.location)
|
|
21
|
+
)
|
|
22
|
+
end
|
|
23
|
+
end
|
|
24
|
+
|
|
25
|
+
# @param beginning [Rucoa::Position]
|
|
26
|
+
# @param ending [Ruoca::Position]
|
|
27
|
+
def initialize(beginning, ending)
|
|
28
|
+
@beginning = beginning
|
|
29
|
+
@ending = ending
|
|
30
|
+
end
|
|
31
|
+
|
|
32
|
+
# @param position [Rucoa::Position]
|
|
33
|
+
# @return [Boolean]
|
|
34
|
+
def include?(position)
|
|
35
|
+
!exclude?(position)
|
|
36
|
+
end
|
|
37
|
+
|
|
38
|
+
# @return [Hash]
|
|
39
|
+
def to_vscode_range
|
|
40
|
+
{
|
|
41
|
+
end: @ending.to_vscode_position,
|
|
42
|
+
start: @beginning.to_vscode_position
|
|
43
|
+
}
|
|
44
|
+
end
|
|
45
|
+
|
|
46
|
+
private
|
|
47
|
+
|
|
48
|
+
# @param position [Rucoa::Position]
|
|
49
|
+
# @return [Boolean]
|
|
50
|
+
def exclude?(position)
|
|
51
|
+
position.line > @ending.line ||
|
|
52
|
+
position.line < @beginning.line ||
|
|
53
|
+
(position.line == @beginning.line && position.column < @beginning.column) ||
|
|
54
|
+
(position.line == @ending.line && position.column >= @ending.column)
|
|
55
|
+
end
|
|
56
|
+
end
|
|
57
|
+
end
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require 'rubocop'
|
|
4
|
+
|
|
5
|
+
module Rucoa
|
|
6
|
+
class RubocopRunner < ::RuboCop::Runner
|
|
7
|
+
class << self
|
|
8
|
+
# @param path [String]
|
|
9
|
+
# @return [Array<RuboCop::Cop::Offense>]
|
|
10
|
+
def call(path:)
|
|
11
|
+
new(path: path).call
|
|
12
|
+
end
|
|
13
|
+
end
|
|
14
|
+
|
|
15
|
+
# @param path [String]
|
|
16
|
+
def initialize(path:)
|
|
17
|
+
@path = path
|
|
18
|
+
@offenses = []
|
|
19
|
+
super(
|
|
20
|
+
::RuboCop::Options.new.parse(
|
|
21
|
+
%w[
|
|
22
|
+
--stderr
|
|
23
|
+
--force-exclusion
|
|
24
|
+
--format RuboCop::Formatter::BaseFormatter
|
|
25
|
+
]
|
|
26
|
+
).first,
|
|
27
|
+
::RuboCop::ConfigStore.new
|
|
28
|
+
)
|
|
29
|
+
end
|
|
30
|
+
|
|
31
|
+
# @return [Array<RuboCop::Cop::Offense>]
|
|
32
|
+
def call
|
|
33
|
+
run([@path])
|
|
34
|
+
@offenses
|
|
35
|
+
end
|
|
36
|
+
|
|
37
|
+
private
|
|
38
|
+
|
|
39
|
+
# @param file [String]
|
|
40
|
+
# @param offenses [Array<RuboCop::Cop::Offense>]
|
|
41
|
+
# @return [void]
|
|
42
|
+
def file_finished(file, offenses)
|
|
43
|
+
@offenses = offenses
|
|
44
|
+
super
|
|
45
|
+
end
|
|
46
|
+
end
|
|
47
|
+
end
|
|
@@ -0,0 +1,97 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Rucoa
|
|
4
|
+
class SelectionRangeProvider
|
|
5
|
+
class << self
|
|
6
|
+
# @param source [Rucoa::Source]
|
|
7
|
+
# @param position [Rucoa::Position]
|
|
8
|
+
# @return [Hash, nil]
|
|
9
|
+
def call(position:, source:)
|
|
10
|
+
new(
|
|
11
|
+
position: position,
|
|
12
|
+
source: source
|
|
13
|
+
).call
|
|
14
|
+
end
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
# @param position [Rucoa::Position]
|
|
18
|
+
# @param source [Rucoa::Source]
|
|
19
|
+
def initialize(position:, source:)
|
|
20
|
+
@position = position
|
|
21
|
+
@source = source
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
# @return [Hash, nil]
|
|
25
|
+
def call
|
|
26
|
+
ranges.reverse.reduce(nil) do |result, range|
|
|
27
|
+
{
|
|
28
|
+
parent: result,
|
|
29
|
+
range: range.to_vscode_range
|
|
30
|
+
}
|
|
31
|
+
end
|
|
32
|
+
end
|
|
33
|
+
|
|
34
|
+
private
|
|
35
|
+
|
|
36
|
+
# @return [Rucoa::Nodes::Base, nil]
|
|
37
|
+
def node_at_position
|
|
38
|
+
if instance_variable_defined?(:@node_at_position)
|
|
39
|
+
@node_at_position
|
|
40
|
+
else
|
|
41
|
+
@node_at_position = @source.node_at(@position)
|
|
42
|
+
end
|
|
43
|
+
end
|
|
44
|
+
|
|
45
|
+
# @return [Array<Rucoa::Range>]
|
|
46
|
+
def ranges
|
|
47
|
+
return [] unless node_at_position
|
|
48
|
+
|
|
49
|
+
[node_at_position, *node_at_position.ancestors].flat_map do |node|
|
|
50
|
+
NodeToRangesMapper.call(node)
|
|
51
|
+
end
|
|
52
|
+
end
|
|
53
|
+
|
|
54
|
+
class NodeToRangesMapper
|
|
55
|
+
class << self
|
|
56
|
+
# @param node [Rucoa::Nodes::Base]
|
|
57
|
+
# @return [Array<Rucoa::Range>]
|
|
58
|
+
def call(node)
|
|
59
|
+
new(node).call
|
|
60
|
+
end
|
|
61
|
+
end
|
|
62
|
+
|
|
63
|
+
# @param node [Rucoa::Nodes::Base]
|
|
64
|
+
def initialize(node)
|
|
65
|
+
@node = node
|
|
66
|
+
end
|
|
67
|
+
|
|
68
|
+
# @return [Array<Rucoa::Range>]
|
|
69
|
+
def call
|
|
70
|
+
case @node
|
|
71
|
+
when Nodes::StrNode
|
|
72
|
+
[
|
|
73
|
+
inner_range,
|
|
74
|
+
expression_range
|
|
75
|
+
]
|
|
76
|
+
else
|
|
77
|
+
[]
|
|
78
|
+
end
|
|
79
|
+
end
|
|
80
|
+
|
|
81
|
+
private
|
|
82
|
+
|
|
83
|
+
# @return [Rucoa::Range]
|
|
84
|
+
def inner_range
|
|
85
|
+
Range.new(
|
|
86
|
+
Position.from_parser_range_ending(@node.location.begin),
|
|
87
|
+
Position.from_parser_range_beginning(@node.location.end)
|
|
88
|
+
)
|
|
89
|
+
end
|
|
90
|
+
|
|
91
|
+
# @return [Rucoa::Range]
|
|
92
|
+
def expression_range
|
|
93
|
+
Range.from_parser_range(@node.location.expression)
|
|
94
|
+
end
|
|
95
|
+
end
|
|
96
|
+
end
|
|
97
|
+
end
|
data/lib/rucoa/server.rb
ADDED
|
@@ -0,0 +1,132 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Rucoa
|
|
4
|
+
class Server
|
|
5
|
+
# @param reader [IO]
|
|
6
|
+
# @param writer [IO]
|
|
7
|
+
def initialize(reader:, writer:)
|
|
8
|
+
@reader = MessageReader.new(reader)
|
|
9
|
+
@writer = MessageWriter.new(writer)
|
|
10
|
+
@source_store = SourceStore.new
|
|
11
|
+
end
|
|
12
|
+
|
|
13
|
+
# @return [void]
|
|
14
|
+
def start
|
|
15
|
+
read do |request|
|
|
16
|
+
result = handle(request)
|
|
17
|
+
if result
|
|
18
|
+
write(
|
|
19
|
+
request: request,
|
|
20
|
+
result: result
|
|
21
|
+
)
|
|
22
|
+
end
|
|
23
|
+
end
|
|
24
|
+
end
|
|
25
|
+
|
|
26
|
+
private
|
|
27
|
+
|
|
28
|
+
# @param request [Hash]
|
|
29
|
+
# @return [Object]
|
|
30
|
+
def handle(request)
|
|
31
|
+
case request['method']
|
|
32
|
+
when 'initialize'
|
|
33
|
+
on_initialize(request)
|
|
34
|
+
when 'textDocument/didChange'
|
|
35
|
+
on_text_document_did_change(request)
|
|
36
|
+
when 'textDocument/didOpen'
|
|
37
|
+
on_text_document_did_open(request)
|
|
38
|
+
when 'textDocument/selectionRange'
|
|
39
|
+
on_text_document_selection_range(request)
|
|
40
|
+
end
|
|
41
|
+
end
|
|
42
|
+
|
|
43
|
+
# @yieldparam request [Hash]
|
|
44
|
+
# @return [void]
|
|
45
|
+
def read(&block)
|
|
46
|
+
@reader.read(&block)
|
|
47
|
+
end
|
|
48
|
+
|
|
49
|
+
# @param request [Hash]
|
|
50
|
+
# @param result [Object]
|
|
51
|
+
# @return [void]
|
|
52
|
+
def write(request:, result:)
|
|
53
|
+
@writer.write(
|
|
54
|
+
{
|
|
55
|
+
id: request['id'],
|
|
56
|
+
result: result
|
|
57
|
+
}
|
|
58
|
+
)
|
|
59
|
+
end
|
|
60
|
+
|
|
61
|
+
# @param uri [String]
|
|
62
|
+
# @return [void]
|
|
63
|
+
def investigate_diagnostics(uri:)
|
|
64
|
+
diagnostics = DiagnosticProvider.call(
|
|
65
|
+
source: @source_store.get(uri)
|
|
66
|
+
)
|
|
67
|
+
return if diagnostics.empty?
|
|
68
|
+
|
|
69
|
+
@writer.write(
|
|
70
|
+
method: 'textDocument/publishDiagnostics',
|
|
71
|
+
params: {
|
|
72
|
+
diagnostics: diagnostics,
|
|
73
|
+
uri: uri
|
|
74
|
+
}
|
|
75
|
+
)
|
|
76
|
+
end
|
|
77
|
+
|
|
78
|
+
# @param _request [Hash]
|
|
79
|
+
# @return [Hash]
|
|
80
|
+
def on_initialize(_request)
|
|
81
|
+
{
|
|
82
|
+
capabilities: {
|
|
83
|
+
textDocumentSync: {
|
|
84
|
+
change: 1, # Full
|
|
85
|
+
openClose: true
|
|
86
|
+
},
|
|
87
|
+
selectionRangeProvider: true
|
|
88
|
+
}
|
|
89
|
+
}
|
|
90
|
+
end
|
|
91
|
+
|
|
92
|
+
# @param request [Hash]
|
|
93
|
+
# @return [Array<Hash>]
|
|
94
|
+
def on_text_document_did_change(request)
|
|
95
|
+
uri = request.dig('params', 'textDocument', 'uri')
|
|
96
|
+
@source_store.set(
|
|
97
|
+
uri,
|
|
98
|
+
request.dig('params', 'contentChanges')[0]['text']
|
|
99
|
+
)
|
|
100
|
+
investigate_diagnostics(uri: uri)
|
|
101
|
+
nil
|
|
102
|
+
end
|
|
103
|
+
|
|
104
|
+
# @param request [Hash]
|
|
105
|
+
# @return [Array<Hash>]
|
|
106
|
+
def on_text_document_did_open(request)
|
|
107
|
+
uri = request.dig('params', 'textDocument', 'uri')
|
|
108
|
+
@source_store.set(
|
|
109
|
+
uri,
|
|
110
|
+
request.dig('params', 'textDocument', 'text')
|
|
111
|
+
)
|
|
112
|
+
investigate_diagnostics(uri: uri)
|
|
113
|
+
nil
|
|
114
|
+
end
|
|
115
|
+
|
|
116
|
+
# @param request [Hash]
|
|
117
|
+
# @return [Array<Hash>, nil]
|
|
118
|
+
def on_text_document_selection_range(request)
|
|
119
|
+
source = @source_store.get(
|
|
120
|
+
request.dig('params', 'textDocument', 'uri')
|
|
121
|
+
)
|
|
122
|
+
return unless source
|
|
123
|
+
|
|
124
|
+
request.dig('params', 'positions').filter_map do |position|
|
|
125
|
+
SelectionRangeProvider.call(
|
|
126
|
+
position: Position.from_vscode_position(position),
|
|
127
|
+
source: source
|
|
128
|
+
)
|
|
129
|
+
end
|
|
130
|
+
end
|
|
131
|
+
end
|
|
132
|
+
end
|
data/lib/rucoa/source.rb
ADDED
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Rucoa
|
|
4
|
+
class Source
|
|
5
|
+
# @return [String]
|
|
6
|
+
attr_reader :content
|
|
7
|
+
|
|
8
|
+
# @return [String]
|
|
9
|
+
attr_reader :path
|
|
10
|
+
|
|
11
|
+
# @param content [String]
|
|
12
|
+
# @param path [String, nil]
|
|
13
|
+
def initialize(content:, path: nil)
|
|
14
|
+
@content = content
|
|
15
|
+
@path = path
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
# @param position [Rucoa::Position]
|
|
19
|
+
# @return [Rucoa::Nodes::Base, nil]
|
|
20
|
+
def node_at(position)
|
|
21
|
+
root_and_descendant_nodes.reverse.find do |node|
|
|
22
|
+
node.include_position?(position)
|
|
23
|
+
end
|
|
24
|
+
end
|
|
25
|
+
|
|
26
|
+
private
|
|
27
|
+
|
|
28
|
+
# @return [Rucoa::Nodes::Base, nil]
|
|
29
|
+
def root_node
|
|
30
|
+
@root_node ||= Parser.call(@content)
|
|
31
|
+
end
|
|
32
|
+
|
|
33
|
+
# @return [Array<Rucoa::Nodes::Base>]
|
|
34
|
+
def root_and_descendant_nodes
|
|
35
|
+
return [] unless root_node
|
|
36
|
+
|
|
37
|
+
[root_node, *root_node.descendants]
|
|
38
|
+
end
|
|
39
|
+
end
|
|
40
|
+
end
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require 'cgi'
|
|
4
|
+
require 'uri'
|
|
5
|
+
|
|
6
|
+
module Rucoa
|
|
7
|
+
class SourceStore
|
|
8
|
+
def initialize
|
|
9
|
+
@data = {}
|
|
10
|
+
end
|
|
11
|
+
|
|
12
|
+
# @param uri [String]
|
|
13
|
+
# @return [String, nil]
|
|
14
|
+
def get(uri)
|
|
15
|
+
@data[uri]
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
# @param uri [String]
|
|
19
|
+
# @param content [String]
|
|
20
|
+
# @return [void]
|
|
21
|
+
def set(uri, content)
|
|
22
|
+
@data[uri] = Source.new(
|
|
23
|
+
content: content,
|
|
24
|
+
path: path_from_uri(uri)
|
|
25
|
+
)
|
|
26
|
+
end
|
|
27
|
+
|
|
28
|
+
private
|
|
29
|
+
|
|
30
|
+
# @param uri [String]
|
|
31
|
+
# @return [String]
|
|
32
|
+
def path_from_uri(uri)
|
|
33
|
+
::CGI.unescape(
|
|
34
|
+
::URI.parse(uri).path
|
|
35
|
+
)
|
|
36
|
+
end
|
|
37
|
+
end
|
|
38
|
+
end
|
data/lib/rucoa.rb
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require_relative 'rucoa/version'
|
|
4
|
+
|
|
5
|
+
module Rucoa
|
|
6
|
+
autoload :Cli, 'rucoa/cli'
|
|
7
|
+
autoload :Errors, 'rucoa/errors'
|
|
8
|
+
autoload :DiagnosticProvider, 'rucoa/diagnostic_provider'
|
|
9
|
+
autoload :MessageReader, 'rucoa/message_reader'
|
|
10
|
+
autoload :MessageWriter, 'rucoa/message_writer'
|
|
11
|
+
autoload :Nodes, 'rucoa/nodes'
|
|
12
|
+
autoload :ParserBuilder, 'rucoa/parser_builder'
|
|
13
|
+
autoload :Parser, 'rucoa/parser'
|
|
14
|
+
autoload :Position, 'rucoa/position'
|
|
15
|
+
autoload :Range, 'rucoa/range'
|
|
16
|
+
autoload :RubocopRunner, 'rucoa/rubocop_runner'
|
|
17
|
+
autoload :SelectionRangeProvider, 'rucoa/selection_range_provider'
|
|
18
|
+
autoload :Server, 'rucoa/server'
|
|
19
|
+
autoload :Source, 'rucoa/source'
|
|
20
|
+
autoload :SourceStore, 'rucoa/source_store'
|
|
21
|
+
end
|
data/rucoa.gemspec
ADDED
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require_relative 'lib/rucoa/version'
|
|
4
|
+
|
|
5
|
+
Gem::Specification.new do |spec|
|
|
6
|
+
spec.name = 'rucoa'
|
|
7
|
+
spec.version = Rucoa::VERSION
|
|
8
|
+
spec.authors = ['Ryo Nakamura']
|
|
9
|
+
spec.email = ['r7kamura@gmail.com']
|
|
10
|
+
|
|
11
|
+
spec.summary = 'Language server for Ruby.'
|
|
12
|
+
spec.homepage = 'https://github.com/r7kamura/rucoa'
|
|
13
|
+
spec.license = 'MIT'
|
|
14
|
+
spec.required_ruby_version = '>= 2.7'
|
|
15
|
+
|
|
16
|
+
spec.metadata['homepage_uri'] = spec.homepage
|
|
17
|
+
spec.metadata['source_code_uri'] = spec.homepage
|
|
18
|
+
spec.metadata['changelog_uri'] = "#{spec.homepage}/releases"
|
|
19
|
+
spec.metadata['rubygems_mfa_required'] = 'true'
|
|
20
|
+
|
|
21
|
+
spec.files = Dir.chdir(__dir__) do
|
|
22
|
+
`git ls-files -z`.split("\x0").reject do |f|
|
|
23
|
+
(f == __FILE__) || f.match(%r{\A(?:(?:bin|test|spec|features)/|\.(?:git|travis|circleci)|appveyor)})
|
|
24
|
+
end
|
|
25
|
+
end
|
|
26
|
+
spec.bindir = 'exe'
|
|
27
|
+
spec.executables = spec.files.grep(%r{\Aexe/}) { |f| File.basename(f) }
|
|
28
|
+
spec.require_paths = ['lib']
|
|
29
|
+
|
|
30
|
+
spec.add_dependency 'parser'
|
|
31
|
+
spec.add_dependency 'rubocop'
|
|
32
|
+
end
|
metadata
ADDED
|
@@ -0,0 +1,105 @@
|
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
|
2
|
+
name: rucoa
|
|
3
|
+
version: !ruby/object:Gem::Version
|
|
4
|
+
version: 0.1.0
|
|
5
|
+
platform: ruby
|
|
6
|
+
authors:
|
|
7
|
+
- Ryo Nakamura
|
|
8
|
+
autorequire:
|
|
9
|
+
bindir: exe
|
|
10
|
+
cert_chain: []
|
|
11
|
+
date: 2022-09-03 00:00:00.000000000 Z
|
|
12
|
+
dependencies:
|
|
13
|
+
- !ruby/object:Gem::Dependency
|
|
14
|
+
name: parser
|
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
|
16
|
+
requirements:
|
|
17
|
+
- - ">="
|
|
18
|
+
- !ruby/object:Gem::Version
|
|
19
|
+
version: '0'
|
|
20
|
+
type: :runtime
|
|
21
|
+
prerelease: false
|
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
23
|
+
requirements:
|
|
24
|
+
- - ">="
|
|
25
|
+
- !ruby/object:Gem::Version
|
|
26
|
+
version: '0'
|
|
27
|
+
- !ruby/object:Gem::Dependency
|
|
28
|
+
name: rubocop
|
|
29
|
+
requirement: !ruby/object:Gem::Requirement
|
|
30
|
+
requirements:
|
|
31
|
+
- - ">="
|
|
32
|
+
- !ruby/object:Gem::Version
|
|
33
|
+
version: '0'
|
|
34
|
+
type: :runtime
|
|
35
|
+
prerelease: false
|
|
36
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
37
|
+
requirements:
|
|
38
|
+
- - ">="
|
|
39
|
+
- !ruby/object:Gem::Version
|
|
40
|
+
version: '0'
|
|
41
|
+
description:
|
|
42
|
+
email:
|
|
43
|
+
- r7kamura@gmail.com
|
|
44
|
+
executables:
|
|
45
|
+
- rucoa
|
|
46
|
+
extensions: []
|
|
47
|
+
extra_rdoc_files: []
|
|
48
|
+
files:
|
|
49
|
+
- ".rspec"
|
|
50
|
+
- ".rubocop.yml"
|
|
51
|
+
- CODE_OF_CONDUCT.md
|
|
52
|
+
- Gemfile
|
|
53
|
+
- Gemfile.lock
|
|
54
|
+
- LICENSE.txt
|
|
55
|
+
- README.md
|
|
56
|
+
- Rakefile
|
|
57
|
+
- exe/rucoa
|
|
58
|
+
- lib/rucoa.rb
|
|
59
|
+
- lib/rucoa/cli.rb
|
|
60
|
+
- lib/rucoa/diagnostic_provider.rb
|
|
61
|
+
- lib/rucoa/errors.rb
|
|
62
|
+
- lib/rucoa/message_reader.rb
|
|
63
|
+
- lib/rucoa/message_writer.rb
|
|
64
|
+
- lib/rucoa/nodes.rb
|
|
65
|
+
- lib/rucoa/nodes/base.rb
|
|
66
|
+
- lib/rucoa/nodes/str_node.rb
|
|
67
|
+
- lib/rucoa/parser.rb
|
|
68
|
+
- lib/rucoa/parser_builder.rb
|
|
69
|
+
- lib/rucoa/position.rb
|
|
70
|
+
- lib/rucoa/range.rb
|
|
71
|
+
- lib/rucoa/rubocop_runner.rb
|
|
72
|
+
- lib/rucoa/selection_range_provider.rb
|
|
73
|
+
- lib/rucoa/server.rb
|
|
74
|
+
- lib/rucoa/source.rb
|
|
75
|
+
- lib/rucoa/source_store.rb
|
|
76
|
+
- lib/rucoa/version.rb
|
|
77
|
+
- rucoa.gemspec
|
|
78
|
+
homepage: https://github.com/r7kamura/rucoa
|
|
79
|
+
licenses:
|
|
80
|
+
- MIT
|
|
81
|
+
metadata:
|
|
82
|
+
homepage_uri: https://github.com/r7kamura/rucoa
|
|
83
|
+
source_code_uri: https://github.com/r7kamura/rucoa
|
|
84
|
+
changelog_uri: https://github.com/r7kamura/rucoa/releases
|
|
85
|
+
rubygems_mfa_required: 'true'
|
|
86
|
+
post_install_message:
|
|
87
|
+
rdoc_options: []
|
|
88
|
+
require_paths:
|
|
89
|
+
- lib
|
|
90
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
|
91
|
+
requirements:
|
|
92
|
+
- - ">="
|
|
93
|
+
- !ruby/object:Gem::Version
|
|
94
|
+
version: '2.7'
|
|
95
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
|
96
|
+
requirements:
|
|
97
|
+
- - ">="
|
|
98
|
+
- !ruby/object:Gem::Version
|
|
99
|
+
version: '0'
|
|
100
|
+
requirements: []
|
|
101
|
+
rubygems_version: 3.3.7
|
|
102
|
+
signing_key:
|
|
103
|
+
specification_version: 4
|
|
104
|
+
summary: Language server for Ruby.
|
|
105
|
+
test_files: []
|