Skip to content

Commit 6ee0252

Browse files
authored
Merge pull request #166 from glennsarti/refactor-caching
(GH-167) Refactor Language Server inmemory caching
2 parents 3511698 + d57c24e commit 6ee0252

File tree

12 files changed

+169
-246
lines changed

12 files changed

+169
-246
lines changed

lib/puppet-languageserver/manifest/completion_provider.rb

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -58,7 +58,7 @@ def self.complete(content, line_num, char_num, options = {})
5858
item_object = PuppetLanguageServer::PuppetHelper.get_type(item.type_name.value)
5959
unless item_object.nil?
6060
# Add Parameters
61-
item_object.parameters.each_key do |name|
61+
item_object.attributes.select { |_name, data| data[:type] == :param }.each_key do |name|
6262
items << LSP::CompletionItem.new(
6363
'label' => name.to_s,
6464
'kind' => LSP::CompletionItemKind::PROPERTY,
@@ -71,7 +71,7 @@ def self.complete(content, line_num, char_num, options = {})
7171
)
7272
end
7373
# Add Properties
74-
item_object.properties.each_key do |name|
74+
item_object.attributes.select { |_name, data| data[:type] == :property }.each_key do |name|
7575
items << LSP::CompletionItem.new(
7676
'label' => name.to_s,
7777
'kind' => LSP::CompletionItemKind::PROPERTY,
@@ -249,7 +249,7 @@ def self.resolve(completion_item)
249249
# The param/property list should initially sorted alphabetically
250250
attr_names.sort!
251251
# Add the 'ensure' param/property at the top if the resource supports it
252-
attr_names.insert(0, 'ensure') unless item_type.allattrs.find_index(:ensure).nil?
252+
attr_names.insert(0, 'ensure') unless item_type.attributes.keys.find_index(:ensure).nil?
253253
# Get the longest string length for later hash-rocket padding
254254
max_length = -1
255255
attr_names.each { |name| max_length = name.length if name.length > max_length }
@@ -269,7 +269,7 @@ def self.resolve(completion_item)
269269
when 'resource_parameter'
270270
item_type = PuppetLanguageServer::PuppetHelper.get_type(data['resource_type'])
271271
return result if item_type.nil?
272-
param_type = item_type.parameters[data['param'].intern]
272+
param_type = item_type.attributes[data['param'].intern]
273273
unless param_type.nil?
274274
# TODO: More things?
275275
result.documentation = param_type[:doc] unless param_type[:doc].nil?
@@ -278,7 +278,7 @@ def self.resolve(completion_item)
278278
when 'resource_property'
279279
item_type = PuppetLanguageServer::PuppetHelper.get_type(data['resource_type'])
280280
return result if item_type.nil?
281-
prop_type = item_type.properties[data['prop'].intern]
281+
prop_type = item_type.attributes[data['prop'].intern]
282282
unless prop_type.nil?
283283
# TODO: More things?
284284
result.documentation = prop_type[:doc] unless prop_type[:doc].nil?

lib/puppet-languageserver/manifest/document_symbol_provider.rb

Lines changed: 9 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -3,14 +3,14 @@
33
module PuppetLanguageServer
44
module Manifest
55
module DocumentSymbolProvider
6-
def self.workspace_symbols(query)
6+
def self.workspace_symbols(query, object_cache)
77
query = '' if query.nil?
88
result = []
9-
PuppetLanguageServer::PuppetHelper.all_objects do |key, item|
9+
object_cache.all_objects do |key, item|
1010
key_string = key.to_s
11-
next unless key_string.include?(query)
11+
next unless query.empty? || key_string.include?(query)
1212
case item
13-
when PuppetLanguageServer::PuppetHelper::PuppetType
13+
when PuppetLanguageServer::Sidecar::Protocol::PuppetType
1414
result << LSP::SymbolInformation.new(
1515
'name' => key_string,
1616
'kind' => LSP::SymbolKind::METHOD,
@@ -21,7 +21,7 @@ def self.workspace_symbols(query)
2121
}
2222
)
2323

