solargraph 0.58.0 → 0.59.0.dev.1

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.
Files changed (166) hide show
  1. checksums.yaml +4 -4
  2. data/.envrc +3 -0
  3. data/.gitattributes +2 -0
  4. data/.github/workflows/linting.yml +4 -5
  5. data/.github/workflows/plugins.yml +40 -36
  6. data/.github/workflows/rspec.yml +45 -13
  7. data/.github/workflows/typecheck.yml +2 -2
  8. data/.rubocop_todo.yml +27 -49
  9. data/CHANGELOG.md +3 -0
  10. data/README.md +3 -3
  11. data/Rakefile +1 -0
  12. data/bin/solargraph +8 -8
  13. data/lib/solargraph/api_map/cache.rb +110 -110
  14. data/lib/solargraph/api_map/constants.rb +289 -279
  15. data/lib/solargraph/api_map/index.rb +204 -193
  16. data/lib/solargraph/api_map/source_to_yard.rb +109 -97
  17. data/lib/solargraph/api_map/store.rb +387 -384
  18. data/lib/solargraph/api_map.rb +1000 -945
  19. data/lib/solargraph/complex_type/conformance.rb +176 -0
  20. data/lib/solargraph/complex_type/type_methods.rb +242 -228
  21. data/lib/solargraph/complex_type/unique_type.rb +632 -482
  22. data/lib/solargraph/complex_type.rb +549 -444
  23. data/lib/solargraph/convention/data_definition/data_definition_node.rb +93 -91
  24. data/lib/solargraph/convention/data_definition.rb +108 -105
  25. data/lib/solargraph/convention/struct_definition/struct_assignment_node.rb +62 -61
  26. data/lib/solargraph/convention/struct_definition/struct_definition_node.rb +103 -102
  27. data/lib/solargraph/convention/struct_definition.rb +168 -164
  28. data/lib/solargraph/diagnostics/require_not_found.rb +54 -53
  29. data/lib/solargraph/diagnostics/rubocop.rb +119 -118
  30. data/lib/solargraph/diagnostics/rubocop_helpers.rb +70 -68
  31. data/lib/solargraph/diagnostics/type_check.rb +56 -55
  32. data/lib/solargraph/doc_map.rb +200 -439
  33. data/lib/solargraph/equality.rb +34 -34
  34. data/lib/solargraph/gem_pins.rb +97 -98
  35. data/lib/solargraph/language_server/host/dispatch.rb +131 -130
  36. data/lib/solargraph/language_server/host/message_worker.rb +113 -112
  37. data/lib/solargraph/language_server/host/sources.rb +100 -99
  38. data/lib/solargraph/language_server/host.rb +883 -878
  39. data/lib/solargraph/language_server/message/extended/check_gem_version.rb +109 -114
  40. data/lib/solargraph/language_server/message/extended/document.rb +24 -23
  41. data/lib/solargraph/language_server/message/text_document/completion.rb +58 -56
  42. data/lib/solargraph/language_server/message/text_document/definition.rb +42 -40
  43. data/lib/solargraph/language_server/message/text_document/document_symbol.rb +28 -26
  44. data/lib/solargraph/language_server/message/text_document/formatting.rb +150 -148
  45. data/lib/solargraph/language_server/message/text_document/hover.rb +60 -58
  46. data/lib/solargraph/language_server/message/text_document/signature_help.rb +25 -24
  47. data/lib/solargraph/language_server/message/text_document/type_definition.rb +27 -25
  48. data/lib/solargraph/language_server/message/workspace/workspace_symbol.rb +25 -23
  49. data/lib/solargraph/library.rb +729 -683
  50. data/lib/solargraph/location.rb +87 -82
  51. data/lib/solargraph/logging.rb +57 -37
  52. data/lib/solargraph/parser/comment_ripper.rb +76 -69
  53. data/lib/solargraph/parser/flow_sensitive_typing.rb +483 -255
  54. data/lib/solargraph/parser/node_processor/base.rb +122 -92
  55. data/lib/solargraph/parser/node_processor.rb +63 -62
  56. data/lib/solargraph/parser/parser_gem/class_methods.rb +167 -149
  57. data/lib/solargraph/parser/parser_gem/node_chainer.rb +191 -166
  58. data/lib/solargraph/parser/parser_gem/node_methods.rb +506 -486
  59. data/lib/solargraph/parser/parser_gem/node_processors/and_node.rb +22 -22
  60. data/lib/solargraph/parser/parser_gem/node_processors/args_node.rb +61 -59
  61. data/lib/solargraph/parser/parser_gem/node_processors/begin_node.rb +24 -15
  62. data/lib/solargraph/parser/parser_gem/node_processors/block_node.rb +46 -46
  63. data/lib/solargraph/parser/parser_gem/node_processors/def_node.rb +60 -53
  64. data/lib/solargraph/parser/parser_gem/node_processors/if_node.rb +53 -23
  65. data/lib/solargraph/parser/parser_gem/node_processors/ivasgn_node.rb +41 -40
  66. data/lib/solargraph/parser/parser_gem/node_processors/lvasgn_node.rb +30 -29
  67. data/lib/solargraph/parser/parser_gem/node_processors/masgn_node.rb +61 -59
  68. data/lib/solargraph/parser/parser_gem/node_processors/opasgn_node.rb +98 -98
  69. data/lib/solargraph/parser/parser_gem/node_processors/or_node.rb +22 -0
  70. data/lib/solargraph/parser/parser_gem/node_processors/orasgn_node.rb +17 -17
  71. data/lib/solargraph/parser/parser_gem/node_processors/resbody_node.rb +39 -38
  72. data/lib/solargraph/parser/parser_gem/node_processors/sclass_node.rb +53 -52
  73. data/lib/solargraph/parser/parser_gem/node_processors/send_node.rb +296 -291
  74. data/lib/solargraph/parser/parser_gem/node_processors/when_node.rb +23 -0
  75. data/lib/solargraph/parser/parser_gem/node_processors/while_node.rb +33 -29
  76. data/lib/solargraph/parser/parser_gem/node_processors.rb +74 -70
  77. data/lib/solargraph/parser/region.rb +75 -69
  78. data/lib/solargraph/parser/snippet.rb +17 -17
  79. data/lib/solargraph/pin/base.rb +761 -729
  80. data/lib/solargraph/pin/base_variable.rb +418 -126
  81. data/lib/solargraph/pin/block.rb +126 -104
  82. data/lib/solargraph/pin/breakable.rb +13 -9
  83. data/lib/solargraph/pin/callable.rb +278 -231
  84. data/lib/solargraph/pin/closure.rb +68 -72
  85. data/lib/solargraph/pin/common.rb +94 -79
  86. data/lib/solargraph/pin/compound_statement.rb +55 -0
  87. data/lib/solargraph/pin/conversions.rb +124 -123
  88. data/lib/solargraph/pin/delegated_method.rb +131 -120
  89. data/lib/solargraph/pin/documenting.rb +115 -114
  90. data/lib/solargraph/pin/instance_variable.rb +38 -34
  91. data/lib/solargraph/pin/keyword.rb +16 -20
  92. data/lib/solargraph/pin/local_variable.rb +31 -75
  93. data/lib/solargraph/pin/method.rb +720 -672
  94. data/lib/solargraph/pin/method_alias.rb +42 -34
  95. data/lib/solargraph/pin/namespace.rb +121 -115
  96. data/lib/solargraph/pin/parameter.rb +338 -275
  97. data/lib/solargraph/pin/proxy_type.rb +40 -39
  98. data/lib/solargraph/pin/reference/override.rb +47 -47
  99. data/lib/solargraph/pin/reference/superclass.rb +17 -15
  100. data/lib/solargraph/pin/reference.rb +41 -39
  101. data/lib/solargraph/pin/search.rb +62 -61
  102. data/lib/solargraph/pin/signature.rb +69 -61
  103. data/lib/solargraph/pin/symbol.rb +53 -53
  104. data/lib/solargraph/pin/until.rb +18 -18
  105. data/lib/solargraph/pin/while.rb +18 -18
  106. data/lib/solargraph/pin.rb +46 -44
  107. data/lib/solargraph/pin_cache.rb +665 -245
  108. data/lib/solargraph/position.rb +118 -119
  109. data/lib/solargraph/range.rb +112 -112
  110. data/lib/solargraph/rbs_map/conversions.rb +846 -823
  111. data/lib/solargraph/rbs_map/core_map.rb +65 -58
  112. data/lib/solargraph/rbs_map/stdlib_map.rb +72 -43
  113. data/lib/solargraph/rbs_map.rb +217 -163
  114. data/lib/solargraph/shell.rb +397 -352
  115. data/lib/solargraph/source/chain/call.rb +372 -337
  116. data/lib/solargraph/source/chain/constant.rb +28 -26
  117. data/lib/solargraph/source/chain/hash.rb +35 -34
  118. data/lib/solargraph/source/chain/if.rb +29 -28
  119. data/lib/solargraph/source/chain/instance_variable.rb +34 -13
  120. data/lib/solargraph/source/chain/literal.rb +53 -48
  121. data/lib/solargraph/source/chain/or.rb +31 -23
  122. data/lib/solargraph/source/chain.rb +294 -291
  123. data/lib/solargraph/source/change.rb +89 -82
  124. data/lib/solargraph/source/cursor.rb +172 -166
  125. data/lib/solargraph/source/encoding_fixes.rb +23 -23
  126. data/lib/solargraph/source/source_chainer.rb +204 -194
  127. data/lib/solargraph/source/updater.rb +59 -55
  128. data/lib/solargraph/source.rb +524 -498
  129. data/lib/solargraph/source_map/clip.rb +237 -226
  130. data/lib/solargraph/source_map/data.rb +37 -34
  131. data/lib/solargraph/source_map/mapper.rb +282 -259
  132. data/lib/solargraph/source_map.rb +220 -212
  133. data/lib/solargraph/type_checker/problem.rb +34 -32
  134. data/lib/solargraph/type_checker/rules.rb +157 -84
  135. data/lib/solargraph/type_checker.rb +895 -814
  136. data/lib/solargraph/version.rb +5 -5
  137. data/lib/solargraph/workspace/config.rb +257 -255
  138. data/lib/solargraph/workspace/gemspecs.rb +367 -0
  139. data/lib/solargraph/workspace/require_paths.rb +98 -97
  140. data/lib/solargraph/workspace.rb +362 -220
  141. data/lib/solargraph/yard_map/helpers.rb +45 -44
  142. data/lib/solargraph/yard_map/mapper/to_method.rb +134 -130
  143. data/lib/solargraph/yard_map/mapper/to_namespace.rb +32 -31
  144. data/lib/solargraph/yard_map/mapper.rb +84 -79
  145. data/lib/solargraph/yardoc.rb +97 -87
  146. data/lib/solargraph.rb +126 -105
  147. data/rbs/fills/rubygems/0/dependency.rbs +193 -0
  148. data/rbs/fills/tuple/tuple.rbs +28 -0
  149. data/rbs/shims/ast/0/node.rbs +5 -0
  150. data/rbs/shims/diff-lcs/1.5/diff-lcs.rbs +11 -0
  151. data/rbs_collection.yaml +1 -1
  152. data/solargraph.gemspec +2 -1
  153. metadata +23 -17
  154. data/lib/solargraph/type_checker/checks.rb +0 -124
  155. data/lib/solargraph/type_checker/param_def.rb +0 -37
  156. data/lib/solargraph/yard_map/to_method.rb +0 -89
  157. data/sig/shims/ast/0/node.rbs +0 -5
  158. /data/{sig → rbs}/shims/ast/2.4/.rbs_meta.yaml +0 -0
  159. /data/{sig → rbs}/shims/ast/2.4/ast.rbs +0 -0
  160. /data/{sig → rbs}/shims/parser/3.2.0.1/builders/default.rbs +0 -0
  161. /data/{sig → rbs}/shims/parser/3.2.0.1/manifest.yaml +0 -0
  162. /data/{sig → rbs}/shims/parser/3.2.0.1/parser.rbs +0 -0
  163. /data/{sig → rbs}/shims/parser/3.2.0.1/polyfill.rbs +0 -0
  164. /data/{sig → rbs}/shims/thor/1.2.0.1/.rbs_meta.yaml +0 -0
  165. /data/{sig → rbs}/shims/thor/1.2.0.1/manifest.yaml +0 -0
  166. /data/{sig → rbs}/shims/thor/1.2.0.1/thor.rbs +0 -0
