solargraph 0.58.1 → 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 (162) hide show
  1. checksums.yaml +4 -4
  2. data/.envrc +3 -0
  3. data/.github/workflows/linting.yml +4 -5
  4. data/.github/workflows/plugins.yml +40 -36
  5. data/.github/workflows/rspec.yml +45 -13
  6. data/.github/workflows/typecheck.yml +2 -2
  7. data/.rubocop_todo.yml +27 -49
  8. data/README.md +3 -3
  9. data/Rakefile +1 -0
  10. data/lib/solargraph/api_map/cache.rb +110 -110
  11. data/lib/solargraph/api_map/constants.rb +289 -279
  12. data/lib/solargraph/api_map/index.rb +204 -193
  13. data/lib/solargraph/api_map/source_to_yard.rb +109 -97
  14. data/lib/solargraph/api_map/store.rb +387 -384
  15. data/lib/solargraph/api_map.rb +1000 -945
  16. data/lib/solargraph/complex_type/conformance.rb +176 -0
  17. data/lib/solargraph/complex_type/type_methods.rb +242 -228
  18. data/lib/solargraph/complex_type/unique_type.rb +632 -482
  19. data/lib/solargraph/complex_type.rb +549 -444
  20. data/lib/solargraph/convention/data_definition/data_definition_node.rb +93 -91
  21. data/lib/solargraph/convention/data_definition.rb +108 -105
  22. data/lib/solargraph/convention/struct_definition/struct_assignment_node.rb +62 -61
  23. data/lib/solargraph/convention/struct_definition/struct_definition_node.rb +103 -102
  24. data/lib/solargraph/convention/struct_definition.rb +168 -164
  25. data/lib/solargraph/diagnostics/require_not_found.rb +54 -53
  26. data/lib/solargraph/diagnostics/rubocop.rb +119 -118
  27. data/lib/solargraph/diagnostics/rubocop_helpers.rb +70 -68
  28. data/lib/solargraph/diagnostics/type_check.rb +56 -55
  29. data/lib/solargraph/doc_map.rb +200 -439
  30. data/lib/solargraph/equality.rb +34 -34
  31. data/lib/solargraph/gem_pins.rb +97 -98
  32. data/lib/solargraph/language_server/host/dispatch.rb +131 -130
  33. data/lib/solargraph/language_server/host/message_worker.rb +113 -112
  34. data/lib/solargraph/language_server/host/sources.rb +100 -99
  35. data/lib/solargraph/language_server/host.rb +883 -878
  36. data/lib/solargraph/language_server/message/extended/check_gem_version.rb +109 -114
  37. data/lib/solargraph/language_server/message/extended/document.rb +24 -23
  38. data/lib/solargraph/language_server/message/text_document/completion.rb +58 -56
  39. data/lib/solargraph/language_server/message/text_document/definition.rb +42 -40
  40. data/lib/solargraph/language_server/message/text_document/document_symbol.rb +28 -26
  41. data/lib/solargraph/language_server/message/text_document/formatting.rb +150 -148
  42. data/lib/solargraph/language_server/message/text_document/hover.rb +60 -58
  43. data/lib/solargraph/language_server/message/text_document/signature_help.rb +25 -24
  44. data/lib/solargraph/language_server/message/text_document/type_definition.rb +27 -25
  45. data/lib/solargraph/language_server/message/workspace/workspace_symbol.rb +25 -23
  46. data/lib/solargraph/library.rb +729 -683
  47. data/lib/solargraph/location.rb +87 -82
  48. data/lib/solargraph/logging.rb +57 -37
  49. data/lib/solargraph/parser/comment_ripper.rb +76 -69
  50. data/lib/solargraph/parser/flow_sensitive_typing.rb +483 -255
  51. data/lib/solargraph/parser/node_processor/base.rb +122 -92
  52. data/lib/solargraph/parser/node_processor.rb +63 -62
  53. data/lib/solargraph/parser/parser_gem/class_methods.rb +167 -149
  54. data/lib/solargraph/parser/parser_gem/node_chainer.rb +191 -166
  55. data/lib/solargraph/parser/parser_gem/node_methods.rb +506 -486
  56. data/lib/solargraph/parser/parser_gem/node_processors/and_node.rb +22 -22
  57. data/lib/solargraph/parser/parser_gem/node_processors/args_node.rb +61 -59
  58. data/lib/solargraph/parser/parser_gem/node_processors/begin_node.rb +24 -15
  59. data/lib/solargraph/parser/parser_gem/node_processors/block_node.rb +46 -46
  60. data/lib/solargraph/parser/parser_gem/node_processors/def_node.rb +60 -53
  61. data/lib/solargraph/parser/parser_gem/node_processors/if_node.rb +53 -23
  62. data/lib/solargraph/parser/parser_gem/node_processors/ivasgn_node.rb +41 -40
  63. data/lib/solargraph/parser/parser_gem/node_processors/lvasgn_node.rb +30 -29
  64. data/lib/solargraph/parser/parser_gem/node_processors/masgn_node.rb +61 -59
  65. data/lib/solargraph/parser/parser_gem/node_processors/opasgn_node.rb +98 -98
  66. data/lib/solargraph/parser/parser_gem/node_processors/or_node.rb +22 -0
  67. data/lib/solargraph/parser/parser_gem/node_processors/orasgn_node.rb +17 -17
  68. data/lib/solargraph/parser/parser_gem/node_processors/resbody_node.rb +39 -38
  69. data/lib/solargraph/parser/parser_gem/node_processors/sclass_node.rb +53 -52
  70. data/lib/solargraph/parser/parser_gem/node_processors/send_node.rb +296 -291
  71. data/lib/solargraph/parser/parser_gem/node_processors/when_node.rb +23 -0
  72. data/lib/solargraph/parser/parser_gem/node_processors/while_node.rb +33 -29
  73. data/lib/solargraph/parser/parser_gem/node_processors.rb +74 -70
  74. data/lib/solargraph/parser/region.rb +75 -69
  75. data/lib/solargraph/parser/snippet.rb +17 -17
  76. data/lib/solargraph/pin/base.rb +761 -729
  77. data/lib/solargraph/pin/base_variable.rb +418 -126
  78. data/lib/solargraph/pin/block.rb +126 -104
  79. data/lib/solargraph/pin/breakable.rb +13 -9
  80. data/lib/solargraph/pin/callable.rb +278 -231
  81. data/lib/solargraph/pin/closure.rb +68 -72
  82. data/lib/solargraph/pin/common.rb +94 -79
  83. data/lib/solargraph/pin/compound_statement.rb +55 -0
  84. data/lib/solargraph/pin/conversions.rb +124 -123
  85. data/lib/solargraph/pin/delegated_method.rb +131 -120
  86. data/lib/solargraph/pin/documenting.rb +115 -114
  87. data/lib/solargraph/pin/instance_variable.rb +38 -34
  88. data/lib/solargraph/pin/keyword.rb +16 -20
  89. data/lib/solargraph/pin/local_variable.rb +31 -75
  90. data/lib/solargraph/pin/method.rb +720 -672
  91. data/lib/solargraph/pin/method_alias.rb +42 -34
  92. data/lib/solargraph/pin/namespace.rb +121 -115
  93. data/lib/solargraph/pin/parameter.rb +338 -275
  94. data/lib/solargraph/pin/proxy_type.rb +40 -39
  95. data/lib/solargraph/pin/reference/override.rb +47 -47
  96. data/lib/solargraph/pin/reference/superclass.rb +17 -15
  97. data/lib/solargraph/pin/reference.rb +41 -39
  98. data/lib/solargraph/pin/search.rb +62 -61
  99. data/lib/solargraph/pin/signature.rb +69 -61
  100. data/lib/solargraph/pin/symbol.rb +53 -53
  101. data/lib/solargraph/pin/until.rb +18 -18
  102. data/lib/solargraph/pin/while.rb +18 -18
  103. data/lib/solargraph/pin.rb +46 -44
  104. data/lib/solargraph/pin_cache.rb +665 -245
  105. data/lib/solargraph/position.rb +118 -119
  106. data/lib/solargraph/range.rb +112 -112
  107. data/lib/solargraph/rbs_map/conversions.rb +846 -823
  108. data/lib/solargraph/rbs_map/core_map.rb +65 -58
  109. data/lib/solargraph/rbs_map/stdlib_map.rb +72 -43
  110. data/lib/solargraph/rbs_map.rb +217 -163
  111. data/lib/solargraph/shell.rb +397 -352
  112. data/lib/solargraph/source/chain/call.rb +372 -337
  113. data/lib/solargraph/source/chain/constant.rb +28 -26
  114. data/lib/solargraph/source/chain/hash.rb +35 -34
  115. data/lib/solargraph/source/chain/if.rb +29 -28
  116. data/lib/solargraph/source/chain/instance_variable.rb +34 -13
  117. data/lib/solargraph/source/chain/literal.rb +53 -48
  118. data/lib/solargraph/source/chain/or.rb +31 -23
  119. data/lib/solargraph/source/chain.rb +294 -291
  120. data/lib/solargraph/source/change.rb +89 -82
  121. data/lib/solargraph/source/cursor.rb +172 -166
  122. data/lib/solargraph/source/source_chainer.rb +204 -194
  123. data/lib/solargraph/source/updater.rb +59 -55
  124. data/lib/solargraph/source.rb +524 -498
  125. data/lib/solargraph/source_map/clip.rb +237 -226
  126. data/lib/solargraph/source_map/data.rb +37 -34
  127. data/lib/solargraph/source_map/mapper.rb +282 -259
  128. data/lib/solargraph/source_map.rb +220 -212
  129. data/lib/solargraph/type_checker/problem.rb +34 -32
  130. data/lib/solargraph/type_checker/rules.rb +157 -84
  131. data/lib/solargraph/type_checker.rb +895 -814
  132. data/lib/solargraph/version.rb +1 -1
  133. data/lib/solargraph/workspace/config.rb +257 -255
  134. data/lib/solargraph/workspace/gemspecs.rb +367 -0
  135. data/lib/solargraph/workspace/require_paths.rb +98 -97
  136. data/lib/solargraph/workspace.rb +362 -220
  137. data/lib/solargraph/yard_map/helpers.rb +45 -44
  138. data/lib/solargraph/yard_map/mapper/to_method.rb +134 -130
  139. data/lib/solargraph/yard_map/mapper/to_namespace.rb +32 -31
  140. data/lib/solargraph/yard_map/mapper.rb +84 -79
  141. data/lib/solargraph/yardoc.rb +97 -87
  142. data/lib/solargraph.rb +126 -105
  143. data/rbs/fills/rubygems/0/dependency.rbs +193 -0
  144. data/rbs/fills/tuple/tuple.rbs +28 -0
  145. data/rbs/shims/ast/0/node.rbs +5 -0
  146. data/rbs/shims/diff-lcs/1.5/diff-lcs.rbs +11 -0
  147. data/rbs_collection.yaml +1 -1
  148. data/solargraph.gemspec +2 -1
  149. metadata +22 -17
  150. data/lib/solargraph/type_checker/checks.rb +0 -124
  151. data/lib/solargraph/type_checker/param_def.rb +0 -37
  152. data/lib/solargraph/yard_map/to_method.rb +0 -89
  153. data/sig/shims/ast/0/node.rbs +0 -5
  154. /data/{sig → rbs}/shims/ast/2.4/.rbs_meta.yaml +0 -0
  155. /data/{sig → rbs}/shims/ast/2.4/ast.rbs +0 -0
  156. /data/{sig → rbs}/shims/parser/3.2.0.1/builders/default.rbs +0 -0
  157. /data/{sig → rbs}/shims/parser/3.2.0.1/manifest.yaml +0 -0
  158. /data/{sig → rbs}/shims/parser/3.2.0.1/parser.rbs +0 -0
  159. /data/{sig → rbs}/shims/parser/3.2.0.1/polyfill.rbs +0 -0
  160. /data/{sig → rbs}/shims/thor/1.2.0.1/.rbs_meta.yaml +0 -0
  161. /data/{sig → rbs}/shims/thor/1.2.0.1/manifest.yaml +0 -0
  162. /data/{sig → rbs}/shims/thor/1.2.0.1/thor.rbs +0 -0
