solargraph 0.32.1 → 0.32.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/.gitignore +9 -0
- data/.rspec +2 -0
- data/.rubocop.yml +6 -0
- data/.travis.yml +25 -0
- data/EXAMPLES.md +76 -0
- data/Gemfile +3 -0
- data/LANGUAGE_SERVER.md +51 -0
- data/LICENSE +21 -0
- data/OVERVIEW.md +37 -0
- data/README.md +106 -0
- data/Rakefile +14 -0
- data/SERVER.md +95 -0
- data/bin/solargraph +0 -0
- data/bin/solargraph-runtime +5 -5
- data/lib/solargraph.rb +54 -54
- data/lib/solargraph/api_map.rb +659 -659
- data/lib/solargraph/api_map/cache.rb +49 -49
- data/lib/solargraph/api_map/source_to_yard.rb +67 -67
- data/lib/solargraph/api_map/store.rb +201 -201
- data/lib/solargraph/bundle.rb +24 -24
- data/lib/solargraph/complex_type.rb +150 -150
- data/lib/solargraph/complex_type/type_methods.rb +124 -124
- data/lib/solargraph/complex_type/unique_type.rb +44 -44
- data/lib/solargraph/core_fills.rb +37 -37
- data/lib/solargraph/diagnostics.rb +52 -52
- data/lib/solargraph/diagnostics/base.rb +20 -20
- data/lib/solargraph/diagnostics/require_not_found.rb +28 -28
- data/lib/solargraph/diagnostics/rubocop.rb +98 -98
- data/lib/solargraph/diagnostics/rubocop_helpers.rb +46 -46
- data/lib/solargraph/diagnostics/type_not_defined.rb +108 -108
- data/lib/solargraph/diagnostics/update_errors.rb +38 -38
- data/lib/solargraph/language_server/completion_item_kinds.rb +33 -33
- data/lib/solargraph/language_server/error_codes.rb +18 -18
- data/lib/solargraph/language_server/host.rb +684 -681
- data/lib/solargraph/language_server/host/cataloger.rb +54 -79
- data/lib/solargraph/language_server/host/diagnoser.rb +80 -80
- data/lib/solargraph/language_server/host/dispatch.rb +112 -113
- data/lib/solargraph/language_server/host/sources.rb +138 -138
- data/lib/solargraph/language_server/message.rb +90 -90
- data/lib/solargraph/language_server/message/base.rb +83 -83
- data/lib/solargraph/language_server/message/completion_item/resolve.rb +40 -40
- data/lib/solargraph/language_server/message/exit_notification.rb +11 -11
- data/lib/solargraph/language_server/message/extended.rb +19 -19
- data/lib/solargraph/language_server/message/extended/check_gem_version.rb +86 -86
- data/lib/solargraph/language_server/message/extended/document.rb +18 -18
- data/lib/solargraph/language_server/message/extended/document_gems.rb +30 -30
- data/lib/solargraph/language_server/message/extended/environment.rb +20 -20
- data/lib/solargraph/language_server/message/extended/search.rb +18 -18
- data/lib/solargraph/language_server/message/initialize.rb +141 -141
- data/lib/solargraph/language_server/message/initialized.rb +23 -23
- data/lib/solargraph/language_server/message/shutdown.rb +11 -11
- data/lib/solargraph/language_server/message/text_document.rb +25 -25
- data/lib/solargraph/language_server/message/text_document/completion.rb +51 -51
- data/lib/solargraph/language_server/message/text_document/definition.rb +18 -18
- data/lib/solargraph/language_server/message/text_document/did_change.rb +13 -13
- data/lib/solargraph/language_server/message/text_document/document_symbol.rb +21 -21
- data/lib/solargraph/language_server/message/text_document/folding_range.rb +24 -24
- data/lib/solargraph/language_server/message/text_document/formatting.rb +50 -50
- data/lib/solargraph/language_server/message/text_document/hover.rb +31 -31
- data/lib/solargraph/language_server/message/text_document/on_type_formatting.rb +32 -32
- data/lib/solargraph/language_server/message/text_document/prepare_rename.rb +9 -9
- data/lib/solargraph/language_server/message/text_document/references.rb +14 -14
- data/lib/solargraph/language_server/message/text_document/rename.rb +17 -17
- data/lib/solargraph/language_server/message/text_document/signature_help.rb +19 -19
- data/lib/solargraph/language_server/message/workspace.rb +12 -12
- data/lib/solargraph/language_server/message/workspace/did_change_configuration.rb +29 -29
- data/lib/solargraph/language_server/message/workspace/did_change_watched_files.rb +29 -27
- data/lib/solargraph/language_server/message/workspace/did_change_workspace_folders.rb +24 -24
- data/lib/solargraph/language_server/message/workspace/workspace_symbol.rb +21 -21
- data/lib/solargraph/language_server/request.rb +22 -22
- data/lib/solargraph/language_server/symbol_kinds.rb +34 -34
- data/lib/solargraph/language_server/transport.rb +11 -11
- data/lib/solargraph/language_server/transport/adapter.rb +60 -60
- data/lib/solargraph/language_server/transport/data_reader.rb +66 -66
- data/lib/solargraph/language_server/uri_helpers.rb +25 -25
- data/lib/solargraph/library.rb +421 -419
- data/lib/solargraph/live_map.rb +126 -126
- data/lib/solargraph/live_map/cache.rb +38 -38
- data/lib/solargraph/location.rb +31 -31
- data/lib/solargraph/logging.rb +25 -25
- data/lib/solargraph/page.rb +68 -68
- data/lib/solargraph/pin.rb +50 -50
- data/lib/solargraph/pin/attribute.rb +41 -41
- data/lib/solargraph/pin/base.rb +280 -280
- data/lib/solargraph/pin/base_method.rb +76 -76
- data/lib/solargraph/pin/base_variable.rb +72 -72
- data/lib/solargraph/pin/block.rb +32 -32
- data/lib/solargraph/pin/block_parameter.rb +103 -103
- data/lib/solargraph/pin/class_variable.rb +9 -9
- data/lib/solargraph/pin/constant.rb +30 -30
- data/lib/solargraph/pin/conversions.rb +79 -79
- data/lib/solargraph/pin/documenting.rb +41 -41
- data/lib/solargraph/pin/duck_method.rb +14 -14
- data/lib/solargraph/pin/global_variable.rb +9 -9
- data/lib/solargraph/pin/instance_variable.rb +9 -9
- data/lib/solargraph/pin/keyword.rb +17 -17
- data/lib/solargraph/pin/local_variable.rb +23 -23
- data/lib/solargraph/pin/localized.rb +22 -22
- data/lib/solargraph/pin/method.rb +126 -126
- data/lib/solargraph/pin/method_alias.rb +30 -30
- data/lib/solargraph/pin/method_parameter.rb +40 -40
- data/lib/solargraph/pin/namespace.rb +54 -54
- data/lib/solargraph/pin/plugin/method.rb +25 -25
- data/lib/solargraph/pin/proxy_type.rb +35 -35
- data/lib/solargraph/pin/reference.rb +22 -22
- data/lib/solargraph/pin/reference/extend.rb +11 -11
- data/lib/solargraph/pin/reference/include.rb +11 -11
- data/lib/solargraph/pin/reference/require.rb +15 -15
- data/lib/solargraph/pin/reference/superclass.rb +11 -11
- data/lib/solargraph/pin/symbol.rb +44 -44
- data/lib/solargraph/pin/yard_pin.rb +10 -10
- data/lib/solargraph/pin/yard_pin/constant.rb +14 -14
- data/lib/solargraph/pin/yard_pin/method.rb +35 -35
- data/lib/solargraph/pin/yard_pin/namespace.rb +19 -19
- data/lib/solargraph/pin/yard_pin/yard_mixin.rb +14 -14
- data/lib/solargraph/plugin.rb +8 -8
- data/lib/solargraph/plugin/base.rb +41 -41
- data/lib/solargraph/plugin/canceler.rb +11 -11
- data/lib/solargraph/plugin/process.rb +172 -172
- data/lib/solargraph/plugin/runtime.rb +134 -134
- data/lib/solargraph/position.rb +110 -110
- data/lib/solargraph/range.rb +83 -83
- data/lib/solargraph/server_methods.rb +14 -14
- data/lib/solargraph/shell.rb +102 -102
- data/lib/solargraph/source.rb +521 -521
- data/lib/solargraph/source/chain.rb +120 -120
- data/lib/solargraph/source/chain/call.rb +107 -107
- data/lib/solargraph/source/chain/class_variable.rb +11 -11
- data/lib/solargraph/source/chain/constant.rb +30 -30
- data/lib/solargraph/source/chain/global_variable.rb +11 -11
- data/lib/solargraph/source/chain/head.rb +33 -33
- data/lib/solargraph/source/chain/instance_variable.rb +11 -11
- data/lib/solargraph/source/chain/link.rb +33 -33
- data/lib/solargraph/source/chain/literal.rb +21 -21
- data/lib/solargraph/source/chain/variable.rb +11 -11
- data/lib/solargraph/source/change.rb +77 -77
- data/lib/solargraph/source/cursor.rb +157 -157
- data/lib/solargraph/source/node_chainer.rb +96 -96
- data/lib/solargraph/source/node_methods.rb +225 -225
- data/lib/solargraph/source/source_chainer.rb +183 -183
- data/lib/solargraph/source_map.rb +169 -169
- data/lib/solargraph/source_map/clip.rb +145 -145
- data/lib/solargraph/source_map/completion.rb +21 -21
- data/lib/solargraph/source_map/mapper.rb +149 -149
- data/lib/solargraph/source_map/node_processor.rb +78 -78
- data/lib/solargraph/source_map/node_processor/alias_node.rb +19 -19
- data/lib/solargraph/source_map/node_processor/args_node.rb +28 -28
- data/lib/solargraph/source_map/node_processor/base.rb +68 -68
- data/lib/solargraph/source_map/node_processor/begin_node.rb +11 -11
- data/lib/solargraph/source_map/node_processor/block_node.rb +14 -14
- data/lib/solargraph/source_map/node_processor/casgn_node.rb +14 -14
- data/lib/solargraph/source_map/node_processor/cvasgn_node.rb +14 -14
- data/lib/solargraph/source_map/node_processor/def_node.rb +54 -54
- data/lib/solargraph/source_map/node_processor/defs_node.rb +21 -21
- data/lib/solargraph/source_map/node_processor/gvasgn_node.rb +12 -12
- data/lib/solargraph/source_map/node_processor/ivasgn_node.rb +18 -18
- data/lib/solargraph/source_map/node_processor/lvasgn_node.rb +16 -16
- data/lib/solargraph/source_map/node_processor/namespace_node.rb +26 -26
- data/lib/solargraph/source_map/node_processor/orasgn_node.rb +12 -12
- data/lib/solargraph/source_map/node_processor/sclass_node.rb +11 -11
- data/lib/solargraph/source_map/node_processor/send_node.rb +162 -162
- data/lib/solargraph/source_map/node_processor/sym_node.rb +11 -11
- data/lib/solargraph/source_map/region.rb +58 -58
- data/lib/solargraph/version.rb +3 -3
- data/lib/solargraph/views/environment.erb +53 -53
- data/lib/solargraph/workspace.rb +183 -183
- data/lib/solargraph/workspace/config.rb +170 -170
- data/lib/solargraph/yard_map.rb +298 -298
- data/lib/solargraph/yard_map/cache.rb +17 -17
- data/lib/solargraph/yard_map/core_docs.rb +163 -163
- data/lib/solargraph/yard_map/core_gen.rb +76 -76
- data/lib/yard-coregen.rb +16 -16
- data/lib/yard-solargraph.rb +18 -18
- data/solargraph.gemspec +37 -0
- data/travis-bundler.rb +10 -0
- metadata +19 -6
data/lib/solargraph/bundle.rb
CHANGED
|
@@ -1,24 +1,24 @@
|
|
|
1
|
-
module Solargraph
|
|
2
|
-
# An aggregation of a workspace and additional sources to be cataloged in an
|
|
3
|
-
# ApiMap.
|
|
4
|
-
#
|
|
5
|
-
class Bundle
|
|
6
|
-
# @return [Workspace]
|
|
7
|
-
attr_reader :workspace
|
|
8
|
-
|
|
9
|
-
# @return [Array<Source>]
|
|
10
|
-
attr_reader :opened
|
|
11
|
-
|
|
12
|
-
# @param workspace [Workspace]
|
|
13
|
-
# @param opened [Array<Source>]
|
|
14
|
-
def initialize workspace: Workspace.new, opened: []
|
|
15
|
-
@workspace = workspace
|
|
16
|
-
@opened = opened
|
|
17
|
-
end
|
|
18
|
-
|
|
19
|
-
# @return [Array<Source>]
|
|
20
|
-
def sources
|
|
21
|
-
@sources ||= (opened + workspace.sources).uniq(&:filename)
|
|
22
|
-
end
|
|
23
|
-
end
|
|
24
|
-
end
|
|
1
|
+
module Solargraph
|
|
2
|
+
# An aggregation of a workspace and additional sources to be cataloged in an
|
|
3
|
+
# ApiMap.
|
|
4
|
+
#
|
|
5
|
+
class Bundle
|
|
6
|
+
# @return [Workspace]
|
|
7
|
+
attr_reader :workspace
|
|
8
|
+
|
|
9
|
+
# @return [Array<Source>]
|
|
10
|
+
attr_reader :opened
|
|
11
|
+
|
|
12
|
+
# @param workspace [Workspace]
|
|
13
|
+
# @param opened [Array<Source>]
|
|
14
|
+
def initialize workspace: Workspace.new, opened: []
|
|
15
|
+
@workspace = workspace
|
|
16
|
+
@opened = opened
|
|
17
|
+
end
|
|
18
|
+
|
|
19
|
+
# @return [Array<Source>]
|
|
20
|
+
def sources
|
|
21
|
+
@sources ||= (opened + workspace.sources).uniq(&:filename)
|
|
22
|
+
end
|
|
23
|
+
end
|
|
24
|
+
end
|
|
@@ -1,150 +1,150 @@
|
|
|
1
|
-
module Solargraph
|
|
2
|
-
# A container for type data based on YARD type tags.
|
|
3
|
-
#
|
|
4
|
-
class ComplexType < Array
|
|
5
|
-
# @todo Figure out how to add the basic type methods here without actually
|
|
6
|
-
# including the module. One possibility:
|
|
7
|
-
#
|
|
8
|
-
# @!parse
|
|
9
|
-
# include TypeMethods
|
|
10
|
-
|
|
11
|
-
autoload :TypeMethods, 'solargraph/complex_type/type_methods'
|
|
12
|
-
autoload :UniqueType, 'solargraph/complex_type/unique_type'
|
|
13
|
-
|
|
14
|
-
# @param types [Array<ComplexType>]
|
|
15
|
-
def initialize types = [ComplexType::UNDEFINED]
|
|
16
|
-
super()
|
|
17
|
-
concat types
|
|
18
|
-
end
|
|
19
|
-
|
|
20
|
-
# @param api_map [ApiMap]
|
|
21
|
-
# @param context [String]
|
|
22
|
-
# @return [ComplexType]
|
|
23
|
-
def qualify api_map, context = ''
|
|
24
|
-
types = map do |t|
|
|
25
|
-
t.qualify api_map, context
|
|
26
|
-
end
|
|
27
|
-
ComplexType.new(types)
|
|
28
|
-
end
|
|
29
|
-
|
|
30
|
-
def method_missing name, *args, &block
|
|
31
|
-
return if first.nil?
|
|
32
|
-
return first.send(name, *args, &block) if respond_to_missing?(name)
|
|
33
|
-
super
|
|
34
|
-
end
|
|
35
|
-
|
|
36
|
-
def respond_to_missing?(name, include_private = false)
|
|
37
|
-
TypeMethods.public_instance_methods.include?(name) || super
|
|
38
|
-
end
|
|
39
|
-
|
|
40
|
-
def to_s
|
|
41
|
-
map(&:tag).join(', ')
|
|
42
|
-
end
|
|
43
|
-
|
|
44
|
-
class << self
|
|
45
|
-
# Parse type strings into a ComplexType.
|
|
46
|
-
#
|
|
47
|
-
# @example
|
|
48
|
-
# ComplexType.parse 'String', 'Foo', 'nil' #=> [String, Foo, nil]
|
|
49
|
-
#
|
|
50
|
-
# @note
|
|
51
|
-
# The `partial` parameter is used to indicate that the method is
|
|
52
|
-
# receiving a string that will be used inside another ComplexType.
|
|
53
|
-
# It returns arrays of ComplexTypes instead of a single cohesive one.
|
|
54
|
-
# Consumers should not need to use this parameter; it should only be
|
|
55
|
-
# used internally.
|
|
56
|
-
#
|
|
57
|
-
# @param *strings [Array<String>] The type definitions to parse
|
|
58
|
-
# @param partial [Boolean] True if the string is part of a another type
|
|
59
|
-
# @return [ComplexType]
|
|
60
|
-
def parse *strings, partial: false
|
|
61
|
-
@cache ||= {}
|
|
62
|
-
unless partial
|
|
63
|
-
cached = @cache[strings]
|
|
64
|
-
return cached unless cached.nil?
|
|
65
|
-
end
|
|
66
|
-
types = []
|
|
67
|
-
key_types = nil
|
|
68
|
-
strings.each do |type_string|
|
|
69
|
-
point_stack = 0
|
|
70
|
-
curly_stack = 0
|
|
71
|
-
paren_stack = 0
|
|
72
|
-
base = ''
|
|
73
|
-
subtype_string = ''
|
|
74
|
-
type_string.each_char do |char|
|
|
75
|
-
if char == '='
|
|
76
|
-
#raise ComplexTypeError, "Invalid = in type #{type_string}" unless curly_stack > 0
|
|
77
|
-
elsif char == '<'
|
|
78
|
-
point_stack += 1
|
|
79
|
-
elsif char == '>'
|
|
80
|
-
if subtype_string.end_with?('=') && curly_stack > 0
|
|
81
|
-
subtype_string += char
|
|
82
|
-
elsif base.end_with?('=')
|
|
83
|
-
raise ComplexTypeError, "Invalid hash thing" unless key_types.nil?
|
|
84
|
-
types.push ComplexType.new([UniqueType.new(base[0..-2].strip)])
|
|
85
|
-
key_types = types
|
|
86
|
-
types = []
|
|
87
|
-
base = ''
|
|
88
|
-
subtype_string = ''
|
|
89
|
-
next
|
|
90
|
-
else
|
|
91
|
-
point_stack -= 1
|
|
92
|
-
subtype_string += char if point_stack == 0
|
|
93
|
-
raise ComplexTypeError, "Invalid close in type #{type_string}" if point_stack < 0
|
|
94
|
-
end
|
|
95
|
-
next
|
|
96
|
-
elsif char == '{'
|
|
97
|
-
curly_stack += 1
|
|
98
|
-
elsif char == '}'
|
|
99
|
-
curly_stack -= 1
|
|
100
|
-
subtype_string += char
|
|
101
|
-
raise ComplexTypeError, "Invalid close in type #{type_string}" if curly_stack < 0
|
|
102
|
-
next
|
|
103
|
-
elsif char == '('
|
|
104
|
-
paren_stack += 1
|
|
105
|
-
elsif char == ')'
|
|
106
|
-
paren_stack -= 1
|
|
107
|
-
subtype_string += char if paren_stack == 0
|
|
108
|
-
raise ComplexTypeError, "Invalid close in type #{type_string}" if paren_stack < 0
|
|
109
|
-
next
|
|
110
|
-
elsif char == ',' && point_stack == 0 && curly_stack == 0 && paren_stack == 0
|
|
111
|
-
types.push ComplexType.new([UniqueType.new(base.strip, subtype_string.strip)])
|
|
112
|
-
base = ''
|
|
113
|
-
subtype_string = ''
|
|
114
|
-
next
|
|
115
|
-
end
|
|
116
|
-
if point_stack == 0 && curly_stack == 0 && paren_stack == 0
|
|
117
|
-
base += char
|
|
118
|
-
else
|
|
119
|
-
subtype_string += char
|
|
120
|
-
end
|
|
121
|
-
end
|
|
122
|
-
base.strip!
|
|
123
|
-
subtype_string.strip!
|
|
124
|
-
raise ComplexTypeError, "Unclosed subtype in #{type_string}" if point_stack != 0 || curly_stack != 0 || paren_stack != 0
|
|
125
|
-
types.push ComplexType.new([UniqueType.new(base, subtype_string)])
|
|
126
|
-
end
|
|
127
|
-
unless key_types.nil?
|
|
128
|
-
raise ComplexTypeError, "Invalid use of key/value parameters" unless partial
|
|
129
|
-
return key_types if types.empty?
|
|
130
|
-
return [key_types, types]
|
|
131
|
-
end
|
|
132
|
-
result = partial ? types : ComplexType.new(types)
|
|
133
|
-
@cache[strings] = result unless partial
|
|
134
|
-
result
|
|
135
|
-
end
|
|
136
|
-
|
|
137
|
-
def try_parse *strings
|
|
138
|
-
parse *strings
|
|
139
|
-
rescue ComplexTypeError => e
|
|
140
|
-
Solargraph.logger.info "Error parsing complex type: #{e.message}"
|
|
141
|
-
ComplexType::UNDEFINED
|
|
142
|
-
end
|
|
143
|
-
end
|
|
144
|
-
|
|
145
|
-
VOID = ComplexType.parse('void')
|
|
146
|
-
UNDEFINED = ComplexType.parse('undefined')
|
|
147
|
-
SYMBOL = ComplexType.parse('Symbol')
|
|
148
|
-
ROOT = ComplexType.parse('Class<>')
|
|
149
|
-
end
|
|
150
|
-
end
|
|
1
|
+
module Solargraph
|
|
2
|
+
# A container for type data based on YARD type tags.
|
|
3
|
+
#
|
|
4
|
+
class ComplexType < Array
|
|
5
|
+
# @todo Figure out how to add the basic type methods here without actually
|
|
6
|
+
# including the module. One possibility:
|
|
7
|
+
#
|
|
8
|
+
# @!parse
|
|
9
|
+
# include TypeMethods
|
|
10
|
+
|
|
11
|
+
autoload :TypeMethods, 'solargraph/complex_type/type_methods'
|
|
12
|
+
autoload :UniqueType, 'solargraph/complex_type/unique_type'
|
|
13
|
+
|
|
14
|
+
# @param types [Array<ComplexType>]
|
|
15
|
+
def initialize types = [ComplexType::UNDEFINED]
|
|
16
|
+
super()
|
|
17
|
+
concat types
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
# @param api_map [ApiMap]
|
|
21
|
+
# @param context [String]
|
|
22
|
+
# @return [ComplexType]
|
|
23
|
+
def qualify api_map, context = ''
|
|
24
|
+
types = map do |t|
|
|
25
|
+
t.qualify api_map, context
|
|
26
|
+
end
|
|
27
|
+
ComplexType.new(types)
|
|
28
|
+
end
|
|
29
|
+
|
|
30
|
+
def method_missing name, *args, &block
|
|
31
|
+
return if first.nil?
|
|
32
|
+
return first.send(name, *args, &block) if respond_to_missing?(name)
|
|
33
|
+
super
|
|
34
|
+
end
|
|
35
|
+
|
|
36
|
+
def respond_to_missing?(name, include_private = false)
|
|
37
|
+
TypeMethods.public_instance_methods.include?(name) || super
|
|
38
|
+
end
|
|
39
|
+
|
|
40
|
+
def to_s
|
|
41
|
+
map(&:tag).join(', ')
|
|
42
|
+
end
|
|
43
|
+
|
|
44
|
+
class << self
|
|
45
|
+
# Parse type strings into a ComplexType.
|
|
46
|
+
#
|
|
47
|
+
# @example
|
|
48
|
+
# ComplexType.parse 'String', 'Foo', 'nil' #=> [String, Foo, nil]
|
|
49
|
+
#
|
|
50
|
+
# @note
|
|
51
|
+
# The `partial` parameter is used to indicate that the method is
|
|
52
|
+
# receiving a string that will be used inside another ComplexType.
|
|
53
|
+
# It returns arrays of ComplexTypes instead of a single cohesive one.
|
|
54
|
+
# Consumers should not need to use this parameter; it should only be
|
|
55
|
+
# used internally.
|
|
56
|
+
#
|
|
57
|
+
# @param *strings [Array<String>] The type definitions to parse
|
|
58
|
+
# @param partial [Boolean] True if the string is part of a another type
|
|
59
|
+
# @return [ComplexType]
|
|
60
|
+
def parse *strings, partial: false
|
|
61
|
+
@cache ||= {}
|
|
62
|
+
unless partial
|
|
63
|
+
cached = @cache[strings]
|
|
64
|
+
return cached unless cached.nil?
|
|
65
|
+
end
|
|
66
|
+
types = []
|
|
67
|
+
key_types = nil
|
|
68
|
+
strings.each do |type_string|
|
|
69
|
+
point_stack = 0
|
|
70
|
+
curly_stack = 0
|
|
71
|
+
paren_stack = 0
|
|
72
|
+
base = ''
|
|
73
|
+
subtype_string = ''
|
|
74
|
+
type_string.each_char do |char|
|
|
75
|
+
if char == '='
|
|
76
|
+
#raise ComplexTypeError, "Invalid = in type #{type_string}" unless curly_stack > 0
|
|
77
|
+
elsif char == '<'
|
|
78
|
+
point_stack += 1
|
|
79
|
+
elsif char == '>'
|
|
80
|
+
if subtype_string.end_with?('=') && curly_stack > 0
|
|
81
|
+
subtype_string += char
|
|
82
|
+
elsif base.end_with?('=')
|
|
83
|
+
raise ComplexTypeError, "Invalid hash thing" unless key_types.nil?
|
|
84
|
+
types.push ComplexType.new([UniqueType.new(base[0..-2].strip)])
|
|
85
|
+
key_types = types
|
|
86
|
+
types = []
|
|
87
|
+
base = ''
|
|
88
|
+
subtype_string = ''
|
|
89
|
+
next
|
|
90
|
+
else
|
|
91
|
+
point_stack -= 1
|
|
92
|
+
subtype_string += char if point_stack == 0
|
|
93
|
+
raise ComplexTypeError, "Invalid close in type #{type_string}" if point_stack < 0
|
|
94
|
+
end
|
|
95
|
+
next
|
|
96
|
+
elsif char == '{'
|
|
97
|
+
curly_stack += 1
|
|
98
|
+
elsif char == '}'
|
|
99
|
+
curly_stack -= 1
|
|
100
|
+
subtype_string += char
|
|
101
|
+
raise ComplexTypeError, "Invalid close in type #{type_string}" if curly_stack < 0
|
|
102
|
+
next
|
|
103
|
+
elsif char == '('
|
|
104
|
+
paren_stack += 1
|
|
105
|
+
elsif char == ')'
|
|
106
|
+
paren_stack -= 1
|
|
107
|
+
subtype_string += char if paren_stack == 0
|
|
108
|
+
raise ComplexTypeError, "Invalid close in type #{type_string}" if paren_stack < 0
|
|
109
|
+
next
|
|
110
|
+
elsif char == ',' && point_stack == 0 && curly_stack == 0 && paren_stack == 0
|
|
111
|
+
types.push ComplexType.new([UniqueType.new(base.strip, subtype_string.strip)])
|
|
112
|
+
base = ''
|
|
113
|
+
subtype_string = ''
|
|
114
|
+
next
|
|
115
|
+
end
|
|
116
|
+
if point_stack == 0 && curly_stack == 0 && paren_stack == 0
|
|
117
|
+
base += char
|
|
118
|
+
else
|
|
119
|
+
subtype_string += char
|
|
120
|
+
end
|
|
121
|
+
end
|
|
122
|
+
base.strip!
|
|
123
|
+
subtype_string.strip!
|
|
124
|
+
raise ComplexTypeError, "Unclosed subtype in #{type_string}" if point_stack != 0 || curly_stack != 0 || paren_stack != 0
|
|
125
|
+
types.push ComplexType.new([UniqueType.new(base, subtype_string)])
|
|
126
|
+
end
|
|
127
|
+
unless key_types.nil?
|
|
128
|
+
raise ComplexTypeError, "Invalid use of key/value parameters" unless partial
|
|
129
|
+
return key_types if types.empty?
|
|
130
|
+
return [key_types, types]
|
|
131
|
+
end
|
|
132
|
+
result = partial ? types : ComplexType.new(types)
|
|
133
|
+
@cache[strings] = result unless partial
|
|
134
|
+
result
|
|
135
|
+
end
|
|
136
|
+
|
|
137
|
+
def try_parse *strings
|
|
138
|
+
parse *strings
|
|
139
|
+
rescue ComplexTypeError => e
|
|
140
|
+
Solargraph.logger.info "Error parsing complex type: #{e.message}"
|
|
141
|
+
ComplexType::UNDEFINED
|
|
142
|
+
end
|
|
143
|
+
end
|
|
144
|
+
|
|
145
|
+
VOID = ComplexType.parse('void')
|
|
146
|
+
UNDEFINED = ComplexType.parse('undefined')
|
|
147
|
+
SYMBOL = ComplexType.parse('Symbol')
|
|
148
|
+
ROOT = ComplexType.parse('Class<>')
|
|
149
|
+
end
|
|
150
|
+
end
|
|
@@ -1,124 +1,124 @@
|
|
|
1
|
-
module Solargraph
|
|
2
|
-
class ComplexType
|
|
3
|
-
# Methods for accessing type data.
|
|
4
|
-
#
|
|
5
|
-
module TypeMethods
|
|
6
|
-
# @return [String]
|
|
7
|
-
attr_reader :name
|
|
8
|
-
|
|
9
|
-
# @return [String]
|
|
10
|
-
attr_reader :substring
|
|
11
|
-
|
|
12
|
-
# @return [String]
|
|
13
|
-
attr_reader :tag
|
|
14
|
-
|
|
15
|
-
# @return [Array<ComplexType>]
|
|
16
|
-
attr_reader :subtypes
|
|
17
|
-
|
|
18
|
-
# @return [Boolean]
|
|
19
|
-
def duck_type?
|
|
20
|
-
@duck_type ||= name.start_with?('#')
|
|
21
|
-
end
|
|
22
|
-
|
|
23
|
-
# @return [Boolean]
|
|
24
|
-
def nil_type?
|
|
25
|
-
@nil_type ||= (name.downcase == 'nil')
|
|
26
|
-
end
|
|
27
|
-
|
|
28
|
-
# @return [Boolean]
|
|
29
|
-
def parameters?
|
|
30
|
-
!substring.empty?
|
|
31
|
-
end
|
|
32
|
-
|
|
33
|
-
def void?
|
|
34
|
-
name == 'void'
|
|
35
|
-
end
|
|
36
|
-
|
|
37
|
-
def defined?
|
|
38
|
-
!undefined?
|
|
39
|
-
end
|
|
40
|
-
|
|
41
|
-
def undefined?
|
|
42
|
-
name == 'undefined'
|
|
43
|
-
end
|
|
44
|
-
|
|
45
|
-
# @return [Boolean]
|
|
46
|
-
def list_parameters?
|
|
47
|
-
substring.start_with?('<')
|
|
48
|
-
end
|
|
49
|
-
|
|
50
|
-
# @return [Boolean]
|
|
51
|
-
def fixed_parameters?
|
|
52
|
-
substring.start_with?('(')
|
|
53
|
-
end
|
|
54
|
-
|
|
55
|
-
# @return [Boolean]
|
|
56
|
-
def hash_parameters?
|
|
57
|
-
substring.start_with?('{')
|
|
58
|
-
end
|
|
59
|
-
|
|
60
|
-
# @return [Array<ComplexType>]
|
|
61
|
-
def value_types
|
|
62
|
-
@subtypes
|
|
63
|
-
end
|
|
64
|
-
|
|
65
|
-
# @return [Array<ComplexType>]
|
|
66
|
-
def key_types
|
|
67
|
-
@key_types
|
|
68
|
-
end
|
|
69
|
-
|
|
70
|
-
# @return [String]
|
|
71
|
-
def namespace
|
|
72
|
-
@namespace ||= 'Object' if duck_type?
|
|
73
|
-
@namespace ||= 'NilClass' if nil_type?
|
|
74
|
-
@namespace ||= (name == 'Class' || name == 'Module') && !subtypes.empty? ? subtypes.first.name : name
|
|
75
|
-
end
|
|
76
|
-
|
|
77
|
-
# @return [Symbol] :class or :instance
|
|
78
|
-
def scope
|
|
79
|
-
@scope ||= :instance if duck_type? || nil_type?
|
|
80
|
-
@scope ||= (name == 'Class' || name == 'Module') && !subtypes.empty? ? :class : :instance
|
|
81
|
-
end
|
|
82
|
-
|
|
83
|
-
def == other
|
|
84
|
-
return false unless self.class == other.class
|
|
85
|
-
tag == other.tag
|
|
86
|
-
end
|
|
87
|
-
|
|
88
|
-
def rooted?
|
|
89
|
-
@rooted
|
|
90
|
-
end
|
|
91
|
-
|
|
92
|
-
# Generate a ComplexType that fully qualifies this type's namespaces.
|
|
93
|
-
#
|
|
94
|
-
# @param api_map [ApiMap] The ApiMap that performs qualification
|
|
95
|
-
# @param context [String] The namespace from which to resolve names
|
|
96
|
-
# @return [ComplexType] The generated ComplexType
|
|
97
|
-
def qualify api_map, context = ''
|
|
98
|
-
return ComplexType.new([self]) if duck_type? || void? || undefined?
|
|
99
|
-
recon = (rooted? ? '' : context)
|
|
100
|
-
fqns = api_map.qualify(name, recon)
|
|
101
|
-
if fqns.nil?
|
|
102
|
-
return ComplexType.parse('Boolean') if tag == 'Boolean'
|
|
103
|
-
return ComplexType::UNDEFINED
|
|
104
|
-
end
|
|
105
|
-
fqns = "::#{fqns}" # Ensure the resulting complex type is rooted
|
|
106
|
-
ltypes = key_types.map do |t|
|
|
107
|
-
t.qualify api_map, context
|
|
108
|
-
end
|
|
109
|
-
rtypes = value_types.map do |t|
|
|
110
|
-
t.qualify api_map, context
|
|
111
|
-
end
|
|
112
|
-
if list_parameters?
|
|
113
|
-
Solargraph::ComplexType.parse("#{fqns}<#{rtypes.map(&:tag).join(', ')}>").first
|
|
114
|
-
elsif fixed_parameters?
|
|
115
|
-
Solargraph::ComplexType.parse("#{fqns}(#{rtypes.map(&:tag).join(', ')})").first
|
|
116
|
-
elsif hash_parameters?
|
|
117
|
-
Solargraph::ComplexType.parse("#{fqns}{#{ltypes.map(&:tag).join(', ')} => #{rtypes.map(&:tag).join(', ')}}").first
|
|
118
|
-
else
|
|
119
|
-
Solargraph::ComplexType.parse(fqns).first
|
|
120
|
-
end
|
|
121
|
-
end
|
|
122
|
-
end
|
|
123
|
-
end
|
|
124
|
-
end
|
|
1
|
+
module Solargraph
|
|
2
|
+
class ComplexType
|
|
3
|
+
# Methods for accessing type data.
|
|
4
|
+
#
|
|
5
|
+
module TypeMethods
|
|
6
|
+
# @return [String]
|
|
7
|
+
attr_reader :name
|
|
8
|
+
|
|
9
|
+
# @return [String]
|
|
10
|
+
attr_reader :substring
|
|
11
|
+
|
|
12
|
+
# @return [String]
|
|
13
|
+
attr_reader :tag
|
|
14
|
+
|
|
15
|
+
# @return [Array<ComplexType>]
|
|
16
|
+
attr_reader :subtypes
|
|
17
|
+
|
|
18
|
+
# @return [Boolean]
|
|
19
|
+
def duck_type?
|
|
20
|
+
@duck_type ||= name.start_with?('#')
|
|
21
|
+
end
|
|
22
|
+
|
|
23
|
+
# @return [Boolean]
|
|
24
|
+
def nil_type?
|
|
25
|
+
@nil_type ||= (name.downcase == 'nil')
|
|
26
|
+
end
|
|
27
|
+
|
|
28
|
+
# @return [Boolean]
|
|
29
|
+
def parameters?
|
|
30
|
+
!substring.empty?
|
|
31
|
+
end
|
|
32
|
+
|
|
33
|
+
def void?
|
|
34
|
+
name == 'void'
|
|
35
|
+
end
|
|
36
|
+
|
|
37
|
+
def defined?
|
|
38
|
+
!undefined?
|
|
39
|
+
end
|
|
40
|
+
|
|
41
|
+
def undefined?
|
|
42
|
+
name == 'undefined'
|
|
43
|
+
end
|
|
44
|
+
|
|
45
|
+
# @return [Boolean]
|
|
46
|
+
def list_parameters?
|
|
47
|
+
substring.start_with?('<')
|
|
48
|
+
end
|
|
49
|
+
|
|
50
|
+
# @return [Boolean]
|
|
51
|
+
def fixed_parameters?
|
|
52
|
+
substring.start_with?('(')
|
|
53
|
+
end
|
|
54
|
+
|
|
55
|
+
# @return [Boolean]
|
|
56
|
+
def hash_parameters?
|
|
57
|
+
substring.start_with?('{')
|
|
58
|
+
end
|
|
59
|
+
|
|
60
|
+
# @return [Array<ComplexType>]
|
|
61
|
+
def value_types
|
|
62
|
+
@subtypes
|
|
63
|
+
end
|
|
64
|
+
|
|
65
|
+
# @return [Array<ComplexType>]
|
|
66
|
+
def key_types
|
|
67
|
+
@key_types
|
|
68
|
+
end
|
|
69
|
+
|
|
70
|
+
# @return [String]
|
|
71
|
+
def namespace
|
|
72
|
+
@namespace ||= 'Object' if duck_type?
|
|
73
|
+
@namespace ||= 'NilClass' if nil_type?
|
|
74
|
+
@namespace ||= (name == 'Class' || name == 'Module') && !subtypes.empty? ? subtypes.first.name : name
|
|
75
|
+
end
|
|
76
|
+
|
|
77
|
+
# @return [Symbol] :class or :instance
|
|
78
|
+
def scope
|
|
79
|
+
@scope ||= :instance if duck_type? || nil_type?
|
|
80
|
+
@scope ||= (name == 'Class' || name == 'Module') && !subtypes.empty? ? :class : :instance
|
|
81
|
+
end
|
|
82
|
+
|
|
83
|
+
def == other
|
|
84
|
+
return false unless self.class == other.class
|
|
85
|
+
tag == other.tag
|
|
86
|
+
end
|
|
87
|
+
|
|
88
|
+
def rooted?
|
|
89
|
+
@rooted
|
|
90
|
+
end
|
|
91
|
+
|
|
92
|
+
# Generate a ComplexType that fully qualifies this type's namespaces.
|
|
93
|
+
#
|
|
94
|
+
# @param api_map [ApiMap] The ApiMap that performs qualification
|
|
95
|
+
# @param context [String] The namespace from which to resolve names
|
|
96
|
+
# @return [ComplexType] The generated ComplexType
|
|
97
|
+
def qualify api_map, context = ''
|
|
98
|
+
return ComplexType.new([self]) if duck_type? || void? || undefined?
|
|
99
|
+
recon = (rooted? ? '' : context)
|
|
100
|
+
fqns = api_map.qualify(name, recon)
|
|
101
|
+
if fqns.nil?
|
|
102
|
+
return ComplexType.parse('Boolean') if tag == 'Boolean'
|
|
103
|
+
return ComplexType::UNDEFINED
|
|
104
|
+
end
|
|
105
|
+
fqns = "::#{fqns}" # Ensure the resulting complex type is rooted
|
|
106
|
+
ltypes = key_types.map do |t|
|
|
107
|
+
t.qualify api_map, context
|
|
108
|
+
end
|
|
109
|
+
rtypes = value_types.map do |t|
|
|
110
|
+
t.qualify api_map, context
|
|
111
|
+
end
|
|
112
|
+
if list_parameters?
|
|
113
|
+
Solargraph::ComplexType.parse("#{fqns}<#{rtypes.map(&:tag).join(', ')}>").first
|
|
114
|
+
elsif fixed_parameters?
|
|
115
|
+
Solargraph::ComplexType.parse("#{fqns}(#{rtypes.map(&:tag).join(', ')})").first
|
|
116
|
+
elsif hash_parameters?
|
|
117
|
+
Solargraph::ComplexType.parse("#{fqns}{#{ltypes.map(&:tag).join(', ')} => #{rtypes.map(&:tag).join(', ')}}").first
|
|
118
|
+
else
|
|
119
|
+
Solargraph::ComplexType.parse(fqns).first
|
|
120
|
+
end
|
|
121
|
+
end
|
|
122
|
+
end
|
|
123
|
+
end
|
|
124
|
+
end
|