rucoa 0.3.0 → 0.5.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (75) hide show
  1. checksums.yaml +4 -4
  2. data/.rubocop.yml +3 -0
  3. data/Gemfile +1 -0
  4. data/Gemfile.lock +12 -2
  5. data/README.md +37 -6
  6. data/data/definitions_ruby_3_1 +0 -0
  7. data/images/diagnostics.gif +0 -0
  8. data/images/document-formatting.gif +0 -0
  9. data/images/document-symbol.gif +0 -0
  10. data/images/selection-ranges.gif +0 -0
  11. data/lib/rucoa/configuration.rb +62 -28
  12. data/lib/rucoa/definition_archiver.rb +29 -0
  13. data/lib/rucoa/definition_builders/rbs_constant_definition_builder.rb +44 -0
  14. data/lib/rucoa/definition_builders/rbs_method_definition_builder.rb +106 -0
  15. data/lib/rucoa/definition_builders/yard_method_definition_builder.rb +218 -0
  16. data/lib/rucoa/definition_builders.rb +9 -0
  17. data/lib/rucoa/definition_store.rb +63 -0
  18. data/lib/rucoa/definitions/base.rb +12 -0
  19. data/lib/rucoa/definitions/constant_definition.rb +51 -0
  20. data/lib/rucoa/definitions/method_definition.rb +126 -0
  21. data/lib/rucoa/definitions/method_parameter_definition.rb +30 -0
  22. data/lib/rucoa/definitions.rb +9 -0
  23. data/lib/rucoa/handler_concerns/diagnostics_publishable.rb +140 -0
  24. data/lib/rucoa/handlers/base.rb +8 -0
  25. data/lib/rucoa/handlers/exit_handler.rb +11 -0
  26. data/lib/rucoa/handlers/initialize_handler.rb +7 -0
  27. data/lib/rucoa/handlers/initialized_handler.rb +10 -0
  28. data/lib/rucoa/handlers/shutdown_handler.rb +12 -0
  29. data/lib/rucoa/handlers/text_document_code_action_handler.rb +78 -3
  30. data/lib/rucoa/handlers/text_document_did_change_handler.rb +1 -20
  31. data/lib/rucoa/handlers/text_document_did_open_handler.rb +11 -4
  32. data/lib/rucoa/handlers/text_document_document_symbol_handler.rb +242 -0
  33. data/lib/rucoa/handlers/text_document_formatting_handler.rb +36 -5
  34. data/lib/rucoa/handlers/text_document_range_formatting_handler.rb +65 -13
  35. data/lib/rucoa/handlers/text_document_selection_range_handler.rb +124 -8
  36. data/lib/rucoa/handlers/text_document_signature_help_handler.rb +68 -0
  37. data/lib/rucoa/handlers.rb +4 -0
  38. data/lib/rucoa/node_concerns/name_full_qualifiable.rb +20 -0
  39. data/lib/rucoa/node_concerns.rb +7 -0
  40. data/lib/rucoa/node_inspector.rb +111 -0
  41. data/lib/rucoa/nodes/base.rb +43 -0
  42. data/lib/rucoa/nodes/casgn_node.rb +14 -0
  43. data/lib/rucoa/nodes/class_node.rb +8 -0
  44. data/lib/rucoa/nodes/const_node.rb +12 -0
  45. data/lib/rucoa/nodes/def_node.rb +71 -0
  46. data/lib/rucoa/nodes/defs_node.rb +12 -0
  47. data/lib/rucoa/nodes/lvar_node.rb +25 -0
  48. data/lib/rucoa/nodes/module_node.rb +21 -0
  49. data/lib/rucoa/nodes/sclass_node.rb +8 -0
  50. data/lib/rucoa/nodes/send_node.rb +60 -0
  51. data/lib/rucoa/nodes/str_node.rb +4 -0
  52. data/lib/rucoa/nodes/sym_node.rb +12 -0
  53. data/lib/rucoa/nodes.rb +10 -0
  54. data/lib/rucoa/parser_builder.rb +20 -10
  55. data/lib/rucoa/position.rb +2 -2
  56. data/lib/rucoa/range.rb +64 -14
  57. data/lib/rucoa/rbs_document_loader.rb +43 -0
  58. data/lib/rucoa/rubocop_autocorrector.rb +1 -1
  59. data/lib/rucoa/rubocop_investigator.rb +1 -1
  60. data/lib/rucoa/server.rb +20 -1
  61. data/lib/rucoa/source.rb +56 -6
  62. data/lib/rucoa/source_store.rb +6 -10
  63. data/lib/rucoa/types/method_type.rb +23 -0
  64. data/lib/rucoa/types.rb +7 -0
  65. data/lib/rucoa/version.rb +1 -1
  66. data/lib/rucoa/yard_glob_document_loader.rb +47 -0
  67. data/lib/rucoa/yard_string_document_loader.rb +70 -0
  68. data/lib/rucoa.rb +10 -5
  69. data/rucoa.gemspec +2 -0
  70. metadata +68 -7
  71. data/lib/rucoa/code_action_provider.rb +0 -102
  72. data/lib/rucoa/diagnostic_provider.rb +0 -143
  73. data/lib/rucoa/formatting_provider.rb +0 -54
  74. data/lib/rucoa/range_formatting_provider.rb +0 -67
  75. data/lib/rucoa/selection_range_provider.rb +0 -99
