ruby-lsp-ree 0.1.0 → 0.1.2

Sign up to get free protection for your applications and to get access to all the features.
@@ -1,78 +1,54 @@
1
1
  module RubyLsp
2
2
  module Ree
3
3
  module ReeLspUtils
4
+ Entry = RubyIndexer::Entry
5
+
6
+ def find_local_file_path(file_path)
7
+ file_name = file_path + ".rb"
8
+ Dir[File.join('**', file_name)].first
9
+ end
10
+
4
11
  def package_name_from_uri(uri)
5
12
  uri_parts = uri.to_s.split('/')
6
- package_index = uri_parts.find_index('package') + 1
7
- uri_parts[package_index]
8
- end
13
+
14
+ package_folder_index = uri_parts.find_index('package')
15
+ return unless package_folder_index
9
16
 
10
- def path_from_package(uri)
11
- uri_parts = uri.chomp(File.extname(uri)).split('/')
12
- pack_folder_index = uri_parts.index('package')
13
- uri_parts.drop(pack_folder_index+1).join('/')
17
+ uri_parts[package_folder_index + 1]
14
18
  end
15
19
 
16
- def parse_document_from_uri(uri)
17
- ast = Prism.parse_file(uri.path).value
18
- result = parse_document(ast)
20
+ def path_from_package_folder(uri)
21
+ uri_parts = uri.chomp(File.extname(uri)).split('/')
19
22
 
20
- result.package_name = package_name_from_uri(uri)
23
+ package_folder_index = uri_parts.index('package')
24
+ return unless package_folder_index
21
25
 
22
- result
26
+ uri_parts.drop(package_folder_index+1).join('/')
23
27
  end
24
28
 
25
- def parse_document_from_source(source)
26
- ast = Prism.parse(source).value
27
- parse_document(ast)
28
- end
29
+ def get_ree_type(ree_object)
30
+ type_comment = ree_object.comments.to_s.lines[1]
31
+ return unless type_comment
29
32
 
30
- def parse_document(ast)
31
- class_node = ast.statements.body.detect{ |node| node.is_a?(Prism::ClassNode) }
32
- fn_node = class_node.body.body.detect{ |node| node.name == :fn }
33
- block_node = fn_node.block
33
+ type_comment.split(' ').last
34
+ end
34
35
 
35
- link_nodes = if block_node && block_node.body
36
- block_node.body.body.select{ |node| node.name == :link }
37
- else
38
- []
39
- end
36
+ def get_range_for_fn_insert(parsed_doc, link_text)
37
+ fn_line = nil
38
+ position = nil
40
39
 
41
- linked_objects = link_nodes.map do |link_node|
42
- name_arg_node = link_node.arguments.arguments.first
40
+ if parsed_doc.links_container_node
41
+ links_container_node = parsed_doc.links_container_node
42
+ fn_line = links_container_node.location.start_line
43
43
 
44
- name_val = case name_arg_node
45
- when Prism::SymbolNode
46
- name_arg_node.value
47
- when Prism::StringNode
48
- name_arg_node.unescaped
44
+ position = if parsed_doc.links_container_block_node
45
+ parsed_doc.links_container_block_node.opening_loc.end_column + 1
49
46
  else
50
- ""
47
+ links_container_node.arguments.location.end_column + 1
51
48
  end
52
-
53
- OpenStruct.new(
54
- name: name_val,
55
- imports: parse_link_node_imports(link_node)
56
- )
57
- end
58
-
59
- return OpenStruct.new(
60
- ast: ast,
61
- class_node: class_node,
62
- fn_node: fn_node,
63
- block_node: block_node,
64
- link_nodes: link_nodes,
65
- linked_objects: linked_objects
66
- )
67
- end
68
-
69
- def get_range_for_fn_insert(doc_info, link_text)
70
- fn_line = doc_info.fn_node.location.start_line
71
-
72
- position = if doc_info.block_node
73
- doc_info.block_node.opening_loc.end_column + 1
74
- else
75
- doc_info.fn_node.arguments.location.end_column + 1
49
+ elsif parsed_doc.includes_link_dsl?
50
+ fn_line = parsed_doc.link_nodes.first.location.start_line - 1
51
+ position = parsed_doc.link_nodes.first.location.start_column
76
52
  end
