solargraph 0.32.5 → 0.33.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.gitignore +1 -0
- data/README.md +2 -11
- data/lib/solargraph.rb +1 -2
- data/lib/solargraph/api_map.rb +93 -63
- data/lib/solargraph/api_map/cache.rb +16 -1
- data/lib/solargraph/api_map/source_to_yard.rb +16 -7
- data/lib/solargraph/api_map/store.rb +55 -12
- data/lib/solargraph/complex_type.rb +58 -14
- data/lib/solargraph/complex_type/type_methods.rb +2 -2
- data/lib/solargraph/complex_type/unique_type.rb +33 -4
- data/lib/solargraph/core_fills.rb +40 -12
- data/lib/solargraph/diagnostics.rb +4 -3
- data/lib/solargraph/diagnostics/base.rb +6 -0
- data/lib/solargraph/diagnostics/require_not_found.rb +17 -10
- data/lib/solargraph/diagnostics/rubocop_helpers.rb +2 -0
- data/lib/solargraph/diagnostics/type_check.rb +51 -0
- data/lib/solargraph/diagnostics/update_errors.rb +1 -0
- data/lib/solargraph/language_server/host.rb +55 -25
- data/lib/solargraph/language_server/host/diagnoser.rb +1 -2
- data/lib/solargraph/language_server/host/dispatch.rb +4 -8
- data/lib/solargraph/language_server/host/sources.rb +1 -1
- data/lib/solargraph/language_server/message.rb +1 -0
- data/lib/solargraph/language_server/message/completion_item/resolve.rb +4 -2
- data/lib/solargraph/language_server/message/initialize.rb +9 -0
- data/lib/solargraph/language_server/message/initialized.rb +1 -0
- data/lib/solargraph/language_server/message/text_document.rb +1 -0
- data/lib/solargraph/language_server/message/text_document/code_action.rb +15 -0
- data/lib/solargraph/language_server/message/text_document/completion.rb +1 -1
- data/lib/solargraph/language_server/message/text_document/definition.rb +25 -5
- data/lib/solargraph/language_server/message/text_document/hover.rb +1 -1
- data/lib/solargraph/language_server/message/text_document/signature_help.rb +4 -0
- data/lib/solargraph/language_server/message/workspace/did_change_watched_files.rb +8 -4
- data/lib/solargraph/language_server/transport/adapter.rb +12 -15
- data/lib/solargraph/library.rb +23 -6
- data/lib/solargraph/location.rb +4 -0
- data/lib/solargraph/pin.rb +7 -3
- data/lib/solargraph/pin/attribute.rb +14 -13
- data/lib/solargraph/pin/base.rb +56 -43
- data/lib/solargraph/pin/base_method.rb +41 -18
- data/lib/solargraph/pin/base_variable.rb +17 -15
- data/lib/solargraph/pin/block.rb +22 -4
- data/lib/solargraph/pin/closure.rb +28 -0
- data/lib/solargraph/pin/common.rb +59 -0
- data/lib/solargraph/pin/constant.rb +4 -4
- data/lib/solargraph/pin/conversions.rb +8 -8
- data/lib/solargraph/pin/duck_method.rb +3 -3
- data/lib/solargraph/pin/instance_variable.rb +30 -0
- data/lib/solargraph/pin/keyword.rb +1 -1
- data/lib/solargraph/pin/local_variable.rb +3 -3
- data/lib/solargraph/pin/localized.rb +9 -5
- data/lib/solargraph/pin/method.rb +26 -40
- data/lib/solargraph/pin/method_alias.rb +9 -6
- data/lib/solargraph/pin/namespace.rb +33 -10
- data/lib/solargraph/pin/parameter.rb +150 -0
- data/lib/solargraph/pin/proxy_type.rb +8 -8
- data/lib/solargraph/pin/reference.rb +1 -12
- data/lib/solargraph/pin/reference/override.rb +18 -0
- data/lib/solargraph/pin/reference/require.rb +2 -1
- data/lib/solargraph/pin/singleton.rb +9 -0
- data/lib/solargraph/pin/symbol.rb +9 -4
- data/lib/solargraph/pin/yard_pin/constant.rb +12 -3
- data/lib/solargraph/pin/yard_pin/method.rb +18 -6
- data/lib/solargraph/pin/yard_pin/namespace.rb +13 -1
- data/lib/solargraph/position.rb +1 -1
- data/lib/solargraph/range.rb +4 -0
- data/lib/solargraph/shell.rb +83 -4
- data/lib/solargraph/source.rb +32 -12
- data/lib/solargraph/source/chain.rb +48 -28
- data/lib/solargraph/source/chain/call.rb +37 -38
- data/lib/solargraph/source/chain/constant.rb +1 -1
- data/lib/solargraph/source/chain/head.rb +2 -8
- data/lib/solargraph/source/chain/instance_variable.rb +1 -1
- data/lib/solargraph/source/chain/link.rb +2 -0
- data/lib/solargraph/source/cursor.rb +59 -24
- data/lib/solargraph/source/node_chainer.rb +0 -2
- data/lib/solargraph/source/node_methods.rb +12 -6
- data/lib/solargraph/source/source_chainer.rb +38 -44
- data/lib/solargraph/source_map.rb +11 -18
- data/lib/solargraph/source_map/clip.rb +13 -15
- data/lib/solargraph/source_map/mapper.rb +37 -26
- data/lib/solargraph/source_map/node_processor.rb +13 -8
- data/lib/solargraph/source_map/node_processor/alias_node.rb +8 -8
- data/lib/solargraph/source_map/node_processor/args_node.rb +10 -16
- data/lib/solargraph/source_map/node_processor/base.rb +47 -4
- data/lib/solargraph/source_map/node_processor/block_node.rb +9 -4
- data/lib/solargraph/source_map/node_processor/casgn_node.rb +7 -2
- data/lib/solargraph/source_map/node_processor/cvasgn_node.rb +8 -3
- data/lib/solargraph/source_map/node_processor/def_node.rb +45 -38
- data/lib/solargraph/source_map/node_processor/defs_node.rb +16 -6
- data/lib/solargraph/source_map/node_processor/gvasgn_node.rb +8 -1
- data/lib/solargraph/source_map/node_processor/ivasgn_node.rb +20 -6
- data/lib/solargraph/source_map/node_processor/lvasgn_node.rb +10 -4
- data/lib/solargraph/source_map/node_processor/namespace_node.rb +18 -12
- data/lib/solargraph/source_map/node_processor/orasgn_node.rb +1 -1
- data/lib/solargraph/source_map/node_processor/resbody_node.rb +30 -0
- data/lib/solargraph/source_map/node_processor/sclass_node.rb +7 -1
- data/lib/solargraph/source_map/node_processor/send_node.rb +102 -52
- data/lib/solargraph/source_map/node_processor/sym_node.rb +4 -1
- data/lib/solargraph/source_map/region.rb +9 -8
- data/lib/solargraph/type_checker.rb +282 -0
- data/lib/solargraph/type_checker/param_def.rb +47 -0
- data/lib/solargraph/type_checker/problem.rb +25 -0
- data/lib/solargraph/version.rb +1 -1
- data/lib/solargraph/views/environment.erb +1 -1
- data/lib/solargraph/workspace.rb +2 -2
- data/lib/solargraph/workspace/config.rb +0 -8
- data/lib/solargraph/yard_map.rb +25 -69
- data/lib/solargraph/yard_map/core_docs.rb +8 -3
- data/lib/solargraph/yard_map/core_gen.rb +1 -3
- data/lib/solargraph/yard_map/mapper.rb +85 -0
- data/lib/yard-solargraph.rb +2 -0
- metadata +14 -14
- data/lib/solargraph/diagnostics/type_not_defined.rb +0 -108
- data/lib/solargraph/live_map.rb +0 -126
- data/lib/solargraph/live_map/cache.rb +0 -38
- data/lib/solargraph/pin/block_parameter.rb +0 -103
- data/lib/solargraph/pin/method_parameter.rb +0 -40
- data/lib/solargraph/pin/plugin/method.rb +0 -25
- data/lib/solargraph/plugin.rb +0 -8
- data/lib/solargraph/plugin/base.rb +0 -41
- data/lib/solargraph/plugin/canceler.rb +0 -11
- data/lib/solargraph/plugin/process.rb +0 -172
- data/lib/solargraph/plugin/runtime.rb +0 -134
- data/lib/yard-coregen.rb +0 -16
data/lib/solargraph/live_map.rb
DELETED
@@ -1,126 +0,0 @@
|
|
1
|
-
module Solargraph
|
2
|
-
# The LiveMap allows extensions to add their own completion suggestions.
|
3
|
-
#
|
4
|
-
class LiveMap
|
5
|
-
autoload :Cache, 'solargraph/live_map/cache'
|
6
|
-
|
7
|
-
@@plugin_registry = {}
|
8
|
-
|
9
|
-
# @return [Solargraph::ApiMap]
|
10
|
-
attr_reader :api_map
|
11
|
-
|
12
|
-
# @param api_map [Solargraph::ApiMap]
|
13
|
-
def initialize api_map
|
14
|
-
@api_map = api_map
|
15
|
-
runners
|
16
|
-
end
|
17
|
-
|
18
|
-
def get_path_pin path
|
19
|
-
cache.get_path_pin(path)
|
20
|
-
end
|
21
|
-
|
22
|
-
# @return [Array<Solargraph::Pin::Base>]
|
23
|
-
def get_methods(namespace, root = '', scope = 'instance', with_private = false)
|
24
|
-
fqns = api_map.qualify(namespace, root)
|
25
|
-
params = {
|
26
|
-
namespace: namespace, root: root, scope: scope, with_private: with_private
|
27
|
-
}
|
28
|
-
cached = cache.get_methods(params)
|
29
|
-
return cached unless cached.nil?
|
30
|
-
did_runtime = false
|
31
|
-
result = []
|
32
|
-
runners.each do |p|
|
33
|
-
next if did_runtime and p.runtime?
|
34
|
-
p.get_methods(namespace: namespace, root: root, scope: scope, with_private: with_private).each do |m|
|
35
|
-
result.push Solargraph::Pin::Method.new(nil, namespace, m['name'], YARD::Docstring.new('(defined at runtime)'), scope.to_sym, nil, [])
|
36
|
-
end
|
37
|
-
did_runtime = true if p.runtime?
|
38
|
-
end
|
39
|
-
cache.set_methods(params, result)
|
40
|
-
result
|
41
|
-
end
|
42
|
-
|
43
|
-
# @return [Array<Solargraph::Pin::Base>]
|
44
|
-
def get_constants(namespace, root = '')
|
45
|
-
cached = cache.get_constants(namespace, root)
|
46
|
-
return cached unless cached.nil?
|
47
|
-
did_runtime = false
|
48
|
-
result = []
|
49
|
-
runners.each do |p|
|
50
|
-
next if did_runtime and p.runtime?
|
51
|
-
result.concat p.get_constants(namespace, root)
|
52
|
-
did_runtime = true if p.runtime?
|
53
|
-
end
|
54
|
-
suggestions = []
|
55
|
-
result.uniq.each do |r|
|
56
|
-
path = (r['namespace'].empty? ? '' : "#{r['namespace']}::") + r['name']
|
57
|
-
kind = Pin::CONSTANT
|
58
|
-
if r['class'] == 'Class'
|
59
|
-
suggestions.push Pin::Namespace.new(nil, r['namespace'], r['name'], YARD::Docstring.new("(defined at runtime)"), :class, :public, nil)
|
60
|
-
elsif r['class'] == 'Module'
|
61
|
-
suggestions.push Pin::Namespace.new(nil, r['namespace'], r['name'], YARD::Docstring.new("(defined at runtime)"), :module, :public, nil)
|
62
|
-
else
|
63
|
-
suggestions.push Pin::Constant.new(nil, r['namespace'], r['name'], YARD::Docstring.new("(defined at runtime"), nil, nil, nil, :public)
|
64
|
-
end
|
65
|
-
end
|
66
|
-
cache.set_constants(namespace, root, suggestions)
|
67
|
-
suggestions
|
68
|
-
end
|
69
|
-
|
70
|
-
def get_fqns(namespace, root)
|
71
|
-
did_runtime = false
|
72
|
-
runners.each do |p|
|
73
|
-
next if did_runtime and p.runtime?
|
74
|
-
result = p.get_fqns(namespace, root)
|
75
|
-
return result unless result.nil?
|
76
|
-
did_runtime = true if p.runtime?
|
77
|
-
end
|
78
|
-
nil
|
79
|
-
end
|
80
|
-
|
81
|
-
def self.register name, klass
|
82
|
-
raise ArgumentError.new("A Solargraph plugin named #{name} already exists") if @@plugin_registry.has_key?(name)
|
83
|
-
@@plugin_registry[name] = klass
|
84
|
-
end
|
85
|
-
|
86
|
-
def refresh
|
87
|
-
changed = false
|
88
|
-
runners.each do |p|
|
89
|
-
changed ||= p.refresh
|
90
|
-
end
|
91
|
-
if changed
|
92
|
-
Solargraph::Logging.logger.debug "Resetting LiveMap cache"
|
93
|
-
cache.clear
|
94
|
-
get_constants('')
|
95
|
-
get_methods('', '', 'class')
|
96
|
-
get_methods('', '', 'instance')
|
97
|
-
get_methods('Kernel', '', 'class')
|
98
|
-
get_methods('Kernel', '', 'instance')
|
99
|
-
end
|
100
|
-
end
|
101
|
-
|
102
|
-
private
|
103
|
-
|
104
|
-
# @return [Solargraph::LiveMap::Cache]
|
105
|
-
def cache
|
106
|
-
@cache ||= Solargraph::LiveMap::Cache.new
|
107
|
-
end
|
108
|
-
|
109
|
-
# @return [Array<Solargraph::Plugin::Base>]
|
110
|
-
def runners
|
111
|
-
@runners ||= load_runners
|
112
|
-
end
|
113
|
-
|
114
|
-
# @return [Array<Solargraph::Plugin::Base>]
|
115
|
-
def load_runners
|
116
|
-
result = []
|
117
|
-
api_map.workspace.config.plugins.each do |name|
|
118
|
-
r = @@plugin_registry[name].new(api_map)
|
119
|
-
result.push r
|
120
|
-
end
|
121
|
-
result
|
122
|
-
end
|
123
|
-
end
|
124
|
-
end
|
125
|
-
|
126
|
-
Solargraph::LiveMap.register 'runtime', Solargraph::Plugin::Runtime
|
@@ -1,38 +0,0 @@
|
|
1
|
-
module Solargraph
|
2
|
-
class LiveMap
|
3
|
-
class Cache
|
4
|
-
def initialize
|
5
|
-
@method_cache = {}
|
6
|
-
@constant_cache = {}
|
7
|
-
@path_cache = {}
|
8
|
-
end
|
9
|
-
|
10
|
-
def get_methods options
|
11
|
-
@method_cache[options]
|
12
|
-
end
|
13
|
-
|
14
|
-
def set_methods options, values
|
15
|
-
@method_cache[options] = values
|
16
|
-
values.each { |pin| @path_cache[pin.path] = pin }
|
17
|
-
end
|
18
|
-
|
19
|
-
def get_constants namespace, root
|
20
|
-
@constant_cache[[namespace, root]]
|
21
|
-
end
|
22
|
-
|
23
|
-
def set_constants namespace, root, values
|
24
|
-
@constant_cache[[namespace, root]] = values
|
25
|
-
end
|
26
|
-
|
27
|
-
def get_path_pin path
|
28
|
-
@path_cache[path]
|
29
|
-
end
|
30
|
-
|
31
|
-
def clear
|
32
|
-
@method_cache.clear
|
33
|
-
@constant_cache.clear
|
34
|
-
@path_cache.clear
|
35
|
-
end
|
36
|
-
end
|
37
|
-
end
|
38
|
-
end
|
@@ -1,103 +0,0 @@
|
|
1
|
-
module Solargraph
|
2
|
-
module Pin
|
3
|
-
class BlockParameter < Base
|
4
|
-
include Localized
|
5
|
-
|
6
|
-
# @return [Pin::Block]
|
7
|
-
attr_reader :block
|
8
|
-
|
9
|
-
def initialize location, namespace, name, comments, block
|
10
|
-
super(location, namespace, name, comments)
|
11
|
-
@block = block
|
12
|
-
@presence = block.location.range
|
13
|
-
end
|
14
|
-
|
15
|
-
# @return [Integer]
|
16
|
-
def kind
|
17
|
-
Pin::BLOCK_PARAMETER
|
18
|
-
end
|
19
|
-
|
20
|
-
# @return [Integer]
|
21
|
-
def completion_item_kind
|
22
|
-
Solargraph::LanguageServer::CompletionItemKinds::VARIABLE
|
23
|
-
end
|
24
|
-
|
25
|
-
# @return [Integer]
|
26
|
-
def symbol_kind
|
27
|
-
Solargraph::LanguageServer::SymbolKinds::VARIABLE
|
28
|
-
end
|
29
|
-
|
30
|
-
# The parameter's zero-based location in the block's signature.
|
31
|
-
#
|
32
|
-
# @return [Integer]
|
33
|
-
def index
|
34
|
-
block.parameters.index(self)
|
35
|
-
end
|
36
|
-
|
37
|
-
def nearly? other
|
38
|
-
return false unless super
|
39
|
-
block.nearly?(other.block)
|
40
|
-
end
|
41
|
-
|
42
|
-
def try_merge! other
|
43
|
-
return false unless super
|
44
|
-
@block = other.block
|
45
|
-
@presence = other.block.location.range
|
46
|
-
@return_complex_type = nil
|
47
|
-
true
|
48
|
-
end
|
49
|
-
|
50
|
-
# @return [Array<Solargraph::ComplexType>]
|
51
|
-
def return_complex_type
|
52
|
-
if @return_complex_type.nil?
|
53
|
-
@return_complex_type = ComplexType.new
|
54
|
-
found = nil
|
55
|
-
params = block.docstring.tags(:param)
|
56
|
-
params.each do |p|
|
57
|
-
next unless p.name == name
|
58
|
-
found = p
|
59
|
-
break
|
60
|
-
end
|
61
|
-
if found.nil? and !index.nil?
|
62
|
-
found = params[index] if params[index] && (params[index].name.nil? || params[index].name.empty?)
|
63
|
-
end
|
64
|
-
@return_complex_type = ComplexType.try_parse(*found.types) unless found.nil? or found.types.nil?
|
65
|
-
end
|
66
|
-
super
|
67
|
-
@return_complex_type
|
68
|
-
end
|
69
|
-
|
70
|
-
def context
|
71
|
-
block
|
72
|
-
end
|
73
|
-
|
74
|
-
# @param api_map [ApiMap]
|
75
|
-
def typify api_map
|
76
|
-
# @todo Does anything need to be eliminated because it's more accurately a probe?
|
77
|
-
type = super
|
78
|
-
return type unless type.undefined?
|
79
|
-
chain = Source::NodeChainer.chain(block.receiver, filename)
|
80
|
-
clip = api_map.clip_at(location.filename, location.range.start)
|
81
|
-
locals = clip.locals - [self]
|
82
|
-
meths = chain.define(api_map, block, locals)
|
83
|
-
meths.each do |meth|
|
84
|
-
if (Solargraph::CoreFills::METHODS_WITH_YIELDPARAM_SUBTYPES.include?(meth.path))
|
85
|
-
bmeth = chain.base.define(api_map, context, locals).first
|
86
|
-
return ComplexType::UNDEFINED if bmeth.nil? or bmeth.return_complex_type.undefined? or bmeth.return_complex_type.subtypes.empty?
|
87
|
-
return bmeth.return_complex_type.subtypes.first.qualify(api_map, bmeth.context.namespace)
|
88
|
-
elsif (Solargraph::CoreFills::METHODS_WITH_YIELDPARAM_SELF.include?(meth.path))
|
89
|
-
bmeth = chain.base.define(api_map, context, locals).first
|
90
|
-
return ComplexType::UNDEFINED if bmeth.nil?
|
91
|
-
return bmeth.typify(api_map)
|
92
|
-
else
|
93
|
-
yps = meth.docstring.tags(:yieldparam)
|
94
|
-
unless yps[index].nil? or yps[index].types.nil? or yps[index].types.empty?
|
95
|
-
return ComplexType.try_parse(yps[index].types.first).qualify(api_map, meth.context.namespace)
|
96
|
-
end
|
97
|
-
end
|
98
|
-
end
|
99
|
-
ComplexType::UNDEFINED
|
100
|
-
end
|
101
|
-
end
|
102
|
-
end
|
103
|
-
end
|
@@ -1,40 +0,0 @@
|
|
1
|
-
module Solargraph
|
2
|
-
module Pin
|
3
|
-
class MethodParameter < LocalVariable
|
4
|
-
def return_complex_type
|
5
|
-
if @return_complex_type.nil?
|
6
|
-
@return_complex_type = ComplexType.new
|
7
|
-
found = nil
|
8
|
-
params = block.docstring.tags(:param)
|
9
|
-
params.each do |p|
|
10
|
-
next unless p.name == name
|
11
|
-
found = p
|
12
|
-
break
|
13
|
-
end
|
14
|
-
if found.nil? and !index.nil?
|
15
|
-
found = params[index] if params[index] && (params[index].name.nil? || params[index].name.empty?)
|
16
|
-
end
|
17
|
-
@return_complex_type = ComplexType.try_parse(*found.types) unless found.nil? or found.types.nil?
|
18
|
-
end
|
19
|
-
super
|
20
|
-
@return_complex_type
|
21
|
-
end
|
22
|
-
|
23
|
-
# The parameter's zero-based location in the block's signature.
|
24
|
-
#
|
25
|
-
# @return [Integer]
|
26
|
-
def index
|
27
|
-
block.parameter_names.index(name)
|
28
|
-
end
|
29
|
-
|
30
|
-
def try_merge! pin
|
31
|
-
return false unless super
|
32
|
-
# @todo This is a little expensive, but it's necessary because
|
33
|
-
# parameter data depends on the method's docstring.
|
34
|
-
@return_complex_type = pin.return_complex_type
|
35
|
-
reset_conversions
|
36
|
-
true
|
37
|
-
end
|
38
|
-
end
|
39
|
-
end
|
40
|
-
end
|
@@ -1,25 +0,0 @@
|
|
1
|
-
module Solargraph
|
2
|
-
module Pin
|
3
|
-
module Plugin
|
4
|
-
class Method < Base
|
5
|
-
attr_reader :name
|
6
|
-
attr_reader :path
|
7
|
-
attr_reader :return_type
|
8
|
-
attr_reader :parameters
|
9
|
-
attr_reader :scope
|
10
|
-
attr_reader :visibility
|
11
|
-
|
12
|
-
def initialize name:, path:, return_type:, parameters:
|
13
|
-
@name = name
|
14
|
-
@path = path
|
15
|
-
@return_type = return_type
|
16
|
-
@parameters = parameters
|
17
|
-
end
|
18
|
-
|
19
|
-
def completion_item_kind
|
20
|
-
Solargraph::LanguageServer::CompletionItemKinds::METHOD
|
21
|
-
end
|
22
|
-
end
|
23
|
-
end
|
24
|
-
end
|
25
|
-
end
|
data/lib/solargraph/plugin.rb
DELETED
@@ -1,41 +0,0 @@
|
|
1
|
-
module Solargraph
|
2
|
-
module Plugin
|
3
|
-
class Base
|
4
|
-
# @return [Solargraph::ApiMap]
|
5
|
-
attr_reader :api_map
|
6
|
-
|
7
|
-
def initialize api_map
|
8
|
-
@api_map = api_map
|
9
|
-
post_initialize
|
10
|
-
end
|
11
|
-
|
12
|
-
def post_initialize
|
13
|
-
end
|
14
|
-
|
15
|
-
# @return [Array<String>]
|
16
|
-
def get_methods namespace:, root:, scope:, with_private: false
|
17
|
-
[]
|
18
|
-
end
|
19
|
-
|
20
|
-
# @return [Array<String>]
|
21
|
-
def get_constants namespace, root
|
22
|
-
[]
|
23
|
-
end
|
24
|
-
|
25
|
-
# @return [String]
|
26
|
-
def get_fqns namespace, root
|
27
|
-
nil
|
28
|
-
end
|
29
|
-
|
30
|
-
# @return [Boolean]
|
31
|
-
def refresh
|
32
|
-
false
|
33
|
-
end
|
34
|
-
|
35
|
-
# @return [Boolean]
|
36
|
-
def runtime?
|
37
|
-
false
|
38
|
-
end
|
39
|
-
end
|
40
|
-
end
|
41
|
-
end
|
@@ -1,172 +0,0 @@
|
|
1
|
-
require 'json'
|
2
|
-
|
3
|
-
module Solargraph
|
4
|
-
module Plugin
|
5
|
-
class Process
|
6
|
-
def initialize
|
7
|
-
@required = []
|
8
|
-
post_initialize
|
9
|
-
end
|
10
|
-
|
11
|
-
def post_initialize
|
12
|
-
end
|
13
|
-
|
14
|
-
def run
|
15
|
-
until STDIN.closed?
|
16
|
-
input = gets
|
17
|
-
break if input.nil?
|
18
|
-
args = nil
|
19
|
-
begin
|
20
|
-
args = JSON.parse(input)
|
21
|
-
case args['command']
|
22
|
-
when 'require'
|
23
|
-
STDOUT.puts do_require args['paths']
|
24
|
-
when 'methods'
|
25
|
-
STDOUT.puts get_methods args['params']
|
26
|
-
when 'constants'
|
27
|
-
STDOUT.puts get_constants args['params']
|
28
|
-
when 'fqns'
|
29
|
-
STDOUT.puts get_fqns args['params']
|
30
|
-
else
|
31
|
-
STDOUT.puts respond_err "Unrecognized command #{args['command']}"
|
32
|
-
end
|
33
|
-
rescue JSON::ParserError => e
|
34
|
-
STDOUT.puts respond_err "Error parsing input: #{e.message}"
|
35
|
-
rescue Exception => e
|
36
|
-
STDOUT.puts respond_err "Error processing input: #{e.message}\n#{e.backtrace}"
|
37
|
-
end
|
38
|
-
STDOUT.flush
|
39
|
-
end
|
40
|
-
end
|
41
|
-
|
42
|
-
private
|
43
|
-
|
44
|
-
def do_require paths
|
45
|
-
errors = []
|
46
|
-
paths.each do |p|
|
47
|
-
begin
|
48
|
-
require p
|
49
|
-
@required.push p
|
50
|
-
rescue Exception => e
|
51
|
-
Solargraph::Logging.logger.info "Failed to require #{p}: #{e.message}"
|
52
|
-
errors.push "Failed to require #{p}: #{e.class} #{e.message}"
|
53
|
-
end
|
54
|
-
end
|
55
|
-
if errors.empty?
|
56
|
-
respond_ok
|
57
|
-
else
|
58
|
-
respond_err errors.join('; ')
|
59
|
-
end
|
60
|
-
end
|
61
|
-
|
62
|
-
def get_methods args
|
63
|
-
result = []
|
64
|
-
# @type [Class]
|
65
|
-
con = find_constant(args['namespace'], args['root'])
|
66
|
-
unless con.nil?
|
67
|
-
if (args['scope'] == 'class')
|
68
|
-
result.concat con.methods if args['with_private']
|
69
|
-
result.concat con.public_methods
|
70
|
-
elsif (args['scope'] == 'instance')
|
71
|
-
result.concat con.instance_methods if args['with_private']
|
72
|
-
result.concat con.public_instance_methods
|
73
|
-
end
|
74
|
-
end
|
75
|
-
result.keep_if{|m| m.to_s.match(/^[a-z_]/i)}
|
76
|
-
respond_ok (result.uniq.sort.map do |name|
|
77
|
-
# @type [Method]
|
78
|
-
meth = args['scope'] == 'class' ? con.method(name) : con.instance_method(name)
|
79
|
-
{
|
80
|
-
name: name,
|
81
|
-
parameters: build_parameter_array(meth.parameters)
|
82
|
-
}
|
83
|
-
end)
|
84
|
-
end
|
85
|
-
|
86
|
-
def get_constants args
|
87
|
-
result = []
|
88
|
-
con = find_constant(args['namespace'], args['root'])
|
89
|
-
unless con.nil?
|
90
|
-
#result.concat con.constants
|
91
|
-
con.constants.each do |c|
|
92
|
-
next if c == :Solargraph and !@required.include?('solargraph')
|
93
|
-
here = con.const_get(c)
|
94
|
-
item = { namespace: con.to_s, name: c.to_s }
|
95
|
-
item[:class] = here.class.to_s
|
96
|
-
result.push item
|
97
|
-
end
|
98
|
-
end
|
99
|
-
respond_ok result
|
100
|
-
end
|
101
|
-
|
102
|
-
def get_fqns args
|
103
|
-
con = find_constant(args['namespace'], args['root'])
|
104
|
-
respond_ok (con.nil? ? nil : con.to_s)
|
105
|
-
end
|
106
|
-
|
107
|
-
def find_constant(namespace, root)
|
108
|
-
result = nil
|
109
|
-
unless root.empty?
|
110
|
-
parts = root.split('::')
|
111
|
-
until parts.empty?
|
112
|
-
result = inner_find_constant("#{parts.join('::')}::#{namespace}")
|
113
|
-
parts.pop
|
114
|
-
break unless result.nil?
|
115
|
-
end
|
116
|
-
end
|
117
|
-
result = inner_find_constant(namespace) if result.nil?
|
118
|
-
result
|
119
|
-
end
|
120
|
-
|
121
|
-
def inner_find_constant(namespace)
|
122
|
-
cursor = Object
|
123
|
-
parts = namespace.split('::')
|
124
|
-
until parts.empty?
|
125
|
-
here = parts.shift
|
126
|
-
begin
|
127
|
-
cursor = cursor.const_get(here)
|
128
|
-
rescue NameError
|
129
|
-
return nil
|
130
|
-
end
|
131
|
-
end
|
132
|
-
cursor
|
133
|
-
end
|
134
|
-
|
135
|
-
def respond_ok data = []
|
136
|
-
{
|
137
|
-
status: 'ok',
|
138
|
-
message: nil,
|
139
|
-
data: data
|
140
|
-
}.to_json
|
141
|
-
end
|
142
|
-
|
143
|
-
def respond_err msg
|
144
|
-
{
|
145
|
-
status: 'err',
|
146
|
-
message: msg,
|
147
|
-
data: []
|
148
|
-
}.to_json
|
149
|
-
end
|
150
|
-
|
151
|
-
def build_parameter_array parameters
|
152
|
-
an = 1
|
153
|
-
parameters.map do |p|
|
154
|
-
if p[0] == :rest
|
155
|
-
str = (p[1] ? "*#{p[1]}" : "*args")
|
156
|
-
else
|
157
|
-
str = (p[1] ? p[1].to_s : "arg#{an}")
|
158
|
-
if p[0] == :opt
|
159
|
-
str += ' = ?'
|
160
|
-
elsif p[0] == :key
|
161
|
-
str += ':'
|
162
|
-
elsif p[0] == :keyreq
|
163
|
-
str += ': ?'
|
164
|
-
end
|
165
|
-
end
|
166
|
-
an += 1
|
167
|
-
str
|
168
|
-
end
|
169
|
-
end
|
170
|
-
end
|
171
|
-
end
|
172
|
-
end
|