@@ -0,0 +1,63 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Rucoa
4
+ class DefinitionStore
5
+ # @return [Array<Rucoa::Definition::Base>]
6
+ attr_accessor :definitions
7
+
8
+ def initialize
9
+ @definitions = []
10
+ end
11
+
12
+ # @param source_path [String]
13
+ # @return [Array<Rucoa::Definition::Base>]
14
+ def update_definitions_defined_in(source_path, definitions:)
15
+ delete_definitions_defined_in(source_path)
16
+ @definitions += definitions
17
+ end
18
+
19
+ # @param full_qualified_name [String]
20
+ # @return [Array<Rucoa::Definitions::Base>]
21
+ def select_by_full_qualified_name(full_qualified_name)
22
+ @definitions.select do |definition|
23
+ definition.full_qualified_name == full_qualified_name
24
+ end
25
+ end
26
+
27
+ # @param namespace [String]
28
+ # @return [Array<Rucoa::Definitions::MethodDefinition>]
29
+ def method_definitions_of(namespace)
30
+ method_definitions.select do |method_definition|
31
+ method_definition.namespace == namespace
32
+ end
33
+ end
34
+
35
+ # @param namespace [String]
36
+ # @return [Array<Rucoa::Definitions::ConstantDefinition>] e.g. File::Separator, File::SEPARATOR, etc.
37
+ def constant_definitions_under(namespace)
38
+ constant_definitions.select do |constant_definition|
39
+ constant_definition.namespace == namespace
40
+ end
41
+ end
42
+
43
+ private
44
+
45
+ # @return [Array<Rucoa::Definition::ConstantDefinition>]
46
+ def constant_definitions
47
+ @definitions.grep(Definitions::ConstantDefinition)
48
+ end
49
+
50
+ # @return [Array<Rucoa::Definition::MethodDefinition>]
51
+ def method_definitions
52
+ @definitions.grep(Definitions::MethodDefinition)
53
+ end
54
+
55
+ # @param source_path [String]
56
+ # @return [Array<Rucoa::Definition::Base>]
57
+ def delete_definitions_defined_in(source_path)
58
+ @definitions.delete_if do |definition|
59
+ definition.source_path == source_path
60
+ end
61
+ end
62
+ end
63
+ end
@@ -0,0 +1,12 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Rucoa
4
+ module Definitions
5
+ class Base
6
+ # @return [String]
7
+ def source_path
8
+ raise ::NotImplementedError
9
+ end
10
+ end
11
+ end
12
+ end
@@ -0,0 +1,51 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Rucoa
4
+ module Definitions
5
+ # Represents class definition, module definition, or constant assignment.
6
+ class ConstantDefinition < Base
7
+ # @return [String]
8
+ attr_reader :full_qualified_name
9
+
10
+ # @return [String]
11
+ attr_reader :source_path
12
+
13
+ # @param full_qualified_name [String]
14
+ # @param source_path [String]
15
+ def initialize(full_qualified_name:, source_path:)
16
+ super()
17
+ @full_qualified_name = full_qualified_name
18
+ @source_path = source_path
19
+ end
20
+
21
+ # @return [String]
22
+ # @example returns non-full-qualified name
23
+ # definition = Rucoa::Definitions::ConstantDefinition.new(
24
+ # full_qualified_name: 'Foo::Bar::Baz',
25
+ # source_path: '/path/to/foo/bar/baz.rb'
26
+ # )
27
+ # expect(definition.name).to eq('Baz')
28
+ def name
29
+ names.last
30
+ end
31
+
32
+ # @return [String]
33
+ # @example returns namespace
34
+ # definition = Rucoa::Definitions::ConstantDefinition.new(
35
+ # full_qualified_name: 'Foo::Bar::Baz',
36
+ # source_path: '/path/to/foo/bar/baz.rb'
37
+ # )
38
+ # expect(definition.namespace).to eq('Foo::Bar')
39
+ def namespace
40
+ names[..-2].join('::')
41
+ end
42
+
43
+ private
44
+
45
+ # @return [Array<String>]
46
+ def names
47
+ @names ||= full_qualified_name.split('::')
48
+ end
49
+ end
50
+ end
51
+ end
@@ -0,0 +1,126 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Rucoa
4
+ module Definitions
5
+ class MethodDefinition < Base
6
+ # @return [String, nil]
7
+ attr_reader :description
8
+
9
+ # @return [String]
10
+ attr_reader :method_name
11
+
12
+ # @return [String]
13
+ attr_reader :namespace
14
+
15
+ # @return [String]
16
+ attr_reader :source_path
17
+
18
+ # @param description [String, nil]
19
+ # @param kind [Symbol]
20
+ # @param method_name [String]
21
+ # @param namespace [String]
22
+ # @param source_path [String]
23
+ # @param types [Array<Rucoa::Types::MethodType>]
24
+ def initialize(
25
+ description:,
26
+ kind:,
27
+ method_name:,
28
+ namespace:,
29
+ source_path:,
30
+ types:
31
+ )
32
+ super()
33
+ @description = description
34
+ @kind = kind
35
+ @method_name = method_name
36
+ @namespace = namespace
37
+ @source_path = source_path
38
+ @types = types
39
+ end
40
+
41
+ # @return [String]
42
+ # @example returns qualified name of method
43
+ # method_definition = Rucoa::Definitions::MethodDefinition.new(
44
+ # description: nil,
45
+ # kind: :instance,
46
+ # method_name: 'foo',
47
+ # namespace: 'Foo::Bar',
48
+ # source_path: '/path/to/foo/bar.rb',
49
+ # types: []
50
+ # )
51
+ # expect(method_definition.full_qualified_name).to eq('Foo::Bar#foo')
52
+ def full_qualified_name
53
+ [
54
+ @namespace,
55
+ method_kind_symbol,
56
+ @method_name
57
+ ].join
58
+ end
59
+
60
+ # @todo
61
+ # @return [Array<Rucoa::Definitions::MethodParameter>]
62
+ def parameters
63
+ []
64
+ end
65
+
66
+ # @return [Array<String>]
67
+ # @example returns return types
68
+ # method_definition = Rucoa::Definitions::MethodDefinition.new(
69
+ # description: nil,
70
+ # kind: :instance,
71
+ # method_name: 'foo',
72
+ # namespace: 'Foo::Bar',
73
+ # source_path: '/path/to/foo/bar.rb',
74
+ # types: [
75
+ # Rucoa::Types::MethodType.new(
76
+ # parameters_string: '',
77
+ # return_type: 'String'
78
+ # )
79
+ # ]
80
+ # )
81
+ # expect(method_definition.return_types).to eq(%w[String])
82
+ def return_types
83
+ @types.map(&:return_type)
84
+ end
85
+
86
+ # @return [Array<String>]
87
+ # @example returns signature
88
+ # method_definition = Rucoa::Definitions::MethodDefinition.new(
89
+ # description: nil,
90
+ # kind: :instance,
91
+ # method_name: 'foo',
92
+ # namespace: 'Foo::Bar',
93
+ # source_path: '/path/to/foo/bar.rb',
94
+ # types: [
95
+ # Rucoa::Types::MethodType.new(
96
+ # parameters_string: '?::int base',
97
+ # return_type: 'String'
98
+ # )
99
+ # ]
100
+ # )
101
+ # expect(method_definition.signatures).to eq(['Foo::Bar#foo(?::int base) -> String'])
102
+ def signatures
103
+ @types.map do |type|
104
+ format(
105
+ '%<full_qualified_name>s(%<parameters>s) -> %<return_types>s',
106
+ full_qualified_name: full_qualified_name,
107
+ parameters: type.parameters_string,
108
+ return_types: type.return_type
109
+ )
110
+ end
111
+ end
112
+
113
+ private
114
+
115
+ # @return [String]
116
+ def method_kind_symbol
117
+ case @kind
118
+ when :instance
119
+ '#'
120
+ else
121
+ '.'
122
+ end
123
+ end
124
+ end
125
+ end
126
+ end
@@ -0,0 +1,30 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Rucoa
4
+ module Definitions
5
+ # Represents method parameter definition.
6
+ class MethodParameterDefinition < Base
7
+ # @return [String]
8
+ attr_reader :name
9
+
10
+ # @return [Array<String>]
11
+ attr_reader :types
12
+
13
+ # @param name [String]
14
+ # @param types [Array<String>]
15
+ def initialize(name:, types:)
16
+ super()
17
+ @name = name
18
+ @types = types
19
+ end
20
+
21
+ # @return [Hash{Symbol => Object}]
22
+ def to_hash
23
+ {
24
+ name: name,
25
+ types: types
26
+ }
27
+ end
28
+ end
29
+ end
30
+ end
@@ -0,0 +1,9 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Rucoa
4
+ module Definitions
5
+ autoload :Base, 'rucoa/definitions/base'
6
+ autoload :ConstantDefinition, 'rucoa/definitions/constant_definition'
7
+ autoload :MethodDefinition, 'rucoa/definitions/method_definition'
8
+ end
9
+ end
@@ -27,6 +27,146 @@ module Rucoa
27
27
  }