@@ -1,120 +1,131 @@
1
- # frozen_string_literal: true
2
-
3
- module Solargraph
4
- module Pin
5
- # A DelegatedMethod is a more complicated version of a MethodAlias that
6
- # allows aliasing a method from a different closure (class/module etc).
7
- class DelegatedMethod < Pin::Method
8
- # A DelegatedMethod can be constructed with either a :resolved_method
9
- # pin, or a :receiver_chain. When a :receiver_chain is supplied, it
10
- # will be used to *dynamically* resolve a receiver type within the
11
- # given closure/scope, and the delegated method will then be resolved
12
- # to a method pin on that type.
13
- #
14
- # @param method [Method, nil] an already resolved method pin.
15
- # @param receiver [Source::Chain, nil] the source code used to resolve the receiver for this delegated method.
16
- # @param name [String]
17
- # @param receiver_method_name [String] the method name that will be called on the receiver (defaults to :name).
18
- def initialize(method: nil, receiver: nil, name: method&.name, receiver_method_name: name, **splat)
19
- raise ArgumentError, 'either :method or :receiver is required' if (method && receiver) || (!method && !receiver)
20
- super(name: name, **splat)
21
-
22
- @receiver_chain = receiver
23
- @resolved_method = method
24
- @receiver_method_name = receiver_method_name
25
- end
26
-
27
- def inner_desc
28
- "#{name} => #{@receiver_chain}##{@receiver_method_name}"
29
- end
30
-
31
- def location
32
- return super if super
33
-
34
- @resolved_method&.send(:location)
35
- end
36
-
37
-
38
- def type_location
39
- return super if super
40
-
41
- @resolved_method&.send(:type_location)
42
- end
43
-
44
- %i[comments parameters return_type signatures].each do |method|
45
- define_method(method) do
46
- # @sg-ignore Need to set context correctly in define_method blocks
47
- @resolved_method ? @resolved_method.send(method) : super()
48
- end
49
- end
50
-
51
- %i[typify realize infer probe].each do |method|
52
- # @param api_map [ApiMap]
53
- define_method(method) do |api_map|
54
- resolve_method(api_map)
55
- # @sg-ignore Need to set context correctly in define_method blocks
56
- @resolved_method ? @resolved_method.send(method, api_map) : super(api_map)
57
- end
58
- end
59
-
60
- # @param api_map [ApiMap]
61
- def resolvable?(api_map)
62
- resolve_method(api_map)
63
- !!@resolved_method
64
- end
65
-
66
- private
67
-
68
- # Resolves the receiver chain and method name to a method pin, resetting any previously resolution.
69
- #
70
- # @param api_map [ApiMap]
71
- # @return [Pin::Method, nil]
72
- def resolve_method api_map
73
- return if @resolved_method
74
-
75
- resolver = @receiver_chain.define(api_map, self, []).first
76
-
77
- unless resolver
78
- Solargraph.logger.warn \
79
- "Delegated receiver for #{path} was resolved to nil from `#{print_chain(@receiver_chain)}'"
80
- return
81
- end
82
-
83
- receiver_type = resolver.return_type
84
-
85
- return if receiver_type.undefined?
86
-
87
- receiver_path, method_scope =
88
- if @receiver_chain.constant?
89
- # HACK: the `return_type` of a constant is Class<Whatever>, but looking up a method expects
90
- # the arguments `"Whatever"` and `scope: :class`.
91
- [receiver_type.to_s.sub(/^Class<(.+)>$/, '\1'), :class]
92
- else
93
- [receiver_type.to_s, :instance]
94
- end
95
-
96
- method_stack = api_map.get_method_stack(receiver_path, @receiver_method_name, scope: method_scope)
97
- @resolved_method = method_stack.first
98
- end
99
-
100
- # helper to print a source chain as code, probably not 100% correct.
101
- #
102
- # @param chain [Source::Chain]
103
- # @return [String]
104
- def print_chain(chain)
105
- out = +''
106
- chain.links.each_with_index do |link, index|
107
- if index > 0
108
- if Source::Chain::Constant
109
- out << '::' unless link.word.start_with?('::')
110
- else
111
- out << '.'
112
- end
113
- end
114
- out << link.word
115
- end
116
- out
117
- end
118
- end
119
- end
120
- end
1
+ # frozen_string_literal: true
2
+
3
+ module Solargraph
4
+ module Pin
5
+ # A DelegatedMethod is a more complicated version of a MethodAlias that
6
+ # allows aliasing a method from a different closure (class/module etc).
7
+ class DelegatedMethod < Pin::Method
8
+ # A DelegatedMethod can be constructed with either a :resolved_method
9
+ # pin, or a :receiver_chain. When a :receiver_chain is supplied, it
10
+ # will be used to *dynamically* resolve a receiver type within the
11
+ # given closure/scope, and the delegated method will then be resolved
12
+ # to a method pin on that type.
13
+ #
14
+ # @param method [Method, nil] an already resolved method pin.
15
+ # @param receiver [Source::Chain, nil] the source code used to resolve the receiver for this delegated method.
16
+ # @param name [String, nil]
17
+ # @param receiver_method_name [String, nil] the method name that will be called on the receiver (defaults to :name).
18
+ def initialize(method: nil, receiver: nil, name: method&.name, receiver_method_name: name, **splat)
19
+ raise ArgumentError, 'either :method or :receiver is required' if (method && receiver) || (!method && !receiver)
20
+ # @sg-ignore Need to add nil check here
21
+ super(name: name, **splat)
22
+
23
+ @receiver_chain = receiver
24
+ @resolved_method = method
25
+ @receiver_method_name = receiver_method_name
26
+ end
27
+
28
+ def inner_desc
29
+ "#{name} => #{@receiver_chain}##{@receiver_method_name}"
30
+ end
31
+
32
+ def location
33
+ return super if super
34
+
35
+ @resolved_method&.send(:location)
36
+ end
37
+
38
+
39
+ def type_location
40
+ return super if super
41
+
42
+ @resolved_method&.send(:type_location)
43
+ end
44
+
45
+ %i[comments parameters return_type signatures].each do |method|
46
+ define_method(method) do
47
+ # @sg-ignore Need to set context correctly in define_method blocks
48
+ @resolved_method ? @resolved_method.send(method) : super()
49
+ end
50
+ end
51
+
52
+ %i[typify realize infer probe].each do |method|
53
+ # @param api_map [ApiMap]
54
+ define_method(method) do |api_map|
55
+ resolve_method(api_map)
56
+ # @sg-ignore Need to set context correctly in define_method blocks
57
+ @resolved_method ? @resolved_method.send(method, api_map) : super(api_map)
58
+ end
59
+ end
60
+
61
+ # @param api_map [ApiMap]
62
+ def resolvable?(api_map)
63
+ resolve_method(api_map)
64
+ !!@resolved_method
65
+ end
66
+
67
+ private
68
+
69
+ # Resolves the receiver chain and method name to a method pin, resetting any previously resolution.
70
+ #
71
+ # @param api_map [ApiMap]
72
+ # @return [Pin::Method, nil]
73
+ # @sg-ignore Declared return type ::Solargraph::Pin::Method, nil
74
+ # does not match inferred type nil, false for
75
+ # Solargraph::Pin::DelegatedMethod#resolve_method
76
+ def resolve_method api_map
77
+ return if @resolved_method
78
+
79
+ # @sg-ignore Need to add nil check here
80
+ resolver = @receiver_chain.define(api_map, self, []).first
81
+
82
+ unless resolver
83
+ # @sg-ignore Need to add nil check here
84
+ Solargraph.logger.warn "Delegated receiver for #{path} was resolved to nil from `#{print_chain(@receiver_chain)}'"
85
+ return
86
+ end
87
+
88
+ # @sg-ignore Need to add nil check here
89
+ receiver_type = resolver.return_type
90
+
91
+ # @sg-ignore Need to add nil check here
92
+ return if receiver_type.undefined?
93
+
94
+ receiver_path, method_scope =
95
+ # @sg-ignore Need to add nil check here
96
+ if @receiver_chain.constant?
97
+ # HACK: the `return_type` of a constant is Class<Whatever>, but looking up a method expects
98
+ # the arguments `"Whatever"` and `scope: :class`.
99
+ # @sg-ignore Need to add nil check here
100
+ [receiver_type.to_s.sub(/^Class<(.+)>$/, '\1'), :class]
101
+ else
102
+ # @sg-ignore Need to add nil check here
103
+ [receiver_type.to_s, :instance]
104
+ end
105
+
106
+ # @sg-ignore Need to add nil check here
107
+ method_stack = api_map.get_method_stack(receiver_path, @receiver_method_name, scope: method_scope)
108
+ @resolved_method = method_stack.first
109
+ end
110
+
111
+ # helper to print a source chain as code, probably not 100% correct.
112
+ #
113
+ # @param chain [Source::Chain]
114
+ # @return [String]
115
+ def print_chain(chain)
116
+ out = +''
117
+ chain.links.each_with_index do |link, index|
118
+ if index > 0
119
+ if Source::Chain::Constant
120
+ out << '::' unless link.word.start_with?('::')
121
+ else
122
+ out << '.'
123
+ end
124
+ end
125
+ out << link.word
126
+ end
127
+ out
128
+ end
129
+ end
130
+ end
131
+ end
@@ -1,114 +1,115 @@
1
- # frozen_string_literal: true
2
-
3
- require 'kramdown'
4
- require 'kramdown-parser-gfm'
5
- require 'yard'
6
- require 'reverse_markdown'
7
- require 'solargraph/converters/dl'
8
- require 'solargraph/converters/dt'
9
- require 'solargraph/converters/dd'
10
- require 'solargraph/converters/misc'
11
-
12
- # @todo upstream this definition
13
-
14
- # @!parse
15
- # module ::Kramdown
16
- # class Document
17
- # # @return [String]
18
- # def to_html; end
19
- # end
20
- # end
21
- # module ReverseMarkdown
22
- # # @param input [String]
23
- # # @param options [Hash]
24
- # # @return [String]
25
- # def self.convert(input, options = {}); end
26
- # end
27
-
28
- module Solargraph
29
- module Pin
30
- # A module to add the Pin::Base#documentation method.
31
- #
32
- module Documenting
33
- # A documentation formatter that either performs Markdown conversion for
34
- # text, or applies backticks for code blocks.
35
- #
36
- class DocSection
37
- # @return [String]
38
- attr_reader :plaintext
39
-
40
- # @param code [Boolean] True if this section is a code block
41
- def initialize code
42
- @plaintext = String.new('')
43
- @code = code
44
- end
45
-
46
- def code?
47
- @code
48
- end
49
-
50
- # @param text [String]
51
- # @return [String]
52
- def concat text
53
- @plaintext.concat text
54
- end
55
-
56
- def to_s
57
- return to_code if code?
58
- to_markdown
59
- end
60
-
61
- private
62
-
63
- # @return [String]
64
- def to_code
65
- "\n```ruby\n#{Documenting.normalize_indentation(@plaintext)}#{@plaintext.end_with?("\n") ? '' : "\n"}```\n\n"
66
- end
67
-
68
- # @return [String]
69
- def to_markdown
70
- ReverseMarkdown.convert Kramdown::Document.new(@plaintext, input: 'GFM').to_html
71
- end
72
- end
73
-
74
- # @return [String]
75
- def documentation
76
- @documentation ||= begin
77
- # Using DocSections allows for code blocks that start with an empty
78
- # line and at least two spaces of indentation. This is a common
79
- # convention in Ruby core documentation, e.g., String#split.
80
- sections = [DocSection.new(false)]
81
- Documenting.normalize_indentation(Documenting.strip_html_comments(docstring.to_s.gsub("\t", ' '))).lines.each do |l|
82
- if l.start_with?(' ')
83
- # Code block
84
- sections.push DocSection.new(true) unless sections.last.code?
85
- elsif sections.last.code?
86
- # Regular documentation
87
- sections.push DocSection.new(false)
88
- end
89
- sections.last.concat l
90
- end
91
- sections.map(&:to_s).join.strip
92
- end
93
- end
94
-
95
- # @param text [String]
96
- # @return [String]
97
- def self.strip_html_comments text
98
- text.gsub(/<!--([\s\S]*?)-->/, '').strip
99
- end
100
-
101
- # @param text [String]
102
- # @return [String]
103
- def self.normalize_indentation text
104
- left = text.lines.map do |line|
105
- match = line.match(/^ +/)
106
- next 0 unless match
107
- match[0].length
108
- end.min
109
- return text if left.nil? || left.zero?
110
- text.lines.map { |line| line[left..] }.join
111
- end
112
- end
113
- end
114
- end
1
+ # frozen_string_literal: true
2
+
3
+ require 'kramdown'
4
+ require 'kramdown-parser-gfm'
5
+ require 'yard'
6
+ require 'reverse_markdown'
7
+ require 'solargraph/converters/dl'
8
+ require 'solargraph/converters/dt'
9
+ require 'solargraph/converters/dd'
10
+ require 'solargraph/converters/misc'
11
+
12
+ # @todo upstream this definition
13
+
14
+ # @!parse
15
+ # module ::Kramdown
16
+ # class Document
17
+ # # @return [String]
18
+ # def to_html; end
19
+ # end
20
+ # end
21
+ # module ReverseMarkdown
22
+ # # @param input [String]
23
+ # # @param options [Hash]
24
+ # # @return [String]
25
+ # def self.convert(input, options = {}); end
26
+ # end
27
+
28
+ module Solargraph
29
+ module Pin
30
+ # A module to add the Pin::Base#documentation method.
31
+ #
32
+ module Documenting
33
+ # A documentation formatter that either performs Markdown conversion for
34
+ # text, or applies backticks for code blocks.
35
+ #
36
+ class DocSection
37
+ # @return [String]
38
+ attr_reader :plaintext
39
+
40
+ # @param code [Boolean] True if this section is a code block
41
+ def initialize code
42
+ @plaintext = String.new('')
43
+ @code = code
44
+ end
45
+
46
+ def code?
47
+ @code
48
+ end
49
+
50
+ # @param text [String]
51
+ # @return [String]
52
+ def concat text
53
+ @plaintext.concat text
54
+ end
55
+
56
+ def to_s
57
+ return to_code if code?
58
+ to_markdown
59
+ end
60
+
61
+ private
62
+
63
+ # @return [String]
64
+ def to_code
65
+ "\n```ruby\n#{Documenting.normalize_indentation(@plaintext)}#{@plaintext.end_with?("\n") ? '' : "\n"}```\n\n"
66
+ end
67
+
68
+ # @return [String]
69
+ def to_markdown
70
+ ReverseMarkdown.convert Kramdown::Document.new(@plaintext, input: 'GFM').to_html
71
+ end
72
+ end
73
+
74
+ # @return [String]
75
+ def documentation
76
+ @documentation ||= begin
77
+ # Using DocSections allows for code blocks that start with an empty
78
+ # line and at least two spaces of indentation. This is a common
79
+ # convention in Ruby core documentation, e.g., String#split.
80
+ sections = [DocSection.new(false)]
81
+ Documenting.normalize_indentation(Documenting.strip_html_comments(docstring.to_s.gsub("\t", ' '))).lines.each do |l|
82
+ if l.start_with?(' ')
83
+ # Code block
84
+ sections.push DocSection.new(true) unless sections.last.code?
85
+ elsif sections.last.code?
86
+ # Regular documentation
87
+ sections.push DocSection.new(false)
88
+ end
89
+ sections.last.concat l
90
+ end
91
+ sections.map(&:to_s).join.strip
92
+ end
93
+ end
94
+
95
+ # @param text [String]
96
+ # @return [String]
97
+ def self.strip_html_comments text
98
+ text.gsub(/<!--([\s\S]*?)-->/, '').strip
99
+ end
100
+
101
+ # @param text [String]
102
+ # @return [String]
103
+ def self.normalize_indentation text
104
+ left = text.lines.map do |line|
105
+ match = line.match(/^ +/)
106
+ next 0 unless match
107
+ # @sg-ignore Need to add nil check here
108
+ match[0].length
109
+ end.min
110
+ return text if left.nil? || left.zero?
111
+ text.lines.map { |line| line[left..] }.join
112
+ end
113
+ end
114
+ end
115
+ end
@@ -1,34 +1,38 @@
1
- # frozen_string_literal: true
2
-
3
- module Solargraph
4
- module Pin
5
- class InstanceVariable < BaseVariable
6
- # @return [ComplexType]
7
- def binder
8
- closure.binder
9
- end
10
-
11
- # @return [::Symbol]
12
- def scope
13
- closure.binder.scope
14
- end
15
-
16
- # @return [ComplexType]
17
- def context
18
- @context ||= begin
19
- result = super
20
- if scope == :class
21
- ComplexType.parse("::Class<#{result.rooted_namespace}>")
22
- else
23
- result.reduce_class_type
24
- end
25
- end
26
- end
27
-
28
- # @param other [InstanceVariable]
29
- def nearly? other
30
- super && binder == other.binder
31
- end
32
- end
33
- end
34
- end
1
+ # frozen_string_literal: true
2
+
3
+ module Solargraph
4
+ module Pin
5
+ class InstanceVariable < BaseVariable
6
+ # @sg-ignore Need to add nil check here
7
+ # @return [ComplexType, ComplexType::UniqueType]
8
+ def binder
9
+ # @sg-ignore Need to add nil check here
10
+ closure.binder
11
+ end
12
+
13
+ # @sg-ignore Need to add nil check here
14
+ # @return [::Symbol]
15
+ def scope
16
+ # @sg-ignore Need to add nil check here
17
+ closure.binder.scope
18
+ end
19
+
20
+ # @return [ComplexType]
21
+ def context
22
+ @context ||= begin
23
+ result = super
24
+ if scope == :class
25
+ ComplexType.parse("::Class<#{result.rooted_namespace}>")
26
+ else
27
+ result.reduce_class_type
28
+ end
29
+ end
30
+ end
31
+
32
+ # @param other [InstanceVariable]
33
+ def nearly? other
34
+ super && binder == other.binder
35
+ end
36
+ end
37
+ end
38
+ end
@@ -1,20 +1,16 @@
1
- # frozen_string_literal: true
2
-
3
- module Solargraph
4
- module Pin
5
- class Keyword < Base
6
- def initialize(name, **kwargs)
7
- # @sg-ignore "Unrecognized keyword argument kwargs to Solargraph::Pin::Base#initialize"
8
- super(name: name, **kwargs)
9
- end
10
-
11
- def closure
12
- @closure ||= Pin::ROOT_PIN
13
- end
14
-
15
- def name
16
- @name
17
- end
18
- end
19
- end
20
- end
1
+ # frozen_string_literal: true
2
+
3
+ module Solargraph
4
+ module Pin
5
+ class Keyword < Base
6
+ def initialize(name, **kwargs)
7
+ # @sg-ignore "Unrecognized keyword argument kwargs to Solargraph::Pin::Base#initialize"
8
+ super(name: name, **kwargs)
9
+ end
10
+
11
+ def closure
12
+ @closure ||= Pin::ROOT_PIN
13
+ end
14
+ end
15
+ end
16
+ end