Skip to content

Commit

Permalink
Merge pull request #86 from glennsarti/spike-add-workspace-symbols
Browse files Browse the repository at this point in the history
(GH-88) Add workspace symbols provider
  • Loading branch information
James Pogran authored Dec 13, 2018
2 parents 4d7d1eb + 24fbfdd commit 2cc861a
Show file tree
Hide file tree
Showing 7 changed files with 142 additions and 6 deletions.
58 changes: 58 additions & 0 deletions lib/languageserver/document_symbol.rb
Original file line number Diff line number Diff line change
Expand Up @@ -76,4 +76,62 @@ def self.create(options)
result
end
end

# /**
# * Represents information about programming constructs like variables, classes,
# * interfaces etc.
# */
# interface SymbolInformation {
# /**
# * The name of this symbol.
# */
# name: string;

# /**
# * The kind of this symbol.
# */
# kind: number;

# /**
# * Indicates if this symbol is deprecated.
# */
# deprecated?: boolean;

# /**
# * The location of this symbol. The location's range is used by a tool
# * to reveal the location in the editor. If the symbol is selected in the
# * tool the range's start information is used to position the cursor. So
# * the range usually spans more then the actual symbol's name and does
# * normally include things like visibility modifiers.
# *
# * The range doesn't have to denote a node range in the sense of a abstract
# * syntax tree. It can therefore not be used to re-construct a hierarchy of
# * the symbols.
# */
# location: Location;

# /**
# * The name of the symbol containing this symbol. This information is for
# * user interface purposes (e.g. to render a qualifier in the user interface
# * if necessary). It can't be used to re-infer a hierarchy for the document
# * symbols.
# */
# containerName?: string;
# }
module SymbolInformation
def self.create(options)
result = {}
raise('name is a required field for SymbolInformation') if options['name'].nil?
raise('kind is a required field for SymbolInformation') if options['kind'].nil?
raise('location is a required field for DocumentSymbol') if options['location'].nil?

result['name'] = options['name']
result['kind'] = options['kind']
result['deprecated'] = options['deprecated'] unless options['deprecated'].nil?
result['location'] = options['location']
result['containerName'] = options['containerName'] unless options['containerName'].nil?

result
end
end
end
50 changes: 50 additions & 0 deletions lib/puppet-languageserver/manifest/document_symbol_provider.rb
Original file line number Diff line number Diff line change
@@ -1,6 +1,56 @@
module PuppetLanguageServer
module Manifest
module DocumentSymbolProvider
def self.workspace_symbols(query)
query = '' if query.nil?
result = []
PuppetLanguageServer::PuppetHelper.all_objects do |key, item|
key_string = key.to_s
next unless key_string.include?(query)
case item
when PuppetLanguageServer::PuppetHelper::PuppetType
result << LanguageServer::SymbolInformation.create(
'name' => key_string,
'kind' => LanguageServer::SYMBOLKIND_METHOD,
'location' => LanguageServer::Location.create(
'uri' => PuppetLanguageServer::UriHelper.build_file_uri(item.source),
'fromline' => item.line,
'fromchar' => 0, # Don't have char pos for types
'toline' => item.line,
'tochar' => 1024, # Don't have char pos for types
)
)

when PuppetLanguageServer::PuppetHelper::PuppetFunction
result << LanguageServer::SymbolInformation.create(
'name' => key_string,
'kind' => LanguageServer::SYMBOLKIND_FUNCTION,
'location' => LanguageServer::Location.create(
'uri' => PuppetLanguageServer::UriHelper.build_file_uri(item.source),
'fromline' => item.line,
'fromchar' => 0, # Don't have char pos for functions
'toline' => item.line,
'tochar' => 1024, # Don't have char pos for functions
)
)

when PuppetLanguageServer::PuppetHelper::PuppetClass
result << LanguageServer::SymbolInformation.create(
'name' => key_string,
'kind' => LanguageServer::SYMBOLKIND_CLASS,
'location' => LanguageServer::Location.create(
'uri' => PuppetLanguageServer::UriHelper.build_file_uri(item.source),
'fromline' => item.line,
'fromchar' => 0, # Don't have char pos for classes
'toline' => item.line,
'tochar' => 1024, # Don't have char pos for classes
)
)
end
end
result
end

def self.extract_document_symbols(content)
parser = Puppet::Pops::Parser::Parser.new
result = parser.parse_string(content, '')
Expand Down
11 changes: 11 additions & 0 deletions lib/puppet-languageserver/message_router.rb
Original file line number Diff line number Diff line change
Expand Up @@ -164,6 +164,17 @@ def receive_request(request)
PuppetLanguageServer.log_message(:error, "(textDocument/documentSymbol) #{exception}")
request.reply_result(nil)
end

when 'workspace/symbol'
begin
result = []
result.concat(PuppetLanguageServer::Manifest::DocumentSymbolProvider.workspace_symbols(request.params['query']))
request.reply_result(result)
rescue StandardError => exception
PuppetLanguageServer.log_message(:error, "(workspace/symbol) #{exception}")
request.reply_result([])
end

else
PuppetLanguageServer.log_message(:error, "Unknown RPC method #{request.rpc_method}")
end
Expand Down
8 changes: 8 additions & 0 deletions lib/puppet-languageserver/puppet_helper.rb
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,14 @@ def self.initialize_helper(options = {})
sidecar_queue.cache = @inmemory_cache
end

def self.all_objects(&_block)
return nil if @default_types_loaded == false
raise('Puppet Helper Cache has not been configured') if @inmemory_cache.nil?
@inmemory_cache.all_objects do |key, item|
yield key, item
end
end

# Node Graph
def self.get_node_graph(content, local_workspace)
with_temporary_file(content) do |filepath|
Expand Down
8 changes: 8 additions & 0 deletions lib/puppet-languageserver/puppet_helper/cache.rb
Original file line number Diff line number Diff line change
Expand Up @@ -75,6 +75,14 @@ def objects_by_section(section, &_block)
end
end

def all_objects(&_block)
@cache_lock.synchronize do
@inmemory_cache.each do |item|
yield item.key, item
end
end
end

private

# <Type of object in the file :function, :type, :class>
Expand Down
11 changes: 6 additions & 5 deletions lib/puppet-languageserver/server_capabilities.rb
Original file line number Diff line number Diff line change
Expand Up @@ -4,14 +4,15 @@ def self.capabilities
# https://github.com/Microsoft/language-server-protocol/blob/master/protocol.md#initialize-request

{
'textDocumentSync' => LanguageServer::TEXTDOCUMENTSYNCKIND_FULL,
'hoverProvider' => true,
'completionProvider' => {
'textDocumentSync' => LanguageServer::TEXTDOCUMENTSYNCKIND_FULL,
'hoverProvider' => true,
'completionProvider' => {
'resolveProvider' => true,
'triggerCharacters' => ['>', '$', '[', '=']
},
'definitionProvider' => true,
'documentSymbolProvider' => true
'definitionProvider' => true,
'documentSymbolProvider' => true,
'workspaceSymbolProvider' => true
}
end
end
Expand Down
2 changes: 1 addition & 1 deletion spec/languageserver/spec_helper.rb
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ def wait_for_puppet_loading
PuppetLanguageServer::PuppetHelper.default_classes_loaded?
sleep(1)
interation += 1
next if interation < 60
next if interation < 90
raise <<-ERRORMSG
Puppet has not be initialised in time:
functions_loaded? = #{PuppetLanguageServer::PuppetHelper.default_functions_loaded?}
Expand Down

0 comments on commit 2cc861a

Please sign in to comment.