77
53
 
78
54
  Interface::Range.new(
@@ -81,24 +57,94 @@ module RubyLsp
81
57
  )
82
58
  end
83
59
 
84
- def parse_link_node_imports(node)
85
- return [] if node.arguments.arguments.size == 1
86
-
87
- last_arg = node.arguments.arguments.last
88
60
 
89
- if last_arg.is_a?(Prism::KeywordHashNode)
90
- import_arg = last_arg.elements.detect{ _1.key.unescaped == 'import' }
91
- return [] unless import_arg
61
+ # params(parameters_node: Prism::ParametersNode).returns(Array[Entry::Parameter])
62
+ # copied from ruby-lsp DeclarationListener#list_params
63
+ def signature_params_from_node(parameters_node)
64
+ return [] unless parameters_node
65
+
66
+ parameters = []
67
+
68
+ parameters_node.requireds.each do |required|
69
+ name = parameter_name(required)
70
+ next unless name
71
+
72
+ parameters << Entry::RequiredParameter.new(name: name)
73
+ end
74
+
75
+ parameters_node.optionals.each do |optional|
76
+ name = parameter_name(optional)
77
+ next unless name
78
+
79
+ parameters << Entry::OptionalParameter.new(name: name)
80
+ end
81
+
82
+ rest = parameters_node.rest
83
+
84
+ if rest.is_a?(Prism::RestParameterNode)
85
+ rest_name = rest.name || Entry::RestParameter::DEFAULT_NAME
86
+ parameters << Entry::RestParameter.new(name: rest_name)
87
+ end
88
+
89
+ parameters_node.keywords.each do |keyword|
90
+ name = parameter_name(keyword)
91
+ next unless name
92
+
93
+ case keyword
94
+ when Prism::RequiredKeywordParameterNode
95
+ parameters << Entry::KeywordParameter.new(name: name)
96
+ when Prism::OptionalKeywordParameterNode
97
+ parameters << Entry::OptionalKeywordParameter.new(name: name)
98
+ end
99
+ end
100
+
101
+ keyword_rest = parameters_node.keyword_rest
102
+
103
+ case keyword_rest
104
+ when Prism::KeywordRestParameterNode
105
+ keyword_rest_name = parameter_name(keyword_rest) || Entry::KeywordRestParameter::DEFAULT_NAME
106
+ parameters << Entry::KeywordRestParameter.new(name: keyword_rest_name)
107
+ when Prism::ForwardingParameterNode
108
+ parameters << Entry::ForwardingParameter.new
109
+ end
110
+
111
+ parameters_node.posts.each do |post|
112
+ name = parameter_name(post)
113
+ next unless name
114
+
115
+ parameters << Entry::RequiredParameter.new(name: name)
116
+ end
117
+
118
+ block = parameters_node.block
119
+ parameters << Entry::BlockParameter.new(name: block.name || Entry::BlockParameter::DEFAULT_NAME) if block
120
+
121
+ parameters
122
+ end
123
+
124
+ # params(node: Prism::Node).returns(Symbol)
125
+ # copied from ruby-lsp DeclarationListener#parameter_name
126
+ def parameter_name(node)
127
+ case node
128
+ when Prism::RequiredParameterNode, Prism::OptionalParameterNode,
129
+ Prism::RequiredKeywordParameterNode, Prism::OptionalKeywordParameterNode,
130
+ Prism::RestParameterNode, Prism::KeywordRestParameterNode
131
+ node.name
132
+ when Prism::MultiTargetNode
133
+ names = node.lefts.map { |parameter_node| parameter_name(parameter_node) }
134
+
135
+ rest = node.rest
136
+ if rest.is_a?(Prism::SplatNode)
137
+ name = rest.expression&.slice
138
+ names << (rest.operator == "*" ? "*#{name}".to_sym : name&.to_sym)
139
+ end
140
+
141
+ names << nil if rest.is_a?(Prism::ImplicitRestNode)
142
+
143
+ names.concat(node.rights.map { |parameter_node| parameter_name(parameter_node) })
92
144
 
93
- [import_arg.value.body.body.first.name.to_s]
94
- elsif last_arg.is_a?(Prism::LambdaNode)
95
- [last_arg.body.body.first.name.to_s]
96
- else
97
- return []
145
+ names_with_commas = names.join(", ")
146
+ :"(#{names_with_commas})"
98
147
  end