28
28
  )
29
29
  end
30
+
31
+ class DiagnosticProvider
32
+ # @param source [Rucoa::Source]
33
+ # @param uri [String]
34
+ # @return [Array<Hash>]
35
+ def self.call(source:, uri:)
36
+ new(
37
+ source: source,
38
+ uri: uri
39
+ ).call
40
+ end
41
+
42
+ # @param source [Rucoa::Source]
43
+ # @param uri [String]
44
+ def initialize(source:, uri:)
45
+ @source = source
46
+ @uri = uri
47
+ end
48
+
49
+ # @return [Array<Hash>]
50
+ def call
51
+ return [] unless RubocopConfigurationChecker.call
52
+
53
+ offenses.map do |offense|
54
+ OffenseToDiagnosticMapper.call(
55
+ offense,
56
+ source: @source,
57
+ uri: @uri
58
+ )
59
+ end
60
+ end
61
+
62
+ private
63
+
64
+ # @return [Array<RuboCop::Cop::Offense>]
65
+ def offenses
66
+ RubocopInvestigator.call(source: @source)
67
+ end
68
+
69
+ class OffenseToDiagnosticMapper
70
+ LSP_SEVERITY_NAME_TO_VALUE_MAP = {
71
+ error: 1,
72
+ hint: 4,
73
+ information: 3,
74
+ warning: 2
75
+ }.freeze
76
+ private_constant :LSP_SEVERITY_NAME_TO_VALUE_MAP
77
+
78
+ RUBOCOP_SEVERITY_NAME_TO_LSP_SEVERITY_MAP = {
79
+ convention: LSP_SEVERITY_NAME_TO_VALUE_MAP[:information],
80
+ error: LSP_SEVERITY_NAME_TO_VALUE_MAP[:error],
81
+ fatal: LSP_SEVERITY_NAME_TO_VALUE_MAP[:error],
82
+ info: LSP_SEVERITY_NAME_TO_VALUE_MAP[:information],
83
+ refactor: LSP_SEVERITY_NAME_TO_VALUE_MAP[:hint],
84
+ warning: LSP_SEVERITY_NAME_TO_VALUE_MAP[:warning]
85
+ }.freeze
86
+ private_constant :RUBOCOP_SEVERITY_NAME_TO_LSP_SEVERITY_MAP
87
+
88
+ class << self
89
+ # @param offense [RuboCop::Cop::Offense]
90
+ # @param source [Rucoa::Source]
91
+ # @param uri [String]
92
+ # @return [Hash]
93
+ def call(offense, source:, uri:)
94
+ new(
95
+ offense,
96
+ source: source,
97
+ uri: uri
98
+ ).call
99
+ end
100
+ end
101
+
102
+ # @param offense [RuboCop::Cop::Offense]
103
+ # @param source [Rucoa::Source]
104
+ # @param uri [String]
105
+ def initialize(offense, source:, uri:)
106
+ @offense = offense
107
+ @source = source
108
+ @uri = uri
109
+ end
110
+
111
+ # @return [Hash]
112
+ def call
113
+ {
114
+ code: code,
115
+ data: data,
116
+ message: message,
117
+ range: range,
118
+ severity: severity,
119
+ source: source
120
+ }
121
+ end
122
+
123
+ private
124
+
125
+ # @return [String]
126
+ def code
127
+ @offense.cop_name
128
+ end
129
+
130
+ # @return [Hash]
131
+ def data
132
+ {
133
+ cop_name: @offense.cop_name,
134
+ edits: edits,
135
+ uri: @uri
136
+ }
137
+ end
138
+
139
+ # @return [Array<Hash>, nil]
140
+ def edits
141
+ @offense.corrector&.as_replacements&.map do |range, replacement|
142
+ {
143
+ newText: replacement,
144
+ range: Range.from_parser_range(range).to_vscode_range
145
+ }
146
+ end
147
+ end
148
+
149
+ # @return [String]
150
+ def message
151
+ @offense.message.delete_prefix("#{@offense.cop_name}: ")
152
+ end
153
+
154
+ # @return [Hash]
155
+ def range
156
+ Range.from_parser_range(@offense.location).to_vscode_range
157
+ end
158
+
159
+ # @return [Integer]
160
+ def severity
161
+ RUBOCOP_SEVERITY_NAME_TO_LSP_SEVERITY_MAP.fetch(@offense.severity.name, 1)
162
+ end
163
+
164
+ # @return [String]
165
+ def source
166
+ 'RuboCop'
167
+ end
168
+ end
169
+ end
30
170
  end
