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,549 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Solargraph
|
4
|
+
# A static analysis tool for validating data types.
|
5
|
+
#
|
6
|
+
class TypeChecker
|
7
|
+
autoload :Problem, 'solargraph/type_checker/problem'
|
8
|
+
autoload :ParamDef, 'solargraph/type_checker/param_def'
|
9
|
+
autoload :Rules, 'solargraph/type_checker/rules'
|
10
|
+
autoload :Checks, 'solargraph/type_checker/checks'
|
11
|
+
|
12
|
+
include Checks
|
13
|
+
include Parser::NodeMethods
|
14
|
+
|
15
|
+
# @return [String]
|
16
|
+
attr_reader :filename
|
17
|
+
|
18
|
+
# @return [Rules]
|
19
|
+
attr_reader :rules
|
20
|
+
|
21
|
+
# @return [ApiMap]
|
22
|
+
attr_reader :api_map
|
23
|
+
|
24
|
+
# @param filename [String]
|
25
|
+
# @param api_map [ApiMap]
|
26
|
+
# @param level [Symbol]
|
27
|
+
def initialize filename, api_map: nil, level: :normal
|
28
|
+
@filename = filename
|
29
|
+
# @todo Smarter directory resolution
|
30
|
+
@api_map = api_map || Solargraph::ApiMap.load(File.dirname(filename))
|
31
|
+
@rules = Rules.new(level)
|
32
|
+
@marked_ranges = []
|
33
|
+
end
|
34
|
+
|
35
|
+
# @return [SourceMap]
|
36
|
+
def source_map
|
37
|
+
@source_map ||= api_map.source_map(filename)
|
38
|
+
end
|
39
|
+
|
40
|
+
# @return [Array<Problem>]
|
41
|
+
def problems
|
42
|
+
@problems ||= begin
|
43
|
+
without_ignored(
|
44
|
+
method_tag_problems
|
45
|
+
.concat variable_type_tag_problems
|
46
|
+
.concat const_problems
|
47
|
+
.concat call_problems
|
48
|
+
)
|
49
|
+
end
|
50
|
+
end
|
51
|
+
|
52
|
+
class << self
|
53
|
+
# @param filename [String]
|
54
|
+
# @return [self]
|
55
|
+
def load filename, level = :normal
|
56
|
+
source = Solargraph::Source.load(filename)
|
57
|
+
api_map = Solargraph::ApiMap.new
|
58
|
+
api_map.map(source)
|
59
|
+
new(filename, api_map: api_map, level: level)
|
60
|
+
end
|
61
|
+
|
62
|
+
# @param code [String]
|
63
|
+
# @param filename [String, nil]
|
64
|
+
# @return [self]
|
65
|
+
def load_string code, filename = nil, level = :normal
|
66
|
+
source = Solargraph::Source.load_string(code, filename)
|
67
|
+
api_map = Solargraph::ApiMap.new
|
68
|
+
api_map.map(source)
|
69
|
+
new(filename, api_map: api_map, level: level)
|
70
|
+
end
|
71
|
+
end
|
72
|
+
|
73
|
+
private
|
74
|
+
|
75
|
+
# @return [Array<Problem>]
|
76
|
+
def method_tag_problems
|
77
|
+
result = []
|
78
|
+
# @param pin [Pin::Method]
|
79
|
+
source_map.pins_by_class(Pin::Method).each do |pin|
|
80
|
+
result.concat method_return_type_problems_for(pin)
|
81
|
+
result.concat method_param_type_problems_for(pin)
|
82
|
+
end
|
83
|
+
result
|
84
|
+
end
|
85
|
+
|
86
|
+
# @param pin [Pin::Method]
|
87
|
+
# @return [Array<Problem>]
|
88
|
+
def method_return_type_problems_for pin
|
89
|
+
return [] if pin.is_a?(Pin::MethodAlias)
|
90
|
+
result = []
|
91
|
+
declared = pin.typify(api_map).self_to(pin.full_context.namespace)
|
92
|
+
if declared.undefined?
|
93
|
+
if pin.return_type.undefined? && rules.require_type_tags?
|
94
|
+
result.push Problem.new(pin.location, "Missing @return tag for #{pin.path}", pin: pin)
|
95
|
+
elsif pin.return_type.defined? && !resolved_constant?(pin)
|
96
|
+
result.push Problem.new(pin.location, "Unresolved return type #{pin.return_type} for #{pin.path}", pin: pin)
|
97
|
+
elsif rules.must_tag_or_infer? && pin.probe(api_map).undefined?
|
98
|
+
result.push Problem.new(pin.location, "Untyped method #{pin.path} could not be inferred")
|
99
|
+
end
|
100
|
+
elsif rules.validate_tags?
|
101
|
+
unless pin.node.nil? || declared.void? || virtual_pin?(pin) || abstract?(pin)
|
102
|
+
inferred = pin.probe(api_map).self_to(pin.full_context.namespace)
|
103
|
+
if inferred.undefined?
|
104
|
+
unless rules.ignore_all_undefined? || external?(pin)
|
105
|
+
result.push Problem.new(pin.location, "#{pin.path} return type could not be inferred", pin: pin)
|
106
|
+
end
|
107
|
+
else
|
108
|
+
unless (rules.rank > 1 ? all_types_match?(api_map, inferred, declared) : any_types_match?(api_map, declared, inferred))
|
109
|
+
result.push Problem.new(pin.location, "Declared return type #{declared} does not match inferred type #{inferred} for #{pin.path}", pin: pin)
|
110
|
+
end
|
111
|
+
end
|
112
|
+
end
|
113
|
+
end
|
114
|
+
result
|
115
|
+
end
|
116
|
+
|
117
|
+
# @todo This is not optimal. A better solution would probably be to mix
|
118
|
+
# namespace alias into types at the ApiMap level.
|
119
|
+
#
|
120
|
+
# @param pin [Pin::Base]
|
121
|
+
# @return [Boolean]
|
122
|
+
def resolved_constant? pin
|
123
|
+
return true if pin.typify(api_map).defined?
|
124
|
+
api_map.get_constants('', *pin.closure.gates)
|
125
|
+
.select { |p| p.name == pin.return_type.namespace }
|
126
|
+
.any? { |p| p.infer(api_map).defined? }
|
127
|
+
end
|
128
|
+
|
129
|
+
def virtual_pin? pin
|
130
|
+
pin.location && source_map.source.comment_at?(pin.location.range.ending)
|
131
|
+
end
|
132
|
+
|
133
|
+
# @param pin [Pin::Method]
|
134
|
+
# @return [Array<Problem>]
|
135
|
+
def method_param_type_problems_for pin
|
136
|
+
stack = api_map.get_method_stack(pin.namespace, pin.name, scope: pin.scope)
|
137
|
+
params = first_param_hash(stack)
|
138
|
+
result = []
|
139
|
+
if rules.require_type_tags?
|
140
|
+
pin.signatures.each do |sig|
|
141
|
+
sig.parameters.each do |par|
|
142
|
+
break if par.decl == :restarg || par.decl == :kwrestarg || par.decl == :blockarg
|
143
|
+
unless params[par.name]
|
144
|
+
result.push Problem.new(pin.location, "Missing @param tag for #{par.name} on #{pin.path}", pin: pin)
|
145
|
+
end
|
146
|
+
end
|
147
|
+
end
|
148
|
+
end
|
149
|
+
params.each_pair do |name, data|
|
150
|
+
type = data[:qualified]
|
151
|
+
if type.undefined?
|
152
|
+
result.push Problem.new(pin.location, "Unresolved type #{data[:tagged]} for #{name} param on #{pin.path}", pin: pin)
|
153
|
+
end
|
154
|
+
end
|
155
|
+
result
|
156
|
+
end
|
157
|
+
|
158
|
+
def ignored_pins
|
159
|
+
@ignored_pins ||= []
|
160
|
+
end
|
161
|
+
|
162
|
+
# @return [Array<Problem>]
|
163
|
+
def variable_type_tag_problems
|
164
|
+
result = []
|
165
|
+
all_variables.each do |pin|
|
166
|
+
if pin.return_type.defined?
|
167
|
+
declared = pin.typify(api_map)
|
168
|
+
next if declared.duck_type?
|
169
|
+
if declared.defined?
|
170
|
+
if rules.validate_tags?
|
171
|
+
inferred = pin.probe(api_map)
|
172
|
+
if inferred.undefined?
|
173
|
+
next if rules.ignore_all_undefined?
|
174
|
+
if declared_externally?(pin)
|
175
|
+
ignored_pins.push pin
|
176
|
+
else
|
177
|
+
result.push Problem.new(pin.location, "Variable type could not be inferred for #{pin.name}", pin: pin)
|
178
|
+
end
|
179
|
+
else
|
180
|
+
unless any_types_match?(api_map, declared, inferred)
|
181
|
+
result.push Problem.new(pin.location, "Declared type #{declared} does not match inferred type #{inferred} for variable #{pin.name}", pin: pin)
|
182
|
+
end
|
183
|
+
end
|
184
|
+
elsif declared_externally?(pin)
|
185
|
+
ignored_pins.push pin
|
186
|
+
end
|
187
|
+
elsif !pin.is_a?(Pin::Parameter) && !resolved_constant?(pin)
|
188
|
+
result.push Problem.new(pin.location, "Unresolved type #{pin.return_type} for variable #{pin.name}", pin: pin)
|
189
|
+
end
|
190
|
+
else
|
191
|
+
inferred = pin.probe(api_map)
|
192
|
+
if inferred.undefined? && declared_externally?(pin)
|
193
|
+
ignored_pins.push pin
|
194
|
+
end
|
195
|
+
end
|
196
|
+
end
|
197
|
+
result
|
198
|
+
end
|
199
|
+
|
200
|
+
# @return [Array<Pin::BaseVariable>]
|
201
|
+
def all_variables
|
202
|
+
source_map.pins_by_class(Pin::BaseVariable) + source_map.locals.select { |pin| pin.is_a?(Pin::LocalVariable) }
|
203
|
+
end
|
204
|
+
|
205
|
+
def const_problems
|
206
|
+
return [] unless rules.validate_consts?
|
207
|
+
result = []
|
208
|
+
Solargraph::Parser::NodeMethods.const_nodes_from(source_map.source.node).each do |const|
|
209
|
+
rng = Solargraph::Range.from_node(const)
|
210
|
+
chain = Solargraph::Parser.chain(const, filename)
|
211
|
+
block_pin = source_map.locate_block_pin(rng.start.line, rng.start.column)
|
212
|
+
location = Location.new(filename, rng)
|
213
|
+
locals = source_map.locals_at(location)
|
214
|
+
pins = chain.define(api_map, block_pin, locals)
|
215
|
+
if pins.empty?
|
216
|
+
result.push Problem.new(location, "Unresolved constant #{Solargraph::Parser::NodeMethods.unpack_name(const)}")
|
217
|
+
@marked_ranges.push location.range
|
218
|
+
end
|
219
|
+
end
|
220
|
+
result
|
221
|
+
end
|
222
|
+
|
223
|
+
def call_problems
|
224
|
+
result = []
|
225
|
+
Solargraph::Parser::NodeMethods.call_nodes_from(source_map.source.node).each do |call|
|
226
|
+
rng = Solargraph::Range.from_node(call)
|
227
|
+
next if @marked_ranges.any? { |d| d.contain?(rng.start) }
|
228
|
+
chain = Solargraph::Parser.chain(call, filename)
|
229
|
+
block_pin = source_map.locate_block_pin(rng.start.line, rng.start.column)
|
230
|
+
location = Location.new(filename, rng)
|
231
|
+
locals = source_map.locals_at(location)
|
232
|
+
type = chain.infer(api_map, block_pin, locals)
|
233
|
+
if type.undefined? && !rules.ignore_all_undefined?
|
234
|
+
base = chain
|
235
|
+
missing = chain
|
236
|
+
found = nil
|
237
|
+
closest = ComplexType::UNDEFINED
|
238
|
+
until base.links.first.undefined?
|
239
|
+
found = base.define(api_map, block_pin, locals).first
|
240
|
+
break if found
|
241
|
+
missing = base
|
242
|
+
base = base.base
|
243
|
+
end
|
244
|
+
closest = found.typify(api_map) if found
|
245
|
+
if !found || found.is_a?(Pin::BaseVariable) || (closest.defined? && internal_or_core?(found))
|
246
|
+
unless closest.parameterized? || ignored_pins.include?(found)
|
247
|
+
result.push Problem.new(location, "Unresolved call to #{missing.links.last.word}")
|
248
|
+
@marked_ranges.push rng
|
249
|
+
end
|
250
|
+
end
|
251
|
+
end
|
252
|
+
result.concat argument_problems_for(chain, api_map, block_pin, locals, location)
|
253
|
+
end
|
254
|
+
result
|
255
|
+
end
|
256
|
+
|
257
|
+
def argument_problems_for chain, api_map, block_pin, locals, location
|
258
|
+
result = []
|
259
|
+
base = chain
|
260
|
+
until base.links.length == 1 && base.undefined?
|
261
|
+
pins = base.define(api_map, block_pin, locals)
|
262
|
+
if pins.first.is_a?(Pin::Method)
|
263
|
+
# @type [Pin::Method]
|
264
|
+
pin = pins.first
|
265
|
+
ap = if base.links.last.is_a?(Solargraph::Source::Chain::ZSuper)
|
266
|
+
arity_problems_for(pin, fake_args_for(block_pin), location)
|
267
|
+
else
|
268
|
+
arity_problems_for(pin, base.links.last.arguments, location)
|
269
|
+
end
|
270
|
+
unless ap.empty?
|
271
|
+
result.concat ap
|
272
|
+
break
|
273
|
+
end
|
274
|
+
break unless rules.validate_calls?
|
275
|
+
params = first_param_hash(pins)
|
276
|
+
|
277
|
+
all_errors = []
|
278
|
+
pin.signatures.sort { |sig| sig.parameters.length }.each do |sig|
|
279
|
+
errors = []
|
280
|
+
sig.parameters.each_with_index do |par, idx|
|
281
|
+
argchain = base.links.last.arguments[idx]
|
282
|
+
if argchain.nil? && par.decl == :arg
|
283
|
+
errors.push Problem.new(location, "Not enough arguments to #{pin.path}")
|
284
|
+
next
|
285
|
+
end
|
286
|
+
if argchain
|
287
|
+
if par.decl != :arg
|
288
|
+
errors.concat kwarg_problems_for argchain, api_map, block_pin, locals, location, pin, params, idx
|
289
|
+
next
|
290
|
+
else
|
291
|
+
ptype = params.key?(par.name) ? params[par.name][:qualified] : ComplexType::UNDEFINED
|
292
|
+
if ptype.nil?
|
293
|
+
# @todo Some level (strong, I guess) should require the param here
|
294
|
+
else
|
295
|
+
argtype = argchain.infer(api_map, block_pin, locals)
|
296
|
+
if argtype.defined? && ptype.defined? && !any_types_match?(api_map, ptype, argtype)
|
297
|
+
errors.push Problem.new(location, "Wrong argument type for #{pin.path}: #{par.name} expected #{ptype}, received #{argtype}")
|
298
|
+
next
|
299
|
+
end
|
300
|
+
end
|
301
|
+
end
|
302
|
+
elsif par.decl == :kwarg
|
303
|
+
errors.push Problem.new(location, "Call to #{pin.path} is missing keyword argument #{par.name}")
|
304
|
+
next
|
305
|
+
end
|
306
|
+
end
|
307
|
+
if errors.empty?
|
308
|
+
all_errors.clear
|
309
|
+
break
|
310
|
+
end
|
311
|
+
all_errors.concat errors
|
312
|
+
end
|
313
|
+
result.concat all_errors
|
314
|
+
end
|
315
|
+
base = base.base
|
316
|
+
end
|
317
|
+
result
|
318
|
+
end
|
319
|
+
|
320
|
+
def kwarg_problems_for argchain, api_map, block_pin, locals, location, pin, params, first
|
321
|
+
result = []
|
322
|
+
kwargs = convert_hash(argchain.node)
|
323
|
+
pin.signatures.first.parameters[first..-1].each_with_index do |par, cur|
|
324
|
+
idx = first + cur
|
325
|
+
argchain = kwargs[par.name.to_sym]
|
326
|
+
if par.decl == :kwrestarg || (par.decl == :optarg && idx == pin.parameters.length - 1 && par.asgn_code == '{}')
|
327
|
+
result.concat kwrestarg_problems_for(api_map, block_pin, locals, location, pin, params, kwargs)
|
328
|
+
else
|
329
|
+
if argchain
|
330
|
+
data = params[par.name]
|
331
|
+
if data.nil?
|
332
|
+
# @todo Some level (strong, I guess) should require the param here
|
333
|
+
else
|
334
|
+
ptype = data[:qualified]
|
335
|
+
next if ptype.undefined?
|
336
|
+
argtype = argchain.infer(api_map, block_pin, locals)
|
337
|
+
if argtype.defined? && ptype && !any_types_match?(api_map, ptype, argtype)
|
338
|
+
result.push Problem.new(location, "Wrong argument type for #{pin.path}: #{par.name} expected #{ptype}, received #{argtype}")
|
339
|
+
end
|
340
|
+
end
|
341
|
+
elsif par.decl == :kwarg
|
342
|
+
result.push Problem.new(location, "Call to #{pin.path} is missing keyword argument #{par.name}")
|
343
|
+
end
|
344
|
+
end
|
345
|
+
end
|
346
|
+
result
|
347
|
+
end
|
348
|
+
|
349
|
+
def kwrestarg_problems_for(api_map, block_pin, locals, location, pin, params, kwargs)
|
350
|
+
result = []
|
351
|
+
kwargs.each_pair do |pname, argchain|
|
352
|
+
next unless params.key?(pname.to_s)
|
353
|
+
ptype = params[pname.to_s][:qualified]
|
354
|
+
argtype = argchain.infer(api_map, block_pin, locals)
|
355
|
+
if argtype.defined? && ptype && !any_types_match?(api_map, ptype, argtype)
|
356
|
+
result.push Problem.new(location, "Wrong argument type for #{pin.path}: #{pname} expected #{ptype}, received #{argtype}")
|
357
|
+
end
|
358
|
+
end
|
359
|
+
result
|
360
|
+
end
|
361
|
+
|
362
|
+
# @param [Pin::Method]
|
363
|
+
# @return [Hash]
|
364
|
+
def param_hash(pin)
|
365
|
+
tags = pin.docstring.tags(:param)
|
366
|
+
return {} if tags.empty?
|
367
|
+
result = {}
|
368
|
+
tags.each do |tag|
|
369
|
+
next if tag.types.nil? || tag.types.empty?
|
370
|
+
result[tag.name.to_s] = {
|
371
|
+
tagged: tag.types.join(', '),
|
372
|
+
qualified: Solargraph::ComplexType.try_parse(*tag.types).qualify(api_map, pin.full_context.namespace)
|
373
|
+
}
|
374
|
+
end
|
375
|
+
result
|
376
|
+
end
|
377
|
+
|
378
|
+
# @param [Array<Pin::Method>]
|
379
|
+
# @return [Hash]
|
380
|
+
def first_param_hash(pins)
|
381
|
+
pins.each do |pin|
|
382
|
+
result = param_hash(pin)
|
383
|
+
return result unless result.empty?
|
384
|
+
end
|
385
|
+
{}
|
386
|
+
end
|
387
|
+
|
388
|
+
# @param pin [Pin::Base]
|
389
|
+
def internal? pin
|
390
|
+
return false if pin.nil?
|
391
|
+
pin.location && api_map.bundled?(pin.location.filename)
|
392
|
+
end
|
393
|
+
|
394
|
+
# True if the pin is either internal (part of the workspace) or from the core/stdlib
|
395
|
+
def internal_or_core? pin
|
396
|
+
# @todo RBS pins are not necessarily core/stdlib pins
|
397
|
+
internal?(pin) || pin.source == :rbs
|
398
|
+
end
|
399
|
+
|
400
|
+
# @param pin [Pin::Base]
|
401
|
+
def external? pin
|
402
|
+
!internal? pin
|
403
|
+
end
|
404
|
+
|
405
|
+
def declared_externally? pin
|
406
|
+
return true if pin.assignment.nil?
|
407
|
+
chain = Solargraph::Parser.chain(pin.assignment, filename)
|
408
|
+
rng = Solargraph::Range.from_node(pin.assignment)
|
409
|
+
block_pin = source_map.locate_block_pin(rng.start.line, rng.start.column)
|
410
|
+
location = Location.new(filename, Range.from_node(pin.assignment))
|
411
|
+
locals = source_map.locals_at(location)
|
412
|
+
type = chain.infer(api_map, block_pin, locals)
|
413
|
+
if type.undefined? && !rules.ignore_all_undefined?
|
414
|
+
base = chain
|
415
|
+
missing = chain
|
416
|
+
found = nil
|
417
|
+
closest = ComplexType::UNDEFINED
|
418
|
+
until base.links.first.undefined?
|
419
|
+
found = base.define(api_map, block_pin, locals).first
|
420
|
+
break if found
|
421
|
+
missing = base
|
422
|
+
base = base.base
|
423
|
+
end
|
424
|
+
closest = found.typify(api_map) if found
|
425
|
+
if !found || closest.defined? || internal?(found)
|
426
|
+
return false
|
427
|
+
end
|
428
|
+
end
|
429
|
+
true
|
430
|
+
end
|
431
|
+
|
432
|
+
def arity_problems_for pin, arguments, location
|
433
|
+
results = pin.signatures.map do |sig|
|
434
|
+
r = parameterized_arity_problems_for(pin, sig.parameters, arguments, location)
|
435
|
+
return [] if r.empty?
|
436
|
+
r
|
437
|
+
end
|
438
|
+
results.first
|
439
|
+
end
|
440
|
+
|
441
|
+
def parameterized_arity_problems_for(pin, parameters, arguments, location)
|
442
|
+
return [] unless pin.explicit?
|
443
|
+
return [] if parameters.empty? && arguments.empty?
|
444
|
+
return [] if pin.anon_splat?
|
445
|
+
if parameters.empty?
|
446
|
+
# Functions tagged param_tuple accepts two arguments (e.g., Hash#[]=)
|
447
|
+
return [] if pin.docstring.tag(:param_tuple) && arguments.length == 2
|
448
|
+
return [] if arguments.length == 1 && arguments.last.links.last.is_a?(Source::Chain::BlockVariable)
|
449
|
+
return [Problem.new(location, "Too many arguments to #{pin.path}")]
|
450
|
+
end
|
451
|
+
unchecked = arguments.clone
|
452
|
+
add_params = 0
|
453
|
+
if unchecked.empty? && parameters.any? { |param| param.decl == :kwarg }
|
454
|
+
return [Problem.new(location, "Missing keyword arguments to #{pin.path}")]
|
455
|
+
end
|
456
|
+
settled_kwargs = 0
|
457
|
+
unless unchecked.empty?
|
458
|
+
if any_splatted_call?(unchecked.map(&:node))
|
459
|
+
settled_kwargs = parameters.count(&:keyword?)
|
460
|
+
else
|
461
|
+
kwargs = convert_hash(unchecked.last.node)
|
462
|
+
if parameters.any? { |param| [:kwarg, :kwoptarg].include?(param.decl) || param.kwrestarg? }
|
463
|
+
if kwargs.empty?
|
464
|
+
add_params += 1
|
465
|
+
else
|
466
|
+
unchecked.pop
|
467
|
+
parameters.each do |param|
|
468
|
+
next unless param.keyword?
|
469
|
+
if kwargs.key?(param.name.to_sym)
|
470
|
+
kwargs.delete param.name.to_sym
|
471
|
+
settled_kwargs += 1
|
472
|
+
elsif param.decl == :kwarg
|
473
|
+
return [] if arguments.last.links.last.is_a?(Solargraph::Source::Chain::Hash) && arguments.last.links.last.splatted?
|
474
|
+
return [Problem.new(location, "Missing keyword argument #{param.name} to #{pin.path}")]
|
475
|
+
end
|
476
|
+
end
|
477
|
+
kwargs.clear if parameters.any?(&:kwrestarg?)
|
478
|
+
unless kwargs.empty?
|
479
|
+
return [Problem.new(location, "Unrecognized keyword argument #{kwargs.keys.first} to #{pin.path}")]
|
480
|
+
end
|
481
|
+
end
|
482
|
+
end
|
483
|
+
end
|
484
|
+
end
|
485
|
+
req = required_param_count(parameters)
|
486
|
+
if req + add_params < unchecked.length
|
487
|
+
return [] if parameters.any?(&:rest?)
|
488
|
+
opt = optional_param_count(parameters)
|
489
|
+
return [] if unchecked.length <= req + opt
|
490
|
+
if unchecked.length == req + opt + 1 && unchecked.last.links.last.is_a?(Source::Chain::BlockVariable)
|
491
|
+
return []
|
492
|
+
end
|
493
|
+
if req + add_params + 1 == unchecked.length && any_splatted_call?(unchecked.map(&:node)) && (parameters.map(&:decl) & [:kwarg, :kwoptarg, :kwrestarg]).any?
|
494
|
+
return []
|
495
|
+
end
|
496
|
+
return [] if arguments.length - req == parameters.select { |p| [:optarg, :kwoptarg].include?(p.decl) }.length
|
497
|
+
return [Problem.new(location, "Too many arguments to #{pin.path}")]
|
498
|
+
elsif unchecked.length < req - settled_kwargs && (arguments.empty? || (!arguments.last.splat? && !arguments.last.links.last.is_a?(Solargraph::Source::Chain::Hash)))
|
499
|
+
# HACK: Kernel#raise signature is incorrect in Ruby 2.7 core docs.
|
500
|
+
# See https://github.com/castwide/solargraph/issues/418
|
501
|
+
unless arguments.empty? && pin.path == 'Kernel#raise'
|
502
|
+
return [Problem.new(location, "Not enough arguments to #{pin.path}")]
|
503
|
+
end
|
504
|
+
end
|
505
|
+
[]
|
506
|
+
end
|
507
|
+
|
508
|
+
def required_param_count(parameters)
|
509
|
+
parameters.sum { |param| %i[arg kwarg].include?(param.decl) ? 1 : 0 }
|
510
|
+
end
|
511
|
+
|
512
|
+
# @param pin [Pin::Method]
|
513
|
+
def optional_param_count(parameters)
|
514
|
+
parameters.select { |p| p.decl == :optarg }.length
|
515
|
+
end
|
516
|
+
|
517
|
+
def abstract? pin
|
518
|
+
pin.docstring.has_tag?(:abstract) ||
|
519
|
+
(pin.closure && pin.closure.docstring.has_tag?(:abstract))
|
520
|
+
end
|
521
|
+
|
522
|
+
def fake_args_for(pin)
|
523
|
+
args = []
|
524
|
+
with_opts = false
|
525
|
+
with_block = false
|
526
|
+
pin.parameters.each do |pin|
|
527
|
+
if [:kwarg, :kwoptarg, :kwrestarg].include?(pin.decl)
|
528
|
+
with_opts = true
|
529
|
+
elsif pin.decl == :block
|
530
|
+
with_block = true
|
531
|
+
elsif pin.decl == :restarg
|
532
|
+
args.push Solargraph::Source::Chain.new([Solargraph::Source::Chain::Variable.new(pin.name)], nil, true)
|
533
|
+
else
|
534
|
+
args.push Solargraph::Source::Chain.new([Solargraph::Source::Chain::Variable.new(pin.name)])
|
535
|
+
end
|
536
|
+
end
|
537
|
+
args.push Solargraph::Parser.chain_string('{}') if with_opts
|
538
|
+
args.push Solargraph::Parser.chain_string('&') if with_block
|
539
|
+
args
|
540
|
+
end
|
541
|
+
|
542
|
+
def without_ignored problems
|
543
|
+
problems.reject do |problem|
|
544
|
+
node = source_map.source.node_at(problem.location.range.start.line, problem.location.range.start.column)
|
545
|
+
source_map.source.comments_for(node)&.include?('@sg-ignore')
|
546
|
+
end
|
547
|
+
end
|
548
|
+
end
|
549
|
+
end
|
@@ -0,0 +1,62 @@
|
|
1
|
+
<h2>
|
2
|
+
Namespace:
|
3
|
+
</h2>
|
4
|
+
<p>
|
5
|
+
<a href="solargraph:/document?query=<%= CGI.escape object.namespace.path %>"><%= object.namespace %></a>
|
6
|
+
</p>
|
7
|
+
<h2>
|
8
|
+
Overview:
|
9
|
+
</h2>
|
10
|
+
<%= htmlify object.docstring %>
|
11
|
+
<p class="document-section">
|
12
|
+
<big><strong>Visibility:</strong></big> <%= object.visibility %>
|
13
|
+
</p>
|
14
|
+
<% unless object.tags(:param).empty? %>
|
15
|
+
<h2>
|
16
|
+
Parameters:
|
17
|
+
</h2>
|
18
|
+
<ul>
|
19
|
+
<% object.tags(:param).each do |tag| %>
|
20
|
+
<li>
|
21
|
+
<%= erb :_name_type_tag, layout: false, locals: {tag: tag} %>
|
22
|
+
</li>
|
23
|
+
<% end %>
|
24
|
+
</ul>
|
25
|
+
<% end %>
|
26
|
+
<% unless object.tags(:raise).empty? %>
|
27
|
+
<h2>
|
28
|
+
Raises:
|
29
|
+
</h2>
|
30
|
+
<ul>
|
31
|
+
<% object.tags(:raise).each do |tag| %>
|
32
|
+
<li>
|
33
|
+
<%= erb :_name_type_tag, layout: false, locals: {tag: tag} %>
|
34
|
+
</li>
|
35
|
+
<% end %>
|
36
|
+
</ul>
|
37
|
+
<% end %>
|
38
|
+
<h2>
|
39
|
+
Returns:
|
40
|
+
</h2>
|
41
|
+
<% if object.tag(:return).nil? %>
|
42
|
+
<p>
|
43
|
+
Undefined/unknown
|
44
|
+
</p>
|
45
|
+
<% else %>
|
46
|
+
<ul>
|
47
|
+
<% object.tags(:return).each do |tag| %>
|
48
|
+
<li>
|
49
|
+
<%= erb :_name_type_tag, layout: false, locals: {tag: tag} %>
|
50
|
+
</li>
|
51
|
+
<% end %>
|
52
|
+
</ul>
|
53
|
+
<% end %>
|
54
|
+
<% examples = object.tags(:example) %>
|
55
|
+
<% unless examples.nil? %>
|
56
|
+
<% examples.each do |example| %>
|
57
|
+
<h2>
|
58
|
+
Example: <%= example.name %>
|
59
|
+
</h2>
|
60
|
+
<%= ruby_to_html example.text.strip %>
|
61
|
+
<% end %>
|
62
|
+
<% end %>
|
@@ -0,0 +1,10 @@
|
|
1
|
+
<%= tag.name %>
|
2
|
+
<% unless tag.types.nil? or tag.types.empty? %>
|
3
|
+
[<%= escape(tag.types.join(', ')) %>]
|
4
|
+
<% end %>
|
5
|
+
<% unless tag.text.nil? || tag.text.empty? %>
|
6
|
+
<% unless (tag.name.nil? or tag.name.empty?) and (tag.types.nil? or tag.types.empty?) %>
|
7
|
+
-
|
8
|
+
<% end %>
|
9
|
+
<%= tag.text %>
|
10
|
+
<% end %>
|
@@ -0,0 +1,24 @@
|
|
1
|
+
<h2>
|
2
|
+
Overview:
|
3
|
+
</h2>
|
4
|
+
<%= htmlify object.docstring %>
|
5
|
+
<h2>
|
6
|
+
Class Methods
|
7
|
+
</h2>
|
8
|
+
<ul class="doc-list">
|
9
|
+
<% object.meths(scope: :class).sort{|a, b| a.name <=> b.name}.each do |meth| %>
|
10
|
+
<li>
|
11
|
+
<a href="solargraph:/document?query=<%= CGI.escape(meth.path) %>"><%= meth.name %></a>
|
12
|
+
</li>
|
13
|
+
<% end %>
|
14
|
+
</ul>
|
15
|
+
<h2>
|
16
|
+
Instance Methods
|
17
|
+
</h2>
|
18
|
+
<ul class="doc-list">
|
19
|
+
<% object.meths(scope: :instance).sort{|a, b| a.name <=> b.name}.each do |meth| %>
|
20
|
+
<li>
|
21
|
+
<a href="solargraph:/document?query=<%= CGI.escape(meth.path) %>"><%= meth.name %></a>
|
22
|
+
</li>
|
23
|
+
<% end %>
|
24
|
+
</ul>
|
@@ -0,0 +1,23 @@
|
|
1
|
+
<% objects.reverse.each do |object| %>
|
2
|
+
<h1>
|
3
|
+
<%= object.name %>
|
4
|
+
<% if object.is_a?(YARD::CodeObjects::MethodObject) and !object.parameters.empty? %>
|
5
|
+
<small>(<%= object.parameters.map {|p| "#{p[0]}#{p[1] and p[0].end_with?(':') ? ' ' : (p[1] ? ' = ' : '')}#{p[1]}"}.join(', ') %>)</small>
|
6
|
+
<% end %>
|
7
|
+
</h1>
|
8
|
+
<% unless object.files.empty? %>
|
9
|
+
<h2>
|
10
|
+
Defined in:
|
11
|
+
</h2>
|
12
|
+
<ul>
|
13
|
+
<% object.files.each do |f| %>
|
14
|
+
<li><%= f %></li>
|
15
|
+
<% end %>
|
16
|
+
</ul>
|
17
|
+
<% end %>
|
18
|
+
<% if object.is_a?(YARD::CodeObjects::NamespaceObject) %>
|
19
|
+
<%= erb :_namespace, layout: false, locals: {object: object} %>
|
20
|
+
<% elsif object.is_a?(YARD::CodeObjects::MethodObject) %>
|
21
|
+
<%= erb :_method, layout: false, locals: {object: object} %>
|
22
|
+
<% end %>
|
23
|
+
<% end %>
|