cosmicgraph 0.49.0
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 +7 -0
- data/.github/FUNDING.yml +1 -0
- data/.github/workflows/rspec.yml +41 -0
- data/.gitignore +9 -0
- data/.rspec +2 -0
- data/.yardopts +2 -0
- data/CHANGELOG.md +1150 -0
- data/Gemfile +7 -0
- data/LICENSE +21 -0
- data/README.md +136 -0
- data/Rakefile +25 -0
- data/SPONSORS.md +15 -0
- data/bin/solargraph +5 -0
- data/cosmicgraph.gemspec +44 -0
- data/lib/.rubocop.yml +22 -0
- data/lib/solargraph/api_map/bundler_methods.rb +22 -0
- data/lib/solargraph/api_map/cache.rb +70 -0
- data/lib/solargraph/api_map/source_to_yard.rb +81 -0
- data/lib/solargraph/api_map/store.rb +268 -0
- data/lib/solargraph/api_map.rb +704 -0
- data/lib/solargraph/bench.rb +27 -0
- data/lib/solargraph/cache.rb +51 -0
- data/lib/solargraph/complex_type/type_methods.rb +134 -0
- data/lib/solargraph/complex_type/unique_type.rb +132 -0
- data/lib/solargraph/complex_type.rb +254 -0
- data/lib/solargraph/convention/base.rb +33 -0
- data/lib/solargraph/convention/gemfile.rb +15 -0
- data/lib/solargraph/convention/gemspec.rb +22 -0
- data/lib/solargraph/convention/rakefile.rb +17 -0
- data/lib/solargraph/convention/rspec.rb +30 -0
- data/lib/solargraph/convention.rb +49 -0
- data/lib/solargraph/converters/dd.rb +12 -0
- data/lib/solargraph/converters/dl.rb +12 -0
- data/lib/solargraph/converters/dt.rb +12 -0
- data/lib/solargraph/converters/misc.rb +1 -0
- data/lib/solargraph/diagnostics/base.rb +29 -0
- data/lib/solargraph/diagnostics/require_not_found.rb +53 -0
- data/lib/solargraph/diagnostics/rubocop.rb +112 -0
- data/lib/solargraph/diagnostics/rubocop_helpers.rb +65 -0
- data/lib/solargraph/diagnostics/severities.rb +15 -0
- data/lib/solargraph/diagnostics/type_check.rb +54 -0
- data/lib/solargraph/diagnostics/update_errors.rb +41 -0
- data/lib/solargraph/diagnostics.rb +55 -0
- data/lib/solargraph/documentor.rb +76 -0
- data/lib/solargraph/environ.rb +45 -0
- data/lib/solargraph/language_server/completion_item_kinds.rb +35 -0
- data/lib/solargraph/language_server/error_codes.rb +20 -0
- data/lib/solargraph/language_server/host/cataloger.rb +56 -0
- data/lib/solargraph/language_server/host/diagnoser.rb +89 -0
- data/lib/solargraph/language_server/host/dispatch.rb +111 -0
- data/lib/solargraph/language_server/host/message_worker.rb +59 -0
- data/lib/solargraph/language_server/host/sources.rb +156 -0
- data/lib/solargraph/language_server/host.rb +869 -0
- data/lib/solargraph/language_server/message/base.rb +89 -0
- data/lib/solargraph/language_server/message/cancel_request.rb +13 -0
- data/lib/solargraph/language_server/message/client/register_capability.rb +15 -0
- data/lib/solargraph/language_server/message/client.rb +11 -0
- data/lib/solargraph/language_server/message/completion_item/resolve.rb +58 -0
- data/lib/solargraph/language_server/message/completion_item.rb +11 -0
- data/lib/solargraph/language_server/message/exit_notification.rb +13 -0
- data/lib/solargraph/language_server/message/extended/check_gem_version.rb +100 -0
- data/lib/solargraph/language_server/message/extended/document.rb +20 -0
- data/lib/solargraph/language_server/message/extended/document_gems.rb +32 -0
- data/lib/solargraph/language_server/message/extended/download_core.rb +19 -0
- data/lib/solargraph/language_server/message/extended/environment.rb +25 -0
- data/lib/solargraph/language_server/message/extended/search.rb +20 -0
- data/lib/solargraph/language_server/message/extended.rb +21 -0
- data/lib/solargraph/language_server/message/initialize.rb +164 -0
- data/lib/solargraph/language_server/message/initialized.rb +27 -0
- data/lib/solargraph/language_server/message/method_not_found.rb +16 -0
- data/lib/solargraph/language_server/message/method_not_implemented.rb +14 -0
- data/lib/solargraph/language_server/message/shutdown.rb +13 -0
- data/lib/solargraph/language_server/message/text_document/base.rb +19 -0
- data/lib/solargraph/language_server/message/text_document/code_action.rb +17 -0
- data/lib/solargraph/language_server/message/text_document/completion.rb +59 -0
- data/lib/solargraph/language_server/message/text_document/definition.rb +38 -0
- data/lib/solargraph/language_server/message/text_document/did_change.rb +15 -0
- data/lib/solargraph/language_server/message/text_document/did_close.rb +15 -0
- data/lib/solargraph/language_server/message/text_document/did_open.rb +15 -0
- data/lib/solargraph/language_server/message/text_document/did_save.rb +17 -0
- data/lib/solargraph/language_server/message/text_document/document_highlight.rb +16 -0
- data/lib/solargraph/language_server/message/text_document/document_symbol.rb +23 -0
- data/lib/solargraph/language_server/message/text_document/folding_range.rb +26 -0
- data/lib/solargraph/language_server/message/text_document/formatting.rb +126 -0
- data/lib/solargraph/language_server/message/text_document/hover.rb +56 -0
- data/lib/solargraph/language_server/message/text_document/on_type_formatting.rb +34 -0
- data/lib/solargraph/language_server/message/text_document/prepare_rename.rb +11 -0
- data/lib/solargraph/language_server/message/text_document/references.rb +16 -0
- data/lib/solargraph/language_server/message/text_document/rename.rb +19 -0
- data/lib/solargraph/language_server/message/text_document/signature_help.rb +24 -0
- data/lib/solargraph/language_server/message/text_document.rb +28 -0
- data/lib/solargraph/language_server/message/workspace/did_change_configuration.rb +30 -0
- data/lib/solargraph/language_server/message/workspace/did_change_watched_files.rb +40 -0
- data/lib/solargraph/language_server/message/workspace/did_change_workspace_folders.rb +24 -0
- data/lib/solargraph/language_server/message/workspace/workspace_symbol.rb +23 -0
- data/lib/solargraph/language_server/message/workspace.rb +14 -0
- data/lib/solargraph/language_server/message.rb +93 -0
- data/lib/solargraph/language_server/message_types.rb +14 -0
- data/lib/solargraph/language_server/request.rb +24 -0
- data/lib/solargraph/language_server/symbol_kinds.rb +36 -0
- data/lib/solargraph/language_server/transport/adapter.rb +53 -0
- data/lib/solargraph/language_server/transport/data_reader.rb +72 -0
- data/lib/solargraph/language_server/transport.rb +13 -0
- data/lib/solargraph/language_server/uri_helpers.rb +49 -0
- data/lib/solargraph/language_server.rb +19 -0
- data/lib/solargraph/library.rb +547 -0
- data/lib/solargraph/location.rb +37 -0
- data/lib/solargraph/logging.rb +27 -0
- data/lib/solargraph/page.rb +83 -0
- data/lib/solargraph/parser/comment_ripper.rb +52 -0
- data/lib/solargraph/parser/legacy/class_methods.rb +135 -0
- data/lib/solargraph/parser/legacy/flawed_builder.rb +16 -0
- data/lib/solargraph/parser/legacy/node_chainer.rb +148 -0
- data/lib/solargraph/parser/legacy/node_methods.rb +325 -0
- data/lib/solargraph/parser/legacy/node_processors/alias_node.rb +23 -0
- data/lib/solargraph/parser/legacy/node_processors/args_node.rb +35 -0
- data/lib/solargraph/parser/legacy/node_processors/begin_node.rb +15 -0
- data/lib/solargraph/parser/legacy/node_processors/block_node.rb +42 -0
- data/lib/solargraph/parser/legacy/node_processors/casgn_node.rb +35 -0
- data/lib/solargraph/parser/legacy/node_processors/cvasgn_node.rb +23 -0
- data/lib/solargraph/parser/legacy/node_processors/def_node.rb +63 -0
- data/lib/solargraph/parser/legacy/node_processors/defs_node.rb +36 -0
- data/lib/solargraph/parser/legacy/node_processors/gvasgn_node.rb +23 -0
- data/lib/solargraph/parser/legacy/node_processors/ivasgn_node.rb +38 -0
- data/lib/solargraph/parser/legacy/node_processors/lvasgn_node.rb +28 -0
- data/lib/solargraph/parser/legacy/node_processors/namespace_node.rb +39 -0
- data/lib/solargraph/parser/legacy/node_processors/orasgn_node.rb +16 -0
- data/lib/solargraph/parser/legacy/node_processors/resbody_node.rb +36 -0
- data/lib/solargraph/parser/legacy/node_processors/sclass_node.rb +42 -0
- data/lib/solargraph/parser/legacy/node_processors/send_node.rb +257 -0
- data/lib/solargraph/parser/legacy/node_processors/sym_node.rb +18 -0
- data/lib/solargraph/parser/legacy/node_processors.rb +54 -0
- data/lib/solargraph/parser/legacy.rb +12 -0
- data/lib/solargraph/parser/node_methods.rb +43 -0
- data/lib/solargraph/parser/node_processor/base.rb +77 -0
- data/lib/solargraph/parser/node_processor.rb +43 -0
- data/lib/solargraph/parser/region.rb +66 -0
- data/lib/solargraph/parser/rubyvm/class_methods.rb +149 -0
- data/lib/solargraph/parser/rubyvm/node_chainer.rb +160 -0
- data/lib/solargraph/parser/rubyvm/node_methods.rb +315 -0
- data/lib/solargraph/parser/rubyvm/node_processors/alias_node.rb +23 -0
- data/lib/solargraph/parser/rubyvm/node_processors/args_node.rb +85 -0
- data/lib/solargraph/parser/rubyvm/node_processors/begin_node.rb +15 -0
- data/lib/solargraph/parser/rubyvm/node_processors/block_node.rb +42 -0
- data/lib/solargraph/parser/rubyvm/node_processors/casgn_node.rb +33 -0
- data/lib/solargraph/parser/rubyvm/node_processors/cvasgn_node.rb +23 -0
- data/lib/solargraph/parser/rubyvm/node_processors/def_node.rb +75 -0
- data/lib/solargraph/parser/rubyvm/node_processors/defs_node.rb +68 -0
- data/lib/solargraph/parser/rubyvm/node_processors/gvasgn_node.rb +23 -0
- data/lib/solargraph/parser/rubyvm/node_processors/ivasgn_node.rb +38 -0
- data/lib/solargraph/parser/rubyvm/node_processors/kw_arg_node.rb +39 -0
- data/lib/solargraph/parser/rubyvm/node_processors/lit_node.rb +20 -0
- data/lib/solargraph/parser/rubyvm/node_processors/lvasgn_node.rb +27 -0
- data/lib/solargraph/parser/rubyvm/node_processors/namespace_node.rb +39 -0
- data/lib/solargraph/parser/rubyvm/node_processors/opt_arg_node.rb +26 -0
- data/lib/solargraph/parser/rubyvm/node_processors/orasgn_node.rb +15 -0
- data/lib/solargraph/parser/rubyvm/node_processors/resbody_node.rb +45 -0
- data/lib/solargraph/parser/rubyvm/node_processors/sclass_node.rb +32 -0
- data/lib/solargraph/parser/rubyvm/node_processors/scope_node.rb +15 -0
- data/lib/solargraph/parser/rubyvm/node_processors/send_node.rb +279 -0
- data/lib/solargraph/parser/rubyvm/node_processors/sym_node.rb +18 -0
- data/lib/solargraph/parser/rubyvm/node_processors.rb +63 -0
- data/lib/solargraph/parser/rubyvm/node_wrapper.rb +47 -0
- data/lib/solargraph/parser/rubyvm.rb +40 -0
- data/lib/solargraph/parser/snippet.rb +13 -0
- data/lib/solargraph/parser.rb +26 -0
- data/lib/solargraph/pin/base.rb +299 -0
- data/lib/solargraph/pin/base_variable.rb +84 -0
- data/lib/solargraph/pin/block.rb +73 -0
- data/lib/solargraph/pin/class_variable.rb +8 -0
- data/lib/solargraph/pin/closure.rb +37 -0
- data/lib/solargraph/pin/common.rb +70 -0
- data/lib/solargraph/pin/constant.rb +43 -0
- data/lib/solargraph/pin/conversions.rb +92 -0
- data/lib/solargraph/pin/documenting.rb +105 -0
- data/lib/solargraph/pin/duck_method.rb +16 -0
- data/lib/solargraph/pin/global_variable.rb +8 -0
- data/lib/solargraph/pin/instance_variable.rb +30 -0
- data/lib/solargraph/pin/keyword.rb +15 -0
- data/lib/solargraph/pin/keyword_param.rb +8 -0
- data/lib/solargraph/pin/local_variable.rb +55 -0
- data/lib/solargraph/pin/method.rb +335 -0
- data/lib/solargraph/pin/method_alias.rb +31 -0
- data/lib/solargraph/pin/namespace.rb +94 -0
- data/lib/solargraph/pin/parameter.rb +206 -0
- data/lib/solargraph/pin/proxy_type.rb +29 -0
- data/lib/solargraph/pin/reference/extend.rb +10 -0
- data/lib/solargraph/pin/reference/include.rb +10 -0
- data/lib/solargraph/pin/reference/override.rb +29 -0
- data/lib/solargraph/pin/reference/prepend.rb +10 -0
- data/lib/solargraph/pin/reference/require.rb +14 -0
- data/lib/solargraph/pin/reference/superclass.rb +10 -0
- data/lib/solargraph/pin/reference.rb +14 -0
- data/lib/solargraph/pin/search.rb +56 -0
- data/lib/solargraph/pin/signature.rb +23 -0
- data/lib/solargraph/pin/singleton.rb +11 -0
- data/lib/solargraph/pin/symbol.rb +47 -0
- data/lib/solargraph/pin.rb +38 -0
- data/lib/solargraph/position.rb +100 -0
- data/lib/solargraph/range.rb +95 -0
- data/lib/solargraph/rbs_map/conversions.rb +394 -0
- data/lib/solargraph/rbs_map/core_fills.rb +61 -0
- data/lib/solargraph/rbs_map/core_map.rb +38 -0
- data/lib/solargraph/rbs_map/core_signs.rb +33 -0
- data/lib/solargraph/rbs_map/stdlib_map.rb +36 -0
- data/lib/solargraph/rbs_map.rb +73 -0
- data/lib/solargraph/server_methods.rb +16 -0
- data/lib/solargraph/shell.rb +234 -0
- data/lib/solargraph/source/chain/block_variable.rb +13 -0
- data/lib/solargraph/source/chain/call.rb +215 -0
- data/lib/solargraph/source/chain/class_variable.rb +13 -0
- data/lib/solargraph/source/chain/constant.rb +75 -0
- data/lib/solargraph/source/chain/global_variable.rb +13 -0
- data/lib/solargraph/source/chain/hash.rb +28 -0
- data/lib/solargraph/source/chain/head.rb +19 -0
- data/lib/solargraph/source/chain/instance_variable.rb +13 -0
- data/lib/solargraph/source/chain/link.rb +71 -0
- data/lib/solargraph/source/chain/literal.rb +23 -0
- data/lib/solargraph/source/chain/or.rb +23 -0
- data/lib/solargraph/source/chain/q_call.rb +11 -0
- data/lib/solargraph/source/chain/variable.rb +13 -0
- data/lib/solargraph/source/chain/z_super.rb +30 -0
- data/lib/solargraph/source/chain.rb +179 -0
- data/lib/solargraph/source/change.rb +79 -0
- data/lib/solargraph/source/cursor.rb +164 -0
- data/lib/solargraph/source/encoding_fixes.rb +23 -0
- data/lib/solargraph/source/source_chainer.rb +191 -0
- data/lib/solargraph/source/updater.rb +54 -0
- data/lib/solargraph/source.rb +522 -0
- data/lib/solargraph/source_map/clip.rb +229 -0
- data/lib/solargraph/source_map/completion.rb +23 -0
- data/lib/solargraph/source_map/mapper.rb +241 -0
- data/lib/solargraph/source_map.rb +180 -0
- data/lib/solargraph/type_checker/checks.rb +112 -0
- data/lib/solargraph/type_checker/param_def.rb +35 -0
- data/lib/solargraph/type_checker/problem.rb +32 -0
- data/lib/solargraph/type_checker/rules.rb +57 -0
- data/lib/solargraph/type_checker.rb +549 -0
- data/lib/solargraph/version.rb +5 -0
- data/lib/solargraph/views/_method.erb +62 -0
- data/lib/solargraph/views/_name_type_tag.erb +10 -0
- data/lib/solargraph/views/_namespace.erb +24 -0
- data/lib/solargraph/views/document.erb +23 -0
- data/lib/solargraph/views/environment.erb +58 -0
- data/lib/solargraph/views/layout.erb +44 -0
- data/lib/solargraph/views/search.erb +11 -0
- data/lib/solargraph/workspace/config.rb +231 -0
- data/lib/solargraph/workspace.rb +212 -0
- data/lib/solargraph/yard_map/cache.rb +19 -0
- data/lib/solargraph/yard_map/helpers.rb +16 -0
- data/lib/solargraph/yard_map/mapper/to_constant.rb +25 -0
- data/lib/solargraph/yard_map/mapper/to_method.rb +81 -0
- data/lib/solargraph/yard_map/mapper/to_namespace.rb +27 -0
- data/lib/solargraph/yard_map/mapper.rb +77 -0
- data/lib/solargraph/yard_map/to_method.rb +79 -0
- data/lib/solargraph/yard_map.rb +301 -0
- data/lib/solargraph.rb +69 -0
- data/lib/yard-solargraph.rb +33 -0
- metadata +587 -0
@@ -0,0 +1,19 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Solargraph
|
4
|
+
class Source
|
5
|
+
class Chain
|
6
|
+
# Chain::Head is a link for ambiguous words, e.g.; `String` can refer to
|
7
|
+
# either a class (`String`) or a function (`Kernel#String`).
|
8
|
+
#
|
9
|
+
# @note Chain::Head is only intended to handle `self` and `super`.
|
10
|
+
class Head < Link
|
11
|
+
def resolve api_map, name_pin, locals
|
12
|
+
return [Pin::ProxyType.anonymous(name_pin.binder)] if word == 'self'
|
13
|
+
# return super_pins(api_map, name_pin) if word == 'super'
|
14
|
+
[]
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
@@ -0,0 +1,13 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Solargraph
|
4
|
+
class Source
|
5
|
+
class Chain
|
6
|
+
class InstanceVariable < Link
|
7
|
+
def resolve api_map, name_pin, locals
|
8
|
+
api_map.get_instance_variable_pins(name_pin.binder.namespace, name_pin.binder.scope).select{|p| p.name == word}
|
9
|
+
end
|
10
|
+
end
|
11
|
+
end
|
12
|
+
end
|
13
|
+
end
|
@@ -0,0 +1,71 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Solargraph
|
4
|
+
class Source
|
5
|
+
class Chain
|
6
|
+
class Link
|
7
|
+
# @return [String]
|
8
|
+
attr_reader :word
|
9
|
+
|
10
|
+
attr_accessor :last_context
|
11
|
+
|
12
|
+
def initialize word = '<undefined>'
|
13
|
+
@word = word
|
14
|
+
end
|
15
|
+
|
16
|
+
def undefined?
|
17
|
+
word == '<undefined>'
|
18
|
+
end
|
19
|
+
|
20
|
+
def constant?
|
21
|
+
is_a?(Chain::Constant)
|
22
|
+
end
|
23
|
+
|
24
|
+
# @param api_map [ApiMap]
|
25
|
+
# @param name_pin [Pin::Base]
|
26
|
+
# @param locals [Array<Pin::Base>]
|
27
|
+
# @return [Array<Pin::Base>]
|
28
|
+
def resolve api_map, name_pin, locals
|
29
|
+
[]
|
30
|
+
end
|
31
|
+
|
32
|
+
def head?
|
33
|
+
@head ||= false
|
34
|
+
end
|
35
|
+
|
36
|
+
def == other
|
37
|
+
self.class == other.class and word == other.word
|
38
|
+
end
|
39
|
+
|
40
|
+
# Make a copy of this link marked as the head of a chain
|
41
|
+
#
|
42
|
+
# @return [self]
|
43
|
+
def clone_head
|
44
|
+
clone.mark_head(true)
|
45
|
+
end
|
46
|
+
|
47
|
+
# Make a copy of this link unmarked as the head of a chain
|
48
|
+
#
|
49
|
+
# @return [self]
|
50
|
+
def clone_body
|
51
|
+
clone.mark_head(false)
|
52
|
+
end
|
53
|
+
|
54
|
+
def nullable?
|
55
|
+
false
|
56
|
+
end
|
57
|
+
|
58
|
+
protected
|
59
|
+
|
60
|
+
# Mark whether this link is the head of a chain
|
61
|
+
#
|
62
|
+
# @param bool [Boolean]
|
63
|
+
# @return [self]
|
64
|
+
def mark_head bool
|
65
|
+
@head = bool
|
66
|
+
self
|
67
|
+
end
|
68
|
+
end
|
69
|
+
end
|
70
|
+
end
|
71
|
+
end
|
@@ -0,0 +1,23 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Solargraph
|
4
|
+
class Source
|
5
|
+
class Chain
|
6
|
+
class Literal < Link
|
7
|
+
def word
|
8
|
+
@word ||= "<#{@type}>"
|
9
|
+
end
|
10
|
+
|
11
|
+
# @param type [String]
|
12
|
+
def initialize type
|
13
|
+
@type = type
|
14
|
+
@complex_type = ComplexType.try_parse(type)
|
15
|
+
end
|
16
|
+
|
17
|
+
def resolve api_map, name_pin, locals
|
18
|
+
[Pin::ProxyType.anonymous(@complex_type)]
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
@@ -0,0 +1,23 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Solargraph
|
4
|
+
class Source
|
5
|
+
class Chain
|
6
|
+
class Or < Link
|
7
|
+
def word
|
8
|
+
'<or>'
|
9
|
+
end
|
10
|
+
|
11
|
+
# @param type [String]
|
12
|
+
def initialize links
|
13
|
+
@links = links
|
14
|
+
end
|
15
|
+
|
16
|
+
def resolve api_map, name_pin, locals
|
17
|
+
types = @links.map { |link| link.infer(api_map, name_pin, locals) }
|
18
|
+
[Solargraph::Pin::ProxyType.anonymous(Solargraph::ComplexType.try_parse(types.map(&:tag).uniq.join(', ')))]
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
@@ -0,0 +1,13 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Solargraph
|
4
|
+
class Source
|
5
|
+
class Chain
|
6
|
+
class Variable < Link
|
7
|
+
def resolve api_map, name_pin, locals
|
8
|
+
api_map.get_instance_variable_pins(name_pin.context.namespace, name_pin.context.scope).select{|p| p.name == word}
|
9
|
+
end
|
10
|
+
end
|
11
|
+
end
|
12
|
+
end
|
13
|
+
end
|
@@ -0,0 +1,30 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Solargraph
|
4
|
+
class Source
|
5
|
+
class Chain
|
6
|
+
class ZSuper < Call
|
7
|
+
# @return [String]
|
8
|
+
attr_reader :word
|
9
|
+
|
10
|
+
# @return [Array<Chain>]
|
11
|
+
attr_reader :arguments
|
12
|
+
|
13
|
+
# @param word [String]
|
14
|
+
# @param arguments [Array<Chain>]
|
15
|
+
# @param with_block [Boolean] True if the chain is inside a block
|
16
|
+
# @param head [Boolean] True if the call is the start of its chain
|
17
|
+
def initialize word, with_block = false
|
18
|
+
super(word, [], with_block)
|
19
|
+
end
|
20
|
+
|
21
|
+
# @param api_map [ApiMap]
|
22
|
+
# @param name_pin [Pin::Base]
|
23
|
+
# @param locals [Array<Pin::Base>]
|
24
|
+
def resolve api_map, name_pin, locals
|
25
|
+
return super_pins(api_map, name_pin)
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
@@ -0,0 +1,179 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
# HACK: Fix autoload issue
|
4
|
+
require 'solargraph/source/chain/link'
|
5
|
+
|
6
|
+
module Solargraph
|
7
|
+
class Source
|
8
|
+
# A chain of constants, variables, and method calls for inferring types of
|
9
|
+
# values.
|
10
|
+
#
|
11
|
+
class Chain
|
12
|
+
autoload :Link, 'solargraph/source/chain/link'
|
13
|
+
autoload :Call, 'solargraph/source/chain/call'
|
14
|
+
autoload :QCall, 'solargraph/source/chain/q_call'
|
15
|
+
autoload :Variable, 'solargraph/source/chain/variable'
|
16
|
+
autoload :ClassVariable, 'solargraph/source/chain/class_variable'
|
17
|
+
autoload :Constant, 'solargraph/source/chain/constant'
|
18
|
+
autoload :InstanceVariable, 'solargraph/source/chain/instance_variable'
|
19
|
+
autoload :GlobalVariable, 'solargraph/source/chain/global_variable'
|
20
|
+
autoload :Literal, 'solargraph/source/chain/literal'
|
21
|
+
autoload :Head, 'solargraph/source/chain/head'
|
22
|
+
autoload :Or, 'solargraph/source/chain/or'
|
23
|
+
autoload :BlockVariable, 'solargraph/source/chain/block_variable'
|
24
|
+
autoload :ZSuper, 'solargraph/source/chain/z_super'
|
25
|
+
autoload :Hash, 'solargraph/source/chain/hash'
|
26
|
+
|
27
|
+
@@inference_stack = []
|
28
|
+
@@inference_depth = 0
|
29
|
+
|
30
|
+
UNDEFINED_CALL = Chain::Call.new('<undefined>')
|
31
|
+
UNDEFINED_CONSTANT = Chain::Constant.new('<undefined>')
|
32
|
+
|
33
|
+
# @return [Array<Source::Chain::Link>]
|
34
|
+
attr_reader :links
|
35
|
+
|
36
|
+
attr_reader :node
|
37
|
+
|
38
|
+
# @param links [Array<Chain::Link>]
|
39
|
+
def initialize links, node = nil, splat = false
|
40
|
+
@links = links.clone
|
41
|
+
@links.push UNDEFINED_CALL if @links.empty?
|
42
|
+
head = true
|
43
|
+
@links.map! do |link|
|
44
|
+
result = (head ? link.clone_head : link.clone_body)
|
45
|
+
head = false
|
46
|
+
result
|
47
|
+
end
|
48
|
+
@node = node
|
49
|
+
@splat = splat
|
50
|
+
end
|
51
|
+
|
52
|
+
# @return [Chain]
|
53
|
+
def base
|
54
|
+
@base ||= Chain.new(links[0..-2])
|
55
|
+
end
|
56
|
+
|
57
|
+
# @param api_map [ApiMap]
|
58
|
+
# @param name_pin [Pin::Base]
|
59
|
+
# @param locals [Array<Pin::Base>]
|
60
|
+
# @return [Array<Pin::Base>]
|
61
|
+
def define api_map, name_pin, locals
|
62
|
+
return [] if undefined?
|
63
|
+
working_pin = name_pin
|
64
|
+
links[0..-2].each do |link|
|
65
|
+
pins = link.resolve(api_map, working_pin, locals)
|
66
|
+
type = infer_first_defined(pins, working_pin, api_map, locals)
|
67
|
+
return [] if type.undefined?
|
68
|
+
working_pin = Pin::ProxyType.anonymous(type)
|
69
|
+
end
|
70
|
+
links.last.last_context = name_pin
|
71
|
+
links.last.resolve(api_map, working_pin, locals)
|
72
|
+
end
|
73
|
+
|
74
|
+
# @param api_map [ApiMap]
|
75
|
+
# @param name_pin [Pin::Base]
|
76
|
+
# @param locals [Array<Pin::Base>]
|
77
|
+
# @return [ComplexType]
|
78
|
+
def infer api_map, name_pin, locals
|
79
|
+
from_here = base.infer(api_map, name_pin, locals) unless links.length == 1
|
80
|
+
if from_here
|
81
|
+
name_pin = name_pin.proxy(from_here)
|
82
|
+
end
|
83
|
+
pins = define(api_map, name_pin, locals)
|
84
|
+
type = infer_first_defined(pins, links.last.last_context, api_map, locals)
|
85
|
+
maybe_nil(type)
|
86
|
+
end
|
87
|
+
|
88
|
+
# @return [Boolean]
|
89
|
+
def literal?
|
90
|
+
links.last.is_a?(Chain::Literal)
|
91
|
+
end
|
92
|
+
|
93
|
+
def undefined?
|
94
|
+
links.any?(&:undefined?)
|
95
|
+
end
|
96
|
+
|
97
|
+
def defined?
|
98
|
+
!undefined?
|
99
|
+
end
|
100
|
+
|
101
|
+
# @return [Boolean]
|
102
|
+
def constant?
|
103
|
+
links.last.is_a?(Chain::Constant)
|
104
|
+
end
|
105
|
+
|
106
|
+
def splat?
|
107
|
+
@splat
|
108
|
+
end
|
109
|
+
|
110
|
+
def nullable?
|
111
|
+
links.any?(&:nullable?)
|
112
|
+
end
|
113
|
+
|
114
|
+
private
|
115
|
+
|
116
|
+
# @param pins [Array<Pin::Base>]
|
117
|
+
# @param context [Pin::Base]
|
118
|
+
# @param api_map [ApiMap]
|
119
|
+
# @return [ComplexType]
|
120
|
+
def infer_first_defined pins, context, api_map, locals
|
121
|
+
possibles = []
|
122
|
+
pins.each do |pin|
|
123
|
+
# Avoid infinite recursion
|
124
|
+
next if @@inference_stack.include?(pin.identity)
|
125
|
+
@@inference_stack.push pin.identity
|
126
|
+
type = pin.typify(api_map)
|
127
|
+
@@inference_stack.pop
|
128
|
+
if type.defined?
|
129
|
+
if type.parameterized?
|
130
|
+
type = type.resolve_parameters(pin.closure, context)
|
131
|
+
# idx = pin.closure.parameters.index(type.subtypes.first.name)
|
132
|
+
# next if idx.nil?
|
133
|
+
# param_type = context.return_type.all_params[idx]
|
134
|
+
# next unless param_type
|
135
|
+
# type = ComplexType.try_parse(param_type.to_s)
|
136
|
+
end
|
137
|
+
if type.defined?
|
138
|
+
possibles.push type
|
139
|
+
break if pin.is_a?(Pin::Method)
|
140
|
+
end
|
141
|
+
end
|
142
|
+
end
|
143
|
+
if possibles.empty?
|
144
|
+
# Limit method inference recursion
|
145
|
+
return ComplexType::UNDEFINED if @@inference_depth >= 10 && pins.first.is_a?(Pin::Method)
|
146
|
+
@@inference_depth += 1
|
147
|
+
pins.each do |pin|
|
148
|
+
# Avoid infinite recursion
|
149
|
+
next if @@inference_stack.include?(pin.identity)
|
150
|
+
@@inference_stack.push pin.identity
|
151
|
+
type = pin.probe(api_map)
|
152
|
+
@@inference_stack.pop
|
153
|
+
if type.defined?
|
154
|
+
possibles.push type
|
155
|
+
break if pin.is_a?(Pin::Method)
|
156
|
+
end
|
157
|
+
end
|
158
|
+
@@inference_depth -= 1
|
159
|
+
end
|
160
|
+
return ComplexType::UNDEFINED if possibles.empty?
|
161
|
+
type = if possibles.length > 1
|
162
|
+
sorted = possibles.map { |t| t.rooted? ? "::#{t}" : t.to_s }.sort { |a, _| a == 'nil' ? 1 : 0 }
|
163
|
+
ComplexType.parse(*sorted)
|
164
|
+
else
|
165
|
+
possibles.first
|
166
|
+
end
|
167
|
+
return type if context.nil? || context.return_type.undefined?
|
168
|
+
type.self_to(context.return_type.namespace)
|
169
|
+
end
|
170
|
+
|
171
|
+
# @param type [ComplexType]
|
172
|
+
def maybe_nil type
|
173
|
+
return type if type.undefined? || type.void? || type.nullable?
|
174
|
+
return type unless nullable?
|
175
|
+
ComplexType.try_parse("#{type}, nil")
|
176
|
+
end
|
177
|
+
end
|
178
|
+
end
|
179
|
+
end
|
@@ -0,0 +1,79 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Solargraph
|
4
|
+
class Source
|
5
|
+
# A change to be applied to text.
|
6
|
+
#
|
7
|
+
class Change
|
8
|
+
include EncodingFixes
|
9
|
+
|
10
|
+
# @return [Range]
|
11
|
+
attr_reader :range
|
12
|
+
|
13
|
+
# @return [String]
|
14
|
+
attr_reader :new_text
|
15
|
+
|
16
|
+
# @param range [Range] The starting and ending positions of the change.
|
17
|
+
# If nil, the original text will be overwritten.
|
18
|
+
# @param new_text [String] The text to be changed.
|
19
|
+
def initialize range, new_text
|
20
|
+
@range = range
|
21
|
+
@new_text = new_text
|
22
|
+
end
|
23
|
+
|
24
|
+
# Write the change to the specified text.
|
25
|
+
#
|
26
|
+
# @param text [String] The text to be changed.
|
27
|
+
# @param nullable [Boolean] If true, minor changes that could generate
|
28
|
+
# syntax errors will be repaired.
|
29
|
+
# @return [String] The updated text.
|
30
|
+
def write text, nullable = false
|
31
|
+
if nullable and !range.nil? and new_text.match(/[\.\[\{\(@\$:]$/)
|
32
|
+
[':', '@'].each do |dupable|
|
33
|
+
next unless new_text == dupable
|
34
|
+
offset = Position.to_offset(text, range.start)
|
35
|
+
if text[offset - 1] == dupable
|
36
|
+
p = Position.from_offset(text, offset - 1)
|
37
|
+
r = Change.new(Range.new(p, range.start), ' ')
|
38
|
+
text = r.write(text)
|
39
|
+
end
|
40
|
+
break
|
41
|
+
end
|
42
|
+
commit text, "#{new_text[0..-2]} "
|
43
|
+
elsif range.nil?
|
44
|
+
new_text
|
45
|
+
else
|
46
|
+
commit text, new_text
|
47
|
+
end
|
48
|
+
end
|
49
|
+
|
50
|
+
# Repair an update by replacing the new text with similarly formatted
|
51
|
+
# whitespace.
|
52
|
+
#
|
53
|
+
# @param text [String] The text to be changed.
|
54
|
+
# @return [String] The updated text.
|
55
|
+
def repair text
|
56
|
+
fixed = new_text.gsub(/[^\s]/, ' ')
|
57
|
+
if range.nil?
|
58
|
+
fixed
|
59
|
+
else
|
60
|
+
result = commit text, fixed
|
61
|
+
off = Position.to_offset(text, range.start)
|
62
|
+
match = result[0, off].match(/[\.:]+\z/)
|
63
|
+
if match
|
64
|
+
result = result[0, off].sub(/#{match[0]}\z/, ' ' * match[0].length) + result[off..-1]
|
65
|
+
end
|
66
|
+
result
|
67
|
+
end
|
68
|
+
end
|
69
|
+
|
70
|
+
private
|
71
|
+
|
72
|
+
def commit text, insert
|
73
|
+
start_offset = Position.to_offset(text, range.start)
|
74
|
+
end_offset = Position.to_offset(text, range.ending)
|
75
|
+
(start_offset == 0 ? '' : text[0..start_offset-1].to_s) + normalize(insert) + text[end_offset..-1].to_s
|
76
|
+
end
|
77
|
+
end
|
78
|
+
end
|
79
|
+
end
|
@@ -0,0 +1,164 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Solargraph
|
4
|
+
class Source
|
5
|
+
# Information about a position in a source, including the word located
|
6
|
+
# there.
|
7
|
+
#
|
8
|
+
class Cursor
|
9
|
+
# @return [Position]
|
10
|
+
attr_reader :position
|
11
|
+
|
12
|
+
# @return [Source]
|
13
|
+
attr_reader :source
|
14
|
+
|
15
|
+
# @param source [Source]
|
16
|
+
# @param position [Position, Array(Integer, Integer)]
|
17
|
+
def initialize source, position
|
18
|
+
@source = source
|
19
|
+
@position = Position.normalize(position)
|
20
|
+
end
|
21
|
+
|
22
|
+
# @return [String]
|
23
|
+
def filename
|
24
|
+
source.filename
|
25
|
+
end
|
26
|
+
|
27
|
+
# The whole word at the current position. Given the text `foo.bar`, the
|
28
|
+
# word at position(0,6) is `bar`.
|
29
|
+
#
|
30
|
+
# @return [String]
|
31
|
+
def word
|
32
|
+
@word ||= start_of_word + end_of_word
|
33
|
+
end
|
34
|
+
|
35
|
+
# The part of the word before the current position. Given the text
|
36
|
+
# `foo.bar`, the start_of_word at position(0, 6) is `ba`.
|
37
|
+
#
|
38
|
+
# @return [String]
|
39
|
+
def start_of_word
|
40
|
+
@start_of_word ||= begin
|
41
|
+
match = source.code[0..offset-1].to_s.match(start_word_pattern)
|
42
|
+
result = (match ? match[0] : '')
|
43
|
+
# Including the preceding colon if the word appears to be a symbol
|
44
|
+
result = ":#{result}" if source.code[0..offset-result.length-1].end_with?(':') and !source.code[0..offset-result.length-1].end_with?('::')
|
45
|
+
result
|
46
|
+
end
|
47
|
+
end
|
48
|
+
|
49
|
+
# The part of the word after the current position. Given the text
|
50
|
+
# `foo.bar`, the end_of_word at position (0,6) is `r`.
|
51
|
+
#
|
52
|
+
# @return [String]
|
53
|
+
def end_of_word
|
54
|
+
@end_of_word ||= begin
|
55
|
+
match = source.code[offset..-1].to_s.match(end_word_pattern)
|
56
|
+
match ? match[0] : ''
|
57
|
+
end
|
58
|
+
end
|
59
|
+
|
60
|
+
# @return [Boolean]
|
61
|
+
def start_of_constant?
|
62
|
+
source.code[offset-2, 2] == '::'
|
63
|
+
end
|
64
|
+
|
65
|
+
# The range of the word at the current position.
|
66
|
+
#
|
67
|
+
# @return [Range]
|
68
|
+
def range
|
69
|
+
@range ||= begin
|
70
|
+
s = Position.from_offset(source.code, offset - start_of_word.length)
|
71
|
+
e = Position.from_offset(source.code, offset + end_of_word.length)
|
72
|
+
Solargraph::Range.new(s, e)
|
73
|
+
end
|
74
|
+
end
|
75
|
+
|
76
|
+
# @return [Chain]
|
77
|
+
def chain
|
78
|
+
@chain ||= SourceChainer.chain(source, position)
|
79
|
+
end
|
80
|
+
|
81
|
+
# True if the statement at the cursor is an argument to a previous
|
82
|
+
# method.
|
83
|
+
#
|
84
|
+
# Given the code `process(foo)`, a cursor pointing at `foo` would
|
85
|
+
# identify it as an argument being passed to the `process` method.
|
86
|
+
#
|
87
|
+
# If #argument? is true, the #recipient method will return a cursor that
|
88
|
+
# points to the method receiving the argument.
|
89
|
+
#
|
90
|
+
# @return [Boolean]
|
91
|
+
def argument?
|
92
|
+
# @argument ||= !signature_position.nil?
|
93
|
+
@argument ||= !recipient.nil?
|
94
|
+
end
|
95
|
+
|
96
|
+
# @return [Boolean]
|
97
|
+
def comment?
|
98
|
+
@comment ||= source.comment_at?(position)
|
99
|
+
end
|
100
|
+
|
101
|
+
# @return [Boolean]
|
102
|
+
def string?
|
103
|
+
@string ||= source.string_at?(position)
|
104
|
+
end
|
105
|
+
|
106
|
+
# Get a cursor pointing to the method that receives the current statement
|
107
|
+
# as an argument.
|
108
|
+
#
|
109
|
+
# @return [Cursor, nil]
|
110
|
+
def recipient
|
111
|
+
@recipient ||= begin
|
112
|
+
node = recipient_node
|
113
|
+
node ? Cursor.new(source, Range.from_node(node).ending) : nil
|
114
|
+
end
|
115
|
+
end
|
116
|
+
alias receiver recipient
|
117
|
+
|
118
|
+
def node
|
119
|
+
@node ||= source.node_at(position.line, position.column)
|
120
|
+
end
|
121
|
+
|
122
|
+
# @return [Position]
|
123
|
+
def node_position
|
124
|
+
@node_position ||= begin
|
125
|
+
if start_of_word.empty?
|
126
|
+
match = source.code[0, offset].match(/[\s]*(\.|:+)[\s]*$/)
|
127
|
+
if match
|
128
|
+
Position.from_offset(source.code, offset - match[0].length)
|
129
|
+
else
|
130
|
+
position
|
131
|
+
end
|
132
|
+
else
|
133
|
+
position
|
134
|
+
end
|
135
|
+
end
|
136
|
+
end
|
137
|
+
|
138
|
+
def recipient_node
|
139
|
+
@recipient_node ||= Solargraph::Parser::NodeMethods.find_recipient_node(self)
|
140
|
+
end
|
141
|
+
|
142
|
+
# @return [Integer]
|
143
|
+
def offset
|
144
|
+
@offset ||= Position.to_offset(source.code, position)
|
145
|
+
end
|
146
|
+
|
147
|
+
private
|
148
|
+
|
149
|
+
# A regular expression to find the start of a word from an offset.
|
150
|
+
#
|
151
|
+
# @return [Regexp]
|
152
|
+
def start_word_pattern
|
153
|
+
/(@{1,2}|\$)?([a-z0-9_]|[^\u0000-\u007F])*\z/i
|
154
|
+
end
|
155
|
+
|
156
|
+
# A regular expression to find the end of a word from an offset.
|
157
|
+
#
|
158
|
+
# @return [Regexp]
|
159
|
+
def end_word_pattern
|
160
|
+
/^([a-z0-9_]|[^\u0000-\u007F])*[\?\!]?/i
|
161
|
+
end
|
162
|
+
end
|
163
|
+
end
|
164
|
+
end
|
@@ -0,0 +1,23 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Solargraph
|
4
|
+
class Source
|
5
|
+
module EncodingFixes
|
6
|
+
module_function
|
7
|
+
|
8
|
+
# Convert strings to normalized UTF-8.
|
9
|
+
#
|
10
|
+
# @param string [String]
|
11
|
+
# @return [String]
|
12
|
+
def normalize string
|
13
|
+
begin
|
14
|
+
string.dup.force_encoding('UTF-8')
|
15
|
+
rescue ::Encoding::CompatibilityError, ::Encoding::UndefinedConversionError, ::Encoding::InvalidByteSequenceError => e
|
16
|
+
# @todo Improve error handling
|
17
|
+
Solargraph::Logging.logger.warn "Normalize error: #{e.message}"
|
18
|
+
string
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|