syntax_tree 2.9.0 → 3.0.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: f8818212d64fea80bd776267ea9dac3a10c454e789b47ed72f4cf715dc087b30
4
- data.tar.gz: ac90d097d6cbd8b50427c5ead994021448732022ce680a809c17e5e7fe9b427f
3
+ metadata.gz: 28783cde4387bbc7d38d9de500564804cd885733abe59e017be73ce04981a854
4
+ data.tar.gz: 6a54750102b8978df75e7f8a7d611e596067bb69863f91d5a8daa9aec8509c31
5
5
  SHA512:
6
- metadata.gz: cfe0af3c52f742ed24f5643710df53fd09b761f428c007ac9434d0e96828bc75c8e082884685173e6b7ea5cf5343d264219c5f5d2c9eb0a90a1fd58d2bec70c8
7
- data.tar.gz: 0ee8b8362d6d18945f5bca0a0bfef1d1dc85e2fa5f27c61e807d7c4aa15b23cbb70fe6a8ebe4b1d6e73fd26e473c6fbb158287de2ee7343d0231e75b3529329b
6
+ metadata.gz: c2f61f01bfa53604686798c96a53d8c98abd30145038db3b7f73f92c5c6b282447f3fe355382f6b3325b3ee98ce60ddcc5c102234b78e9c8d1fe9cbf006cb38d
7
+ data.tar.gz: e5a63e7fdc4f7e70e354a5861e42b8c0dffbbd2ffde38754c0a1fca8a6033be2deecd52ea3ec5fb7a2aa05e0d07ab93d3b4d69762ca3c911f36a6e898ef2ffaf
data/CHANGELOG.md CHANGED
@@ -6,8 +6,20 @@ The format is based on [Keep a Changelog](http://keepachangelog.com/en/1.0.0/) a
6
6
 
7
7
  ## [Unreleased]
8
8
 
9
+ ## [3.0.0] - 2022-07-04
10
+
11
+ ### Changed
12
+
13
+ - [#102](https://github.com/ruby-syntax-tree/syntax_tree/issues/102) - Handle requests to the language server for files that do not yet exist on disk.
14
+
15
+ ### Removed
16
+
17
+ - [#108](https://github.com/ruby-syntax-tree/syntax_tree/pull/108) - Remove old inlay hints code.
18
+
9
19
  ## [2.9.0] - 2022-07-04
10
20
 
21
+ ### Added
22
+
11
23
  - [#106](https://github.com/ruby-syntax-tree/syntax_tree/pull/106) - Add inlay hint support to match the LSP specification.
12
24
 
13
25
  ## [2.8.0] - 2022-06-21
@@ -276,8 +288,8 @@ The format is based on [Keep a Changelog](http://keepachangelog.com/en/1.0.0/) a
276
288
 
277
289
  - 🎉 Initial release! 🎉
278
290
 
279
- [unreleased]: https://github.com/ruby-syntax-tree/syntax_tree/compare/v2.1.0...HEAD
280
- [2.1.0]: https://github.com/ruby-syntax-tree/syntax_tree/compare/v2.8.0...v2.1.0
291
+ [unreleased]: https://github.com/ruby-syntax-tree/syntax_tree/compare/v2.9.0...HEAD
292
+ [2.9.0]: https://github.com/ruby-syntax-tree/syntax_tree/compare/v2.8.0...v2.9.0
281
293
  [2.8.0]: https://github.com/ruby-syntax-tree/syntax_tree/compare/v2.7.1...v2.8.0
282
294
  [2.7.1]: https://github.com/ruby-syntax-tree/syntax_tree/compare/v2.7.0...v2.7.1
283
295
  [2.7.0]: https://github.com/ruby-syntax-tree/syntax_tree/compare/v2.6.0...v2.7.0
data/Gemfile.lock CHANGED
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- syntax_tree (2.9.0)
4
+ syntax_tree (3.0.0)
5
5
  prettier_print
6
6
 
7
7
  GEM
data/README.md CHANGED
@@ -35,7 +35,7 @@ It is built with only standard library dependencies. It additionally ships with
35
35
  - [BasicVisitor](#basicvisitor)
36
36
  - [Language server](#language-server)
37
37
  - [textDocument/formatting](#textdocumentformatting)
38
- - [textDocument/inlayHints](#textdocumentinlayhints)
38
+ - [textDocument/inlayHint](#textdocumentinlayhint)
39
39
  - [syntaxTree/visualizing](#syntaxtreevisualizing)
40
40
  - [Plugins](#plugins)
41
41
  - [Configuration](#configuration)
@@ -402,7 +402,7 @@ By default, the language server is relatively minimal, mostly meant to provide a
402
402
 
403
403
  As mentioned above, the language server responds to formatting requests with the formatted document. It typically responds on the order of tens of milliseconds, so it should be fast enough for any IDE.
404
404
 
405
- ### textDocument/inlayHints
405
+ ### textDocument/inlayHint
406
406
 
407
407
  The language server also responds to the relatively new inlay hints request. This request allows the language server to define additional information that should exist in the source code as helpful hints to the developer. In our case we use it to display things like implicit parentheses. For example, if you had the following code:
408
408
 
@@ -410,7 +410,7 @@ The language server also responds to the relatively new inlay hints request. Thi
410
410
  1 + 2 * 3
411
411
  ```
412
412
 
413
- Implicity, the `2 * 3` is going to be executed first because the `*` operator has higher precedence than the `+` operator. However, to ease mental overhead, our language server includes small parentheses to make this explicit, as in:
413
+ Implicity, the `2 * 3` is going to be executed first because the `*` operator has higher precedence than the `+` operator. To ease mental overhead, our language server includes small parentheses to make this explicit, as in:
414
414
 
415
415
  ```ruby
416
416
  1 + ₍2 * 3₎
@@ -68,7 +68,9 @@ module SyntaxTree
68
68
  # going to just print out the node as it was seen in the source.
69
69
  doc =
70
70
  if leading.last&.ignore?
71
- text(source[node.location.start_char...node.location.end_char])
71
+ range = source[node.location.start_char...node.location.end_char]
72
+ separator = -> { breakable(indent: false, force: true) }
73
+ seplist(range.split(/\r?\n/, -1), separator) { |line| text(line) }
72
74
  else
73
75
  node.format(self)
74
76
  end
@@ -2,21 +2,37 @@
2
2
 
3
3
  module SyntaxTree
4
4
  class LanguageServer
5
- # This class provides inlay hints for the language server. It existed
6
- # before the spec was finalized so, so it provides two result formats:
7
- # aligned with the spec (`#all`) and proprietary (`#before` and `#after`).
8
- #
9
- # For more information, see the spec here:
5
+ # This class provides inlay hints for the language server. For more
6
+ # information, see the spec here:
10
7
  # https://github.com/microsoft/language-server-protocol/issues/956.
11
- #
12
8
  class InlayHints < Visitor
13
- attr_reader :stack, :all, :before, :after
9
+ # This represents a hint that is going to be displayed in the editor.
10
+ class Hint
11
+ attr_reader :line, :character, :label
12
+
13
+ def initialize(line:, character:, label:)
14
+ @line = line
15
+ @character = character
16
+ @label = label
17
+ end
18
+
19
+ # This is the shape that the LSP expects.
20
+ def to_json(*opts)
21
+ {
22
+ position: {
23
+ line: line,
24
+ character: character
25
+ },
26
+ label: label
27
+ }.to_json(*opts)
28
+ end
29
+ end
30
+
31
+ attr_reader :stack, :hints
14
32
 
15
33
  def initialize
16
34
  @stack = []
17
- @all = []
18
- @before = Hash.new { |hash, key| hash[key] = +"" }
19
- @after = Hash.new { |hash, key| hash[key] = +"" }
35
+ @hints = []
20
36
  end
21
37
 
22
38
  def visit(node)
@@ -98,14 +114,11 @@ module SyntaxTree
98
114
  #
99
115
  def visit_rescue(node)
100
116
  if node.exception.nil?
101
- after[node.location.start_char + "rescue".length] << " StandardError"
102
- all << {
103
- position: {
104
- line: node.location.start_line - 1,
105
- character: node.location.start_column + "rescue".length
106
- },
117
+ hints << Hint.new(
118
+ line: node.location.start_line - 1,
119
+ character: node.location.start_column + "rescue".length,
107
120
  label: " StandardError"
108
- }
121
+ )
109
122
  end
110
123
 
111
124
  super
@@ -128,31 +141,20 @@ module SyntaxTree
128
141
  super
129
142
  end
130
143
 
131
- def self.find(program)
132
- visitor = new
133
- visitor.visit(program)
134
- visitor
135
- end
136
-
137
144
  private
138
145
 
139
146
  def parentheses(location)
140
- all << {
141
- position: {
142
- line: location.start_line - 1,
143
- character: location.start_column
144
- },
147
+ hints << Hint.new(
148
+ line: location.start_line - 1,
149
+ character: location.start_column,
145
150
  label: "₍"
146
- }
147
- all << {
148
- position: {
149
- line: location.end_line - 1,
150
- character: location.end_column
151
- },
151
+ )
152
+
153
+ hints << Hint.new(
154
+ line: location.end_line - 1,
155
+ character: location.end_column,
152
156
  label: "₎"
153
- }
154
- before[location.start_char] << "₍"
155
- after[location.end_char] << "₎"
157
+ )
156
158
  end
157
159
  end
158
160
  end
@@ -20,73 +20,51 @@ module SyntaxTree
20
20
  @output = output.binmode
21
21
  end
22
22
 
23
+ # rubocop:disable Layout/LineLength
23
24
  def run
24
25
  store =
25
26
  Hash.new do |hash, uri|
26
- hash[uri] = File.binread(CGI.unescape(URI.parse(uri).path))
27
+ filepath = CGI.unescape(URI.parse(uri).path)
28
+ File.exist?(filepath) ? (hash[uri] = File.read(filepath)) : nil
27
29
  end
28
30
 
29
31
  while (headers = input.gets("\r\n\r\n"))
30
32
  source = input.read(headers[/Content-Length: (\d+)/i, 1].to_i)
31
33
  request = JSON.parse(source, symbolize_names: true)
32
34
 
35
+ # stree-ignore
33
36
  case request
34
37
  in { method: "initialize", id: }
35
38
  store.clear
36
39
  write(id: id, result: { capabilities: capabilities })
37
- in method: "initialized"
40
+ in { method: "initialized" }
38
41
  # ignored
39
- in method: "shutdown" # tolerate missing ID to be a good citizen
42
+ in { method: "shutdown" } # tolerate missing ID to be a good citizen
40
43
  store.clear
41
44
  write(id: request[:id], result: {})
42
45
  return
43
- in {
44
- method: "textDocument/didChange",
45
- params: { textDocument: { uri: }, contentChanges: [{ text: }, *] }
46
- }
46
+ in { method: "textDocument/didChange", params: { textDocument: { uri: }, contentChanges: [{ text: }, *] } }
47
47
  store[uri] = text
48
- in {
49
- method: "textDocument/didOpen",
50
- params: { textDocument: { uri:, text: } }
51
- }
48
+ in { method: "textDocument/didOpen", params: { textDocument: { uri:, text: } } }
52
49
  store[uri] = text
53
- in {
54
- method: "textDocument/didClose", params: { textDocument: { uri: } }
55
- }
50
+ in { method: "textDocument/didClose", params: { textDocument: { uri: } } }
56
51
  store.delete(uri)
57
- in {
58
- method: "textDocument/formatting",
59
- id:,
60
- params: { textDocument: { uri: } }
61
- }
62
- write(id: id, result: [format(store[uri])])
63
- in {
64
- # official RPC in LSP spec 3.17
65
- method: "textDocument/inlayHint",
66
- id:,
67
- params: { textDocument: { uri: } }
68
- }
69
- write(id: id, result: inlay_hints(store[uri], false))
70
- in {
71
- # proprietary RPC (deprecated) between this gem and vscode-syntax-tree
72
- method: "textDocument/inlayHints",
73
- id:,
74
- params: { textDocument: { uri: } }
75
- }
76
- write(id: id, result: inlay_hints(store[uri], true))
77
- in {
78
- method: "syntaxTree/visualizing",
79
- id:,
80
- params: { textDocument: { uri: } }
81
- }
52
+ in { method: "textDocument/formatting", id:, params: { textDocument: { uri: } } }
53
+ contents = store[uri]
54
+ write(id: id, result: contents ? [format(store[uri])] : nil)
55
+ in { method: "textDocument/inlayHint", id:, params: { textDocument: { uri: } } }
56
+ contents = store[uri]
57
+ write(id: id, result: contents ? inlay_hints(store[uri]) : nil)
58
+ in { method: "syntaxTree/visualizing", id:, params: { textDocument: { uri: } } }
82
59
  write(id: id, result: PP.pp(SyntaxTree.parse(store[uri]), +""))
83
- in method: %r{\$/.+}
60
+ in { method: %r{\$/.+} }
84
61
  # ignored
85
62
  else
86
63
  raise ArgumentError, "Unhandled: #{request}"
87
64
  end
88
65
  end
89
66
  end
67
+ # rubocop:enable Layout/LineLength
90
68
 
91
69
  private
92
70
 
@@ -119,21 +97,14 @@ module SyntaxTree
119
97
  }
120
98
  end
121
99
 
122
- def inlay_hints(source, proprietary)
123
- inlay_hints = InlayHints.find(SyntaxTree.parse(source))
124
- serialize = ->(position, text) { { position: position, text: text } }
125
-
126
- if proprietary
127
- {
128
- before: inlay_hints.before.map(&serialize),
129
- after: inlay_hints.after.map(&serialize)
130
- }
131
- else
132
- inlay_hints.all
133
- end
100
+ def inlay_hints(source)
101
+ visitor = InlayHints.new
102
+ SyntaxTree.parse(source).accept(visitor)
103
+ visitor.hints
134
104
  rescue Parser::ParseError
135
105
  # If there is a parse error, then we're not going to return any inlay
136
106
  # hints for this source.
107
+ []
137
108
  end
138
109
 
139
110
  def write(value)
@@ -1641,12 +1641,12 @@ module SyntaxTree
1641
1641
  heredoc = @heredocs[-1]
1642
1642
 
1643
1643
  location =
1644
- Location.token(
1645
- line: lineno,
1646
- char: char_pos,
1647
- column: current_column,
1648
- size: value.size + 1
1649
- )
1644
+ Location.token(
1645
+ line: lineno,
1646
+ char: char_pos,
1647
+ column: current_column,
1648
+ size: value.size + 1
1649
+ )
1650
1650
 
1651
1651
  heredoc_end = HeredocEnd.new(value: value.chomp, location: location)
1652
1652
 
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module SyntaxTree
4
- VERSION = "2.9.0"
4
+ VERSION = "3.0.0"
5
5
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: syntax_tree
3
3
  version: !ruby/object:Gem::Version
4
- version: 2.9.0
4
+ version: 3.0.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Kevin Newton
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2022-07-04 00:00:00.000000000 Z
11
+ date: 2022-07-05 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: prettier_print
@@ -160,7 +160,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
160
160
  - !ruby/object:Gem::Version
161
161
  version: '0'
162
162
  requirements: []
163
- rubygems_version: 3.4.0.dev
163
+ rubygems_version: 3.3.3
164
164
  signing_key:
165
165
  specification_version: 4
166
166
  summary: A parser based on ripper