99
- rescue => e
100
- $stderr.puts("can't parse imports: #{e.message}")
101
- return []
102
148
  end
103
149
  end
104
150
  end
@@ -0,0 +1,43 @@
1
+ module RubyLsp
2
+ module Ree
3
+ class ReeObjectFinder
4
+ MAX_LIMIT = 1000
5
+
6
+ REE_OBJECT_STRING = 'ree_object'
7
+ ENUM_TYPE_STRING = 'type: :enum'
8
+ DAO_TYPE_STRING = 'type: :dao'
9
+ BEAN_TYPE_STRING = 'type: :bean'
10
+
11
+ def self.search_objects(index, name, limit)
12
+ index.prefix_search(name)
13
+ .take(MAX_LIMIT)
14
+ .flatten
15
+ .select{ _1.comments }
16
+ .select{ _1.comments.to_s.lines.first&.chomp == REE_OBJECT_STRING }
17
+ .sort_by{ _1.name.length }
18
+ .take(limit)
19
+ end
20
+
21
+ def self.find_enum(index, name)
22
+ objects_by_name = index[name]
23
+ return unless objects_by_name
24
+
25
+ objects_by_name.detect{ _1.comments.lines[1]&.chomp == ENUM_TYPE_STRING }
26
+ end
27
+
28
+ def self.find_dao(index, name)
29
+ objects_by_name = index[name]
30
+ return unless objects_by_name
31
+
32
+ objects_by_name.detect{ _1.comments.lines[1]&.chomp == DAO_TYPE_STRING }
33
+ end
34
+
35
+ def self.find_bean(index, name)
36
+ objects_by_name = index[name]
37
+ return unless objects_by_name
38
+
39
+ objects_by_name.detect{ _1.comments.lines[1]&.chomp == BEAN_TYPE_STRING }
40
+ end
41
+ end
42
+ end
43
+ end
@@ -3,7 +3,7 @@
3
3
  module Ruby
4
4
  module Lsp
5
5
  module Ree
6
- VERSION = "0.1.0"
6
+ VERSION = "0.1.2"
7
7
  end
8
8
  end
9
9
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: ruby-lsp-ree
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.0
4
+ version: 0.1.2
5
5
  platform: ruby
6
6
  authors:
7
7
  - Ruslan Gatiyatov
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2025-01-31 00:00:00.000000000 Z
11
+ date: 2025-02-14 00:00:00.000000000 Z
12
12
  dependencies: []
13
13
  description: A Ruby LSP addon that adds extra editor functionality for Ree applications
14
14
  email:
@@ -20,15 +20,21 @@ files:
20
20
  - CHANGELOG.md
21
21
  - CODE_OF_CONDUCT.md
22
22
  - Gemfile
23
+ - Gemfile.lock
23
24
  - LICENSE.txt
24
25
  - README.md
25
26
  - Rakefile
26
27
  - lib/ruby_lsp/ruby_lsp_ree/addon.rb
27
28
  - lib/ruby_lsp/ruby_lsp_ree/completion.rb
29
+ - lib/ruby_lsp/ruby_lsp_ree/completion_utils.rb
28
30
  - lib/ruby_lsp/ruby_lsp_ree/definition.rb
31
+ - lib/ruby_lsp/ruby_lsp_ree/parsing/parsed_document.rb
32
+ - lib/ruby_lsp/ruby_lsp_ree/parsing/parsed_document_builder.rb
33
+ - lib/ruby_lsp/ruby_lsp_ree/parsing/parsed_link_node.rb
29
34
  - lib/ruby_lsp/ruby_lsp_ree/ree_formatter.rb
30
35
  - lib/ruby_lsp/ruby_lsp_ree/ree_indexing_enhancement.rb
31
36
  - lib/ruby_lsp/ruby_lsp_ree/ree_lsp_utils.rb
37
+ - lib/ruby_lsp/ruby_lsp_ree/ree_object_finder.rb
32
38
  - lib/ruby_lsp_ree.rb
33
39
  - lib/ruby_lsp_ree/version.rb
34
40
  - ruby-lsp-ree.gemspec