6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
|
# File 'lib/puppet-languageserver/manifest/signature_provider.rb', line 6
def self.signature_help(session_state, content, line_num, char_num, options = {})
options = {
tasks_mode: false
}.merge(options)
result = PuppetLanguageServer::PuppetParserHelper.object_under_cursor(content, line_num, char_num,
multiple_attempts: false,
tasks_mode: options[:tasks_mode],
remove_trigger_char: false)
response = LSP::SignatureHelp.new.from_h!('signatures' => [], 'activeSignature' => nil, 'activeParameter' => nil)
return response if result.nil?
item = result[:model]
path = result[:path]
locator = result[:locator]
function_ast_object = nil
if item.instance_of?(::Puppet::Pops::Model::CallNamedFunctionExpression)
function_ast_object = item
else
distance_up_ast = -1
function_ast_object = path[distance_up_ast]
while !function_ast_object.nil? && function_ast_object.class.to_s != 'Puppet::Pops::Model::CallNamedFunctionExpression'
distance_up_ast -= 1
function_ast_object = path[distance_up_ast]
end
raise "Unable to find suitable parent object for object of type #{item.class}" if function_ast_object.nil?
end
function_name = function_ast_object.functor_expr.value
raise 'Could not determine the function name' if function_name.nil?
line_offset = if function_ast_object.respond_to?(:locator)
function_ast_object.locator.line_index[line_num]
else
locator.line_index[line_num]
end
abs_offset = line_offset + char_num
param_number = param_number_from_ast(abs_offset, function_ast_object, locator)
raise 'Cursor is not within the function expression' if param_number.nil?
func_info = PuppetLanguageServer::PuppetHelper.function(session_state, function_name)
raise "Function #{function_name} does not exist" if func_info.nil?
func_info.signatures.each do |sig|
lsp_sig = LSP::SignatureInformation.new.from_h!(
'label' => sig.key,
'documentation' => sig.doc,
'parameters' => []
)
sig.parameters.each do |param|
lsp_sig.parameters << LSP::ParameterInformation.new.from_h!(
'label' => param.signature_key_offset.nil? || param.signature_key_length.nil? ? param.name : [param.signature_key_offset, param.signature_key_offset + param.signature_key_length],
'documentation' => param.doc
)
end
response.signatures << lsp_sig
end
func_arg_count = function_ast_object.arguments.count
signature_number = func_info.signatures.find_index { |sig| sig.parameters.count >= func_arg_count }
signature_number = 0 if signature_number.nil? && func_info.signatures.count > 0
response.activeSignature = signature_number unless signature_number.nil?
response.activeParameter = param_number
response
end
|