solargraph 0.57.0 → 0.58.3

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 (216) hide show
  1. checksums.yaml +4 -4
  2. data/.gitattributes +2 -0
  3. data/.github/workflows/linting.yml +4 -2
  4. data/.github/workflows/plugins.yml +63 -28
  5. data/.github/workflows/rspec.yml +19 -4
  6. data/.github/workflows/typecheck.yml +2 -2
  7. data/.gitignore +1 -0
  8. data/.rubocop.yml +1 -1
  9. data/.rubocop_todo.yml +90 -1438
  10. data/CHANGELOG.md +39 -0
  11. data/Rakefile +1 -1
  12. data/bin/solargraph +3 -0
  13. data/lib/solargraph/api_map/cache.rb +110 -110
  14. data/lib/solargraph/api_map/constants.rb +279 -218
  15. data/lib/solargraph/api_map/index.rb +193 -169
  16. data/lib/solargraph/api_map/source_to_yard.rb +97 -94
  17. data/lib/solargraph/api_map/store.rb +384 -374
  18. data/lib/solargraph/api_map.rb +945 -951
  19. data/lib/solargraph/bench.rb +45 -45
  20. data/lib/solargraph/complex_type/type_methods.rb +228 -223
  21. data/lib/solargraph/complex_type/unique_type.rb +482 -475
  22. data/lib/solargraph/complex_type.rb +444 -427
  23. data/lib/solargraph/convention/active_support_concern.rb +1 -1
  24. data/lib/solargraph/convention/data_definition/data_assignment_node.rb +61 -61
  25. data/lib/solargraph/convention/data_definition/data_definition_node.rb +91 -91
  26. data/lib/solargraph/convention/data_definition.rb +105 -105
  27. data/lib/solargraph/convention/gemfile.rb +15 -15
  28. data/lib/solargraph/convention/gemspec.rb +23 -23
  29. data/lib/solargraph/convention/rakefile.rb +17 -17
  30. data/lib/solargraph/convention/struct_definition/struct_assignment_node.rb +61 -61
  31. data/lib/solargraph/convention/struct_definition/struct_definition_node.rb +102 -102
  32. data/lib/solargraph/convention/struct_definition.rb +164 -164
  33. data/lib/solargraph/convention.rb +78 -78
  34. data/lib/solargraph/converters/dd.rb +17 -17
  35. data/lib/solargraph/converters/dl.rb +15 -15
  36. data/lib/solargraph/converters/dt.rb +15 -15
  37. data/lib/solargraph/converters/misc.rb +1 -1
  38. data/lib/solargraph/diagnostics/require_not_found.rb +53 -53
  39. data/lib/solargraph/diagnostics/rubocop.rb +118 -118
  40. data/lib/solargraph/diagnostics/rubocop_helpers.rb +68 -66
  41. data/lib/solargraph/diagnostics/type_check.rb +55 -55
  42. data/lib/solargraph/diagnostics/update_errors.rb +41 -41
  43. data/lib/solargraph/doc_map.rb +439 -436
  44. data/lib/solargraph/environ.rb +1 -1
  45. data/lib/solargraph/equality.rb +34 -33
  46. data/lib/solargraph/gem_pins.rb +98 -94
  47. data/lib/solargraph/language_server/error_codes.rb +20 -20
  48. data/lib/solargraph/language_server/host/diagnoser.rb +89 -89
  49. data/lib/solargraph/language_server/host/dispatch.rb +130 -130
  50. data/lib/solargraph/language_server/host/message_worker.rb +112 -112
  51. data/lib/solargraph/language_server/host/sources.rb +99 -99
  52. data/lib/solargraph/language_server/host.rb +878 -872
  53. data/lib/solargraph/language_server/message/base.rb +97 -97
  54. data/lib/solargraph/language_server/message/client/register_capability.rb +15 -15
  55. data/lib/solargraph/language_server/message/completion_item/resolve.rb +60 -60
  56. data/lib/solargraph/language_server/message/extended/check_gem_version.rb +114 -114
  57. data/lib/solargraph/language_server/message/extended/document.rb +23 -23
  58. data/lib/solargraph/language_server/message/extended/document_gems.rb +32 -32
  59. data/lib/solargraph/language_server/message/extended/download_core.rb +19 -19
  60. data/lib/solargraph/language_server/message/extended/search.rb +20 -20
  61. data/lib/solargraph/language_server/message/initialize.rb +191 -191
  62. data/lib/solargraph/language_server/message/text_document/completion.rb +56 -56
  63. data/lib/solargraph/language_server/message/text_document/definition.rb +40 -40
  64. data/lib/solargraph/language_server/message/text_document/document_highlight.rb +16 -16
  65. data/lib/solargraph/language_server/message/text_document/document_symbol.rb +26 -26
  66. data/lib/solargraph/language_server/message/text_document/formatting.rb +148 -145
  67. data/lib/solargraph/language_server/message/text_document/hover.rb +58 -58
  68. data/lib/solargraph/language_server/message/text_document/prepare_rename.rb +11 -11
  69. data/lib/solargraph/language_server/message/text_document/references.rb +16 -16
  70. data/lib/solargraph/language_server/message/text_document/rename.rb +19 -19
  71. data/lib/solargraph/language_server/message/text_document/signature_help.rb +24 -24
  72. data/lib/solargraph/language_server/message/text_document/type_definition.rb +25 -25
  73. data/lib/solargraph/language_server/message/workspace/did_change_configuration.rb +35 -35
  74. data/lib/solargraph/language_server/message/workspace/did_change_watched_files.rb +40 -40
  75. data/lib/solargraph/language_server/message/workspace/did_change_workspace_folders.rb +26 -26
  76. data/lib/solargraph/language_server/message/workspace/workspace_symbol.rb +23 -23
  77. data/lib/solargraph/language_server/message.rb +94 -94
  78. data/lib/solargraph/language_server/progress.rb +1 -1
  79. data/lib/solargraph/language_server/request.rb +27 -25
  80. data/lib/solargraph/language_server/transport/data_reader.rb +74 -74
  81. data/lib/solargraph/language_server/uri_helpers.rb +49 -49
  82. data/lib/solargraph/library.rb +683 -683
  83. data/lib/solargraph/location.rb +82 -81
  84. data/lib/solargraph/logging.rb +37 -37
  85. data/lib/solargraph/page.rb +92 -93
  86. data/lib/solargraph/parser/comment_ripper.rb +69 -69
  87. data/lib/solargraph/parser/flow_sensitive_typing.rb +255 -255
  88. data/lib/solargraph/parser/node_processor/base.rb +92 -92
  89. data/lib/solargraph/parser/node_processor.rb +62 -62
  90. data/lib/solargraph/parser/parser_gem/class_methods.rb +149 -159
  91. data/lib/solargraph/parser/parser_gem/flawed_builder.rb +19 -19
  92. data/lib/solargraph/parser/parser_gem/node_chainer.rb +166 -166
  93. data/lib/solargraph/parser/parser_gem/node_methods.rb +486 -499
  94. data/lib/solargraph/parser/parser_gem/node_processors/and_node.rb +22 -21
  95. data/lib/solargraph/parser/parser_gem/node_processors/args_node.rb +59 -59
  96. data/lib/solargraph/parser/parser_gem/node_processors/begin_node.rb +15 -15
  97. data/lib/solargraph/parser/parser_gem/node_processors/block_node.rb +46 -46
  98. data/lib/solargraph/parser/parser_gem/node_processors/def_node.rb +53 -53
  99. data/lib/solargraph/parser/parser_gem/node_processors/defs_node.rb +37 -37
  100. data/lib/solargraph/parser/parser_gem/node_processors/if_node.rb +23 -23
  101. data/lib/solargraph/parser/parser_gem/node_processors/ivasgn_node.rb +40 -40
  102. data/lib/solargraph/parser/parser_gem/node_processors/lvasgn_node.rb +29 -29
  103. data/lib/solargraph/parser/parser_gem/node_processors/masgn_node.rb +59 -59
  104. data/lib/solargraph/parser/parser_gem/node_processors/opasgn_node.rb +98 -42
  105. data/lib/solargraph/parser/parser_gem/node_processors/orasgn_node.rb +17 -17
  106. data/lib/solargraph/parser/parser_gem/node_processors/resbody_node.rb +38 -38
  107. data/lib/solargraph/parser/parser_gem/node_processors/sclass_node.rb +52 -43
  108. data/lib/solargraph/parser/parser_gem/node_processors/send_node.rb +291 -292
  109. data/lib/solargraph/parser/parser_gem/node_processors/until_node.rb +29 -29
  110. data/lib/solargraph/parser/parser_gem/node_processors/while_node.rb +29 -29
  111. data/lib/solargraph/parser/parser_gem/node_processors.rb +70 -70
  112. data/lib/solargraph/parser/parser_gem.rb +12 -12
  113. data/lib/solargraph/parser/region.rb +69 -69
  114. data/lib/solargraph/parser/snippet.rb +17 -17
  115. data/lib/solargraph/parser.rb +23 -23
  116. data/lib/solargraph/pin/base.rb +729 -708
  117. data/lib/solargraph/pin/base_variable.rb +126 -124
  118. data/lib/solargraph/pin/block.rb +104 -103
  119. data/lib/solargraph/pin/breakable.rb +9 -9
  120. data/lib/solargraph/pin/callable.rb +231 -227
  121. data/lib/solargraph/pin/closure.rb +72 -76
  122. data/lib/solargraph/pin/common.rb +79 -79
  123. data/lib/solargraph/pin/constant.rb +45 -45
  124. data/lib/solargraph/pin/conversions.rb +123 -123
  125. data/lib/solargraph/pin/delegated_method.rb +120 -121
  126. data/lib/solargraph/pin/documenting.rb +114 -114
  127. data/lib/solargraph/pin/instance_variable.rb +34 -34
  128. data/lib/solargraph/pin/keyword.rb +20 -20
  129. data/lib/solargraph/pin/local_variable.rb +75 -79
  130. data/lib/solargraph/pin/method.rb +672 -656
  131. data/lib/solargraph/pin/method_alias.rb +34 -34
  132. data/lib/solargraph/pin/namespace.rb +115 -115
  133. data/lib/solargraph/pin/parameter.rb +275 -271
  134. data/lib/solargraph/pin/proxy_type.rb +39 -36
  135. data/lib/solargraph/pin/reference/override.rb +47 -47
  136. data/lib/solargraph/pin/reference/superclass.rb +15 -15
  137. data/lib/solargraph/pin/reference.rb +39 -48
  138. data/lib/solargraph/pin/search.rb +61 -58
  139. data/lib/solargraph/pin/signature.rb +61 -61
  140. data/lib/solargraph/pin/symbol.rb +53 -53
  141. data/lib/solargraph/pin/until.rb +18 -18
  142. data/lib/solargraph/pin/while.rb +18 -18
  143. data/lib/solargraph/pin.rb +44 -44
  144. data/lib/solargraph/pin_cache.rb +245 -245
  145. data/lib/solargraph/position.rb +132 -118
  146. data/lib/solargraph/range.rb +112 -108
  147. data/lib/solargraph/rbs_map/conversions.rb +823 -802
  148. data/lib/solargraph/rbs_map/core_fills.rb +84 -66
  149. data/lib/solargraph/rbs_map/core_map.rb +58 -54
  150. data/lib/solargraph/rbs_map/stdlib_map.rb +43 -43
  151. data/lib/solargraph/rbs_map.rb +163 -163
  152. data/lib/solargraph/server_methods.rb +16 -16
  153. data/lib/solargraph/shell.rb +363 -271
  154. data/lib/solargraph/source/chain/array.rb +37 -37
  155. data/lib/solargraph/source/chain/call.rb +337 -333
  156. data/lib/solargraph/source/chain/class_variable.rb +13 -13
  157. data/lib/solargraph/source/chain/constant.rb +26 -89
  158. data/lib/solargraph/source/chain/global_variable.rb +13 -13
  159. data/lib/solargraph/source/chain/hash.rb +34 -34
  160. data/lib/solargraph/source/chain/if.rb +28 -28
  161. data/lib/solargraph/source/chain/instance_variable.rb +13 -13
  162. data/lib/solargraph/source/chain/link.rb +109 -109
  163. data/lib/solargraph/source/chain/literal.rb +48 -48
  164. data/lib/solargraph/source/chain/or.rb +23 -23
  165. data/lib/solargraph/source/chain/q_call.rb +11 -11
  166. data/lib/solargraph/source/chain/variable.rb +13 -13
  167. data/lib/solargraph/source/chain/z_super.rb +30 -30
  168. data/lib/solargraph/source/chain.rb +291 -289
  169. data/lib/solargraph/source/change.rb +82 -82
  170. data/lib/solargraph/source/cursor.rb +166 -166
  171. data/lib/solargraph/source/encoding_fixes.rb +23 -23
  172. data/lib/solargraph/source/source_chainer.rb +194 -194
  173. data/lib/solargraph/source/updater.rb +55 -55
  174. data/lib/solargraph/source.rb +498 -498
  175. data/lib/solargraph/source_map/clip.rb +226 -234
  176. data/lib/solargraph/source_map/data.rb +34 -34
  177. data/lib/solargraph/source_map/mapper.rb +259 -261
  178. data/lib/solargraph/source_map.rb +212 -207
  179. data/lib/solargraph/type_checker/checks.rb +124 -124
  180. data/lib/solargraph/type_checker/param_def.rb +37 -37
  181. data/lib/solargraph/type_checker/problem.rb +32 -32
  182. data/lib/solargraph/type_checker/rules.rb +84 -70
  183. data/lib/solargraph/type_checker.rb +814 -752
  184. data/lib/solargraph/version.rb +5 -5
  185. data/lib/solargraph/workspace/config.rb +255 -237
  186. data/lib/solargraph/workspace/require_paths.rb +97 -98
  187. data/lib/solargraph/workspace.rb +220 -225
  188. data/lib/solargraph/yard_map/helpers.rb +44 -44
  189. data/lib/solargraph/yard_map/mapper/to_method.rb +130 -129
  190. data/lib/solargraph/yard_map/mapper/to_namespace.rb +31 -30
  191. data/lib/solargraph/yard_map/mapper.rb +79 -79
  192. data/lib/solargraph/yard_map/to_method.rb +89 -88
  193. data/lib/solargraph/yard_tags.rb +20 -20
  194. data/lib/solargraph/yardoc.rb +87 -64
  195. data/lib/solargraph.rb +105 -105
  196. data/rbs/fills/bundler/0/bundler.rbs +4271 -0
  197. data/rbs/fills/open3/0/open3.rbs +172 -0
  198. data/rbs/fills/rubygems/0/basic_specification.rbs +326 -0
  199. data/rbs/fills/rubygems/0/errors.rbs +364 -0
  200. data/rbs/fills/rubygems/0/spec_fetcher.rbs +107 -0
  201. data/rbs/fills/rubygems/0/specification.rbs +1753 -0
  202. data/rbs/shims/ast/0/node.rbs +5 -0
  203. data/rbs/shims/ast/2.4/.rbs_meta.yaml +9 -0
  204. data/rbs/shims/ast/2.4/ast.rbs +73 -0
  205. data/rbs/shims/parser/3.2.0.1/manifest.yaml +7 -0
  206. data/rbs/shims/parser/3.2.0.1/parser.rbs +201 -0
  207. data/rbs/shims/parser/3.2.0.1/polyfill.rbs +4 -0
  208. data/rbs_collection.yaml +4 -4
  209. data/solargraph.gemspec +15 -4
  210. metadata +71 -16
  211. data/lib/solargraph/parser/node_methods.rb +0 -97
  212. /data/rbs/fills/{tuple.rbs → tuple/tuple.rbs} +0 -0
  213. /data/{sig → rbs}/shims/parser/3.2.0.1/builders/default.rbs +0 -0
  214. /data/{sig → rbs}/shims/thor/1.2.0.1/.rbs_meta.yaml +0 -0
  215. /data/{sig → rbs}/shims/thor/1.2.0.1/manifest.yaml +0 -0
  216. /data/{sig → rbs}/shims/thor/1.2.0.1/thor.rbs +0 -0
