solargraph 0.32.1 → 0.32.2

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 (177) hide show
  1. checksums.yaml +4 -4
  2. data/.gitignore +9 -0
  3. data/.rspec +2 -0
  4. data/.rubocop.yml +6 -0
  5. data/.travis.yml +25 -0
  6. data/EXAMPLES.md +76 -0
  7. data/Gemfile +3 -0
  8. data/LANGUAGE_SERVER.md +51 -0
  9. data/LICENSE +21 -0
  10. data/OVERVIEW.md +37 -0
  11. data/README.md +106 -0
  12. data/Rakefile +14 -0
  13. data/SERVER.md +95 -0
  14. data/bin/solargraph +0 -0
  15. data/bin/solargraph-runtime +5 -5
  16. data/lib/solargraph.rb +54 -54
  17. data/lib/solargraph/api_map.rb +659 -659
  18. data/lib/solargraph/api_map/cache.rb +49 -49
  19. data/lib/solargraph/api_map/source_to_yard.rb +67 -67
  20. data/lib/solargraph/api_map/store.rb +201 -201
  21. data/lib/solargraph/bundle.rb +24 -24
  22. data/lib/solargraph/complex_type.rb +150 -150
  23. data/lib/solargraph/complex_type/type_methods.rb +124 -124
  24. data/lib/solargraph/complex_type/unique_type.rb +44 -44
  25. data/lib/solargraph/core_fills.rb +37 -37
  26. data/lib/solargraph/diagnostics.rb +52 -52
  27. data/lib/solargraph/diagnostics/base.rb +20 -20
  28. data/lib/solargraph/diagnostics/require_not_found.rb +28 -28
  29. data/lib/solargraph/diagnostics/rubocop.rb +98 -98
  30. data/lib/solargraph/diagnostics/rubocop_helpers.rb +46 -46
  31. data/lib/solargraph/diagnostics/type_not_defined.rb +108 -108
  32. data/lib/solargraph/diagnostics/update_errors.rb +38 -38
  33. data/lib/solargraph/language_server/completion_item_kinds.rb +33 -33
  34. data/lib/solargraph/language_server/error_codes.rb +18 -18
  35. data/lib/solargraph/language_server/host.rb +684 -681
  36. data/lib/solargraph/language_server/host/cataloger.rb +54 -79
  37. data/lib/solargraph/language_server/host/diagnoser.rb +80 -80
  38. data/lib/solargraph/language_server/host/dispatch.rb +112 -113
  39. data/lib/solargraph/language_server/host/sources.rb +138 -138
  40. data/lib/solargraph/language_server/message.rb +90 -90
  41. data/lib/solargraph/language_server/message/base.rb +83 -83
  42. data/lib/solargraph/language_server/message/completion_item/resolve.rb +40 -40
  43. data/lib/solargraph/language_server/message/exit_notification.rb +11 -11
  44. data/lib/solargraph/language_server/message/extended.rb +19 -19
  45. data/lib/solargraph/language_server/message/extended/check_gem_version.rb +86 -86
  46. data/lib/solargraph/language_server/message/extended/document.rb +18 -18
  47. data/lib/solargraph/language_server/message/extended/document_gems.rb +30 -30
  48. data/lib/solargraph/language_server/message/extended/environment.rb +20 -20
  49. data/lib/solargraph/language_server/message/extended/search.rb +18 -18
  50. data/lib/solargraph/language_server/message/initialize.rb +141 -141
  51. data/lib/solargraph/language_server/message/initialized.rb +23 -23
  52. data/lib/solargraph/language_server/message/shutdown.rb +11 -11
  53. data/lib/solargraph/language_server/message/text_document.rb +25 -25
  54. data/lib/solargraph/language_server/message/text_document/completion.rb +51 -51
  55. data/lib/solargraph/language_server/message/text_document/definition.rb +18 -18
  56. data/lib/solargraph/language_server/message/text_document/did_change.rb +13 -13
  57. data/lib/solargraph/language_server/message/text_document/document_symbol.rb +21 -21
  58. data/lib/solargraph/language_server/message/text_document/folding_range.rb +24 -24
  59. data/lib/solargraph/language_server/message/text_document/formatting.rb +50 -50
  60. data/lib/solargraph/language_server/message/text_document/hover.rb +31 -31
  61. data/lib/solargraph/language_server/message/text_document/on_type_formatting.rb +32 -32
  62. data/lib/solargraph/language_server/message/text_document/prepare_rename.rb +9 -9
  63. data/lib/solargraph/language_server/message/text_document/references.rb +14 -14
  64. data/lib/solargraph/language_server/message/text_document/rename.rb +17 -17
  65. data/lib/solargraph/language_server/message/text_document/signature_help.rb +19 -19
  66. data/lib/solargraph/language_server/message/workspace.rb +12 -12
  67. data/lib/solargraph/language_server/message/workspace/did_change_configuration.rb +29 -29
  68. data/lib/solargraph/language_server/message/workspace/did_change_watched_files.rb +29 -27
  69. data/lib/solargraph/language_server/message/workspace/did_change_workspace_folders.rb +24 -24
  70. data/lib/solargraph/language_server/message/workspace/workspace_symbol.rb +21 -21
  71. data/lib/solargraph/language_server/request.rb +22 -22
  72. data/lib/solargraph/language_server/symbol_kinds.rb +34 -34
  73. data/lib/solargraph/language_server/transport.rb +11 -11
  74. data/lib/solargraph/language_server/transport/adapter.rb +60 -60
  75. data/lib/solargraph/language_server/transport/data_reader.rb +66 -66
  76. data/lib/solargraph/language_server/uri_helpers.rb +25 -25
  77. data/lib/solargraph/library.rb +421 -419
  78. data/lib/solargraph/live_map.rb +126 -126
  79. data/lib/solargraph/live_map/cache.rb +38 -38
  80. data/lib/solargraph/location.rb +31 -31
  81. data/lib/solargraph/logging.rb +25 -25
  82. data/lib/solargraph/page.rb +68 -68
  83. data/lib/solargraph/pin.rb +50 -50
  84. data/lib/solargraph/pin/attribute.rb +41 -41
  85. data/lib/solargraph/pin/base.rb +280 -280
  86. data/lib/solargraph/pin/base_method.rb +76 -76
  87. data/lib/solargraph/pin/base_variable.rb +72 -72
  88. data/lib/solargraph/pin/block.rb +32 -32
  89. data/lib/solargraph/pin/block_parameter.rb +103 -103
  90. data/lib/solargraph/pin/class_variable.rb +9 -9
  91. data/lib/solargraph/pin/constant.rb +30 -30
  92. data/lib/solargraph/pin/conversions.rb +79 -79
  93. data/lib/solargraph/pin/documenting.rb +41 -41
  94. data/lib/solargraph/pin/duck_method.rb +14 -14
  95. data/lib/solargraph/pin/global_variable.rb +9 -9
  96. data/lib/solargraph/pin/instance_variable.rb +9 -9
  97. data/lib/solargraph/pin/keyword.rb +17 -17
  98. data/lib/solargraph/pin/local_variable.rb +23 -23
  99. data/lib/solargraph/pin/localized.rb +22 -22
  100. data/lib/solargraph/pin/method.rb +126 -126
  101. data/lib/solargraph/pin/method_alias.rb +30 -30
  102. data/lib/solargraph/pin/method_parameter.rb +40 -40
  103. data/lib/solargraph/pin/namespace.rb +54 -54
  104. data/lib/solargraph/pin/plugin/method.rb +25 -25
  105. data/lib/solargraph/pin/proxy_type.rb +35 -35
  106. data/lib/solargraph/pin/reference.rb +22 -22
  107. data/lib/solargraph/pin/reference/extend.rb +11 -11
  108. data/lib/solargraph/pin/reference/include.rb +11 -11
  109. data/lib/solargraph/pin/reference/require.rb +15 -15
  110. data/lib/solargraph/pin/reference/superclass.rb +11 -11
  111. data/lib/solargraph/pin/symbol.rb +44 -44
  112. data/lib/solargraph/pin/yard_pin.rb +10 -10
  113. data/lib/solargraph/pin/yard_pin/constant.rb +14 -14
  114. data/lib/solargraph/pin/yard_pin/method.rb +35 -35
  115. data/lib/solargraph/pin/yard_pin/namespace.rb +19 -19
  116. data/lib/solargraph/pin/yard_pin/yard_mixin.rb +14 -14
  117. data/lib/solargraph/plugin.rb +8 -8
  118. data/lib/solargraph/plugin/base.rb +41 -41
  119. data/lib/solargraph/plugin/canceler.rb +11 -11
  120. data/lib/solargraph/plugin/process.rb +172 -172
  121. data/lib/solargraph/plugin/runtime.rb +134 -134
  122. data/lib/solargraph/position.rb +110 -110
  123. data/lib/solargraph/range.rb +83 -83
  124. data/lib/solargraph/server_methods.rb +14 -14
  125. data/lib/solargraph/shell.rb +102 -102
  126. data/lib/solargraph/source.rb +521 -521
  127. data/lib/solargraph/source/chain.rb +120 -120
  128. data/lib/solargraph/source/chain/call.rb +107 -107
  129. data/lib/solargraph/source/chain/class_variable.rb +11 -11
  130. data/lib/solargraph/source/chain/constant.rb +30 -30
  131. data/lib/solargraph/source/chain/global_variable.rb +11 -11
  132. data/lib/solargraph/source/chain/head.rb +33 -33
  133. data/lib/solargraph/source/chain/instance_variable.rb +11 -11
  134. data/lib/solargraph/source/chain/link.rb +33 -33
  135. data/lib/solargraph/source/chain/literal.rb +21 -21
  136. data/lib/solargraph/source/chain/variable.rb +11 -11
  137. data/lib/solargraph/source/change.rb +77 -77
  138. data/lib/solargraph/source/cursor.rb +157 -157
  139. data/lib/solargraph/source/node_chainer.rb +96 -96
  140. data/lib/solargraph/source/node_methods.rb +225 -225
  141. data/lib/solargraph/source/source_chainer.rb +183 -183
  142. data/lib/solargraph/source_map.rb +169 -169
  143. data/lib/solargraph/source_map/clip.rb +145 -145
  144. data/lib/solargraph/source_map/completion.rb +21 -21
  145. data/lib/solargraph/source_map/mapper.rb +149 -149
  146. data/lib/solargraph/source_map/node_processor.rb +78 -78
  147. data/lib/solargraph/source_map/node_processor/alias_node.rb +19 -19
  148. data/lib/solargraph/source_map/node_processor/args_node.rb +28 -28
  149. data/lib/solargraph/source_map/node_processor/base.rb +68 -68
  150. data/lib/solargraph/source_map/node_processor/begin_node.rb +11 -11
  151. data/lib/solargraph/source_map/node_processor/block_node.rb +14 -14
  152. data/lib/solargraph/source_map/node_processor/casgn_node.rb +14 -14
  153. data/lib/solargraph/source_map/node_processor/cvasgn_node.rb +14 -14
  154. data/lib/solargraph/source_map/node_processor/def_node.rb +54 -54
  155. data/lib/solargraph/source_map/node_processor/defs_node.rb +21 -21
  156. data/lib/solargraph/source_map/node_processor/gvasgn_node.rb +12 -12
  157. data/lib/solargraph/source_map/node_processor/ivasgn_node.rb +18 -18
  158. data/lib/solargraph/source_map/node_processor/lvasgn_node.rb +16 -16
  159. data/lib/solargraph/source_map/node_processor/namespace_node.rb +26 -26
  160. data/lib/solargraph/source_map/node_processor/orasgn_node.rb +12 -12
  161. data/lib/solargraph/source_map/node_processor/sclass_node.rb +11 -11
  162. data/lib/solargraph/source_map/node_processor/send_node.rb +162 -162
  163. data/lib/solargraph/source_map/node_processor/sym_node.rb +11 -11
  164. data/lib/solargraph/source_map/region.rb +58 -58
  165. data/lib/solargraph/version.rb +3 -3
  166. data/lib/solargraph/views/environment.erb +53 -53
  167. data/lib/solargraph/workspace.rb +183 -183
  168. data/lib/solargraph/workspace/config.rb +170 -170
  169. data/lib/solargraph/yard_map.rb +298 -298
  170. data/lib/solargraph/yard_map/cache.rb +17 -17
  171. data/lib/solargraph/yard_map/core_docs.rb +163 -163
  172. data/lib/solargraph/yard_map/core_gen.rb +76 -76
  173. data/lib/yard-coregen.rb +16 -16
  174. data/lib/yard-solargraph.rb +18 -18
  175. data/solargraph.gemspec +37 -0
  176. data/travis-bundler.rb +10 -0
  177. metadata +19 -6