24-
when PuppetLanguageServer::PuppetHelper::PuppetFunction
24+
when PuppetLanguageServer::Sidecar::Protocol::PuppetFunction
2525
result << LSP::SymbolInformation.new(
2626
'name' => key_string,
2727
'kind' => LSP::SymbolKind::FUNCTION,
@@ -32,7 +32,7 @@ def self.workspace_symbols(query)
3232
}
3333
)
3434

35-
when PuppetLanguageServer::PuppetHelper::PuppetClass
35+
when PuppetLanguageServer::Sidecar::Protocol::PuppetClass
3636
result << LSP::SymbolInformation.new(
3737
'name' => key_string,
3838
'kind' => LSP::SymbolKind::CLASS,
@@ -42,6 +42,9 @@ def self.workspace_symbols(query)
4242
'range' => LSP.create_range(item.line, 0, item.line, 1024)
4343
}
4444
)
45+
46+
else
47+
PuppetLanguageServer.log_message(:warn, "[Manifest::DocumentSymbolProvider] Unknown object type #{item.class}")
4548
end
4649
end
4750
result

lib/puppet-languageserver/manifest/hover_provider.rb

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -49,10 +49,10 @@ def self.resolve(content, line_num, char_num, options = {})
4949
resource_object = PuppetLanguageServer::PuppetHelper.get_type(resource_type_name)
5050
unless resource_object.nil?
5151
# Check if it's a property
52-
attribute = resource_object.properties.key?(item.attribute_name.intern)
53-
if attribute != false
52+
attribute = resource_object.attributes[item.attribute_name.intern]
53+
if attribute[:type] == :property
5454
content = get_attribute_type_property_content(resource_object, item.attribute_name.intern)
55-
elsif resource_object.parameters.key?(item.attribute_name.intern)
55+
elsif attribute[:type] == :param
5656
content = get_attribute_type_parameter_content(resource_object, item.attribute_name.intern)
5757
end
5858
end
@@ -114,14 +114,14 @@ def self.get_fact_content(factname)
114114
end
115115

116116
def self.get_attribute_type_parameter_content(item_type, param)
117-
param_type = item_type.parameters[param]
117+
param_type = item_type.attributes[param]
118118
content = "**#{param}** Parameter"
119119
content += "\n\n#{param_type[:doc]}" unless param_type[:doc].nil?
120120
content
121121
end
122122

123123
def self.get_attribute_type_property_content(item_type, property)
124-
prop_type = item_type.properties[property]
124+
prop_type = item_type.attributes[property]
125125
content = "**#{property}** Property"
126126
content += "\n\n(_required_)" if prop_type[:required?]
127127
content += "\n\n#{prop_type[:doc]}" unless prop_type[:doc].nil?
@@ -161,7 +161,7 @@ def self.get_puppet_type_content(item_type)
161161
content = "**#{item_type.key}** Resource\n\n"
162162
content += "\n\n#{item_type.doc}" unless item_type.doc.nil?
163163
content += "\n\n---\n"
164-
item_type.allattrs.sort.each do |attr|
164+
item_type.attributes.keys.sort.each do |attr|
165165
content += "* #{attr}\n"
166166
end
167167

lib/puppet-languageserver/message_router.rb

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -187,7 +187,12 @@ def receive_request(request)
187187
begin
188188
case documents.document_type(file_uri)
189189
when :manifest
190-
request.reply_result(PuppetLanguageServer::Manifest::SignatureProvider.signature_help(content, line_num, char_num, :tasks_mode => PuppetLanguageServer::DocumentStore.module_plan_file?(file_uri)))
190+
request.reply_result(PuppetLanguageServer::Manifest::SignatureProvider.signature_help(
191+
content,
192+
line_num,
193+
char_num,
194+
:tasks_mode => PuppetLanguageServer::DocumentStore.plan_file?(file_uri)
195+
))
191196
else
192197
raise "Unable to provide signatures on #{file_uri}"
193198
end
@@ -199,7 +204,7 @@ def receive_request(request)
199204
when 'workspace/symbol'
200205
begin
201206
result = []
202-
result.concat(PuppetLanguageServer::Manifest::DocumentSymbolProvider.workspace_symbols(request.params['query']))
207+
result.concat(PuppetLanguageServer::Manifest::DocumentSymbolProvider.workspace_symbols(request.params['query'], PuppetLanguageServer::PuppetHelper.cache))
203208
request.reply_result(result)
204209
rescue StandardError => e
205210
PuppetLanguageServer.log_message(:error, "(workspace/symbol) #{e}")