@@ -1,118 +1,119 @@
1
- # frozen_string_literal: true
2
-
3
- require 'stringio'
4
-
5
- module Solargraph
6
- module Diagnostics
7
- # This reporter provides linting through RuboCop.
8
- #
9
- class Rubocop < Base
10
- include RubocopHelpers
11
-
12
- # Conversion of RuboCop severity names to LSP constants
13
- SEVERITIES = {
14
- 'info' => Severities::HINT,
15
- 'refactor' => Severities::HINT,
16
- 'convention' => Severities::INFORMATION,
17
- 'warning' => Severities::WARNING,
18
- 'error' => Severities::ERROR,
19
- 'fatal' => Severities::ERROR
20
- }
21
-
22
- # @param source [Solargraph::Source]
23
- # @param _api_map [Solargraph::ApiMap]
24
- # @return [Array<Hash>]
25
- def diagnose source, _api_map
26
- @source = source
27
- require_rubocop(rubocop_version)
28
- options, paths = generate_options(source.filename, source.code)
29
- store = RuboCop::ConfigStore.new
30
- runner = RuboCop::Runner.new(options, store)
31
- # Ensure only one instance of RuboCop::Runner is running at
32
- # a time - it uses 'chdir' to read config files with ERB,
33
- # which can conflict with other chdirs.
34
- result = Solargraph::CHDIR_MUTEX.synchronize do
35
- redirect_stdout{ runner.run(paths) }
36
- end
37
-
38
- return [] if result.empty?
39
-
40
- make_array JSON.parse(result)
41
- rescue RuboCop::ValidationError, RuboCop::ConfigNotFoundError => e
42
- raise DiagnosticsError, "Error in RuboCop configuration: #{e.message}"
43
- rescue JSON::ParserError => e
44
- raise DiagnosticsError, "RuboCop returned invalid data: #{e.message}"
45
- end
46
-
47
- private
48
-
49
- # Extracts the rubocop version from _args_
50
- #
51
- # @return [String]
52
- def rubocop_version
53
- args.find { |a| a =~ /version=/ }.to_s.split('=').last
54
- end
55
-
56
- # @param resp [Hash{String => Array<Hash{String => Array<Hash{String => undefined}>}>}]
57
- # @return [Array<Hash>]
58
- def make_array resp
59
- diagnostics = []
60
- resp['files'].each do |file|
61
- file['offenses'].each do |off|
62
- diagnostics.push offense_to_diagnostic(off)
63
- end
64
- end
65
- diagnostics
66
- end
67
-
68
- # Convert a RuboCop offense to an LSP diagnostic
69
- #
70
- # @param off [Hash{String => unknown}] Offense received from Rubocop
71
- # @return [Hash{Symbol => Hash, String, Integer}] LSP diagnostic
72
- def offense_to_diagnostic off
73
- {
74
- range: offense_range(off).to_hash,
75
- # 1 = Error, 2 = Warning, 3 = Information, 4 = Hint
76
- severity: SEVERITIES[off['severity']],
77
- source: 'rubocop',
78
- code: off['cop_name'],
79
- message: off['message'].gsub(/^#{off['cop_name']}\:/, '')
80
- }
81
- end
82
-
83
- # @param off [Hash]
84
- # @return [Range]
85
- def offense_range off
86
- Range.new(offense_start_position(off), offense_ending_position(off))
87
- end
88
-
89
- # @param off [Hash{String => Hash{String => Integer}}]
90
- # @return [Position]
91
- def offense_start_position off
92
- Position.new(off['location']['start_line'] - 1, off['location']['start_column'] - 1)
93
- end
94
-
95
- # @param off [Hash{String => Hash{String => Integer}}]
96
- # @return [Position]
97
- def offense_ending_position off
98
- if off['location']['start_line'] != off['location']['last_line']
99
- Position.new(off['location']['start_line'], 0)
100
- else
101
- start_line = off['location']['start_line'] - 1
102
- # @type [Integer]
103
- last_column = off['location']['last_column']
104
- line = @source.code.lines[start_line]
105
- col_off = if line.nil? || line.empty?
106
- 1
107
- else
108
- 0
109
- end
110
-
111
- Position.new(
112
- start_line, last_column - col_off
113
- )
114
- end
115
- end
116
- end
117
- end
118
- end
1
+ # frozen_string_literal: true
2
+
3
+ require 'stringio'
4
+
5
+ module Solargraph
6
+ module Diagnostics
7
+ # This reporter provides linting through RuboCop.
8
+ #
9
+ class Rubocop < Base
10
+ include RubocopHelpers
11
+
12
+ # Conversion of RuboCop severity names to LSP constants
13
+ SEVERITIES = {
14
+ 'info' => Severities::HINT,
15
+ 'refactor' => Severities::HINT,
16
+ 'convention' => Severities::INFORMATION,
17
+ 'warning' => Severities::WARNING,
18
+ 'error' => Severities::ERROR,
19
+ 'fatal' => Severities::ERROR
20
+ }
21
+
22
+ # @param source [Solargraph::Source]
23
+ # @param _api_map [Solargraph::ApiMap]
24
+ # @return [Array<Hash>]
25
+ def diagnose source, _api_map
26
+ @source = source
27
+ require_rubocop(rubocop_version)
28
+ # @sg-ignore Need to add nil check here
29
+ options, paths = generate_options(source.filename, source.code)
30
+ store = RuboCop::ConfigStore.new
31
+ runner = RuboCop::Runner.new(options, store)
32
+ # Ensure only one instance of RuboCop::Runner is running at
33
+ # a time - it uses 'chdir' to read config files with ERB,
34
+ # which can conflict with other chdirs.
35
+ result = Solargraph::CHDIR_MUTEX.synchronize do
36
+ redirect_stdout{ runner.run(paths) }
37
+ end
38
+
39
+ return [] if result.empty?
40
+
41
+ make_array JSON.parse(result)
42
+ rescue RuboCop::ValidationError, RuboCop::ConfigNotFoundError => e
43
+ raise DiagnosticsError, "Error in RuboCop configuration: #{e.message}"
44
+ rescue JSON::ParserError => e
45
+ raise DiagnosticsError, "RuboCop returned invalid data: #{e.message}"
46
+ end
47
+
48
+ private
49
+
50
+ # Extracts the rubocop version from _args_
51
+ #
52
+ # @return [String]
53
+ def rubocop_version
54
+ args.find { |a| a =~ /version=/ }.to_s.split('=').last
55
+ end
56
+
57
+ # @param resp [Hash{String => Array<Hash{String => Array<Hash{String => undefined}>}>}]
58
+ # @return [Array<Hash>]
59
+ def make_array resp
60
+ diagnostics = []
61
+ resp['files'].each do |file|
62
+ file['offenses'].each do |off|
63
+ diagnostics.push offense_to_diagnostic(off)
64
+ end
65
+ end
66
+ diagnostics
67
+ end
68
+
69
+ # Convert a RuboCop offense to an LSP diagnostic
70
+ #
71
+ # @param off [Hash{String => unknown}] Offense received from Rubocop
72
+ # @return [Hash{Symbol => Hash, String, Integer}] LSP diagnostic
73
+ def offense_to_diagnostic off
74
+ {
75
+ range: offense_range(off).to_hash,
76
+ # 1 = Error, 2 = Warning, 3 = Information, 4 = Hint
77
+ severity: SEVERITIES[off['severity']],
78
+ source: 'rubocop',
79
+ code: off['cop_name'],
80
+ message: off['message'].gsub(/^#{off['cop_name']}\:/, '')
81
+ }
82
+ end
83
+
84
+ # @param off [Hash]
85
+ # @return [Range]
86
+ def offense_range off
87
+ Range.new(offense_start_position(off), offense_ending_position(off))
88
+ end
89
+
90
+ # @param off [Hash{String => Hash{String => Integer}}]
91
+ # @return [Position]
92
+ def offense_start_position off
93
+ Position.new(off['location']['start_line'] - 1, off['location']['start_column'] - 1)
94
+ end
95
+
96
+ # @param off [Hash{String => Hash{String => Integer}}]
97
+ # @return [Position]
98
+ def offense_ending_position off
99
+ if off['location']['start_line'] != off['location']['last_line']
100
+ Position.new(off['location']['start_line'], 0)
101
+ else
102
+ start_line = off['location']['start_line'] - 1
103
+ # @type [Integer]
104
+ last_column = off['location']['last_column']
105
+ line = @source.code.lines[start_line]
106
+ col_off = if line.nil? || line.empty?
107
+ 1
108
+ else
109
+ 0
110
+ end
111
+
112
+ Position.new(
113
+ start_line, last_column - col_off
114
+ )
115
+ end
116
+ end
117
+ end
118
+ end
119
+ end
@@ -1,68 +1,70 @@
1
- # frozen_string_literal: true
2
-
3
- module Solargraph
4
- module Diagnostics
5
- # Utility methods for the RuboCop diagnostics reporter.
6
- #
7
- module RubocopHelpers
8
- module_function
9
-
10
- # Requires a specific version of rubocop, or the latest installed version
11
- # if _version_ is `nil`.
12
- #
13
- # @param version [String, nil]
14
- # @raise [InvalidRubocopVersionError] if _version_ is not installed
15
- # @return [void]
16
- def require_rubocop(version = nil)
17
- begin
18
- # @type [String]
19
- gem_path = Gem::Specification.find_by_name('rubocop', version).full_gem_path
20
- gem_lib_path = File.join(gem_path, 'lib')
21
- $LOAD_PATH.unshift(gem_lib_path) unless $LOAD_PATH.include?(gem_lib_path)
22
- rescue Gem::MissingSpecVersionError => e
23
- # @type [Array<Gem::Specification>]
24
- specs = e.specs
25
- raise InvalidRubocopVersionError,
26
- "could not find '#{e.name}' (#{e.requirement}) - "\
27
- "did find: [#{specs.map { |s| s.version.version }.join(', ')}]"
28
- end
29
- require 'rubocop'
30
- end
31
-
32
- # Generate command-line options for the specified filename and code.
33
- #
34
- # @param filename [String]
35
- # @param code [String]
36
- # @return [Array(Array<String>, Array<String>)]
37
- def generate_options filename, code
38
- args = ['-f', 'j', '--force-exclusion', filename]
39
- base_options = RuboCop::Options.new
40
- options, paths = base_options.parse(args)
41
- # @sg-ignore
42
- options[:stdin] = code
43
- [options, paths]
44
- end
45
-
46
- # RuboCop internally uses capitalized drive letters for Windows paths,
47
- # so we need to convert the paths provided to the command.
48
- #
49
- # @param path [String]
50
- # @return [String]
51
- def fix_drive_letter path
52
- return path unless path.match(/^[a-z]:/)
53
- path[0].upcase + path[1..-1]
54
- end
55
-
56
- # @todo This is a smelly way to redirect output, but the RuboCop specs do
57
- # the same thing.
58
- # @return [String]
59
- def redirect_stdout
60
- redir = StringIO.new
61
- $stdout = redir
62
- yield if block_given?
63
- $stdout = STDOUT
64
- redir.string
65
- end
66
- end
67
- end
68
- end
1
+ # frozen_string_literal: true
2
+
3
+ module Solargraph
4
+ module Diagnostics
5
+ # Utility methods for the RuboCop diagnostics reporter.
6
+ #
7
+ module RubocopHelpers
8
+ module_function
9
+
10
+ # Requires a specific version of rubocop, or the latest installed version
11
+ # if _version_ is `nil`.
12
+ #
13
+ # @param version [String, nil]
14
+ # @raise [InvalidRubocopVersionError] if _version_ is not installed
15
+ # @return [void]
16
+ def require_rubocop(version = nil)
17
+ begin
18
+ # @type [String]
19
+ gem_path = Gem::Specification.find_by_name('rubocop', version).full_gem_path
20
+ gem_lib_path = File.join(gem_path, 'lib')
21
+ # @sg-ignore Should better support meaning of '&' in RBS
22
+ $LOAD_PATH.unshift(gem_lib_path) unless $LOAD_PATH.include?(gem_lib_path)
23
+ rescue Gem::MissingSpecVersionError => e
24
+ # @type [Array<Gem::Specification>]
25
+ specs = e.specs
26
+ raise InvalidRubocopVersionError,
27
+ "could not find '#{e.name}' (#{e.requirement}) - "\
28
+ "did find: [#{specs.map { |s| s.version.version }.join(', ')}]"
29
+ end
30
+ require 'rubocop'
31
+ end
32
+
33
+ # Generate command-line options for the specified filename and code.
34
+ #
35
+ # @param filename [String]
36
+ # @param code [String]
37
+ # @return [Array(Array<String>, Array<String>)]
38
+ def generate_options filename, code
39
+ args = ['-f', 'j', '--force-exclusion', filename]
40
+ base_options = RuboCop::Options.new
41
+ options, paths = base_options.parse(args)
42
+ # @sg-ignore
43
+ options[:stdin] = code
44
+ [options, paths]
45
+ end
46
+
47
+ # RuboCop internally uses capitalized drive letters for Windows paths,
48
+ # so we need to convert the paths provided to the command.
49
+ #
50
+ # @param path [String]
51
+ # @return [String]
52
+ def fix_drive_letter path
53
+ return path unless path.match(/^[a-z]:/)
54
+ # @sg-ignore Need to add nil check here
55
+ path[0].upcase + path[1..-1]
56
+ end
57
+
58
+ # @todo This is a smelly way to redirect output, but the RuboCop specs do
59
+ # the same thing.
60
+ # @return [String]
61
+ def redirect_stdout
62
+ redir = StringIO.new
63
+ $stdout = redir
64
+ yield if block_given?
65
+ $stdout = STDOUT
66
+ redir.string
67
+ end
68
+ end
69
+ end
70
+ end
@@ -1,55 +1,56 @@
1
- # frozen_string_literal: true
2
-
3
- module Solargraph
4
- module Diagnostics
5
- # TypeCheck reports methods with undefined return types, untagged
6
- # parameters, and invalid param tags.
7
- #
8
- class TypeCheck < Base
9
- # @return [Array<Hash>]
10
- def diagnose source, api_map
11
- # return [] unless args.include?('always') || api_map.workspaced?(source.filename)
12
- severity = Diagnostics::Severities::ERROR
13
- level = (args.reverse.find { |a| ['normal', 'typed', 'strict', 'strong'].include?(a) }) || :normal
14
- checker = Solargraph::TypeChecker.new(source.filename, api_map: api_map, level: level.to_sym)
15
- checker.problems
16
- .sort { |a, b| a.location.range.start.line <=> b.location.range.start.line }
17
- .map do |problem|
18
- {
19
- range: extract_first_line(problem.location, source),
20
- severity: severity,
21
- source: 'Typecheck',
22
- message: problem.message
23
- }
24
- end
25
- end
26
-
27
- private
28
-
29
- # @param location [Location]
30
- # @param source [Source]
31
- # @return [Hash]
32
- def extract_first_line location, source
33
- return location.range.to_hash if location.range.start.line == location.range.ending.line
34
- {
35
- start: {
36
- line: location.range.start.line,
37
- character: location.range.start.character
38
- },
39
- end: {
40
- line: location.range.start.line,
41
- character: last_character(location.range.start, source)
42
- }
43
- }
44
- end
45
-
46
- # @param position [Solargraph::Position]
47
- # @param source [Solargraph::Source]
48
- # @return [Integer]
49
- def last_character position, source
50
- cursor = Position.to_offset(source.code, position)
51
- source.code.index(/[\r\n]/, cursor) || source.code.length
52
- end
53
- end
54
- end
55
- end
1
+ # frozen_string_literal: true
2
+
3
+ module Solargraph
4
+ module Diagnostics
5
+ # TypeCheck reports methods with undefined return types, untagged
6
+ # parameters, and invalid param tags.
7
+ #
8
+ class TypeCheck < Base
9
+ # @return [Array<Hash>]
10
+ def diagnose source, api_map
11
+ # return [] unless args.include?('always') || api_map.workspaced?(source.filename)
12
+ severity = Diagnostics::Severities::ERROR
13
+ level = (args.reverse.find { |a| ['normal', 'typed', 'strict', 'strong'].include?(a) }) || :normal
14
+ # @sg-ignore sensitive typing needs to handle || on nil types
15
+ checker = Solargraph::TypeChecker.new(source.filename, api_map: api_map, level: level.to_sym)
16
+ checker.problems
17
+ .sort { |a, b| a.location.range.start.line <=> b.location.range.start.line }
18
+ .map do |problem|
19
+ {
20
+ range: extract_first_line(problem.location, source),
21
+ severity: severity,
22
+ source: 'Typecheck',
23
+ message: problem.message
24
+ }
25
+ end
26
+ end
27
+
28
+ private
29
+
30
+ # @param location [Location]
31
+ # @param source [Source]
32
+ # @return [Hash]
33
+ def extract_first_line location, source
34
+ return location.range.to_hash if location.range.start.line == location.range.ending.line
35
+ {
36
+ start: {
37
+ line: location.range.start.line,
38
+ character: location.range.start.character
39
+ },
40
+ end: {
41
+ line: location.range.start.line,
42
+ character: last_character(location.range.start, source)
43
+ }
44
+ }
45
+ end
46
+
47
+ # @param position [Solargraph::Position]
48
+ # @param source [Solargraph::Source]
49
+ # @return [Integer]
50
+ def last_character position, source
51
+ cursor = Position.to_offset(source.code, position)
52
+ source.code.index(/[\r\n]/, cursor) || source.code.length
53
+ end
54
+ end
55
+ end
56
+ end