@@ -1,134 +1,134 @@
1
- require 'json'
2
-
3
- module Solargraph
4
- module Plugin
5
- class Runtime < Base
6
- attr_writer :executable
7
-
8
- def executable
9
- @executable ||= 'solargraph-runtime'
10
- end
11
-
12
- def post_initialize
13
- start_process
14
- end
15
-
16
- # @return [Boolean]
17
- def runtime?
18
- true
19
- end
20
-
21
- # Get an array of method names.
22
- #
23
- # @return [Array<String>]
24
- def get_methods namespace:, root:, scope:, with_private: false
25
- response = send_get_methods(namespace, root, scope, with_private)
26
- response['data']
27
- end
28
-
29
- # Get an array of constant names.
30
- #
31
- # @return [Array<String>]
32
- def get_constants namespace, root
33
- response = send_get_constants namespace, root
34
- response['data']
35
- end
36
-
37
- def get_fqns namespace, root
38
- response = send_get_fqns namespace, root
39
- response['data']
40
- end
41
-
42
- def refresh
43
- if api_map.nil?
44
- false
45
- else
46
- if @current_required != api_map.required
47
- @io.close unless @io.nil? or @io.closed?
48
- start_process
49
- true
50
- else
51
- false
52
- end
53
- end
54
- end
55
-
56
- def stop
57
- @io.close
58
- end
59
-
60
- protected
61
-
62
- def load_environment
63
- return if api_map.nil?
64
- send_require api_map.required
65
- @current_required = api_map.required.clone
66
- end
67
-
68
- private
69
-
70
- def start_process
71
- dir = Dir.pwd
72
- unless api_map.nil? or api_map.workspace.nil? or api_map.workspace.directory.nil?
73
- dir = api_map.workspace.directory
74
- end
75
- Dir.chdir(dir) do
76
- @io = IO.popen(executable, 'r+')
77
- end
78
- load_environment
79
- end
80
-
81
- def send_require paths
82
- cmd = {
83
- command: 'require',
84
- paths: paths
85
- }
86
- transact cmd
87
- end
88
-
89
- def send_get_methods namespace, root, scope, with_private
90
- cmd = {
91
- command: 'methods',
92
- params: {
93
- namespace: namespace,
94
- root: root,
95
- scope: scope,
96
- with_private: with_private
97
- }
98
- }
99
- transact cmd
100
- end
101
-
102
- def send_get_constants namespace, root
103
- cmd = {
104
- command: 'constants',
105
- params: {
106
- namespace: namespace,
107
- root: root
108
- }
109
- }
110
- transact cmd
111
- end
112
-
113
- def send_get_fqns namespace, root
114
- cmd = {
115
- command: 'fqns',
116
- params: {
117
- namespace: namespace,
118
- root: root
119
- }
120
- }
121
- transact cmd
122
- end
123
-
124
- def transact cmd
125
- @io.puts cmd.to_json
126
- @io.flush
127
- result = @io.gets
128
- obj = JSON.parse(result)
129
- STDERR.puts obj['message'] if obj['status'] == 'err'
130
- obj
131
- end
132
- end
133
- end
134
- end
1
+ require 'json'
2
+
3
+ module Solargraph
4
+ module Plugin
5
+ class Runtime < Base
6
+ attr_writer :executable
7
+
8
+ def executable
9
+ @executable ||= 'solargraph-runtime'
10
+ end
11
+
12
+ def post_initialize
13
+ start_process
14
+ end
15
+
16
+ # @return [Boolean]
17
+ def runtime?
18
+ true
19
+ end
20
+
21
+ # Get an array of method names.
22
+ #
23
+ # @return [Array<String>]
24
+ def get_methods namespace:, root:, scope:, with_private: false
25
+ response = send_get_methods(namespace, root, scope, with_private)
26
+ response['data']
27
+ end
28
+
29
+ # Get an array of constant names.
30
+ #
31
+ # @return [Array<String>]
32
+ def get_constants namespace, root
33
+ response = send_get_constants namespace, root
34
+ response['data']
35
+ end
36
+
37
+ def get_fqns namespace, root
38
+ response = send_get_fqns namespace, root
39
+ response['data']
40
+ end
41
+
42
+ def refresh
43
+ if api_map.nil?
44
+ false
45
+ else
46
+ if @current_required != api_map.required
47
+ @io.close unless @io.nil? or @io.closed?
48
+ start_process
49
+ true
50
+ else
51
+ false
52
+ end
53
+ end
54
+ end
55
+
56
+ def stop
57
+ @io.close
58
+ end
59
+
60
+ protected
61
+
62
+ def load_environment
63
+ return if api_map.nil?
64
+ send_require api_map.required
65
+ @current_required = api_map.required.clone
66
+ end
67
+
68
+ private
69
+
70
+ def start_process
71
+ dir = Dir.pwd
72
+ unless api_map.nil? or api_map.workspace.nil? or api_map.workspace.directory.nil?
73
+ dir = api_map.workspace.directory
74
+ end
75
+ Dir.chdir(dir) do
76
+ @io = IO.popen(executable, 'r+')
77
+ end
78
+ load_environment
79
+ end
80
+
81
+ def send_require paths
82
+ cmd = {
83
+ command: 'require',
84
+ paths: paths
85
+ }
86
+ transact cmd
87
+ end
88
+
89
+ def send_get_methods namespace, root, scope, with_private
90
+ cmd = {
91
+ command: 'methods',
92
+ params: {
93
+ namespace: namespace,
94
+ root: root,
95
+ scope: scope,
96
+ with_private: with_private
97
+ }
98
+ }
99
+ transact cmd
100
+ end
101
+
102
+ def send_get_constants namespace, root
103
+ cmd = {
104
+ command: 'constants',
105
+ params: {
106
+ namespace: namespace,
107
+ root: root
108
+ }
109
+ }
110
+ transact cmd
111
+ end
112
+
113
+ def send_get_fqns namespace, root
114
+ cmd = {
115
+ command: 'fqns',
116
+ params: {
117
+ namespace: namespace,
118
+ root: root
119
+ }
120
+ }
121
+ transact cmd
122
+ end
123
+
124
+ def transact cmd
125
+ @io.puts cmd.to_json
126
+ @io.flush
127
+ result = @io.gets
128
+ obj = JSON.parse(result)
129
+ STDERR.puts obj['message'] if obj['status'] == 'err'
130
+ obj
131
+ end
132
+ end
133
+ end
134
+ end
@@ -1,110 +1,110 @@
1
- module Solargraph
2
- # The zero-based line and column numbers of a position in a string.
3
- #
4
- class Position
5
- # @return [Integer]
6
- attr_reader :line
7
-
8
- # @return [Integer]
9
- attr_reader :character
10
-
11
- alias column character
12
-
13
- # @param line [Integer]
14
- # @param character [Integer]
15
- def initialize line, character
16
- @line = line
17
- @character = character
18
- end
19
-
20
- # Get a hash of the position. This representation is suitable for use in
21
- # the language server protocol.
22
- #
23
- # @return [Hash]
24
- def to_hash
25
- {
26
- line: line,
27
- character: character
28
- }
29
- end
30
-
31
- def inspect
32
- "<Position #{line}, #{character}>"
33
- end
34
-
35
- # Get a numeric offset for the specified text and position.
36
- #
37
- # @param text [String]
38
- # @param position [Position]
39
- # @return [Integer]
40
- def self.to_offset text, position
41
- result = 0
42
- feed = 0
43
- line = position.line
44
- column = position.character
45
- text.lines.each do |l|
46
- line_length = l.length
47
- if feed == line
48
- result += column
49
- break
50
- end
51
- result += line_length
52
- feed += 1
53
- end
54
- result
55
- end
56
-
57
- # Get a numeric offset for the specified text and a position identified
58
- # by its line and character.
59
- #
60
- # @param text [String]
61
- # @param line [Integer]
62
- # @param character [Integer]
63
- # @return [Integer]
64
- def self.line_char_to_offset text, line, character
65
- to_offset(text, Position.new(line, character))
66
- end
67
-
68
- # Get a position for the specified text and offset.
69
- #
70
- # @param text [String]
71
- # @param offset [Integer]
72
- # @return [Position]
73
- def self.from_offset text, offset
74
- cursor = 0
75
- line = 0
76
- character = nil
77
- text.lines.each do |l|
78
- line_length = l.length
79
- char_length = l.chomp.length
80
- if cursor + char_length >= offset
81
- character = offset - cursor
82
- break
83
- end
84
- cursor += line_length
85
- line += 1
86
- end
87
- character = 0 if character.nil? and (cursor - offset).between?(0, 1)
88
- raise InvalidOffsetError if character.nil?
89
- Position.new(line, character)
90
- end
91
-
92
- # A helper method for generating positions from arrays of integers. The
93
- # original parameter is returned if it is already a position.
94
- #
95
- # @raise [ArgumentError] if the object cannot be converted to a position.
96
- #
97
- # @param object [Position, Array(Integer, Integer)]
98
- # @return [Position]
99
- def self.normalize object
100
- return object if object.is_a?(Position)
101
- return Position.new(object[0], object[1]) if object.is_a?(Array)
102
- raise ArgumentError, "Unable to convert #{object.class} to Position"
103
- end
104
-
105
- def == other
106
- return false unless other.is_a?(Position)
107
- line == other.line and character == other.character
108
- end
109
- end
110
- end
1
+ module Solargraph
2
+ # The zero-based line and column numbers of a position in a string.
3
+ #
4
+ class Position
5
+ # @return [Integer]
6
+ attr_reader :line
7
+
8
+ # @return [Integer]
9
+ attr_reader :character
10
+
11
+ alias column character
12
+
13
+ # @param line [Integer]
14
+ # @param character [Integer]
15
+ def initialize line, character
16
+ @line = line
17
+ @character = character
18
+ end
19
+
20
+ # Get a hash of the position. This representation is suitable for use in
21
+ # the language server protocol.
22
+ #
23
+ # @return [Hash]
24
+ def to_hash
25
+ {
26
+ line: line,
27
+ character: character
28
+ }
29
+ end
30
+
31
+ def inspect
32
+ "<Position #{line}, #{character}>"
33
+ end
34
+
35
+ # Get a numeric offset for the specified text and position.
36
+ #
37
+ # @param text [String]
38
+ # @param position [Position]
39
+ # @return [Integer]
40
+ def self.to_offset text, position
41
+ result = 0
42
+ feed = 0
43
+ line = position.line
44
+ column = position.character
45
+ text.lines.each do |l|
46
+ line_length = l.length
47
+ if feed == line
48
+ result += column
49
+ break
50
+ end
51
+ result += line_length
52
+ feed += 1
53
+ end
54
+ result
55
+ end
56
+
57
+ # Get a numeric offset for the specified text and a position identified
58
+ # by its line and character.
59
+ #
60
+ # @param text [String]
61
+ # @param line [Integer]
62
+ # @param character [Integer]
63
+ # @return [Integer]
64
+ def self.line_char_to_offset text, line, character
65
+ to_offset(text, Position.new(line, character))
66
+ end
67
+
68
+ # Get a position for the specified text and offset.
69
+ #
70
+ # @param text [String]
71
+ # @param offset [Integer]
72
+ # @return [Position]
73
+ def self.from_offset text, offset
74
+ cursor = 0
75
+ line = 0
76
+ character = nil
77
+ text.lines.each do |l|
78
+ line_length = l.length
79
+ char_length = l.chomp.length
80
+ if cursor + char_length >= offset
81
+ character = offset - cursor
82
+ break
83
+ end
84
+ cursor += line_length
85
+ line += 1
86
+ end
87
+ character = 0 if character.nil? and (cursor - offset).between?(0, 1)
88
+ raise InvalidOffsetError if character.nil?
89
+ Position.new(line, character)
90
+ end
91
+
92
+ # A helper method for generating positions from arrays of integers. The
93
+ # original parameter is returned if it is already a position.
94
+ #
95
+ # @raise [ArgumentError] if the object cannot be converted to a position.
96
+ #
97
+ # @param object [Position, Array(Integer, Integer)]
98
+ # @return [Position]
99
+ def self.normalize object
100
+ return object if object.is_a?(Position)
101
+ return Position.new(object[0], object[1]) if object.is_a?(Array)
102
+ raise ArgumentError, "Unable to convert #{object.class} to Position"
103
+ end
104
+
105
+ def == other
106
+ return false unless other.is_a?(Position)
107
+ line == other.line and character == other.character
108
+ end
109
+ end
110
+ end