lib/puppet-languageserver/puppet_helper.rb

Lines changed: 2 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
require 'pathname'
44
require 'tempfile'
55

6-
%w[puppet_helper/cache_objects puppet_helper/cache].each do |lib|
6+
%w[puppet_helper/cache].each do |lib|
77
begin
88
require "puppet-languageserver/#{lib}"
99
rescue LoadError
@@ -28,14 +28,6 @@ def self.initialize_helper(options = {})
2828
sidecar_queue.cache = @inmemory_cache
2929
end
3030

31-
def self.all_objects(&_block)
32-
return nil if @default_types_loaded == false
33-
raise('Puppet Helper Cache has not been configured') if @inmemory_cache.nil?
34-
@inmemory_cache.all_objects do |key, item|
35-
yield key, item
36-
end
37-
end
38-
3931
# Node Graph
4032
def self.get_node_graph(content, local_workspace)
4133
with_temporary_file(content) do |filepath|
@@ -174,8 +166,8 @@ def self.class_names
174166
@inmemory_cache.object_names_by_section(:class).map(&:to_s)
175167
end
176168

177-
# The object cache. Note this should only be used for testing
178169
def self.cache
170+
raise('Puppet Helper Cache has not been configured') if @inmemory_cache.nil?
179171
@inmemory_cache
180172
end
181173

lib/puppet-languageserver/puppet_helper/cache.rb

Lines changed: 36 additions & 49 deletions
Original file line numberDiff line numberDiff line change
@@ -3,49 +3,48 @@
33
module PuppetLanguageServer
44
module PuppetHelper
55
class Cache
6+
SECTIONS = %i[class type function].freeze
7+
ORIGINS = %i[default workspace].freeze
8+
69
def initialize(_options = {})
710
@cache_lock = Mutex.new
8-
@inmemory_cache = []
9-
# The cache consists of an array of module PuppetLanguageServer::PuppetHelper objects
11+
@inmemory_cache = {}
12+
# The cache consists of hash of hashes
13+
# @inmemory_cache[<origin>][<section>] = [ Array of SidecarProtocol Objects ]
1014
end
1115

12-
def import_sidecar_list!(list, section, origin = nil)
13-
section_object = section_to_object(section)
14-
return if section_object.nil?
16+
def import_sidecar_list!(list, section, origin)
17+
return if origin.nil?
18+
return if section.nil?
1519
list = [] if list.nil?
1620

1721
@cache_lock.synchronize do
1822
# Remove the existing items
19-
@inmemory_cache.reject! { |item| item.is_a?(section_object) && (origin.nil? || item.origin == origin) }
20-
# Append the list
21-
list.each do |item|
22-
object = sidecar_protocol_to_cache_object(item)
23-
object.origin = origin
24-
@inmemory_cache << object
25-
end
23+
remove_section_impl(section, origin)
24+
# Set the list
25+
@inmemory_cache[origin] = {} if @inmemory_cache[origin].nil?
26+
@inmemory_cache[origin][section] = list
2627
end
2728
nil
2829
end
2930

3031
def remove_section!(section, origin = nil)
31-
section_object = section_to_object(section)
32-
return if section_object.nil?
33-
3432
@cache_lock.synchronize do
35-
@inmemory_cache.reject! { |item| item.is_a?(section_object) && (origin.nil? || item.origin == origin) }
33+
remove_section_impl(section, origin)
3634
end
3735
nil
3836
end
3937