31
171
  end
32
172
  end
@@ -32,6 +32,9 @@ module Rucoa
32
32
  # @return [Hash]
33
33
  attr_reader :request
34
34
 
35
+ # @return [Rucoa::Server]
36
+ attr_reader :server
37
+
35
38
  # @param message [Hash]
36
39
  # @return [void]
37
40
  def respond(message)
@@ -46,6 +49,11 @@ module Rucoa
46
49
  @server.configuration
47
50
  end
48
51
 
52
+ # @return [Rucoa::DefinitionStore]
53
+ def definition_store
54
+ @server.definition_store
55
+ end
56
+
49
57
  # @return [Rucoa::SourceStore]
50
58
  def source_store
51
59
  @server.source_store
@@ -0,0 +1,11 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Rucoa
4
+ module Handlers
5
+ class ExitHandler < Base
6
+ def call
7
+ server.finish
8
+ end
9
+ end
10
+ end
11
+ end
@@ -9,7 +9,14 @@ module Rucoa
9
9
  codeActionProvider: true,
10
10
  documentFormattingProvider: true,
11
11
  documentRangeFormattingProvider: true,
12
+ documentSymbolProvider: true,
12
13
  selectionRangeProvider: true,
14
+ signatureHelpProvider: {
15
+ triggerCharacters: %w[
16
+ (
17
+ ,
18
+ ]
19
+ },
13
20
  textDocumentSync: {
14
21
  change: 1, # Full
15
22
  openClose: true
@@ -7,6 +7,16 @@ module Rucoa
7
7
 
8
8
  def call
9
9
  request_workspace_configuration
10
+ load_definitions
11
+ end
12
+
13
+ private
14
+
15
+ # @return [void]
16
+ def load_definitions
17
+ YardGlobDocumentLoader.call(
18
+ globs: ::YARD::Parser::SourceParser::DEFAULT_PATH_GLOB
19
+ )
10
20
  end
11
21
  end
12
22
  end
@@ -0,0 +1,12 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Rucoa
4
+ module Handlers
5
+ class ShutdownHandler < Base
6
+ def call
7
+ server.shutting_down = true
8
+ respond(nil)
9
+ end
10
+ end
11
+ end
12
+ end
@@ -15,15 +15,90 @@ module Rucoa
15
15
  def code_actions
16
16
  return [] unless configuration.enables_code_action?
17
17
 
18
- CodeActionProvider.call(
19
- diagnostics: diagnostics
20
- )
18
+ correctable_diagnostics.map do |diagnostic|
19
+ DiagnosticToCodeActionMapper.call(diagnostic)
20
+ end
21
+ end
22
+
23
+ # @return [Array<Hash>]
24
+ def correctable_diagnostics
25
+ diagnostics.select do |diagnostic|
26
+ diagnostic.dig('data', 'edits')
27
+ end
21
28
  end
22
29
 
23
30
  # @return [Array<Hash>, nil]
24
31
  def diagnostics
25
32
  @diagnostics ||= request.dig('params', 'context', 'diagnostics')
26
33
  end
34
+
35
+ class DiagnosticToCodeActionMapper
36
+ class << self
37
+ # @param diagnostic [Hash]
38
+ # @return [Hash]
39
+ def call(diagnostic)
40
+ new(diagnostic).call
41
+ end
42
+ end
43
+
44
+ # @param diagnostic [Hash]
45
+ def initialize(diagnostic)
46
+ @diagnostic = diagnostic
47
+ end
48
+
49
+ # @return [Hash]
50
+ def call
51
+ {
52
+ diagnostics: diagnostics,
53
+ edit: edit,
54
+ isPreferred: preferred?,
55
+ kind: kind,
56
+ title: title
57
+ }
58
+ end
59
+
60
+ private
61
+
62
+ # @return [Hash]
63
+ def edit
64
+ {
65
+ documentChanges: [
66
+ {
67
+ edits: @diagnostic.dig('data', 'edits'),
68
+ textDocument: {
69
+ uri: @diagnostic.dig('data', 'uri'),
70
+ version: nil
71
+ }
72
+ }
73
+ ]
74
+ }
75
+ end
76
+
77
+ # @return [String]
78
+ def cop_name
79
+ @diagnostic.dig('data', 'cop_name')
80
+ end
81
+
82
+ # @return [Array]
83
+ def diagnostics
84
+ [@diagnostic]
85
+ end
86
+
87
+ # @return [Boolean]
88
+ def preferred?
89
+ true
90
+ end
91
+
92
+ # @return [String]
93
+ def kind
94
+ 'quickfix'
95
+ end
96
+
97
+ # @return [String]
98
+ def title
99
+ "Autocorrect #{cop_name}"
100
+ end
101
+ end
27
102
  end
28
103
  end
29
104
  end
@@ -2,30 +2,11 @@
2
2
 
3
3
  module Rucoa
4
4
  module Handlers
5
- class TextDocumentDidChangeHandler < Base
6
- include HandlerConcerns::DiagnosticsPublishable
7
-
8
- def call
9
- update_source
10
- publish_diagnostics_on(uri)
11
- end
12
-
13
- private
14
-
15
- # @return [void]
16
- def update_source
17
- source_store.set(uri, text)
18
- end
19
-
5
+ class TextDocumentDidChangeHandler < TextDocumentDidOpenHandler
20
6
  # @return [String]
21
7
  def text
22
8
  request.dig('params', 'contentChanges')[0]['text']
23
9
  end
24
-
25
- # @return [String]
26
- def uri
27
- @uri ||= request.dig('params', 'textDocument', 'uri')
28
- end
29
10
  end
30
11
  end
31
12
  end
@@ -6,15 +6,22 @@ module Rucoa
6
6
  include HandlerConcerns::DiagnosticsPublishable
7
7
 
8
8
  def call
9
- update_source
9
+ source_store.update(source)
10
+ definition_store.update_definitions_defined_in(
11
+ source.path,
12
+ definitions: source.definitions
13
+ )
10
14
  publish_diagnostics_on(uri)
11
15
  end
12
16
 
13
17
  private
14
18
 
15
- # @return [void]
16
- def update_source
17
- source_store.set(uri, text)
19
+ # @return [Rucoa::Source]
20
+ def source
21
+ @source ||= Source.new(
22
+ content: text,
23
+ uri: uri
24
+ )
18
25
  end
19
26
 
20
27
  # @return [String]