@@ -1,5 +1,5 @@
1
- # frozen_string_literal: true
2
-
3
- module Solargraph
4
- VERSION = '0.57.0'
5
- end
1
+ # frozen_string_literal: true
2
+
3
+ module Solargraph
4
+ VERSION = '0.58.3'
5
+ end
@@ -1,237 +1,255 @@
1
- # frozen_string_literal: true
2
-
3
- require 'yaml'
4
-
5
- module Solargraph
6
- class Workspace
7
- # Configuration data for a workspace.
8
- #
9
- class Config
10
- # The maximum number of files that can be added to a workspace.
11
- # The workspace's .solargraph.yml can override this value.
12
- MAX_FILES = 5000
13
-
14
- # @return [String]
15
- attr_reader :directory
16
-
17
- # @todo To make this strongly typed we'll need a record syntax
18
- # @return [Hash{String => Array, Hash, Integer, nil}]
19
- attr_reader :raw_data
20
-
21
- # @param directory [String]
22
- def initialize directory = ''
23
- @directory = File.absolute_path(directory)
24
- @raw_data = config_data
25
- included
26
- excluded
27
- end
28
-
29
- # An array of files included in the workspace (before calculating excluded files).
30
- #
31
- # @return [Array<String>]
32
- def included
33
- return [] if directory.empty? || directory == '*'
34
- @included ||= process_globs(@raw_data['include'])
35
- end
36
-
37
- # An array of files excluded from the workspace.
38
- #
39
- # @return [Array<String>]
40
- def excluded
41
- return [] if directory.empty? || directory == '*'
42
- @excluded ||= process_exclusions(@raw_data['exclude'])
43
- end
44
-
45
- # @param filename [String]
46
- def allow? filename
47
- filename = File.absolute_path(filename, directory)
48
- filename.start_with?(directory) &&
49
- !excluded.include?(filename) &&
50
- excluded_directories.none? { |d| filename.start_with?(d) }
51
- end
52
-
53
- # The calculated array of (included - excluded) files in the workspace.
54
- #
55
- # @return [Array<String>]
56
- def calculated
57
- Solargraph.logger.info "Indexing workspace files in #{directory}" unless @calculated || directory.empty? || directory == '*'
58
- @calculated ||= included - excluded
59
- end
60
-
61
- # An array of domains configured for the workspace.
62
- # A domain is a namespace that the ApiMap should include in the global
63
- # namespace. It's typically used to identify available DSLs.
64
- #
65
- # @return [Array<String>]
66
- def domains
67
- raw_data['domains']
68
- end
69
-
70
- # An array of required paths to add to the workspace.
71
- #
72
- # @return [Array<String>]
73
- def required
74
- raw_data['require']
75
- end
76
-
77
- # An array of load paths for required paths.
78
- #
79
- # @return [Array<String>]
80
- def require_paths
81
- raw_data['require_paths'] || []
82
- end
83
-
84
- # An array of reporters to use for diagnostics.
85
- #
86
- # @return [Array<String>]
87
- def reporters
88
- raw_data['reporters']
89
- end
90
-
91
- # A hash of options supported by the formatter
92
- #
93
- # @return [Hash]
94
- def formatter
95
- raw_data['formatter']
96
- end
97
-
98
- # An array of plugins to require.
99
- #
100
- # @return [Array<String>]
101
- def plugins
102
- raw_data['plugins']
103
- end
104
-
105
- # The maximum number of files to parse from the workspace.
106
- #
107
- # @return [Integer]
108
- def max_files
109
- raw_data['max_files']
110
- end
111
-
112
- private
113
-
114
- # @return [String]
115
- def global_config_path
116
- ENV['SOLARGRAPH_GLOBAL_CONFIG'] ||
117
- File.join(Dir.home, '.config', 'solargraph', 'config.yml')
118
- end
119
-
120
- # @return [String]
121
- def workspace_config_path
122
- return '' if @directory.empty?
123
- File.join(@directory, '.solargraph.yml')
124
- end
125
-
126
- # @return [Hash{String => Array<undefined>, Hash{String => undefined}, Integer}]
127
- def config_data
128
- workspace_config = read_config(workspace_config_path)
129
- global_config = read_config(global_config_path)
130
-
131
- defaults = default_config
132
- defaults.merge({'exclude' => []}) unless workspace_config.nil?
133
-
134
- defaults
135
- .merge(global_config || {})
136
- .merge(workspace_config || {})
137
- end
138
-
139
- # Read a .solargraph yaml config
140
- #
141
- # @param config_path [String]
142
- # @return [Hash{String => Array, Hash, Integer}, nil]
143
- def read_config config_path = ''
144
- return nil if config_path.empty?
145
- return nil unless File.file?(config_path)
146
- YAML.safe_load(File.read(config_path))
147
- end
148
-
149
- # @return [Hash{String => Array, Hash, Integer}]
150
- def default_config
151
- {
152
- 'include' => ['Rakefile', 'Gemfile', '*.gemspec', '**/*.rb'],
153
- 'exclude' => ['spec/**/*', 'test/**/*', 'vendor/**/*', '.bundle/**/*'],
154
- 'require' => [],
155
- 'domains' => [],
156
- 'reporters' => %w[rubocop require_not_found],
157
- 'formatter' => {
158
- 'rubocop' => {
159
- 'cops' => 'safe',
160
- 'except' => [],
161
- 'only' => [],
162
- 'extra_args' =>[]
163
- }
164
- },
165
- 'require_paths' => [],
166
- 'plugins' => [],
167
- 'max_files' => MAX_FILES
168
- }
169
- end
170
-
171
- # Get an array of files from the provided globs.
172
- #
173
- # @param globs [Array<String>]
174
- # @return [Array<String>]
175
- def process_globs globs
176
- result = globs.flat_map do |glob|
177
- Dir[File.absolute_path(glob, directory)]
178
- .map{ |f| f.gsub(/\\/, '/') }
179
- .select { |f| File.file?(f) }
180
- end
181
- result
182
- end
183
-
184
- # Modify the included files based on excluded directories and get an
185
- # array of additional files to exclude.
186
- #
187
- # @param globs [Array<String>]
188
- # @return [Array<String>]
189
- def process_exclusions globs
190
- remainder = globs.select do |glob|
191
- if glob_is_directory?(glob)
192
- exdir = File.absolute_path(glob_to_directory(glob), directory)
193
- included.delete_if { |file| file.start_with?(exdir) }
194
- false
195
- else
196
- true
197
- end
198
- end
199
- process_globs remainder
200
- end
201
-
202
- # True if the glob translates to a whole directory.
203
- #
204
- # @example
205
- # glob_is_directory?('path/to/dir') # => true
206
- # glob_is_directory?('path/to/dir/**/*) # => true
207
- # glob_is_directory?('path/to/file.txt') # => false
208
- # glob_is_directory?('path/to/*.txt') # => false
209
- #
210
- # @param glob [String]
211
- # @return [Boolean]
212
- def glob_is_directory? glob
213
- File.directory?(glob) || File.directory?(glob_to_directory(glob))
214
- end
215
-
216
- # Translate a glob to a base directory if applicable
217
- #
218
- # @example
219
- # glob_to_directory('path/to/dir/**/*') # => 'path/to/dir'
220
- #
221
- # @param glob [String]
222
- # @return [String]
223
- def glob_to_directory glob
224
- glob.gsub(/(\/\*|\/\*\*\/\*\*?)$/, '')
225
- end
226
-
227
- # @return [Array<String>]
228
- def excluded_directories
229
- # @type [Array<String>]
230
- excluded = @raw_data['exclude']
231
- excluded
232
- .select { |g| glob_is_directory?(g) }
233
- .map { |g| File.absolute_path(glob_to_directory(g), directory) }
234
- end
235
- end
236
- end
237
- end
1
+ # frozen_string_literal: true
2
+
3
+ require 'yaml'
4
+
5
+ module Solargraph
6
+ class Workspace
7
+ # Configuration data for a workspace.
8
+ #
9
+ class Config
10
+ # The maximum number of files that can be added to a workspace.
11
+ # The workspace's .solargraph.yml can override this value.
12
+ MAX_FILES = 5000
13
+
14
+ # @return [String]
15
+ attr_reader :directory
16
+
17
+ # @todo To make JSON strongly typed we'll need a record syntax
18
+ # @return [Hash{String => undefined, nil}]
19
+ attr_reader :raw_data
20
+
21
+ # @param directory [String]
22
+ def initialize directory = ''
23
+ @directory = File.absolute_path(directory)
24
+ @raw_data = config_data
25
+ included
26
+ excluded
27
+ end
28
+
29
+ # An array of files included in the workspace (before calculating excluded files).
30
+ #
31
+ # @return [Array<String>]
32
+ def included
33
+ return [] if directory.empty? || directory == '*'
34
+ @included ||= process_globs(@raw_data['include'])
35
+ end
36
+
37
+ # An array of files excluded from the workspace.
38
+ #
39
+ # @return [Array<String>]
40
+ def excluded
41
+ return [] if directory.empty? || directory == '*'
42
+ @excluded ||= process_exclusions(@raw_data['exclude'])
43
+ end
44
+
45
+ # @param filename [String]
46
+ def allow? filename
47
+ filename = File.absolute_path(filename, directory)
48
+ filename.start_with?(directory) &&
49
+ !excluded.include?(filename) &&
50
+ excluded_directories.none? { |d| filename.start_with?(d) }
51
+ end
52
+
53
+ # The calculated array of (included - excluded) files in the workspace.
54
+ #
55
+ # @return [Array<String>]
56
+ def calculated
57
+ Solargraph.logger.info "Indexing workspace files in #{directory}" unless @calculated || directory.empty? || directory == '*'
58
+ @calculated ||= included - excluded
59
+ end
60
+
61
+ # An array of domains configured for the workspace.
62
+ # A domain is a namespace that the ApiMap should include in the global
63
+ # namespace. It's typically used to identify available DSLs.
64
+ #
65
+ # @return [Array<String>]
66
+ # @sg-ignore Need to validate config
67
+ def domains
68
+ raw_data['domains']
69
+ end
70
+
71
+ # An array of required paths to add to the workspace.
72
+ #
73
+ # @return [Array<String>]
74
+ # @sg-ignore Need to validate config
75
+ def required
76
+ raw_data['require']
77
+ end
78
+
79
+ # An array of load paths for required paths.
80
+ #
81
+ # @return [Array<String>]
82
+ def require_paths
83
+ raw_data['require_paths'] || []
84
+ end
85
+
86
+ # An array of reporters to use for diagnostics.
87
+ #
88
+ # @sg-ignore Need to validate config
89
+ # @return [Array<String>]
90
+ def reporters
91
+ raw_data['reporters']
92
+ end
93
+
94
+ # A hash of options supported by the formatter
95
+ #
96
+ # @sg-ignore Need to validate config
97
+ # @return [Hash]
98
+ def formatter
99
+ raw_data['formatter']
100
+ end
101
+
102
+ # An array of plugins to require.
103
+ #
104
+ # @sg-ignore Need to validate config
105
+ # @return [Array<String>]
106
+ def plugins
107
+ raw_data['plugins']
108
+ end
109
+
110
+ # The maximum number of files to parse from the workspace.
111
+ #
112
+ # @sg-ignore Need to validate config
113
+ # @return [Integer]
114
+ def max_files
115
+ raw_data['max_files']
116
+ end
117
+
118
+ # @return [Hash{Symbol => Symbol}]
119
+ def type_checker_rules
120
+ # @type [Hash{String => String}]
121
+ raw_rules = raw_data.fetch('type_checker', {}).fetch('rules', {})
122
+ raw_rules.to_h do |k, v|
123
+ [k.to_sym, v.to_sym]
124
+ end
125
+ end
126
+
127
+ private
128
+
129
+ # @return [String]
130
+ def global_config_path
131
+ ENV['SOLARGRAPH_GLOBAL_CONFIG'] ||
132
+ File.join(Dir.home, '.config', 'solargraph', 'config.yml')
133
+ end
134
+
135
+ # @return [String]
136
+ def workspace_config_path
137
+ return '' if @directory.empty?
138
+ File.join(@directory, '.solargraph.yml')
139
+ end
140
+
141
+ # @return [Hash{String => undefined}]
142
+ def config_data
143
+ workspace_config = read_config(workspace_config_path)
144
+ global_config = read_config(global_config_path)
145
+
146
+ defaults = default_config
147
+ defaults.merge({'exclude' => []}) unless workspace_config.nil?
148
+
149
+ defaults
150
+ .merge(global_config || {})
151
+ .merge(workspace_config || {})
152
+ end
153
+
154
+ # Read a .solargraph yaml config
155
+ #
156
+ # @param config_path [String]
157
+ # @return [Hash{String => Array, Hash, Integer}, nil]
158
+ def read_config config_path = ''
159
+ return nil if config_path.empty?
160
+ return nil unless File.file?(config_path)
161
+ YAML.safe_load(File.read(config_path))
162
+ end
163
+
164
+ # @return [Hash{String => Array, Hash, Integer}]
165
+ def default_config
166
+ {
167
+ 'include' => ['Rakefile', 'Gemfile', '*.gemspec', '**/*.rb'],
168
+ 'exclude' => ['spec/**/*', 'test/**/*', 'vendor/**/*', '.bundle/**/*'],
169
+ 'require' => [],
170
+ 'domains' => [],
171
+ 'reporters' => %w[rubocop require_not_found],
172
+ 'formatter' => {
173
+ 'rubocop' => {
174
+ 'cops' => 'safe',
175
+ 'except' => [],
176
+ 'only' => [],
177
+ 'extra_args' =>[]
178
+ }
179
+ },
180
+ 'type_checker' => {
181
+ 'rules' => { }
182
+ },
183
+ 'require_paths' => [],
184
+ 'plugins' => [],
185
+ 'max_files' => MAX_FILES
186
+ }
187
+ end
188
+
189
+ # Get an array of files from the provided globs.
190
+ #
191
+ # @param globs [Array<String>]
192
+ # @return [Array<String>]
193
+ def process_globs globs
194
+ result = globs.flat_map do |glob|
195
+ Dir[File.absolute_path(glob, directory)]
196
+ .map{ |f| f.gsub(/\\/, '/') }
197
+ .select { |f| File.file?(f) }
198
+ end
199
+ result
200
+ end
201
+
202
+ # Modify the included files based on excluded directories and get an
203
+ # array of additional files to exclude.
204
+ #
205
+ # @param globs [Array<String>]
206
+ # @return [Array<String>]
207
+ def process_exclusions globs
208
+ remainder = globs.select do |glob|
209
+ if glob_is_directory?(glob)
210
+ exdir = File.absolute_path(glob_to_directory(glob), directory)
211
+ included.delete_if { |file| file.start_with?(exdir) }
212
+ false
213
+ else
214
+ true
215
+ end
216
+ end
217
+ process_globs remainder
218
+ end
219
+
220
+ # True if the glob translates to a whole directory.
221
+ #
222
+ # @example
223
+ # glob_is_directory?('path/to/dir') # => true
224
+ # glob_is_directory?('path/to/dir/**/*) # => true
225
+ # glob_is_directory?('path/to/file.txt') # => false
226
+ # glob_is_directory?('path/to/*.txt') # => false
227
+ #
228
+ # @param glob [String]
229
+ # @return [Boolean]
230
+ def glob_is_directory? glob
231
+ File.directory?(glob) || File.directory?(glob_to_directory(glob))
232
+ end
233
+
234
+ # Translate a glob to a base directory if applicable
235
+ #
236
+ # @example
237
+ # glob_to_directory('path/to/dir/**/*') # => 'path/to/dir'
238
+ #
239
+ # @param glob [String]
240
+ # @return [String]
241
+ def glob_to_directory glob
242
+ glob.gsub(/(\/\*|\/\*\*\/\*\*?)$/, '')
243
+ end
244
+
245
+ # @return [Array<String>]
246
+ def excluded_directories
247
+ # @type [Array<String>]
248
+ excluded = @raw_data['exclude']
249
+ excluded
250
+ .select { |g| glob_is_directory?(g) }
251
+ .map { |g| File.absolute_path(glob_to_directory(g), directory) }
252
+ end
253
+ end
254
+ end
255
+ end