4038
# section => <Type of object in the file :function, :type, :class>
4139
def object_by_name(section, name)
4240
name = name.intern if name.is_a?(String)
43-
section_object = section_to_object(section)
44-
return nil if section_object.nil?
41+
return nil if section.nil?
4542
@cache_lock.synchronize do
46-
@inmemory_cache.each do |item|
47-
next unless item.is_a?(section_object) && item.key == name
48-
return item
43+
@inmemory_cache.each do |_, sections|
44+
next if sections[section].nil? || sections[section].empty?
45+
sections[section].each do |item|
46+
return item if item.key == name
47+
end
4948
end
5049
end
5150
nil
@@ -54,12 +53,11 @@ def object_by_name(section, name)
5453
# section => <Type of object in the file :function, :type, :class>
5554
def object_names_by_section(section)
5655
result = []
57-
section_object = section_to_object(section)
58-
return result if section_object.nil?
56+
return result if section.nil?
5957
@cache_lock.synchronize do
60-
@inmemory_cache.each do |item|
61-
next unless item.is_a?(section_object)
62-
result << item.key
58+
@inmemory_cache.each do |_, sections|
59+
next if sections[section].nil? || sections[section].empty?
60+
result.concat(sections[section].map { |i| i.key })
6361
end
6462
end
6563
result.uniq!
@@ -68,44 +66,33 @@ def object_names_by_section(section)
6866

6967
# section => <Type of object in the file :function, :type, :class>
7068
def objects_by_section(section, &_block)
71-
section_object = section_to_object(section)
72-
return if section_object.nil?
69+
return if section.nil?
7370
@cache_lock.synchronize do
74-
@inmemory_cache.each do |item|
75-
next unless item.is_a?(section_object)
76-
yield item.key, item
71+
@inmemory_cache.each do |_, sections|
72+
next if sections[section].nil? || sections[section].empty?
73+
sections[section].each { |i| yield i.key, i }
7774
end
7875
end
7976
end
8077

8178
def all_objects(&_block)
8279
@cache_lock.synchronize do
83-
@inmemory_cache.each do |item|
84-
yield item.key, item
80+
@inmemory_cache.each do |_origin, sections|
81+
sections.each do |_section_name, list|
82+
list.each { |i| yield i.key, i }
83+
end
8584
end
8685
end
8786
end
8887

8988
private
9089

91-
# <Type of object in the file :function, :type, :class>
92-
def section_to_object(section)
93-
case section
94-
when :class
95-
PuppetLanguageServer::PuppetHelper::PuppetClass
96-
when :function
97-
PuppetLanguageServer::PuppetHelper::PuppetFunction
98-
when :type
99-
PuppetLanguageServer::PuppetHelper::PuppetType
90+
def remove_section_impl(section, origin = nil)
91+
@inmemory_cache.each do |list_origin, sections|
92+
next unless origin.nil? || list_origin == origin
93+
sections[section].clear unless sections[section].nil?
10094
end
10195
end
102-
103-
def sidecar_protocol_to_cache_object(value)
104-
return PuppetLanguageServer::PuppetHelper::PuppetClass.new.from_sidecar!(value) if value.is_a?(PuppetLanguageServer::Sidecar::Protocol::PuppetClass)
105-
return PuppetLanguageServer::PuppetHelper::PuppetFunction.new.from_sidecar!(value) if value.is_a?(PuppetLanguageServer::Sidecar::Protocol::PuppetFunction)
106-
return PuppetLanguageServer::PuppetHelper::PuppetType.new.from_sidecar!(value) if value.is_a?(PuppetLanguageServer::Sidecar::Protocol::PuppetType)
107-
nil
108-
end
10996
end
11097
end
11198
end

lib/puppet-languageserver/puppet_helper/cache_objects.rb

Lines changed: 0 additions & 48 deletions
This file was deleted.

0 commit comments

Comments
 (0)